index.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545
  1. <template>
  2. <div class="app-container">
  3. <el-form
  4. :model="queryParams"
  5. ref="queryForm"
  6. size="small"
  7. :inline="true"
  8. v-show="showSearch"
  9. label-width="68px"
  10. >
  11. <el-form-item label="任务名称" prop="taskName">
  12. <el-input
  13. v-model="queryParams.taskName"
  14. placeholder="请输入任务名称"
  15. clearable
  16. @keyup.enter.native="handleQuery"
  17. />
  18. </el-form-item>
  19. <el-form-item label="算法" prop="algorithmId">
  20. <el-select
  21. v-model="queryParams.algorithmId"
  22. placeholder="请选择算法"
  23. @keyup.enter.native="handleQuery"
  24. clearable
  25. >
  26. <el-option
  27. v-for="option in configOptions"
  28. :key="option.id"
  29. :label="option.name"
  30. :value="option.id"
  31. />
  32. </el-select>
  33. </el-form-item>
  34. <el-form-item label="状态" prop="status">
  35. <el-select
  36. v-model="queryParams.status"
  37. placeholder="请选择状态"
  38. clearable
  39. >
  40. <el-option
  41. v-for="dict in dict.type.biz_status"
  42. :key="dict.value"
  43. :label="dict.label"
  44. :value="dict.value"
  45. />
  46. </el-select>
  47. </el-form-item>
  48. <!-- <el-form-item label="开始时间" prop="startTime">
  49. <el-date-picker
  50. clearable
  51. v-model="queryParams.startTime"
  52. type="date"
  53. value-format="yyyy-MM-dd"
  54. placeholder="请选择开始时间"
  55. >
  56. </el-date-picker>
  57. </el-form-item>
  58. <el-form-item label="结束时间" prop="endTime">
  59. <el-date-picker
  60. clearable
  61. v-model="queryParams.endTime"
  62. type="date"
  63. value-format="yyyy-MM-dd"
  64. placeholder="请选择结束时间"
  65. >
  66. </el-date-picker>
  67. </el-form-item> -->
  68. <el-form-item>
  69. <el-button
  70. type="primary"
  71. icon="el-icon-search"
  72. size="mini"
  73. @click="handleQuery"
  74. >搜索</el-button
  75. >
  76. <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
  77. >重置</el-button
  78. >
  79. </el-form-item>
  80. </el-form>
  81. <el-row :gutter="10" class="mb8">
  82. <el-col :span="1.5">
  83. <el-button
  84. type="primary"
  85. plain
  86. icon="el-icon-plus"
  87. size="mini"
  88. @click="handleAdd"
  89. v-hasPermi="['biz:test:add']"
  90. >新增</el-button
  91. >
  92. </el-col>
  93. <el-col :span="1.5">
  94. <el-button
  95. type="success"
  96. plain
  97. icon="el-icon-edit"
  98. size="mini"
  99. :disabled="single"
  100. @click="handleUpdate"
  101. v-hasPermi="['biz:test:edit']"
  102. >修改</el-button
  103. >
  104. </el-col>
  105. <el-col :span="1.5">
  106. <el-button
  107. type="danger"
  108. plain
  109. icon="el-icon-delete"
  110. size="mini"
  111. :disabled="multiple"
  112. @click="handleDelete"
  113. v-hasPermi="['biz:test:remove']"
  114. >删除</el-button
  115. >
  116. </el-col>
  117. <!-- <el-col :span="1.5">
  118. <el-button
  119. type="warning"
  120. plain
  121. icon="el-icon-download"
  122. size="mini"
  123. @click="handleExport"
  124. v-hasPermi="['biz:test:export']"
  125. >导出</el-button
  126. >
  127. </el-col> -->
  128. <right-toolbar
  129. :showSearch.sync="showSearch"
  130. @queryTable="getList"
  131. ></right-toolbar>
  132. </el-row>
  133. <el-table
  134. v-loading="loading"
  135. :data="testList"
  136. @selection-change="handleSelectionChange"
  137. >
  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" />
  141. <el-table-column label="算法" align="center" prop="algorithmName" />
  142. <el-table-column label="状态" align="center" prop="status">
  143. <template slot-scope="scope">
  144. <dict-tag :options="dict.type.biz_status" :value="scope.row.status" />
  145. </template>
  146. </el-table-column>
  147. <el-table-column
  148. label="开始时间"
  149. align="center"
  150. prop="startTime"
  151. width="180"
  152. >
  153. <template slot-scope="scope">
  154. <span>{{ parseTime(scope.row.startTime) }}</span>
  155. </template>
  156. </el-table-column>
  157. <el-table-column
  158. label="结束时间"
  159. align="center"
  160. prop="endTime"
  161. width="180"
  162. >
  163. <template slot-scope="scope">
  164. <span>{{ parseTime(scope.row.endTime) }}</span>
  165. </template>
  166. </el-table-column>
  167. <el-table-column label="备注" align="center" prop="remark" />
  168. <el-table-column
  169. label="操作"
  170. align="center"
  171. class-name="small-padding fixed-width"
  172. >
  173. <template slot-scope="scope">
  174. <el-button
  175. size="mini"
  176. type="text"
  177. icon="el-icon-video-play"
  178. @click="handleRun(scope.row)"
  179. v-hasPermi="['biz:test:add']"
  180. >运行</el-button
  181. >
  182. <el-button
  183. type="text"
  184. icon="el-icon-search"
  185. @click="showLogViewer(scope.row)"
  186. >
  187. 日志
  188. </el-button>
  189. <el-button
  190. size="mini"
  191. type="text"
  192. icon="el-icon-info"
  193. @click="openFolder(scope.row)"
  194. v-hasPermi="['biz:images:add']"
  195. >打开结果</el-button
  196. >
  197. <el-button
  198. size="mini"
  199. type="text"
  200. icon="el-icon-edit"
  201. @click="handleUpdate(scope.row)"
  202. v-hasPermi="['biz:test:edit']"
  203. >修改</el-button
  204. >
  205. <el-button
  206. size="mini"
  207. type="text"
  208. icon="el-icon-delete"
  209. @click="handleDelete(scope.row)"
  210. v-hasPermi="['biz:test:remove']"
  211. >删除</el-button
  212. >
  213. </template>
  214. </el-table-column>
  215. </el-table>
  216. <pagination
  217. v-show="total > 0"
  218. :total="total"
  219. :page.sync="queryParams.pageNum"
  220. :limit.sync="queryParams.pageSize"
  221. @pagination="getList"
  222. />
  223. <!-- 添加或修改分类测试对话框 -->
  224. <el-dialog
  225. :title="title"
  226. :visible.sync="open"
  227. width="500px"
  228. append-to-body
  229. :close-on-click-modal="false"
  230. >
  231. <el-form ref="form" :model="form" :rules="rules" label-width="80px">
  232. <el-form-item label="任务名称" prop="taskName">
  233. <el-input v-model="form.taskName" placeholder="请输入任务名称" />
  234. </el-form-item>
  235. <el-form-item label="算法" prop="algorithmId">
  236. <el-select
  237. v-model="form.algorithmId"
  238. placeholder="请选择算法"
  239. @change="changeAlgorithmId"
  240. clearable
  241. >
  242. <el-option
  243. v-for="option in configOptions"
  244. :key="option.id"
  245. :label="option.name"
  246. :value="option.id"
  247. />
  248. </el-select>
  249. </el-form-item>
  250. <el-form-item label="pth模型" prop="modelPath">
  251. <folder-picker v-model="form.modelPath" />
  252. </el-form-item>
  253. <el-form-item label="pkl模型" prop="modelPklPath">
  254. <file-picker v-model="form.modelPklPath" />
  255. </el-form-item>
  256. <el-form-item label="输入路径" prop="inputPath">
  257. <folder-picker v-model="form.inputPath" />
  258. </el-form-item>
  259. <el-form-item label="输出路径" prop="outputPath">
  260. <folder-picker v-model="form.outputPath" />
  261. </el-form-item>
  262. <el-form-item label="算法参数" prop="algorithmParams">
  263. <el-button @click="showParamsDialog = true">设置参数</el-button>
  264. <dynamic-form-dialog
  265. :json-str="form.algorithmParams"
  266. :visible.sync="showParamsDialog"
  267. @submit="handleConfigSubmit"
  268. />
  269. </el-form-item>
  270. <el-form-item label="备注" prop="remark">
  271. <el-input
  272. v-model="form.remark"
  273. type="textarea"
  274. placeholder="请输入内容"
  275. />
  276. </el-form-item>
  277. </el-form>
  278. <div slot="footer" class="dialog-footer">
  279. <el-button type="primary" @click="submitForm">确 定</el-button>
  280. <el-button @click="cancel">取 消</el-button>
  281. </div>
  282. </el-dialog>
  283. <log-viewer
  284. :currentLogUrl="currentLogUrl"
  285. :dialogTitle="dialogTitle"
  286. :logDialogVisible="logDialogVisible"
  287. @updateLogDiaLlogVisible="updateLogDiaLlogVisible"
  288. />
  289. </div>
  290. </template>
  291. <script>
  292. import {
  293. listTest,
  294. getTest,
  295. delTest,
  296. addTest,
  297. updateTest,
  298. run,
  299. getResultDetails,
  300. } from "@/api/biz/test";
  301. import { getStatic } from "@/api/biz/common";
  302. import { getOptionsByType } from "@/api/biz/config";
  303. import FolderPicker from "@/components/FolderPicker";
  304. import FilePicker from "@/components/FilePicker";
  305. import DynamicFormDialog from "@/components/DynamicFormDialog";
  306. import LogViewer from "@/components/LogViewer";
  307. const { shell } = window.require("electron");
  308. export default {
  309. name: "Test",
  310. dicts: ["biz_status"],
  311. components: {
  312. FolderPicker,
  313. FilePicker,
  314. DynamicFormDialog,
  315. LogViewer,
  316. },
  317. data() {
  318. return {
  319. staticsUrl: process.env.VUE_APP_BASE_API + "/biz/common/getStatic",
  320. // 遮罩层
  321. loading: true,
  322. // 选中数组
  323. ids: [],
  324. // 非单个禁用
  325. single: true,
  326. // 非多个禁用
  327. multiple: true,
  328. // 显示搜索条件
  329. showSearch: true,
  330. // 总条数
  331. total: 0,
  332. // 分类测试表格数据
  333. testList: [],
  334. // 弹出层标题
  335. title: "",
  336. // 是否显示弹出层
  337. open: false,
  338. // 查询参数
  339. queryParams: {
  340. pageNum: 1,
  341. pageSize: 10,
  342. taskName: null,
  343. algorithmId: null,
  344. status: null,
  345. startTime: null,
  346. endTime: null,
  347. remark: null,
  348. },
  349. // 表单参数
  350. form: {},
  351. // 表单校验
  352. rules: {},
  353. configOptions: [],
  354. resultDetails: {},
  355. detailsOpen: false,
  356. jsonResult: {},
  357. selectFileName: "",
  358. showParamsDialog: false,
  359. // 日志查看器
  360. logDialogVisible: false,
  361. currentLogUrl: "",
  362. dialogTitle: "",
  363. };
  364. },
  365. created() {
  366. this.getList();
  367. this.getOptions();
  368. },
  369. activated() {
  370. this.getList();
  371. this.getOptions();
  372. },
  373. methods: {
  374. /** 查询分类测试列表 */
  375. getList() {
  376. this.loading = true;
  377. listTest(this.queryParams).then((response) => {
  378. this.testList = response.rows;
  379. this.total = response.total;
  380. this.loading = false;
  381. });
  382. },
  383. // 取消按钮
  384. cancel() {
  385. this.open = false;
  386. this.reset();
  387. },
  388. // 表单重置
  389. reset() {
  390. this.form = {
  391. id: null,
  392. taskName: null,
  393. algorithmId: null,
  394. inputPath: null,
  395. outputPath: null,
  396. algorithmParams: null,
  397. status: null,
  398. startTime: null,
  399. endTime: null,
  400. remark: null,
  401. createBy: null,
  402. createTime: null,
  403. updateBy: null,
  404. updateTime: null,
  405. };
  406. this.resetForm("form");
  407. },
  408. /** 搜索按钮操作 */
  409. handleQuery() {
  410. this.queryParams.pageNum = 1;
  411. this.getList();
  412. },
  413. /** 重置按钮操作 */
  414. resetQuery() {
  415. this.resetForm("queryForm");
  416. this.handleQuery();
  417. },
  418. // 多选框选中数据
  419. handleSelectionChange(selection) {
  420. this.ids = selection.map((item) => item.id);
  421. this.single = selection.length !== 1;
  422. this.multiple = !selection.length;
  423. },
  424. /** 新增按钮操作 */
  425. handleAdd() {
  426. this.reset();
  427. this.open = true;
  428. this.title = "添加分类测试";
  429. },
  430. /** 修改按钮操作 */
  431. handleUpdate(row) {
  432. this.reset();
  433. const id = row.id || this.ids;
  434. getTest(id).then((response) => {
  435. this.form = response.data;
  436. this.open = true;
  437. this.title = "修改分类测试";
  438. });
  439. },
  440. handleRun(row) {
  441. const id = row.id;
  442. run(id).then((response) => {
  443. alert("任务开始运行!");
  444. });
  445. },
  446. /** 提交按钮 */
  447. submitForm() {
  448. this.$refs["form"].validate((valid) => {
  449. if (valid) {
  450. if (this.form.id != null) {
  451. updateTest(this.form).then((response) => {
  452. this.$modal.msgSuccess("修改成功");
  453. this.open = false;
  454. this.getList();
  455. });
  456. } else {
  457. addTest(this.form).then((response) => {
  458. this.$modal.msgSuccess("新增成功");
  459. this.open = false;
  460. this.getList();
  461. });
  462. }
  463. }
  464. });
  465. },
  466. /** 删除按钮操作 */
  467. handleDelete(row) {
  468. const ids = row.id || this.ids;
  469. this.$modal
  470. .confirm('是否确认删除分类测试编号为"' + ids + '"的数据项?')
  471. .then(function () {
  472. return delTest(ids);
  473. })
  474. .then(() => {
  475. this.getList();
  476. this.$modal.msgSuccess("删除成功");
  477. })
  478. .catch(() => {});
  479. },
  480. /** 导出按钮操作 */
  481. handleExport() {
  482. this.download(
  483. "biz/test/export",
  484. {
  485. ...this.queryParams,
  486. },
  487. `test_${new Date().getTime()}.xlsx`
  488. );
  489. },
  490. getOptions() {
  491. getOptionsByType("5").then((response) => {
  492. this.configOptions = response.data;
  493. });
  494. },
  495. changeAlgorithmId() {
  496. const algorithmId = this.form.algorithmId;
  497. const config = this.configOptions.find((item) => item.id === algorithmId);
  498. if (config && config.params) {
  499. this.form.algorithmParams = config.params;
  500. } else {
  501. this.form.algorithmParams = "";
  502. }
  503. },
  504. handleGetResult(row) {
  505. this.resultDetails = {};
  506. this.selectFileName = "";
  507. const id = row.id;
  508. getResultDetails(id).then((response) => {
  509. this.resultDetails = response.data;
  510. this.detailsOpen = true;
  511. });
  512. },
  513. handleConfigSubmit(modifiedJson) {
  514. this.form.algorithmParams = modifiedJson;
  515. // 这里可以添加处理配置更新的逻辑
  516. console.log("更新后的配置:", JSON.parse(modifiedJson));
  517. },
  518. updateLogDiaLlogVisible(visiible) {
  519. console.log("updateLogDiaLlogVisible", visiible);
  520. this.logDialogVisible = visiible;
  521. },
  522. showLogViewer(row) {
  523. this.currentLogUrl = row.outputPath + "\\" + "log.log";
  524. this.dialogTitle = "日志";
  525. this.logDialogVisible = true;
  526. },
  527. openFolder(row) {
  528. try {
  529. shell.openPath(row.outputPath).then((result) => {
  530. if (result) {
  531. this.$message.error(`打开文件夹失败: ${result}`);
  532. }
  533. });
  534. } catch (error) {
  535. this.$message.error(`打开文件夹出错: ${error.message}`);
  536. }
  537. },
  538. },
  539. };
  540. </script>