index.vue 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. <script setup lang="ts">
  2. import { onMounted, ref, unref } from 'vue'
  3. import dayjs from 'dayjs'
  4. import { ElMessage, ElTag, ElSelect, ElOption } from 'element-plus'
  5. import { DICT_TYPE } from '@/utils/dict'
  6. import { useTable } from '@/hooks/web/useTable'
  7. import { useI18n } from '@/hooks/web/useI18n'
  8. import { FormExpose } from '@/components/Form'
  9. import type { SensitiveWordVO } from '@/api/system/sensitiveWord/types'
  10. import { rules, allSchemas } from './sensitiveWord.data'
  11. import * as SensitiveWordApi from '@/api/system/sensitiveWord'
  12. const { t } = useI18n() // 国际化
  13. // ========== 列表相关 ==========
  14. const { register, tableObject, methods } = useTable<SensitiveWordVO>({
  15. getListApi: SensitiveWordApi.getSensitiveWordPageApi,
  16. delListApi: SensitiveWordApi.deleteSensitiveWordApi,
  17. exportListApi: SensitiveWordApi.exportSensitiveWordApi
  18. })
  19. const { getList, setSearchParams, delList, exportList } = methods
  20. // 获取标签
  21. const tagsOptions = ref()
  22. const getTags = async () => {
  23. const res = await SensitiveWordApi.getSensitiveWordTagsApi()
  24. tagsOptions.value = res
  25. }
  26. // ========== CRUD 相关 ==========
  27. const actionLoading = ref(false) // 遮罩层
  28. const actionType = ref('') // 操作按钮的类型
  29. const dialogVisible = ref(false) // 是否显示弹出层
  30. const dialogTitle = ref('edit') // 弹出层标题
  31. const formRef = ref<FormExpose>() // 表单 Ref
  32. const tags = ref()
  33. // 设置标题
  34. const setDialogTile = (type: string) => {
  35. dialogTitle.value = t('action.' + type)
  36. actionType.value = type
  37. dialogVisible.value = true
  38. }
  39. // 新增操作
  40. const handleCreate = () => {
  41. setDialogTile('create')
  42. }
  43. // 修改操作
  44. const handleUpdate = async (row: SensitiveWordVO) => {
  45. setDialogTile('update')
  46. // 设置数据
  47. const res = await SensitiveWordApi.getSensitiveWordApi(row.id)
  48. unref(formRef)?.setValues(res)
  49. }
  50. // 提交按钮
  51. const submitForm = async () => {
  52. const elForm = unref(formRef)?.getElFormRef()
  53. if (!elForm) return
  54. elForm.validate(async (valid) => {
  55. if (valid) {
  56. actionLoading.value = true
  57. // 提交请求
  58. try {
  59. const data = unref(formRef)?.formModel as SensitiveWordVO
  60. if (actionType.value === 'create') {
  61. await SensitiveWordApi.createSensitiveWordApi(data)
  62. ElMessage.success(t('common.createSuccess'))
  63. } else {
  64. await SensitiveWordApi.updateSensitiveWordApi(data)
  65. ElMessage.success(t('common.updateSuccess'))
  66. }
  67. // 操作成功,重新加载列表
  68. dialogVisible.value = false
  69. await getList()
  70. } finally {
  71. actionLoading.value = false
  72. }
  73. }
  74. })
  75. }
  76. // ========== 详情相关 ==========
  77. const detailRef = ref() // 详情 Ref
  78. // 详情操作
  79. const handleDetail = async (row: SensitiveWordVO) => {
  80. // 设置数据
  81. detailRef.value = row
  82. setDialogTile('detail')
  83. }
  84. // ========== 初始化 ==========
  85. onMounted(async () => {
  86. await getTags()
  87. await getList()
  88. })
  89. </script>
  90. <template>
  91. <!-- 搜索工作区 -->
  92. <ContentWrap>
  93. <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />
  94. </ContentWrap>
  95. <ContentWrap>
  96. <!-- 操作工具栏 -->
  97. <div class="mb-10px">
  98. <el-button type="primary" v-hasPermi="['system:post:create']" @click="handleCreate">
  99. <Icon icon="ep:zoom-in" class="mr-5px" /> {{ t('action.add') }}
  100. </el-button>
  101. <el-button
  102. type="warning"
  103. v-hasPermi="['system:post:export']"
  104. :loading="tableObject.exportLoading"
  105. @click="exportList('敏感词数据.xls')"
  106. >
  107. <Icon icon="ep:download" class="mr-5px" /> {{ t('action.export') }}
  108. </el-button>
  109. </div>
  110. <!-- 列表 -->
  111. <Table
  112. :columns="allSchemas.tableColumns"
  113. :selection="false"
  114. :data="tableObject.tableList"
  115. :loading="tableObject.loading"
  116. :pagination="{
  117. total: tableObject.total
  118. }"
  119. v-model:pageSize="tableObject.pageSize"
  120. v-model:currentPage="tableObject.currentPage"
  121. @register="register"
  122. >
  123. <template #tags="{ row }">
  124. <el-tag
  125. :disable-transitions="true"
  126. :key="index"
  127. v-for="(tag, index) in row.tags"
  128. :index="index"
  129. >
  130. {{ tag }}
  131. </el-tag>
  132. </template>
  133. <template #status="{ row }">
  134. <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />
  135. </template>
  136. <template #createTime="{ row }">
  137. <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
  138. </template>
  139. <template #action="{ row }">
  140. <el-button
  141. link
  142. type="primary"
  143. v-hasPermi="['system:post:update']"
  144. @click="handleUpdate(row)"
  145. >
  146. <Icon icon="ep:edit" class="mr-1px" /> {{ t('action.edit') }}
  147. </el-button>
  148. <el-button
  149. link
  150. type="primary"
  151. v-hasPermi="['system:post:update']"
  152. @click="handleDetail(row)"
  153. >
  154. <Icon icon="ep:view" class="mr-1px" /> {{ t('action.detail') }}
  155. </el-button>
  156. <el-button
  157. link
  158. type="primary"
  159. v-hasPermi="['system:post:delete']"
  160. @click="delList(row.id, false)"
  161. >
  162. <Icon icon="ep:delete" class="mr-1px" /> {{ t('action.del') }}
  163. </el-button>
  164. </template>
  165. </Table>
  166. </ContentWrap>
  167. <XModal v-model="dialogVisible" :title="dialogTitle">
  168. <!-- 对话框(添加 / 修改) -->
  169. <Form
  170. v-if="['create', 'update'].includes(actionType)"
  171. :schema="allSchemas.formSchema"
  172. :rules="rules"
  173. ref="formRef"
  174. >
  175. <template #tags>
  176. <el-select v-model="tags" multiple placeholder="请选择">
  177. <el-option v-for="item in tagsOptions" :key="item" :label="item" :value="item" />
  178. </el-select>
  179. </template>
  180. </Form>
  181. <!-- 对话框(详情) -->
  182. <Descriptions
  183. v-if="actionType === 'detail'"
  184. :schema="allSchemas.detailSchema"
  185. :data="detailRef"
  186. />
  187. <!-- 操作按钮 -->
  188. <template #footer>
  189. <el-button
  190. v-if="['create', 'update'].includes(actionType)"
  191. type="primary"
  192. :loading="actionLoading"
  193. @click="submitForm"
  194. >
  195. {{ t('action.save') }}
  196. </el-button>
  197. <el-button @click="dialogVisible = false">{{ t('dialog.close') }}</el-button>
  198. </template>
  199. </XModal>
  200. </template>