index.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597
  1. <template>
  2. <div class="jobmanage">
  3. <basic-container>
  4. <avue-crud ref="crud"
  5. :page="page"
  6. v-model="form"
  7. :data="tableData"
  8. :table-loading="tableLoading"
  9. :option="tableOption"
  10. @on-load="getList"
  11. @row-save="save"
  12. @row-update="update"
  13. @refresh-change="refreshChange"
  14. @search-change="handleFilter"
  15. @search-reset="handleSearchReset">
  16. <template slot-scope="scope" slot="jobStatus">
  17. <div v-if="scope.row.jobStatus == 1">
  18. <el-tag type="info">{{getDicNameJobStatus(scope.row.jobStatus)}}</el-tag>
  19. </div>
  20. <div v-else-if="scope.row.jobStatus == 2">
  21. <el-tag type="success">{{getDicNameJobStatus(scope.row.jobStatus)}}</el-tag>
  22. </div>
  23. <div v-else-if="scope.row.jobStatus == 3">
  24. <el-tag type="danger">{{getDicNameJobStatus(scope.row.jobStatus)}}</el-tag>
  25. </div>
  26. </template>
  27. <template slot-scope="scope" slot="jobExecuteStatus">
  28. <div v-if="scope.row.jobExecuteStatus == 0">
  29. <el-tag type="success">{{getDicNameJobExecuteStatus(scope.row.jobExecuteStatus)}}</el-tag>
  30. </div>
  31. <div v-else>
  32. <el-tag type="danger">{{getDicNameJobExecuteStatus(scope.row.jobExecuteStatus)}}</el-tag>
  33. </div>
  34. </template>
  35. <template slot="cronExpressionForm" slot-scope="scope">
  36. <div class="cron">
  37. <el-popover v-model="cronPopover">
  38. <cron @change="changeCron" @close="cronPopover=false" i18n="cn"></cron>
  39. <el-input slot="reference" @click="cronPopover=true" v-model="form.cronExpression"
  40. placeholder="请输入定时策略"></el-input>
  41. </el-popover>
  42. </div>
  43. </template>
  44. <template slot="menuLeft">
  45. <el-button type="primary" @click="handleAdd" size="small" v-if="permissions.job_sys_job_add">
  46. 新建任务
  47. </el-button>
  48. <el-tooltip content="暂停全部运行状态的定时任务" placement="top">
  49. <el-button type="warning" @click="shutdownJobs" size="small" v-if="permissions.job_sys_job_shutdown_job">
  50. 暂停全部任务
  51. </el-button>
  52. </el-tooltip>
  53. <el-tooltip content="启动全部暂停状态的定时任务" placement="top">
  54. <el-button type="success" @click="startJobs" size="small" v-if="permissions.job_sys_job_start_job">
  55. 启动全部任务
  56. </el-button>
  57. </el-tooltip>
  58. <el-tooltip content="谨慎使用" placement="top">
  59. <el-button type="danger" @click="refreshJobs" size="small" v-if="permissions.job_sys_job_refresh_job">重置全部任务
  60. </el-button>
  61. </el-tooltip>
  62. </template>
  63. <template slot="menu"
  64. slot-scope="scope">
  65. <el-button type="text"
  66. icon="el-icon-info"
  67. size="mini"
  68. plain
  69. @click="getJobLog(scope.row)">日志
  70. </el-button>
  71. <el-button type="text"
  72. icon="el-icon-caret-right"
  73. size="mini"
  74. v-if="permissions.job_sys_job_start_job"
  75. plain
  76. @click="handleStartJob(scope.row)">启动
  77. </el-button>
  78. <el-button type="text"
  79. icon="el-icon-error"
  80. size="mini"
  81. v-if="permissions.job_sys_job_shutdown_job"
  82. plain
  83. @click="handleShutDownJob(scope.row)">暂停
  84. </el-button>
  85. <el-button type="text"
  86. icon="el-icon-edit"
  87. size="mini"
  88. v-if="permissions.job_sys_job_edit"
  89. plain
  90. @click="handleUpdate(scope.row,scope.index)">修改
  91. </el-button>
  92. <el-button type="text"
  93. v-if="permissions.job_sys_job_del"
  94. icon="el-icon-delete"
  95. size="mini"
  96. plain
  97. @click="handleDelete(scope.row,scope.index)">删除
  98. </el-button>
  99. </template>
  100. </avue-crud>
  101. </basic-container>
  102. <el-dialog title="执行日志" :visible.sync="dialogFormVisible" width="90%" @close="closeJobLogDialog">
  103. <avue-crud ref="crudLog"
  104. :page="pageLog"
  105. @on-load="getJobLogList"
  106. :data="tableLogData"
  107. :option="tableLogOption"
  108. @refresh-change="getJobLogList"
  109. :table-loading="tableLogLoading">
  110. <template slot-scope="scope" slot="jobLogStatus">
  111. <div v-if="scope.row.jobLogStatus == 0">
  112. <el-tag type="success">{{getDicNameJobExecuteStatus(scope.row.jobLogStatus)}}</el-tag>
  113. </div>
  114. <div v-else>
  115. <el-tag type="danger">{{getDicNameJobExecuteStatus(scope.row.jobLogStatus)}}</el-tag>
  116. </div>
  117. </template>
  118. </avue-crud>
  119. </el-dialog>
  120. </div>
  121. </template>
  122. <script>
  123. import {
  124. addObj,
  125. delObj,
  126. fetchList,
  127. getJobLogList,
  128. isValidTaskName,
  129. putObj,
  130. refreshJobsRa,
  131. shutDownJobRa,
  132. shutdownJobsRa,
  133. startJobRa,
  134. startJobsRa
  135. } from '@/api/daemon/sys-job'
  136. import {tableLogOption, tableOption} from '@/const/crud/daemon/sys-job'
  137. import {remote} from '@/api/admin/dict'
  138. import {mapGetters} from 'vuex'
  139. import {cron} from 'vue-cron'
  140. export default {
  141. components: {cron},
  142. name: 'sys-manage',
  143. data() {
  144. return {
  145. form: {},
  146. cronPopover: false,
  147. queryParams: [],//全局检索条件
  148. tableData: [],
  149. tableLogData: [],
  150. dialogFormVisible: false,
  151. jobId: "",
  152. page: {
  153. total: 0, // 总页数
  154. currentPage: 1, // 当前页数
  155. pageSize: 10, // 每页显示多少条,
  156. },
  157. pageLog: {
  158. total: 0, // 总页数
  159. currentPage: 1, // 当前页数
  160. pageSize: 10, // 每页显示多少条,
  161. },
  162. tableLoading: false,
  163. tableLogLoading: false,
  164. tableOption: tableOption,
  165. tableLogOption: tableLogOption,
  166. JobExecuteStatusDicCache: [],
  167. JobStatusDicCache: [],
  168. }
  169. },
  170. mounted: function () {
  171. this.getDicJobExecuteStatusCache("job_execute_status");//获取定时任务运行时状态
  172. this.getDicJobStatusCache("job_status");//获取定时任务状态
  173. },
  174. computed: {
  175. ...mapGetters(['permissions'])
  176. },
  177. methods: {
  178. changeCron(val) {
  179. this.form.cronExpression = val
  180. },
  181. /**
  182. * 关闭执行日志对话框重置信息
  183. */
  184. closeJobLogDialog() {
  185. this.jobId = ""
  186. this.pageLog.total = 0
  187. this.pageLog.currentPage = 1
  188. this.pageLog.pageSize = 10
  189. },
  190. /**
  191. * 定时任务分页查询
  192. */
  193. getList(page) {
  194. this.tableLoading = true
  195. fetchList(Object.assign({
  196. descs: 'create_time',
  197. current: this.page.currentPage,
  198. size: this.page.pageSize
  199. }, this.queryParams)).then(response => {
  200. this.tableData = response.data.data.records
  201. this.page.pageSize = response.data.data.pageSize
  202. this.page.total = response.data.data.total
  203. this.tableLoading = false
  204. })
  205. },
  206. /**
  207. * 清除全局检索条件
  208. */
  209. handleSearchReset() {
  210. this.queryParams = [];
  211. },
  212. /**
  213. * 定时任务检索查询分页查询
  214. */
  215. handleFilter(params) {
  216. this.queryParams = this.filterForm(params)
  217. this.getList(this.page);
  218. },
  219. /**
  220. * 启动定时任务
  221. */
  222. handleStartJob(row) {
  223. let jobStatus = row.jobStatus;
  224. if ('1' == jobStatus || '3' == jobStatus) {
  225. this.$confirm(
  226. "即将发布或启动(任务名称:" + row.jobName + "), 是否继续?",
  227. "提示",
  228. {
  229. confirmButtonText: "确定",
  230. cancelButtonText: "取消",
  231. type: "warning"
  232. }
  233. ).then(() => {
  234. startJobRa(row.jobId).then(response => {
  235. let code = response.data.code;
  236. if ('0' == code) {
  237. this.$notify({
  238. title: "成功",
  239. message: "启动成功",
  240. type: "success"
  241. });
  242. this.refreshChange()
  243. }
  244. }).catch(() => {
  245. this.$notify.error({
  246. title: '错误',
  247. message: '启动失败'
  248. });
  249. })
  250. })
  251. } else {
  252. this.$notify.error({
  253. title: '错误',
  254. message: '定时任务已运行'
  255. });
  256. }
  257. },
  258. /**
  259. * 新增定时任务
  260. */
  261. handleAdd() {
  262. this.$refs.crud.rowAdd();
  263. },
  264. /**
  265. * 修改定时任务
  266. */
  267. handleUpdate(row, index) {
  268. let jobStatus = row.jobStatus;
  269. if ('1' == jobStatus || '3' == jobStatus) {
  270. this.$refs.crud.rowEdit(row, index);
  271. } else {
  272. this.$notify.error({
  273. title: '错误',
  274. message: '运行中定时任务不可修改,请先暂停后操作'
  275. });
  276. }
  277. },
  278. /**
  279. * 暂停定时任务
  280. */
  281. handleShutDownJob(row) {
  282. let jobStatus = row.jobStatus;
  283. if ('2' == jobStatus) {
  284. this.$confirm(
  285. "即将暂停(任务名称:" + row.jobName + "), 是否继续?",
  286. "提示",
  287. {
  288. confirmButtonText: "确定",
  289. cancelButtonText: "取消",
  290. type: "warning"
  291. }
  292. ).then(() => {
  293. shutDownJobRa(row.jobId).then(response => {
  294. let code = response.data.code;
  295. if ('0' == code) {
  296. this.getList(this.page);
  297. this.$notify({
  298. title: "成功",
  299. message: "暂停成功",
  300. type: "success"
  301. });
  302. }
  303. this.refreshChange()
  304. }).catch(() => {
  305. this.$notify.error({
  306. title: '错误',
  307. message: '暂停失败'
  308. });
  309. })
  310. })
  311. } else {
  312. this.$notify.error({
  313. title: '错误',
  314. message: '运行中定时任务可暂停'
  315. });
  316. }
  317. },
  318. /**
  319. * 刷新回调
  320. */
  321. refreshChange() {
  322. this.getList(this.page)
  323. },
  324. /**
  325. * 获取定时任务执行日志
  326. */
  327. getJobLog(row) {
  328. this.dialogFormVisible = true
  329. this.tableLogLoading = true
  330. this.jobId = row.jobId
  331. this.getJobLogList(this.pageLog)
  332. },
  333. /**
  334. * 获取定时任务执行日志
  335. */
  336. getJobLogList(page) {
  337. getJobLogList(Object.assign({
  338. descs: 'create_time',
  339. current: page.currentPage,
  340. size: page.pageSize
  341. }, {jobId: this.jobId})).then(response => {
  342. this.tableLogData = response.data.data.records
  343. this.pageLog.total = response.data.data.total
  344. this.pageLog.pageSize = response.data.data.pageSize
  345. this.tableLogLoading = false
  346. })
  347. },
  348. /**
  349. * 暂停运行中定时任务
  350. */
  351. shutdownJobs() {
  352. this.$confirm(
  353. "即将暂停全部运行中定时任务, 是否继续?",
  354. "提示",
  355. {
  356. confirmButtonText: "确定",
  357. cancelButtonText: "取消",
  358. type: "warning"
  359. }
  360. ).then(() => {
  361. shutdownJobsRa().then(response => {
  362. let code = response.data.code;
  363. let msg = response.data.msg;
  364. if ("0" == code) {
  365. this.getList(this.page);
  366. this.$notify({
  367. title: "成功",
  368. message: msg,
  369. type: "success"
  370. });
  371. this.refreshChange()
  372. } else {
  373. this.$notify.error({
  374. title: '错误',
  375. message: '暂停失败'
  376. });
  377. }
  378. }).catch(() => {
  379. this.$notify.error({
  380. title: '错误',
  381. message: '暂停失败'
  382. });
  383. })
  384. })
  385. },
  386. /**
  387. * 启动全部暂停定时任务
  388. */
  389. startJobs() {
  390. this.$confirm(
  391. "即将启动全部暂定中定时任务, 是否继续?",
  392. "提示",
  393. {
  394. confirmButtonText: "确定",
  395. cancelButtonText: "取消",
  396. type: "warning"
  397. }
  398. ).then(() => {
  399. startJobsRa().then(response => {
  400. let code = response.data.code;
  401. if ("0" == code) {
  402. this.getList(this.page);
  403. this.$notify({
  404. title: "成功",
  405. message: '启动成功',
  406. type: "success"
  407. });
  408. this.refreshChange()
  409. } else {
  410. this.$notify.error({
  411. title: '错误',
  412. message: '启动失败'
  413. });
  414. }
  415. }).catch(() => {
  416. this.$notify.error({
  417. title: '错误',
  418. message: '启动失败'
  419. });
  420. })
  421. })
  422. },
  423. /**
  424. * 刷新定时任务
  425. */
  426. refreshJobs() {
  427. this.$confirm(
  428. "即将刷新全部定时任务, 是否继续?",
  429. "提示",
  430. {
  431. confirmButtonText: "确定",
  432. cancelButtonText: "取消",
  433. type: "warning"
  434. }
  435. ).then(() => {
  436. refreshJobsRa().then(response => {
  437. let code = response.data.code;
  438. if ("0" == code) {
  439. this.getList(this.page);
  440. this.$notify({
  441. title: "成功",
  442. message: '重置成功',
  443. type: "success"
  444. });
  445. this.refreshChange()
  446. } else {
  447. this.$notify.error({
  448. title: '错误',
  449. message: '重置失败'
  450. });
  451. }
  452. }).catch(() => {
  453. this.$notify.error({
  454. title: '错误',
  455. message: '重置失败'
  456. });
  457. }
  458. )
  459. })
  460. },
  461. /**
  462. * 新增定时任务持久化处理
  463. */
  464. save(row, done, loading) {
  465. isValidTaskName(row.jobName, row.jobGroup).then(response => {
  466. let result = response.data.data;
  467. if (result != 0) {
  468. this.$notify.error({
  469. title: '错误',
  470. message: '任务名称与任务组重复,请确认后重新添加'
  471. });
  472. } else {
  473. addObj(row).then(() => {
  474. this.$notify({
  475. title: '成功',
  476. message: '创建成功',
  477. type: 'success',
  478. duration: 2000
  479. })
  480. }).catch(() => {
  481. loading();
  482. });
  483. }
  484. done();
  485. this.refreshChange()
  486. })
  487. }
  488. ,
  489. /**
  490. * 更新定时任务持久化处理
  491. */
  492. update(row, index, done, loading) {
  493. putObj(row).then(() => {
  494. this.getList(this.page)
  495. done();
  496. this.$notify({
  497. title: '成功',
  498. message: '修改成功',
  499. type: 'success',
  500. duration: 2000
  501. })
  502. this.refreshChange()
  503. }).catch(() => {
  504. loading();
  505. });
  506. },
  507. /**
  508. * 删除定时任务持久化处理
  509. */
  510. handleDelete(row, index) {
  511. let jobStatus = row.jobStatus;
  512. if ('1' == jobStatus || '3' == jobStatus) {
  513. this.$confirm('是否确认删除(任务名称:' + row.jobName + '), 是否继续?删除后不可恢复', '警告', {
  514. confirmButtonText: '确定',
  515. cancelButtonText: '取消',
  516. type: 'warning'
  517. }).then(function () {
  518. return delObj(row.jobId)
  519. }).then(() => {
  520. this.getList(this.page)
  521. this.$notify({
  522. title: '成功',
  523. message: '删除成功',
  524. type: 'success',
  525. duration: 2000
  526. })
  527. this.refreshChange()
  528. }).catch(function () {
  529. })
  530. } else {
  531. this.$notify.error({
  532. title: '错误',
  533. message: '运行中定时任务不可删除,请先暂停后操作'
  534. });
  535. }
  536. },
  537. /**
  538. * 获取字典显示名称并缓存
  539. */
  540. getDicJobExecuteStatusCache(type) {
  541. remote(type).then(response => {
  542. let code = response.data.code;
  543. if (code == 0) {
  544. let _data = response.data.data;
  545. this.JobExecuteStatusDicCache = _data;
  546. }
  547. })
  548. },
  549. /**
  550. * 获取字典显示名称并缓存
  551. */
  552. getDicJobStatusCache(type) {
  553. remote(type).then(response => {
  554. let code = response.data.code;
  555. if (code == 0) {
  556. let _data = response.data.data;
  557. this.JobStatusDicCache = _data;
  558. }
  559. })
  560. },
  561. /**
  562. * 获取字典定时任务执行状态字典值显示名称
  563. */
  564. getDicNameJobExecuteStatus(value) {
  565. let re = '';
  566. this.JobExecuteStatusDicCache.forEach(obj => {
  567. if (obj.value == value) {
  568. re = obj.label;
  569. return
  570. }
  571. });
  572. return re
  573. },
  574. /**
  575. * 获取字典定时任务状态字典值显示名称
  576. */
  577. getDicNameJobStatus(value) {
  578. let re = '';
  579. this.JobStatusDicCache.forEach(obj => {
  580. if (obj.value == value) {
  581. re = obj.label;
  582. return
  583. }
  584. });
  585. return re
  586. },
  587. }
  588. }
  589. </script>
  590. <style lang="scss" scoped>
  591. </style>