list.vue 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. <template>
  2. <div class="store-page">
  3. <Breadcrumb />
  4. <a-card title="AI 对话管理">
  5. <AppQueryFilter>
  6. <a-row class="query-row">
  7. <a-col :flex="'1000px'" class="query-main">
  8. <a-form class="app-query-form" :model="queryData" :label-col-props="{ span: 6 }" :wrapper-col-props="{ span: 18 }" label-align="left">
  9. <a-row :gutter="16">
  10. <a-col :span="6">
  11. <a-form-item field="channel" label="消息通道">
  12. <a-input v-model="queryData.channel" allow-clear />
  13. </a-form-item>
  14. </a-col>
  15. <a-col :span="6">
  16. <a-form-item field="id" label="会话编号">
  17. <a-input-number v-model="queryData.id" :precision="0" allow-clear />
  18. </a-form-item>
  19. </a-col>
  20. <a-col :span="6">
  21. <a-form-item field="username" label="用户名">
  22. <a-input v-model="queryData.username" allow-clear />
  23. </a-form-item>
  24. </a-col>
  25. <a-col :span="6">
  26. <a-form-item field="create_user" label="用户UUID">
  27. <a-input v-model="queryData.create_user" allow-clear />
  28. </a-form-item>
  29. </a-col>
  30. <a-col :span="6">
  31. <a-form-item field="state" label="状态">
  32. <a-select v-model="queryData.state">
  33. <a-option :value="-1">全部</a-option>
  34. <a-option :value="1">正常</a-option>
  35. <a-option :value="2">已删除</a-option>
  36. </a-select>
  37. </a-form-item>
  38. </a-col>
  39. <a-col :span="8">
  40. <a-form-item field="queryTime" label="更新时间">
  41. <a-range-picker v-model="queryData.queryTime" show-time value-format="x" popup-container="body" />
  42. </a-form-item>
  43. </a-col>
  44. </a-row>
  45. </a-form>
  46. </a-col>
  47. <a-divider class="query-divider" style="height: 84px" direction="vertical" />
  48. <a-col :flex="1" class="app-query-actions">
  49. <a-space class="query-actions-space" direction="vertical" :size="18">
  50. <a-button type="primary" @click="search">
  51. <template #icon><icon-search /></template>
  52. 搜索
  53. </a-button>
  54. <a-button @click="reset">
  55. <template #icon><icon-refresh /></template>
  56. 重置
  57. </a-button>
  58. </a-space>
  59. </a-col>
  60. </a-row>
  61. </AppQueryFilter>
  62. <a-table
  63. class="table"
  64. :bordered="false"
  65. :data="data"
  66. :loading="loading"
  67. :columns="columns"
  68. :scroll="{ x: 1240 }"
  69. :pagination="{
  70. showPageSize: true,
  71. showJumper: true,
  72. showTotal: true,
  73. pageSize: pagination.pagesize,
  74. current: pagination.current,
  75. total: pagination.total
  76. }"
  77. @page-change="handlePageChange"
  78. @page-size-change="handlePageSizeChange"
  79. >
  80. <template #state="{ record }">
  81. <a-tag :color="record.state === 1 ? 'green' : 'gray'">{{ record.state === 1 ? '正常' : '已删除' }}</a-tag>
  82. </template>
  83. <template #last_message_time="{ record }">
  84. {{ formatTime(record.last_message_time) }}
  85. </template>
  86. <template #update_time="{ record }">
  87. {{ formatTime(record.update_time) }}
  88. </template>
  89. <template #optional="{ record }">
  90. <a-button @click="$router.push(`/aiManage/aiChat/detail/${record.id}`)">查看详情</a-button>
  91. </template>
  92. </a-table>
  93. </a-card>
  94. </div>
  95. </template>
  96. <script setup>
  97. import { reactive, ref, onMounted } from 'vue'
  98. import { Notification } from '@arco-design/web-vue'
  99. import { adminListAIChatConversations } from '@/api/aiChat'
  100. import { useResponsiveTable } from '@/hooks/useResponsiveTable'
  101. const pagination = reactive({ current: 1, pagesize: 20, total: 0 })
  102. const queryData = reactive({ id: '', channel: '', username: '', create_user: '', state: -1, queryTime: [] })
  103. const data = ref([])
  104. const loading = ref(false)
  105. const columnDefs = [
  106. { title: '消息来源', dataIndex: 'channel', width: 100 },
  107. { title: '会话ID', dataIndex: 'id', width: 100 },
  108. { title: '标题', dataIndex: 'title', width: 180, ellipsis: true, tooltip: true },
  109. { title: '用户', dataIndex: 'username', width: 140, ellipsis: true, tooltip: true },
  110. { title: '最后消息', dataIndex: 'last_message_preview', width: 260, ellipsis: true, tooltip: true },
  111. { title: '最后消息时间', slotName: 'last_message_time', width: 170 },
  112. { title: '更新时间', slotName: 'update_time', width: 170 },
  113. { title: '状态', slotName: 'state', width: 100 },
  114. { title: '操作', slotName: 'optional', width: 120, fixed: 'right' }
  115. ]
  116. const { useTableColumns } = useResponsiveTable()
  117. const columns = useTableColumns(columnDefs)
  118. const formatTime = (time) => time ? new Date(Number(time)).toLocaleString('zh-CN', { hour12: false }) : '-'
  119. const fetchList = async () => {
  120. loading.value = true
  121. try {
  122. const res = await adminListAIChatConversations({
  123. ...queryData,
  124. current: pagination.current,
  125. pagesize: pagination.pagesize
  126. })
  127. if (!res || res.code !== 0) return Notification.error({ title: '获取 AI 对话失败', content: res?.msg || '请稍后再试' })
  128. data.value = res.data || []
  129. pagination.total = res.pagination?.total || 0
  130. } finally {
  131. loading.value = false
  132. }
  133. }
  134. const search = () => {
  135. pagination.current = 1
  136. fetchList()
  137. }
  138. const reset = () => {
  139. queryData.id = ''
  140. queryData.channel = ''
  141. queryData.username = ''
  142. queryData.create_user = ''
  143. queryData.state = -1
  144. queryData.queryTime = []
  145. search()
  146. }
  147. const handlePageChange = (page) => {
  148. pagination.current = page
  149. fetchList()
  150. }
  151. const handlePageSizeChange = (size) => {
  152. pagination.pagesize = size
  153. pagination.current = 1
  154. fetchList()
  155. }
  156. onMounted(fetchList)
  157. </script>
  158. <style scoped>
  159. .query-row {
  160. margin-bottom: 10px;
  161. }
  162. .table {
  163. margin-top: 15px;
  164. }
  165. @media (max-width: 768px) {
  166. .query-row {
  167. display: block;
  168. }
  169. .query-divider {
  170. display: none;
  171. }
  172. .query-actions-space {
  173. margin-top: 4px;
  174. flex-direction: row !important;
  175. gap: 10px !important;
  176. }
  177. }
  178. </style>