yonge 16 часов назад
Родитель
Сommit
a1522cebd6

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
dist/assets/index-Bikyjl5G.js


+ 1 - 1
dist/assets/index-ByxzWVNc.js → dist/assets/index-C6rSfLk-.js

@@ -1 +1 @@
-import{u as c,af as l}from"./index-BAPd0_0T.js";import{w as p,bA as d,a5 as g,cD as m,R as t,ae as r,af as u,al as f,ag as w,bH as k}from"./index-CS7FTuzz.js";import"./shapes-C3yc_Yz1.js";const S=()=>{function o(a){if(window.parent===window)return;const{api:e,playState:n}=a.data||{};e==="headerTogge"?window.parent.postMessage({api:"headerTogge",playState:n},"*"):e==="changeTogge"?window.parent.postMessage({api:"changeTogge"},"*"):["clickTempo","clickViewFigner"].includes(e)&&window.parent.postMessage({api:e},"*")}p(()=>{window.addEventListener("message",o)}),d(()=>{window.removeEventListener("message",o)})},_=g({__name:"mobileScreen",setup(o){S();const a=m(),e=t(!0),n=t(!1),i=c();return a.setScreenMode("mobileScreen"),i.initPPTData().then(()=>{e.value=!1}),(v,s)=>(r(),u("div",{class:"mobileScreen",onClick:s[0]||(s[0]=b=>n.value=!1)},[e.value?w("",!0):(r(),f(l,{key:0}))]))}}),P=k(_,[["__scopeId","data-v-90b2692a"]]);export{P as default};
+import{u as c,af as l}from"./index-z-hsNSCS.js";import{w as p,bA as d,a5 as g,cD as m,R as t,ae as r,af as u,al as f,ag as w,bH as k}from"./index-DFzcmnzu.js";import"./shapes-DveQjeNx.js";const S=()=>{function o(a){if(window.parent===window)return;const{api:e,playState:n}=a.data||{};e==="headerTogge"?window.parent.postMessage({api:"headerTogge",playState:n},"*"):e==="changeTogge"?window.parent.postMessage({api:"changeTogge"},"*"):["clickTempo","clickViewFigner"].includes(e)&&window.parent.postMessage({api:e},"*")}p(()=>{window.addEventListener("message",o)}),d(()=>{window.removeEventListener("message",o)})},_=g({__name:"mobileScreen",setup(o){S();const a=m(),e=t(!0),n=t(!1),i=c();return a.setScreenMode("mobileScreen"),i.initPPTData().then(()=>{e.value=!1}),(v,s)=>(r(),u("div",{class:"mobileScreen",onClick:s[0]||(s[0]=b=>n.value=!1)},[e.value?w("",!0):(r(),f(l,{key:0}))]))}}),P=k(_,[["__scopeId","data-v-90b2692a"]]);export{P as default};

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
dist/assets/index-CWPOTzjU.css


+ 1 - 1
dist/assets/index-BEuUI6a5.js → dist/assets/index-CX_sSYUQ.js

@@ -1 +1 @@
-import{_ as a}from"./404-R0y5dkvZ.js";import{a5 as o,en as t,ae as r,af as c,bO as _,bP as d,ak as s,bH as p}from"./index-CS7FTuzz.js";const i=e=>(_("data-v-dda25179"),e=e(),d(),e),n={class:"errorPage"},m=i(()=>s("div",{class:"error"},[s("img",{src:a,class:"img",alt:""}),s("div",{class:"tit"},"页面找不到了~")],-1)),l=[m],f=o({__name:"errorPage",setup(e){return t(),(u,h)=>(r(),c("div",n,l))}}),I=p(f,[["__scopeId","data-v-dda25179"]]);export{I as default};
+import{_ as a}from"./404-R0y5dkvZ.js";import{a5 as o,en as t,ae as r,af as c,bO as _,bP as d,ak as s,bH as p}from"./index-DFzcmnzu.js";const i=e=>(_("data-v-dda25179"),e=e(),d(),e),n={class:"errorPage"},m=i(()=>s("div",{class:"error"},[s("img",{src:a,class:"img",alt:""}),s("div",{class:"tit"},"页面找不到了~")],-1)),l=[m],f=o({__name:"errorPage",setup(e){return t(),(u,h)=>(r(),c("div",n,l))}}),I=p(f,[["__scopeId","data-v-dda25179"]]);export{I as default};

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
dist/assets/index-Cs_xKhZX.js


+ 1 - 1
dist/assets/index-CmuGMYTG.js → dist/assets/index-D3jfJ_kE.js

@@ -1 +1 @@
-import{_ as t}from"./404-R0y5dkvZ.js";import{E as c}from"./index-CjpSQ8o9.js";import{a5 as n,ae as i,af as r,ak as o,aq as _,am as d,P as l,aS as p,bO as m,bP as f,bH as u}from"./index-CS7FTuzz.js";const s=a=>(m("data-v-340bbdaa"),a=a(),f(),a),h={class:"login"},b={class:"error"},g=s(()=>o("img",{src:t,class:"img",alt:""},null,-1)),k=s(()=>o("div",{class:"tit"},"登录已过期或服务器错误!",-1)),v=n({__name:"login",setup(a){function e(){window.close()}return(x,B)=>(i(),r("div",h,[o("div",b,[g,k,_(l(c),{class:"backBtn",type:"primary",plain:"",onClick:e},{default:d(()=>[p("关闭页面")]),_:1})])]))}}),C=u(v,[["__scopeId","data-v-340bbdaa"]]);export{C as default};
+import{_ as t}from"./404-R0y5dkvZ.js";import{E as c}from"./index-Bikyjl5G.js";import{a5 as n,ae as i,af as r,ak as o,aq as _,am as d,P as l,aS as p,bO as m,bP as f,bH as u}from"./index-DFzcmnzu.js";const s=a=>(m("data-v-340bbdaa"),a=a(),f(),a),h={class:"login"},b={class:"error"},g=s(()=>o("img",{src:t,class:"img",alt:""},null,-1)),k=s(()=>o("div",{class:"tit"},"登录已过期或服务器错误!",-1)),v=n({__name:"login",setup(a){function e(){window.close()}return(x,B)=>(i(),r("div",h,[o("div",b,[g,k,_(l(c),{class:"backBtn",type:"primary",plain:"",onClick:e},{default:d(()=>[p("关闭页面")]),_:1})])]))}}),C=u(v,[["__scopeId","data-v-340bbdaa"]]);export{C as default};

Разница между файлами не показана из-за своего большого размера
+ 1 - 1
dist/assets/index-DFzcmnzu.js


+ 1 - 1
dist/assets/index-DX0i0z2z.js → dist/assets/index-DuxVnsxW.js

@@ -1 +1 @@
-import{u as s,af as r}from"./index-BAPd0_0T.js";import{a5 as c,cD as n,R as p,ae as t,af as _,al as u,ag as i,bH as f}from"./index-CS7FTuzz.js";const l={class:"pptScreen"},m=c({__name:"pptScreen",setup(d){const a=n(),e=p(!0),o=s();return a.setScreenMode("pptScreen"),o.initPPTData().then(()=>{e.value=!1}),(S,k)=>(t(),_("div",l,[e.value?i("",!0):(t(),u(r,{key:0}))]))}}),h=f(m,[["__scopeId","data-v-678905e9"]]);export{h as default};
+import{u as s,af as r}from"./index-z-hsNSCS.js";import{a5 as c,cD as n,R as p,ae as t,af as _,al as u,ag as i,bH as f}from"./index-DFzcmnzu.js";const l={class:"pptScreen"},m=c({__name:"pptScreen",setup(d){const a=n(),e=p(!0),o=s();return a.setScreenMode("pptScreen"),o.initPPTData().then(()=>{e.value=!1}),(S,k)=>(t(),_("div",l,[e.value?i("",!0):(t(),u(r,{key:0}))]))}}),h=f(m,[["__scopeId","data-v-678905e9"]]);export{h as default};

+ 1 - 1
dist/assets/index-BAPd0_0T.js → dist/assets/index-z-hsNSCS.js

@@ -1,4 +1,4 @@
-import{cH as dw,cI as hw,aG as vw,cJ as pw,cK as gw,cL as mw,cM as yw,ah as Yt,cN as Sw,cO as bw,cP as xw,cQ as Cw,aM as ww,aF as Tw,cR as Iw,aB as c1,bg as _w,cS as Aw,cT as Ew,cU as Pw,cV as Mw,cW as Rw,cX as Dw,cY as Lw,aE as kw,cZ as Ow,s as Ae,bl as Bw,al as je,ag as ze,af as ve,ak as Z,c_ as Nw,c$ as Fw,d0 as $w,d1 as zw,bk as Uw,cy as ul,aS as Cv,aq as Ye,d2 as Hw,d3 as Vw,a5 as $e,d4 as Gw,d5 as Ww,d6 as jw,d7 as Kw,d8 as Xw,d9 as Yw,da as Zw,db as Qw,dc as Jw,dd as qw,de as eT,v as tT,df as rT,dg as nT,dh as iT,aW as aT,di as oT,dj as sT,dk as lT,dl as uT,dm as cT,ay as sr,dn as fT,dp as dT,dq as hT,dr as vT,A as pT,ds as gT,dt as mT,bq as yT,du as ST,dv as bT,dw as xT,ap as CT,ac as f1,ai as dt,dx as wT,au as Ce,dy as TT,X as d1,y as IT,dz as _T,aP as AT,dA as ET,w as _r,dB as PT,dC as MT,H as RT,dD as DT,bA as hn,aD as LT,ae as ie,bP as ea,$ as wc,dE as kT,bO as ta,dF as OT,aC as BT,aO as NT,R as fe,dG as FT,br as rh,b3 as Lr,aj as Hs,b1 as lt,b2 as Ua,an as wv,dH as $T,dI as zT,dJ as UT,dK as HT,dL as VT,dM as GT,dN as WT,Q as jT,dO as KT,dP as XT,dQ as YT,at as Mt,dR as ZT,aR as QT,aY as JT,ad as cl,aZ as qT,dS as eI,dT as tI,dU as rI,P as le,a6 as nI,dV as iI,dW as aI,dX as oI,dY as sI,a7 as lI,dZ as uI,bL as cI,d_ as fI,d$ as dI,bK as hI,b4 as vI,aA as Tv,e0 as pI,e1 as gI,E as gr,x as mI,e2 as yI,e3 as SI,e4 as bI,am as _n,e5 as xI,az as hr,aU as nh,e6 as CI,as as jr,e7 as wI,e8 as Iv,cG as mr,by as ih,cv as ah,bI as TI,bH as Ve,bu as oh,bv as _v,bx as Wt,bB as Tc,bN as di,e9 as wu,bE as hi,ea as II,bJ as ra,bC as _I,bw as Bt,eb as AI,ec as ui,cw as EI,ed as PI,ee as MI,ef as RI,eg as DI,bM as Zp,eh as LI,bF as Qp,cD as Ic,cC as kI,ei as Hu,ej as Il}from"./index-CS7FTuzz.js";/**
+import{cH as dw,cI as hw,aG as vw,cJ as pw,cK as gw,cL as mw,cM as yw,ah as Yt,cN as Sw,cO as bw,cP as xw,cQ as Cw,aM as ww,aF as Tw,cR as Iw,aB as c1,bg as _w,cS as Aw,cT as Ew,cU as Pw,cV as Mw,cW as Rw,cX as Dw,cY as Lw,aE as kw,cZ as Ow,s as Ae,bl as Bw,al as je,ag as ze,af as ve,ak as Z,c_ as Nw,c$ as Fw,d0 as $w,d1 as zw,bk as Uw,cy as ul,aS as Cv,aq as Ye,d2 as Hw,d3 as Vw,a5 as $e,d4 as Gw,d5 as Ww,d6 as jw,d7 as Kw,d8 as Xw,d9 as Yw,da as Zw,db as Qw,dc as Jw,dd as qw,de as eT,v as tT,df as rT,dg as nT,dh as iT,aW as aT,di as oT,dj as sT,dk as lT,dl as uT,dm as cT,ay as sr,dn as fT,dp as dT,dq as hT,dr as vT,A as pT,ds as gT,dt as mT,bq as yT,du as ST,dv as bT,dw as xT,ap as CT,ac as f1,ai as dt,dx as wT,au as Ce,dy as TT,X as d1,y as IT,dz as _T,aP as AT,dA as ET,w as _r,dB as PT,dC as MT,H as RT,dD as DT,bA as hn,aD as LT,ae as ie,bP as ea,$ as wc,dE as kT,bO as ta,dF as OT,aC as BT,aO as NT,R as fe,dG as FT,br as rh,b3 as Lr,aj as Hs,b1 as lt,b2 as Ua,an as wv,dH as $T,dI as zT,dJ as UT,dK as HT,dL as VT,dM as GT,dN as WT,Q as jT,dO as KT,dP as XT,dQ as YT,at as Mt,dR as ZT,aR as QT,aY as JT,ad as cl,aZ as qT,dS as eI,dT as tI,dU as rI,P as le,a6 as nI,dV as iI,dW as aI,dX as oI,dY as sI,a7 as lI,dZ as uI,bL as cI,d_ as fI,d$ as dI,bK as hI,b4 as vI,aA as Tv,e0 as pI,e1 as gI,E as gr,x as mI,e2 as yI,e3 as SI,e4 as bI,am as _n,e5 as xI,az as hr,aU as nh,e6 as CI,as as jr,e7 as wI,e8 as Iv,cG as mr,by as ih,cv as ah,bI as TI,bH as Ve,bu as oh,bv as _v,bx as Wt,bB as Tc,bN as di,e9 as wu,bE as hi,ea as II,bJ as ra,bC as _I,bw as Bt,eb as AI,ec as ui,cw as EI,ed as PI,ee as MI,ef as RI,eg as DI,bM as Zp,eh as LI,bF as Qp,cD as Ic,cC as kI,ei as Hu,ej as Il}from"./index-DFzcmnzu.js";/**
 * vue v3.4.34
 * (c) 2018-present Yuxi (Evan) You and Vue contributors
 * @license MIT

+ 1 - 1
dist/assets/shapes-C3yc_Yz1.js → dist/assets/shapes-DveQjeNx.js

@@ -1,4 +1,4 @@
-import{cG as k,bB as $1}from"./index-CS7FTuzz.js";import{ag as Z,ah as H1,ai as U,aj as n0,ak as c0,al as i0,am as j1,an as K1,ao as Y1,ap as R}from"./index-BAPd0_0T.js";var z1={exports:{}};/*!
+import{cG as k,bB as $1}from"./index-DFzcmnzu.js";import{ag as Z,ah as H1,ai as U,aj as n0,ak as c0,al as i0,am as j1,an as K1,ao as Y1,ap as R}from"./index-z-hsNSCS.js";var z1={exports:{}};/*!
  * clipboard.js v2.0.11
  * https://clipboardjs.com/
  *

+ 1 - 1
dist/index.html

@@ -10,7 +10,7 @@
     <meta name="description" content="ppt编辑器" />
     <meta name="keywords" content="ppt,powerpoint,office powerpoint,在线ppt,幻灯片,演示文稿,ppt在线制作,Vue3,TypeScript" />
     <title>PPT</title>
-    <script type="module" crossorigin src="./assets/index-CS7FTuzz.js"></script>
+    <script type="module" crossorigin src="./assets/index-DFzcmnzu.js"></script>
     <link rel="stylesheet" crossorigin href="./assets/index-AavUEaYy.css">
   </head>
   <body>

+ 72 - 69
src/config/aiCoursewareTemplates.ts

@@ -1,12 +1,12 @@
 import type { AiCoursewareOutline } from "@/api/aiCourseware"
 
 export type AiCoursewareTemplateId =
-  | "playful-handdrawn"
-  | "fresh-education"
-  | "academic-blue"
-  | "oriental-culture"
-  | "digital-tech"
-  | "active-classroom"
+  | "fairytale-forest"
+  | "warm-handdrawn"
+  | "music-doodle"
+  | "ink-wash"
+  | "stage-documentary"
+  | "modern-geometry"
 
 export type AiCoursewareTemplatePageRole =
   | "cover"
@@ -63,10 +63,10 @@ const freshPalettes: AiCoursewareTemplate["palettes"] = [
   palette("#526FA8", "#5C9EAD", "#E98B73", "#F3C677", "#F7F9FC", "#E8EEF7", "#243040", "#6E7887", "#2C405F")
 ]
 
-const academicPalettes: AiCoursewareTemplate["palettes"] = [
-  palette("#1E4F86", "#2F6F66", "#C77D22", "#D8B45B", "#F4F7FA", "#E6EDF4", "#172534", "#647383", "#102A43"),
-  palette("#243B64", "#356A72", "#B56B45", "#D1AF68", "#F5F6F8", "#E8EBF0", "#1D2733", "#69727E", "#17243A"),
-  palette("#3E4C78", "#39736B", "#A75D72", "#D2B978", "#F6F6F9", "#EAEBF2", "#242636", "#707181", "#252B49")
+const stagePalettes: AiCoursewareTemplate["palettes"] = [
+  palette("#26344E", "#697C9B", "#C88B3D", "#E6C26D", "#F7F8FA", "#E9EDF3", "#172231", "#697586", "#1C2940"),
+  palette("#4A3553", "#7E8EA8", "#C4725A", "#E2B567", "#FAF8FA", "#F0EBF1", "#2B2630", "#776F7A", "#392B40"),
+  palette("#344B5C", "#4C7D7D", "#B96B49", "#DAB66F", "#F7FAFA", "#E7F0EF", "#1F3034", "#63777A", "#263F49")
 ]
 
 const orientalPalettes: AiCoursewareTemplate["palettes"] = [
@@ -75,13 +75,13 @@ const orientalPalettes: AiCoursewareTemplate["palettes"] = [
   palette("#6E3F63", "#496554", "#B4864C", "#DCC68C", "#F8F3EA", "#EEE5D8", "#342D33", "#766D74", "#45333F")
 ]
 
-const techPalettes: AiCoursewareTemplate["palettes"] = [
-  palette("#2563EB", "#06B6D4", "#8B5CF6", "#FBBF24", "#071426", "#102744", "#EAF6FF", "#91AFC9", "#040B17", "#102744"),
-  palette("#3B82F6", "#14B8A6", "#EC4899", "#F59E0B", "#081A24", "#12333B", "#ECFEFF", "#91B5B9", "#041013", "#12333B"),
-  palette("#6366F1", "#22D3EE", "#A855F7", "#FACC15", "#0E1024", "#1C2142", "#F0F2FF", "#A1A7D0", "#080914", "#1C2142")
+const geometryPalettes: AiCoursewareTemplate["palettes"] = [
+  palette("#287B72", "#4FAD93", "#E07A35", "#E9C66D", "#F8FBFA", "#E7F3EF", "#20342F", "#6B817A", "#1E5A52"),
+  palette("#236D98", "#58A6A6", "#E08D50", "#EBCB7A", "#F7FAFC", "#E6F1F4", "#1D3038", "#678089", "#1E5967"),
+  palette("#4B6E9B", "#76A48C", "#C87863", "#DCC280", "#FAFBF9", "#EDF2EA", "#273038", "#737E83", "#415B79")
 ]
 
-const activePalettes: AiCoursewareTemplate["palettes"] = [
+const doodlePalettes: AiCoursewareTemplate["palettes"] = [
   palette("#F05A47", "#13A89E", "#6C63D9", "#F6C945", "#FFF8F2", "#FDEBDD", "#2D2B36", "#756F7C", "#3A3550"),
   palette("#EC4899", "#0EA5A4", "#F97316", "#FACC15", "#FFF7FB", "#FCE7F3", "#302937", "#7A6D7D", "#46354D"),
   palette("#7C5CE7", "#18A999", "#F06449", "#FFD166", "#FAF8FF", "#ECE8FB", "#302D3C", "#746E82", "#403755")
@@ -89,11 +89,11 @@ const activePalettes: AiCoursewareTemplate["palettes"] = [
 
 export const AI_COURSEWARE_TEMPLATES: AiCoursewareTemplate[] = [
   {
-    id: "playful-handdrawn",
-    name: "趣味手绘课堂",
-    sourceName: "原创故事课堂布局包",
-    scene: "小学低年级",
-    description: "故事导入、情境欣赏和童趣互动",
+    id: "fairytale-forest",
+    name: "童话森林",
+    sourceName: "参考《动画音乐会》的童话场景语言",
+    scene: "低年级歌曲与律动",
+    description: "绘本场景、故事导入和童趣互动",
     baseStyle: "cartoon",
     layoutFamily: "story",
     typography: "圆润醒目的低龄课堂字体层级,标题短而大,正文不低于30px",
@@ -111,15 +111,15 @@ export const AI_COURSEWARE_TEMPLATES: AiCoursewareTemplate[] = [
       practice: "practice_check",
       summary: "visual_summary"
     },
-    visualPrompt: "趣味手绘课堂风格,画面亲切活泼,使用统一插画语言和明确场景,避免商务卡片堆叠。",
+    visualPrompt: "童话森林音乐课堂风格,画面亲切活泼,使用统一绘本场景、自然边框和明确文字区,避免商务卡片堆叠。",
     palettes: playfulPalettes
   },
   {
-    id: "fresh-education",
-    name: "清新教育课件",
-    sourceName: "原创清新教育布局包",
-    scene: "常规音乐课",
-    description: "知识讲解、听赏练习和课堂总结",
+    id: "warm-handdrawn",
+    name: "温暖手绘",
+    sourceName: "参考《音乐小屋》的温暖手绘语言",
+    scene: "小学音乐活动",
+    description: "轻柔插画、情境聆听和课堂练习",
     baseStyle: "clean",
     layoutFamily: "education",
     typography: "清晰现代的教学字体层级,标题明确,正文适合远距离投屏",
@@ -137,20 +137,20 @@ export const AI_COURSEWARE_TEMPLATES: AiCoursewareTemplate[] = [
       practice: "practice_check",
       summary: "summary_checklist"
     },
-    visualPrompt: "清新教育课件风格,留白充足、结构清楚、色彩温和,兼顾教师讲解和学生远距离阅读。",
+    visualPrompt: "温暖手绘音乐课件风格,留白充足、结构清楚、色彩柔和,使用统一儿童手绘元素,兼顾教师讲解和学生远距离阅读。",
     palettes: freshPalettes
   },
   {
-    id: "academic-blue",
-    name: "蓝色学术课堂",
-    sourceName: "原创蓝色学术布局包",
-    scene: "初高中课堂",
-    description: "乐理、作品结构和知识密集型内容",
+    id: "stage-documentary",
+    name: "舞台纪实",
+    sourceName: "参考《鼓乐》的写实音乐现场氛围",
+    scene: "世界音乐与演出欣赏",
+    description: "大图舞台、演出现场和音乐文化体验",
     baseStyle: "clean",
     layoutFamily: "academic",
-    typography: "严谨的标题、正文和注释三级层级",
-    backgroundStyle: "克制蓝灰背景与清晰内容分区",
-    illustrationStyle: "写实乐器、谱例和结构图优先",
+    typography: "具有演出节目单感的标题、正文和注释三级层级",
+    backgroundStyle: "深浅对比的舞台画面与克制文字承载区",
+    illustrationStyle: "写实演出、乐器和地域音乐素材优先",
     pageLayouts: {
       cover: "cover_scene",
       intro: "full_image_question",
@@ -162,13 +162,13 @@ export const AI_COURSEWARE_TEMPLATES: AiCoursewareTemplate[] = [
       practice: "practice_check",
       summary: "summary_checklist"
     },
-    visualPrompt: "蓝色学术课堂风格,严谨克制、层级明确,强化标题、数据和谱例焦点,减少无关装饰。",
-    palettes: academicPalettes
+    visualPrompt: "舞台纪实音乐课堂风格,以高质量演出或音乐文化大图建立氛围,文字置于清晰承载区,标题有节目单感,减少无关装饰。",
+    palettes: stagePalettes
   },
   {
-    id: "oriental-culture",
-    name: "东方文化课堂",
-    sourceName: "原创东方文化布局包",
+    id: "ink-wash",
+    name: "水墨国风",
+    sourceName: "参考《姑苏行》《十面埋伏》的东方意境",
     scene: "传统文化主题",
     description: "民歌、戏曲、民族音乐和传统节日",
     baseStyle: "clean",
@@ -187,20 +187,20 @@ export const AI_COURSEWARE_TEMPLATES: AiCoursewareTemplate[] = [
       practice: "practice_check",
       summary: "visual_summary"
     },
-    visualPrompt: "现代东方文化课堂风格,使用米白、黛色和朱砂色,装饰克制,突出传统文化意境与课堂可读性。",
+    visualPrompt: "水墨国风音乐课堂风格,使用米白、黛色和朱砂色,借景留白、装饰克制,突出传统器乐意境与课堂可读性。",
     palettes: orientalPalettes
   },
   {
-    id: "digital-tech",
-    name: "数字科技课堂",
-    sourceName: "原创数字科技布局包",
-    scene: "音乐科技主题",
-    description: "电子音乐、数字工具和声音科技",
+    id: "modern-geometry",
+    name: "现代几何",
+    sourceName: "参考《探索旋律结构的规律》的现代几何版式",
+    scene: "项目学习与乐理分析",
+    description: "结构讲解、旋律分析和知识项目展示",
     baseStyle: "clean",
     layoutFamily: "technology",
-    typography: "高对比科技标题与简洁正文层级",
-    backgroundStyle: "深色网格、光点和节点背景",
-    illustrationStyle: "统一数字音乐科技视觉,避免无关赛博装饰",
+    typography: "高对比现代标题与简洁正文层级",
+    backgroundStyle: "浅色几何分区、轻量网格和清晰信息层级",
+    illustrationStyle: "统一等距几何和音乐结构图形,避免无关赛博装饰",
     pageLayouts: {
       cover: "cover_scene",
       intro: "full_image_question",
@@ -212,15 +212,15 @@ export const AI_COURSEWARE_TEMPLATES: AiCoursewareTemplate[] = [
       practice: "practice_check",
       summary: "visual_summary"
     },
-    visualPrompt: "数字科技课堂风格,深色背景配高对比蓝青光感,使用克制的网格和节点元素,保证教学文字清晰。",
-    palettes: techPalettes
+    visualPrompt: "现代几何音乐课堂风格,使用浅色几何分区、等距图形和绿色蓝色点缀,突出旋律结构、项目步骤和知识关系。",
+    palettes: geometryPalettes
   },
   {
-    id: "active-classroom",
-    name: "活力互动课堂",
-    sourceName: "原创互动课堂布局包",
-    scene: "课堂活动",
-    description: "分组练习、节奏游戏、表演与展示",
+    id: "music-doodle",
+    name: "音符涂鸦",
+    sourceName: "参考《溜冰圆舞曲》的音符涂鸦语言",
+    scene: "乐理、节奏与欣赏",
+    description: "音符插画、节奏任务和轻松知识讲解",
     baseStyle: "cartoon",
     layoutFamily: "activity",
     typography: "大字号动作指令与清晰编号层级",
@@ -238,8 +238,8 @@ export const AI_COURSEWARE_TEMPLATES: AiCoursewareTemplate[] = [
       practice: "practice_check",
       summary: "visual_summary"
     },
-    visualPrompt: "活力互动课堂风格,节奏感强、色彩明快,用清晰编号和动作路径组织任务,避免信息拥挤。",
-    palettes: activePalettes
+    visualPrompt: "音符涂鸦音乐课堂风格,使用深蓝手绘音符、轻量星点和清晰任务编号,轻松但不幼稚,避免信息拥挤。",
+    palettes: doodlePalettes
   }
 ]
 
@@ -264,22 +264,25 @@ export function recommendAiCoursewareTemplate(outline: AiCoursewareOutline): { i
     .filter(Boolean)
     .join(" ")
 
-  if (/民歌|民族|戏曲|京剧|昆曲|古琴|国乐|传统|节日|非遗|中国风/.test(text)) {
-    return { id: "oriental-culture", reason: "课程包含传统文化或民族音乐内容" }
+  if (/民歌|民族|戏曲|京剧|昆曲|古琴|国乐|传统|节日|非遗|中国风|民乐|古筝|二胡|琵琶/.test(text)) {
+    return { id: "ink-wash", reason: "课程包含传统文化、民乐或民族音乐内容" }
   }
-  if (/电子音乐|数字音乐|音乐科技|人工智能|AI|编曲软件|录音|声学|科技/.test(text)) {
-    return { id: "digital-tech", reason: "课程包含数字音乐或声音科技内容" }
+  if (/旋律结构|曲式|乐理|和声|分析|项目|探究|规律|结构/.test(text)) {
+    return { id: "modern-geometry", reason: "课程以结构分析、项目探究或乐理讲解为主" }
   }
-  if (/分组|小组|节奏游戏|律动|表演|展示|闯关|任务|活动/.test(text)) {
-    return { id: "active-classroom", reason: "课程以课堂活动和学生参与为主" }
+  if (/分组|小组|节奏游戏|律动|表演|展示|闯关|任务|活动|节拍|节奏/.test(text)) {
+    return { id: "music-doodle", reason: "课程以节奏任务、互动练习或学生参与为主" }
   }
-  if (/[初高]中|七年级|八年级|九年级|乐理|曲式|和声|结构|分析|鉴赏/.test(text)) {
-    return { id: "academic-blue", reason: "课程年级或内容需要更严谨的知识呈现" }
+  if (/世界音乐|打击乐|鼓乐|管弦乐|交响乐|音乐会|舞台|演出|爵士|摇滚|非洲|拉丁/.test(text)) {
+    return { id: "stage-documentary", reason: "课程适合以音乐现场或文化影像建立氛围" }
   }
-  if (/一年级|二年级|三年级|低年级|故事|童话|动物|情境/.test(text)) {
-    return { id: "playful-handdrawn", reason: "课程面向低龄学生或采用故事化导入" }
+  if (/[初高]中|七年级|八年级|九年级/.test(text)) {
+    return { id: "stage-documentary", reason: "课程面向中学阶段,适合更成熟的演出与音乐文化视觉" }
   }
-  return { id: "fresh-education", reason: "适合常规音乐课堂的讲解与练习结构" }
+  if (/一年级|二年级|低年级|故事|童话|动物|情境|儿歌/.test(text)) {
+    return { id: "fairytale-forest", reason: "课程面向低龄学生或采用故事化导入" }
+  }
+  return { id: "warm-handdrawn", reason: "适合常规小学音乐课的聆听、演唱与练习结构" }
 }
 
 function palette(

+ 7 - 7
src/utils/aiPptTemplateEngine.ts

@@ -112,30 +112,30 @@ function buildSlide(page: AiCoursewarePage, outline: AiCoursewareOutline, palett
 function templateDecorationElements(templateId: AiCoursewareTemplateId | undefined, palette: Palette, role: PageRole): PPTElement[] {
   if (!templateId || role === "cover") return []
   switch (templateId) {
-    case "playful-handdrawn":
+    case "fairytale-forest":
       return [
         shapeElement({ left: 1450, top: 36, width: 74, height: 74, fill: palette.warm, opacity: 0.5, radius: 37 }),
         shapeElement({ left: 1518, top: 92, width: 42, height: 42, fill: palette.accent, opacity: 0.45, radius: 21 }),
         shapeElement({ left: 26, top: 792, width: 58, height: 58, fill: palette.secondary, opacity: 0.26, radius: 29 })
       ]
-    case "fresh-education":
+    case "warm-handdrawn":
       return [
         shapeElement({ left: 0, top: 0, width: 1600, height: 12, fill: palette.secondary, opacity: 0.85, radius: 0 }),
         shapeElement({ left: 1530, top: 742, width: 70, height: 158, fill: palette.soft, opacity: 0.8, radius: 0 })
       ]
-    case "academic-blue":
+    case "stage-documentary":
       return [
         shapeElement({ left: 0, top: 0, width: 1600, height: 18, fill: palette.primary, radius: 0 }),
         shapeElement({ left: 1548, top: 38, width: 18, height: 132, fill: palette.accent, radius: 0 }),
         shapeElement({ left: 1574, top: 38, width: 8, height: 84, fill: palette.secondary, radius: 0 })
       ]
-    case "oriental-culture":
+    case "ink-wash":
       return [
         shapeElement({ left: 1460, top: 42, width: 88, height: 88, fill: palette.primary, opacity: 0.14, radius: 44 }),
         shapeElement({ left: 1499, top: 52, width: 10, height: 68, fill: palette.primary, opacity: 0.62, radius: 2 }),
         shapeElement({ left: 1434, top: 148, width: 114, height: 4, fill: palette.accent, opacity: 0.55, radius: 2 })
       ]
-    case "digital-tech":
+    case "modern-geometry":
       return [
         shapeElement({ left: 80, top: 120, width: 1440, height: 2, fill: palette.secondary, opacity: 0.16, radius: 0 }),
         shapeElement({ left: 80, top: 780, width: 1440, height: 2, fill: palette.primary, opacity: 0.16, radius: 0 }),
@@ -143,7 +143,7 @@ function templateDecorationElements(templateId: AiCoursewareTemplateId | undefin
         shapeElement({ left: 1480, top: 80, width: 2, height: 740, fill: palette.primary, opacity: 0.12, radius: 0 }),
         shapeElement({ left: 1468, top: 108, width: 26, height: 26, fill: palette.secondary, opacity: 0.75, radius: 4 })
       ]
-    case "active-classroom":
+    case "music-doodle":
       return [
         shapeElement({ left: 1390, top: 30, width: 58, height: 18, fill: palette.accent, radius: 9 }),
         shapeElement({ left: 1458, top: 30, width: 92, height: 18, fill: palette.secondary, radius: 9 }),
@@ -1456,7 +1456,7 @@ function slideRemark(page: AiCoursewarePage) {
 }
 
 function buildPalette(outline: AiCoursewareOutline, variant: number, templateId?: AiCoursewareTemplateId): Palette {
-  const fallbackTemplate = outline.style === "cartoon" ? "playful-handdrawn" : "fresh-education"
+  const fallbackTemplate = outline.style === "cartoon" ? "fairytale-forest" : "warm-handdrawn"
   return { ...getAiCoursewarePalette(templateId || fallbackTemplate, variant) }
 }
 

+ 3 - 2
src/views/Editor/EditorHeader/AiCoursewareDialog.vue

@@ -469,7 +469,7 @@ const workflowSteps = [
 ] as const
 const taskMode = ref<"full" | "sample">("full")
 const coursewareTemplates = AI_COURSEWARE_TEMPLATES
-const selectedTemplateId = ref<AiCoursewareTemplateId>("fresh-education")
+const selectedTemplateId = ref<AiCoursewareTemplateId>("warm-handdrawn")
 const templateSelectionMode = ref<"auto" | "manual">("auto")
 const templatePickerExpanded = ref(false)
 const paletteVariant = ref(0)
@@ -500,7 +500,7 @@ const selectedStyle = computed(() => selectedTemplate.value.baseStyle)
 const templateRecommendation = computed(() =>
   outline.value
     ? recommendAiCoursewareTemplate(outline.value)
-    : { id: "fresh-education" as AiCoursewareTemplateId, reason: "生成大纲后将根据课程内容自动推荐" }
+    : { id: "warm-handdrawn" as AiCoursewareTemplateId, reason: "生成大纲后将根据课程内容自动推荐" }
 )
 const recommendedTemplate = computed(() => getAiCoursewareTemplate(templateRecommendation.value.id))
 const progressValue = computed(() => taskInfo.value?.progress || 0)
@@ -626,6 +626,7 @@ watch(
   outline,
   () => {
     if (!outline.value) return
+    if (templateSelectionMode.value === "auto") selectedTemplateId.value = templateRecommendation.value.id
     invalidateVisualApproval()
   },
   { deep: true }

Некоторые файлы не были показаны из-за большого количества измененных файлов