PlanManagement.vue 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. <template>
  2. <div class="plan-management">
  3. <div class="header">
  4. <h2>方案管理</h2>
  5. <div class="filters">
  6. <el-select v-model="statusFilter" placeholder="状态筛选" clearable @change="loadPlans" style="width:160px">
  7. <el-option label="全部" value="" />
  8. <el-option label="待审核(generated)" value="generated" />
  9. <el-option label="已审核(reviewed)" value="reviewed" />
  10. <el-option label="已激活(active)" value="active" />
  11. <el-option label="已完成(completed)" value="completed" />
  12. <el-option label="已驳回(rejected)" value="rejected" />
  13. </el-select>
  14. <el-input v-model="familySearch" placeholder="搜索家庭ID" style="width:180px;margin-left:10px" @keyup.enter="loadPlans" />
  15. <el-button type="primary" @click="loadPlans" style="margin-left:10px">查询</el-button>
  16. </div>
  17. </div>
  18. <el-table :data="plans" border stripe style="width:100%" :max-height="tableHeight">
  19. <el-table-column prop="id" label="方案ID" width="80" />
  20. <el-table-column prop="familyId" label="家庭ID" width="80" />
  21. <el-table-column prop="childId" label="孩子ID" width="80" />
  22. <el-table-column prop="name" label="方案名称" min-width="180" />
  23. <el-table-column label="状态" width="100">
  24. <template slot-scope="{ row }">
  25. <el-tag :type="statusType(row.status)">{{ statusLabel(row.status) }}</el-tag>
  26. </template>
  27. </el-table-column>
  28. <el-table-column label="进度" width="120">
  29. <template slot-scope="{ row }">
  30. {{ row.completedDays || 0 }} / {{ row.totalDays || '-' }} 天
  31. </template>
  32. </el-table-column>
  33. <el-table-column prop="source" label="来源" width="100" />
  34. <el-table-column prop="createdAt" label="创建时间" width="160" />
  35. <el-table-column prop="reviewedAt" label="审核时间" width="160" />
  36. <el-table-column label="操作" width="180">
  37. <template slot-scope="{ row }">
  38. <el-button size="mini" type="primary" @click="showDetail(row)">详情</el-button>
  39. <el-button v-if="row.status === 'generated'" size="mini" type="success" @click="handleApprove(row)">批准</el-button>
  40. <el-button v-if="row.status === 'reviewed'" size="mini" @click="handleActivate(row)">激活</el-button>
  41. </template>
  42. </el-table-column>
  43. </el-table>
  44. <el-dialog title="方案详情" :visible.sync="detailVisible" width="600px">
  45. <el-form label-width="100px" v-if="currentPlan">
  46. <el-form-item label="方案ID">{{ currentPlan.id }}</el-form-item>
  47. <el-form-item label="家庭ID">{{ currentPlan.familyId }}</el-form-item>
  48. <el-form-item label="孩子ID">{{ currentPlan.childId }}</el-form-item>
  49. <el-form-item label="方案名称">{{ currentPlan.name }}</el-form-item>
  50. <el-form-item label="状态">
  51. <el-tag :type="statusType(currentPlan.status)">{{ statusLabel(currentPlan.status) }}</el-tag>
  52. </el-form-item>
  53. <el-form-item label="周期">{{ currentPlan.totalDays }} 天</el-form-item>
  54. <el-form-item label="进度">{{ currentPlan.completedDays || 0 }} / {{ currentPlan.totalDays || '-' }} 天</el-form-item>
  55. <el-form-item label="来源">{{ currentPlan.source }}</el-form-item>
  56. <el-form-item label="创建时间">{{ currentPlan.createdAt }}</el-form-item>
  57. <el-form-item label="审核时间">{{ currentPlan.reviewedAt || '-' }}</el-form-item>
  58. <el-form-item label="激活时间">{{ currentPlan.activatedAt || '-' }}</el-form-item>
  59. <el-form-item label="备注">
  60. <pre style="white-space:pre-wrap;background:#f5f5f5;padding:12px;border-radius:6px;">{{ currentPlan.remark }}</pre>
  61. </el-form-item>
  62. </el-form>
  63. </el-dialog>
  64. </div>
  65. </template>
  66. <script>
  67. import { listFamilyPlans, reviewPlan, activatePlan } from '@/api/assessment'
  68. export default {
  69. computed: {
  70. tableHeight() {
  71. return window.innerHeight - 300
  72. }
  73. },
  74. data() {
  75. return {
  76. plans: [],
  77. statusFilter: '',
  78. familySearch: '',
  79. detailVisible: false,
  80. currentPlan: null
  81. }
  82. },
  83. created() { this.loadPlans() },
  84. methods: {
  85. async loadPlans() {
  86. const res = await listFamilyPlans({
  87. status: this.statusFilter || null,
  88. familyId: this.familySearch ? Number(this.familySearch) : null
  89. })
  90. if (res.code === 200) this.plans = res.data || []
  91. },
  92. statusType(s) {
  93. const map = { generated: 'warning', reviewed: 'primary', active: 'success', completed: 'info', rejected: 'danger' }
  94. return map[s] || 'info'
  95. },
  96. statusLabel(s) {
  97. const map = { generated: '待审核', reviewed: '已审核', active: '已激活', completed: '已完成', rejected: '已驳回' }
  98. return map[s] || s
  99. },
  100. showDetail(row) {
  101. this.currentPlan = row
  102. this.detailVisible = true
  103. },
  104. async handleApprove(row) {
  105. const res = await reviewPlan({ planId: row.id, approved: true })
  106. if (res.code === 200) { this.$message.success('已批准'); this.loadPlans() }
  107. },
  108. async handleActivate(row) {
  109. await this.$confirm('激活后将生成任务,确定激活?')
  110. const res = await activatePlan({ planId: row.id })
  111. if (res.code === 200) { this.$message.success('已激活'); this.loadPlans() }
  112. }
  113. }
  114. }
  115. </script>
  116. <style scoped>
  117. .header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; }
  118. .filters { display: flex; align-items: center; }
  119. </style>