admin
2024-06-15 8cfe20288690f2ba46c804f41f39e8aa48c2dea0
提交 | 用户 | 时间
e57a89 1 <template>
2   <div class="app-container">
3     <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
4       <el-form-item label="任务名称" prop="jobName">
5         <el-input
6           v-model="queryParams.jobName"
7           placeholder="请输入任务名称"
8           clearable
9           @keyup.enter.native="handleQuery"
10         />
11       </el-form-item>
12       <el-form-item label="任务组名" prop="jobGroup">
13         <el-select v-model="queryParams.jobGroup" placeholder="请选择任务组名" clearable>
14           <el-option
15             v-for="dict in dict.type.sys_job_group"
16             :key="dict.value"
17             :label="dict.label"
18             :value="dict.value"
19           />
20         </el-select>
21       </el-form-item>
22       <el-form-item label="任务状态" prop="status">
23         <el-select v-model="queryParams.status" placeholder="请选择任务状态" clearable>
24           <el-option
25             v-for="dict in dict.type.sys_job_status"
26             :key="dict.value"
27             :label="dict.label"
28             :value="dict.value"
29           />
30         </el-select>
31       </el-form-item>
32       <el-form-item>
33         <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
34         <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
35       </el-form-item>
36     </el-form>
37
38     <el-row :gutter="10" class="mb8">
39       <el-col :span="1.5">
40         <el-button
41           type="primary"
42           plain
43           icon="el-icon-plus"
44           size="mini"
45           @click="handleAdd"
46           v-hasPermi="['monitor:job:add']"
47         >新增</el-button>
48       </el-col>
49       <el-col :span="1.5">
50         <el-button
51           type="success"
52           plain
53           icon="el-icon-edit"
54           size="mini"
55           :disabled="single"
56           @click="handleUpdate"
57           v-hasPermi="['monitor:job:edit']"
58         >修改</el-button>
59       </el-col>
60       <el-col :span="1.5">
61         <el-button
62           type="danger"
63           plain
64           icon="el-icon-delete"
65           size="mini"
66           :disabled="multiple"
67           @click="handleDelete"
68           v-hasPermi="['monitor:job:remove']"
69         >删除</el-button>
70       </el-col>
71       <el-col :span="1.5">
72         <el-button
73           type="warning"
74           plain
75           icon="el-icon-download"
76           size="mini"
77           @click="handleExport"
78           v-hasPermi="['monitor:job:export']"
79         >导出</el-button>
80       </el-col>
81       <el-col :span="1.5">
82         <el-button
83           type="info"
84           plain
85           icon="el-icon-s-operation"
86           size="mini"
87           @click="handleJobLog"
88           v-hasPermi="['monitor:job:query']"
89         >日志</el-button>
90       </el-col>
91       <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
92     </el-row>
93
94     <el-table v-loading="loading" :data="jobList" @selection-change="handleSelectionChange">
95       <el-table-column type="selection" width="55" align="center" />
96       <el-table-column label="任务编号" width="100" align="center" prop="jobId" />
97       <el-table-column label="任务名称" align="center" prop="jobName" :show-overflow-tooltip="true" />
98       <el-table-column label="任务组名" align="center" prop="jobGroup">
99         <template slot-scope="scope">
100           <dict-tag :options="dict.type.sys_job_group" :value="scope.row.jobGroup"/>
101         </template>
102       </el-table-column>
103       <el-table-column label="调用目标字符串" align="center" prop="invokeTarget" :show-overflow-tooltip="true" />
104       <el-table-column label="cron执行表达式" align="center" prop="cronExpression" :show-overflow-tooltip="true" />
105       <el-table-column label="状态" align="center">
106         <template slot-scope="scope">
107           <el-switch
108             v-model="scope.row.status"
109             active-value="0"
110             inactive-value="1"
111             @change="handleStatusChange(scope.row)"
112           ></el-switch>
113         </template>
114       </el-table-column>
115       <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
116         <template slot-scope="scope">
117           <el-button
118             size="mini"
119             type="text"
120             icon="el-icon-edit"
121             @click="handleUpdate(scope.row)"
122             v-hasPermi="['monitor:job:edit']"
123           >修改</el-button>
124           <el-button
125             size="mini"
126             type="text"
127             icon="el-icon-delete"
128             @click="handleDelete(scope.row)"
129             v-hasPermi="['monitor:job:remove']"
130           >删除</el-button>
131           <el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)" v-hasPermi="['monitor:job:changeStatus', 'monitor:job:query']">
132             <el-button size="mini" type="text" icon="el-icon-d-arrow-right">更多</el-button>
133             <el-dropdown-menu slot="dropdown">
134               <el-dropdown-item command="handleRun" icon="el-icon-caret-right"
135                 v-hasPermi="['monitor:job:changeStatus']">执行一次</el-dropdown-item>
136               <el-dropdown-item command="handleView" icon="el-icon-view"
137                 v-hasPermi="['monitor:job:query']">任务详细</el-dropdown-item>
138               <el-dropdown-item command="handleJobLog" icon="el-icon-s-operation"
139                 v-hasPermi="['monitor:job:query']">调度日志</el-dropdown-item>
140             </el-dropdown-menu>
141           </el-dropdown>
142         </template>
143       </el-table-column>
144     </el-table>
145
146     <pagination
147       v-show="total>0"
148       :total="total"
149       :page.sync="queryParams.pageNum"
150       :limit.sync="queryParams.pageSize"
151       @pagination="getList"
152     />
153
154     <!-- 添加或修改定时任务对话框 -->
155     <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
156       <el-form ref="form" :model="form" :rules="rules" label-width="120px">
157         <el-row>
158           <el-col :span="12">
159             <el-form-item label="任务名称" prop="jobName">
160               <el-input v-model="form.jobName" placeholder="请输入任务名称" />
161             </el-form-item>
162           </el-col>
163           <el-col :span="12">
164             <el-form-item label="任务分组" prop="jobGroup">
165               <el-select v-model="form.jobGroup" placeholder="请选择任务分组">
166                 <el-option
167                   v-for="dict in dict.type.sys_job_group"
168                   :key="dict.value"
169                   :label="dict.label"
170                   :value="dict.value"
171                 ></el-option>
172               </el-select>
173             </el-form-item>
174           </el-col>
175           <el-col :span="24">
176             <el-form-item prop="invokeTarget">
177               <span slot="label">
178                 调用方法
179                 <el-tooltip placement="top">
180                   <div slot="content">
181                     Bean调用示例:ryTask.ryParams('ry')
182                     <br />Class类调用示例:com.jcdm.quartz.task.RyTask.ryParams('ry')
183                     <br />参数说明:支持字符串,布尔类型,长整型,浮点型,整型
184                   </div>
185                   <i class="el-icon-question"></i>
186                 </el-tooltip>
187               </span>
188               <el-input v-model="form.invokeTarget" placeholder="请输入调用目标字符串" />
189             </el-form-item>
190           </el-col>
191           <el-col :span="24">
192             <el-form-item label="cron表达式" prop="cronExpression">
193               <el-input v-model="form.cronExpression" placeholder="请输入cron执行表达式">
194                 <template slot="append">
195                   <el-button type="primary" @click="handleShowCron">
196                     生成表达式
197                     <i class="el-icon-time el-icon--right"></i>
198                   </el-button>
199                 </template>
200               </el-input>
201             </el-form-item>
202           </el-col>
203           <el-col :span="24" v-if="form.jobId !== undefined">
204             <el-form-item label="状态">
205               <el-radio-group v-model="form.status">
206                 <el-radio
207                   v-for="dict in dict.type.sys_job_status"
208                   :key="dict.value"
209                   :label="dict.value"
210                 >{{dict.label}}</el-radio>
211               </el-radio-group>
212             </el-form-item>
213           </el-col>
214           <el-col :span="12">
215             <el-form-item label="执行策略" prop="misfirePolicy">
216               <el-radio-group v-model="form.misfirePolicy" size="small">
217                 <el-radio-button label="1">立即执行</el-radio-button>
218                 <el-radio-button label="2">执行一次</el-radio-button>
219                 <el-radio-button label="3">放弃执行</el-radio-button>
220               </el-radio-group>
221             </el-form-item>
222           </el-col>
223           <el-col :span="12">
224             <el-form-item label="是否并发" prop="concurrent">
225               <el-radio-group v-model="form.concurrent" size="small">
226                 <el-radio-button label="0">允许</el-radio-button>
227                 <el-radio-button label="1">禁止</el-radio-button>
228               </el-radio-group>
229             </el-form-item>
230           </el-col>
231         </el-row>
232       </el-form>
233       <div slot="footer" class="dialog-footer">
234         <el-button type="primary" @click="submitForm">确 定</el-button>
235         <el-button @click="cancel">取 消</el-button>
236       </div>
237     </el-dialog>
238
239     <el-dialog title="Cron表达式生成器" :visible.sync="openCron" append-to-body destroy-on-close class="scrollbar">
240       <crontab @hide="openCron=false" @fill="crontabFill" :expression="expression"></crontab>
241     </el-dialog>
242
243     <!-- 任务日志详细 -->
244     <el-dialog title="任务详细" :visible.sync="openView" width="700px" append-to-body>
245       <el-form ref="form" :model="form" label-width="120px" size="mini">
246         <el-row>
247           <el-col :span="12">
248             <el-form-item label="任务编号:">{{ form.jobId }}</el-form-item>
249             <el-form-item label="任务名称:">{{ form.jobName }}</el-form-item>
250           </el-col>
251           <el-col :span="12">
252             <el-form-item label="任务分组:">{{ jobGroupFormat(form) }}</el-form-item>
253             <el-form-item label="创建时间:">{{ form.createTime }}</el-form-item>
254           </el-col>
255           <el-col :span="12">
256             <el-form-item label="cron表达式:">{{ form.cronExpression }}</el-form-item>
257           </el-col>
258           <el-col :span="12">
259             <el-form-item label="下次执行时间:">{{ parseTime(form.nextValidTime) }}</el-form-item>
260           </el-col>
261           <el-col :span="24">
262             <el-form-item label="调用目标方法:">{{ form.invokeTarget }}</el-form-item>
263           </el-col>
264           <el-col :span="12">
265             <el-form-item label="任务状态:">
266               <div v-if="form.status == 0">正常</div>
267               <div v-else-if="form.status == 1">暂停</div>
268             </el-form-item>
269           </el-col>
270           <el-col :span="12">
271             <el-form-item label="是否并发:">
272               <div v-if="form.concurrent == 0">允许</div>
273               <div v-else-if="form.concurrent == 1">禁止</div>
274             </el-form-item>
275           </el-col>
276           <el-col :span="12">
277             <el-form-item label="执行策略:">
278               <div v-if="form.misfirePolicy == 0">默认策略</div>
279               <div v-else-if="form.misfirePolicy == 1">立即执行</div>
280               <div v-else-if="form.misfirePolicy == 2">执行一次</div>
281               <div v-else-if="form.misfirePolicy == 3">放弃执行</div>
282             </el-form-item>
283           </el-col>
284         </el-row>
285       </el-form>
286       <div slot="footer" class="dialog-footer">
287         <el-button @click="openView = false">关 闭</el-button>
288       </div>
289     </el-dialog>
290   </div>
291 </template>
292
293 <script>
294 import { listJob, getJob, delJob, addJob, updateJob, runJob, changeJobStatus } from "@/api/monitor/job";
295 import Crontab from '@/components/Crontab'
296
297 export default {
298   components: { Crontab },
299   name: "Job",
300   dicts: ['sys_job_group', 'sys_job_status'],
301   data() {
302     return {
303       // 遮罩层
304       loading: true,
305       // 选中数组
306       ids: [],
307       // 非单个禁用
308       single: true,
309       // 非多个禁用
310       multiple: true,
311       // 显示搜索条件
312       showSearch: true,
313       // 总条数
314       total: 0,
315       // 定时任务表格数据
316       jobList: [],
317       // 弹出层标题
318       title: "",
319       // 是否显示弹出层
320       open: false,
321       // 是否显示详细弹出层
322       openView: false,
323       // 是否显示Cron表达式弹出层
324       openCron: false,
325       // 传入的表达式
326       expression: "",
327       // 查询参数
328       queryParams: {
329         pageNum: 1,
330         pageSize: 10,
331         jobName: undefined,
332         jobGroup: undefined,
333         status: undefined
334       },
335       // 表单参数
336       form: {},
337       // 表单校验
338       rules: {
339         jobName: [
340           { required: true, message: "任务名称不能为空", trigger: "blur" }
341         ],
342         invokeTarget: [
343           { required: true, message: "调用目标字符串不能为空", trigger: "blur" }
344         ],
345         cronExpression: [
346           { required: true, message: "cron执行表达式不能为空", trigger: "blur" }
347         ]
348       }
349     };
350   },
351   created() {
352     this.getList();
353   },
354   methods: {
355     /** 查询定时任务列表 */
356     getList() {
357       this.loading = true;
358       listJob(this.queryParams).then(response => {
359         this.jobList = response.rows;
360         this.total = response.total;
361         this.loading = false;
362       });
363     },
364     // 任务组名字典翻译
365     jobGroupFormat(row, column) {
366       return this.selectDictLabel(this.dict.type.sys_job_group, row.jobGroup);
367     },
368     // 取消按钮
369     cancel() {
370       this.open = false;
371       this.reset();
372     },
373     // 表单重置
374     reset() {
375       this.form = {
376         jobId: undefined,
377         jobName: undefined,
378         jobGroup: undefined,
379         invokeTarget: undefined,
380         cronExpression: undefined,
381         misfirePolicy: 1,
382         concurrent: 1,
383         status: "0"
384       };
385       this.resetForm("form");
386     },
387     /** 搜索按钮操作 */
388     handleQuery() {
389       this.queryParams.pageNum = 1;
390       this.getList();
391     },
392     /** 重置按钮操作 */
393     resetQuery() {
394       this.resetForm("queryForm");
395       this.handleQuery();
396     },
397     // 多选框选中数据
398     handleSelectionChange(selection) {
399       this.ids = selection.map(item => item.jobId);
400       this.single = selection.length != 1;
401       this.multiple = !selection.length;
402     },
403     // 更多操作触发
404     handleCommand(command, row) {
405       switch (command) {
406         case "handleRun":
407           this.handleRun(row);
408           break;
409         case "handleView":
410           this.handleView(row);
411           break;
412         case "handleJobLog":
413           this.handleJobLog(row);
414           break;
415         default:
416           break;
417       }
418     },
419     // 任务状态修改
420     handleStatusChange(row) {
421       let text = row.status === "0" ? "启用" : "停用";
422       this.$modal.confirm('确认要"' + text + '""' + row.jobName + '"任务吗?').then(function() {
423         return changeJobStatus(row.jobId, row.status);
424       }).then(() => {
425         this.$modal.msgSuccess(text + "成功");
426       }).catch(function() {
427         row.status = row.status === "0" ? "1" : "0";
428       });
429     },
430     /* 立即执行一次 */
431     handleRun(row) {
432       this.$modal.confirm('确认要立即执行一次"' + row.jobName + '"任务吗?').then(function() {
433         return runJob(row.jobId, row.jobGroup);
434       }).then(() => {
435         this.$modal.msgSuccess("执行成功");
436       }).catch(() => {});
437     },
438     /** 任务详细信息 */
439     handleView(row) {
440       getJob(row.jobId).then(response => {
441         this.form = response.data;
442         this.openView = true;
443       });
444     },
445     /** cron表达式按钮操作 */
446     handleShowCron() {
447       this.expression = this.form.cronExpression;
448       this.openCron = true;
449     },
450     /** 确定后回传值 */
451     crontabFill(value) {
452       this.form.cronExpression = value;
453     },
454     /** 任务日志列表查询 */
455     handleJobLog(row) {
456       const jobId = row.jobId || 0;
457       this.$router.push('/monitor/job-log/index/' + jobId)
458     },
459     /** 新增按钮操作 */
460     handleAdd() {
461       this.reset();
462       this.open = true;
463       this.title = "添加任务";
464     },
465     /** 修改按钮操作 */
466     handleUpdate(row) {
467       this.reset();
468       const jobId = row.jobId || this.ids;
469       getJob(jobId).then(response => {
470         this.form = response.data;
471         this.open = true;
472         this.title = "修改任务";
473       });
474     },
475     /** 提交按钮 */
476     submitForm: function() {
477       this.$refs["form"].validate(valid => {
478         if (valid) {
479           if (this.form.jobId != undefined) {
480             updateJob(this.form).then(response => {
481               this.$modal.msgSuccess("修改成功");
482               this.open = false;
483               this.getList();
484             });
485           } else {
486             addJob(this.form).then(response => {
487               this.$modal.msgSuccess("新增成功");
488               this.open = false;
489               this.getList();
490             });
491           }
492         }
493       });
494     },
495     /** 删除按钮操作 */
496     handleDelete(row) {
497       const jobIds = row.jobId || this.ids;
498       this.$modal.confirm('是否确认删除定时任务编号为"' + jobIds + '"的数据项?').then(function() {
499         return delJob(jobIds);
500       }).then(() => {
501         this.getList();
502         this.$modal.msgSuccess("删除成功");
503       }).catch(() => {});
504     },
505     /** 导出按钮操作 */
506     handleExport() {
507       this.download('monitor/job/export', {
508         ...this.queryParams
509       }, `job_${new Date().getTime()}.xlsx`)
510     }
511   }
512 };
513 </script>