detail.vue 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. <template>
  2. <view class="container" v-if="plan">
  3. <view class="card">
  4. <view class="card-header">
  5. <text class="card-title">{{ plan.name || '测评方案' }}</text>
  6. <text class="status-tag" :class="'status-' + plan.status">{{ statusLabel(plan.status) }}</text>
  7. </view>
  8. <view class="card-body">
  9. <view class="info-row"><text class="label">家庭ID</text><text>{{ plan.familyId }}</text></view>
  10. <view class="info-row"><text class="label">孩子ID</text><text>{{ plan.childId }}</text></view>
  11. <view class="info-row"><text class="label">周期</text><text>{{ plan.totalDays || '-' }} 天</text></view>
  12. <view class="info-row"><text class="label">来源</text><text>{{ plan.source || '-' }}</text></view>
  13. <view class="info-row" v-if="plan.sourceResultId"><text class="label">来源测评</text><text>{{ plan.sourceResultId }}</text></view>
  14. <view class="info-row"><text class="label">创建时间</text><text>{{ formatDate(plan.createdAt) }}</text></view>
  15. <view class="info-row" v-if="plan.reviewedAt"><text class="label">审核时间</text><text>{{ formatDate(plan.reviewedAt) }}</text></view>
  16. <view class="info-row" v-if="plan.activatedAt"><text class="label">激活时间</text><text>{{ formatDate(plan.activatedAt) }}</text></view>
  17. </view>
  18. <view class="card-remark" v-if="plan.remark">
  19. <text class="remark-title">方案说明</text>
  20. <text class="remark-text">{{ plan.remark }}</text>
  21. </view>
  22. </view>
  23. <view class="action-bar" v-if="plan.status === 'generated'">
  24. <button class="btn-approve" @click="handleApprove">批准方案</button>
  25. <button class="btn-reject" @click="handleReject">驳回方案</button>
  26. </view>
  27. <view class="action-bar" v-if="plan.status === 'reviewed'">
  28. <button class="btn-activate" @click="handleActivate">激活方案</button>
  29. </view>
  30. </view>
  31. </template>
  32. <script>
  33. import { getGuidePlanDetail, reviewPlan, activatePlan } from '@/utils/api'
  34. export default {
  35. data() {
  36. return {
  37. plan: null
  38. }
  39. },
  40. onLoad(options) {
  41. if (options.planId) this.loadPlan(options.planId)
  42. },
  43. methods: {
  44. async loadPlan(planId) {
  45. try {
  46. const res = await getGuidePlanDetail({ planId })
  47. if (res.code === 200) this.plan = res.data
  48. } catch (e) { /* ignore */ }
  49. },
  50. statusLabel(s) {
  51. const map = { generated: '待审核', reviewed: '已审核', active: '已激活', completed: '已完成', rejected: '已驳回' }
  52. return map[s] || s
  53. },
  54. formatDate(d) {
  55. if (!d) return '-'
  56. const date = new Date(d)
  57. return date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate()
  58. },
  59. async handleApprove() {
  60. const res = await reviewPlan({ planId: this.plan.id, approved: true })
  61. if (res.code === 200) { uni.showToast({ title: '已批准' }); this.loadPlan(this.plan.id) }
  62. },
  63. async handleReject() {
  64. uni.showModal({
  65. title: '驳回方案',
  66. content: '确定驳回该方案吗?',
  67. success: async (r) => {
  68. if (!r.confirm) return
  69. const res = await reviewPlan({ planId: this.plan.id, approved: false })
  70. if (res.code === 200) { uni.showToast({ title: '已驳回' }); this.loadPlan(this.plan.id) }
  71. }
  72. })
  73. },
  74. async handleActivate() {
  75. uni.showModal({
  76. title: '激活方案',
  77. content: '激活后将生成任务,确定激活?',
  78. success: async (r) => {
  79. if (!r.confirm) return
  80. const res = await activatePlan({ planId: this.plan.id })
  81. if (res.code === 200) { uni.showToast({ title: '已激活' }); this.loadPlan(this.plan.id) }
  82. }
  83. })
  84. }
  85. }
  86. }
  87. </script>
  88. <style scoped>
  89. .container { min-height: 100vh; background: #f5f5f5; padding: 30rpx; }
  90. .card { background: #fff; border-radius: 16rpx; padding: 30rpx; margin-bottom: 30rpx; }
  91. .card-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 24rpx; }
  92. .card-title { font-size: 34rpx; font-weight: bold; }
  93. .status-tag { font-size: 24rpx; padding: 6rpx 16rpx; border-radius: 6rpx; }
  94. .status-generated { background: #fff3cd; color: #856404; }
  95. .status-reviewed { background: #d1ecf1; color: #0c5460; }
  96. .status-active { background: #d4edda; color: #155724; }
  97. .status-completed { background: #e2e3e5; color: #383d41; }
  98. .status-rejected { background: #f8d7da; color: #721c24; }
  99. .card-body { margin-bottom: 20rpx; }
  100. .info-row { display: flex; justify-content: space-between; padding: 16rpx 0; border-bottom: 2rpx solid #f5f5f5; font-size: 28rpx; }
  101. .label { color: #999; }
  102. .card-remark { background: #f8f9fa; border-radius: 12rpx; padding: 20rpx; }
  103. .remark-title { font-size: 28rpx; font-weight: bold; display: block; margin-bottom: 12rpx; }
  104. .remark-text { font-size: 26rpx; color: #666; white-space: pre-wrap; }
  105. .action-bar { display: flex; gap: 20rpx; padding: 0 30rpx; }
  106. .btn-approve { flex: 1; background: #27ae60; color: #fff; border-radius: 40rpx; }
  107. .btn-reject { flex: 1; background: #e74c3c; color: #fff; border-radius: 40rpx; }
  108. .btn-activate { flex: 1; background: #4A9BD7; color: #fff; border-radius: 40rpx; }
  109. </style>