|
|
@@ -213,6 +213,46 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
+ <!-- AI 配置 -->
|
|
|
+ <div class="ai-config-section">
|
|
|
+ <button class="section-toggle" @click="aiConfigExpanded = !aiConfigExpanded">
|
|
|
+ <span class="section-toggle-label">{{ lang.ssAiConfig }}</span>
|
|
|
+ <svg
|
|
|
+ class="section-toggle-arrow"
|
|
|
+ :class="{ collapsed: !aiConfigExpanded }"
|
|
|
+ width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
|
+ >
|
|
|
+ <path d="M6 9l6 6 6-6" />
|
|
|
+ </svg>
|
|
|
+ </button>
|
|
|
+
|
|
|
+ <div v-if="aiConfigExpanded" class="ai-config-body">
|
|
|
+ <div class="form-row">
|
|
|
+ <label class="form-label">{{ lang.ssCustomGreeting }}</label>
|
|
|
+ <textarea
|
|
|
+ class="form-textarea"
|
|
|
+ rows="3"
|
|
|
+ :value="activeGreeting"
|
|
|
+ @input="onGreetingInput(($event.target as HTMLTextAreaElement).value)"
|
|
|
+ />
|
|
|
+ <div class="form-hint">{{ lang.ssCustomGreetingHint }}</div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="form-row">
|
|
|
+ <label class="form-label">{{ lang.ssCustomSystemPrompt }}</label>
|
|
|
+ <textarea
|
|
|
+ class="form-textarea"
|
|
|
+ rows="10"
|
|
|
+ :value="activeSystemPrompt"
|
|
|
+ @input="onSystemPromptInput(($event.target as HTMLTextAreaElement).value)"
|
|
|
+ />
|
|
|
+ <div v-if="store.config.videoScene.enabled" class="form-hint">
|
|
|
+ {{ lang.ssCustomSystemPromptPlaceholderHint }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
<!-- 分割线 -->
|
|
|
<div class="section-spacer"></div>
|
|
|
|
|
|
@@ -339,7 +379,7 @@
|
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
-import { ref, nextTick } from 'vue'
|
|
|
+import { ref, computed, nextTick } from 'vue'
|
|
|
import { storeToRefs } from 'pinia'
|
|
|
import { lang } from '@/main'
|
|
|
import { useSpeakingStore } from '@/store/speaking'
|
|
|
@@ -357,6 +397,35 @@ const store = useSpeakingStore()
|
|
|
// UI 状态
|
|
|
const learningGoalsExpanded = ref(true)
|
|
|
const advancedExpanded = ref(false)
|
|
|
+const aiConfigExpanded = ref(true)
|
|
|
+
|
|
|
+// AI 配置 — 按当前模式路由到对应 store slot
|
|
|
+const activeGreeting = computed(() =>
|
|
|
+ store.config.videoScene.enabled
|
|
|
+ ? store.config.videoScene.greeting
|
|
|
+ : store.config.nonVideoScene.greeting
|
|
|
+)
|
|
|
+const activeSystemPrompt = computed(() =>
|
|
|
+ store.config.videoScene.enabled
|
|
|
+ ? store.config.videoScene.systemPrompt
|
|
|
+ : store.config.nonVideoScene.systemPrompt
|
|
|
+)
|
|
|
+
|
|
|
+function onGreetingInput(value: string) {
|
|
|
+ if (store.config.videoScene.enabled) {
|
|
|
+ store.config.videoScene.greeting = value
|
|
|
+ } else {
|
|
|
+ store.config.nonVideoScene.greeting = value
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function onSystemPromptInput(value: string) {
|
|
|
+ if (store.config.videoScene.enabled) {
|
|
|
+ store.config.videoScene.systemPrompt = value
|
|
|
+ } else {
|
|
|
+ store.config.nonVideoScene.systemPrompt = value
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
// 词汇新增
|
|
|
const isAddingVocab = ref(false)
|
|
|
@@ -1090,4 +1159,51 @@ const handleApply = async () => {
|
|
|
background: #ea580c;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+// AI 配置区
|
|
|
+.ai-config-section {
|
|
|
+ padding: 12px 0;
|
|
|
+
|
|
|
+ .ai-config-body {
|
|
|
+ margin-top: 12px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 16px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .form-row {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 6px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .form-label {
|
|
|
+ font-size: 13px;
|
|
|
+ font-weight: 500;
|
|
|
+ color: #374151;
|
|
|
+ }
|
|
|
+
|
|
|
+ .form-textarea {
|
|
|
+ width: 100%;
|
|
|
+ padding: 8px 12px;
|
|
|
+ border: 1px solid #d1d5db;
|
|
|
+ border-radius: 6px;
|
|
|
+ font-size: 13px;
|
|
|
+ font-family: inherit;
|
|
|
+ line-height: 1.5;
|
|
|
+ resize: vertical;
|
|
|
+ box-sizing: border-box;
|
|
|
+
|
|
|
+ &:focus {
|
|
|
+ outline: none;
|
|
|
+ border-color: #3b82f6;
|
|
|
+ box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .form-hint {
|
|
|
+ font-size: 12px;
|
|
|
+ color: #6b7280;
|
|
|
+ }
|
|
|
+}
|
|
|
</style>
|