1
This commit is contained in:
+1
-1
@@ -98,7 +98,7 @@ func processField(name string, def map[string]any, input map[string]any) (any, e
|
||||
rawVal, exists := input[name]
|
||||
if !exists {
|
||||
if required {
|
||||
return nil, fmt.Errorf("'%s' is required", name)
|
||||
return nil, fmt.Errorf("%s", def["description"])
|
||||
}
|
||||
if dflt, ok := def["default"]; ok {
|
||||
return convertDefault(dflt, fieldType), nil
|
||||
|
||||
Binary file not shown.
@@ -1238,7 +1238,6 @@ func buildCharacterGuide(charNames []string, chars []*entity.Character, labelOf
|
||||
|
||||
// extractAndSaveEntities 从镜头数组中提取演员/场景/道具,去重后写入数据库。
|
||||
// 如果同 drama 下已存在同名记录,跳过插入(避免重复)。
|
||||
// 描述信息从镜头的 event 画面描述中提取,保证是视觉/外观描述。
|
||||
func extractAndSaveEntities(ctx context.Context, dramaId int64, shots []domain.Shot) {
|
||||
if len(shots) == 0 {
|
||||
return
|
||||
@@ -1247,39 +1246,22 @@ func extractAndSaveEntities(ctx context.Context, dramaId int64, shots []domain.S
|
||||
charSet := make(map[string]bool)
|
||||
sceneSet := make(map[string]bool)
|
||||
propSet := make(map[string]bool)
|
||||
// name → []event 片段
|
||||
charEvents := make(map[string][]string)
|
||||
sceneEvents := make(map[string][]string)
|
||||
propEvents := make(map[string][]string)
|
||||
|
||||
for _, sh := range shots {
|
||||
for _, c := range sh.Characters {
|
||||
if c == "" {
|
||||
continue
|
||||
}
|
||||
if !charSet[c] {
|
||||
charSet[c] = true
|
||||
}
|
||||
if sh.Event != "" {
|
||||
charEvents[c] = append(charEvents[c], sh.Event)
|
||||
}
|
||||
charSet[c] = true
|
||||
}
|
||||
if sh.Scene != "" {
|
||||
sceneSet[sh.Scene] = true
|
||||
if sh.Event != "" {
|
||||
sceneEvents[sh.Scene] = append(sceneEvents[sh.Scene], sh.Event)
|
||||
}
|
||||
}
|
||||
for _, p := range sh.Props {
|
||||
if p == "" {
|
||||
continue
|
||||
}
|
||||
if !propSet[p] {
|
||||
propSet[p] = true
|
||||
}
|
||||
if sh.Event != "" {
|
||||
propEvents[p] = append(propEvents[p], sh.Event)
|
||||
}
|
||||
propSet[p] = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1312,43 +1294,17 @@ func extractAndSaveEntities(ctx context.Context, dramaId int64, shots []domain.S
|
||||
return false
|
||||
}
|
||||
|
||||
buildDesc := func(events []string) string {
|
||||
seen := make(map[string]bool)
|
||||
var parts []string
|
||||
for _, e := range events {
|
||||
if e == "" || seen[e] {
|
||||
continue
|
||||
}
|
||||
seen[e] = true
|
||||
parts = append(parts, e)
|
||||
if len(parts) >= 3 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if len(parts) == 0 {
|
||||
return ""
|
||||
}
|
||||
result := strings.Join(parts, ";")
|
||||
runes := []rune(result)
|
||||
if len(runes) > 300 {
|
||||
result = string(runes[:300]) + "……"
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
now := time.Now().Format("2006-01-02 15:04:05")
|
||||
|
||||
for name := range charSet {
|
||||
if existName(existingChars, name) {
|
||||
continue
|
||||
}
|
||||
desc := buildDesc(charEvents[name])
|
||||
_, _ = g.DB().Model(consts.TableNameCharacter).Ctx(ctx).Data(g.Map{
|
||||
"drama_id": dramaId,
|
||||
"name": name,
|
||||
"description": desc,
|
||||
"created_at": now,
|
||||
"updated_at": now,
|
||||
"drama_id": dramaId,
|
||||
"name": name,
|
||||
"created_at": now,
|
||||
"updated_at": now,
|
||||
}).Insert()
|
||||
}
|
||||
|
||||
@@ -1356,13 +1312,11 @@ func extractAndSaveEntities(ctx context.Context, dramaId int64, shots []domain.S
|
||||
if existName(existingScenes, name) {
|
||||
continue
|
||||
}
|
||||
desc := buildDesc(sceneEvents[name])
|
||||
_, _ = g.DB().Model(consts.TableNameScene).Ctx(ctx).Data(g.Map{
|
||||
"drama_id": dramaId,
|
||||
"name": name,
|
||||
"description": desc,
|
||||
"created_at": now,
|
||||
"updated_at": now,
|
||||
"drama_id": dramaId,
|
||||
"name": name,
|
||||
"created_at": now,
|
||||
"updated_at": now,
|
||||
}).Insert()
|
||||
}
|
||||
|
||||
@@ -1370,13 +1324,11 @@ func extractAndSaveEntities(ctx context.Context, dramaId int64, shots []domain.S
|
||||
if existName(existingProps, name) {
|
||||
continue
|
||||
}
|
||||
desc := buildDesc(propEvents[name])
|
||||
_, _ = g.DB().Model(consts.TableNameProp).Ctx(ctx).Data(g.Map{
|
||||
"drama_id": dramaId,
|
||||
"name": name,
|
||||
"description": desc,
|
||||
"created_at": now,
|
||||
"updated_at": now,
|
||||
"drama_id": dramaId,
|
||||
"name": name,
|
||||
"created_at": now,
|
||||
"updated_at": now,
|
||||
}).Insert()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
@@ -71,7 +72,17 @@ func (s *generationService) GenerateEpisode(ctx context.Context, dramaId, epId i
|
||||
if videoCfg.ApiKey == "" || videoCfg.BaseUrl == "" || videoCfg.ModelName == "" {
|
||||
return fmt.Errorf("video model not configured")
|
||||
}
|
||||
// 客户身份:余额检查并预扣费
|
||||
|
||||
// ============ 检查待生成任务的 media 文件是否存在 ============
|
||||
if !continueIfMissing {
|
||||
if missingNames := checkTaskMediaExistence(ctx, epId); len(missingNames) > 0 {
|
||||
return errors.New("至少需要包含一个人物形象")
|
||||
}
|
||||
} else {
|
||||
rebuildTasksMedia(ctx, epId)
|
||||
}
|
||||
|
||||
// 客户身份:余额检查并预扣费(放在 media 检查之后,确认可生成再扣费)
|
||||
if r := g.RequestFromCtx(ctx); r != nil {
|
||||
if role := r.GetCtxVar("role").String(); role == "customer" {
|
||||
userId := r.GetCtxVar("userId").Int64()
|
||||
@@ -100,15 +111,6 @@ func (s *generationService) GenerateEpisode(ctx context.Context, dramaId, epId i
|
||||
g.Log().Infof(ctx, "预加载引用数据: %d个演员, %d个场景, %d个道具, %d个引用",
|
||||
len(genCtx2.Characters), len(genCtx2.Scenes), len(genCtx2.Props), len(genCtx2.OrderedRefs))
|
||||
|
||||
// ============ 检查待生成任务的 media 文件是否存在 ============
|
||||
if !continueIfMissing {
|
||||
if missingNames := checkTaskMediaExistence(ctx, epId); len(missingNames) > 0 {
|
||||
return fmt.Errorf("missing_character_media:%s", strings.Join(missingNames, ","))
|
||||
}
|
||||
} else {
|
||||
rebuildTasksMedia(ctx, epId)
|
||||
}
|
||||
|
||||
genCtx := agent.WithDramaID(ctx, d.Id)
|
||||
|
||||
segDurs := calcSegDurs(d.EpisodeDuration, videoCfg.ModelConfig)
|
||||
@@ -2125,7 +2127,7 @@ func (s *generationService) submitVideoTask(ctx context.Context, d *entity.Drama
|
||||
taskId, requestJSON, err := submitVideoGenRequest(ctx, modelCfg.ApiKey, modelCfg.BaseUrl, modelCfg.ModelName,
|
||||
prompt, negativePrompt, refURLs, effectiveDur, d.Resolution, d.AspectRatio, modelCfg.Schema, seed, segIdx, genTaskId, ep.Id, d.Title, ep.Title, modelCfg.SchemaMapping)
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("video composition request failed: %w", err)
|
||||
return "", "", fmt.Errorf("%s", err)
|
||||
}
|
||||
|
||||
if taskId == "" {
|
||||
@@ -2225,7 +2227,7 @@ func submitVideoGenRequest(ctx context.Context, apiKey, baseURL, modelName, prom
|
||||
bodyDef, _ := nested(vs, "body").(map[string]any)
|
||||
body, err := common.BuildSchemaRequest(bodyDef, input)
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("build request body failed: %w", err)
|
||||
return "", "", fmt.Errorf("%s", err)
|
||||
}
|
||||
if body == nil {
|
||||
body = map[string]any{}
|
||||
|
||||
Reference in New Issue
Block a user