EmotionAlertManage.vue 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. <template>
  2. <div class="emotion-alert-manage admin-page">
  3. <div class="header">
  4. <h2>情绪告警管理</h2>
  5. <el-input v-model="keyword" placeholder="搜索..." prefix-icon="el-icon-search" style="width:200px" clearable @keyup.enter.native="handleSearch" @clear="handleSearch" />
  6. <el-radio-group v-model="resolvedFilter" @change="onFilterChange">
  7. <el-radio-button label="">全部</el-radio-button>
  8. <el-radio-button label="false">未处理</el-radio-button>
  9. <el-radio-button label="true">已处理</el-radio-button>
  10. </el-radio-group>
  11. </div>
  12. <el-table :max-height="tableHeight" :data="list" v-loading="loading" border stripe>
  13. <el-table-column prop="id" label="ID" width="70" />
  14. <el-table-column prop="childId" label="孩子ID" width="90" />
  15. <el-table-column label="告警类型" width="140">
  16. <template slot-scope="{ row }">
  17. {{ alertTypeLabel(row.alertType) }}
  18. </template>
  19. </el-table-column>
  20. <el-table-column label="严重程度" width="100">
  21. <template slot-scope="{ row }">
  22. <el-tag :type="severityType(row.severity)">{{ severityLabel(row.severity) }}</el-tag>
  23. </template>
  24. </el-table-column>
  25. <el-table-column prop="title" label="标题" width="180" show-overflow-tooltip />
  26. <el-table-column prop="message" label="详情" min-width="220" show-overflow-tooltip />
  27. <el-table-column label="状态" width="80">
  28. <template slot-scope="{ row }">
  29. <el-tag :type="row.resolved ? 'success' : 'danger'" size="small">
  30. {{ row.resolved ? '已处理' : '未处理' }}
  31. </el-tag>
  32. </template>
  33. </el-table-column>
  34. <el-table-column label="创建时间" width="160">
  35. <template slot-scope="{ row }">
  36. {{ formatTime(row.createdAt) }}
  37. </template>
  38. </el-table-column>
  39. <el-table-column label="处理时间" width="160">
  40. <template slot-scope="{ row }">
  41. {{ row.resolvedAt ? formatTime(row.resolvedAt) : '-' }}
  42. </template>
  43. </el-table-column>
  44. <el-table-column label="操作" width="160" fixed="right">
  45. <template slot-scope="{ row }">
  46. <el-button
  47. v-if="!row.resolved"
  48. type="primary"
  49. size="mini"
  50. @click="handleResolve(row)"
  51. >标记已处理</el-button>
  52. <span v-else class="resolved-text">-</span>
  53. </template>
  54. </el-table-column>
  55. </el-table>
  56. <el-pagination
  57. @size-change="onSizeChange"
  58. @current-change="onPageChange"
  59. :current-page="page"
  60. :page-size="size"
  61. :total="total"
  62. layout="total, prev, pager, next"
  63. style="margin-top: 20px; text-align: right;"
  64. />
  65. </div>
  66. </template>
  67. <script>
  68. import { getEmotionAlertList, resolveEmotionAlert } from '@/api/admin'
  69. export default {
  70. name: 'EmotionAlertManage',
  71. computed: {
  72. tableHeight() {
  73. return window.innerHeight - 300
  74. }
  75. },
  76. data() {
  77. return {
  78. list: [],
  79. loading: false,
  80. page: 1,
  81. size: 20,
  82. total: 0,
  83. keyword: '',
  84. resolvedFilter: ''
  85. }
  86. },
  87. mounted() {
  88. this.loadList()
  89. },
  90. methods: {
  91. async loadList() {
  92. this.loading = true
  93. try {
  94. var params = { page: this.page, size: this.size }
  95. if (this.resolvedFilter !== '') {
  96. params.resolved = this.resolvedFilter
  97. }
  98. if (this.keyword) {
  99. params.keyword = this.keyword
  100. }
  101. var res = await getEmotionAlertList(params)
  102. this.list = res.data && res.data.list ? res.data.list : []
  103. this.total = res.data && res.data.total ? res.data.total : 0
  104. } catch (e) {
  105. this.$message.error('加载失败')
  106. } finally {
  107. this.loading = false
  108. }
  109. },
  110. onFilterChange() {
  111. this.page = 1
  112. this.loadList()
  113. },
  114. handleSearch() {
  115. this.page = 1
  116. this.loadList()
  117. },
  118. onSizeChange(val) {
  119. this.size = val
  120. this.page = 1
  121. this.loadList()
  122. },
  123. onPageChange(val) {
  124. this.page = val
  125. this.loadList()
  126. },
  127. async handleResolve(row) {
  128. try {
  129. await this.$confirm('确认将该告警标记为已处理?', '提示', {
  130. confirmButtonText: '确定',
  131. cancelButtonText: '取消',
  132. type: 'warning'
  133. })
  134. await resolveEmotionAlert(row.id)
  135. this.$message.success('操作成功')
  136. this.loadList()
  137. } catch (e) {
  138. if (e !== 'cancel') {
  139. this.$message.error('操作失败')
  140. }
  141. }
  142. },
  143. alertTypeLabel(type) {
  144. var map = {
  145. consecutive_low_mood: '连续低情绪',
  146. crisis_keyword: '危机关键词',
  147. sharp_decline: '情绪锐降'
  148. }
  149. return map[type] || type
  150. },
  151. severityType(severity) {
  152. var map = { high: 'danger', medium: 'warning', low: 'info' }
  153. return map[severity] || 'info'
  154. },
  155. severityLabel(severity) {
  156. var map = { high: '高', medium: '中', low: '低' }
  157. return map[severity] || severity
  158. },
  159. formatTime(t) {
  160. if (!t) return '-'
  161. return t.replace ? t.replace('T', ' ').substring(0, 19) : t
  162. }
  163. }
  164. }
  165. </script>
  166. <style scoped>
  167. .emotion-alert-manage {
  168. padding: 20px;
  169. }
  170. .header {
  171. display: flex;
  172. justify-content: space-between;
  173. align-items: center;
  174. margin-bottom: 20px;
  175. }
  176. .header h2 {
  177. margin: 0;
  178. }
  179. .resolved-text {
  180. color: #909399;
  181. }
  182. </style>