index.vue 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. <script lang="ts" setup>
  2. import { ref, unref } from 'vue'
  3. import DictTag from '@/components/DictTag/src/DictTag.vue'
  4. import * as JobApi from '@/api/infra/job'
  5. import { JobVO } from '@/api/infra/job/types'
  6. import Icon from '@/components/Icon/src/Icon.vue'
  7. import { DICT_TYPE } from '@/utils/dict'
  8. import { useTable } from '@/hooks/web/useTable'
  9. import { useI18n } from '@/hooks/web/useI18n'
  10. import { FormExpose } from '@/components/Form'
  11. import { rules, allSchemas } from './job.data'
  12. import { useRouter } from 'vue-router'
  13. import { useMessage } from '@/hooks/web/useMessage'
  14. const message = useMessage()
  15. const { t } = useI18n() // 国际化
  16. const { push } = useRouter()
  17. // ========== 列表相关 ==========
  18. const { register, tableObject, methods } = useTable<JobVO>({
  19. getListApi: JobApi.getJobPageApi,
  20. delListApi: JobApi.deleteJobApi,
  21. exportListApi: JobApi.exportJobApi
  22. })
  23. const { getList, setSearchParams, delList, exportList } = methods
  24. // ========== CRUD 相关 ==========
  25. const actionLoading = ref(false) // 遮罩层
  26. const actionType = ref('') // 操作按钮的类型
  27. const dialogVisible = ref(false) // 是否显示弹出层
  28. const dialogTitle = ref('edit') // 弹出层标题
  29. const formRef = ref<FormExpose>() // 表单 Ref
  30. // 设置标题
  31. const setDialogTile = (type: string) => {
  32. dialogTitle.value = t('action.' + type)
  33. actionType.value = type
  34. dialogVisible.value = true
  35. }
  36. // 新增操作
  37. const handleCreate = () => {
  38. setDialogTile('create')
  39. // 重置表单
  40. unref(formRef)?.getElFormRef()?.resetFields()
  41. }
  42. // 修改操作
  43. const handleUpdate = async (row: JobVO) => {
  44. setDialogTile('update')
  45. // 设置数据
  46. const res = await JobApi.getJobApi(row.id)
  47. unref(formRef)?.setValues(res)
  48. }
  49. // 执行日志
  50. const handleJobLog = (row: JobVO) => {
  51. if (row.id) {
  52. push('/job/job-log?id=' + row.id)
  53. } else {
  54. push('/job/job-log')
  55. }
  56. }
  57. // 执行一次
  58. const handleRun = (row: JobVO) => {
  59. message.confirm('确认要立即执行一次' + row.name + '?', t('common.reminder')).then(async () => {
  60. await JobApi.runJobApi(row.id)
  61. message.success('执行成功')
  62. getList()
  63. })
  64. }
  65. // 提交按钮
  66. const submitForm = async () => {
  67. actionLoading.value = true
  68. // 提交请求
  69. try {
  70. const data = unref(formRef)?.formModel as JobVO
  71. if (actionType.value === 'create') {
  72. await JobApi.createJobApi(data)
  73. message.success(t('common.createSuccess'))
  74. } else {
  75. await JobApi.updateJobApi(data)
  76. message.success(t('common.updateSuccess'))
  77. }
  78. // 操作成功,重新加载列表
  79. dialogVisible.value = false
  80. await getList()
  81. } finally {
  82. actionLoading.value = false
  83. }
  84. }
  85. // ========== 详情相关 ==========
  86. const detailRef = ref() // 详情 Ref
  87. // 详情操作
  88. const handleDetail = async (row: JobVO) => {
  89. // 设置数据
  90. const res = JobApi.getJobApi(row.id)
  91. detailRef.value = res
  92. setDialogTile('detail')
  93. }
  94. // ========== 初始化 ==========
  95. getList()
  96. </script>
  97. <template>
  98. <!-- 搜索工作区 -->
  99. <ContentWrap>
  100. <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />
  101. </ContentWrap>
  102. <ContentWrap>
  103. <!-- 操作工具栏 -->
  104. <div class="mb-10px">
  105. <el-button type="primary" v-hasPermi="['infra:job:create']" @click="handleCreate">
  106. <Icon icon="ep:zoom-in" class="mr-5px" /> {{ t('action.add') }}
  107. </el-button>
  108. <el-button
  109. type="warning"
  110. v-hasPermi="['infra:job:export']"
  111. :loading="tableObject.exportLoading"
  112. @click="exportList('定时任务.xls')"
  113. >
  114. <Icon icon="ep:download" class="mr-5px" /> {{ t('action.export') }}
  115. </el-button>
  116. <el-button type="info" v-hasPermi="['infra:job:query']" @click="handleJobLog">
  117. <Icon icon="ep:zoom-in" class="mr-5px" /> 执行日志
  118. </el-button>
  119. </div>
  120. <!-- 列表 -->
  121. <Table
  122. :columns="allSchemas.tableColumns"
  123. :selection="false"
  124. :data="tableObject.tableList"
  125. :loading="tableObject.loading"
  126. :pagination="{
  127. total: tableObject.total
  128. }"
  129. v-model:pageSize="tableObject.pageSize"
  130. v-model:currentPage="tableObject.currentPage"
  131. @register="register"
  132. >
  133. <template #status="{ row }">
  134. <DictTag :type="DICT_TYPE.INFRA_JOB_STATUS" :value="row.status" />
  135. </template>
  136. <template #action="{ row }">
  137. <el-button link type="primary" v-hasPermi="['infra:job:update']" @click="handleUpdate(row)">
  138. <Icon icon="ep:edit" class="mr-1px" /> {{ t('action.edit') }}
  139. </el-button>
  140. <el-button link type="primary" v-hasPermi="['infra:job:query']" @click="handleDetail(row)">
  141. <Icon icon="ep:view" class="mr-1px" /> {{ t('action.detail') }}
  142. </el-button>
  143. <el-button
  144. link
  145. type="primary"
  146. v-hasPermi="['infra:job:delete']"
  147. @click="delList(row.id, false)"
  148. >
  149. <Icon icon="ep:delete" class="mr-1px" /> {{ t('action.del') }}
  150. </el-button>
  151. <el-button link type="primary" v-hasPermi="['infra:job:trigger']" @click="handleRun(row)">
  152. <Icon icon="ep:view" class="mr-1px" /> 执行一次
  153. </el-button>
  154. <el-button link type="primary" v-hasPermi="['infra:job:query']" @click="handleJobLog(row)">
  155. <Icon icon="ep:view" class="mr-1px" /> 调度日志
  156. </el-button>
  157. </template>
  158. </Table>
  159. </ContentWrap>
  160. <Dialog v-model="dialogVisible" :title="dialogTitle">
  161. <!-- 对话框(添加 / 修改) -->
  162. <Form
  163. v-if="['create', 'update'].includes(actionType)"
  164. :schema="allSchemas.formSchema"
  165. :rules="rules"
  166. ref="formRef"
  167. />
  168. <!-- 对话框(详情) -->
  169. <Descriptions
  170. v-if="actionType === 'detail'"
  171. :schema="allSchemas.detailSchema"
  172. :data="detailRef"
  173. >
  174. <template #status="{ row }">
  175. <DictTag :type="DICT_TYPE.INFRA_JOB_STATUS" :value="row.status" />
  176. </template>
  177. <template #retryInterval="{ row }">
  178. <span>{{ row.retryInterval + '毫秒' }} </span>
  179. </template>
  180. <template #monitorTimeout="{ row }">
  181. <span>{{ row.monitorTimeout > 0 ? row.monitorTimeout + ' 毫秒' : '未开启' }}</span>
  182. </template>
  183. </Descriptions>
  184. <!-- 操作按钮 -->
  185. <template #footer>
  186. <el-button
  187. v-if="['create', 'update'].includes(actionType)"
  188. type="primary"
  189. :loading="actionLoading"
  190. @click="submitForm"
  191. >
  192. {{ t('action.save') }}
  193. </el-button>
  194. <el-button @click="dialogVisible = false">{{ t('dialog.close') }}</el-button>
  195. </template>
  196. </Dialog>
  197. </template>