index.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  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="type">
  5. <el-select v-model="queryParams.type" placeholder="请选择算法类型" clearable filterable @change=changeQueryType()>
  6. <el-option
  7. v-for="dict in dict.type.predict_type"
  8. :key="dict.value"
  9. :label="dict.label"
  10. :value="dict.value"
  11. />
  12. </el-select>
  13. </el-form-item>
  14. <el-form-item label="算法子类型" prop="subTypeId">
  15. <el-select
  16. v-model="queryParams.subTypeId"
  17. placeholder="请选择算法子类型"
  18. clearable
  19. filterable
  20. >
  21. <el-option
  22. v-for="item in algoTypeList"
  23. :key="item.id"
  24. :label="item.name"
  25. :value="item.id"
  26. >
  27. </el-option>
  28. </el-select>
  29. </el-form-item>
  30. <el-form-item label="名称" prop="name">
  31. <el-input
  32. v-model="queryParams.name"
  33. placeholder="请输入名称"
  34. clearable
  35. @keyup.enter.native="handleQuery"
  36. />
  37. </el-form-item>
  38. <!-- <el-form-item label="开始时间" prop="startTime">
  39. <el-date-picker clearable
  40. v-model="queryParams.startTime"
  41. type="date"
  42. value-format="yyyy-MM-dd"
  43. placeholder="请选择开始时间">
  44. </el-date-picker>
  45. </el-form-item>
  46. <el-form-item label="完成时间" prop="completedTime">
  47. <el-date-picker clearable
  48. v-model="queryParams.completedTime"
  49. type="date"
  50. value-format="yyyy-MM-dd"
  51. placeholder="请选择完成时间">
  52. </el-date-picker>
  53. </el-form-item>
  54. <el-form-item label="耗时(s)" prop="costSecond">
  55. <el-input
  56. v-model="queryParams.costSecond"
  57. placeholder="请输入耗时(s)"
  58. clearable
  59. @keyup.enter.native="handleQuery"
  60. />
  61. </el-form-item> -->
  62. <el-form-item>
  63. <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
  64. <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
  65. </el-form-item>
  66. </el-form>
  67. <el-row :gutter="10" class="mb8">
  68. <el-col :span="1.5">
  69. <el-button
  70. type="primary"
  71. plain
  72. icon="el-icon-plus"
  73. size="mini"
  74. @click="handleAdd"
  75. v-hasPermi="['algoManager:algorithm:add']"
  76. >新增</el-button>
  77. </el-col>
  78. <el-col :span="1.5">
  79. <el-button
  80. type="success"
  81. plain
  82. icon="el-icon-edit"
  83. size="mini"
  84. :disabled="single"
  85. @click="handleUpdate"
  86. v-hasPermi="['algoManager:algorithm:edit']"
  87. >修改</el-button>
  88. </el-col>
  89. <el-col :span="1.5">
  90. <el-button
  91. type="danger"
  92. plain
  93. icon="el-icon-delete"
  94. size="mini"
  95. :disabled="multiple"
  96. @click="handleDelete"
  97. v-hasPermi="['algoManager:algorithm:remove']"
  98. >删除</el-button>
  99. </el-col>
  100. <el-col :span="1.5">
  101. <el-button
  102. type="warning"
  103. plain
  104. icon="el-icon-download"
  105. size="mini"
  106. :disabled="single"
  107. @click="handleExport"
  108. v-hasPermi="['algoManager:algorithm:export']"
  109. >导出</el-button>
  110. </el-col>
  111. <el-col :span="1.5">
  112. <el-button
  113. type="success"
  114. plain
  115. icon="el-icon-mouse"
  116. size="mini"
  117. @click="handleRun"
  118. :disabled="single"
  119. v-hasPermi="['algoManager:algorithm:run']"
  120. >算法运行</el-button>
  121. </el-col>
  122. <right-toolbar :showSearch.sync="showSearch" @queryTable="getList()"></right-toolbar>
  123. </el-row>
  124. <el-table v-loading="loading" :data="algorithmList" @selection-change="handleSelectionChange">
  125. <el-table-column type="selection" width="55" align="center" />
  126. <el-table-column label="编号" align="center" prop="id" />
  127. <el-table-column label="算法类型" align="center" prop="type">
  128. <template slot-scope="scope">
  129. <dict-tag :options="dict.type.predict_type" :value="scope.row.type"/>
  130. </template>
  131. </el-table-column>
  132. <el-table-column label="算法子类型" align="center" prop="algoSubName" />
  133. <el-table-column label="名称" align="center" prop="name" />
  134. <el-table-column label="运行状态" align="center" prop="status">
  135. <template slot-scope="scope">
  136. <dict-tag :options="dict.type.algo_run_status" :value="scope.row.status"/>
  137. </template>
  138. </el-table-column>
  139. <el-table-column label="开始时间" align="center" prop="startTime" width="180">
  140. <template slot-scope="scope">
  141. <span>{{ parseTime(scope.row.startTime) }}</span>
  142. </template>
  143. </el-table-column>
  144. <el-table-column label="完成时间" align="center" prop="completedTime" width="180">
  145. <template slot-scope="scope">
  146. <span>{{ parseTime(scope.row.completedTime) }}</span>
  147. </template>
  148. </el-table-column>
  149. <el-table-column label="耗时(s)" align="center" prop="costSecond" />
  150. <el-table-column label="错误日志" align="center" prop="error" />
  151. <el-table-column label="备注" align="center" prop="remark" />
  152. <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
  153. <template slot-scope="scope">
  154. <el-button
  155. v-show="scope.row.status == 0"
  156. size="mini"
  157. type="text"
  158. icon="el-icon-edit"
  159. @click="handleUpdate(scope.row)"
  160. v-hasPermi="['algoManager:algorithm:edit']"
  161. >修改</el-button>
  162. <el-button
  163. v-show="scope.row.status == 2"
  164. size="mini"
  165. type="text"
  166. icon="el-icon-warning-outline"
  167. @click="viewResult(scope.row)"
  168. v-hasPermi="['algoManager:algorithm:edit']"
  169. >查看结果</el-button>
  170. <el-button
  171. size="mini"
  172. type="text"
  173. icon="el-icon-delete"
  174. @click="handleDelete(scope.row)"
  175. v-hasPermi="['algoManager:algorithm:remove']"
  176. >删除</el-button>
  177. </template>
  178. </el-table-column>
  179. </el-table>
  180. <pagination
  181. v-show="total>0"
  182. :total="total"
  183. :page.sync="queryParams.pageNum"
  184. :limit.sync="queryParams.pageSize"
  185. @pagination="getList"
  186. />
  187. <!-- 添加或修改算法对话框 -->
  188. <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
  189. <el-form ref="form" :model="form" :rules="rules" label-width="80px">
  190. <el-form-item label="算法类型" prop="type">
  191. <el-select v-model="form.type" placeholder="请选择算法类型" clearable filterable :disabled="form.status == 2" @change='changeFormType()'>
  192. <el-option
  193. v-for="dict in dict.type.predict_type"
  194. :key="dict.value"
  195. :label="dict.label"
  196. :value="dict.value"
  197. ></el-option>
  198. </el-select>
  199. </el-form-item>
  200. <el-form-item label="算法子类型" prop="subTypeId">
  201. <el-select
  202. v-model="form.subTypeId"
  203. placeholder="请选择算法子类型"
  204. clearable
  205. filterable
  206. :disabled="form.status == 2"
  207. @change='changeFormSubType()'
  208. >
  209. <el-option
  210. v-for="item in algoTypeList"
  211. :key="item.id"
  212. :label="item.name"
  213. :value="item.id"
  214. >
  215. </el-option>
  216. </el-select>
  217. </el-form-item>
  218. <template v-if="form.subTypeId">
  219. <el-form-item v-for="item in form.ioSubList" :label="item.name" :key="item.id">
  220. <!-- <file-upload v-model="form.path"/> -->
  221. <image-preview v-if="form.status == 2 && imageList.includes(item.path.split('.').pop())" :src="item.path" :width="50" :height="50"/>
  222. <template v-else-if="form.status == 2 && textList.includes(item.path.split('.').pop())">
  223. <div>
  224. <!-- 显示文件内容 -->
  225. <div class="file-content" v-show="fileContent">
  226. {{ fileContent }}
  227. </div>
  228. </div>
  229. </template>
  230. <el-select
  231. v-else
  232. v-model="item.uploadId"
  233. placeholder="请选择文件"
  234. clearable
  235. filterable
  236. :disabled="form.status == 2 || item.type == 2"
  237. >
  238. <el-option
  239. v-for="inputFile in inputFileList"
  240. :key="inputFile.id"
  241. :label="inputFile.name"
  242. :value="inputFile.id"
  243. >
  244. </el-option>
  245. </el-select>
  246. <template v-if="form.status == 2">
  247. <el-button
  248. size="mini"
  249. type="text"
  250. icon="el-icon-download"
  251. @click="download(item.path)"
  252. v-hasPermi="['data:model:edit']"
  253. >{{ "下载文件" }}
  254. </el-button>
  255. </template>
  256. </el-form-item>
  257. </template>
  258. <el-form-item label="名称" prop="name">
  259. <el-input v-model="form.name" placeholder="请输入名称" :disabled="form.status == 2"/>
  260. </el-form-item>
  261. <el-form-item label="备注" prop="remark">
  262. <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" :disabled="form.status == 2"/>
  263. </el-form-item>
  264. </el-form>
  265. <div slot="footer" class="dialog-footer">
  266. <el-button v-show="form.status != 2" type="primary" @click="submitForm">确 定</el-button>
  267. <el-button v-show="form.status != 2" @click="cancel">取 消</el-button>
  268. </div>
  269. </el-dialog>
  270. </div>
  271. </template>
  272. <script>
  273. import { listAlgorithm, getAlgorithmDto, delAlgorithm, addOrUpdateDto, runAlgorithms } from "@/api/algoManager/algorithm";
  274. import { getAlgoSubOption } from "@/api/algoManager/algorithm";
  275. import { getIoSubList } from "@/api/conf/field";
  276. import { getFileList, getInputFileList } from "@/api/algoManager/file";
  277. import axios from 'axios';
  278. import { isExternal } from "@/utils/validate";
  279. export default {
  280. name: "Algorithm",
  281. dicts: ['predict_type','algo_run_status'],
  282. data() {
  283. return {
  284. // 遮罩层
  285. loading: true,
  286. // 选中数组
  287. ids: [],
  288. // 非单个禁用
  289. single: true,
  290. // 非多个禁用
  291. multiple: true,
  292. // 显示搜索条件
  293. showSearch: true,
  294. // 总条数
  295. total: 0,
  296. // 算法表格数据
  297. algorithmList: [],
  298. predictList: [],
  299. // 算法子类列表
  300. algorithmSubList: [],
  301. // 算法特定类列表
  302. algoTypeList: [],
  303. // 已上传文件列表
  304. fileList: [],
  305. // 输入文件表格数据
  306. inputFileList: [],
  307. // 弹出层标题
  308. title: "",
  309. // 是否显示弹出层
  310. open: false,
  311. // 查询参数
  312. queryParams: {
  313. pageNum: 1,
  314. pageSize: 10,
  315. type: null,
  316. subTypeId: null,
  317. name: null,
  318. dictType: "predict_type",
  319. startTime: null,
  320. completedTime: null,
  321. costSecond: null,
  322. },
  323. // 表单参数
  324. form: {},
  325. // 表单校验
  326. rules: {
  327. subTypeId: [
  328. { required: true, message: "算法子类型不能为空", trigger: "blur" }
  329. ],
  330. },
  331. typeMap: new Map(),
  332. imageList: ["jpg", "jpeg", "png", "bmp", "gif"],
  333. textList: ["txt", "doc", "hlp", "wps"],
  334. fileContent: '',
  335. };
  336. },
  337. created() {
  338. this.getList();
  339. this.getAlgoSubOption();
  340. },
  341. activated() {
  342. this.getList();
  343. this.getAlgoSubOption();
  344. },
  345. methods: {
  346. /** 查询算法列表 */
  347. getList() {
  348. this.loading = true;
  349. listAlgorithm(this.queryParams).then(response => {
  350. this.algorithmList = response.rows;
  351. this.total = response.total;
  352. this.loading = false;
  353. });
  354. },
  355. getAlgoSubOption() {
  356. getAlgoSubOption().then((resp) => {
  357. this.algorithmSubList = resp.data;
  358. this.createTypeMap();
  359. });
  360. },
  361. // getFileList() {
  362. // getFileList().then((resp) => {
  363. // this.fileList = resp.data;
  364. // console.info(resp);
  365. // console.info(this);
  366. // });
  367. // },
  368. getInputFileList() {
  369. getInputFileList(this.form.subTypeId).then((resp) => {
  370. this.inputFileList = resp.data;
  371. console.info(resp);
  372. console.info(this);
  373. });
  374. },
  375. // 取消按钮
  376. cancel() {
  377. this.open = false;
  378. this.reset();
  379. },
  380. // 表单重置
  381. reset() {
  382. this.form = {
  383. id: null,
  384. type: null,
  385. subTypeId: null,
  386. name: null,
  387. startTime: null,
  388. completedTime: null,
  389. costSecond: null,
  390. createBy: null,
  391. createTime: null,
  392. updateBy: null,
  393. updateTime: null,
  394. remark: null,
  395. // 具体算法输入输出文件列表
  396. ioSubList: []
  397. };
  398. this.resetForm("form");
  399. },
  400. /** 搜索按钮操作 */
  401. handleQuery() {
  402. this.queryParams.pageNum = 1;
  403. this.getList();
  404. },
  405. /** 重置按钮操作 */
  406. resetQuery() {
  407. this.resetForm("queryForm");
  408. this.handleQuery();
  409. },
  410. // 多选框选中数据
  411. handleSelectionChange(selection) {
  412. this.ids = selection.map(item => item.id)
  413. this.single = selection.length!==1
  414. this.multiple = !selection.length
  415. },
  416. /** 新增按钮操作 */
  417. handleAdd() {
  418. this.reset();
  419. this.open = true;
  420. this.title = "添加算法";
  421. },
  422. /** 修改按钮操作 */
  423. handleUpdate(row) {
  424. this.reset();
  425. const id = row.id || this.ids
  426. getAlgorithmDto(id).then(response => {
  427. this.form = response.data;
  428. this.open = true;
  429. this.title = "修改算法";
  430. this.algoTypeList = this.typeMap.get(this.form.type);
  431. });
  432. console.info(this);
  433. },
  434. /** 查看结果按钮操作 */
  435. viewResult(row) {
  436. this.reset();
  437. const id = row.id || this.ids
  438. // getAlgorithmDto(id).then(response => {
  439. // this.form = response.data;
  440. // this.open = true;
  441. // this.title = "查看结果";
  442. // this.algoTypeList = this.typeMap.get(this.form.type);
  443. // this.fetchFileContent(this.form.ioSubList);
  444. // });
  445. // console.info(this);
  446. this.$router.push({
  447. name: 'Result3',
  448. params: {
  449. resultID: id,
  450. },
  451. })
  452. },
  453. /** 提交按钮 */
  454. submitForm() {
  455. this.$refs["form"].validate(valid => {
  456. if (valid) {
  457. addOrUpdateDto(this.form).then(response => {
  458. this.$modal.msgSuccess("成功");
  459. this.open = false;
  460. this.getList();
  461. });
  462. }
  463. });
  464. },
  465. /** 删除按钮操作 */
  466. handleDelete(row) {
  467. const ids = row.id || this.ids;
  468. this.$modal.confirm('是否确认删除算法编号为"' + ids + '"的数据项?').then(function() {
  469. return delAlgorithm(ids);
  470. }).then(() => {
  471. this.getList();
  472. this.$modal.msgSuccess("删除成功");
  473. }).catch(() => {});
  474. },
  475. /** 导出按钮操作 */
  476. handleExport() {
  477. this.download('algoManager/algorithm/export', {
  478. ...this.queryParams
  479. }, `algorithm_${new Date().getTime()}.xlsx`)
  480. },
  481. /** 运行算法按钮操作 */
  482. handleRun(row) {
  483. const id = row.id || this.ids
  484. // debugger
  485. this.$router.push({
  486. path:`/algoManager/algoRun3/${id}`,
  487. })
  488. },
  489. createTypeMap() {
  490. this.typeMap = new Map();
  491. for (const algorithmSub of this.algorithmSubList) {
  492. if(this.typeMap.has(algorithmSub.type)) {
  493. this.typeMap.get(algorithmSub.type).push({
  494. id: algorithmSub.id,
  495. name: algorithmSub.name
  496. });
  497. }
  498. else {
  499. this.typeMap.set(algorithmSub.type, [{
  500. id: algorithmSub.id,
  501. name: algorithmSub.name
  502. }]);
  503. }
  504. }
  505. },
  506. changeQueryType() {
  507. this.queryParams.subTypeId = null;
  508. this.algoTypeList = this.typeMap.get(this.queryParams.type);
  509. },
  510. changeFormType() {
  511. this.form.subTypeId = null;
  512. this.algoTypeList = this.typeMap.get(this.form.type);
  513. },
  514. changeFormSubType() {
  515. if(this.form.subTypeId) {
  516. getIoSubList(this.form.subTypeId, this.form.id).then((resp) => {
  517. this.form.ioSubList = resp.data;
  518. console.info(resp);
  519. });
  520. this.getInputFileList();
  521. }
  522. else {
  523. this.inputFileList = [];
  524. }
  525. },
  526. download(path) {
  527. this.$download.resource(path);
  528. },
  529. // 拿到文本文件里的内容
  530. async fetchFileContent(ioSubList) {
  531. try {
  532. let filePath;
  533. for (let item of ioSubList) {
  534. if (this.textList.includes(item.path.split('.').pop())) {
  535. filePath = item.path;
  536. }
  537. }
  538. if (filePath) {
  539. const response = await axios.get(this.realSrc(filePath), { responseType: 'text' });
  540. this.fileContent = response.data;
  541. }
  542. // const response = await axios.get(this.realSrc(filePath), { responseType: 'text' });
  543. // this.fileContent = response.data;
  544. } catch (error) {
  545. console.error("Error fetching the file:", error);
  546. }
  547. },
  548. // 通过path得到绝对路径
  549. realSrc(src) {
  550. if (!src) {
  551. return;
  552. }
  553. let real_src = src.split(",")[0];
  554. if (isExternal(real_src)) {
  555. return real_src;
  556. }
  557. return process.env.VUE_APP_BASE_API + real_src;
  558. },
  559. }
  560. };
  561. </script>