فهرست منبع

feat(frontend): 添加"上传新模板"功能

- Home 页新增上传模板对话框
- 支持上传 Word/PDF 文档作为基础文档创建模板
- 与"创建新模板"(空白模板)形成两种创建方式
何文松 1 ماه پیش
والد
کامیت
4e6586e595
1فایلهای تغییر یافته به همراه116 افزوده شده و 1 حذف شده
  1. 116 1
      frontend/vue-demo/src/views/Home.vue

+ 116 - 1
frontend/vue-demo/src/views/Home.vue

@@ -147,13 +147,64 @@
         <el-button type="primary" @click="handleCreateTemplate" :loading="creating">创建</el-button>
       </template>
     </el-dialog>
+
+    <!-- 上传模板对话框 -->
+    <el-dialog v-model="showUploadDialog" title="上传新模板" width="600">
+      <el-form :model="uploadTemplate" label-width="80px">
+        <el-form-item label="模板名称" required>
+          <el-input v-model="uploadTemplate.name" placeholder="请输入模板名称" />
+        </el-form-item>
+        <el-form-item label="描述">
+          <el-input
+            v-model="uploadTemplate.description"
+            type="textarea"
+            :rows="2"
+            placeholder="请输入模板描述(可选)"
+          />
+        </el-form-item>
+        <el-form-item label="基础文档" required>
+          <el-upload
+            class="upload-area"
+            drag
+            action="/api/v1/parse/upload"
+            :on-success="handleUploadSuccess"
+            :on-error="handleUploadError"
+            :show-file-list="true"
+            :limit="1"
+            accept=".doc,.docx,.pdf"
+          >
+            <div v-if="uploadTemplate.baseDocumentId" class="upload-success">
+              <el-icon size="40" color="#52c41a"><CircleCheckFilled /></el-icon>
+              <div>文档已上传</div>
+            </div>
+            <template v-else>
+              <el-icon class="el-icon--upload" size="40"><UploadFilled /></el-icon>
+              <div class="el-upload__text">
+                拖拽文件到此处,或<em>点击上传</em>
+              </div>
+            </template>
+            <template #tip>
+              <div class="el-upload__tip">
+                支持 Word (.doc, .docx) 和 PDF 格式,上传后可标记变量
+              </div>
+            </template>
+          </el-upload>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="showUploadDialog = false">取消</el-button>
+        <el-button type="primary" @click="handleUploadTemplate" :loading="uploading">
+          创建模板
+        </el-button>
+      </template>
+    </el-dialog>
   </div>
 </template>
 
 <script setup>
 import { ref, reactive, computed, onMounted } from 'vue'
 import { useRouter } from 'vue-router'
-import { Promotion } from '@element-plus/icons-vue'
+import { Promotion, UploadFilled, CircleCheckFilled } from '@element-plus/icons-vue'
 import { ElMessage } from 'element-plus'
 import { useTemplateStore } from '@/stores/template'
 import { templateApi } from '@/api'
@@ -193,6 +244,13 @@ const newTemplate = reactive({
 })
 const creating = ref(false)
 
+const uploadTemplate = reactive({
+  name: '',
+  description: '',
+  baseDocumentId: ''
+})
+const uploading = ref(false)
+
 // 推荐模板数据(从 API 获取)
 const recommendTemplates = ref([])
 
@@ -258,6 +316,48 @@ async function handleCreateTemplate() {
     creating.value = false
   }
 }
+
+function handleUploadSuccess(response) {
+  if (response.code === 200) {
+    uploadTemplate.baseDocumentId = response.data.id
+    ElMessage.success('文档上传成功')
+  } else {
+    ElMessage.error('上传失败: ' + (response.msg || '未知错误'))
+  }
+}
+
+function handleUploadError(error) {
+  ElMessage.error('上传失败: ' + error.message)
+}
+
+async function handleUploadTemplate() {
+  if (!uploadTemplate.name) {
+    ElMessage.warning('请输入模板名称')
+    return
+  }
+  if (!uploadTemplate.baseDocumentId) {
+    ElMessage.warning('请上传基础文档')
+    return
+  }
+
+  uploading.value = true
+  try {
+    const template = await templateStore.createTemplate({
+      name: uploadTemplate.name,
+      description: uploadTemplate.description || '',
+      baseDocumentId: uploadTemplate.baseDocumentId
+    })
+    showUploadDialog.value = false
+    // 重置表单
+    Object.assign(uploadTemplate, { name: '', description: '', baseDocumentId: '' })
+    ElMessage.success('模板创建成功')
+    router.push(`/editor/${template.id}`)
+  } catch (error) {
+    ElMessage.error('创建失败: ' + error.message)
+  } finally {
+    uploading.value = false
+  }
+}
 </script>
 
 <style lang="scss" scoped>
@@ -414,4 +514,19 @@ async function handleCreateTemplate() {
     }
   }
 }
+
+.upload-area {
+  width: 100%;
+  
+  .upload-success {
+    text-align: center;
+    padding: 20px;
+    color: #52c41a;
+
+    div {
+      margin-top: 8px;
+      font-size: 14px;
+    }
+  }
+}
 </style>