index.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  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="taskName">
  5. <el-input
  6. v-model="queryParams.taskName"
  7. placeholder="请输入任务名称"
  8. clearable
  9. @keyup.enter.native="handleQuery"
  10. />
  11. </el-form-item>
  12. <!-- <el-form-item label="任务数" prop="subtaskNum">-->
  13. <!-- <el-input-->
  14. <!-- v-model="queryParams.subtaskNum"-->
  15. <!-- placeholder="请输入任务数"-->
  16. <!-- clearable-->
  17. <!-- @keyup.enter.native="handleQuery"-->
  18. <!-- />-->
  19. <!-- </el-form-item>-->
  20. <!-- <el-form-item label="开始时间" prop="startTime">-->
  21. <!-- <el-date-picker clearable-->
  22. <!-- v-model="queryParams.startTime"-->
  23. <!-- type="date"-->
  24. <!-- value-format="yyyy-MM-dd"-->
  25. <!-- placeholder="请选择开始时间">-->
  26. <!-- </el-date-picker>-->
  27. <!-- </el-form-item>-->
  28. <!-- <el-form-item label="结束时间" prop="endTime">-->
  29. <!-- <el-date-picker clearable-->
  30. <!-- v-model="queryParams.endTime"-->
  31. <!-- type="date"-->
  32. <!-- value-format="yyyy-MM-dd"-->
  33. <!-- placeholder="请选择结束时间">-->
  34. <!-- </el-date-picker>-->
  35. <!-- </el-form-item>-->
  36. <!-- <el-form-item label="完成率" prop="progress">-->
  37. <!-- <el-input-->
  38. <!-- v-model="queryParams.progress"-->
  39. <!-- placeholder="请输入完成率"-->
  40. <!-- clearable-->
  41. <!-- @keyup.enter.native="handleQuery"-->
  42. <!-- />-->
  43. <!-- </el-form-item>-->
  44. <!-- <el-form-item label="准确率" prop="accuracyRate">-->
  45. <!-- <el-input-->
  46. <!-- v-model="queryParams.accuracyRate"-->
  47. <!-- placeholder="请输入准确率"-->
  48. <!-- clearable-->
  49. <!-- @keyup.enter.native="handleQuery"-->
  50. <!-- />-->
  51. <!-- </el-form-item>-->
  52. <!-- <el-form-item label="召回率" prop="recallRate">-->
  53. <!-- <el-input-->
  54. <!-- v-model="queryParams.recallRate"-->
  55. <!-- placeholder="请输入召回率"-->
  56. <!-- clearable-->
  57. <!-- @keyup.enter.native="handleQuery"-->
  58. <!-- />-->
  59. <!-- </el-form-item>-->
  60. <el-form-item>
  61. <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
  62. <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
  63. </el-form-item>
  64. </el-form>
  65. <el-row :gutter="10" class="mb8">
  66. <!-- <el-col :span="1.5">-->
  67. <!-- <el-button-->
  68. <!-- type="primary"-->
  69. <!-- plain-->
  70. <!-- icon="el-icon-plus"-->
  71. <!-- size="mini"-->
  72. <!-- @click="handleAdd"-->
  73. <!-- v-hasPermi="['biz:task:add']"-->
  74. <!-- >新增</el-button>-->
  75. <!-- </el-col>-->
  76. <!-- <el-col :span="1.5">-->
  77. <!-- <el-button-->
  78. <!-- type="success"-->
  79. <!-- plain-->
  80. <!-- icon="el-icon-edit"-->
  81. <!-- size="mini"-->
  82. <!-- :disabled="single"-->
  83. <!-- @click="handleUpdate"-->
  84. <!-- v-hasPermi="['biz:task:edit']"-->
  85. <!-- >修改</el-button>-->
  86. <!-- </el-col>-->
  87. <!-- <el-col :span="1.5">-->
  88. <!-- <el-button-->
  89. <!-- type="danger"-->
  90. <!-- plain-->
  91. <!-- icon="el-icon-delete"-->
  92. <!-- size="mini"-->
  93. <!-- :disabled="multiple"-->
  94. <!-- @click="handleDelete"-->
  95. <!-- v-hasPermi="['biz:task:remove']"-->
  96. <!-- >删除</el-button>-->
  97. <!-- </el-col>-->
  98. <el-col :span="1.5">
  99. <el-button
  100. type="info"
  101. icon="el-icon-upload2"
  102. size="mini"
  103. @click="handleImport"
  104. v-hasPermi="['biz:detail:import']"
  105. >导入</el-button>
  106. </el-col>
  107. <el-col :span="1.5">
  108. <el-button
  109. type="warning"
  110. plain
  111. icon="el-icon-download"
  112. size="mini"
  113. @click="handleExport"
  114. v-hasPermi="['biz:detail:export']"
  115. >选择任务导出任务详情</el-button>
  116. </el-col>
  117. <el-col :span="1.5" >
  118. <el-button
  119. type='success'
  120. plain
  121. icon="el-icon-video-play"
  122. size="mini"
  123. @click="handleRun"
  124. >运行</el-button>
  125. </el-col>
  126. <!-- <el-col :span="1.5" >-->
  127. <!-- <el-button-->
  128. <!-- type='danger'-->
  129. <!-- plain-->
  130. <!-- icon="el-icon-video-pause"-->
  131. <!-- size="mini"-->
  132. <!-- @click="handleRun"-->
  133. <!-- >终止</el-button>-->
  134. <!-- </el-col>-->
  135. <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
  136. </el-row>
  137. <el-table v-loading="loading" :data="taskList" @selection-change="handleSelectionChange">
  138. <el-table-column type="selection" width="55" align="center" />
  139. <el-table-column label="任务编号" align="center" prop="id" />
  140. <el-table-column label="任务名称" align="center" prop="taskName" :show-overflow-tooltip='true' />
  141. <el-table-column label="状态" align="center" prop="taskStatus" :show-overflow-tooltip='true' />
  142. <el-table-column label="任务数" align="center" prop="subtaskNum" />
  143. <el-table-column label="开始时间" align="center" prop="startTime" width="180">
  144. <template slot-scope="scope">
  145. <span>{{ parseTime(scope.row.startTime) }}</span>
  146. </template>
  147. </el-table-column>
  148. <el-table-column label="结束时间" align="center" prop="endTime" width="180">
  149. <template slot-scope="scope">
  150. <span>{{ parseTime(scope.row.endTime) }}</span>
  151. </template>
  152. </el-table-column>
  153. <el-table-column label="完成率" align="center" prop="progress" />
  154. <el-table-column label="准确率" align="center" prop="accuracyRate" />
  155. <el-table-column label="召回率" align="center" prop="recallRate" />
  156. <el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip='true' />
  157. <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="100">
  158. <template slot-scope="scope">
  159. <el-button
  160. size="mini"
  161. type="text"
  162. icon="el-icon-edit"
  163. @click="handleUpdate(scope.row)"
  164. v-hasPermi="['biz:task:edit']"
  165. >修改</el-button>
  166. <el-button
  167. size="mini"
  168. type="text"
  169. icon="el-icon-delete"
  170. @click="handleDelete(scope.row)"
  171. v-hasPermi="['biz:task:remove']"
  172. >删除</el-button>
  173. </template>
  174. </el-table-column>
  175. </el-table>
  176. <pagination
  177. v-show="total>0"
  178. :total="total"
  179. :page.sync="queryParams.pageNum"
  180. :limit.sync="queryParams.pageSize"
  181. @pagination="getList"
  182. />
  183. <!-- 任务详情导入对话框 -->
  184. <el-dialog :title="upload.title" :visible.sync="upload.open" width="400px">
  185. <el-upload
  186. ref="upload"
  187. :limit="1"
  188. accept=".xlsx, .xls"
  189. :headers="upload.headers"
  190. :action="upload.url + '?updateSupport=' + upload.updateSupport"
  191. :disabled="upload.isUploading"
  192. :on-progress="handleFileUploadProgress"
  193. :on-success="handleFileSuccess"
  194. :auto-upload="false"
  195. drag
  196. >
  197. <i class="el-icon-upload"></i>
  198. <div class="el-upload__text">
  199. 将文件拖到此处,或
  200. <em>点击上传</em>
  201. </div>
  202. <div class="el-upload__tip" slot="tip">
  203. <el-checkbox v-model="upload.updateSupport" />是否更新已经存在的数据
  204. <el-link type="info" style="font-size:12px" @click="importTemplate">下载模板</el-link>
  205. </div>
  206. <div class="el-upload__tip" style="color:red" slot="tip">提示:仅允许导入“xls”或“xlsx”格式文件!</div>
  207. </el-upload>
  208. <div slot="footer" class="dialog-footer">
  209. <el-button type="primary" @click="submitFileForm">确 定</el-button>
  210. <el-button @click="upload.open = false">取 消</el-button>
  211. </div>
  212. </el-dialog>
  213. <!-- 添加或修改验证任务对话框 -->
  214. <el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
  215. <el-form style="border:1px solid #C0C0C0;padding: 5px;margin: auto" ref="form" :model="form" :rules="rules" label-width="120px">
  216. <el-form-item label="任务名称" prop="taskName">
  217. <el-input v-model="form.taskName" placeholder="请输入任务名称" />
  218. </el-form-item>
  219. <el-form-item label="任务数" prop="subtaskNum">
  220. <el-input v-model="form.subtaskNum" placeholder="请输入任务数" />
  221. </el-form-item>
  222. <el-form-item label="开始时间" prop="startTime">
  223. <el-date-picker clearable
  224. v-model="form.startTime"
  225. type="date"
  226. value-format="yyyy-MM-dd HH:mm:ss"
  227. placeholder="请选择开始时间">
  228. </el-date-picker>
  229. </el-form-item>
  230. <el-form-item label="结束时间" prop="endTime">
  231. <el-date-picker clearable
  232. v-model="form.endTime"
  233. type="date"
  234. value-format="yyyy-MM-dd HH:mm:ss"
  235. placeholder="请选择结束时间">
  236. </el-date-picker>
  237. </el-form-item>
  238. <el-form-item label="完成率" prop="progress">
  239. <el-input v-model="form.progress" placeholder="请输入完成率" />
  240. </el-form-item>
  241. <el-form-item label="准确率" prop="accuracyRate">
  242. <el-input v-model="form.accuracyRate" placeholder="请输入准确率" />
  243. </el-form-item>
  244. <el-form-item label="召回率" prop="recallRate">
  245. <el-input v-model="form.recallRate" placeholder="请输入召回率" />
  246. </el-form-item>
  247. <el-form-item label="备注" prop="remark">
  248. <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
  249. </el-form-item>
  250. </el-form>
  251. <div slot="footer" class="dialog-footer">
  252. <el-button type="primary" @click="submitForm">确 定</el-button>
  253. <el-button @click="cancel">取 消</el-button>
  254. </div>
  255. </el-dialog>
  256. </div>
  257. </template>
  258. <script>
  259. import { listTask, getTask, delTask, addTask, updateTask } from "@/api/biz/task";
  260. import { getToken } from "@/utils/auth";
  261. import {Loading, Message} from "element-ui";
  262. import service from "../../../utils/request";
  263. import errorCode from "../../../utils/errorCode";
  264. import dayjs from "dayjs";
  265. export default {
  266. name: "Task",
  267. data() {
  268. return {
  269. // 遮罩层
  270. loading: true,
  271. // 选中数组
  272. ids: [],
  273. // 非单个禁用
  274. single: true,
  275. // 非多个禁用
  276. multiple: true,
  277. // 显示搜索条件
  278. showSearch: true,
  279. // 总条数
  280. total: 0,
  281. // 验证任务表格数据
  282. taskList: [],
  283. // 弹出层标题
  284. title: "",
  285. // 是否显示弹出层
  286. open: false,
  287. // 查询参数
  288. queryParams: {
  289. pageNum: 1,
  290. pageSize: 10,
  291. taskName: null,
  292. taskStatus: null,
  293. subtaskNum: null,
  294. startTime: null,
  295. endTime: null,
  296. progress: null,
  297. accuracyRate: null,
  298. recallRate: null,
  299. },
  300. // 表单参数
  301. form: {},
  302. // 表单校验
  303. rules: {
  304. },
  305. // 导入参数
  306. upload: {
  307. // 是否显示弹出层(导入)
  308. open: false,
  309. // 弹出层标题(导入)
  310. title: "",
  311. // 是否禁用上传
  312. isUploading: false,
  313. // 是否更新已经存在的用户数据
  314. updateSupport: 0,
  315. // 设置上传的请求头部
  316. headers: { Authorization: "Bearer " + getToken() },
  317. // 上传的地址
  318. url: process.env.VUE_APP_BASE_API + "/biz/detail/importData"
  319. },
  320. };
  321. },
  322. created() {
  323. this.getList();
  324. },
  325. methods: {
  326. handleRun(){
  327. let taskids = this.ids;
  328. const dayjs = require('dayjs');
  329. for(let taskid of taskids){
  330. getTask(taskid).then(response => {
  331. let task = response.data;
  332. task.startTime = dayjs().format('YYYY-MM-DD HH:mm:ss');
  333. setTimeout(()=>{
  334. task.taskStatus = "运行成功"
  335. task.endTime = dayjs().format('YYYY-MM-DD HH:mm:ss');
  336. updateTask(task).then(res => {
  337. this.$message.success("任务"+taskid+"运行成功!")
  338. this.getList();
  339. });
  340. }, 3000);
  341. });
  342. }
  343. },
  344. /** 查询验证任务列表 */
  345. getList() {
  346. this.loading = true;
  347. listTask(this.queryParams).then(response => {
  348. this.taskList = response.rows;
  349. this.total = response.total;
  350. this.loading = false;
  351. });
  352. },
  353. // 取消按钮
  354. cancel() {
  355. this.open = false;
  356. this.reset();
  357. },
  358. // 表单重置
  359. reset() {
  360. this.form = {
  361. id: null,
  362. taskName: null,
  363. taskStatus: null,
  364. subtaskNum: null,
  365. startTime: null,
  366. endTime: null,
  367. progress: null,
  368. accuracyRate: null,
  369. recallRate: null,
  370. createBy: null,
  371. createTime: null,
  372. updateBy: null,
  373. updateTime: null,
  374. remark: null
  375. };
  376. this.resetForm("form");
  377. },
  378. /** 搜索按钮操作 */
  379. handleQuery() {
  380. this.queryParams.pageNum = 1;
  381. this.getList();
  382. },
  383. /** 重置按钮操作 */
  384. resetQuery() {
  385. this.resetForm("queryForm");
  386. this.handleQuery();
  387. },
  388. // 多选框选中数据
  389. handleSelectionChange(selection) {
  390. this.ids = selection.map(item => item.id)
  391. this.single = selection.length!==1
  392. this.multiple = !selection.length
  393. },
  394. /** 新增按钮操作 */
  395. handleAdd() {
  396. this.reset();
  397. this.open = true;
  398. this.title = "添加验证任务";
  399. },
  400. /** 修改按钮操作 */
  401. handleUpdate(row) {
  402. this.reset();
  403. const id = row.id || this.ids
  404. getTask(id).then(response => {
  405. this.form = response.data;
  406. this.open = true;
  407. this.title = "修改验证任务";
  408. });
  409. },
  410. /** 提交按钮 */
  411. submitForm() {
  412. this.$refs["form"].validate(valid => {
  413. if (valid) {
  414. if (this.form.id != null) {
  415. updateTask(this.form).then(response => {
  416. this.$modal.msgSuccess("修改成功");
  417. this.open = false;
  418. this.getList();
  419. });
  420. } else {
  421. addTask(this.form).then(response => {
  422. this.$modal.msgSuccess("新增成功");
  423. this.open = false;
  424. this.getList();
  425. });
  426. }
  427. }
  428. });
  429. },
  430. /** 删除按钮操作 */
  431. handleDelete(row) {
  432. const ids = row.id || this.ids;
  433. this.$modal.confirm('是否确认删除验证任务编号为"' + ids + '"的数据项?').then(function() {
  434. return delTask(ids);
  435. }).then(() => {
  436. this.getList();
  437. this.$modal.msgSuccess("删除成功");
  438. }).catch(() => {});
  439. },
  440. /** 导出按钮操作 */
  441. handleExport() {
  442. if(this.ids.length===0) {
  443. this.importTemplate()
  444. }else {
  445. // this.download('biz/detail/export', this.ids, `taskdetail_${new Date().getTime()}.xlsx`)
  446. let downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", })
  447. let taskids = this.ids;
  448. return service.post('biz/detail/export', taskids, {
  449. headers: { 'Content-Type': 'application/json' },
  450. responseType: 'blob',
  451. }).then(async (data) => {
  452. // Debug: 输出实际的响应 Content-Type
  453. // console.log(data)
  454. // console.log("Response Content-Type:", data.type);
  455. const isBlob = (data.type !== 'application/json');
  456. if (isBlob) {
  457. const blob = new Blob([data])
  458. saveAs(blob, `taskdetail_${new Date().getTime()}.xlsx`)
  459. } else {
  460. const resText = await data.text();
  461. const rspObj = JSON.parse(resText);
  462. const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
  463. Message.error(errMsg);
  464. }
  465. downloadLoadingInstance.close();
  466. }).catch((error) => {
  467. console.error(error)
  468. Message.error('下载文件出现错误,请联系管理员!')
  469. downloadLoadingInstance.close();
  470. })
  471. }
  472. },
  473. /** 导入按钮操作 */
  474. handleImport() {
  475. this.upload.title = "任务详情导入";
  476. this.upload.open = true;
  477. },
  478. /** 下载模板操作 */
  479. importTemplate() {
  480. this.download('biz/detail/importTemplate', {
  481. }, `taskdetail_template_${new Date().getTime()}.xlsx`)
  482. },
  483. // 文件上传中处理
  484. handleFileUploadProgress(event, file, fileList) {
  485. this.upload.isUploading = true;
  486. },
  487. // 文件上传成功处理
  488. handleFileSuccess(response, file, fileList) {
  489. this.upload.open = false;
  490. this.upload.isUploading = false;
  491. this.$refs.upload.clearFiles();
  492. this.$alert(response.msg, "导入结果", { dangerouslyUseHTMLString: true });
  493. this.getList();
  494. },
  495. // 提交上传文件
  496. submitFileForm() {
  497. this.$refs.upload.submit();
  498. }
  499. }
  500. };
  501. </script>