houzhongjian
2024-07-11 759b1c71011abd6b58c37d2566f3f3c208c2f1b2
提交 | 用户 | 时间
759b1c 1 <template>
H 2   <div class="app-container">
3     <!-- 搜索栏 -->
4     <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="100px">
5       <el-form-item label="任务名称" prop="name">
6         <el-input v-model="queryParams.name" placeholder="请输入任务名称" clearable @keyup.enter.native="handleQuery"/>
7       </el-form-item>
8       <el-form-item label="任务状态" prop="status">
9         <el-select v-model="queryParams.status" placeholder="请选择任务状态" clearable>
10           <el-option v-for="dict in this.getDictDatas(DICT_TYPE.INFRA_JOB_STATUS)"
11                      :key="dict.value" :label="dict.label" :value="dict.value"/>
12         </el-select>
13       </el-form-item>
14       <el-form-item label="处理器的名字" prop="handlerName">
15         <el-input v-model="queryParams.handlerName" placeholder="请输入处理器的名字" clearable @keyup.enter.native="handleQuery"/>
16       </el-form-item>
17       <el-form-item>
18         <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
19         <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
20       </el-form-item>
21     </el-form>
22
23     <el-row :gutter="10" class="mb8">
24       <el-col :span="1.5">
25         <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
26                    v-hasPermi="['infra:job:create']">新增</el-button>
27       </el-col>
28       <el-col :span="1.5">
29         <el-button type="warning" icon="el-icon-download" size="mini" @click="handleExport" :loading="exportLoading"
30                    v-hasPermi="['infra:job:export']">导出</el-button>
31       </el-col>
32       <el-col :span="1.5">
33         <el-button type="info" icon="el-icon-s-operation" size="mini" @click="handleJobLog"
34                    v-hasPermi="['infra:job:query']">执行日志</el-button>
35       </el-col>
36       <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
37     </el-row>
38
39     <el-table v-loading="loading" :data="jobList">
40       <el-table-column label="任务编号" align="center" prop="id" />
41       <el-table-column label="任务名称" align="center" prop="name" />
42       <el-table-column label="任务状态" align="center" prop="status">
43         <template v-slot="scope">
44           <dict-tag :type="DICT_TYPE.INFRA_JOB_STATUS" :value="scope.row.status" />
45         </template>
46       </el-table-column>>
47       <el-table-column label="处理器的名字" align="center" prop="handlerName" />
48       <el-table-column label="处理器的参数" align="center" prop="handlerParam" />
49       <el-table-column label="CRON 表达式" align="center" prop="cronExpression" />
50       <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
51         <template v-slot="scope">
52           <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
53                      v-hasPermi="['infra:job:update']">修改</el-button>
54           <el-button size="mini" type="text" icon="el-icon-check" @click="handleChangeStatus(scope.row, true)"
55                      v-if="scope.row.status === InfJobStatusEnum.STOP" v-hasPermi="['infra:job:update']">开启</el-button>
56           <el-button size="mini" type="text" icon="el-icon-close" @click="handleChangeStatus(scope.row, false)"
57                      v-if="scope.row.status === InfJobStatusEnum.NORMAL" v-hasPermi="['infra:job:update']">暂停</el-button>
58           <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
59                      v-hasPermi="['infra:job:delete']">删除</el-button>
60           <el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)"
61                        v-hasPermi="['infra:job:trigger', 'infra:job:query']">
62             <el-button size="mini" type="text" icon="el-icon-d-arrow-right">更多</el-button>
63             <el-dropdown-menu slot="dropdown">
64               <el-dropdown-item command="handleRun" icon="el-icon-caret-right"
65                                 v-hasPermi="['infra:job:trigger']">执行一次</el-dropdown-item>
66               <el-dropdown-item command="handleView" icon="el-icon-view"
67                                 v-hasPermi="['infra:job:query']">任务详细</el-dropdown-item>
68               <el-dropdown-item command="handleJobLog" icon="el-icon-s-operation"
69                                 v-hasPermi="['infra:job:query']">调度日志</el-dropdown-item>
70             </el-dropdown-menu>
71           </el-dropdown>
72         </template>
73       </el-table-column>
74     </el-table>
75     <!-- 分页组件 -->
76     <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
77                 @pagination="getList"/>
78
79     <!-- 添加或修改定时任务对话框 -->
80     <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
81       <el-form ref="form" :model="form" :rules="rules" label-width="120px">
82         <el-form-item label="任务名称" prop="name">
83           <el-input v-model="form.name" placeholder="请输入任务名称" />
84         </el-form-item>
85         <el-form-item label="处理器的名字" prop="handlerName">
86           <el-input v-model="form.handlerName" placeholder="请输入处理器的名字" v-bind:readonly="form.id !== undefined" />
87         </el-form-item>
88         <el-form-item label="处理器的参数" prop="handlerParam">
89           <el-input v-model="form.handlerParam" placeholder="请输入处理器的参数" />
90         </el-form-item>
91         <el-form-item label="CRON 表达式" prop="cronExpression">
92           <el-input v-model="form.cronExpression" placeholder="请输入CRON 表达式">
93             <template slot="append">
94               <el-button type="primary" @click="handleShowCron">
95                 生成表达式
96                 <i class="el-icon-time el-icon--right"></i>
97               </el-button>
98             </template>
99           </el-input>
100         </el-form-item>
101         <el-form-item label="重试次数" prop="retryCount">
102           <el-input v-model="form.retryCount" placeholder="请输入重试次数。设置为 0 时,不进行重试" />
103         </el-form-item>
104         <el-form-item label="重试间隔" prop="retryInterval">
105           <el-input v-model="form.retryInterval" placeholder="请输入重试间隔,单位:毫秒。设置为 0 时,无需间隔" />
106         </el-form-item>
107         <el-form-item label="监控超时时间" prop="monitorTimeout">
108           <el-input v-model="form.monitorTimeout" placeholder="请输入监控超时时间,单位:毫秒" />
109         </el-form-item>
110       </el-form>
111       <div slot="footer" class="dialog-footer">
112         <el-button type="primary" @click="submitForm">确 定</el-button>
113         <el-button @click="cancel">取 消</el-button>
114       </div>
115     </el-dialog>
116
117     <el-dialog title="Cron表达式生成器" :visible.sync="openCron" append-to-body class="scrollbar" destroy-on-close>
118       <crontab @hide="openCron=false" @fill="crontabFill" :expression="expression"></crontab>
119     </el-dialog>
120
121     <!-- 任务详细 -->
122     <el-dialog title="任务详细" :visible.sync="openView" width="700px" append-to-body>
123       <el-form ref="form" :model="form" label-width="200px" size="mini">
124         <el-row>
125           <el-col :span="24">
126             <el-form-item label="任务编号:">{{ form.id }}</el-form-item>
127             <el-form-item label="任务名称:">{{ form.name }}</el-form-item>
128             <el-form-item label="任务名称:">
129               <dict-tag :type="DICT_TYPE.INFRA_JOB_STATUS" :value="form.status" />
130             </el-form-item>
131             <el-form-item label="处理器的名字:">{{ form.handlerName }}</el-form-item>
132             <el-form-item label="处理器的参数:">{{ form.handlerParam }}</el-form-item>
133             <el-form-item label="cron表达式:">{{ form.cronExpression }}</el-form-item>
134             <el-form-item label="重试次数:">{{ form.retryCount }}</el-form-item>
135             <el-form-item label="重试间隔:">{{ form.retryInterval + " 毫秒" }}</el-form-item>
136             <el-form-item label="监控超时时间:">{{ form.monitorTimeout > 0 ? form.monitorTimeout + " 毫秒" : "未开启" }}</el-form-item>
137             <el-form-item label="后续执行时间:">{{ Array.from(nextTimes, x => parseTime(x)).join('; ')}}</el-form-item>
138           </el-col>
139         </el-row>
140       </el-form>
141       <div slot="footer" class="dialog-footer">
142         <el-button @click="openView = false">关 闭</el-button>
143       </div>
144     </el-dialog>
145   </div>
146 </template>
147
148 <script>
149 import { listJob, getJob, delJob, addJob, updateJob, exportJob, runJob, updateJobStatus, getJobNextTimes } from "@/api/infra/job";
150 import { InfraJobStatusEnum } from "@/utils/constants";
151 import Crontab from '@/components/Crontab'
152
153 export default {
154   components: { Crontab },
155   name: "InfraJob",
156   data() {
157     return {
158       // 遮罩层
159       loading: true,
160       // 导出遮罩层
161       exportLoading: false,
162       // 显示搜索条件
163       showSearch: true,
164       // 总条数
165       total: 0,
166       // 定时任务表格数据
167       jobList: [],
168       // 弹出层标题
169       title: "",
170       // 是否显示弹出层
171       open: false,
172       // 是否显示详细弹出层
173       openView: false,
174       // 是否显示Cron表达式弹出层
175       openCron: false,
176       // 传入的表达式
177       expression: "",
178       // 状态字典
179       statusOptions: [],
180       // 查询参数
181       queryParams: {
182         pageNo: 1,
183         pageSize: 10,
184         name: undefined,
185         status: undefined,
186         handlerName: undefined
187       },
188       // 表单参数
189       form: {},
190       // 表单校验
191       rules: {
192         name: [{ required: true, message: "任务名称不能为空", trigger: "blur" }],
193         handlerName: [{ required: true, message: "处理器的名字不能为空", trigger: "blur" }],
194         cronExpression: [{ required: true, message: "CRON 表达式不能为空", trigger: "blur" }],
195         retryCount: [{ required: true, message: "重试次数不能为空", trigger: "blur" }],
196         retryInterval: [{ required: true, message: "重试间隔不能为空", trigger: "blur" }],
197       },
198       nextTimes: [], // 后续执行时间
199
200       // 枚举
201       InfJobStatusEnum: InfraJobStatusEnum
202     };
203   },
204   created() {
205     this.getList();
206   },
207   methods: {
208     /** 查询定时任务列表 */
209     getList() {
210       this.loading = true;
211       listJob(this.queryParams).then(response => {
212         this.jobList = response.data.list;
213         this.total = response.data.total;
214         this.loading = false;
215       });
216     },
217     /** 取消按钮 */
218     cancel() {
219       this.open = false;
220       this.reset();
221     },
222     /** 表单重置 */
223     reset() {
224       this.form = {
225         id: undefined,
226         name: undefined,
227         handlerName: undefined,
228         handlerParam: undefined,
229         cronExpression: undefined,
230         retryCount: undefined,
231         retryInterval: undefined,
232         monitorTimeout: undefined,
233       };
234       this.nextTimes = [];
235       this.resetForm("form");
236     },
237     /** 搜索按钮操作 */
238     handleQuery() {
239       this.queryParams.pageNo = 1;
240       this.getList();
241     },
242     /** 重置按钮操作 */
243     resetQuery() {
244       this.resetForm("queryForm");
245       this.handleQuery();
246     },
247     /** 立即执行一次 **/
248     handleRun(row) {
249       this.$modal.confirm('确认要立即执行一次"' + row.name + '"任务吗?').then(function() {
250           return runJob(row.id);
251         }).then(() => {
252           this.$modal.msgSuccess("执行成功");
253       }).catch(() => {});
254     },
255     /** 任务详细信息 */
256     handleView(row) {
257       getJob(row.id).then(response => {
258         this.form = response.data;
259         this.openView = true;
260       });
261       // 获取下一次执行时间
262       getJobNextTimes(row.id).then(response => {
263         this.nextTimes = response.data;
264       });
265     },
266     /** cron表达式按钮操作 */
267     handleShowCron() {
268       this.expression = this.form.cronExpression;
269       this.openCron = true;
270     },
271     /** 确定后回传值 */
272     crontabFill(value) {
273       this.form.cronExpression = value;
274     },
275     /** 任务日志列表查询 */
276     handleJobLog(row) {
277       if (row.id) {
278         this.$router.push({
279           path:"/job/log",
280           query:{
281             jobId: row.id
282           }
283         });
284       } else {
285         this.$router.push("/job/log");
286       }
287     },
288     /** 新增按钮操作 */
289     handleAdd() {
290       this.reset();
291       this.open = true;
292       this.title = "添加任务";
293     },
294     /** 修改按钮操作 */
295     handleUpdate(row) {
296       this.reset();
297       const id = row.id;
298       getJob(id).then(response => {
299         this.form = response.data;
300         this.open = true;
301         this.title = "修改任务";
302       });
303     },
304     /** 提交按钮 */
305     submitForm: function() {
306       this.$refs["form"].validate(valid => {
307         if (valid) {
308           if (this.form.id !== undefined) {
309             updateJob(this.form).then(response => {
310               this.$modal.msgSuccess("修改成功");
311               this.open = false;
312               this.getList();
313             });
314           } else {
315             addJob(this.form).then(response => {
316               this.$modal.msgSuccess("新增成功");
317               this.open = false;
318               this.getList();
319             });
320           }
321         }
322       });
323     },
324     /** 删除按钮操作 */
325     handleDelete(row) {
326       const ids = row.id;
327       this.$modal.confirm('是否确认删除定时任务编号为"' + ids + '"的数据项?').then(function() {
328           return delJob(ids);
329         }).then(() => {
330           this.getList();
331           this.$modal.msgSuccess("删除成功");
332       }).catch(() => {});
333     },
334     /** 更新状态操作 */
335     handleChangeStatus(row, open) {
336       const id = row.id;
337       let status = open ? InfraJobStatusEnum.NORMAL : InfraJobStatusEnum.STOP;
338       let statusStr = open ? '开启' : '关闭';
339       this.$modal.confirm('是否确认' + statusStr + '定时任务编号为"' + id + '"的数据项?').then(function() {
340         return updateJobStatus(id, status);
341       }).then(() => {
342         this.getList();
343         this.$modal.msgSuccess(statusStr + "成功");
344       }).catch(() => {});
345     },
346     // 更多操作触发
347     handleCommand(command, row) {
348       switch (command) {
349         case "handleRun":
350           this.handleRun(row);
351           break;
352         case "handleView":
353           this.handleView(row);
354           break;
355         case "handleJobLog":
356           this.handleJobLog(row);
357           break;
358         default:
359           break;
360       }
361     },
362     /** 导出按钮操作 */
363     handleExport() {
364       const queryParams = this.queryParams;
365       this.$modal.confirm("是否确认导出所有定时任务数据项?").then(() => {
366           this.exportLoading = true;
367           return exportJob(queryParams);
368         }).then(response => {
369           this.$download.excel(response, '定时任务.xls');
370           this.exportLoading = false;
371       }).catch(() => {});
372     }
373   }
374 };
375 </script>