Просмотр исходного кода

feat(web): 规划师端健康方案结构化任务条目编辑

iwt 3 недель назад
Родитель
Сommit
82e93b3997
1 измененных файлов с 81 добавлено и 2 удалено
  1. 81 2
      cfc-web/src/views/teacher/HealthPlanReview.vue

+ 81 - 2
cfc-web/src/views/teacher/HealthPlanReview.vue

@@ -52,6 +52,27 @@
         <el-form-item label="方案内容">
         <el-form-item label="方案内容">
           <el-input v-model="editForm.planContent" type="textarea" :rows="18" placeholder="编辑方案内容..." />
           <el-input v-model="editForm.planContent" type="textarea" :rows="18" placeholder="编辑方案内容..." />
         </el-form-item>
         </el-form-item>
+        <el-form-item label="任务条目">
+          <div v-for="(sec, si) in editTasks.sections" :key="'sec'+si" style="margin-bottom:12px;border:1px solid #ebeef5;border-radius:4px;padding:8px;">
+            <div style="font-weight:600;margin-bottom:6px;">{{ sec.title || sec.key }}</div>
+            <div v-for="(task, ti) in sec.tasks" :key="'t'+si+'-'+ti" style="display:flex;gap:6px;margin-bottom:6px;align-items:center;">
+              <el-select v-model="task.action_type" size="mini" style="width:90px">
+                <el-option v-for="a in actionTypes" :key="a.value" :label="a.label" :value="a.value" />
+              </el-select>
+              <el-select v-model="task.dimension" size="mini" style="width:80px">
+                <el-option v-for="d in dimensions" :key="d.value" :label="d.label" :value="d.value" />
+              </el-select>
+              <el-select v-model="task.frequency" size="mini" style="width:70px">
+                <el-option label="一次性" value="once" />
+                <el-option label="每日" value="daily" />
+              </el-select>
+              <el-input v-model="task.title" size="mini" placeholder="任务标题" />
+              <el-input v-model="task.notes" size="mini" placeholder="备注" style="width:120px" />
+              <el-button size="mini" type="danger" icon="el-icon-delete" @click="removeTask(si, ti)" />
+            </div>
+            <el-button size="mini" type="text" icon="el-icon-plus" @click="addTask(si)">添加任务</el-button>
+          </div>
+        </el-form-item>
         <el-form-item label="审核意见">
         <el-form-item label="审核意见">
           <el-input v-model="editForm.reviewComment" type="textarea" :rows="3" placeholder="可选:添加审核备注" />
           <el-input v-model="editForm.reviewComment" type="textarea" :rows="3" placeholder="可选:添加审核备注" />
         </el-form-item>
         </el-form-item>
@@ -95,7 +116,23 @@ export default {
       rejecting: false,
       rejecting: false,
       currentPlan: null,
       currentPlan: null,
       editForm: { planContent: '', reviewComment: '' },
       editForm: { planContent: '', reviewComment: '' },
-      rejectForm: { planId: null, comment: '' }
+      rejectForm: { planId: null, comment: '' },
+      editTasks: { sections: [] },
+      actionTypes: [
+        { value: 'buy', label: '购买' },
+        { value: 'read', label: '阅读' },
+        { value: 'exercise', label: '运动' },
+        { value: 'checkin', label: '打卡' },
+        { value: 'diet', label: '饮食' },
+        { value: 'activity', label: '活动' }
+      ],
+      dimensions: [
+        { value: 'body', label: '身' },
+        { value: 'mind', label: '心' },
+        { value: 'wisdom', label: '智' },
+        { value: 'action', label: '行' },
+        { value: 'wealth', label: '富' }
+      ]
     }
     }
   },
   },
   created() {
   created() {
@@ -142,15 +179,17 @@ export default {
         planContent: row.planContent || '',
         planContent: row.planContent || '',
         reviewComment: row.reviewComment || ''
         reviewComment: row.reviewComment || ''
       }
       }
+      this.loadEditTasks(row.planJson)
       this.editVisible = true
       this.editVisible = true
     },
     },
     async saveEdit() {
     async saveEdit() {
       this.saving = true
       this.saving = true
       try {
       try {
+        const newPlanJson = this.buildPlanJsonWithTasks()
         const res = await updatePlanContent({
         const res = await updatePlanContent({
           planId: this.currentPlan.id,
           planId: this.currentPlan.id,
           planContent: this.editForm.planContent,
           planContent: this.editForm.planContent,
-          planJson: this.currentPlan.planJson
+          planJson: newPlanJson
         })
         })
         if (res.code === 200) {
         if (res.code === 200) {
           this.$message.success('保存成功')
           this.$message.success('保存成功')
@@ -165,6 +204,46 @@ export default {
         this.saving = false
         this.saving = false
       }
       }
     },
     },
+    parsePlanJson(str) {
+      try {
+        return JSON.parse(str || '{}')
+      } catch (e) {
+        return {}
+      }
+    },
+    loadEditTasks(planJson) {
+      const parsed = this.parsePlanJson(planJson)
+      const sections = (parsed.sections || []).map(s => ({
+        key: s.key || '',
+        title: s.title || '',
+        tasks: (s.tasks || []).map(t => ({
+          action_type: t.action_type || 'diet',
+          title: t.title || '',
+          dimension: t.dimension || 'body',
+          frequency: t.frequency || 'daily',
+          notes: t.notes || ''
+        }))
+      }))
+      this.editTasks = { sections }
+    },
+    addTask(si) {
+      this.editTasks.sections[si].tasks.push({
+        action_type: 'diet', title: '', dimension: 'body', frequency: 'daily', notes: ''
+      })
+    },
+    removeTask(si, ti) {
+      this.editTasks.sections[si].tasks.splice(ti, 1)
+    },
+    buildPlanJsonWithTasks() {
+      const parsed = this.parsePlanJson(this.currentPlan.planJson)
+      const sections = parsed.sections || []
+      this.editTasks.sections.forEach(es => {
+        const target = sections.find(s => s.key === es.key)
+        if (!target) return
+        target.tasks = es.tasks.filter(t => t.title && t.title.trim())
+      })
+      return JSON.stringify(parsed)
+    },
     showReject(row) {
     showReject(row) {
       this.rejectForm = { planId: row.id, comment: '' }
       this.rejectForm = { planId: row.id, comment: '' }
       this.rejectVisible = true
       this.rejectVisible = true