diff --git a/data/skills/art_prompts/chinese_sweet_romance/README.md b/data/skills/art_prompts/chinese_sweet_romance/README.md new file mode 100644 index 0000000..0d35dd8 --- /dev/null +++ b/data/skills/art_prompts/chinese_sweet_romance/README.md @@ -0,0 +1,4 @@ +name +123123水电费水电费水电费水电费水电费 +123123123 +123123123 \ No newline at end of file diff --git a/data/skills/art_prompts/chinese_sweet_romance/art_prompt/art_character.md b/data/skills/art_prompts/chinese_sweet_romance/art_prompt/art_character.md new file mode 100644 index 0000000..6c3b10e --- /dev/null +++ b/data/skills/art_prompts/chinese_sweet_romance/art_prompt/art_character.md @@ -0,0 +1,203 @@ +# 人物基础形象生成 · 约束手册 + + +--- + +## 一、基础形象原则 + +1. **面容即灵魂** — 五官是角色唯一锚点,毛孔级精细渲染 +2. **底模即基础** — 白色中衣 + 素颜,后续服化均为叠加层 +3. **四视图一致** — 面容/体型/发型/中衣跨视图高度统一 +4. **冷艳含情** — 无妆状态仍需体现角色气质(清冷/温润/妩媚) +5. **着装安全** — 基础中衣完整覆盖,端庄得体 + +--- + +## 二、面容约束 + +### 女性面容 + +| 部位 | 约束 | 提示词 | +|---|---|---| +| 脸型 | 长脸、线条流畅、下颌收窄 | 长脸、鹅蛋偏长脸 | +| 眼型 | 狭长妩媚、双眼皮窄、眼尾上扬 | 妩媚狭长眼、凤眼微挑 | +| 眉型 | 自然眉形、眉色灰棕(裸眉) | 自然眉形、裸眉 | +| 鼻型 | 高挺直鼻、鼻翼窄 | 高鼻梁、鼻翼精致 | +| 唇型 | 薄唇、唇色自然裸粉 | 薄唇、唇色裸粉 | +| 气质 | 清冷、五官立体、素颜无妆 | 面容清冷、五官立体、素颜 | + +### 男性面容 + +| 部位 | 约束 | 提示词 | +|---|---|---| +| 脸型 | 棱角分明、下颌线清晰 | 棱角分明、下颌线硬朗 | +| 眼型 | 剑眉星目、深邃克制 | 剑眉星目、眼神清冽 | +| 鼻型 | 高挺英挺、鼻梁笔直 | 高鼻英挺 | +| 唇型 | 薄唇微抿、唇色自然 | 薄唇、唇色自然 | +| 气质 | 清冷疏离 / 温润如玉 | 清冷俊逸 / 温润如玉、素颜 | + +--- + +## 三、肤感约束 + +### 女性 + +| 项目 | 约束 | 提示词 | +|---|---|---| +| 肤色 | 冷白皮、全身均匀、白得通透 | 冷白皮、牛奶肌、milky white skin | +| 光泽 | 水光肌、内透光感、非哑光非油光 | 水光肌、luminous skin、dewy skin | +| 质感 | 细腻、保留毛孔微质感 | 皮肤细腻、毛孔微可见 | +| 露肤 | 面部/颈部/锁骨/手部 | 肩颈线条优美、肌肤白皙透亮 | + +### 男性 + +| 项目 | 约束 | 提示词 | +|---|---|---| +| 肤色 | 白皙透亮、带健康感、全身均匀 | 肤色白皙透亮、奶油肌 | +| 光泽 | 清爽水光、自然光泽 | 水光肌、皮肤透亮清爽 | +| 质感 | 干净利落、可见毛孔 | 皮肤质感细腻、面容清冽 | + +--- + +## 四、体型约束 + +### 女性 + +| 项目 | 约束 | 提示词 | +|---|---|---| +| 比例 | 修长纤细、七头身以上 | 身材修长、比例匀称 | +| 肩颈 | 天鹅颈、肩颈线优美 | 天鹅颈、肩颈优美 | +| 手部 | 纤长白皙、指节分明、五指正常 | 纤纤玉手、指节分明 | +| 体态 | 古典仕女、含蓄端庄 | 体态端庄、身姿优雅 | + +### 男性 + +| 项目 | 约束 | 提示词 | +|---|---|---| +| 比例 | 高挑挺拔、肩宽腰窄、七头半身以上 | 身材高挑、比例匀称 | +| 肩颈 | 肩部宽阔、颈部有力 | 宽肩窄腰 | +| 手部 | 骨节分明、手掌宽大、五指正常 | 手指骨节分明 | +| 体态 | 武将/书生体态(按角色) | 身姿挺拔、体态从容 | + +--- + +## 五、基础发型约束 + +> 仅定义自然散发/简单束发,发饰在服化衍生环节叠加。 + +### 女性 + +| 项目 | 约束 | 提示词 | +|---|---|---| +| 发色 | 纯黑,禁棕色/挑染 | 黑色长发、墨发如瀑 | +| 发长 | 及腰或更长 | 及腰长发 | +| 发质 | 根根分明、丝缕清晰 | 发丝根根分明、发丝细腻渲染 | +| 造型 | 自然散发、中分/偏分、无发饰 | 长发自然散落、青丝如瀑 | + +### 男性 + +| 项目 | 约束 | 提示词 | +|---|---|---| +| 发色 | 纯黑或墨色 | 墨发、黑发如墨 | +| 发长 | 中长至长发 | 长发、及肩长发 | +| 发质 | 根根分明、质感清晰 | 发丝根根分明、发丝细腻渲染 | +| 造型 | 自然散发或半束、无发冠 | 长发自然散落、半束长发 | + +--- + +## 六、基础中衣约束 + +> 白色交领中衣(古风内搭),完整覆盖身体。正式服饰在服化衍生环节叠加。 + +### 女性中衣 + +| 项目 | 约束 | 提示词 | +|---|---|---| +| 款式 | 交领右衽、宽袖及腕、衣长及足面 | 白色交领中衣、素白长衣 | +| 面料 | 素白棉麻、轻薄不透、自然垂坠 | 棉麻质感、布料垂坠 | +| 领口 | 交领V字、锁骨微露、端庄 | 交领、锁骨微露 | +| 色彩 | 纯素白 #F8F6F0、无纹样 | 素白无纹样 | + +### 男性中衣 + +| 项目 | 约束 | 提示词 | +|---|---|---| +| 款式 | 交领右衽、窄袖/直袖、衣长过膝 | 白色交领中衣、素白长衫 | +| 面料 | 素白棉麻、挺括自然 | 棉麻质感、素白面料 | +| 领口 | 交领、端正大方 | 交领、领口端正 | +| 色彩 | 纯素白 #F8F6F0、无纹样 | 素白无纹样 | + +### 着装统一规则 + +- 纯素白无纹样,确保后续服饰叠加无色彩干扰 +- 除面部/手部/颈部外完全覆盖 +- 四视图中衣款式完全一致 +- 中衣仅为安全打底,焦点在面容与体态 + +--- + +## 七、四视图设定图规范 + +### 视图定义 + +| 位置 | 视图 | 角度 | 景别 | 要求 | 提示词 | +|---|---|---|---|---|---| +| 左一 | 人像特写 | 正面平视 | 面部至锁骨 | 面部占60%+,五官清晰 | portrait closeup、face detail | +| 左二 | 正视图 | 正面 0° | 全身立像 | 面对镜头、双臂自然 | front view | +| 右二 | 侧视图 | 右侧 90° | 全身立像 | 纯侧面轮廓清晰 | side view、profile | +| 右一 | 后视图 | 后方 180° | 全身立像 | 后脑/背部/发尾清晰 | back view、rear view | + +### 画面规范 + +| 项目 | 约束 | +|---|---| +| 布局 | 同一画面从左至右并排四视图 | +| 背景 | 纯净中性灰 #E8E8E8 | +| 站姿 | 自然站立、双脚平行微分、双臂自然下垂或微展 | +| 表情 | 中性微表情,符合角色气质 | +| 光线 | 均匀柔光,前方主光 + 双侧补光,无硬阴影 | +| 一致性 | 四视图的肤色/体型/发型/面容/中衣完全一致 | +| 画面比例 | 建议 4:1 或 3:1 | + +--- + +## 八、提示词模板 + +``` +{性别}角色四视图设定图,真人写实摄影,超现实主义纪实,强对比度,极致细节, +character design sheet,character turnaround, +{脸型},{眼型},{鼻型},{唇型},{整体气质},素颜无妆, +{肤色},水光肌,皮肤通透发光,皮肤细腻,毛孔微可见, +{身材描述},{体态描述}, +{发色}{发长},发丝根根分明,{基础造型},无发饰, +身着白色交领右衽中衣,素白无纹样,布带束腰,端庄得体, +同一画面左至右并排:人像特写+正视图+侧视图+后视图, +自然站立,纯净中性灰背景,均匀柔光,无硬阴影, +四视图一致性,面容细腻渲染,发丝细腻渲染 +``` + +--- + +## 九、约束规则 + +### 必守 + +| 编号 | 规则 | +|---|---| +| R1 | 必须为「素颜无妆」状态 | +| R2 | 必须声明「白色交领中衣」 | +| R3 | 必须声明「无发饰、无配饰」 | +| R4 | 必须指定「纯净中性灰背景」 | +| R5 | 必须指定「四视图一致性」 | + +### 严禁 + +| 编号 | 严禁 | +|---|---| +| X1 | 中衣以外的任何服装/配饰/妆容 | +| X2 | 正顶硬光/正底光/彩色光 | +| X3 | 过度美白至无血色 / 肤色发灰 | +| X4 | 复杂场景背景(必须纯灰底) | +| X5 | 夸张表情/动态姿势 | + + diff --git a/data/skills/art_prompts/chinese_sweet_romance/art_prompt/art_character_derivative.md b/data/skills/art_prompts/chinese_sweet_romance/art_prompt/art_character_derivative.md new file mode 100644 index 0000000..fb03860 --- /dev/null +++ b/data/skills/art_prompts/chinese_sweet_romance/art_prompt/art_character_derivative.md @@ -0,0 +1,218 @@ +# 人物衍生资产生成 · 约束手册 + +--- + +## 一、叠加原则 + +1. **面容不变** — 叠加后五官必须与底模完全一致,禁止面容偏移 +2. **逐层可控** — 每层独立描述,便于按层替换(换装不换妆) +3. **风格统一** — 所有服化元素服从同一美学体系 +4. **质感不降** — 叠加后质感标准不低于底模 + +--- + +## 二、叠加层级 + +| 层级 | 内容 | 说明 | +|---|---|---| +| L0 | 底模 | 基础形象底模,不修改 | +| L1 | 妆容 | 底妆 + 眉/眼/唇/腮红 | +| L2 | 发型造型 | 发髻/束发/编发 + 发饰 | +| L3 | 中衣/内搭 | 替换白色基础中衣 | +| L4 | 外衣/主服 | 大袖衫/直裾/大氅等 | +| L5 | 配饰 | 头饰/耳饰/项饰/腰饰/手饰 | + +--- + +## 三、妆容约束(L1) + +### 女性妆容风格矩阵 + +| 风格 | 适用场景 | 核心提示词 | +|---|---|---| +| 清雅素妆 | 日常、初遇、闺中 | 妆容清雅、淡扫蛾眉、素妆清颜 | +| 冷艳霜妆 | 正式、对峙、权力 | 妆容冷艳、眉眼锋利、薄唇冷冽 | +| 柔媚桃妆 | 甜宠、暧昧、心动 | 桃花妆、眼尾微红、唇色水润 | +| 病弱梨妆 | 受伤、虚弱 | 面色苍白、唇色极淡、眼下微红 | +| 华贵凤妆 | 大婚、盛装 | 浓妆华美、朱唇凤眼 | + +### 通用底肤(所有妆容共享) + +| 项目 | 约束 | 提示词 | +|---|---|---| +| 质感 | 水光肌、自然透亮 | 水光肌、奶油瓷肌、luminous skin | +| 白度 | 冷白皮、通透不惨白 | 牛奶肌、milky white skin | +| 内透光 | 从内向外柔光感 | 内透光感、皮肤通透发光 | +| 禁止 | 哑光/死白/蜡感/油光/过曝 | — | + +### 分部位(以清雅素妆为例) + +| 部位 | 约束 | 提示词 | +|---|---|---| +| 底妆 | 轻薄通透、水光微光泽 | 底妆轻薄、水光奶油肌 | +| 眉妆 | 远山眉/柳叶眉、灰棕淡扫 | 远山黛眉、淡扫蛾眉 | +| 眼妆 | 极淡眼影、内眼线、睫毛纤长 | 眼妆清透、睫毛纤长 | +| 腮红 | 极淡薄粉、苹果肌微扫 | 腮红极淡、薄粉微醺 | +| 唇妆 | 水润浅粉、微光泽 | 唇色水润浅粉 | + +### 男性妆容 + +| 项目 | 约束 | 提示词 | +|---|---|---| +| 底肤 | 水光奶油肌、白皙透亮、清爽自然 | 水光肌、奶油肌、luminous skin | +| 原则 | 伪素颜——看着没化妆但皮肤极好 | 伪素颜、天生好皮 | +| 眉毛 | 自然浓眉、不画眉 | 剑眉自然、眉形英挺 | +| 唇色 | 自然血色、微润 | 唇色自然、血色感 | + +--- + +## 四、发型造型约束(L2) + +### 女性造型类型 + +| 造型 | 描述 | 适用 | 提示词 | +|---|---|---|---| +| 半挽云髻 | 发顶挽髻+后方垂发 | 日常、出行 | 半挽云髻、青丝半绾 | +| 飞仙髻 | 高髻飞挑、飘逸 | 仙境、亮相 | 飞仙髻、高髻飞挑 | +| 堕马髻 | 侧偏低髻、慵懒 | 私密、暧昧 | 堕马髻、慵懒侧髻 | +| 双环髻 | 双髻对称、少女 | 年轻角色 | 双环髻、少女双髻 | +| 全散发 | 长发全散、配简单发饰 | 受伤、落魄 | 长发散落、青丝如瀑 | +| 束发马尾 | 高束干练 | 习武、行动 | 束发高马尾、干练利落 | + +### 女性发饰 + +| 项目 | 约束 | 提示词 | +|---|---|---| +| 风格 | 极繁主义,与服饰配套 | 极繁主义发饰、华美精致 | +| 材质 | 金属 + 珠玉 + 流苏 | 金丝流苏、珠翠满头 | +| 工艺 | 大师工艺、超精细 | 大师工艺、精雕细琢 | + +### 男性造型类型 + +| 造型 | 适用 | 提示词 | +|---|---|---| +| 束发半冠 | 日常、文人 | 束发半冠、玉簪束发 | +| 全冠高束 | 正式、朝堂 | 全冠高束、玉冠束发 | +| 散发披肩 | 私密、受伤 | 散发披肩、长发如墨 | +| 战束马尾 | 战斗、习武 | 高束战发、马尾利落 | + +--- + +## 五、服饰约束(L3+L4) + +### 女性服饰矩阵 + +| 风格 | 款式 | 适用 | 提示词 | +|---|---|---|---| +| 仙气飘逸装 | 多层大袖衫、魏晋制 | 日常、仙境 | 大袖衫、多层衣衫、衣料飘逸 | +| 端庄礼服 | 曲裾深衣/襦裙 | 朝堂、宴会 | 曲裾深衣、端庄华美 | +| 轻便常服 | 窄袖襦裙/短衫 | 行动、习武 | 窄袖短衫、轻便利落 | +| 寝衣 | 薄纱内衫、素色 | 室内、夜间 | 素色寝衣、宽松舒适 | +| 大婚嫁衣 | 凤冠霞帔、层叠红装 | 婚礼 | 凤冠霞帔、层叠红裳 | + +### 女性服饰通用约束 + +| 项目 | 约束 | 提示词 | +|---|---|---| +| 主色 | 白色/月白/银灰为默认 | 白色精致衣服、素衣如雪 | +| 材质 | 厚实飘逸 + 刺绣 + 珠光面料 | 衣料厚实飘逸、珠光刺绣 | +| 质感 | 纹理必须超清晰 | 衣服质感清晰、纹理超清晰 | +| 肩部 | 肩饰/披帛/云肩 | 云肩华美、肩头有装饰 | +| 层次 | 多层叠穿、层次分明 | 多层叠穿、层次分明 | + +### 男性服饰矩阵 + +| 风格 | 适用 | 提示词 | +|---|---|---| +| 文人雅装 | 日常、书房 | 宽袖长衫、月白衣衫 | +| 武将劲装 | 战斗、练武 | 窄袖劲装、深色战服 | +| 玄衣大氅 | 出场、夜行 | 墨色大氅、披风猎猎 | +| 常服便装 | 休闲、私密 | 素色常服、简约便装 | +| 礼服朝服 | 朝堂、典礼 | 正式朝服、华贵礼袍 | + +--- + +## 六、配饰约束(L5) + +### 女性配饰 + +| 类型 | 约束 | 提示词 | +|---|---|---| +| 头饰 | 极繁主义、不单薄 | 极繁主义头饰、珠翠满头 | +| 耳饰 | 垂坠流苏/玉珰 | 流苏耳环、玉珰垂坠 | +| 项饰 | 璎珞/项圈 | 璎珞华美、精致项圈 | +| 腰饰 | 宫绦/玉佩 | 宫绦飘逸、腰间玉佩 | +| 手饰 | 玉镯/臂钏 | 玉镯通透、臂钏精致 | + +### 男性配饰 + +| 类型 | 约束 | 提示词 | +|---|---|---| +| 发冠 | 玉冠/金冠、精致 | 玉冠束发 | +| 腰封 | 宽腰封/革带 | 宽腰封、质感分明 | +| 玉佩 | 通透温润 | 腰间玉佩 | +| 兵器 | 佩剑/扇/笛(可选) | 长剑在侧、折扇半掩 | + +--- + +## 七、服化组合速查 + +| 场景 | 妆容 | 发型 | 服饰 | 配饰 | +|---|---|---|---|---| +| 日常闺中 | 清雅素妆 | 半挽云髻 | 仙气飘逸装 | 中等 | +| 初次相遇 | 清雅素妆 | 半挽/飞仙 | 仙气飘逸装 | 中偏多 | +| 甜宠互动 | 柔媚桃妆 | 半挽/堕马 | 仙气/轻便 | 中等 | +| 正式亮相 | 冷艳霜妆 | 飞仙髻 | 端庄礼服 | 极繁 | +| 夜间密谈 | 清雅/桃妆 | 全散/堕马 | 寝衣 | 极简 | +| 受伤落魄 | 病弱梨妆 | 全散(乱) | 破损常服 | 极简/无 | +| 大婚典礼 | 华贵凤妆 | 飞仙髻 | 嫁衣 | 极繁 | +| 习武行动 | 素妆(极淡) | 束发马尾 | 轻便常服 | 简 | + +--- + +## 八、提示词模板 + +### 完整服化叠加 + +``` +以角色基础形象图为底图,img2img叠加服化妆造, +古风{性别}角色,真人写实摄影,超现实主义纪实,强对比度,极致细节, +保持基础形象面容不变,{整体气质}, +【L1·妆容】{妆容风格},水光奶油瓷肌,{眉妆},{眼妆},{唇妆}, +【L2·发型】{造型类型},发丝根根分明,{发饰描述}, +【L3+L4·服饰】{主色}{款式},{材质},{装饰工艺},衣服质感清晰,纹理超清晰, +【L5·配饰】{头饰},{耳饰},{项饰},{腰饰}, +面容细腻渲染,发丝细腻渲染,纹理细节超清晰 +``` + +### 单层替换 + +``` +以已有角色图为底图,img2img仅替换{目标层级}, +保持其余层级不变, +【替换层·{层级}】{详细描述}, +面容不变,纹理细节超清晰 +``` + +--- + +## 九、约束规则 + +### 必守 + +| 编号 | 规则 | +|---|---| +| R1 | 叠加后面容必须与底模一致 | +| R2 | 服饰必须用「衣服质感清晰 + 纹理超清晰」 | +| R3 | 女性配饰必须「极繁主义 + 大师工艺」 | +| R4 | 妆容/发型/服饰/配饰风格统一 | + +### 严禁 + +| 编号 | 严禁 | +|---|---| +| X1 | 叠加后面容偏移 | +| X2 | 配饰过于简单/现代化(女性) | +| X3 | 妆容/服饰风格互相冲突 | + + diff --git a/data/skills/art_prompts/chinese_sweet_romance/art_prompt/art_prop.md b/data/skills/art_prompts/chinese_sweet_romance/art_prompt/art_prop.md new file mode 100644 index 0000000..5dc945a --- /dev/null +++ b/data/skills/art_prompts/chinese_sweet_romance/art_prompt/art_prop.md @@ -0,0 +1,122 @@ +# 道具图像生成 · 约束手册 + +--- + +## 一、道具设计原则 + +1. **功能可读** — 道具用途一目了然,造型服务于功能 +2. **质感极致** — 材质纹理必须清晰可辨(金属/玉石/木/布/纸) +3. **年代一致** — 所有道具必须符合古风世界观,禁止现代元素 +4. **尺度明确** — 通过参照物或标注暗示道具真实尺寸 + +--- + +## 二、道具分类与美学约束 + +### 2.1 兵器类 + +| 项目 | 约束 | 提示词 | +|---|---|---| +| 类型 | 剑/刀/弓/枪/扇 | {兵器类型},古风兵器 | +| 材质 | 精钢/玄铁 + 宝石镶嵌 + 丝绸剑穗 | 寒光凛冽、精钢锻造 | +| 装饰 | 剑鞘/刀柄雕花、流苏、暗纹 | 雕花精致、流苏垂坠 | +| 光泽 | 金属冷光泽、刃口反光 | 寒光闪烁、金属质感 | +| 提示词 | 古风{兵器},精钢锻造,寒光凛冽,雕花精致 | — | + +### 2.2 饰品类 + +| 项目 | 约束 | 提示词 | +|---|---|---| +| 类型 | 簪/钗/璎珞/玉佩/手镯/耳坠 | {饰品类型},古风首饰 | +| 材质 | 金/银/玉/珍珠/宝石 | 金丝编织、玉质通透 | +| 工艺 | 极致精细、花丝/掐丝/镶嵌 | 大师工艺、精雕细琢 | +| 光泽 | 珠光/玉润/金属光泽 | 珠光莹润、金属光泽 | +| 提示词 | 古风{饰品},{材质},大师工艺,精雕细琢 | — | + +### 2.3 生活器物类 + +| 项目 | 约束 | 提示词 | +|---|---|---| +| 类型 | 茶具/酒具/香炉/棋盘/书卷/灯笼 | {器物类型},古风器物 | +| 材质 | 瓷/铜/竹/木/纸 | 青瓷温润、紫铜古朴 | +| 质感 | 釉面/木纹/竹节清晰 | 釉面光泽、木纹清晰 | +| 风格 | 素雅/华贵按场景切换 | 素雅古朴 / 华贵精致 | +| 提示词 | 古风{器物},{材质}质感,纹理清晰 | — | + +### 2.4 信物/关键道具类 + +| 项目 | 约束 | 提示词 | +|---|---|---| +| 类型 | 信物/令牌/卷轴/药瓶/玉印 | {道具类型},古风道具 | +| 特殊性 | 需有辨识度、叙事象征意义 | 独特造型、寓意深远 | +| 做旧感 | 可按剧情需要添加年代感 | 古旧斑驳 / 崭新精致 | +| 提示词 | 古风{道具},{材质},{状态},独特造型 | — | + +--- + +## 三、多角度设定图规范 + +### 视图定义 + +| 位置 | 视图 | 角度 | 要求 | 提示词 | +|---|---|---|---|---| +| 左 | 正面图 | 正面 0° | 道具完整正面形态 | front view | +| 中 | 侧面图 | 侧面 90° | 厚度/轮廓/结构清晰 | side view | +| 右 | 细节特写 | 局部放大 | 材质纹理/工艺细节 | detail closeup | + +### 画面规范 + +| 项目 | 约束 | +|---|---| +| 布局 | 同一画面三视图并排 | +| 背景 | 纯净中性灰 #E8E8E8 | +| 光线 | 均匀柔光,无硬阴影 | +| 比例 | 道具占画面主体 70%+ | +| 投影 | 允许自然地面微投影 | +| 画面比例 | 建议 3:1 | + +--- + +## 四、材质渲染约束 + +| 材质 | 渲染要求 | 提示词 | +|---|---|---| +| 金属 | 反光/高光/冷光泽、划痕微可见 | 金属质感、冷光泽、反光清晰 | +| 玉石 | 内透光、温润、微通透 | 玉质通透、温润如脂 | +| 木质 | 木纹清晰、年轮可见 | 木纹清晰、质感温润 | +| 瓷器 | 釉面光泽、色泽均匀 | 釉面光泽、瓷质温润 | +| 布/纸 | 纤维质感、边缘自然 | 布料纹理、纸质古朴 | +| 宝石 | 折射/内部光线、切面清晰 | 宝石璀璨、光芒折射 | + +--- + +## 五、提示词模板 + +``` +古风道具设定图,真人写实摄影风格,超现实主义纪实,强对比度,极致细节, +{道具类型},{材质描述},{工艺/装饰描述},{状态描述}, +同一画面三视图:正面图+侧面图+细节特写, +纯净中性灰背景,均匀柔光,无硬阴影, +材质纹理超清晰,质感写实,{材质光泽描述} +``` + +--- + +## 六、约束规则 + +### 必守 + +| 编号 | 规则 | +|---|---| +| R1 | 必须指定「纯净中性灰背景」 | +| R2 | 必须明确道具材质与工艺 | +| R3 | 道具造型必须符合古风世界观 | + +### 严禁 + +| 编号 | 严禁 | +|---|---| +| X1 | 复杂场景背景 | +| X2 | 道具与人物同画面(本环节为纯道具图) | + + diff --git a/data/skills/art_prompts/chinese_sweet_romance/art_prompt/art_prop_derivative.md b/data/skills/art_prompts/chinese_sweet_romance/art_prompt/art_prop_derivative.md new file mode 100644 index 0000000..e970f06 --- /dev/null +++ b/data/skills/art_prompts/chinese_sweet_romance/art_prompt/art_prop_derivative.md @@ -0,0 +1,120 @@ +# 道具衍生状态生成 · 约束手册 + +--- + +## 一、衍生原则 + +1. **造型锚定** — 道具核心造型/轮廓在所有状态中可识别 +2. **状态可读** — 状态差异必须一目了然,观众能立即区分 +3. **叙事服务** — 每种状态变体服务于特定剧情节点 +4. **渐进退化** — 损伤/老化状态应有合理的物理逻辑 + +--- + +## 二、状态类型 + +### 2.1 使用状态 + +| 状态 | 描述 | 适用道具 | 提示词 | +|---|---|---|---| +| 崭新 | 完好无损、光泽如新 | 所有道具 | 崭新、完好无损、光泽如新 | +| 日常使用 | 微磨损、自然包浆 | 兵器/器物/饰品 | 日常使用痕迹、自然包浆 | +| 陈旧 | 明显年代感、色泽暗淡 | 器物/信物/卷轴 | 古旧斑驳、年代感、色泽暗沉 | + +### 2.2 损伤状态 + +| 状态 | 描述 | 适用道具 | 提示词 | +|---|---|---|---| +| 微损 | 小裂纹/小缺口/轻微磨损 | 瓷器/玉佩/兵器 | 细微裂纹、轻微缺口 | +| 破损 | 明显裂缝/断裂/破碎 | 瓷器/饰品/兵器 | 裂缝明显、碎裂、断裂 | +| 残片 | 仅剩部分/碎片 | 瓷器/玉佩/信物 | 残片、碎片、仅存半块 | + +### 2.3 特殊状态 + +| 状态 | 描述 | 适用道具 | 提示词 | +|---|---|---|---| +| 染血 | 血迹附着 | 兵器/衣物/信物 | 血迹斑驳、染血 | +| 浸水/湿润 | 水渍、湿润反光 | 卷轴/信物/衣物 | 浸水、纸张湿润、墨迹晕染 | +| 燃烧/焦损 | 焦黑边缘、火烧痕迹 | 卷轴/信物/木质品 | 边缘焦黑、火烧痕迹 | +| 发光/激活 | 内在能量、光芒四射 | 信物/法器/玉石 | 微微发光、内蕴光华 | +| 包裹/封存 | 用布/盒子包裹 | 信物/饰品/秘物 | 锦布包裹、木盒封存 | + +--- + +## 三、状态变体画面规范 + +### 单状态图 + +| 项目 | 约束 | +|---|---| +| 背景 | 纯净中性灰 #E8E8E8(与设定图一致) | +| 光线 | 均匀照明,无硬阴影 | +| 角度 | 与原设定图正面图一致 | +| 比例 | 道具占画面主体 70%+ | + +### 状态对比图 + +| 项目 | 约束 | +|---|---| +| 布局 | 同一画面并排展示 2-3 种状态 | +| 标注 | 每种状态下方标注状态名 | +| 一致性 | 角度/光线/背景完全一致,仅状态不同 | + +--- + +## 四、材质状态变化规则 + +| 材质 | 崭新 → 日常 | 日常 → 陈旧 | 损伤表现 | +|---|---|---|---| +| 金属 | 亮光泽 → 微包浆 | 包浆 → 锈蚀斑点 | 缺口/卷刃/断裂 | +| 玉石 | 通透温润 → 微磨损 | 磨损 → 表面微裂 | 裂纹/碎裂/缺角 | +| 木质 | 新木纹理 → 自然包浆 | 包浆 → 色泽暗沉 | 开裂/断裂/虫蛀 | +| 瓷器 | 釉面光泽 → 微划痕 | 划痕 → 釉面暗淡 | 裂纹/碎裂/缺口 | +| 布/纸 | 崭新平整 → 微皱折 | 皱折 → 发黄变脆 | 撕裂/焦损/墨迹晕染 | + +--- + +## 五、提示词模板 + +### 单状态变体 + +``` +基于{道具名}设定图,真人写实摄影风格,超现实主义纪实,强对比度,极致细节, +{道具类型},{材质描述}, +当前状态:{状态名},{状态视觉描述}, +{材质表面变化描述}, +纯净中性灰背景,均匀柔光, +材质纹理超清晰,状态细节可辨 +``` + +### 状态对比图 + +``` +{道具名}状态对比图,真人写实摄影风格,超现实主义纪实, +同一画面并排展示:{状态A} + {状态B} + {状态C}, +角度/光线/背景一致,仅状态不同, +{每种状态的简要描述}, +纯净中性灰背景,均匀柔光,材质纹理超清晰 +``` + +--- + +## 六、约束规则 + +### 必守 + +| 编号 | 规则 | +|---|---| +| R1 | 道具核心造型/轮廓在所有状态中可识别 | +| R2 | 状态变化须符合物理逻辑 | +| R3 | 对比图中角度/光线/背景一致 | + +### 严禁 + +| 编号 | 严禁 | +|---|---| +| X1 | 状态变化后道具不可识别 | +| X2 | 违反物理逻辑的损伤(玉石生锈等) | +| X3 | 过度血腥/恐怖的损伤描绘 | + + diff --git a/data/skills/art_prompts/chinese_sweet_romance/art_prompt/art_scene.md b/data/skills/art_prompts/chinese_sweet_romance/art_prompt/art_scene.md new file mode 100644 index 0000000..a848b28 --- /dev/null +++ b/data/skills/art_prompts/chinese_sweet_romance/art_prompt/art_scene.md @@ -0,0 +1,104 @@ +# 场景图生成 · 约束手册 + +--- + +## 一、场景美学原则 + +1. **空间叙事** — 场景承载情绪与叙事功能,不是纯背景板 +2. **层次纵深** — 所有场景必须具备前/中/后景,杜绝扁平 +3. **质感至上** — 木纹/石质/布料/水面等材质纹理必须超清晰 + +--- + +## 二、季节色调映射 + +| 季节 | 主色调 | 辅色调 | 提示词 | +|---|---|---|---| +| 春 | 青翠 + 桃粉 | 月白、鹅黄 | 春色青翠、桃花灼灼 | +| 夏 | 碧绿 + 荷粉 | 天青、莲白 | 夏荷碧绿、浓荫蔽日 | +| 秋 | 赤红 + 金黄 | 琥珀、暮灰 | 秋枫赤红、金叶飘零 | +| 冬 | 素白 + 霜银 | 墨玉黑、冰蓝 | 冬雪素白、枯枝霜挂 | + +--- + +## 三、室内场景 + +### 空间规范 + +| 维度 | 约束 | 提示词 | +|---|---|---| +| 风格 | 古代宅邸/宫殿/书房/闺阁,魏晋至唐宋 | 古代{朝代}风格 | +| 材质 | 木质为主、石/玉/绢/纱为辅 | 檀木家具、玉石屏风、绢纱帷幔 | +| 色调 | 低饱和暖木色 + 月白纱幔 + 青瓷 | 暖木色调、素雅陈设 | +| 纵深 | 前/中/后景层次 | 前景{元素}、中景{元素}、后景{元素} | +| 质感 | 木纹/布料垂感/瓷器光泽可辨 | 纹理清晰、质感写实 | + +### 室内类型速查 + +| 类型 | 核心元素 | 氛围词 | +|---|---|---| +| 闺阁/卧房 | 纱帐、梳妆台、铜镜、花瓶 | 温馨私密、纱幔轻垂 | +| 书房/书斋 | 书架、卷轴、笔墨、棋盘 | 幽静雅致、墨香四溢 | +| 大殿/正厅 | 高柱、匾额、帷幕、烛台 | 庄严华美、气势恢宏 | +| 庭院回廊 | 廊柱、石栏、花木、灯笼 | 曲径通幽、灯影摇曳 | +| 厨房/膳堂 | 灶台、蒸笼、食器 | 烟火气息、温馨日常 | + +--- + +## 四、室外场景 + +### 空间规范 + +| 维度 | 约束 | 提示词 | +|---|---|---| +| 类型 | 庭院/山林/溪畔/古桥/集市 | {场景},{季节},{时间} | +| 天候 | 晴/阴/薄雾/细雨/飞雪 | 薄雾弥漫、细雨如丝 | +| 植被 | 梅/竹/松/桃花/柳/荷(须符合季节) | 桃花灼灼、翠竹成林 | +| 水体 | 溪/湖/瀑布需有光影反射 | 溪水潺潺、湖面如镜 | +| 建筑 | 飞檐斗拱、青瓦白墙、石桥木亭 | 飞檐翘角、石拱桥 | +| 空气感 | 必须有空气透视,远处偏灰偏蓝 | 远山如黛、空气透视 | + +### 室外类型速查 + +| 类型 | 核心元素 | 氛围词 | +|---|---|---| +| 庭院花园 | 假山、池塘、花木、石径 | 花影扶疏、曲径通幽 | +| 山林竹海 | 古木、竹林、山石、云雾 | 层峦叠嶂、云雾缥缈 | +| 溪畔湖边 | 溪流、卵石、垂柳、荷花 | 溪水潺潺、柳影婆娑 | +| 古桥长亭 | 石拱桥、长亭、柳树 | 长亭古道、杨柳依依 | +| 集市街道 | 酒旗、摊贩、灯笼 | 热闹市井、烟火人间 | +| 屋顶天台 | 瓦片、飞檐、夜空 | 月下独酌、清风徐来 | + +--- + +## 五、提示词模板 + +``` +古风场景,真人写实摄影风格,超现实主义纪实,强对比度,极致细节, +{室内/室外},{场景类型},{朝代风格},{季节+时间}, +前景:{元素},中景:{元素},后景:{元素}, +{色调描述},{天候/氛围元素}, +{材质描述},空气透视,纹理细节超清晰 +``` + +--- + +## 六、约束规则 + +### 必守 + +| 编号 | 规则 | +|---|---| +| R1 | 场景必须有「前中后景层次」 | +| R2 | 室外必须包含「空气透视」 | + +### 严禁 + +| 编号 | 严禁 | +|---|---| +| X1 | 背景纯白/纯黑/无场景 | +| X2 | 极端天候(暴风雨/雷电/暴雪,除非剧情需要) | +| X3 | 场景无纵深/无层次 | +| X4 | 植被/天候与季节矛盾 | + + diff --git a/data/skills/art_prompts/chinese_sweet_romance/art_prompt/art_scene_derivative.md b/data/skills/art_prompts/chinese_sweet_romance/art_prompt/art_scene_derivative.md new file mode 100644 index 0000000..9c1ae47 --- /dev/null +++ b/data/skills/art_prompts/chinese_sweet_romance/art_prompt/art_scene_derivative.md @@ -0,0 +1,132 @@ +# 场景衍生资产生成 · 约束手册 + +--- + +## 一、衍生原则 + +1. **空间一致** — 建筑结构/布局/材质在所有变体中保持一致 +2. **景别驱动** — 同一场景通过不同景别展示不同叙事功能 +3. **时段切换** — 同一空间在不同时间段呈现不同光影氛围 +4. **天候变化** — 同一空间在不同天气下呈现不同情绪 + +--- + +## 二、景别变体 + +### 景别定义 + +| 景别 | 范围 | 叙事功能 | 提示词 | +|---|---|---|---| +| 大全景 | 场景全貌 + 周围环境 | 建立空间感、定位 | extreme wide shot、大全景 | +| 全景 | 场景完整呈现 | 展示空间结构 | wide shot、全景 | +| 中景 | 场景局部区域 | 聚焦功能区 | medium shot、中景 | +| 近景 | 场景细部 | 材质/氛围道具特写 | close shot、近景 | +| 特写 | 极局部细节 | 材质纹理/关键道具 | extreme closeup、特写 | + +### 景别衍生规范 + +| 从基准图衍生 | 保持不变 | 允许变化 | +|---|---|---| +| 大全景 → 全景 | 建筑外观、整体布局 | 视角收窄、前景增加 | +| 全景 → 中景 | 材质、色调、光线 | 裁切聚焦、景深变化 | +| 中景 → 近景 | 材质、色调 | 景深浅、背景虚化 | +| 近景 → 特写 | 材质纹理 | 极浅景深、微距感 | + +--- + +## 三、时段变体 + +### 时段定义 + +| 时段 | 视觉特征 | 提示词 | +|---|---|---| +| 清晨 | 薄雾柔光、色调偏冷暖交织 | 晨光微熹、清晨薄雾 | +| 正午 | 明亮、阴影短、色彩鲜明 | 正午阳光、光线明亮 | +| 黄昏 | 金色色调、长影、天空渐变 | 暮色金辉、golden hour | +| 夜间(月光) | 冷蓝色调、幽静清冷 | 月光清辉、moonlight | +| 夜间(灯火) | 暖黄点缀、明暗对比 | 灯火阑珊、烛光点点 | + +### 时段衍生规范 + +| 从基准时段衍生 | 保持不变 | 变化项 | +|---|---|---| +| 日间 → 黄昏 | 建筑/布局/材质 | 天空色调暖化、影子拉长 | +| 日间 → 夜间 | 建筑/布局/材质 | 整体变暗、增加灯火/月色氛围 | +| 室内日间 → 室内夜间 | 空间结构、家具 | 整体色调暖化、增加烛火/灯笼元素 | + +--- + +## 四、天候变体 + +### 天候定义 + +| 天候 | 视觉特征 | 提示词 | +|---|---|---| +| 晴天 | 明亮、阴影清晰 | 晴空万里、阳光明媚 | +| 阴天 | 光线均匀、无硬影 | 阴天柔光、overcast | +| 薄雾 | 能见度降低、空气朦胧 | 薄雾弥漫、雾气缭绕 | +| 细雨 | 水珠、湿润反光、雨丝 | 细雨如丝、雨幕轻纱 | +| 飞雪 | 白色覆盖、雪花飘落 | 飞雪纷纷、银装素裹 | + +### 天候衍生规范 + +| 从基准天候衍生 | 保持不变 | 变化项 | +|---|---|---| +| 晴 → 薄雾 | 建筑/布局 | 增加雾气层、远景模糊、饱和度降低 | +| 晴 → 细雨 | 建筑/布局 | 增加雨丝、地面反光、色调偏冷 | +| 晴 → 飞雪 | 建筑/布局 | 增加积雪、雪花、色调偏白 | +| 植被需随天候逻辑适配 | — | 雨中花瓣湿润、雪中枯枝挂霜 | + +--- + +## 五、提示词模板 + +### 景别变体 + +``` +基于{场景名}概念图,真人写实摄影风格,超现实主义纪实,强对比度,极致细节, +{景别}视角,保持场景空间结构一致, +{前景},{中景},{后景}, +{色调},{景深描述}, +纹理细节超清晰,空气透视 +``` + +### 时段变体 + +``` +基于{场景名}概念图,真人写实摄影风格,超现实主义纪实,强对比度,极致细节, +{时段}时分,保持场景空间结构一致, +{天空色调变化},{氛围调整}, +纹理细节超清晰 +``` + +### 天候变体 + +``` +基于{场景名}概念图,真人写实摄影风格,超现实主义纪实,强对比度,极致细节, +{天候}天气,保持场景空间结构一致, +{天候视觉特征},{色调变化},{材质表面变化}, +{植被适配描述},纹理细节超清晰 +``` + +--- + +## 六、约束规则 + +### 必守 + +| 编号 | 规则 | +|---|---| +| R1 | 场景空间结构在所有变体中保持一致 | +| R2 | 时段变体必须调整天空色调与氛围 | +| R3 | 天候变体必须适配植被/材质表面 | + +### 严禁 + +| 编号 | 严禁 | +|---|---| +| X1 | 变体间建筑结构/布局不一致 | +| X2 | 天候与季节矛盾(夏天飞雪等) | +| X3 | 变体间材质/风格突变 | + + diff --git a/data/skills/art_prompts/chinese_sweet_romance/art_prompt/art_storyboard.md b/data/skills/art_prompts/chinese_sweet_romance/art_prompt/art_storyboard.md new file mode 100644 index 0000000..9e0dcd1 --- /dev/null +++ b/data/skills/art_prompts/chinese_sweet_romance/art_prompt/art_storyboard.md @@ -0,0 +1,164 @@ +# 分镜图生成 · 约束手册 + +--- + +## 一、构图三原则 + +1. **景别即情绪** — 景别选择直接决定观众与角色的心理距离 +2. **角度即态度** — 仰/俯/平视传递权力关系与情感立场 +3. **光影即叙事** — 打光方案必须服务于当前情节的情感基调 + +--- + +## 二、景别规范 + +| 景别 | 画面范围 | 适用场景 | 提示词 | 构图要点 | +|---|---|---|---|---| +| 大特写 | 面部局部(眼/唇/手) | 情绪爆发、关键道具 | 极致特写、微距 | 主体占 80%+,背景全虚 | +| 特写 | 面部至颈部 | 内心独白、情感反应 | 面部特写 | 面部占 60%+,浅景深 | +| 近景 | 胸部以上 | 对话、表情 | 近景、胸部以上 | 三分法偏置,留视线空间 | +| 半身 | 腰部以上 | 人物展示、主视觉 | 半身照 | 人物占 50-70% | +| 全身 | 完整人物 | 服饰全貌、亮相 | 全身照 | 人物占 40-60%,头脚留白 | +| 远景 | 人物 + 大面积环境 | 场景建立、氛围 | 远景、全景 | 人物占 15-30% | + +--- + +## 三、镜头角度 + +| 角度 | 效果 | 适用 | 提示词 | +|---|---|---|---| +| 平视 | 平等、亲近 | 日常、对话 | eye level | +| 微仰 15° | 英气、高贵 | 亮相、权势 | slight low angle | +| 俯视 30° | 柔弱、可怜 | 受伤、示弱 | high angle | +| 侧面 45° | 轮廓美、意境 | 沉思、侧颜 | three-quarter view | +| 正侧 90° | 剪影、轮廓 | 意境、对峙 | profile view | +| 荷兰角 | 不安、冲突 | 打斗、危机 | Dutch angle | + +--- + +## 四、构图法则 + +| 构图 | 适用场景 | +|---|---| +| 中心构图 | 正式亮相、权力感 | +| 三分法 | 对话、情感互动、留白 | +| 对角线 | 动态、追逐、冲突 | +| 框架式 | 偷窥视角、窗前独坐 | +| 引导线 | 走廊/桥/栏杆纵深 | +| 留白式 | 孤独、意境远景 | + +--- + +## 五、情节 × 镜头速查 + +| 情节类型 | 景别 | 角度 | 构图 | +|---|---|---|---| +| 初次相遇 | 全身/半身 | 平视/微仰 | 三分法 | +| 暧昧互动 | 近景/特写 | 平视/俯视 | 中心/三分法 | +| 深情对视 | 特写/大特写 | 平视 | 中心构图 | +| 独自思念 | 半身/远景 | 侧面 45° | 框架/留白 | +| 冲突对峙 | 半身/近景 | 微仰/正侧 | 对角线 | +| 追逐奔跑 | 全身/远景 | 平视/微仰 | 对角线/引导线 | +| 受伤落泪 | 特写/近景 | 俯视 | 中心构图 | +| 大场面亮相 | 全身/远景 | 微仰 | 中心/留白 | +| 隐秘偷看 | 近景/半身 | 平视 | 框架式 | +| 离别远去 | 远景 | 平视/正侧 | 留白/引导线 | + +--- + +## 六、光影方案 + +| 编号 | 方案名 | 核心效果 | 适用场景 | 提示词 | +|---|---|---|---|---| +| A | 珠光柔漫光 | 均匀柔亮、肤感通透 | 日常、对话、甜宠 | soft lighting、pearly glow | +| B | 侧逆光仙气光 | 发丝/衣袂边缘光 | 出场亮相、仙境 | rim light、backlit glow | +| C | 烛光暖影光 | 半明半暗、暖色渐变 | 夜间室内、暧昧 | candlelight、warm side light | +| D | 月光冷辉光 | 冷蓝色调、清冷气氛 | 夜间室外、独处 | moonlight、cold blue light | +| E | 窗纱透光 | 柔和侧光、光影斑驳 | 室内日间、窗前 | window light、filtered daylight | +| F | 天光漫射光 | 无硬阴影、均匀散射 | 远景、雾中场景 | overcast light、diffused daylight | + +### 禁用光型 + +正顶硬光 · 正底光 · 闪光灯直闪 · 彩色霓虹光 · 过度HDR均匀光 · 现代人工光源 + +### 情节 × 光影速查 + +| 情节类型 | 光影方案 | +|---|---| +| 日常甜宠 | A·珠光柔漫光 | +| 仙境/亮相 | B·侧逆光仙气光 | +| 夜间密谈/暧昧 | C·烛光暖影光 | +| 夜间独处/思念 | D·月光冷辉光 | +| 室内日间/窗前 | E·窗纱透光 | +| 远景/雾中 | F·天光漫射光 | + +--- + +## 七、人物速查 + +### 女性核心锚词 + +面容清冷、妩媚狭长眼、五官立体、冷白皮、水光肌、皮肤通透发光、 +黑色长发发丝根根分明、{当前服化方案关键词} + +### 男性核心锚词 + +棱角分明、剑眉星目、清冷俊逸、肤色白皙、皮肤质感细腻、 +墨发束冠、{当前服化方案关键词} + +--- + +## 八、场景速查 + +- 室内:古代{朝代}风格,{材质},{光线},前中后景层次 +- 室外:{场景+季节+时间},{天候},{植被},空气透视 + +--- + +## 九、提示词模板 + +``` +古风写实摄影,超现实主义纪实,强对比度,极致细节,甜宠短剧, +{景别},{角度},{构图}, +{人物名},{面容锚词},{肤感锚词},{表情/情绪}, +{发型},{服饰},{配饰}, +{场景类型},{色调},{氛围元素}, +{动作描述}, +{光影方案}, +面容细腻渲染,发丝细腻渲染,纹理细节超清晰 +``` + +### 示例 + +``` +古风写实摄影,超现实主义纪实,强对比度,极致细节,甜宠短剧, +近景,平视,三分法, +女主,面容清冷、妩媚狭长眼、五官立体,冷白皮、水光肌,微微低头浅笑, +半挽云髻、发丝根根分明,白色大袖衫、珠光刺绣,极繁主义头饰、大师工艺, +庭院花园,春色青翠,桃花灼灼、花瓣飘落, +低头拈花浅笑, +柔和光线、soft lighting, +面容细腻渲染,发丝细腻渲染,纹理细节超清晰 +``` + +--- + +## 十、约束规则 + +### 必守 + +| 编号 | 规则 | +|---|---| +| R1 | 每条必须指定「景别 + 角度」 | +| R2 | 场景必须有「前中后景」或明确纵深描述 | +| R3 | 必须指定光影方案 | + +### 严禁 + +| 编号 | 严禁 | +|---|---| +| X1 | 正顶硬光/正底光/闪光灯直闪 | +| X2 | 背景纯白/纯黑/无场景(除非特殊设定) | +| X3 | 服饰透视/暴露/现代剪裁 | + + diff --git a/data/skills/art_prompts/chinese_sweet_romance/art_prompt/art_storyboard_video.md b/data/skills/art_prompts/chinese_sweet_romance/art_prompt/art_storyboard_video.md new file mode 100644 index 0000000..d027366 --- /dev/null +++ b/data/skills/art_prompts/chinese_sweet_romance/art_prompt/art_storyboard_video.md @@ -0,0 +1,171 @@ +# 分镜视频提示词策略 · 约束手册 + +--- + +## 一、视频生成原则 + +1. **静制动** — 以静态分镜图为锚点,动态描述为增量,防止画面崩坏 +2. **动作克制** — 单镜头内动作幅度小而精,避免大幅度运动导致变形 +3. **运镜叙事** — 摄像机运动服务于情绪,不为炫技 +4. **一致性优先** — 角色面容/服饰在运动中必须保持稳定 + +--- + +## 二、运镜类型 + +| 运镜 | 效果 | 适用场景 | 提示词 | +|---|---|---|---| +| 静止 | 稳定、专注 | 对话、凝视、特写 | static camera、fixed shot | +| 缓推 | 逐渐聚焦、情绪递进 | 心动瞬间、发现 | slow push in、dolly in | +| 缓拉 | 揭示环境、抽离 | 场景建立、离别 | slow pull out、dolly out | +| 横摇 | 跟随、环境展示 | 行走、场景扫视 | pan left/right、horizontal pan | +| 竖摇 | 展示全身、揭示 | 人物亮相、从头到脚 | tilt up/down、vertical pan | +| 跟随 | 伴随人物移动 | 行走、奔跑 | tracking shot、follow | +| 环绕 | 360°展示、戏剧性 | 亮相、对峙 | orbit shot、circular dolly | +| 升降 | 宏大感、力量感 | 大场面、鸟瞰 | crane up/down | + +--- + +## 三、人物动作约束 + +### 安全动作(推荐) + +| 动作类型 | 描述 | 提示词 | +|---|---|---| +| 微表情 | 眨眼、微笑、蹙眉、唇角微动 | subtle expression、微笑、蹙眉 | +| 头部 | 微转头、微低头、抬头 | slight head turn、微低头 | +| 眼神 | 眼神流转、对视、移开视线 | eye movement、眼波流转 | +| 发丝 | 风吹发丝、发丝轻扬 | hair flowing in wind | +| 手部 | 拈花、执扇、抬手、抚琴 | hand gesture、拈花微笑 | +| 衣袂 | 衣袂飘动、袖摆摇曳 | flowing robes、衣袂飘扬 | +| 环境 | 花瓣飘落、烟雾缭绕、水波荡漾 | falling petals、smoke rising | + +### 中等动作(谨慎使用) + +| 动作类型 | 描述 | 提示词 | +|---|---|---| +| 起身/落座 | 缓慢站起、缓慢坐下 | slowly standing、slowly sitting | +| 转身 | 缓慢转身 | slowly turning around | +| 行走 | 缓步行走 | walking slowly、步履轻盈 | +| 饮茶/倒酒 | 缓慢动作 | pouring tea、drinking | + +### 危险动作(尽量避免) + +| 动作类型 | 风险 | 替代方案 | +|---|---|---| +| 奔跑 | 肢体变形 | 用跟随运镜暗示速度 | +| 武打 | 身体崩坏 | 分解为多个静态关键帧 | +| 拥抱 | 双人交叠变形 | 用近景手部/肩部暗示 | +| 骑马 | 复杂运动叠加 | 用特写+环境暗示 | + +--- + +## 四、时长与节奏 + +| 镜头类型 | 建议时长 | 运镜速度 | 说明 | +|---|---|---|---| +| 特写/表情 | 2-3s | 静止或极缓推 | 聚焦微表情变化 | +| 对话近景 | 3-4s | 静止 | 稳定出词,交替切换 | +| 全身亮相 | 3-5s | 缓推/竖摇 | 展示服饰全貌 | +| 远景建立 | 4-6s | 缓拉/横摇 | 环境氛围渲染 | +| 行走跟随 | 3-5s | 跟随 | 匀速、稳定 | +| 转场空镜 | 2-3s | 缓推/静止 | 环境元素特写 | + +--- + +## 五、视频提示词结构 + +### 三层结构 + +视频提示词由三层组成,确保静态画面、动态行为、技术参数分离: + +| 层级 | 内容 | 说明 | +|---|---|---| +| **画面层** | 继承分镜图提示词 | 人物/场景/光影/风格 | +| **动态层** | 动作 + 运镜 + 环境动态 | 运动描述 | +| **参数层** | 时长 + 帧率 + 节奏 | 技术控制 | + +--- + +## 六、提示词模板 + +``` +【画面层·继承分镜】 +古风写实摄影,超现实主义纪实,强对比度,极致细节, +{景别},{角度},{构图}, +{人物描述},{服化描述}, +{场景描述},{光影方案} + +【动态层】 +人物动作:{动作描述} +运镜方式:{运镜类型} +环境动态:{花瓣/烟雾/水波/风等} +面容保持:保持人物面容稳定不变形 + +【参数层】 +时长:{N}秒 +节奏:{缓慢/中等/快速} +画面稳定性:高(优先保持角色一致性) +``` + +### 示例 + +``` +【画面层】 +古风写实摄影,超现实主义纪实,强对比度,极致细节, +近景,平视,三分法, +女主,面容清冷、妩媚狭长眼,冷白皮、水光肌,含羞微笑, +半挽云髻、白色大袖衫、珠光刺绣,极繁主义头饰, +庭院花园,春色青翠,桃花树下,柔和光线 + +【动态层】 +人物动作:微低头浅笑,手指轻拈花瓣 +运镜方式:static camera,极缓推 +环境动态:花瓣缓缓飘落,发丝微扬 +面容保持:面容稳定不变形 + +【参数层】 +时长:3秒 +节奏:缓慢 +画面稳定性:高 +``` + +--- + +## 七、运镜 × 情节速查 + +| 情节类型 | 推荐运镜 | 推荐时长 | 动态要素 | +|---|---|---|---| +| 初次相遇 | 缓推 / 竖摇 | 4-5s | 发丝微扬、衣袂轻动 | +| 暧昧互动 | 静止 / 极缓推 | 3-4s | 微表情、眼神流转 | +| 深情对视 | 静止 | 3s | 微表情、睫毛微颤 | +| 出场亮相 | 竖摇(从下到上) | 4-5s | 衣袂飘动、发饰摇曳 | +| 独自思念 | 缓拉 | 4-5s | 烛光摇曳、纱帘飘动 | +| 离别远去 | 缓拉 | 5-6s | 背影渐远、花瓣飘落 | +| 场景建立 | 横摇 / 缓推 | 4-6s | 雾气、水波、树叶 | + +--- + +## 八、约束规则 + +### 必守 + +| 编号 | 规则 | +|---|---| +| R1 | 必须继承分镜图的完整画面层提示词 | +| R2 | 必须声明「面容保持稳定不变形」 | +| R3 | 必须指定运镜类型和时长 | +| R4 | 单镜头内动作不超过两个 | +| R5 | 优先使用安全动作,危险动作需拆解 | + +### 严禁 + +| 编号 | 严禁 | +|---|---| +| X1 | 单镜头内大幅度复杂动作 | +| X2 | 快速运镜导致画面模糊 | +| X3 | 多人复杂交互动作(拥抱/打斗) | +| X4 | 运镜与情绪基调矛盾 | +| X5 | 时长超过 6 秒的单镜头 | + + diff --git a/data/skills/art_prompts/chinese_sweet_romance/driector_skills/director_planning.md b/data/skills/art_prompts/chinese_sweet_romance/driector_skills/director_planning.md new file mode 100644 index 0000000..c8a24bb --- /dev/null +++ b/data/skills/art_prompts/chinese_sweet_romance/driector_skills/director_planning.md @@ -0,0 +1,70 @@ +# 导演规划 · 古风甜宠写实超现实主义 · 风格技法参考 + +--- + +## 一、主题立意与叙事核心 + +### 风格适配要点 + +- **冷中带暖、疏中见密** — 本风格的情感表达不靠台词铺陈,靠画面留白与微表情。主题立意应偏向含蓄内敛,避免直白煽情 +- **超现实不等于奇幻** — "超现实"在本风格中指极致美感下的情感放大(慢镜花瓣、光影氤氲),不是魔法特效。叙事核心应扎根于人物情感,不依赖奇观 +- **甜宠的克制** — 甜的部分用"差一点就碰到"比"黏在一起"更有效。情感主线应设计"欲说还休"的推拉节奏 +- **离场感受建议方向** — 心疼 / 意难平 / 怦然心动 / 治愈。避免"爽感""热血"等与本风格气质不匹配的方向 + +--- + +## 二、视觉风格与画面基调 + +### 风格适配要点 + +- **色调基底** — 全片以月白(C1)、冷白肤(C2)、青黛(C6)为基底色,整体色温偏冷(5800-7000K),饱和度中低(30-50%),呈现清冷仙气的高级灰调。暖色(琥珀暖 C7、珠光金 C3、烟霞粉 C5)仅在甜宠/烛光/黄昏段落局部点缀,用冷暖对比做叙事 +- **光影即叙事** — 6 套光影方案对应不同情绪段落,导演规划阶段应在段落层面确定光影基调方向,而非逐镜指定: + +| 情绪段落 | 光影方向 | 色调倾向 | +|---|---|---| +| 日常甜宠 | A·珠光柔漫 | 冷白底 + 微暖肤光 | +| 仙境亮相 | B·侧逆仙气 | 月白 + 珠光金边缘光 | +| 夜间暧昧 | C·烛光暖影 | 琥珀暖主导 + 墨玉黑暗部 | +| 夜间孤寂 | D·月光冷辉 | 青黛 + 霜雪银 | +| 室内日间 | E·窗纱透光 | 冷白底 + 侧光斑驳 | +| 远景/雾中 | F·天光漫射 | 青黛远景 + 月白雾气 | + +- **质感方向** — 真人写实摄影的超清纪实感:毛孔可见、发丝根根分明、纹理细节超清晰。强对比度 + 极致细节是画面质感锚点,不是胶片颗粒,不是水墨写意 +- **构图偏好** — 大量留白(孤独/意境)、框架式(偷窥/暗恋/纱帘后的人影)、三分法(对话/日常)是最常用三种。中心构图留给正式亮相和权力场景 +- **镜头运动** — 以静制动为主。缓推/缓拉服务于情绪递进,快切碎剪与本风格气质不兼容 + +--- + +## 三、叙事结构与节奏规划 + +### 风格适配要点 + +- **慢是基本功** — 本风格的画面信息密度高(服化细节、场景质感),需要给观众"看"的时间。整体节奏偏慢,不等于拖沓,而是每个镜头都有信息量 +- **情绪曲线宜缓坡** — 避免"平平平→突然爆发"。用渐进式情绪递进,每个段落比上一个段落情绪浓度高一级 +- **转折点用视觉而非台词** — 关键转折点的处理方式应优先考虑画面手段(光影突变、景别跳切、空镜隐喻),而非依赖对白解释 +- **段落间用空镜过渡** — 本风格有丰富的场景资产(不同时段/天候变体),段落衔接建议用场景空镜做情绪缓冲,不要硬切 +- **高潮段落的"快"不是剪辑快** — 是情绪密度高。可以用更紧密的景别切换(全身→近景→特写→大特写)制造加速感,而非缩短镜头时长 + +--- + +## 四、分场景情绪与画面意图 + +### 风格适配要点 + +- **情绪目标用具象词** — 不说"开心",说"偷偷心动后的嘴角压不住"。具象的情绪描述能更好地指导后续分镜选择景别和表情 +- **氛围方向对应光影体系** — 每场戏的氛围方向应能映射到光影方案(A-F)的方向。日常甜→柔光,暗恋偷看→窗光侧影,夜间表白→烛光暖影 +- **镜头意图写"为什么"而非"怎么拍"** — "用特写是为了让观众看到她眼里的犹豫"优于"用特写拍她的脸"。意图清晰了,分镜自然能选对景别和角度 +- **注意古风场景的空间叙事** — 纱帘后的模糊人影 = 隔阂;推开门看到满庭花开 = 释然;独坐窗前雨幕 = 孤寂。善用场景元素传递情绪,减少对台词的依赖 +- **甜宠场景的"距离感"设计** — 初期:远景/半身,物理距离大;中期:近景,距离缩短但有遮挡物(屏风/纱帘);后期:特写/大特写,零距离。用景别变化映射关系变化 + +--- + +## 五、声音与音乐方向 + +### 风格适配要点 + +- **主导乐器** — 古琴 / 箫 / 笛 适合清冷孤寂段落;琵琶 / 二胡 适合情感激荡段落;弦乐铺底可增加电影感但不宜喧宾夺主 +- **沉默比配乐更有力** — 关键情感瞬间(对视、泪落、转身离去)优先考虑去掉配乐,只留环境音(风声、雨声、衣料摩擦)。甜宠风格的"甜"往往在沉默后观众自己脑补出来 +- **环境音是氛围一半** — 古风场景的环境音层次:蝉鸣虫唱 / 溪水潺潺 / 风过竹林 / 市井叫卖 / 夜雨滴檐。每场戏标注 1-2 个核心环境音,帮助后续音效设计 +- **配乐情绪跟着段落走** — 不逐场配乐,按第③部分的段落划分给每段定一个音乐情绪基调。同段落内场景切换靠环境音变化过渡,不频繁换曲 +- **避免满配** — 全片配乐覆盖率建议不超过 60%。留白段落的"无声"与配乐段落形成呼吸感 diff --git a/data/skills/art_prompts/chinese_sweet_romance/driector_skills/director_storyboard_table.md b/data/skills/art_prompts/chinese_sweet_romance/driector_skills/director_storyboard_table.md new file mode 100644 index 0000000..d8fa743 --- /dev/null +++ b/data/skills/art_prompts/chinese_sweet_romance/driector_skills/director_storyboard_table.md @@ -0,0 +1,57 @@ +# 分镜表设计 · 古风甜宠写实超现实主义 · 风格技法参考 + +--- + +## 一、分镜表定位 + +分镜表是导演将剧本转化为镜头语言的核心工具。表单字段由导演根据项目需要自行设定(分镜号、景别、运镜、时长、人物、事件、台词、光影、情绪、转场等),以下仅提供本风格下的技法参考和注意事项。 + +--- + +## 二、风格适配要点 + +### 景别选择 + +- **甜宠戏的景别递进** — 同场戏内景别应随情感升温递进:半身→近景→特写→大特写。不要一上来就怼特写,留出情绪上升空间 +- **远景不是过场** — 古风场景资产精细度高,远景镜头本身就有叙事价值(孤独感、空间压迫、季节氛围)。给远景足够时长(4-6s),别急着切走 +- **大特写要有理由** — 大特写(眼/唇/手)是情绪核弹,一集用 2-3 次足够。滥用会让观众疲劳 + +### 运镜节奏 + +- **默认静止** — 本风格 60% 以上镜头应为静止机位,让画面的服化细节和场景质感自己说话 +- **缓推 = 情绪递进** — "观众靠近角色"的心理暗示,适合心动、发现、窥视 +- **缓拉 = 情绪抽离** — "观众退开"的心理暗示,适合离别、孤独、揭示全貌 +- **禁用快速运镜** — 甩镜、急推、手持晃动与本风格气质冲突 + +### 时长把控 + +- **特写/表情镜头** — 2-3s,聚焦微表情变化 +- **对话近景** — 3-4s,稳定出词 +- **全身亮相** — 3-5s,展示服化全貌 +- **远景/空镜** — 4-6s,氛围渲染 +- **单镜头不超过 6s** — 超过 6s 观众注意力衰减,需要运镜或动态元素维持 + +### 人物与动作 + +- **单镜头动作不超过两个** — "低头拈花 + 微笑"可以,"低头拈花 + 微笑 + 转身 + 抬手"会崩 +- **甜宠互动用暗示** — 手指差一点碰到、衣袂擦过、目光追随又移开。不要在分镜表里写"拥抱""接吻"等大幅度双人交互,拆成暗示性的局部镜头 +- **古风动作要慢** — 所有人物动作默认慢速。起身、转身、抬手都应标注"缓慢" + +### 台词与留白 + +- **台词少的镜头给长时长** — 无台词的情绪镜头往往比有台词的更需要时间。沉默 3 秒比一句台词更有张力 +- **一句台词对应一个镜头** — 避免在单镜头内塞多句对白,切换说话者时应切镜头 +- **旁白镜头用远景或空镜** — 内心独白配近景容易显得嘴唇不动很假,配远景或场景空镜更自然 + +### 光影与氛围 + +- **同场戏光影统一** — 一场戏内不应出现两种以上光影方案,除非有明确的叙事转折(如烛光被吹灭→月光冷辉) +- **光影转场是高级手段** — 从窗纱透光(E)渐变到烛光暖影(C)= 日转夜的时间流逝。在分镜表中标注光影变化点 +- **环境动态增加画面呼吸感** — 花瓣飘落、烟雾升腾、水波荡漾、纱帘飘动。每 3-4 个镜头至少安排一个有环境动态的镜头,避免画面"死"掉 + +### 转场设计 + +- **默认硬切** — 同场戏内镜头间用硬切,干净利落 +- **场景切换用空镜过渡** — 不同场景间插入 1 个场景空镜(2-3s)做情绪缓冲 +- **段落切换可用叠化/淡入淡出** — 大段落间的情绪跳跃用柔性转场,避免观众出戏 +- **禁用花式转场** — 划屏、旋转、百叶窗等与本风格不兼容 diff --git a/data/skills/art_prompts/chinese_sweet_romance/prefix.md b/data/skills/art_prompts/chinese_sweet_romance/prefix.md new file mode 100644 index 0000000..6398b50 --- /dev/null +++ b/data/skills/art_prompts/chinese_sweet_romance/prefix.md @@ -0,0 +1,65 @@ +# 全局美学基础 · 古风甜宠写实超现实主义 + +--- + +## 一、风格基因 + +| 维度 | 定义 | +|---|---| +| **一级风格** | 古风写实超现实主义(Ancient-Chinese Photorealistic Surrealism) | +| **二级风格** | 真人写实摄影 · 极致细节纪实 | +| **情感基调** | 甜宠向 — 冷中带暖、疏中见密 | +| **质感锚词** | 强对比度、极致细节、超现实主义纪实 | + +--- + +## 二、全局色彩盘 + +| 序号 | 色名 | 色值 | 用途 | +|---|---|---|---| +| C1 | 月白 | #D6E4EC | 主服底色、雾气、纱幔 | +| C2 | 冷白肤 | #F5EDE8 | 女性肤色基准 | +| C2b | 暖白肤 | #F5E6D8 | 男性肤色基准 | +| C3 | 珠光金 | #E8D5B0 | 刺绣、配饰高光、头饰 | +| C4 | 墨玉黑 | #1A1A2E | 发色、眼瞳、描边 | +| C5 | 烟霞粉 | #F2D7D5 | 唇色、腮红、花瓣 | +| C6 | 青黛 | #4A6670 | 远景山水、暗部补色 | +| C7 | 琥珀暖 | #C9A96E | 暖光、烛光、夕照 | +| C8 | 霜雪银 | #C0C7CE | 兵器、水面反光、银饰 | +| C9 | 中性灰 | #E8E8E8 | 设定图背景 | +| C10 | 素白 | #F8F6F0 | 基础中衣色 | + +### 色温约束 + +| 参数 | 值 | 说明 | +|---|---|---| +| 整体色温 | 偏冷 5800-7000K | 清冷仙气 | +| 肤色色温 | 微暖 5200-5600K | 冷白但有生命感 | +| 对比度 | 强 | 明暗反差鲜明 | +| 饱和度 | 中低 30-50% | 高级灰调 | + +--- + +## 三、全局约束规则 + +### 必守规则(所有技能继承) + +| 编号 | 规则 | +|---|---| +| R1 | 必须包含「真人写实摄影」风格锚定词 | +| R2 | 必须声明「强对比度 + 极致细节」 | +| R3 | 面部必须使用「面容细腻渲染 + 皮肤细腻」 | +| R4 | 发丝必须使用「根根分明 + 发丝细腻渲染」 | +| R5 | 纹理必须声明「纹理细节超清晰」 | + +### 严禁项(所有技能继承) + +| 编号 | 严禁内容 | +|---|---| +| X1 | 严禁「卡通/动漫/二次元/插画风」 | +| X2 | 严禁「高饱和荧光色/霓虹色」 | +| X3 | 严禁「现代元素入镜」 | +| X4 | 严禁「面部变形/多指/肢体异常」倾向词 | +| X5 | 严禁「裸体/暴露/透视/暗示性描述」 | + + diff --git a/data/skills/art_prompts/你好/README.md b/data/skills/art_prompts/你好/README.md new file mode 100644 index 0000000..67f98b5 --- /dev/null +++ b/data/skills/art_prompts/你好/README.md @@ -0,0 +1 @@ +1212水电费水电费萨芬的水电费 \ No newline at end of file diff --git a/data/skills/art_prompts/你好/art_prompt/art_character.md b/data/skills/art_prompts/你好/art_prompt/art_character.md new file mode 100644 index 0000000..f73dd74 --- /dev/null +++ b/data/skills/art_prompts/你好/art_prompt/art_character.md @@ -0,0 +1 @@ +1212 \ No newline at end of file diff --git a/data/skills/art_prompts/你好/art_prompt/art_character_derivative.md b/data/skills/art_prompts/你好/art_prompt/art_character_derivative.md new file mode 100644 index 0000000..f73dd74 --- /dev/null +++ b/data/skills/art_prompts/你好/art_prompt/art_character_derivative.md @@ -0,0 +1 @@ +1212 \ No newline at end of file diff --git a/data/skills/art_prompts/你好/art_prompt/art_prop.md b/data/skills/art_prompts/你好/art_prompt/art_prop.md new file mode 100644 index 0000000..f73dd74 --- /dev/null +++ b/data/skills/art_prompts/你好/art_prompt/art_prop.md @@ -0,0 +1 @@ +1212 \ No newline at end of file diff --git a/data/skills/art_prompts/你好/art_prompt/art_prop_derivative.md b/data/skills/art_prompts/你好/art_prompt/art_prop_derivative.md new file mode 100644 index 0000000..f73dd74 --- /dev/null +++ b/data/skills/art_prompts/你好/art_prompt/art_prop_derivative.md @@ -0,0 +1 @@ +1212 \ No newline at end of file diff --git a/data/skills/art_prompts/你好/art_prompt/art_scene.md b/data/skills/art_prompts/你好/art_prompt/art_scene.md new file mode 100644 index 0000000..f73dd74 --- /dev/null +++ b/data/skills/art_prompts/你好/art_prompt/art_scene.md @@ -0,0 +1 @@ +1212 \ No newline at end of file diff --git a/data/skills/art_prompts/你好/art_prompt/art_scene_derivative.md b/data/skills/art_prompts/你好/art_prompt/art_scene_derivative.md new file mode 100644 index 0000000..f73dd74 --- /dev/null +++ b/data/skills/art_prompts/你好/art_prompt/art_scene_derivative.md @@ -0,0 +1 @@ +1212 \ No newline at end of file diff --git a/data/skills/art_prompts/你好/art_prompt/art_storyboard.md b/data/skills/art_prompts/你好/art_prompt/art_storyboard.md new file mode 100644 index 0000000..f73dd74 --- /dev/null +++ b/data/skills/art_prompts/你好/art_prompt/art_storyboard.md @@ -0,0 +1 @@ +1212 \ No newline at end of file diff --git a/data/skills/art_prompts/你好/art_prompt/art_storyboard_video.md b/data/skills/art_prompts/你好/art_prompt/art_storyboard_video.md new file mode 100644 index 0000000..f73dd74 --- /dev/null +++ b/data/skills/art_prompts/你好/art_prompt/art_storyboard_video.md @@ -0,0 +1 @@ +1212 \ No newline at end of file diff --git a/data/skills/art_prompts/你好/driector_skills/director_planning.md b/data/skills/art_prompts/你好/driector_skills/director_planning.md new file mode 100644 index 0000000..f73dd74 --- /dev/null +++ b/data/skills/art_prompts/你好/driector_skills/director_planning.md @@ -0,0 +1 @@ +1212 \ No newline at end of file diff --git a/data/skills/art_prompts/你好/driector_skills/director_storyboard_table.md b/data/skills/art_prompts/你好/driector_skills/director_storyboard_table.md new file mode 100644 index 0000000..f73dd74 --- /dev/null +++ b/data/skills/art_prompts/你好/driector_skills/director_storyboard_table.md @@ -0,0 +1 @@ +1212 \ No newline at end of file diff --git a/data/skills/art_prompts/你好/prefix.md b/data/skills/art_prompts/你好/prefix.md new file mode 100644 index 0000000..f73dd74 --- /dev/null +++ b/data/skills/art_prompts/你好/prefix.md @@ -0,0 +1 @@ +1212 \ No newline at end of file diff --git a/src/lib/initDB.ts b/src/lib/initDB.ts index 610777a..69b40ae 100644 --- a/src/lib/initDB.ts +++ b/src/lib/initDB.ts @@ -260,6 +260,101 @@ export default async (knex: Knex, forceInit: boolean = false): Promise => type: "assetsPromptGeneration", data: "# 资产提示词生成指令 根据提供的项目参数和资产设定,生成符合要求的提示词\n\n请根据以下参数生成提示词:\n\n**基础参数:**\n- 风格: {风格}\n- 小说类型: {小说类型}\n- 小说背景: {小说背景}\n\n**资产设定:**\n- 类型: {角色/场景/道具}\n- 名称:{名称}\n- 描述:{描述}\n\n请严格按照skill规范生成提示词。", }, + { + name: "剧本资产提取", + type: "scriptAssetExtraction", + data: ` + --- + name: universal_agent + description: 专注于从剧本内容中提取所使用的资产(角色、场景、道具)并生成结构化资产列表的助手。 + --- + + # Script Assets Extract + + 你是一个专业的剧本内容分析助手,专注于从剧本文本中识别和提取所有涉及的资产(角色、场景、道具),并为每项资产生成可供下游制作流程使用的结构化描述和提示词。 + + ## 何时使用 + + 用户提供剧本内容,你需要逐段阅读并提取其中涉及的所有资产(人物角色、场景地点、道具物件),输出为结构化的资产列表。产出的资产描述将用于后续 AI 图片生成和制作流程。 + + ## 与系统的对应关系 + + - 资产类型: + - \`role\` — 角色(对应 \`o_assets.type = "role"\`) + - \`scene\` — 场景(对应 \`o_assets.type = "scene"\`) + - \`tool\` — 道具(对应 \`o_assets.type = "tool"\`) + - 下游用途:资产提示词生成 → AI 资产图生成 → 分镜制作 + + ## 输出要求 + + **必须通过调用 \`resultTool\` 工具返回结果**,禁止以纯文本、Markdown 表格或 JSON 代码块等形式直接输出资产列表。 + \`resultTool\` 的 schema 会对字段类型和枚举值做强校验,调用时请严格按照下方字段定义填写,确保数据结构正确、字段完整、类型匹配。 + + 每个资产对象包含以下字段: + + | 字段 | 类型 | 必填 | 说明 | + | ---- | ---- | ---- | ---- | + | \`name\` | string | 是 | 资产名称,使用剧本中的原始称呼,不做其他多余描述 | + | \`desc\` | string | 是 | 资产描述,30-80 字的视觉化描述 | + | \`prompt\` | string | 是 | 生成提示词,英文,用于 AI 图片生成 | + | \`type\` | enum | 是 | 资产类型:\`role\` / \`scene\` / \`tool\` | + + ## 提取规则 + + ### 角色(role) + + - 提取剧本中出现的所有有名字的角色 + - \`desc\`:包含外貌特征、服饰风格、体态气质等视觉要素 + - \`prompt\`:英文提示词,描述角色的外观特征,适用于 AI 角色图生成 + - 同一角色有多个称呼时,取最常用的作为 \`name\` + - 无名龙套(如"路人甲"、"士兵")可跳过,除非其造型对剧情有重要视觉意义 + + ### 场景(scene) + + - 提取剧本中出现的所有场景/地点 + - \`desc\`:包含空间结构、光照氛围、关键陈设、色调基调等视觉要素 + - \`prompt\`:英文提示词,描述场景的整体视觉风格,适用于 AI 场景图生成 + - 同一场景的不同状态(如白天/夜晚)不重复提取,在 \`desc\` 中注明即可 + + ### 道具(tool) + + - 提取剧本中出现的重要道具/物品 + - \`desc\`:包含外观形状、颜色材质、尺寸参考、特殊效果等视觉要素 + - \`prompt\`:英文提示词,描述道具的外观细节,适用于 AI 道具图生成 + - 仅提取有独立视觉意义或剧情功能的道具,通用物品可跳过 + + + ## 提示词(prompt)生成规范 + + - 采用逗号分隔的关键词/短语格式 + - 优先描述**视觉特征**,避免抽象概念 + - 包含风格关键词(如 anime style, manga style 等,根据项目风格决定) + - 角色 prompt 示例:\`a young man, sharp eyebrows, black hair, pale skin, wearing a gray Taoist robe, slender build, cold expression\` + - 场景 prompt 示例:\`dark cave interior, glowing crystals on walls, misty atmosphere, dim blue lighting, stone altar in center\` + - 道具 prompt 示例:\`ancient jade pendant, oval shape, translucent green, carved dragon pattern, glowing faintly\` + + ## 提取流程 + + 1. 通读剧本全文,识别所有出现的角色、场景、道具 + 2. 对每个资产生成结构化的 \`name\`、\`desc\`、\`prompt\`、\`type\` + 3. 去重:同一资产不重复提取 + 4. **必须通过调用 \`resultTool\` 工具输出完整资产列表**,不要分多次调用,一次性将所有资产放入 \`assetsList\` 数组中提交 + + ## 提取原则 + + 1. **忠于剧本**:所有提取基于剧本中的实际内容,不臆造未出现的资产 + 2. **视觉优先**:描述和提示词聚焦视觉特征,便于 AI 图片生成 + 3. **精简实用**:只提取对制作有实际意义的资产,避免过度提取 + 4. **分类准确**:严格按照 role/scene/tool 分类,不混淆 + 5. **提示词质量**:英文提示词应具体、可执行,能直接用于 AI 图片生成 + + ## 注意事项 + + - 资产列表中**不要包含剧本内容本身**,仅提取所使用到的资产 + - 角色的随身物品如果有独立剧情功能,应单独作为道具提取 + - 场景中的固定陈设不需要单独提取为道具,除非该物件有独立剧情作用 + `, + }, ]); }, }, diff --git a/src/router.ts b/src/router.ts index c07465b..8d43229 100644 --- a/src/router.ts +++ b/src/router.ts @@ -1,4 +1,4 @@ -// @routes-hash e584b1af18da2fc25158fd68183fa645 +// @routes-hash 5a19c42c22d44ec4c7fe2fc7245535d9 import { Express } from "express"; import route1 from "./routes/agents/clearMemory"; @@ -65,49 +65,54 @@ import route61 from "./routes/production/workbench/getChatLines"; import route62 from "./routes/production/workbench/getVideoModelDetail"; import route63 from "./routes/production/workbench/videoPolling"; import route64 from "./routes/project/addProject"; -import route65 from "./routes/project/delProject"; -import route66 from "./routes/project/editProject"; -import route67 from "./routes/project/getProject"; -import route68 from "./routes/script/addScript"; -import route69 from "./routes/script/delScript"; -import route70 from "./routes/script/exportScript"; -import route71 from "./routes/script/extractAssets"; -import route72 from "./routes/script/getScrptApi"; -import route73 from "./routes/script/pollScriptAssets"; -import route74 from "./routes/script/updateScript"; -import route75 from "./routes/scriptAgent/getPlanData"; -import route76 from "./routes/scriptAgent/setPlanData"; -import route77 from "./routes/setting/about/checkUpdate"; -import route78 from "./routes/setting/about/downloadApp"; -import route79 from "./routes/setting/agentDeploy/agentSetKey"; -import route80 from "./routes/setting/agentDeploy/deployAgentModel"; -import route81 from "./routes/setting/agentDeploy/getAgentDeploy"; -import route82 from "./routes/setting/dbConfig/clearData"; -import route83 from "./routes/setting/dev/getSwitchAiDevTool"; -import route84 from "./routes/setting/dev/updateSwitchAiDevTool"; -import route85 from "./routes/setting/fileManagement/openFolder"; -import route86 from "./routes/setting/getTextModel"; -import route87 from "./routes/setting/loginConfig/getUser"; -import route88 from "./routes/setting/loginConfig/updateUserPwd"; -import route89 from "./routes/setting/memoryConfig/delAllMemory"; -import route90 from "./routes/setting/memoryConfig/getMemory"; -import route91 from "./routes/setting/memoryConfig/sureMemory"; -import route92 from "./routes/setting/promptManage/getPrompt"; -import route93 from "./routes/setting/promptManage/updatePrompt"; -import route94 from "./routes/setting/skillManagement/getSkillContent"; -import route95 from "./routes/setting/skillManagement/getSkillList"; -import route96 from "./routes/setting/skillManagement/saveSkillContent"; -import route97 from "./routes/setting/vendorConfig/addVendor"; -import route98 from "./routes/setting/vendorConfig/deleteVendor"; -import route99 from "./routes/setting/vendorConfig/getVendorList"; -import route100 from "./routes/setting/vendorConfig/modelTest"; -import route101 from "./routes/setting/vendorConfig/updateCode"; -import route102 from "./routes/setting/vendorConfig/updateVendor"; -import route103 from "./routes/task/getProject"; -import route104 from "./routes/task/getTaskApi"; -import route105 from "./routes/task/getTaskCategories"; -import route106 from "./routes/task/taskDetails"; -import route107 from "./routes/test/test"; +import route65 from "./routes/project/addVisual"; +import route66 from "./routes/project/deleteVisualManual"; +import route67 from "./routes/project/delProject"; +import route68 from "./routes/project/editProject"; +import route69 from "./routes/project/editVisualManual"; +import route70 from "./routes/project/getProject"; +import route71 from "./routes/project/getVisualManual"; +import route72 from "./routes/project/visualManual"; +import route73 from "./routes/script/addScript"; +import route74 from "./routes/script/delScript"; +import route75 from "./routes/script/exportScript"; +import route76 from "./routes/script/extractAssets"; +import route77 from "./routes/script/getScrptApi"; +import route78 from "./routes/script/pollScriptAssets"; +import route79 from "./routes/script/updateScript"; +import route80 from "./routes/scriptAgent/getPlanData"; +import route81 from "./routes/scriptAgent/setPlanData"; +import route82 from "./routes/setting/about/checkUpdate"; +import route83 from "./routes/setting/about/downloadApp"; +import route84 from "./routes/setting/agentDeploy/agentSetKey"; +import route85 from "./routes/setting/agentDeploy/deployAgentModel"; +import route86 from "./routes/setting/agentDeploy/getAgentDeploy"; +import route87 from "./routes/setting/dbConfig/clearData"; +import route88 from "./routes/setting/dev/getSwitchAiDevTool"; +import route89 from "./routes/setting/dev/updateSwitchAiDevTool"; +import route90 from "./routes/setting/fileManagement/openFolder"; +import route91 from "./routes/setting/getTextModel"; +import route92 from "./routes/setting/loginConfig/getUser"; +import route93 from "./routes/setting/loginConfig/updateUserPwd"; +import route94 from "./routes/setting/memoryConfig/delAllMemory"; +import route95 from "./routes/setting/memoryConfig/getMemory"; +import route96 from "./routes/setting/memoryConfig/sureMemory"; +import route97 from "./routes/setting/promptManage/getPrompt"; +import route98 from "./routes/setting/promptManage/updatePrompt"; +import route99 from "./routes/setting/skillManagement/getSkillContent"; +import route100 from "./routes/setting/skillManagement/getSkillList"; +import route101 from "./routes/setting/skillManagement/saveSkillContent"; +import route102 from "./routes/setting/vendorConfig/addVendor"; +import route103 from "./routes/setting/vendorConfig/deleteVendor"; +import route104 from "./routes/setting/vendorConfig/getVendorList"; +import route105 from "./routes/setting/vendorConfig/modelTest"; +import route106 from "./routes/setting/vendorConfig/updateCode"; +import route107 from "./routes/setting/vendorConfig/updateVendor"; +import route108 from "./routes/task/getProject"; +import route109 from "./routes/task/getTaskApi"; +import route110 from "./routes/task/getTaskCategories"; +import route111 from "./routes/task/taskDetails"; +import route112 from "./routes/test/test"; export default async (app: Express) => { app.use("/api/agents/clearMemory", route1); @@ -174,47 +179,52 @@ export default async (app: Express) => { app.use("/api/production/workbench/getVideoModelDetail", route62); app.use("/api/production/workbench/videoPolling", route63); app.use("/api/project/addProject", route64); - app.use("/api/project/delProject", route65); - app.use("/api/project/editProject", route66); - app.use("/api/project/getProject", route67); - app.use("/api/script/addScript", route68); - app.use("/api/script/delScript", route69); - app.use("/api/script/exportScript", route70); - app.use("/api/script/extractAssets", route71); - app.use("/api/script/getScrptApi", route72); - app.use("/api/script/pollScriptAssets", route73); - app.use("/api/script/updateScript", route74); - app.use("/api/scriptAgent/getPlanData", route75); - app.use("/api/scriptAgent/setPlanData", route76); - app.use("/api/setting/about/checkUpdate", route77); - app.use("/api/setting/about/downloadApp", route78); - app.use("/api/setting/agentDeploy/agentSetKey", route79); - app.use("/api/setting/agentDeploy/deployAgentModel", route80); - app.use("/api/setting/agentDeploy/getAgentDeploy", route81); - app.use("/api/setting/dbConfig/clearData", route82); - app.use("/api/setting/dev/getSwitchAiDevTool", route83); - app.use("/api/setting/dev/updateSwitchAiDevTool", route84); - app.use("/api/setting/fileManagement/openFolder", route85); - app.use("/api/setting/getTextModel", route86); - app.use("/api/setting/loginConfig/getUser", route87); - app.use("/api/setting/loginConfig/updateUserPwd", route88); - app.use("/api/setting/memoryConfig/delAllMemory", route89); - app.use("/api/setting/memoryConfig/getMemory", route90); - app.use("/api/setting/memoryConfig/sureMemory", route91); - app.use("/api/setting/promptManage/getPrompt", route92); - app.use("/api/setting/promptManage/updatePrompt", route93); - app.use("/api/setting/skillManagement/getSkillContent", route94); - app.use("/api/setting/skillManagement/getSkillList", route95); - app.use("/api/setting/skillManagement/saveSkillContent", route96); - app.use("/api/setting/vendorConfig/addVendor", route97); - app.use("/api/setting/vendorConfig/deleteVendor", route98); - app.use("/api/setting/vendorConfig/getVendorList", route99); - app.use("/api/setting/vendorConfig/modelTest", route100); - app.use("/api/setting/vendorConfig/updateCode", route101); - app.use("/api/setting/vendorConfig/updateVendor", route102); - app.use("/api/task/getProject", route103); - app.use("/api/task/getTaskApi", route104); - app.use("/api/task/getTaskCategories", route105); - app.use("/api/task/taskDetails", route106); - app.use("/api/test/test", route107); + app.use("/api/project/addVisual", route65); + app.use("/api/project/deleteVisualManual", route66); + app.use("/api/project/delProject", route67); + app.use("/api/project/editProject", route68); + app.use("/api/project/editVisualManual", route69); + app.use("/api/project/getProject", route70); + app.use("/api/project/getVisualManual", route71); + app.use("/api/project/visualManual", route72); + app.use("/api/script/addScript", route73); + app.use("/api/script/delScript", route74); + app.use("/api/script/exportScript", route75); + app.use("/api/script/extractAssets", route76); + app.use("/api/script/getScrptApi", route77); + app.use("/api/script/pollScriptAssets", route78); + app.use("/api/script/updateScript", route79); + app.use("/api/scriptAgent/getPlanData", route80); + app.use("/api/scriptAgent/setPlanData", route81); + app.use("/api/setting/about/checkUpdate", route82); + app.use("/api/setting/about/downloadApp", route83); + app.use("/api/setting/agentDeploy/agentSetKey", route84); + app.use("/api/setting/agentDeploy/deployAgentModel", route85); + app.use("/api/setting/agentDeploy/getAgentDeploy", route86); + app.use("/api/setting/dbConfig/clearData", route87); + app.use("/api/setting/dev/getSwitchAiDevTool", route88); + app.use("/api/setting/dev/updateSwitchAiDevTool", route89); + app.use("/api/setting/fileManagement/openFolder", route90); + app.use("/api/setting/getTextModel", route91); + app.use("/api/setting/loginConfig/getUser", route92); + app.use("/api/setting/loginConfig/updateUserPwd", route93); + app.use("/api/setting/memoryConfig/delAllMemory", route94); + app.use("/api/setting/memoryConfig/getMemory", route95); + app.use("/api/setting/memoryConfig/sureMemory", route96); + app.use("/api/setting/promptManage/getPrompt", route97); + app.use("/api/setting/promptManage/updatePrompt", route98); + app.use("/api/setting/skillManagement/getSkillContent", route99); + app.use("/api/setting/skillManagement/getSkillList", route100); + app.use("/api/setting/skillManagement/saveSkillContent", route101); + app.use("/api/setting/vendorConfig/addVendor", route102); + app.use("/api/setting/vendorConfig/deleteVendor", route103); + app.use("/api/setting/vendorConfig/getVendorList", route104); + app.use("/api/setting/vendorConfig/modelTest", route105); + app.use("/api/setting/vendorConfig/updateCode", route106); + app.use("/api/setting/vendorConfig/updateVendor", route107); + app.use("/api/task/getProject", route108); + app.use("/api/task/getTaskApi", route109); + app.use("/api/task/getTaskCategories", route110); + app.use("/api/task/taskDetails", route111); + app.use("/api/test/test", route112); } diff --git a/src/routes/project/addVisual.ts b/src/routes/project/addVisual.ts new file mode 100644 index 0000000..958e15c --- /dev/null +++ b/src/routes/project/addVisual.ts @@ -0,0 +1,85 @@ +import express from "express"; +import u from "@/utils"; +import { success } from "@/lib/responseFormat"; +import fs from "fs"; +import path from "path"; +import { validateFields } from "@/middleware/middleware"; +import { z } from "zod"; +const router = express.Router(); + +// 新增视觉手册 +export default router.post( + "/", + validateFields({ + name: z.string(), + image: z.string(), + data: z.array( + z.object({ + label: z.string(), + value: z.string(), + data: z.string(), + }), + ), + }), + async (req, res) => { + try { + const { name, image, data } = req.body as { + name: string; + image: string; + data: { label: string; value: string; data: string }[]; + }; + + const mainPath = u.getPath(["skills", "art_prompts", name]); + + // 将 image 写入 mainPath/images/image 文件(无后缀) + if (image) { + const imagesDir = path.join(mainPath, "images"); + if (!fs.existsSync(imagesDir)) { + fs.mkdirSync(imagesDir, { recursive: true }); + } + fs.writeFileSync(path.join(imagesDir, "image"), image, "utf-8"); + } + + // 字段映射表(与 getVisualManual 保持一致) + const DATA_MAP: { label: string; value: string; subDir?: string }[] = [ + { label: "README", value: "README" }, + { label: "前缀", value: "prefix" }, + { label: "角色", value: "art_character", subDir: "art_prompt" }, + { label: "角色衍生", value: "art_character_derivative", subDir: "art_prompt" }, + { label: "道具", value: "art_prop", subDir: "art_prompt" }, + { label: "道具衍生", value: "art_prop_derivative", subDir: "art_prompt" }, + { label: "场景", value: "art_scene", subDir: "art_prompt" }, + { label: "场景衍生", value: "art_scene_derivative", subDir: "art_prompt" }, + { label: "分镜", value: "art_storyboard", subDir: "art_prompt" }, + { label: "分镜视频", value: "art_storyboard_video", subDir: "art_prompt" }, + { label: "技法-导演规划", value: "director_planning", subDir: "driector_skills" }, + { label: "技法-分镜表设计", value: "director_storyboard_table", subDir: "driector_skills" }, + ]; + + // 根据 DATA_MAP 构建 value -> subDir 的映射 + const SUB_DIR_MAP = new Map(DATA_MAP.map(({ value, subDir }) => [value, subDir ?? ""])); + + // 合法的 value 值集合,用于校验 + const VALID_KEYS = new Set(DATA_MAP.map(({ value }) => value)); + + for (const item of data) { + if (!VALID_KEYS.has(item.value)) continue; + + const subDir = SUB_DIR_MAP.get(item.value)!; + const dirArr = subDir ? [mainPath, subDir] : [mainPath]; + const filePath = u.getPath([...dirArr, `${item.value}.md`]); + + const fileDir = path.dirname(filePath); + // 目录不存在时递归创建 + if (!fs.existsSync(fileDir)) { + fs.mkdirSync(fileDir, { recursive: true }); + } + fs.writeFileSync(filePath, item.data, "utf-8"); + } + + res.status(200).send(success()); + } catch (err) { + res.status(500).send({ error: String(err) }); + } + }, +); diff --git a/src/routes/project/deleteVisualManual.ts b/src/routes/project/deleteVisualManual.ts new file mode 100644 index 0000000..16d184b --- /dev/null +++ b/src/routes/project/deleteVisualManual.ts @@ -0,0 +1,43 @@ +import express from "express"; +import u from "@/utils"; +import fs from "fs"; +import { z } from "zod"; +import { error, success } from "@/lib/responseFormat"; +import { validateFields } from "@/middleware/middleware"; +const router = express.Router(); + +// 删除视觉手册 +export default router.post( + "/", + validateFields({ + name: z.string(), + }), + async (req, res) => { + try { + const { name } = req.body as { name: string }; + + // 安全校验:不允许包含路径分隔符、纯数字,防止越级删除或误删项目目录 + if (name.includes("/") || name.includes("\\") || name === "." || name === ".." || /^\d+$/.test(name)) { + res.status(400).send(error("名称不能包含路径分隔符或为纯数字")); + return; + } + + const artPromptsDir = u.getPath(["skills", "art_prompts", name]); + + // 1. 删除 skills/art_prompts 下的同名文件夹 + if (fs.existsSync(artPromptsDir)) { + fs.rmSync(artPromptsDir, { recursive: true, force: true }); + // 2. 删除 oss 下的同名文件夹(存放图片) + try { + await u.oss.deleteDirectory(name); + } catch { + // oss 下不存在该目录则忽略 + } + } + + res.status(200).send(success({ message: "删除成功" })); + } catch (err) { + res.status(500).send(error(u.error(err).message || "删除失败")); + } + }, +); diff --git a/src/routes/project/editVisualManual.ts b/src/routes/project/editVisualManual.ts new file mode 100644 index 0000000..142975f --- /dev/null +++ b/src/routes/project/editVisualManual.ts @@ -0,0 +1,100 @@ +import express from "express"; +import u from "@/utils"; +import { error, success } from "@/lib/responseFormat"; +import fs from "fs"; +import path from "path"; +import { validateFields } from "@/middleware/middleware"; +import { z } from "zod"; +const router = express.Router(); + +// 编辑视觉手册 +export default router.post( + "/", + validateFields({ + name: z.string(), + images: z.array(z.string()), + data: z.array( + z.object({ + label: z.string(), + value: z.string(), + data: z.string(), + }), + ), + }), + async (req, res) => { + try { + const { name, images, data } = req.body as { + name: string; + images: string[]; + data: { label: string; value: string; data: string }[]; + }; + + if (/^\d+$/.test(name)) { + res.status(400).send(error("名称不能为纯数字")); + return; + } + + const mainPath = u.getPath(["skills", "art_prompts", name]); + + // 字段映射表(与 getVisualManual 保持一致) + const DATA_MAP: { label: string; value: string; subDir?: string }[] = [ + { label: "README", value: "README" }, + { label: "前缀", value: "prefix" }, + { label: "角色", value: "art_character", subDir: "art_prompt" }, + { label: "角色衍生", value: "art_character_derivative", subDir: "art_prompt" }, + { label: "道具", value: "art_prop", subDir: "art_prompt" }, + { label: "道具衍生", value: "art_prop_derivative", subDir: "art_prompt" }, + { label: "场景", value: "art_scene", subDir: "art_prompt" }, + { label: "场景衍生", value: "art_scene_derivative", subDir: "art_prompt" }, + { label: "分镜", value: "art_storyboard", subDir: "art_prompt" }, + { label: "分镜视频", value: "art_storyboard_video", subDir: "art_prompt" }, + { label: "技法-导演规划", value: "director_planning", subDir: "driector_skills" }, + { label: "技法-分镜表设计", value: "director_storyboard_table", subDir: "driector_skills" }, + ]; + + // 根据 DATA_MAP 构建 value -> subDir 的映射 + const SUB_DIR_MAP = new Map(DATA_MAP.map(({ value, subDir }) => [value, subDir ?? ""])); + + // 合法的 value 值集合,用于校验 + const VALID_KEYS = new Set(DATA_MAP.map(({ value }) => value)); + + for (const item of data) { + if (!VALID_KEYS.has(item.value)) continue; + + const subDir = SUB_DIR_MAP.get(item.value)!; + const dirArr = subDir ? [mainPath, subDir] : [mainPath]; + const filePath = u.getPath([...dirArr, `${item.value}.md`]); + + const fileDir = path.dirname(filePath); + // 目录不存在时递归创建 + if (!fs.existsSync(fileDir)) { + fs.mkdirSync(fileDir, { recursive: true }); + } + fs.writeFileSync(filePath, item.data, "utf-8"); + } + const ossImagesDir = u.getPath(["oss", name]); + + let existingFiles: string[] = []; + try { + const allFiles = fs.readdirSync(ossImagesDir); + existingFiles = allFiles.filter((f) => /\.(png|jpe?g|gif|webp|svg)$/i.test(f)); + } catch {} + + const retainedFileNames = new Set(images.filter((item) => item.startsWith("http")).map((url) => path.basename(new URL(url).pathname))); + + for (const file of existingFiles) { + if (!retainedFileNames.has(file)) { + await u.oss.deleteFile(`${name}/${file}`); + } + } + + for (const item of images) { + if (!item.startsWith("http")) await u.oss.writeFile(`${name}/${u.uuid()}.jpg`, item); + } + + res.status(200).send(success()); + } catch (err) { + res.status(500).send({ error: String(err) }); + } + }, +); diff --git a/src/routes/project/getVisualManual.ts b/src/routes/project/getVisualManual.ts new file mode 100644 index 0000000..43a29f0 --- /dev/null +++ b/src/routes/project/getVisualManual.ts @@ -0,0 +1,92 @@ +import express from "express"; +import u from "@/utils"; +import { success } from "@/lib/responseFormat"; +import fs from "fs"; +import path from "path"; +const router = express.Router(); + +// 字段映射表 +const DATA_MAP: { label: string; value: string; subDir?: string }[] = [ + { label: "README", value: "README" }, + { label: "前缀", value: "prefix" }, + { label: "角色", value: "art_character", subDir: "art_prompt" }, + { label: "角色衍生", value: "art_character_derivative", subDir: "art_prompt" }, + { label: "道具", value: "art_prop", subDir: "art_prompt" }, + { label: "道具衍生", value: "art_prop_derivative", subDir: "art_prompt" }, + { label: "场景", value: "art_scene", subDir: "art_prompt" }, + { label: "场景衍生", value: "art_scene_derivative", subDir: "art_prompt" }, + { label: "分镜", value: "art_storyboard", subDir: "art_prompt" }, + { label: "分镜视频", value: "art_storyboard_video", subDir: "art_prompt" }, + { label: "技法-导演规划", value: "director_planning", subDir: "driector_skills" }, + { label: "技法-分镜表设计", value: "director_storyboard_table", subDir: "driector_skills" }, +]; + +// 读取 md 文件内容,文件不存在时返回空字符串 +function readMd(filePath: string): string { + try { + return fs.readFileSync(filePath, "utf-8"); + } catch { + return ""; + } +} + +// 获取 images 文件夹下所有图片文件路径列表 +async function readAllImages(imagesDir: string) { + try { + const ossPath = u.getPath(["oss", imagesDir]); + const files = fs.readdirSync(ossPath); + const images = files.filter((f) => /\.(png|jpe?g|gif|webp|svg)$/i.test(f)).map((f) => path.join(imagesDir, f)); + if (images.length) { + return Promise.all(images.map(async (i) => await u.oss.getFileUrl(i))); + } else { + return []; + } + } catch { + return []; + } +} + +// 获取视觉手册 +export default router.post("/", async (req, res) => { + try { + const artPromptsDir = u.getPath(["skills", "art_prompts"]); + + // 读取所有风格文件夹 + const styleDirs = fs + .readdirSync(artPromptsDir, { withFileTypes: true }) + .filter((d) => d.isDirectory()) + .map((d) => d.name); + + const result = await Promise.all( + styleDirs.map(async (styleName) => { + const styleDir = path.join(artPromptsDir, styleName); + const imagesDir = path.join(styleDir, "images"); + + const images = await readAllImages(styleName); + + const data = DATA_MAP.map(({ label, value, subDir }) => { + let mdPath: string; + if (subDir) { + mdPath = path.join(styleDir, subDir, `${value}.md`); + } else { + mdPath = path.join(styleDir, `${value}.md`); + } + return { + label, + value, + data: readMd(mdPath), + }; + }); + + return { + name: styleName, + image: images, + data, + }; + }), + ); + res.status(200).send(success(result)); + } catch (err) { + res.status(500).send({ error: String(err) }); + } +}); diff --git a/src/routes/project/visualManual.ts b/src/routes/project/visualManual.ts new file mode 100644 index 0000000..c0e3fc0 --- /dev/null +++ b/src/routes/project/visualManual.ts @@ -0,0 +1,42 @@ +import express from "express"; +import u from "@/utils"; +import { z } from "zod"; +import { success } from "@/lib/responseFormat"; +import { validateFields } from "@/middleware/middleware"; +import getPath from "@/utils/getPath"; +import fs from "fs"; +import path from "path"; +const router = express.Router(); + +// 视觉手册 +export default router.post( + "/", + validateFields({ + type: z.string(), + }), + async (req, res) => { + const { type } = req.body; + const basePath = getPath(["skills", "art_prompts", "chinese_sweet_romance"]); + // 递归查找 basePath 下名为 `${type}.md` 的文件 + const findFile = (dir: string, target: string): string | null => { + const entries = fs.readdirSync(dir, { withFileTypes: true }); + for (const entry of entries) { + const fullPath = path.join(dir, entry.name); + if (entry.isDirectory()) { + const found = findFile(fullPath, target); + if (found) return found; + } else if (entry.isFile() && entry.name === target) { + return fullPath; + } + } + return null; + }; + const filePath = findFile(basePath, `${type}.md`); + if (!filePath) { + res.status(404).json({ error: `未找到对应的文件: ${type}.md` }); + return; + } + const content = fs.readFileSync(filePath, "utf-8"); + res.status(200).send(success(content)); + }, +); diff --git a/src/routes/script/extractAssets.ts b/src/routes/script/extractAssets.ts index e8adca4..873252d 100644 --- a/src/routes/script/extractAssets.ts +++ b/src/routes/script/extractAssets.ts @@ -156,13 +156,13 @@ export default router.post( }); try { - const skill = await useSkill("universal_agent.md");//todo:改为AI + const data = await u.db("o_prompt").where("type", "scriptAssetExtraction").first("data"); await intansce.invoke({ messages: [ { role: "system", content: - skill.prompt + + data?.data + "\n\n提取剧本中涉及的资产(角色、场景、道具),参考技能 script_assets_extract 规范,结果必须通过 resultTool 工具返回。", }, { @@ -170,13 +170,16 @@ export default router.post( content: `请根据以下剧本提取对应的剧本资产(角色、场景、道具、素材片段):\n\n${script.content}`, }, ], - tools: { ...skill.tools, resultTool }, + tools: { resultTool }, }); } catch (e: any) { const msg = e?.message || String(e); console.error(`[extractAssets] scriptId=${scriptId} name=${script.name} 提取失败:`, msg); errors.push({ scriptId, error: script.name + ":" + u.error(e).message }); - await u.db("o_script").where("id", scriptId).update({ extractState: -1, errorReason: u.error(e).message }); + await u + .db("o_script") + .where("id", scriptId) + .update({ extractState: -1, errorReason: u.error(e).message }); return null; } diff --git a/src/routes/setting/vendorConfig/deleteVendor.ts b/src/routes/setting/vendorConfig/deleteVendor.ts index a4a58ed..a9bd942 100644 --- a/src/routes/setting/vendorConfig/deleteVendor.ts +++ b/src/routes/setting/vendorConfig/deleteVendor.ts @@ -14,7 +14,6 @@ export default router.post( await u.db("o_vendorConfig").where("id", id).del(); await u.db("o_agentDeploy").where("vendorId", id).update({ model: null, - key: null, vendorId: null, }); res.status(200).send(success("删除成功")); diff --git a/src/utils/oss.ts b/src/utils/oss.ts index e2b935d..e3e9f0c 100644 --- a/src/utils/oss.ts +++ b/src/utils/oss.ts @@ -145,7 +145,11 @@ class OSS { const absPath = resolveSafeLocalPath(userRelPath, this.rootDir); await fs.mkdir(path.dirname(absPath), { recursive: true }); // 如果 data 是 string,则视为 base64 编码,先解码再写入 - const buffer = typeof data === "string" ? Buffer.from(data, "base64") : data; + // 自动去除可能存在的 Data URL 前缀(如 "data:image/png;base64,") + const buffer = + typeof data === "string" + ? Buffer.from(data.replace(/^data:[^;]+;base64,/, ""), "base64") + : data; await fs.writeFile(absPath, buffer); }