InRequestForm.vue 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126
  1. <template>
  2. <div class="app-container">
  3. <div class="page-header">
  4. <div class="header-content">
  5. <!-- 按钮区域 -->
  6. <div class="header-buttons">
  7. <el-button
  8. type="primary"
  9. :loading="formLoading"
  10. plain
  11. size="mini"
  12. :disabled="isFormDisabled"
  13. @click="submitForm"
  14. >
  15. 保 存
  16. </el-button>
  17. <!-- 提交菜单 -->
  18. <el-dropdown class="ml-5" trigger="click">
  19. <el-button type="primary" size="mini" plain>
  20. 提交菜单
  21. <i class="el-icon-arrow-down el-icon--right" />
  22. </el-button>
  23. <el-dropdown-menu slot="dropdown">
  24. <el-dropdown-item
  25. :disabled="isButtonDisabled('commit')"
  26. @click.native="commit"
  27. >提交</el-dropdown-item
  28. >
  29. <el-dropdown-item
  30. :disabled="isButtonDisabled('cancel')"
  31. @click.native="cancel"
  32. >撤销</el-dropdown-item
  33. >
  34. </el-dropdown-menu>
  35. </el-dropdown>
  36. <!-- 审批菜单 -->
  37. <el-dropdown class="ml-5 mr-5" trigger="click">
  38. <el-button type="warning" size="mini" plain>
  39. 审批菜单
  40. <i class="el-icon-arrow-down el-icon--right" />
  41. </el-button>
  42. <el-dropdown-menu slot="dropdown">
  43. <el-dropdown-item
  44. :disabled="isButtonDisabled('audit')"
  45. @click.native="audit"
  46. >审核</el-dropdown-item
  47. >
  48. <el-dropdown-item
  49. :disabled="isButtonDisabled('antiAudit')"
  50. @click.native="antiAudit"
  51. >反审核</el-dropdown-item
  52. >
  53. </el-dropdown-menu>
  54. </el-dropdown>
  55. <!-- <el-button @click="reset" plain>重置</el-button> -->
  56. <el-button
  57. type="primary"
  58. size="mini"
  59. plain
  60. :disabled="isFormDisabled"
  61. @click="add()"
  62. >新增明细
  63. </el-button>
  64. <el-button plain size="mini" @click="handleCancel">返回</el-button>
  65. </div>
  66. </div>
  67. </div>
  68. <el-tabs v-model="activeName" @tab-click="handleClick">
  69. <el-tab-pane label="明细信息" name="detail">
  70. <el-form
  71. ref="formRef"
  72. v-loading="formLoading"
  73. :model="formData"
  74. :rules="dynamicFormRules"
  75. label-width="150px"
  76. class="form-container"
  77. >
  78. <el-row :gutter="20">
  79. <el-col :span="12"
  80. ><el-form-item label="业务类型" prop="businessType">
  81. <el-select
  82. v-model="formData.businessType"
  83. placeholder="请选择业务类型"
  84. :disabled="!isEditable"
  85. @change="changeBusinessType"
  86. >
  87. <el-option
  88. v-for="dict in getDictDatas('in_business_type')"
  89. :key="dict.value"
  90. :label="dict.label"
  91. :value="dict.value"
  92. />
  93. </el-select>
  94. </el-form-item>
  95. </el-col>
  96. <el-col :span="12">
  97. <el-form-item label="申请单号" prop="remark">
  98. <el-input
  99. v-model="formData.requestNo"
  100. :disabled="true"
  101. placeholder="保存后自动生成"
  102. /> </el-form-item
  103. ></el-col>
  104. <el-col :span="12">
  105. <el-form-item :label="getDeptLabel" prop="deptCode">
  106. <DepartMentSelect
  107. ref="departMentSelect"
  108. v-model="formData.deptCode"
  109. :disabled="isFormDisabled || !formData.businessType"
  110. :placeholder="getDeptPlaceholder"
  111. clearable
  112. @change="selectDepart"
  113. />
  114. </el-form-item>
  115. </el-col>
  116. <el-col :span="12"
  117. ><el-form-item label="业务分类名称" prop="businessDescribe">
  118. <el-select
  119. v-model="formData.businessDescribe"
  120. :disabled="isFormDisabled || !formData.businessType"
  121. placeholder="请选择业务类型"
  122. @change="changeBusinessDescribe"
  123. >
  124. <el-option
  125. v-for="dict in businessDescribeList"
  126. :key="dict.label"
  127. :label="dict.label"
  128. :value="dict.label"
  129. />
  130. </el-select> </el-form-item
  131. ></el-col>
  132. <el-col :span="12"
  133. ><el-form-item label="优先级" prop="priority">
  134. <el-select
  135. v-model="formData.priority"
  136. :disabled="isFormDisabled || !formData.businessType"
  137. placeholder="请选择优先级"
  138. >
  139. <el-option
  140. v-for="dict in getDictDatas('priority')"
  141. :key="dict.value"
  142. :label="dict.label"
  143. :value="dict.value"
  144. />
  145. </el-select>
  146. </el-form-item>
  147. </el-col>
  148. <el-col :span="12">
  149. <el-form-item label="供应商编码" prop="supplierCode">
  150. <el-input
  151. v-model="formData.supplierCode"
  152. :disabled="isFormDisabled || !formData.businessType"
  153. placeholder="请输入供应商编码"
  154. />
  155. </el-form-item>
  156. </el-col>
  157. <el-col :span="12">
  158. <el-form-item label="客户编码" prop="customerCode">
  159. <el-input
  160. v-model="formData.customerCode"
  161. :disabled="isFormDisabled || !formData.businessType"
  162. placeholder="请输入客户编码"
  163. />
  164. </el-form-item>
  165. </el-col>
  166. <el-col :span="12">
  167. <el-form-item label="源单编号" prop="sourceOrderNo">
  168. <el-select
  169. v-model="formData.sourceOrderNo"
  170. filterable
  171. remote
  172. :disabled="isFormDisabled || !formData.businessType"
  173. reserve-keyword
  174. placeholder="请输入源单编号"
  175. :remote-method="remoteMethod"
  176. :loading="loading"
  177. @change="changeSourceOrderNo"
  178. >
  179. <el-option
  180. v-for="item in sourceOrderNoList"
  181. :key="item.sourceOrderNo"
  182. :label="item.sourceOrderNo"
  183. :value="item.sourceOrderNo"
  184. />
  185. </el-select>
  186. </el-form-item>
  187. </el-col>
  188. <el-col :span="12">
  189. <el-form-item label="预计出入库时间" prop="expectedTime">
  190. <el-date-picker
  191. v-model="formData.expectedTime"
  192. :disabled="isFormDisabled || !formData.businessType"
  193. clearable
  194. type="date"
  195. value-format="timestamp"
  196. placeholder="选择预计出入库时间"
  197. /> </el-form-item
  198. ></el-col>
  199. <el-col :span="12">
  200. <el-form-item label="实际出入库时间" prop="actualTime">
  201. <el-date-picker
  202. v-model="formData.actualTime"
  203. clearable
  204. :disabled="true"
  205. type="date"
  206. value-format="timestamp"
  207. placeholder="选择实际出入库时间"
  208. /> </el-form-item
  209. ></el-col>
  210. <el-col :span="12">
  211. <el-form-item label="备注" prop="remark">
  212. <el-input
  213. v-model="formData.remark"
  214. :disabled="isFormDisabled || !formData.businessType"
  215. placeholder="请输入备注"
  216. /> </el-form-item
  217. ></el-col>
  218. <el-col :span="12">
  219. <el-form-item label="存储地点" prop="warehouseId">
  220. <el-select
  221. v-model="formData.warehouseId"
  222. filterable
  223. remote
  224. :disabled="isFormDisabled || !formData.businessType"
  225. reserve-keyword
  226. placeholder="请输入存储地点"
  227. :remote-method="remoteWarehouse"
  228. :loading="loading"
  229. >
  230. <el-option
  231. v-for="item in warehouseList"
  232. :key="item.erpId"
  233. :label="item.name"
  234. :value="item.erpId"
  235. />
  236. </el-select>
  237. </el-form-item>
  238. </el-col>
  239. <el-col :span="12">
  240. <el-form-item label="状态" prop="status" aria-disabled="true">
  241. <el-select
  242. v-model="formData.status"
  243. disabled
  244. placeholder="请选择状态"
  245. >
  246. <el-option
  247. v-for="dict in getDictDatas('in_out_status')"
  248. :key="dict.value"
  249. :label="dict.label"
  250. :value="dict.value"
  251. />
  252. </el-select>
  253. </el-form-item>
  254. </el-col>
  255. <el-col :span="12">
  256. <el-form-item label="收货人" prop="receivePerson">
  257. <el-select
  258. v-model="formData.receivePerson"
  259. filterable
  260. :disabled="isFormDisabled || !formData.businessType"
  261. placeholder="请输入收货人"
  262. clearable
  263. style="width: 100%"
  264. >
  265. <el-option
  266. v-for="item in users"
  267. :key="parseInt(item.id)"
  268. :label="item.nickname"
  269. :value="parseInt(item.id)"
  270. />
  271. </el-select>
  272. </el-form-item>
  273. </el-col>
  274. <el-col :span="8" class="text-right">
  275. <el-button
  276. type="primary"
  277. plain
  278. style="width: 60%"
  279. icon="el-icon-upload2"
  280. @click="handleUpload"
  281. >附件上传</el-button
  282. >
  283. </el-col>
  284. </el-row>
  285. </el-form>
  286. <!-- <el-tabs v-model="activeName" @tab-click="handleClick">
  287. <el-tab-pane label="明细信息" name="detail"> -->
  288. <el-table :data="formData.list" border size="mini">
  289. <el-table-column
  290. label="源单编号"
  291. align="center"
  292. prop="sourceRequestId"
  293. width="160"
  294. show-overflow-tooltip
  295. />
  296. <el-table-column
  297. label="源单行号"
  298. align="center"
  299. prop="sourceLineNo"
  300. width="160"
  301. show-overflow-tooltip
  302. />
  303. <el-table-column
  304. label="物料编码"
  305. align="center"
  306. prop="materialNo"
  307. width="200"
  308. show-overflow-tooltip
  309. >
  310. <template v-slot="scope">
  311. <el-select
  312. v-model="scope.row.materialNo"
  313. filterable
  314. remote
  315. reserve-keyword
  316. placeholder="请选择物料编码"
  317. :remote-method="
  318. (query) => remoteMaterialSearch(query, 'code', scope.$index)
  319. "
  320. :loading="loading"
  321. @change="(value) => changeMaterial(value, scope.$index, 'code')"
  322. >
  323. <el-option
  324. v-for="item in materialNoList"
  325. :key="item.code"
  326. :label="item.code"
  327. :value="item.code"
  328. />
  329. </el-select>
  330. </template>
  331. </el-table-column>
  332. <el-table-column
  333. label="物料名称"
  334. align="center"
  335. prop="materialName"
  336. width="200"
  337. show-overflow-tooltip
  338. >
  339. <template v-slot="scope">
  340. <el-select
  341. v-model="scope.row.materialName"
  342. filterable
  343. remote
  344. reserve-keyword
  345. placeholder="请选择物料名称"
  346. :remote-method="
  347. (query) => remoteMaterialSearch(query, 'name', scope.$index)
  348. "
  349. :loading="loading"
  350. @change="(value) => changeMaterial(value, scope.$index, 'name')"
  351. >
  352. <el-option
  353. v-for="item in materialNameList"
  354. :key="item.code"
  355. :label="item.name"
  356. :value="item.name"
  357. />
  358. </el-select>
  359. </template>
  360. </el-table-column>
  361. <el-table-column
  362. label="客户编码"
  363. align="center"
  364. prop="customerCode"
  365. width="150"
  366. show-overflow-tooltip
  367. />
  368. <el-table-column
  369. label="客户名称"
  370. align="center"
  371. prop="customerName"
  372. width="160"
  373. show-overflow-tooltip
  374. />
  375. <el-table-column
  376. label="本次申请数量"
  377. align="center"
  378. prop="nowDeliveredQty"
  379. width="160"
  380. >
  381. <template slot-scope="scope">
  382. <el-input
  383. v-model="scope.row.nowDeliveredQty"
  384. :disabled="isFormDisabled"
  385. @change="deliverChange"
  386. />
  387. </template>
  388. </el-table-column>
  389. <el-table-column
  390. label="已入库数量"
  391. align="center"
  392. prop="completedQty"
  393. width="120"
  394. />
  395. <el-table-column
  396. label="源单计划数量"
  397. align="center"
  398. prop="planQty"
  399. width="120"
  400. />
  401. <el-table-column
  402. label="单位"
  403. align="center"
  404. prop="unitName"
  405. width="150"
  406. show-overflow-tooltip
  407. />
  408. <el-table-column
  409. label="行备注"
  410. align="center"
  411. prop="remark"
  412. width="200"
  413. >
  414. <template slot-scope="scope">
  415. <el-input v-model="scope.row.remark" :disabled="isFormDisabled" />
  416. </template>
  417. </el-table-column>
  418. <el-table-column
  419. label="操作"
  420. align="center"
  421. fixed="right"
  422. width="150px"
  423. class-name="small-padding fixed-width"
  424. >
  425. <template v-slot="scope">
  426. <el-button
  427. size="mini"
  428. type="text"
  429. icon="el-icon-delete"
  430. :disabled="isFormDisabled"
  431. @click="handleDelete(scope)"
  432. >删除</el-button
  433. >
  434. </template>
  435. </el-table-column>
  436. </el-table>
  437. </el-tab-pane>
  438. <el-tab-pane label="审批任务" name="approvalTask" lazy>
  439. <ApprovalTask
  440. v-if="
  441. activeName === 'approvalTask' &&
  442. formData.bpmInstanceId !== null &&
  443. formData.bpmInstanceId !== undefined
  444. "
  445. :id="formData.bpmInstanceId"
  446. :receive-person="formData.receivePerson"
  447. />
  448. <div v-else class="isNotApproval">暂未开启工作流</div>
  449. </el-tab-pane>
  450. </el-tabs>
  451. <!-- 附件上传 -->
  452. <AttachmentUpload ref="attachmentUpload" @files="getFileList" />
  453. </div>
  454. </template>
  455. <script>
  456. import * as InRequestApi from "@/api/wms/output/inrequest";
  457. import DepartMentSelect from "./components/DepartMentSelect.vue";
  458. import AttachmentUpload from "../../wms/incoming/register/components/AttachmentUpload.vue";
  459. // 审批任务
  460. import ApprovalTask from "../../wms/quality/iqcInspection/components/ApprovalTaskNew2.vue";
  461. import { getFilesById } from "@/api/wms/incoming/register";
  462. import { listSimpleUsers } from "@/api/system/user";
  463. export default {
  464. name: "InRequestForm",
  465. components: {
  466. DepartMentSelect,
  467. ApprovalTask,
  468. AttachmentUpload,
  469. },
  470. data() {
  471. return {
  472. activeName: "detail",
  473. materialNameList: [],
  474. materialNoList: [],
  475. sourceOrderNoList: [],
  476. businessDescribeList: [],
  477. warehouseList: [],
  478. uploadFiles: [], // 上传的文件
  479. users: [],
  480. loading: false,
  481. // 页面标题
  482. dialogTitle: "",
  483. // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
  484. formLoading: false,
  485. // 表单参数
  486. formData: {
  487. departmentNo: undefined,
  488. deptCode: undefined,
  489. deptName: undefined,
  490. id: undefined,
  491. requestNo: undefined,
  492. requestType: undefined,
  493. businessType: undefined,
  494. businessCategory: undefined,
  495. businessDescribe: undefined,
  496. businessSubType: undefined,
  497. status: undefined,
  498. priority: undefined,
  499. warehouseId: undefined,
  500. relatedWarehouseId: undefined,
  501. supplierCode: undefined,
  502. customerCode: undefined,
  503. sourceOrderNo: undefined,
  504. expectedTime: undefined,
  505. actualTime: undefined,
  506. totalQty: undefined,
  507. totalSku: undefined,
  508. totalLine: undefined,
  509. remark: undefined,
  510. extendInfo: undefined,
  511. submitter: undefined,
  512. submitTime: undefined,
  513. auditor: undefined,
  514. auditTime: undefined,
  515. erpWriteFlag: undefined,
  516. erpErrMsg: undefined,
  517. erpBackId: undefined,
  518. list: [],
  519. bpmInstanceId: undefined,
  520. },
  521. // 表单校验
  522. formRules: {
  523. businessType: [
  524. {
  525. required: true,
  526. message: "业务类型不能为空",
  527. trigger: "blur",
  528. },
  529. ],
  530. priority: [
  531. {
  532. required: true,
  533. message: "优先级不能为空",
  534. trigger: "blur",
  535. },
  536. ],
  537. expectedTime: [
  538. { required: true, message: "预计入库时间不能为空", trigger: "blur" },
  539. ],
  540. receivePerson: [
  541. {
  542. required: true,
  543. message: "收货人不能为空",
  544. trigger: "blur",
  545. },
  546. ],
  547. },
  548. };
  549. },
  550. computed: {
  551. isFormDisabled() {
  552. // 当路径有id且status>=1时禁用表单
  553. const status = parseInt(this.formData.status || "0");
  554. return status >= 1;
  555. },
  556. // 计算属性判断修改状态下是否可编辑
  557. isEditable() {
  558. // 有 id 表示是编辑模式,不可编辑
  559. // 没有 id 表示是新增模式,可编辑
  560. return (
  561. this.formData.id === undefined ||
  562. this.formData.id === null ||
  563. this.formData.id === ""
  564. );
  565. },
  566. // 动态获取部门标签
  567. getDeptLabel() {
  568. const businessType = this.formData.businessType;
  569. if (businessType === "9") {
  570. // 委外入库
  571. return "收货部门";
  572. } else if (businessType === "8") {
  573. // 委外退料
  574. return "退货部门";
  575. } else if (businessType === "3") {
  576. // 生产退料
  577. return "发料部门";
  578. }
  579. return "部门";
  580. },
  581. // 动态获取部门占位符
  582. getDeptPlaceholder() {
  583. const businessType = this.formData.businessType;
  584. if (businessType === "9") {
  585. // 委外入库
  586. return "请选择收货部门";
  587. } else if (businessType === "8") {
  588. // 委外退料
  589. return "请选择退货部门";
  590. } else if (businessType === "3") {
  591. // 生产退料
  592. return "请选择发料部门";
  593. }
  594. return "请选择部门";
  595. },
  596. // 动态生成表单验证规则
  597. dynamicFormRules() {
  598. // 从原始规则中只保留业务类型、优先级、预计出入库时间、收货人
  599. const baseRules = {
  600. businessType: this.formRules.businessType,
  601. priority: this.formRules.priority,
  602. expectedTime: this.formRules.expectedTime,
  603. receivePerson: this.formRules.receivePerson,
  604. };
  605. const rules = { ...baseRules };
  606. const businessType = this.formData.businessType;
  607. // 只有选择了业务类型后,才添加其他字段的验证规则
  608. if (businessType) {
  609. // 委外入库(9)和委外退料(8)需要的必填字段
  610. if (businessType === "9" || businessType === "8") {
  611. rules.deptCode = [
  612. {
  613. required: true,
  614. message: this.getDeptLabel + "不能为空",
  615. trigger: "blur",
  616. },
  617. ];
  618. rules.businessDescribe = [
  619. {
  620. required: true,
  621. message: "业务分类名称不能为空",
  622. trigger: "blur",
  623. },
  624. ];
  625. rules.supplierCode = [
  626. { required: true, message: "供应商不能为空", trigger: "blur" },
  627. ];
  628. rules.sourceOrderNo = [
  629. { required: true, message: "源单编号不能为空", trigger: "blur" },
  630. ];
  631. }
  632. // 生产退料(3)需要的必填字段
  633. else if (businessType === "3") {
  634. rules.deptCode = [
  635. {
  636. required: true,
  637. message: this.getDeptLabel + "不能为空",
  638. trigger: "blur",
  639. },
  640. ];
  641. rules.businessDescribe = [
  642. {
  643. required: true,
  644. message: "业务分类名称不能为空",
  645. trigger: "blur",
  646. },
  647. ];
  648. rules.sourceOrderNo = [
  649. { required: true, message: "源单编号不能为空", trigger: "blur" },
  650. ];
  651. }
  652. // 其他业务类型不需要必填部门字段
  653. else {
  654. // 移除部门字段的必填规则
  655. delete rules.deptCode;
  656. }
  657. }
  658. return rules;
  659. },
  660. },
  661. watch: {
  662. "$route.query.id": {
  663. immediate: true,
  664. handler(newId) {
  665. // 只有当前路由路径包含"/inStorageManage/in-request/InRequestForm"时才处理,避免标签跳转时错误调用API
  666. if (
  667. this.$route.path.includes("/inStorageManage/in-request/InRequestForm")
  668. ) {
  669. if (newId) {
  670. this.initData(newId);
  671. } else {
  672. this.reset();
  673. }
  674. }
  675. },
  676. },
  677. },
  678. created() {
  679. // 从路由参数获取ID
  680. const id = this.$route.query.id;
  681. listSimpleUsers().then((response) => {
  682. this.users = response.data;
  683. });
  684. if (id) {
  685. this.dialogTitle = "修改";
  686. // this.initData(id)
  687. } else {
  688. this.dialogTitle = "新增";
  689. }
  690. },
  691. methods: {
  692. // 通用的判断函数判断按钮是否可点击
  693. isButtonDisabled(buttonType) {
  694. const status = Number(this.formData.status);
  695. switch (buttonType) {
  696. case "commit":
  697. return status !== 0; // 提交,status=0时可点击
  698. case "cancel":
  699. return status !== 1; // 撤销,status=1时可点击
  700. case "audit":
  701. return status !== 1; // 审核,status=1时可点击
  702. case "antiAudit":
  703. return status < 2; // 反审核,status>=2时可点击
  704. default:
  705. return true;
  706. }
  707. },
  708. // 标签页切换处理
  709. handleClick(tab, event) {
  710. // 可以在这里添加标签切换时的逻辑
  711. console.log(tab, event);
  712. },
  713. handleDelete(row) {
  714. console.log(row);
  715. this.formData.list.splice(row.$index, 1);
  716. },
  717. selectDepart(item) {
  718. this.formData.deptCode = item.code;
  719. this.formData.deptName = item.name;
  720. },
  721. remoteMaterialSearch(query, type, index) {
  722. if (query !== "") {
  723. this.loading = true;
  724. setTimeout(async () => {
  725. this.loading = false;
  726. const params = {
  727. pageSize: 999,
  728. };
  729. // 根据搜索类型设置参数
  730. if (type === "code") {
  731. params.code = query;
  732. } else {
  733. params.name = query;
  734. }
  735. try {
  736. const {
  737. data: { list },
  738. } = await InRequestApi.getMaterialPage(params);
  739. // 每次搜索都重新赋值,保证列表始终是最新数据
  740. if (type === "code") {
  741. this.materialNoList = list || [];
  742. } else {
  743. this.materialNameList = list || [];
  744. }
  745. } catch (error) {
  746. console.error("搜索物料失败:", error);
  747. // 出错时清空列表
  748. if (type === "code") {
  749. this.materialNoList = [];
  750. } else {
  751. this.materialNameList = [];
  752. }
  753. }
  754. }, 200);
  755. } else {
  756. // 清空对应的列表
  757. if (type === "code") {
  758. this.materialNoList = [];
  759. } else {
  760. this.materialNameList = [];
  761. }
  762. }
  763. },
  764. remoteMethod(query) {
  765. if (query !== "") {
  766. const that = this;
  767. this.loading = true;
  768. setTimeout(async () => {
  769. this.loading = false;
  770. const { data } = await InRequestApi.getSourceOrder({
  771. businessType: that.formData.businessType,
  772. sourceOrderNo: query,
  773. pageSize: 999,
  774. });
  775. this.sourceOrderNoList = data || [];
  776. }, 200);
  777. } else {
  778. this.sourceOrderNoList = [];
  779. }
  780. },
  781. add() {
  782. if (!this.formData.businessType) {
  783. return this.$message.error("请先选择业务类型");
  784. }
  785. this.formData.list = this.formData.list || [];
  786. this.formData.list.push({});
  787. this.formData = { ...this.formData };
  788. },
  789. remoteWarehouse(query) {
  790. if (query !== "") {
  791. const that = this;
  792. this.loading = true;
  793. setTimeout(async () => {
  794. this.loading = false;
  795. const {
  796. data: { list },
  797. } = await InRequestApi.getStockPage({
  798. name: query,
  799. pageSize: 999,
  800. });
  801. this.warehouseList = list || [];
  802. }, 200);
  803. } else {
  804. this.warehouseList = [];
  805. }
  806. },
  807. changeSourceOrderNo(value) {
  808. this.sourceOrderNoList.map((v) => {
  809. if (v.sourceOrderNo == value) {
  810. this.formData.list = v.list;
  811. }
  812. });
  813. },
  814. changeMaterial(value, index, type) {
  815. // 根据选择的类型获取对应的列表
  816. const list =
  817. type === "code" ? this.materialNoList : this.materialNameList;
  818. // 查找选中的物料信息
  819. let selectedMaterial = null;
  820. if (type === "code") {
  821. selectedMaterial = list.find((item) => item.code === value);
  822. // 如果在当前列表找不到,尝试从另一个列表找
  823. if (!selectedMaterial) {
  824. selectedMaterial = this.materialNameList.find(
  825. (item) => item.code === value
  826. );
  827. }
  828. } else {
  829. selectedMaterial = list.find((item) => item.name === value);
  830. // 如果在当前列表找不到,尝试从另一个列表找
  831. if (!selectedMaterial) {
  832. selectedMaterial = this.materialNoList.find(
  833. (item) => item.name === value
  834. );
  835. }
  836. }
  837. if (selectedMaterial) {
  838. // 更新表单中的物料信息
  839. const newRow = {
  840. ...this.formData.list[index],
  841. materialNo: selectedMaterial.code,
  842. materialName: selectedMaterial.name,
  843. unitName: selectedMaterial.unit || "",
  844. };
  845. // 更新行数据
  846. this.$set(this.formData.list, index, newRow);
  847. // 强制更新列表,确保页面正常展示
  848. this.formData.list = [...this.formData.list];
  849. }
  850. },
  851. changeBusinessDescribe(e) {
  852. this.businessDescribeList.map((v) => {
  853. if (v.label == e) {
  854. this.formData.businessCategory = v.value;
  855. }
  856. });
  857. },
  858. async changeBusinessType(value) {
  859. this.formData.businessType = value;
  860. this.formData.businessDescribe = "";
  861. this.formData.businessCategory = "";
  862. // 重置表单校验状态
  863. this.$nextTick(() => {
  864. this.$refs.formRef.clearValidate();
  865. });
  866. const { data } = await InRequestApi.getDictByOrderType({
  867. orderType: value,
  868. });
  869. this.businessDescribeList = data;
  870. },
  871. /** 初始化数据 */
  872. async initData(id) {
  873. this.formLoading = true;
  874. try {
  875. const res = await InRequestApi.getRequest(id);
  876. res.data.businessType = res.data.businessType
  877. ? res.data.businessType.toString()
  878. : "0";
  879. res.data.businessDescribe = res.data.businessDescribe
  880. ? res.data.businessDescribe.toString()
  881. : "";
  882. res.data.priority = res.data.priority
  883. ? res.data.priority.toString()
  884. : "0";
  885. res.data.status = res.data.status ? res.data.status.toString() : "0";
  886. res.data.receivePerson = res.data.receivePerson
  887. ? Number(res.data.receivePerson)
  888. : null;
  889. // res.data.list = res.data.list || [];
  890. this.formData = res.data;
  891. // 附件列表
  892. this.uploadFiles = this.formData.filesListVos;
  893. } finally {
  894. this.formLoading = false;
  895. }
  896. },
  897. /** 保存按钮 */
  898. async submitForm() {
  899. // 校验主表
  900. await this.$refs["formRef"].validate();
  901. this.formLoading = true;
  902. try {
  903. // /* 1. 深拷贝一份,避免污染页面数据 */
  904. // const data = JSON.parse(JSON.stringify(this.formData));
  905. // /* 2. 把收货人转回字符串 */
  906. // data.receivePerson =
  907. // data.receivePerson != null ? String(data.receivePerson) : "";
  908. const data = this.formData;
  909. data.list = data.list
  910. .filter((v) => v.nowDeliveredQty)
  911. .map(
  912. ({
  913. completedQty,
  914. actualQty,
  915. stock_code,
  916. area_code,
  917. location_code,
  918. status,
  919. lineNo,
  920. inventory_status,
  921. ...rest
  922. }) => rest
  923. );
  924. // 上传的附件拼接传给后端
  925. const fileIds = (this.uploadFiles || [])
  926. .map((item) => {
  927. return item.id || item.name?.fileId;
  928. })
  929. .filter((id) => id && id !== "");
  930. // 拼接文件ID
  931. data.fileId = fileIds.join(",");
  932. // 修改的提交
  933. if (data.id) {
  934. await InRequestApi.updateRequest(data);
  935. this.$modal.msgSuccess("修改成功");
  936. return;
  937. }
  938. // 添加的提交
  939. await InRequestApi.createRequest(data);
  940. this.$modal.msgSuccess("新增成功");
  941. this.$router.push({
  942. path: "/inStorageManage/in-request",
  943. });
  944. } finally {
  945. this.formLoading = false;
  946. }
  947. },
  948. /** 提交按钮 */
  949. async commit() {
  950. console.log("打印一下收货人信息", this.formData.receivePerson);
  951. if (!this.formData.receivePerson) {
  952. this.$modal.msgWarning("请先添加收货人");
  953. return;
  954. }
  955. const menuId = this.$route.meta.id;
  956. // 只提取需要的字段
  957. const requestData = {
  958. id: this.formData.id,
  959. menuId: menuId,
  960. };
  961. // 接口调用
  962. await InRequestApi.commitInRequest(requestData);
  963. this.$modal.msgSuccess("提交成功");
  964. // 状态变化
  965. this.$set(this.formData, "status", "1");
  966. // 重新获取数据
  967. const res = await InRequestApi.getRequest(this.formData.id);
  968. this.formData.bpmInstanceId = res.data.bpmInstanceId;
  969. },
  970. /** 撤销按钮 */
  971. async cancel() {
  972. const data = this.formData;
  973. // 接口调用
  974. await InRequestApi.cancelInRequest(data);
  975. this.$modal.msgSuccess("撤销成功");
  976. // 状态变化
  977. this.$set(this.formData, "status", "0");
  978. },
  979. /** 审核按钮 */
  980. async audit() {
  981. // 检查是否存在工作流实例ID
  982. if (this.formData.bpmInstanceId) {
  983. // 如果存在工作流实例,跳转到审批任务tab页
  984. this.activeName = "approvalTask";
  985. this.$modal.msgWarning("请在审批任务页面完成审核!");
  986. return;
  987. }
  988. const data = this.formData;
  989. // 接口调用
  990. await InRequestApi.auditInRequest(data);
  991. this.$modal.msgSuccess("审核成功");
  992. // 状态变化
  993. this.$set(this.formData, "status", "2");
  994. },
  995. /** 反审核按钮 */
  996. async antiAudit() {
  997. const data = this.formData;
  998. // 接口调用
  999. await InRequestApi.antiAuditInRequest(data);
  1000. this.$modal.msgSuccess("反审核成功");
  1001. // 状态变化
  1002. this.$set(this.formData, "status", "0");
  1003. },
  1004. /** 返回按钮 */
  1005. handleCancel() {
  1006. this.reset();
  1007. this.$router.push({
  1008. path: "/inStorageManage/in-request",
  1009. });
  1010. },
  1011. /** 表单重置 */
  1012. reset() {
  1013. this.formData = {
  1014. id: undefined,
  1015. // list: [],
  1016. requestNo: undefined,
  1017. requestType: undefined,
  1018. businessType: undefined,
  1019. businessCategory: undefined,
  1020. businessDescribe: undefined,
  1021. businessSubType: undefined,
  1022. status: undefined,
  1023. priority: undefined,
  1024. warehouseId: undefined,
  1025. relatedWarehouseId: undefined,
  1026. supplierCode: undefined,
  1027. customerCode: undefined,
  1028. sourceOrderNo: undefined,
  1029. expectedTime: undefined,
  1030. actualTime: undefined,
  1031. totalQty: undefined,
  1032. totalSku: undefined,
  1033. totalLine: undefined,
  1034. remark: undefined,
  1035. extendInfo: undefined,
  1036. submitter: undefined,
  1037. submitTime: undefined,
  1038. auditor: undefined,
  1039. auditTime: undefined,
  1040. erpWriteFlag: undefined,
  1041. erpErrMsg: undefined,
  1042. erpBackId: undefined,
  1043. list: [],
  1044. };
  1045. this.resetForm("formRef");
  1046. },
  1047. deliverChange(val) {
  1048. // 这里可以写“本次出入数量”变化后的校验或计算逻辑
  1049. console.log("deliverChange", val);
  1050. },
  1051. // 附件上传
  1052. handleUpload() {
  1053. this.$refs.attachmentUpload.isUploadShow = -1;
  1054. this.$refs.attachmentUpload.title = "上传附件";
  1055. // 直接使用当前组件维护的 uploadFiles,而不是重新获取
  1056. this.$refs.attachmentUpload.fileList = this.uploadFiles || [];
  1057. this.$refs.attachmentUpload.visible = true;
  1058. },
  1059. // 获取上传的附件
  1060. getFileList(data) {
  1061. this.uploadFiles = data;
  1062. },
  1063. },
  1064. };
  1065. </script>
  1066. <style scoped>
  1067. .page-header {
  1068. margin-bottom: 20px;
  1069. padding: 15px 0;
  1070. border-bottom: 1px solid #eee;
  1071. }
  1072. .header-content {
  1073. display: flex;
  1074. flex-direction: column;
  1075. align-items: flex-start;
  1076. }
  1077. .breadcrumb {
  1078. margin-bottom: 15px;
  1079. }
  1080. .header-buttons {
  1081. display: flex;
  1082. justify-content: flex-start;
  1083. align-items: center;
  1084. }
  1085. .header-buttons .el-button {
  1086. margin-right: 10px;
  1087. }
  1088. .form-container {
  1089. margin-bottom: 20px;
  1090. }
  1091. .app-container {
  1092. min-width: 900px;
  1093. margin: 0 auto;
  1094. overflow-x: auto;
  1095. }
  1096. </style>