x1ongzhu 1 vuosi sitten
vanhempi
commit
c309be1aa1
3 muutettua tiedostoa jossa 193 lisäystä ja 1 poistoa
  1. 8 0
      src/router/index.js
  2. 7 1
      src/views/MainView.vue
  3. 178 0
      src/views/StoryTemplateView.vue

+ 8 - 0
src/router/index.js

@@ -77,6 +77,14 @@ const router = createRouter({
                     meta: {
                         title: '直播间'
                     }
+                },
+                {
+                    path: '/storyTemplate',
+                    name: 'storyTemplate',
+                    component: () => import('../views/StoryTemplateView.vue'),
+                    meta: {
+                        title: '故事模板'
+                    }
                 }
             ]
         }

+ 7 - 1
src/views/MainView.vue

@@ -65,7 +65,8 @@ import {
     Photo,
     DeviceGamepad,
     Prompt,
-    Camera
+    Camera,
+    Components
 } from '@vicons/tabler'
 import UserAvatar from '@/components/UserAvatar.vue'
 import ChangePwd from '@/components/ChangePwd.vue'
@@ -117,6 +118,11 @@ const menus = [
                 title: '参数设置'
             }
         ]
+    },
+    {
+        name: '/storyTemplate',
+        title: '故事模板',
+        icon: Components
     }
 ]
 function toggleMenu() {

+ 178 - 0
src/views/StoryTemplateView.vue

@@ -0,0 +1,178 @@
+<template>
+    <PagingTable url="/story/templates" :where="where" ref="table">
+        <template #filter>
+            <ElButton :icon="Plus" @click="onEdit()">添加</ElButton>
+        </template>
+        <ElTableColumn prop="id" label="#" width="80" />
+        <ElTableColumn prop="name" label="名称" min-width="120" />
+        <ElTableColumn prop="createdAt" label="创建时间" :formatter="timeFormatter" width="150" />
+        <ElTableColumn label="操作" align="center" width="250">
+            <template #default="{ row }">
+                <ElButton @click="onEdit(row)">编辑</ElButton>
+                <!-- <ElButton @click="onTest(row)">测试</ElButton> -->
+                <ElButton type="danger" @click="onDelete(row)">删除</ElButton>
+            </template>
+        </ElTableColumn>
+    </PagingTable>
+    <EditDialog
+        v-model="showEditDialog"
+        :model="model"
+        :rules="rules"
+        :on-submit="submit"
+        @success="table.refresh()"
+        label-width="120px"
+        width="800px"
+    >
+        <ElFormItem prop="name" label="名称">
+            <ElInput v-model="model.name" placeholder="请输入名称" />
+        </ElFormItem>
+        <ElFormItem prop="firstPrompt" label="配置">
+            <el-tabs v-model="tab" class="w-full">
+                <el-tab-pane label="初始" name="first">
+                    <div class="p-4 rounded bg-neutral-100 dark:border-neutral-900">
+                        <div class="flex items-center mb-4" v-for="(item, i) in model.firstVariables" :key="i">
+                            <span class="w-12 text-right">参数名</span>
+                            <ElInput class="!w-32 ml-1" v-model="item.name" placeholder="请输入参数名" />
+                            <span class="w-12 text-right">描述</span>
+                            <ElInput class="!w-48 ml-1" v-model="item.description" placeholder="请输入描述" />
+                            <ElButton
+                                class="ml-2"
+                                type="danger"
+                                :icon="X"
+                                link
+                                @click="removeVariable('firstVariables', i)"
+                            ></ElButton>
+                        </div>
+                        <ElButton :icon="Plus" @click="addVariable('firstVariables')"></ElButton>
+                    </div>
+                    <ElInput v-model="model.firstPrompt" type="textarea" placeholder="请输入初始提示词" autosize />
+                </el-tab-pane>
+                <el-tab-pane label="继续" name="second">
+                    <div class="p-4 rounded bg-neutral-100 dark:border-neutral-900">
+                        <div class="flex items-center mb-4" v-for="(item, i) in model.continueVariables" :key="i">
+                            <span class="w-12 text-right">参数名</span>
+                            <ElInput class="!w-32 ml-1" v-model="item.name" placeholder="请输入参数名" />
+                            <span class="w-12 text-right">描述</span>
+                            <ElInput class="!w-48 ml-1" v-model="item.description" placeholder="请输入描述" />
+                            <ElButton
+                                class="ml-2"
+                                type="danger"
+                                :icon="X"
+                                link
+                                @click="removeVariable('continueVariables', i)"
+                            ></ElButton>
+                        </div>
+                        <ElButton :icon="Plus" @click="addVariable('continueVariables')"></ElButton>
+                    </div>
+                    <ElInput v-model="model.continuePrompt" type="textarea" placeholder="请输入继续提示词" autosize />
+                </el-tab-pane>
+                <el-tab-pane label="结束" name="third">
+                    <div class="p-4 rounded bg-neutral-100 dark:border-neutral-900">
+                        <div class="flex items-center mb-4" v-for="(item, i) in model.endVariables" :key="i">
+                            <span class="w-12 text-right">参数名</span>
+                            <ElInput class="!w-32 ml-1" v-model="item.name" placeholder="请输入参数名" />
+                            <span class="w-12 text-right">描述</span>
+                            <ElInput class="!w-48 ml-1" v-model="item.description" placeholder="请输入描述" />
+                            <ElButton
+                                class="ml-2"
+                                type="danger"
+                                :icon="X"
+                                link
+                                @click="removeVariable('endVariables', i)"
+                            ></ElButton>
+                        </div>
+                        <ElButton :icon="Plus" @click="addVariable('endVariables')"></ElButton>
+                    </div>
+                    <ElInput v-model="model.endPrompt" type="textarea" placeholder="请输入结束提示词" autosize />
+                </el-tab-pane>
+            </el-tabs>
+        </ElFormItem>
+    </EditDialog>
+    <ElDialog title="测试" v-model="showTestDialog" width="800px">
+        <ElForm :model="testVariables" label-width="120" label-position="right" inline ref="testForm" :rules="testRuls">
+            <ElFormItem v-for="(item, i) in seleted?.variables" :key="i" :label="item.description" :prop="item.name">
+                <ElInput v-model="testVariables[item.name]" />
+            </ElFormItem>
+        </ElForm>
+        <ElButton @click="startTest">开始</ElButton>
+    </ElDialog>
+</template>
+<script setup>
+import { computed, ref } from 'vue'
+import PagingTable from '@/components/PagingTable.vue'
+import { useTimeFormatter } from '@/utils/formatter'
+import { Plus, X } from '@vicons/tabler'
+import EditDialog from '@/components/EditDialog.vue'
+import { setupEditDialog } from '@/utils/editDialog'
+import EnumSelect from '@/components/EnumSelect.vue'
+import { UserRole } from '@/enums'
+import { http } from '@/plugins/http'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import { useClipboard } from '@vueuse/core'
+
+const where = ref({})
+const timeFormatter = useTimeFormatter()
+const table = ref(null)
+const model = ref({
+    variables: []
+})
+const rules = {
+    name: [{ required: true, message: '请输入名称', trigger: 'blur' }]
+}
+const { showEditDialog, onEdit } = setupEditDialog(model)
+async function submit() {
+    await http.put(model.value.id ? `/story/templates/${model.value.id}` : '/story/templates', model.value)
+    ElMessage.success('保存成功')
+}
+async function onDelete(row) {
+    await ElMessageBox.confirm('确认删除?', '删除', { type: 'warning' })
+    await http.delete(`/story/templates/${row.id}`)
+    ElMessage.success('删除成功')
+    table.value.refresh()
+}
+function addVariable(v) {
+    model.value[v] = model.value[v] || []
+    model.value[v].push({})
+}
+function removeVariable(v, index) {
+    model.value[v].splice(index, 1)
+}
+const tab = ref('first')
+
+const showTestDialog = ref(false)
+const seleted = ref(null)
+const testForm = ref(null)
+const testRuls = computed(() => {
+    const rules = {}
+    seleted.value?.variables?.forEach((item) => {
+        rules[item.name] = [{ required: true, message: '请输入' + item.description, trigger: 'blur' }]
+    })
+    return rules
+})
+
+const testVariables = ref({
+    variables: {}
+})
+const testResults = ref([])
+function onTest(row) {
+    seleted.value = row
+    testVariables.value = {}
+    testResults.value = []
+    testForm.value?.clearValidate()
+    showTestDialog.value = true
+}
+
+const testLoading = ref(false)
+async function startTest() {
+    await testForm.value.validate()
+    const data = { templateId: seleted.value.id, variables: testVariables.value }
+    testLoading.value = true
+    try {
+        const res = await http.post(`/story/start`, data)
+        testResults.value.push(res)
+    } catch (error) {
+        ElMessage.error(error.message)
+    }
+    testLoading.value = false
+}
+</script>