index.vue 6.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. <template>
  2. <div class="app-container">
  3. <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px">
  4. <el-form-item label="所属租户" prop="companyId">
  5. <el-select v-model="queryParams.companyId" placeholder="全部租户" clearable size="small" @change="handleQuery">
  6. <el-option v-for="item in companyList" :key="item.id" :label="item.companyName" :value="item.id" />
  7. </el-select>
  8. </el-form-item>
  9. <el-form-item label="工作流ID" prop="workflowId">
  10. <el-input v-model="queryParams.workflowId" placeholder="请输入工作流ID" clearable size="small" />
  11. </el-form-item>
  12. <el-form-item>
  13. <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
  14. <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
  15. </el-form-item>
  16. </el-form>
  17. <el-row :gutter="10" class="mb8">
  18. <el-col :span="1.5"><el-button type="success" plain icon="el-icon-check" size="mini" @click="handleBatchAudit(true)">批量通过</el-button></el-col>
  19. <el-col :span="1.5"><el-button type="danger" plain icon="el-icon-close" size="mini" @click="handleBatchAudit(false)">批量驳回</el-button></el-col>
  20. <el-col :span="1.5"><el-button type="primary" plain icon="el-icon-data-analysis" size="mini" @click="handleAnalyze">触发分析</el-button></el-col>
  21. <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
  22. </el-row>
  23. <!-- 统计卡片 -->
  24. <el-row :gutter="16" class="mb8">
  25. <el-col :span="6"><el-card shadow="hover"><div class="stat-card"><div class="stat-value">{{ stats.totalOptimizations || 0 }}</div><div class="stat-label">总优化数</div></div></el-card></el-col>
  26. <el-col :span="6"><el-card shadow="hover"><div class="stat-card"><div class="stat-value" style="color:#E6A23C">{{ stats.pendingCount || 0 }}</div><div class="stat-label">待审核</div></div></el-card></el-col>
  27. <el-col :span="6"><el-card shadow="hover"><div class="stat-card"><div class="stat-value" style="color:#67C23A">{{ stats.appliedCount || 0 }}</div><div class="stat-label">已应用</div></div></el-card></el-col>
  28. <el-col :span="6"><el-card shadow="hover"><div class="stat-card"><div class="stat-value" style="color:#F56C6C">{{ stats.rejectedCount || 0 }}</div><div class="stat-label">已驳回</div></div></el-card></el-col>
  29. </el-row>
  30. <el-table border v-loading="loading" :data="list" @selection-change="handleSelectionChange">
  31. <el-table-column type="selection" width="55" align="center" />
  32. <el-table-column label="优化ID" align="center" prop="optimizationId" width="80" />
  33. <el-table-column label="优化原因" align="center" prop="optimizationReason" show-overflow-tooltip />
  34. <el-table-column label="原始话术" align="center" prop="originalContent" show-overflow-tooltip />
  35. <el-table-column label="优化话术" align="center" prop="optimizedContent" show-overflow-tooltip />
  36. <el-table-column label="置信度" align="center" prop="confidence" width="80" />
  37. <el-table-column label="状态" align="center" prop="status" width="80">
  38. <template slot-scope="scope">
  39. <el-tag :type="scope.row.status==='pending'?'warning':scope.row.status==='applied'?'success':'danger'" size="small">{{ scope.row.status }}</el-tag>
  40. </template>
  41. </el-table-column>
  42. <el-table-column label="操作" align="center" width="120">
  43. <template slot-scope="scope">
  44. <el-button v-if="scope.row.status==='pending'" size="mini" type="text" @click="handleAuditSingle(scope.row, true)">通过</el-button>
  45. <el-button v-if="scope.row.status==='pending'" size="mini" type="text" style="color:#F56C6C" @click="handleAuditSingle(scope.row, false)">驳回</el-button>
  46. </template>
  47. </el-table-column>
  48. </el-table>
  49. </div>
  50. </template>
  51. <script>
  52. import { listAllCompanies } from '@/api/workflow/lobster-admin'
  53. import { listPendingAudit, batchAuditOptimization, auditSingleOptimization, getOptimizationStats, analyzeEvolution } from '@/api/workflow/lobster'
  54. export default {
  55. name: 'LobsterOptimization',
  56. data() {
  57. return { loading: false, showSearch: true, list: [], stats: {}, ids: [],
  58. queryParams: { page: 1, pageSize: 20, workflowId: null } }
  59. },
  60. created() { this.getCompanyList()
  61. this.getList(); this.getStats() },
  62. methods: {
  63. getCompanyList() {
  64. listAllCompanies().then(res => { this.companyList = res.data || [] })
  65. },
  66. getList() { this.loading = true; listPendingAudit(this.queryParams).then(res => { this.list = res.data || []; this.loading = false }).catch(() => { this.loading = false }) },
  67. getStats() { getOptimizationStats().then(res => { this.stats = res.data || {} }) },
  68. handleQuery() { this.queryParams.page = 1; this.getList() },
  69. resetQuery() { this.resetForm('queryForm'); this.handleQuery() },
  70. handleSelectionChange(sel) { this.ids = sel.map(s => s.optimizationId) },
  71. handleAuditSingle(row, approved) { auditSingleOptimization(row.optimizationId, approved, '').then(() => { this.$message.success(approved?'已通过':'已驳回'); this.getList(); this.getStats() }) },
  72. handleBatchAudit(approved) {
  73. if (this.ids.length===0) { this.$message.warning('请先选择要审核的项'); return }
  74. let items = this.ids.map(id => ({ optimizationId: id, approved, remark: '' }))
  75. batchAuditOptimization({ auditItems: items, auditRemark: approved?'批量通过':'批量驳回' }).then(() => { this.$message.success('批量审核完成'); this.getList(); this.getStats() })
  76. },
  77. handleAnalyze() {
  78. if (!this.queryParams.workflowId) { this.$message.warning('请输入工作流ID'); return }
  79. analyzeEvolution(this.queryParams.workflowId).then(() => {
  80. this.$message.success('进化分析已触发')
  81. this.getList(); this.getStats()
  82. })
  83. }
  84. }
  85. }
  86. </script>
  87. <style scoped>
  88. .stat-card { text-align: center; padding: 10px 0; }
  89. .stat-value { font-size: 24px; font-weight: bold; color: #409EFF; }
  90. .stat-label { font-size: 12px; color: #909399; margin-top: 4px; }
  91. </style>