diff --git a/backend/internal/service/provider.go b/backend/internal/service/provider.go index 7df413967..62e8ba579 100644 --- a/backend/internal/service/provider.go +++ b/backend/internal/service/provider.go @@ -15,6 +15,7 @@ import ( "net/http" "net/textproto" "net/url" + "path/filepath" "strconv" "strings" "time" @@ -225,8 +226,41 @@ func (s *Service) hydrateProviderMedia(userID string, media *providerMedia, requ if resource.Status != "ready" { return errors.New("任务参考资源尚未上传完成") } + // 本地素材自动迁移到 OSS if resource.Provider == "local" { - return errors.New("当前 JSON 视频协议的参考素材需要公网可访问地址,请启用 OSS 后重新上传该素材") + setting, storageSettingID, useOSS, ossErr := s.activeResourceOSSSetting(userID) + if ossErr != nil || !useOSS || setting.Provider != "aliyun" { + return errors.New("当前 JSON 视频协议的参考素材需要公网可访问地址,请启用 OSS 后重新上传该素材") + } + // 读取本地文件并上传到 OSS + _, body, readErr := s.OpenResource(userID, resourceID) + if readErr != nil { + return fmt.Errorf("读取本地素材失败:%w", readErr) + } + ossKey := ossObjectKey(setting, userID, resource.Kind, filepath.Base(resource.ObjectKey), time.Now()) + if _, uploadErr := putOSSObject(setting, ossKey, resource.MimeType, resource.Size, body); uploadErr != nil { + body.Close() + return fmt.Errorf("素材迁移到 OSS 失败:%w", uploadErr) + } + body.Close() + // 更新资源记录 + resource.Provider = "aliyun" + resource.ObjectKey = ossKey + resource.Endpoint = setting.Endpoint + resource.Bucket = setting.Bucket + resource.StorageSettingID = storageSettingID + if saveErr := s.repo.SaveResource(resource); saveErr != nil { + return fmt.Errorf("更新资源记录失败:%w", saveErr) + } + // 生成签名 URL + signedURL, signErr := signedOSSObjectURL(setting, ossKey, time.Now().Add(providerResourceURLTTL)) + if signErr != nil { + return fmt.Errorf("生成 OSS 签名地址失败:%w", signErr) + } + media.URL = signedURL + media.DataURL = "" + media.MimeType = firstNonEmpty(media.MimeType, resource.MimeType) + return nil } setting, err := s.ossSettingForResource(userID, resource) if err != nil { diff --git a/web/src/components/canvas/canvas-active-task-panel.tsx b/web/src/components/canvas/canvas-active-task-panel.tsx index 9f9365f23..2bb4c0ea6 100644 --- a/web/src/components/canvas/canvas-active-task-panel.tsx +++ b/web/src/components/canvas/canvas-active-task-panel.tsx @@ -13,7 +13,7 @@ export function CanvasActiveTaskPanel({ tasks }: { tasks: GenerationTask[] }) { const theme = canvasThemes[useThemeStore((state) => state.theme)]; const reducedMotion = useReducedMotion(); const [now, setNow] = useState(() => Date.now()); - const [open, setOpen] = useState(true); + const [open, setOpen] = useState(false); const [expandedTaskId, setExpandedTaskId] = useState(null); useEffect(() => {