Detail.vue 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. <template>
  2. <el-dialog title="计划详情" :visible.sync="dialogVisible" width="880px" @open="load">
  3. <div class="detail-wrap" v-loading="loading">
  4. <div class="block">
  5. <h4>基本信息</h4>
  6. <div class="info-grid" v-if="plan">
  7. <div class="info-item"><label>计划名称</label><span>{{ plan.planName || '-' }}</span></div>
  8. <div class="info-item"><label>计划类型</label><span>{{ planTypeText(plan.planType) }}</span></div>
  9. <div class="info-item"><label>巡检周期</label><span>{{ cycleText(plan.cycleType) }}</span></div>
  10. <div class="info-item"><label>日期范围</label><span>{{ fmt(plan.startDate) }} ~ {{ fmt(plan.endDate) }}</span></div>
  11. <div class="info-item"><label>下次执行</label><span>{{ fmt(plan.nextExecuteDate) }}</span></div>
  12. <div class="info-item"><label>巡检员</label><span>{{ plan.inspectorName || '-' }}</span></div>
  13. <div class="info-item"><label>门店数</label><span>{{ plan.storeCount || 0 }}</span></div>
  14. <div class="info-item"><label>状态</label><span><el-tag size="mini" :type="planStatus(plan.status).type">{{ planStatus(plan.status).text }}</el-tag></span></div>
  15. <div class="info-item"><label>自动采集</label><span>{{ plan.autoCollectFlag === 1 ? '开启' : '关闭' }}</span></div>
  16. <div class="info-item full"><label>备注</label><span>{{ plan.rmk || '-' }}</span></div>
  17. </div>
  18. </div>
  19. <div class="block">
  20. <h4>关联指标({{ indicators.length }})</h4>
  21. <el-table :data="indicators" border size="mini" max-height="260">
  22. <el-table-column prop="indicatorName" label="指标名称" min-width="130" />
  23. <el-table-column label="类型" width="80">
  24. <template slot-scope="s"><el-tag size="mini" :type="s.row.indicatorType === 1 ? 'primary' : 'warning'">{{ s.row.indicatorType === 1 ? '自动' : '人工' }}</el-tag></template>
  25. </el-table-column>
  26. <el-table-column prop="maxScore" label="满分" width="70" align="center" />
  27. <el-table-column prop="passScore" label="及格分" width="70" align="center" />
  28. <el-table-column prop="weight" label="权重%" width="80" align="center" />
  29. </el-table>
  30. </div>
  31. <div class="block">
  32. <h4>关联门店({{ stores.length }})</h4>
  33. <el-table :data="stores" border size="mini" max-height="260">
  34. <el-table-column prop="storeName" label="门店名称" min-width="160" />
  35. <el-table-column prop="storeBelongto" label="归属校区" width="100" />
  36. <el-table-column prop="province" label="省" width="80" />
  37. <el-table-column prop="city" label="市" width="80" />
  38. </el-table>
  39. </div>
  40. <div class="block">
  41. <div class="block-head">
  42. <h4>已生成任务({{ tasks.length }})</h4>
  43. <el-button type="primary" size="mini" @click="$emit('generate', plan && plan.planId)">生成任务</el-button>
  44. </div>
  45. <el-table :data="tasks" border size="mini" max-height="280">
  46. <el-table-column prop="taskId" label="任务ID" width="80" />
  47. <el-table-column prop="storeName" label="门店" min-width="140" />
  48. <el-table-column label="执行日期" width="110">
  49. <template slot-scope="s">{{ fmt(s.row.taskDate) }}</template>
  50. </el-table-column>
  51. <el-table-column label="总分" width="100">
  52. <template slot-scope="s">{{ fmtNum(s.row.totalScore) }}/{{ fmtNum(s.row.maxScore) }}</template>
  53. </el-table-column>
  54. <el-table-column label="结果" width="80">
  55. <template slot-scope="s">
  56. <el-tag v-if="s.row.status === 3" size="mini" :type="s.row.passFlag === 1 ? 'success' : 'danger'">{{ s.row.passFlag === 1 ? '及格' : '不及格' }}</el-tag>
  57. <span v-else>-</span>
  58. </template>
  59. </el-table-column>
  60. <el-table-column label="状态" width="90">
  61. <template slot-scope="s"><el-tag size="mini" :type="taskStatus(s.row.status).type">{{ taskStatus(s.row.status).text }}</el-tag></template>
  62. </el-table-column>
  63. </el-table>
  64. <div class="empty" v-if="!tasks.length">该计划暂未生成任务,可点击“生成任务”按执行日期创建。</div>
  65. </div>
  66. </div>
  67. </el-dialog>
  68. </template>
  69. <script>
  70. import { post, fmt, fmtNum, PLAN_TYPE, CYCLE_TYPE, PLAN_STATUS, TASK_STATUS } from '../common'
  71. export default {
  72. name: 'InspectPlanDetail',
  73. props: {
  74. visible: Boolean,
  75. planId: [Number, String]
  76. },
  77. computed: {
  78. dialogVisible: {
  79. get() { return this.visible },
  80. set(v) { this.$emit('update:visible', v) }
  81. }
  82. },
  83. data() {
  84. return { loading: false, plan: null, indicators: [], stores: [], tasks: [] }
  85. },
  86. methods: {
  87. load() {
  88. if (!this.planId) return
  89. this.loading = true
  90. Promise.all([
  91. post(this.$axios, '/inspectPlanManage/getPlanDetail', { id: this.planId }),
  92. post(this.$axios, '/inspectPlanManage/getPlanIndicators', { planId: this.planId }),
  93. post(this.$axios, '/inspectPlanManage/getPlanStores', { planId: this.planId }),
  94. post(this.$axios, '/inspectTaskManage/getTaskPage', { planId: this.planId, pageSize: 50, currentPage: 1 })
  95. ]).then(([r1, r2, r3, r4]) => {
  96. this.plan = (r1 && r1.obj) || null
  97. this.indicators = (r2 && r2.list) || []
  98. this.stores = (r3 && r3.list) || []
  99. this.tasks = (r4 && r4.list) || []
  100. }).finally(() => { this.loading = false })
  101. },
  102. planStatus(v) { return PLAN_STATUS[v] || { text: '-', type: 'info' } },
  103. taskStatus(v) { return TASK_STATUS[v] || { text: '-', type: 'info' } },
  104. planTypeText(v) { return PLAN_TYPE[v] || '-' },
  105. cycleText(v) { return CYCLE_TYPE[v] || '-' },
  106. fmt,
  107. fmtNum
  108. }
  109. }
  110. </script>
  111. <style scoped>
  112. .detail-wrap { max-height: 560px; overflow-y: auto; }
  113. .block { margin-bottom: 18px; }
  114. .block h4 { margin: 0 0 10px; color: #303133; }
  115. .info-grid { display: flex; flex-wrap: wrap; background: #fafbfc; border: 1px solid #ebeef5; border-radius: 4px; padding: 6px 0; }
  116. .info-item { width: 33.33%; display: flex; padding: 8px 14px; box-sizing: border-box; }
  117. .info-item.full { width: 100%; }
  118. .info-item label { width: 74px; color: #909399; flex-shrink: 0; }
  119. .block-head { display: flex; justify-content: space-between; align-items: center; }
  120. .empty { color: #909399; padding: 12px 0; }
  121. </style>