checkDetails.vue 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004
  1. <template>
  2. <ele-modal
  3. :title="title"
  4. :visible.sync="visible"
  5. v-if="visible"
  6. :close-on-click-modal="false"
  7. @close="handleClose"
  8. resizable
  9. maxable
  10. width="80%"
  11. append-to-body
  12. >
  13. <div
  14. v-if="(type == 'detail' || type == 'edit') && form.processInstanceId"
  15. class="switch"
  16. :maxable="true"
  17. style="margin-bottom: 20px"
  18. >
  19. <div class="switch_left">
  20. <ul>
  21. <li
  22. v-for="item in tabOptions"
  23. :key="item.key"
  24. :class="{ active: activeComp == item.key }"
  25. @click="activeComp = item.key"
  26. >
  27. {{ item.name }}
  28. </li>
  29. </ul>
  30. </div>
  31. </div>
  32. <bpmDetail
  33. v-if="activeComp == 'bpm' && form && form.processInstanceId"
  34. :id="form.processInstanceId"
  35. >
  36. </bpmDetail>
  37. <el-form
  38. v-if="activeComp == 'main'"
  39. ref="formRef"
  40. :model="form"
  41. :rules="rules"
  42. label-width="100px"
  43. :disabled="type == 'detail'"
  44. >
  45. <header-title title="基本信息"></header-title>
  46. <el-row :gutter="10">
  47. <el-col :span="8">
  48. <el-form-item label="放行单编码">
  49. <el-input
  50. v-model="form.code"
  51. placeholder="系统自动生成"
  52. disabled
  53. ></el-input>
  54. </el-form-item>
  55. </el-col>
  56. <el-col :span="8">
  57. <el-form-item label="放行单名称" prop="name">
  58. <el-input v-model="form.name" placeholder="请输入"></el-input>
  59. </el-form-item>
  60. </el-col>
  61. </el-row>
  62. <header-title title="物品清单">
  63. <el-button type="primary" icon="el-icon-plus" @click="openAddModel">
  64. 添加
  65. </el-button>
  66. </header-title>
  67. <ele-pro-table
  68. ref="table"
  69. row-key="userId"
  70. :columns="ordersColumns"
  71. :datasource="form.orders"
  72. >
  73. <template v-slot:action="{ row }">
  74. <el-link
  75. icon="el-icon-view"
  76. type="primary"
  77. :underline="false"
  78. @click="openWorkOrderDetail(row)"
  79. >详情</el-link
  80. >
  81. <el-link
  82. v-if="type != 'detail'"
  83. icon="el-icon-delete"
  84. type="danger"
  85. :underline="false"
  86. @click="deleteRow(row)"
  87. >删除</el-link
  88. >
  89. </template>
  90. </ele-pro-table>
  91. <el-button
  92. type="primary"
  93. style="margin-bottom: 15px"
  94. @click="getKitCheck"
  95. :loading="butLoading"
  96. >
  97. 规则齐套检查
  98. </el-button>
  99. <header-title title="生产放行规则"> </header-title>
  100. <ele-pro-table
  101. ref="scTable"
  102. row-key="id"
  103. :columns="detailsColumns"
  104. :datasource="scDetails"
  105. >
  106. <template v-slot:isPass="{ row }">
  107. <el-radio-group v-model="row.isPass">
  108. <el-radio :label="1">是</el-radio>
  109. <el-radio :label="0">否</el-radio>
  110. </el-radio-group>
  111. </template>
  112. <template v-slot:remark="{ row }">
  113. <el-input
  114. type="textarea"
  115. v-model="row.remark"
  116. :placeholder="row.isPass === 0 ? '审核不通过,请输入备注(必填)' : '请输入备注'"
  117. :rows="1"
  118. :class="{ 'remark-error': row.isPass === 0 && !row.remark }"
  119. ></el-input>
  120. </template>
  121. </ele-pro-table>
  122. <table
  123. class="detail-table"
  124. key="first-table"
  125. style="width: 500px; margin: 15px 0"
  126. >
  127. <tr>
  128. <td>结论</td>
  129. <td>
  130. <el-radio-group v-model="form.workConclution">
  131. <el-radio :label="0">不符合规定</el-radio>
  132. <el-radio :label="1">符合规定</el-radio>
  133. </el-radio-group>
  134. </td>
  135. </tr>
  136. <tr>
  137. <td>验收人</td>
  138. <td @click="openSelectUser(0)">
  139. <div class="mask-box">
  140. <el-input
  141. v-model="form.workCheckUserName"
  142. placeholder="请输选择验收人"
  143. readonly
  144. ></el-input>
  145. </div>
  146. </td>
  147. </tr>
  148. <tr>
  149. <td>验收时间</td>
  150. <td>
  151. <el-date-picker
  152. v-model="form.workCheckTime"
  153. type="datetime"
  154. placeholder="选择日期时间"
  155. style="width: 100%"
  156. value-format="yyyy-MM-dd HH:mm:ss"
  157. ></el-date-picker>
  158. </td>
  159. </tr>
  160. </table>
  161. <header-title title="质检放行规则"></header-title>
  162. <ele-pro-table
  163. ref="zjTable"
  164. row-key="id"
  165. :columns="detailsColumns"
  166. :datasource="zjDetails"
  167. >
  168. <template v-slot:isPass="{ row }">
  169. <el-radio-group v-model="row.isPass">
  170. <el-radio :label="1">是</el-radio>
  171. <el-radio :label="0">否</el-radio>
  172. </el-radio-group>
  173. </template>
  174. <template v-slot:remark="{ row }">
  175. <el-input
  176. type="textarea"
  177. v-model="row.remark"
  178. :placeholder="row.isPass === 0 ? '审核不通过,请输入备注(必填)' : '请输入备注'"
  179. :rows="1"
  180. :class="{ 'remark-error': row.isPass === 0 && !row.remark }"
  181. ></el-input>
  182. </template>
  183. </ele-pro-table>
  184. <table
  185. class="detail-table"
  186. key="tow"
  187. style="width: 500px; margin: 15px 0"
  188. >
  189. <tr>
  190. <td>结论</td>
  191. <td>
  192. <el-radio-group v-model="form.qualityConclution">
  193. <el-radio :label="0">不符合规定</el-radio>
  194. <el-radio :label="1">符合规定</el-radio>
  195. </el-radio-group>
  196. </td>
  197. </tr>
  198. <tr>
  199. <td>验收人</td>
  200. <td>
  201. <div class="mask-box" @click="openSelectUser(1)">
  202. <el-input
  203. v-model="form.qualityCheckUserName"
  204. placeholder="请输选择验收人"
  205. readonly
  206. ></el-input>
  207. </div>
  208. </td>
  209. </tr>
  210. <tr>
  211. <td>验收时间</td>
  212. <td>
  213. <el-date-picker
  214. v-model="form.qualityCheckTime"
  215. type="datetime"
  216. placeholder="选择日期时间"
  217. style="width: 100%"
  218. value-format="yyyy-MM-dd HH:mm:ss"
  219. ></el-date-picker>
  220. </td>
  221. </tr>
  222. </table>
  223. <!-- 选择生产工单 -->
  224. <selectWorkOrder
  225. ref="selectWorkOrderRef"
  226. :where="workOrderWhere"
  227. :autoClose="false"
  228. @confirm="selectWorkOrderConfirm"
  229. ></selectWorkOrder>
  230. <!-- 选择用户 -->
  231. <SelectUser
  232. ref="SelectUserRef"
  233. v-model="showSelectUser"
  234. @selectUserFinished="selectUserFinished"
  235. ></SelectUser>
  236. </el-form>
  237. <template v-slot:footer>
  238. <el-button
  239. v-if="type != 'detail' && !form.approvalStatus"
  240. type="primary"
  241. @click="submit('submit')"
  242. :loading="butLoading"
  243. >保存并提交</el-button
  244. >
  245. <el-button
  246. v-if="type != 'detail' && !form.approvalStatus"
  247. type="primary"
  248. @click="submit('save')"
  249. :loading="butLoading"
  250. >保存</el-button
  251. >
  252. <el-button @click="handleClose">取 消</el-button>
  253. </template>
  254. <detailsPop ref="detailsRef"> </detailsPop>
  255. <process-submit-dialog
  256. :processSubmitDialogFlag.sync="processSubmitDialogFlag"
  257. v-if="processSubmitDialogFlag"
  258. ref="processSubmitDialogRef"
  259. :isNotNeedProcess="false"
  260. ></process-submit-dialog>
  261. </ele-modal>
  262. </template>
  263. <script>
  264. import dictMixins from '@/mixins/dictMixins';
  265. import selectWorkOrder from './selectWorkOrder.vue';
  266. import { checklisttemplateGetById } from '@/api/checklisttemplate/index';
  267. import SelectUser from '@/components/select/SelectUser/index.vue';
  268. import {
  269. checklistrecordSave,
  270. checklistrecordGetById,
  271. checklistrecordUpdate,
  272. checklistrecordKitCheck
  273. } from '@/api/checklistrecord/index';
  274. import bpmTask from '@/components/bpmTask/bpmTask.vue';
  275. import bpmDetail from '@/views/bpm/processInstance/detail.vue';
  276. import detailsPop from '@/views/produceOrder/components/details/index.vue';
  277. import { getById as getworkOrderById } from '@/api/produceOrder/index';
  278. import processSubmitDialog from '@/components/processSubmitDialog/processSubmitDialog.vue';
  279. export default {
  280. mixins: [dictMixins],
  281. components: {
  282. selectWorkOrder,
  283. SelectUser,
  284. bpmTask,
  285. bpmDetail,
  286. detailsPop,
  287. processSubmitDialog
  288. },
  289. props: {
  290. // 保存是否关闭弹窗
  291. saveClose: {
  292. type: Boolean,
  293. default: false
  294. }
  295. },
  296. data() {
  297. const formBaseData = {
  298. id: null,
  299. approvalStatus: null,
  300. checklistType: 0,
  301. code: '',
  302. createUserName: '',
  303. details: [],
  304. name: '',
  305. orders: [],
  306. processInstanceId: '',
  307. qualityCheckTime: '',
  308. qualityCheckUserId: null,
  309. qualityCheckUserName: '',
  310. qualityConclution: null,
  311. templateId: 0,
  312. templateName: '',
  313. workCheckTime: '',
  314. workCheckUserId: null,
  315. workCheckUserName: '',
  316. workConclution: null
  317. };
  318. return {
  319. visible: false,
  320. title: '放行申请单',
  321. formBaseData,
  322. form: JSON.parse(JSON.stringify(formBaseData)),
  323. rules: {
  324. name: [
  325. { required: true, message: '请输入放行单名称', trigger: 'blur' },
  326. { required: true, message: '请输入放行单名称', trigger: 'change' }
  327. ]
  328. },
  329. // 类型 add / edit / detail
  330. type: '',
  331. // 生产工单查询条件
  332. workOrderWhere: {
  333. statusList: ['6'],
  334. queryTermination: 0
  335. },
  336. loading: false,
  337. butLoading: false,
  338. tabOptions: [
  339. { key: 'main', name: '放行单详情' },
  340. { key: 'bpm', name: '流程详情' }
  341. ],
  342. // 当前选项
  343. activeComp: 'main',
  344. showSelectUser: false,
  345. // 0 生产验收人 1 质检验收人
  346. selectUserType: 0,
  347. processSubmitDialogFlag: false
  348. };
  349. },
  350. watch: {
  351. 'form.details': {
  352. handler(details) {
  353. console.log('details', details);
  354. // 区分生产放行规则 质检放行规则
  355. // 根据 审核结果修改 结论
  356. const scDetails = details.filter((item) => item.checkType == 1);
  357. const zjDetails = details.filter((item) => item.checkType == 2);
  358. // 当workConclution全为1 则为1 否则为0
  359. if (scDetails.length > 0) {
  360. const allPass = scDetails
  361. .map((item) => item.isPass)
  362. .every((val) => val === 1);
  363. this.form.workConclution = allPass ? 1 : 0;
  364. } else {
  365. this.form.workConclution = null;
  366. }
  367. if (zjDetails.length > 0) {
  368. const allPass = zjDetails
  369. .map((item) => item.isPass)
  370. .every((val) => val == 1);
  371. this.form.qualityConclution = allPass ? 1 : 0;
  372. } else {
  373. this.form.qualityConclution = null;
  374. }
  375. },
  376. deep: true
  377. },
  378. processSubmitDialogFlag(val) {
  379. if (!val) {
  380. // 关闭后 刷新详情
  381. if (this.form.id) {
  382. this.$emit('reload');
  383. this.$nextTick(() => {
  384. this.handleClose();
  385. });
  386. }
  387. }
  388. }
  389. },
  390. computed: {
  391. ordersColumns() {
  392. return [
  393. {
  394. width: 55,
  395. type: 'index',
  396. columnKey: 'index',
  397. label: '序号',
  398. align: 'center'
  399. },
  400. {
  401. prop: 'batchNo',
  402. label: '批次号',
  403. align: 'center',
  404. minWidth: 110,
  405. showOverflowTooltip: true
  406. },
  407. {
  408. prop: 'productCode',
  409. label: '产品编码',
  410. align: 'center',
  411. minWidth: 110,
  412. showOverflowTooltip: true
  413. },
  414. {
  415. prop: 'productName',
  416. label: '产品名称',
  417. align: 'center',
  418. minWidth: 110,
  419. showOverflowTooltip: true
  420. },
  421. {
  422. prop: 'workOrderCode',
  423. label: '生产工单号',
  424. align: 'center',
  425. minWidth: 110,
  426. showOverflowTooltip: true
  427. },
  428. {
  429. prop: 'formingNum',
  430. label: '要求生产数量',
  431. align: 'center',
  432. minWidth: 110,
  433. showOverflowTooltip: true
  434. },
  435. {
  436. prop: 'formedNum',
  437. label: '实际生产数量',
  438. align: 'center',
  439. minWidth: 110,
  440. showOverflowTooltip: true
  441. },
  442. {
  443. prop: 'specification',
  444. label: '规格',
  445. align: 'center',
  446. minWidth: 110,
  447. showOverflowTooltip: true
  448. },
  449. {
  450. prop: 'productModel',
  451. label: '型号',
  452. align: 'center',
  453. minWidth: 110,
  454. showOverflowTooltip: true
  455. },
  456. {
  457. label: '操作',
  458. columnKey: 'action',
  459. slot: 'action',
  460. minWidth: 120
  461. }
  462. ];
  463. },
  464. // 生产放行规则
  465. scDetails() {
  466. return this.form.details.filter((item) => item.checkType == 1);
  467. },
  468. // 质检放行规则
  469. zjDetails() {
  470. return this.form.details.filter((item) => item.checkType == 2);
  471. },
  472. detailsColumns() {
  473. return [
  474. {
  475. width: 55,
  476. type: 'index',
  477. columnKey: 'index',
  478. label: '序号',
  479. align: 'center'
  480. },
  481. {
  482. prop: 'mainIndicatorName',
  483. label: '指标名称',
  484. align: 'center',
  485. minWidth: 110,
  486. showOverflowTooltip: true
  487. },
  488. {
  489. prop: 'isPass',
  490. label: '审核结果',
  491. align: 'center',
  492. slot: 'isPass',
  493. minWidth: 110,
  494. showOverflowTooltip: true
  495. },
  496. {
  497. prop: 'remark',
  498. label: '备注',
  499. align: 'center',
  500. slot: 'remark',
  501. minWidth: 110,
  502. showOverflowTooltip: true
  503. }
  504. ];
  505. }
  506. },
  507. methods: {
  508. // 外部调用,打开弹窗
  509. open(type, data) {
  510. console.log('data , type', data, type);
  511. this.type = type;
  512. if (type == 'add') {
  513. this.title = '放行申请单';
  514. // 生产放心单名称 = 模版名称+年月日+3位数
  515. this.form.name = `${data.templateName}${new Date()
  516. .toLocaleDateString()
  517. .replace(/\//g, '')}${String(
  518. Math.floor(Math.random() * 1000)
  519. ).padStart(3, '0')}`;
  520. this.form.templateId = data.templateId;
  521. this.form.templateName = data.templateName;
  522. this.form.checklistType = data.checklistType;
  523. // 处理携带的生产工单
  524. if (data.workOrderList && data.workOrderList.length) {
  525. this.selectWorkOrderConfirm(data.workOrderList);
  526. }
  527. // 根据模版id 查询模版详情
  528. this.getTemplateDetails(data.templateId);
  529. } else if (type == 'edit') {
  530. this.title = '放行申请单';
  531. this.getCheckDetails(data.id);
  532. } else if (type == 'detail') {
  533. this.title = '放行单详情';
  534. this.getCheckDetails(data.id);
  535. } else {
  536. this.title = '审批';
  537. }
  538. this.visible = true;
  539. },
  540. // 关闭时清理表单
  541. handleClose() {
  542. this.form = JSON.parse(JSON.stringify(this.formBaseData));
  543. this.activeComp = 'main';
  544. this.$nextTick(() => {
  545. // 关闭流程里 visible 可能已变为 false(v-if 卸载整块内容),或当前在 BPM 页签时表单未挂载
  546. this.$refs.formRef?.clearValidate();
  547. this.visible = false;
  548. });
  549. },
  550. // 校验放行规则备注(isPass为否时备注必填)
  551. validateDetailsRemark() {
  552. const scNoRemarkItems = this.scDetails.filter(
  553. (item) => item.isPass === 0 && !item.remark
  554. );
  555. const zjNoRemarkItems = this.zjDetails.filter(
  556. (item) => item.isPass === 0 && !item.remark
  557. );
  558. if (scNoRemarkItems.length > 0) {
  559. const names = scNoRemarkItems
  560. .map((item) => item.mainIndicatorName)
  561. .join('、');
  562. this.$message.warning(
  563. `生产放行规则中【${names}】审核不通过,备注为必填项`
  564. );
  565. return false;
  566. }
  567. if (zjNoRemarkItems.length > 0) {
  568. const names = zjNoRemarkItems
  569. .map((item) => item.mainIndicatorName)
  570. .join('、');
  571. this.$message.warning(
  572. `质检放行规则中【${names}】审核不通过,备注为必填项`
  573. );
  574. return false;
  575. }
  576. return true;
  577. },
  578. // 提交
  579. // submit(type) {
  580. // console.log('this.form', this.form);
  581. // this.$refs.formRef.validate(async (valid, invalidFields) => {
  582. // if (valid) {
  583. // // 必须要有物品清单
  584. // if (this.form.orders.length == 0) {
  585. // this.$message.warning('请添加物品清单');
  586. // return;
  587. // }
  588. // this.butLoading = true;
  589. // try {
  590. // if (type == 'save') {
  591. // // 存在id 则更新
  592. // if (this.form.id) {
  593. // await checklistrecordUpdate(this.form);
  594. // this.$message.success('操作成功,已保存到放行单列表');
  595. // } else {
  596. // this.form.createUserName = this.$store.state.user.info.name;
  597. // const data = await checklistrecordSave(this.form);
  598. // this.$message.success('操作成功,已保存到放行单列表');
  599. // this.form.id = data;
  600. // this.getCheckDetails(this.form.id);
  601. // }
  602. // } else {
  603. // // submit 保存并提交审核
  604. // // 存在id 则更新
  605. // if (this.form.id) {
  606. // await checklistrecordUpdate(this.form);
  607. // } else {
  608. // this.form.createUserName = this.$store.state.user.info.name;
  609. // const data = await checklistrecordSave(this.form);
  610. // this.form.id = data;
  611. // await this.getCheckDetails(this.form.id);
  612. // }
  613. // this.openApproval();
  614. // }
  615. // this.butLoading = false;
  616. // this.$emit('reload');
  617. // } catch (error) {
  618. // this.butLoading = false;
  619. // }
  620. // } else {
  621. // // 转换为数组
  622. // const firstErrorField = Object.values(invalidFields);
  623. // if (firstErrorField.length > 0) {
  624. // this.$message.warning(firstErrorField[0][0].message);
  625. // }
  626. // return false;
  627. // }
  628. // });
  629. // },
  630. submit(type) {
  631. this.$refs.formRef.validate(async (valid, invalidFields) => {
  632. if (valid) {
  633. // 必须要有物品清单
  634. if (this.form.orders.length == 0) {
  635. this.$message.warning('请添加物品清单');
  636. return;
  637. }
  638. // 校验放行规则备注(isPass为否时备注必填)
  639. if (!this.validateDetailsRemark()) {
  640. return;
  641. }
  642. this.butLoading = true;
  643. const text = type == 'save' ? '保存中...' : '提交中...';
  644. const loading = this.$loading({
  645. lock: true,
  646. text,
  647. spinner: 'el-icon-loading',
  648. background: 'rgba(0, 0, 0, 0.7)'
  649. });
  650. try {
  651. if (type == 'save') {
  652. // 存在id 则更新
  653. if (this.form.id) {
  654. await checklistrecordUpdate(this.form);
  655. this.$message.success('操作成功,已保存到放行单列表');
  656. } else {
  657. this.form.createUserName = this.$store.state.user.info.name;
  658. const data = await checklistrecordSave(this.form);
  659. this.$message.success('操作成功,已保存到放行单列表');
  660. this.form.id = data;
  661. this.getCheckDetails(this.form.id);
  662. }
  663. } else {
  664. if (this.form.id) {
  665. await checklistrecordUpdate(this.form);
  666. } else {
  667. this.form.createUserName = this.$store.state.user.info.name;
  668. const data = await checklistrecordSave(this.form);
  669. this.form.id = data;
  670. await this.getCheckDetails(this.form.id);
  671. }
  672. this.openApproval();
  673. }
  674. // this.visible = false;
  675. this.$emit('reload');
  676. } catch (error) {
  677. console.error(error);
  678. } finally {
  679. this.butLoading = false;
  680. loading.close();
  681. }
  682. } else {
  683. // 转换为数组
  684. const firstErrorField = Object.values(invalidFields);
  685. if (firstErrorField.length > 0) {
  686. this.$message.warning(firstErrorField[0][0].message);
  687. }
  688. return false;
  689. }
  690. });
  691. },
  692. // 选择生产工单
  693. openAddModel() {
  694. this.$refs.selectWorkOrderRef?.open();
  695. },
  696. // 选择生产工单确认
  697. selectWorkOrderConfirm(selection) {
  698. const selectList = selection.map((i) => {
  699. return {
  700. formedNum: i.formedNum,
  701. batchNo: i.batchNo,
  702. createUserName: i.createUserName,
  703. formingNum: i.formingNum,
  704. produceRoutingId: i.produceRoutingId,
  705. produceRoutingName: i.produceRoutingName,
  706. productCode: i.productCode,
  707. productModel: i.productModel,
  708. productName: i.productName,
  709. recordId: i.recordId,
  710. specification: i.specification,
  711. workOrderCode: i.code,
  712. workOrderId: i.id
  713. };
  714. });
  715. console.log('selectList', selectList);
  716. // 判断是否同一产品 同一批次
  717. if (selectList.length != 0) {
  718. const productCode = selectList[0].productCode;
  719. const batchNo = selectList[0].batchNo;
  720. const isSame = selectList.every(
  721. (item) =>
  722. item.productCode === productCode && item.batchNo === batchNo
  723. );
  724. const isSameOrders = this.form.orders.every(
  725. (item) =>
  726. item.productCode === productCode && item.batchNo === batchNo
  727. );
  728. if (!isSame || !isSameOrders) {
  729. this.$message.warning('请选择同产品同批次号工单发起批量放行');
  730. return;
  731. }
  732. // 去重
  733. const existingWorkOrderIds = this.form.orders.map(
  734. (order) => order.workOrderId
  735. );
  736. const newOrders = selectList.filter(
  737. (item) => !existingWorkOrderIds.includes(item.workOrderId)
  738. );
  739. this.form.orders = [...this.form.orders, ...newOrders];
  740. }
  741. // 关闭弹窗
  742. this.$refs.selectWorkOrderRef?.handleClose();
  743. },
  744. // 删除行
  745. deleteRow(row) {
  746. this.form.orders = this.form.orders.filter(
  747. (item) => item.workOrderId !== row.workOrderId
  748. );
  749. },
  750. // 获取模板详情
  751. async getTemplateDetails(id) {
  752. this.loading = true;
  753. try {
  754. const data = await checklisttemplateGetById(id);
  755. console.log('模板详情', data);
  756. // 详情
  757. this.form.details = data.details;
  758. this.loading = false;
  759. this.setDefaultValue();
  760. } catch (error) {
  761. this.loading = false;
  762. }
  763. },
  764. // 获取放行单详情
  765. async getCheckDetails(id) {
  766. this.loading = true;
  767. try {
  768. const data = await checklistrecordGetById(id);
  769. this.$util.assignObject(this.form, data);
  770. console.log('this.form', this.form);
  771. if (this.type == 'edit' || this.type == 'add') {
  772. this.setDefaultValue();
  773. }
  774. this.loading = false;
  775. } catch (error) {
  776. this.loading = false;
  777. }
  778. },
  779. // 设置默认值
  780. setDefaultValue() {
  781. // 编辑时 设置默认值
  782. if (!this.form.qualityCheckUserId) {
  783. // 设置为当前用户
  784. this.form.qualityCheckUserId = this.$store.state.user.info.id;
  785. this.form.qualityCheckUserName = this.$store.state.user.info.name;
  786. }
  787. if (!this.form.workCheckUserId) {
  788. // 设置为当前用户
  789. this.form.workCheckUserId = this.$store.state.user.info.id;
  790. this.form.workCheckUserName = this.$store.state.user.info.name;
  791. }
  792. if (!this.form.qualityCheckTime) {
  793. this.form.qualityCheckTime = this.$util.toDateString(
  794. new Date(),
  795. 'yyyy-MM-dd HH:mm:ss'
  796. );
  797. }
  798. if (!this.form.workCheckTime) {
  799. this.form.workCheckTime = this.$util.toDateString(
  800. new Date(),
  801. 'yyyy-MM-dd HH:mm:ss'
  802. );
  803. }
  804. },
  805. // 规则齐套检查
  806. async getKitCheck() {
  807. // 判断 是否有需要自动检查的项
  808. const hasAutoCheck = this.form.details.some((item) => item.isAutoCheck);
  809. if (!hasAutoCheck) {
  810. console.log('this.form.details', this.form.details);
  811. this.$message.warning('当前没有需要自动检查的规则');
  812. return;
  813. }
  814. // 必须要有物品清单
  815. if (this.form.orders.length == 0) {
  816. this.$message.warning('请添加物品清单');
  817. return;
  818. }
  819. if (!this.form.id) {
  820. this.$message.warning('请先保存放行单');
  821. return;
  822. }
  823. try {
  824. this.butLoading = true;
  825. const data = await checklistrecordKitCheck(this.form.id);
  826. console.log('规则齐套检查', data);
  827. // 把检查结果赋值给对应的明细
  828. this.form.details = this.form.details.map((item) => {
  829. const checkItem = data.find((d) => d.id === item.id);
  830. console.log('checkItem 存在', checkItem);
  831. if (checkItem && item.isAutoCheck) {
  832. return {
  833. ...item,
  834. isPass: checkItem.isPass
  835. };
  836. }
  837. return item;
  838. });
  839. console.log('规则齐套检查', this.form.details);
  840. this.butLoading = false;
  841. this.$message.success('规则齐套检查完成!');
  842. } catch (error) {
  843. this.butLoading = false;
  844. }
  845. },
  846. // 打开选择用户
  847. openSelectUser(type) {
  848. this.selectUserType = type;
  849. this.showSelectUser = true;
  850. },
  851. selectUserFinished(userInfo) {
  852. console.log('userInfo', userInfo);
  853. console.log('this.selectUserType', this.selectUserType);
  854. if (this.selectUserType == 0) {
  855. this.form.workCheckUserId = userInfo.id;
  856. this.form.workCheckUserName = userInfo.name;
  857. } else {
  858. this.form.qualityCheckUserId = userInfo.id;
  859. this.form.qualityCheckUserName = userInfo.name;
  860. }
  861. },
  862. async openWorkOrderDetail(row) {
  863. console.log('row', row);
  864. const info = await getworkOrderById(row.workOrderId);
  865. this.$refs.detailsRef.open(info);
  866. },
  867. // 提交审批
  868. openApproval() {
  869. const row = this.form;
  870. console.log('row', row);
  871. let businessType = this.getDictValue(
  872. '放行类型',
  873. row.checklistType + ''
  874. );
  875. console.log('businessType', businessType);
  876. this.processSubmitDialogFlag = true;
  877. this.$nextTick(async () => {
  878. let params = {
  879. businessId: row.id,
  880. businessKey: 'work_order_checklist_approval',
  881. formCreateUserId: row.createUserId,
  882. variables: {
  883. businessCode: row.code,
  884. businessName: '放行单',
  885. businessType: businessType
  886. }
  887. };
  888. if (this.clientEnvironmentId == 5) {
  889. // 嘉实环境
  890. const data = await getCategoryByCode(row.orders[0]?.productCode);
  891. // 判断品类
  892. if (data && data.categoryLevelCodePath?.includes('W3-209')) {
  893. // 药品
  894. params.businessKey = 'work_order_checklist_approval1';
  895. } else {
  896. // 器械
  897. params.businessKey = 'work_order_checklist_approval';
  898. }
  899. }
  900. console.log('params', params);
  901. this.$refs.processSubmitDialogRef.init(params);
  902. });
  903. }
  904. }
  905. };
  906. </script>
  907. <style scoped lang="scss">
  908. .detail-table {
  909. border: 1px solid #ebeef5;
  910. // 实线边框
  911. border-collapse: collapse;
  912. td {
  913. border: none;
  914. padding: 10px 15px;
  915. border: 1px solid #ebeef5;
  916. &:first-child {
  917. font-weight: 600;
  918. background: #f5f7fa;
  919. width: 130px;
  920. text-align: center;
  921. }
  922. }
  923. }
  924. .mask-box {
  925. position: relative;
  926. &::after {
  927. content: '';
  928. width: 100%;
  929. height: 100%;
  930. position: absolute;
  931. top: 0;
  932. left: 0;
  933. background: rgba(0, 0, 0, 0);
  934. cursor: pointer;
  935. }
  936. }
  937. .remark-error {
  938. ::v-deep .el-textarea__inner {
  939. border-color: #f56c6c !important;
  940. }
  941. }
  942. </style>