index.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796
  1. <template>
  2. <div>
  3. <seek-page
  4. :seekList="seekList"
  5. @search="search"
  6. ref="search"
  7. :keyValue="'qms-inspectionWork-index-search'"
  8. ></seek-page>
  9. <ele-pro-table
  10. ref="table"
  11. :columns="columns"
  12. :datasource="datasource"
  13. :pageSize="20"
  14. :pageSizes="[20, 30, 40, 50, 100]"
  15. full-height="calc(100vh - 140px)"
  16. height="calc(100vh - 380px)"
  17. @columns-change="handleColumnChange"
  18. :cache-key="cacheKeyUrl"
  19. row-key="id"
  20. @selection-change="selectionChangeHandle"
  21. >
  22. <!-- 表头工具栏 -->
  23. <template v-slot:toolbar>
  24. <!-- <el-button
  25. v-if="$hasPermission('qms:quality_work_order:close')"
  26. size="small"
  27. type="primary"
  28. class="ele-btn-icon"
  29. @click="batchClose"
  30. :disabled="selection.length === 0"
  31. >
  32. 批量关闭
  33. </el-button> -->
  34. </template>
  35. <template v-slot:code="{ row }">
  36. <el-link type="primary" :underline="false" @click="openDetails(row)">{{
  37. row.code
  38. }}</el-link>
  39. </template>
  40. <template v-slot:sourceCode="{ row }">
  41. <div>
  42. <el-link
  43. type="primary"
  44. :underline="false"
  45. @click="openWorkDetails(row)"
  46. >
  47. {{
  48. row.qualityPlanCode ? row.qualityPlanCode : row.workOrderCode
  49. }}</el-link
  50. >
  51. </div>
  52. </template>
  53. <template v-slot:files="scope">
  54. <el-link
  55. v-for="link in scope.row.files"
  56. :key="link.id"
  57. type="primary"
  58. :underline="false"
  59. @click="downloadFile(link)"
  60. >{{ link.name }}</el-link
  61. >
  62. </template>
  63. <template v-slot:qualityType="{ row }">{{
  64. getDictValue('质检计划类型', row.qualityType)
  65. }}</template>
  66. <template v-slot:qualityMode="{ row }">{{
  67. getDictValue('取样类型', row.qualityMode)
  68. }}</template>
  69. <template v-slot:accessory="scope">
  70. <el-link
  71. v-for="link in scope.row.accessory"
  72. :key="link.id"
  73. type="primary"
  74. :underline="false"
  75. @click="downloadFile(link)"
  76. >{{ link.name }}</el-link
  77. >
  78. </template>
  79. <!-- 操作列 -->
  80. <template v-slot:action="{ row }">
  81. <el-link
  82. v-if="row.status == 0"
  83. type="primary"
  84. :underline="false"
  85. @click="handelRouterTo(row)"
  86. >报工</el-link
  87. >
  88. </template>
  89. <template v-slot:templateList="{ row }">
  90. <div style="width: 250px; max-height: 60px; overflow: auto">
  91. <el-tag
  92. v-for="(item, index) in row.templateList"
  93. :key="item.inspectionName + index"
  94. :type="
  95. inspectionProjectStatus.find(
  96. (ProjectStatus) => ProjectStatus.value == item.status
  97. )?.type
  98. "
  99. effect="dark"
  100. style="margin-top: 4px"
  101. >
  102. <span
  103. :title="
  104. inspectionProjectStatus.find(
  105. (ProjectStatus) => ProjectStatus.value == item.status
  106. )?.label
  107. "
  108. >
  109. {{ item.inspectionName }}
  110. </span>
  111. </el-tag>
  112. </div>
  113. </template>
  114. </ele-pro-table>
  115. </div>
  116. </template>
  117. <script>
  118. import {
  119. getList,
  120. removeItem,
  121. getDetailById,
  122. closeWorkList,
  123. verificationQualityInspector,
  124. closeWork,
  125. sampleCollection,
  126. checkByQualityWorkOrderId,
  127. getQmsReportTemplatePageList
  128. } from '@/api/qms/inspectionWork/index.js';
  129. // import { queryTodo } from '@/api/bpm/task';
  130. import dictMixins from '@/mixins/dictMixins';
  131. import { getFile } from '@/api/system/file';
  132. import { parameterGetByCode } from '@/api/main/index.js';
  133. import tabMixins from '@/mixins/tableColumnsMixin';
  134. import { getCategoryByCode } from '@/api/main/index';
  135. import { inspectionProjectStatus } from '@/enum/dict.js';
  136. import { recordingMethodList } from '@/enum/dict.js';
  137. export default {
  138. name: 'InspectionWorkList',
  139. mixins: [dictMixins, tabMixins],
  140. components: {
  141. },
  142. props: {
  143. // 是否只显示我的工单
  144. myWork: {
  145. type: Boolean,
  146. default: false
  147. }
  148. },
  149. data() {
  150. return {
  151. inspectionProjectStatus,
  152. cacheKeyUrl: 'qsm-c2e9664a-inspectionWork',
  153. targetComponent: null,
  154. isView: false,
  155. targetVisible: false,
  156. currentRow: {},
  157. currentItem: {},
  158. columns: [
  159. {
  160. width: 45,
  161. type: 'selection',
  162. columnKey: 'selection',
  163. align: 'center',
  164. reserveSelection: true
  165. },
  166. {
  167. type: 'index',
  168. columnKey: 'index',
  169. align: 'center',
  170. label: '序号',
  171. width: 55,
  172. showOverflowTooltip: true,
  173. fixed: 'left'
  174. },
  175. {
  176. prop: 'code',
  177. label: '质检工单编码',
  178. slot: 'code',
  179. align: 'center',
  180. width: 180,
  181. showOverflowTooltip: true,
  182. fixed: 'left'
  183. },
  184. {
  185. prop: 'name',
  186. label: '质检工单名称',
  187. align: 'center',
  188. width: 120,
  189. showOverflowTooltip: true
  190. },
  191. {
  192. label: '来源单号',
  193. prop: 'sourceCode',
  194. // slot: 'sourceCode',
  195. align: 'center',
  196. width: 160,
  197. showOverflowTooltip: true
  198. },
  199. {
  200. label: '类型',
  201. prop: 'qualityType',
  202. slot: 'qualityType',
  203. align: 'center',
  204. width: 120,
  205. showOverflowTooltip: true
  206. },
  207. {
  208. label: '质检方式',
  209. prop: 'qualityMode',
  210. slot: 'qualityMode',
  211. align: 'center',
  212. width: 120,
  213. showOverflowTooltip: true
  214. },
  215. {
  216. prop: 'qualityName',
  217. label: '接收人',
  218. align: 'center',
  219. width: 120,
  220. showOverflowTooltip: true,
  221. formatter: (row) => {
  222. if (row.qualityName) {
  223. return row.qualityName;
  224. }
  225. return row.qualityNames || '';
  226. }
  227. },
  228. {
  229. prop: 'executeUserName',
  230. label: '执行人',
  231. align: 'center',
  232. width: 120,
  233. showOverflowTooltip: true,
  234. formatter: (row) => {
  235. return row.executeUserName || '';
  236. }
  237. },
  238. {
  239. prop: 'qualityTime',
  240. label: '质检时间',
  241. align: 'center',
  242. width: 120,
  243. showOverflowTooltip: true
  244. },
  245. {
  246. prop: 'productCode',
  247. width: 120,
  248. label: '编码',
  249. align: 'center',
  250. showOverflowTooltip: true
  251. },
  252. {
  253. prop: 'productName',
  254. width: 120,
  255. label: '名称',
  256. align: 'center',
  257. showOverflowTooltip: true
  258. },
  259. {
  260. prop: 'batchNo',
  261. label: '批次号',
  262. align: 'center',
  263. width: 120,
  264. showOverflowTooltip: true
  265. },
  266. {
  267. prop: 'inspectionTeamName',
  268. label: '送检班组',
  269. align: 'center',
  270. width: 120,
  271. showOverflowTooltip: true
  272. },
  273. {
  274. prop: 'createUserName',
  275. label: '送检人',
  276. align: 'center',
  277. width: 120,
  278. showOverflowTooltip: true
  279. },
  280. {
  281. prop: 'specification',
  282. label: '规格',
  283. align: 'center',
  284. showOverflowTooltip: true
  285. },
  286. {
  287. prop: 'brandNo',
  288. label: '牌号',
  289. align: 'center',
  290. showOverflowTooltip: true
  291. },
  292. {
  293. prop: 'colorKey',
  294. label: '颜色',
  295. align: 'center',
  296. showOverflowTooltip: true
  297. },
  298. {
  299. prop: 'produceTaskName',
  300. label: '工序',
  301. align: 'center',
  302. width: 120,
  303. showOverflowTooltip: true
  304. },
  305. {
  306. prop: 'total',
  307. label: '总数量',
  308. align: 'center',
  309. showOverflowTooltip: true
  310. },
  311. {
  312. prop: 'qualifiedNumber',
  313. label: '合格数',
  314. align: 'center',
  315. showOverflowTooltip: true
  316. },
  317. {
  318. prop: 'qualificationRate',
  319. label: '合格率',
  320. align: 'center',
  321. showOverflowTooltip: true
  322. },
  323. {
  324. prop: 'noQualifiedNumber',
  325. label: '不合格数',
  326. align: 'center',
  327. showOverflowTooltip: true
  328. },
  329. {
  330. prop: 'noQualificationRate',
  331. label: '不合格率',
  332. align: 'center',
  333. showOverflowTooltip: true
  334. },
  335. {
  336. prop: 'hours',
  337. label: '工时',
  338. align: 'center',
  339. showOverflowTooltip: true
  340. },
  341. {
  342. label: '附件',
  343. prop: 'accessory',
  344. align: 'center',
  345. slot: 'accessory',
  346. showOverflowTooltip: true
  347. },
  348. {
  349. label: '创建时间',
  350. prop: 'createTime',
  351. align: 'center',
  352. width: 160
  353. },
  354. {
  355. prop: 'recordingMethod',
  356. label: '记录方法',
  357. align: 'center',
  358. formatter: (row) => {
  359. return (
  360. recordingMethodList.find(
  361. (item) => item.value == row.recordingMethod
  362. )?.label || ''
  363. );
  364. },
  365. width: 130,
  366. showOverflowTooltip: true
  367. },
  368. {
  369. label: '进度',
  370. prop: 'templateList',
  371. slot: 'templateList',
  372. align: 'center',
  373. width: 250
  374. },
  375. {
  376. prop: 'status',
  377. label: '状态',
  378. align: 'center',
  379. width: 80,
  380. formatter: (row, column, cellValue) => {
  381. switch (cellValue) {
  382. case 0:
  383. return '未报工';
  384. case 1:
  385. return '已报工';
  386. case 2:
  387. return '已关闭';
  388. case 3:
  389. return '待请样';
  390. default:
  391. return '';
  392. }
  393. },
  394. fixed: 'right'
  395. },
  396. {
  397. columnKey: 'action',
  398. label: '操作',
  399. align: 'center',
  400. width: 200,
  401. resizable: false,
  402. slot: 'action',
  403. fixed: 'right'
  404. }
  405. ],
  406. formData: {
  407. certificateNumber: ''
  408. },
  409. processSubmitDialogFlag: false,
  410. rowData: {},
  411. statusList: [
  412. {
  413. value: 0,
  414. label: '未报工'
  415. },
  416. {
  417. value: 1,
  418. label: '已报工'
  419. },
  420. {
  421. value: 2,
  422. label: '已关闭'
  423. },
  424. {
  425. value: 3,
  426. label: '待请样'
  427. }
  428. ],
  429. addOpen: false,
  430. transferVisible: false,
  431. transferId: '',
  432. isReportApproval: 0,
  433. selection: [],
  434. reportTemplateList: [],
  435. templateArr: ['inspection_report1', 'ABBCCC']
  436. };
  437. },
  438. created() {
  439. this.requestDict('质检计划类型');
  440. this.requestDict('不良品处理类型');
  441. this.requestDict('取样类型');
  442. this.getCode();
  443. this.getReportTemplateList();
  444. },
  445. computed: {
  446. seekList() {
  447. return [
  448. {
  449. label: '工单编码:',
  450. value: 'code',
  451. type: 'input',
  452. placeholder: ''
  453. },
  454. {
  455. label: '工单名称:',
  456. value: 'name',
  457. type: 'input',
  458. placeholder: ''
  459. },
  460. {
  461. label: '来源单号:',
  462. value: 'sourceCode',
  463. type: 'input',
  464. placeholder: ''
  465. },
  466. {
  467. label: '类型:',
  468. value: 'qualityType',
  469. type: 'DictSelection',
  470. dictName: '质检计划类型',
  471. placeholder: ''
  472. },
  473. {
  474. label: '质检方式:',
  475. value: 'qualityMode',
  476. type: 'DictSelection',
  477. dictName: '取样类型',
  478. placeholder: ''
  479. },
  480. {
  481. label: '编码:',
  482. value: 'productCode',
  483. type: 'input',
  484. placeholder: ''
  485. },
  486. {
  487. label: '名称:',
  488. value: 'productName',
  489. type: 'input',
  490. placeholder: ''
  491. },
  492. {
  493. label: '质检人:',
  494. value: 'qualityName',
  495. type: 'input',
  496. placeholder: ''
  497. },
  498. // {
  499. // label: '状态:',
  500. // value: 'status',
  501. // type: 'select',
  502. // placeholder: '',
  503. // planList: this.statusList
  504. // },
  505. {
  506. label: '记录方法:',
  507. value: 'recordingMethod',
  508. type: 'select',
  509. placeholder: '',
  510. planList: recordingMethodList
  511. }
  512. ];
  513. },
  514. clientEnvironmentId() {
  515. return this.$store.state.user.info.clientEnvironmentId;
  516. }
  517. },
  518. methods: {
  519. async handelRouterTo(row) {
  520. // window.history.pushState(null, '', '/page-qms/inspectionWork?isWt=true&businessId=' + row.id);
  521. // // this.$router.push(path);
  522. // if (type == 'edit') {
  523. const code = await verificationQualityInspector(row.id);
  524. if (code == '-1') {
  525. return;
  526. }
  527. // }
  528. const id = row.id;
  529. const qualityType = row.qualityType;
  530. const qualityTimeStart = row.qualityTimeStart || '';
  531. window.history.pushState(null, '', '/page-qms/inspectionWork/edit?type=edit&id=' + id + '&qualityType=' + qualityType + '&qualityTimeStart=' + qualityTimeStart);
  532. // this.$router.push({
  533. // path: '/inspectionWork/edit',
  534. // query: {
  535. // type,
  536. // id,
  537. // qualityType,
  538. // qualityTimeStart
  539. // }
  540. // });
  541. },
  542. getReportTemplateList() {
  543. getQmsReportTemplatePageList({
  544. pageNum: 1,
  545. pageSize: 999,
  546. isEnabled: 1,
  547. type: 0
  548. })
  549. .then((res) => {
  550. this.reportTemplateList = res.list;
  551. console.log('reportTemplateList', this.reportTemplateList);
  552. })
  553. .catch((err) => {
  554. console.error('获取报表模板列表失败:', err);
  555. });
  556. },
  557. generateReportApproval(row, item) {
  558. this.targetComponent = item.code;
  559. this.isView = false;
  560. this.currentRow = row;
  561. this.currentItem = item;
  562. this.$nextTick(() => {
  563. this.targetVisible = true;
  564. console.log('targetVisible~~~~', this.targetVisible);
  565. });
  566. },
  567. async openReport(row) {
  568. const data = await getDetailById(row.id);
  569. this.targetComponent = row.reportTemplateCode;
  570. this.isView = true;
  571. this.currentRow = row;
  572. this.currentRow.reportApprovalTaskVos =
  573. data.data.reportApprovalTaskVos || {};
  574. this.$nextTick(() => {
  575. this.targetVisible = true;
  576. });
  577. },
  578. selectionChangeHandle(val) {
  579. this.selection = val;
  580. },
  581. async addSampleOpen(row) {
  582. const code = await verificationQualityInspector(row.id);
  583. if (code == '-1') {
  584. return;
  585. }
  586. const is = await checkByQualityWorkOrderId(row.id);
  587. if (is) {
  588. this.$message.warning('此工单存在未处理完的请样记录,请检查!');
  589. return;
  590. }
  591. this.$refs.addSampleRef.open('add', row);
  592. },
  593. async sampleCollection(row) {
  594. const code = await verificationQualityInspector(row.id);
  595. if (code == '-1') {
  596. return;
  597. }
  598. sampleCollection({ id: row.id }).then((res) => {
  599. this.$message.success('收样成功');
  600. this.search();
  601. });
  602. },
  603. batchClose() {
  604. const validRows = this.selection.filter(
  605. (row) => row.status === 0 && row.qualityType === 2
  606. );
  607. if (validRows.length === 0) {
  608. this.$message.warning('所选工单中没有可关闭的工单');
  609. return;
  610. }
  611. this.$confirm(`确定关闭选中的 ${validRows.length} 个工单吗?`, '提示', {
  612. confirmButtonText: '确定',
  613. cancelButtonText: '取消',
  614. type: 'warning'
  615. }).then(async () => {
  616. try {
  617. await closeWorkList(validRows.map((row) => row.id));
  618. this.$refs.table.clearSelection();
  619. this.search();
  620. } catch (err) {
  621. this.$message.error('批量关闭失败:' + (err.message || '操作异常'));
  622. }
  623. });
  624. },
  625. reportApprovalSubmit(res) {
  626. this.processSubmitDialogFlag = true;
  627. this.$nextTick(async () => {
  628. let params = {
  629. businessId: res.id,
  630. businessKey: 'qms_report_approval',
  631. formCreateUserId: res.createUserId,
  632. variables: {
  633. businessCode: res.code,
  634. businessName: res.name,
  635. businessType: '质检报告单'
  636. }
  637. };
  638. if (this.clientEnvironmentId == 5) {
  639. const data = await getCategoryByCode(res.productCode);
  640. if (data && data.categoryLevelCodePath?.includes('W3-209')) {
  641. params.businessKey = 'qms_report_approval1';
  642. } else {
  643. params.businessKey = 'qms_report_approval';
  644. }
  645. }
  646. this.$refs.processSubmitDialogRef.init(params);
  647. });
  648. },
  649. getCode() {
  650. parameterGetByCode({
  651. code: 'qms_report_approval'
  652. }).then((res) => {
  653. this.isReportApproval = res.value;
  654. });
  655. },
  656. async qualityInspectionSend(row, type) {
  657. const code = await verificationQualityInspector(row.id);
  658. if (code == '-1') {
  659. return;
  660. }
  661. this.$refs.inspectionProjectTaskSendRef.open(row, type);
  662. },
  663. async datasource({ page, where, limit }) {
  664. // try {
  665. // await queryTodo({});
  666. // } catch (err) {
  667. // console.error('调用queryTodo失败:', err);
  668. // }
  669. // if (this.myWork) {
  670. where.currentLoginUserId = this.$store.state.user.info.userId;
  671. where.status = 0;
  672. // }
  673. return getList({
  674. ...where,
  675. pageNum: page,
  676. size: limit
  677. });
  678. },
  679. search(where) {
  680. this.$refs.table.reload({
  681. where: where
  682. });
  683. },
  684. isEmptyObject(obj) {
  685. return Object.keys(obj).length === 0;
  686. },
  687. async openEdit(type, row) {
  688. // const menusList = this.$store.state.user.menus;
  689. if (type == 'edit') {
  690. const code = await verificationQualityInspector(row.id);
  691. if (code == '-1') {
  692. return;
  693. }
  694. }
  695. const id = type !== 'add' ? row.id : '';
  696. const qualityType = type !== 'add' ? row.qualityType : null;
  697. const qualityTimeStart = row.qualityTimeStart || '';
  698. this.$router.push({
  699. path: '/inspectionWork/edit',
  700. query: {
  701. type,
  702. id,
  703. qualityType,
  704. qualityTimeStart
  705. }
  706. });
  707. // for (const item of menusList) {
  708. // if (item.children) {
  709. // for (const item2 of item.children) {
  710. // if (item2.path === '/inspectionWork/edit') {
  711. // found = true;
  712. // return;
  713. // }
  714. // }
  715. // }
  716. // }
  717. // if (!found) {
  718. // this.$message.error('请到角色管理配置菜单权限!');
  719. // }
  720. },
  721. openDetails(row) {
  722. let id = row.id;
  723. window.history.pushState(null, '', '/inspectionWork/details?id=' + id + '&path=' + '/inspectionWork' + '&name=工单');
  724. // this.$router.push({
  725. // path: '/inspectionWork/details',
  726. // query: { id, path: '/inspectionWork', name: '工单' }
  727. // });
  728. },
  729. openWorkDetails(row) {
  730. if (row.qualityPlanCode) {
  731. } else {
  732. this.$refs.mesWorkOrderRef.open(row);
  733. }
  734. },
  735. downloadFile(file) {
  736. getFile({ objectName: file.storePath }, file.name);
  737. },
  738. remove(row) {
  739. removeItem([row.id])
  740. .then((message) => {
  741. this.$message.success(message);
  742. this.done();
  743. })
  744. .catch((e) => {});
  745. },
  746. done() {
  747. this.$refs.search.search();
  748. },
  749. openNumber(row) {
  750. this.formData.certificateNumber = row.certificateNumber;
  751. this.rowData = row;
  752. this.addOpen = true;
  753. },
  754. closeModel() {
  755. this.addOpen = false;
  756. },
  757. async close(row) {
  758. const code = await verificationQualityInspector(row.id);
  759. if (code == '-1') {
  760. return;
  761. }
  762. await closeWork(row);
  763. this.done();
  764. },
  765. async openTransfer(id) {
  766. const code = await verificationQualityInspector(id);
  767. if (code == '-1') {
  768. return;
  769. }
  770. this.transferVisible = true;
  771. this.transferId = id;
  772. },
  773. transferConfirm(id) {
  774. this.transferVisible = false;
  775. this.$message.success('转派成功');
  776. this.done();
  777. }
  778. }
  779. };
  780. </script>