index.vue 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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="search">
  5. <el-input v-model="queryParams.search" placeholder="请输入模型名称" clearable size="small" @keyup.enter.native="handleQuery" />
  6. </el-form-item>
  7. <el-form-item label="分类" prop="category">
  8. <el-select v-model="queryParams.category" placeholder="请选择分类" clearable size="small">
  9. <el-option v-for="cat in categories" :key="cat" :label="cat" :value="cat" />
  10. </el-select>
  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. <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
  19. </el-row>
  20. <!-- 渠道概览 -->
  21. <el-row :gutter="16" class="mb8">
  22. <el-col :span="4">
  23. <el-card shadow="hover">
  24. <div class="stat-card">
  25. <div class="stat-value">{{ channelInfo.qw || 0 }}</div>
  26. <div class="stat-label">企微渠道</div>
  27. </div>
  28. </el-card>
  29. </el-col>
  30. <el-col :span="4">
  31. <el-card shadow="hover">
  32. <div class="stat-card">
  33. <div class="stat-value" style="color:#67C23A">{{ channelInfo.wx || 0 }}</div>
  34. <div class="stat-label">个微渠道</div>
  35. </div>
  36. </el-card>
  37. </el-col>
  38. <el-col :span="4">
  39. <el-card shadow="hover">
  40. <div class="stat-card">
  41. <div class="stat-value" style="color:#E6A23C">{{ channelInfo.sms || 0 }}</div>
  42. <div class="stat-label">短信渠道</div>
  43. </div>
  44. </el-card>
  45. </el-col>
  46. <el-col :span="4">
  47. <el-card shadow="hover">
  48. <div class="stat-card">
  49. <div class="stat-value" style="color:#F56C6C">{{ channelInfo.ai_call || 0 }}</div>
  50. <div class="stat-label">AI外呼渠道</div>
  51. </div>
  52. </el-card>
  53. </el-col>
  54. </el-row>
  55. <el-table border v-loading="loading" :data="list">
  56. <el-table-column label="配置ID" align="center" prop="id" width="60" />
  57. <el-table-column label="模型名称" align="center" prop="prompt_name" />
  58. <el-table-column label="模型标识" align="center" prop="prompt_key" />
  59. <el-table-column label="分类" align="center" prop="prompt_category" width="100" />
  60. <el-table-column label="使用模型" align="center" prop="model_name" width="100">
  61. <template slot-scope="scope">
  62. <el-tag type="success" size="small">{{ scope.row.model_name || '-' }}</el-tag>
  63. </template>
  64. </el-table-column>
  65. <el-table-column label="角色" align="center" prop="system_role" width="100" show-overflow-tooltip />
  66. <el-table-column label="行业" align="center" prop="industry_type" width="80" />
  67. <el-table-column label="状态" align="center" width="80">
  68. <template slot-scope="scope">
  69. <el-tag v-if="scope.row.enabled===1" type="success" size="small">启用</el-tag>
  70. <el-tag v-else type="info" size="small">禁用</el-tag>
  71. </template>
  72. </el-table-column>
  73. <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="120">
  74. <template slot-scope="scope">
  75. <el-button size="mini" type="text" icon="el-icon-view" @click="handleDetail(scope.row)">详情</el-button>
  76. </template>
  77. </el-table-column>
  78. </el-table>
  79. <pagination v-show="total>0" :total="total" :page.sync="queryParams.page" :limit.sync="queryParams.size" @pagination="getList" />
  80. <!-- 详情弹窗 -->
  81. <el-dialog title="模型配置详情" :visible.sync="detailVisible" width="600px" append-to-body>
  82. <el-descriptions :column="2" border>
  83. <el-descriptions-item label="配置名称">{{ detail.prompt_name }}</el-descriptions-item>
  84. <el-descriptions-item label="标识">{{ detail.prompt_key }}</el-descriptions-item>
  85. <el-descriptions-item label="分类">{{ detail.prompt_category }}</el-descriptions-item>
  86. <el-descriptions-item label="模型">{{ detail.model_name }}</el-descriptions-item>
  87. <el-descriptions-item label="角色">{{ detail.system_role }}</el-descriptions-item>
  88. <el-descriptions-item label="行业">{{ detail.industry_type }}</el-descriptions-item>
  89. <el-descriptions-item label="状态">{{ detail.enabled===1?'启用':'禁用' }}</el-descriptions-item>
  90. </el-descriptions>
  91. <el-divider>提示词配置</el-divider>
  92. <div style="white-space:pre-wrap;max-height:300px;overflow:auto;background:#f5f7fa;padding:10px;font-size:12px">{{ detail.prompt_content }}</div>
  93. </el-dialog>
  94. </div>
  95. </template>
  96. <script>
  97. import { listPrompts, getPrompt, getPromptCategories, getAvailableChannels } from '@/api/workflow/lobster'
  98. export default {
  99. name: 'LobsterModelConfig',
  100. data() {
  101. return {
  102. loading: false,
  103. showSearch: true,
  104. list: [],
  105. total: 0,
  106. categories: [],
  107. channelInfo: {},
  108. detailVisible: false,
  109. detail: {},
  110. queryParams: { page: 1, size: 10, search: null, category: null }
  111. }
  112. },
  113. created() {
  114. this.getList()
  115. this.getCategories()
  116. this.getChannelInfo()
  117. },
  118. methods: {
  119. getList() {
  120. this.loading = true
  121. listPrompts(this.queryParams).then(res => {
  122. let data = res.data || {}
  123. this.list = data.list || []
  124. this.total = data.total || 0
  125. this.loading = false
  126. }).catch(() => { this.loading = false })
  127. },
  128. getCategories() {
  129. getPromptCategories().then(res => { this.categories = res.data || [] })
  130. },
  131. getChannelInfo() {
  132. getAvailableChannels().then(res => { this.channelInfo = res.data || {} })
  133. },
  134. handleQuery() { this.queryParams.page = 1; this.getList() },
  135. resetQuery() { this.resetForm('queryForm'); this.handleQuery() },
  136. handleDetail(row) {
  137. getPrompt(row.id).then(res => { this.detail = res.data || {}; this.detailVisible = true })
  138. }
  139. }
  140. }
  141. </script>
  142. <style scoped>
  143. .stat-card { text-align: center; padding: 10px 0; }
  144. .stat-value { font-size: 24px; font-weight: bold; color: #409EFF; }
  145. .stat-label { font-size: 12px; color: #909399; margin-top: 4px; }
  146. </style>