| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- <template>
- <div class="crowd-task-view">
- <el-card v-if="current">
- <template #header>
- <div class="header">
- <span class="title">客群任务详情</span>
- </div>
- </template>
- <!-- 基本信息 -->
- <div class="section-title">基本信息</div>
- <el-descriptions :column="2" border>
- <el-descriptions-item label="客群名称">{{ current.name }}</el-descriptions-item>
- <el-descriptions-item label="客群编号">{{ current.id }}</el-descriptions-item>
- <el-descriptions-item label="状态">
- <el-tag :type="statusTagType(current.status)" size="small">{{ statusLabel(current.status) }}</el-tag>
- </el-descriptions-item>
- <el-descriptions-item label="客群描述" :span="2">{{ current.description || '-' }}</el-descriptions-item>
- <el-descriptions-item label="任务开始/结束日期" :span="2">
- {{ current.startDate }} ~ {{ current.endDate }}
- </el-descriptions-item>
- <el-descriptions-item label="任务创建时间">{{ current.createdAt }}</el-descriptions-item>
- <el-descriptions-item label="任务创建用户">{{ current.creator }}</el-descriptions-item>
- <el-descriptions-item label="审核人">{{ current.reviewer || '-' }}</el-descriptions-item>
- <el-descriptions-item label="最近更新时间">{{ current.updatedAt }}</el-descriptions-item>
- </el-descriptions>
- <!-- 规则组信息 -->
- <div class="section-title" style="margin-top: 24px">规则组信息</div>
- <div class="rule-group-meta">
- <span class="meta-label">规则组间逻辑:</span>
- <span>{{ current.ruleGroupLogic === 'AND' ? 'and/且' : 'or/或' }}</span>
- </div>
- <div class="rule-group-meta">
- <span class="meta-label">规则组详情:</span>
- </div>
- <el-table :data="current.ruleGroups || []" border style="width: 100%" empty-text="无规则组">
- <el-table-column prop="id" label="规则组编号" width="170" align="center" />
- <el-table-column prop="name" label="规则组名称" min-width="160" show-overflow-tooltip />
- <el-table-column prop="description" label="规则组描述" min-width="200" show-overflow-tooltip />
- <el-table-column label="规则组内逻辑" width="120" align="center">
- <template #default="scope">{{ scope.row.logic === 'AND' ? 'and/且' : 'or/或' }}</template>
- </el-table-column>
- <el-table-column prop="ruleCount" label="规则个数" width="90" align="center" />
- </el-table>
- <!-- 运行信息 -->
- <div class="section-title" style="margin-top: 24px">运行信息</div>
- <div class="run-info">
- <div class="run-row">
- <span class="run-label">总数(count):</span>
- <span class="run-value">{{ countDisplay }}</span>
- </div>
- <div class="run-row">
- <span class="run-label">校验(sample):</span>
- <span class="run-value">
- <el-link
- v-if="sampleAvailable"
- type="primary"
- :underline="false"
- @click="showSample = true"
- >详情</el-link>
- <span v-else-if="current.run.sample === 'running'" class="muted">详情</span>
- <span v-else class="muted">未运行</span>
- </span>
- <el-button
- size="small"
- type="primary"
- :disabled="!canRerun"
- style="margin-left: 16px"
- @click="handleRerun"
- >重新校验</el-button>
- </div>
- <div class="run-row">
- <span class="run-label">全量圈客(fulllist):</span>
- <span :class="['run-value', fulllistClass]">{{ fulllistDisplay }}</span>
- </div>
- </div>
- <div class="footer">
- <el-button type="primary" @click="$router.push('/customization/hsbc/crowd-tasks')">返回</el-button>
- </div>
- </el-card>
- <sample-detail-dialog
- v-model:visible="showSample"
- :rows="sampleRows"
- />
- </div>
- </template>
- <script>
- import { ElMessage, ElMessageBox } from 'element-plus'
- import crowdTaskStore from '@/store/crowdTaskStore'
- import SampleDetailDialog from '@/components/crowdTask/SampleDetailDialog.vue'
- export default {
- name: 'CrowdTaskView',
- components: { SampleDetailDialog },
- data() {
- return { current: null, showSample: false }
- },
- computed: {
- sampleAvailable() {
- return this.current && Array.isArray(this.current.run.sample) && this.current.run.sample.length > 0
- },
- sampleRows() {
- return this.sampleAvailable ? this.current.run.sample : []
- },
- countDisplay() {
- const c = this.current && this.current.run.count
- if (c === null || c === undefined) return '未运行'
- if (c === 'running') return '正在运行'
- return c
- },
- fulllistDisplay() {
- const f = this.current && this.current.run.fulllist
- if (f === null || f === undefined) return '未运行'
- if (f === 'running') return '正在运行'
- if (f === 'completed') return '已完成'
- return f
- },
- fulllistClass() {
- const f = this.current && this.current.run.fulllist
- if (!f) return 'red'
- if (f === 'running') return 'muted'
- return 'green'
- },
- canRerun() {
- if (!this.current) return false
- if (this.current.run.count === 'running' || this.current.run.sample === 'running') return false
- if (this.current.status === 'stopped') return false
- // 任意非"正在运行"且非"已停止"状态都支持运维人员重跑
- return this.current.run.count !== null
- }
- },
- created() {
- const target = crowdTaskStore.getById(this.$route.params.id)
- if (!target) {
- ElMessage.error('任务不存在')
- this.$router.replace('/customization/hsbc/crowd-tasks')
- return
- }
- this.current = target
- },
- methods: {
- statusLabel(s) {
- return { draft: '新建', verifying: '校验', online: '上线', stopped: '已停止' }[s] || s
- },
- statusTagType(s) {
- return { draft: 'info', verifying: 'warning', online: 'success', stopped: 'danger' }[s] || ''
- },
- handleRerun() {
- ElMessageBox.confirm('重新校验将重新运行 count 和 sample,不影响 fullist。', '重新校验', {
- confirmButtonText: '运行', cancelButtonText: '取消', type: 'info'
- }).then(() => {
- crowdTaskStore.rerunCountSample(this.current.id)
- ElMessage.success('已触发重新校验,请稍候查看结果')
- }).catch(() => {})
- }
- }
- }
- </script>
- <style scoped>
- .crowd-task-view { padding: 0; }
- .header { display: flex; align-items: center; justify-content: center; }
- .title { font-size: 16px; font-weight: 600; color: #409EFF; }
- .section-title {
- font-size: 14px; font-weight: 600; color: #303133;
- background: #f5f7fa; padding: 10px 14px; border-radius: 4px;
- margin-bottom: 16px;
- }
- .rule-group-meta { margin: 8px 0; font-size: 13px; color: #606266; }
- .rule-group-meta .meta-label { font-weight: 600; color: #303133; }
- .run-info {
- border: 1px solid #fbbfbf; border-radius: 4px;
- background: #fffaf0; padding: 16px 24px;
- }
- .run-row { display: flex; align-items: center; padding: 6px 0; font-size: 14px; }
- .run-label { width: 160px; color: #303133; font-weight: 600; }
- .run-value { color: #606266; }
- .run-value.red { color: #F56C6C; }
- .run-value.green { color: #67C23A; }
- .muted { color: #c0c4cc; }
- .footer { text-align: center; margin-top: 24px; padding-top: 16px; border-top: 1px solid #ebeef5; }
- </style>
|