producePlan.vue 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887
  1. <template>
  2. <ele-modal :visible.sync="visible" @closed="cancel" :title="`${type == 'add' ? '创建' : '编辑'}采购计划`"
  3. custom-class="ele-dialog-form" :close-on-click-modal="false" :close-on-press-escape="false" width="80%"
  4. :maxable="true">
  5. <el-form :model="formData" ref="formRef" label-width="120px" class="ele-body" :rules="rules">
  6. <el-row :gutter="24">
  7. <el-col :span="8">
  8. <el-form-item label="需求类型" prop="demandType">
  9. <el-select v-model="formData.demandType" :key="formData.demandType" placeholder="请选择" style="width: 100%"
  10. :disabled="type == 'detail'">
  11. <el-option v-for="item in demandTypeList" :key="item.dictCode" :label="item.dictValue"
  12. :value="item.dictCode">
  13. </el-option>
  14. </el-select>
  15. </el-form-item>
  16. </el-col>
  17. <el-col :span="8">
  18. <el-form-item label="计划名称" prop="name">
  19. <el-input placeholder="请选择" v-model="formData.name" :readonly="type == 'detail'"></el-input>
  20. </el-form-item>
  21. </el-col>
  22. <el-col :span="8">
  23. <el-form-item label="备注" prop="remark">
  24. <el-input placeholder="备注" v-model="formData.remark" :readonly="type == 'detail'"></el-input>
  25. </el-form-item>
  26. </el-col>
  27. </el-row>
  28. </el-form>
  29. <el-form :model="formData" ref="tableForm">
  30. <ele-pro-table ref="table" :needPage="false" :columns="columns" row-key="id">
  31. <template v-slot:toolbar>
  32. <el-button size="small" type="primary" icon="el-icon-plus" class="ele-btn-icon" @click="produceAdd"
  33. v-if="type != 'detail'">
  34. 添加生产计划
  35. </el-button>
  36. </template>
  37. <template v-slot:code="{ row }">
  38. <el-input placeholder="请输入" readonly :value="row.code || row.salesOrderCode"></el-input>
  39. </template>
  40. <template v-slot:bomId="{ row }">
  41. <el-select v-model="row.bomId" placeholder="请选择" style="width: 100%" :disabled="type == 'detail'"
  42. @change="changeVersions(row)">
  43. <el-option v-for="item in row.bomCategoryList" :key="item.id" :label="'V' + item.versions + '.0'"
  44. :value="item.id">
  45. </el-option>
  46. </el-select>
  47. </template>
  48. <template v-slot:action="{ row, $index }" v-if="type != 'detail'">
  49. <template>
  50. <el-link type="primary" :underline="false" @click="categorySelect(row)">
  51. 添加物料
  52. </el-link>
  53. <el-popconfirm class="ele-action" title="确定要删除此生产计划吗?" @confirm="remove(row, $index)">
  54. <template v-slot:reference>
  55. <el-link type="danger" :underline="false" icon="el-icon-delete">
  56. 删除
  57. </el-link>
  58. </template>
  59. </el-popconfirm>
  60. </template>
  61. </template>
  62. <!-- 展开内容 -->
  63. <template v-slot:expand="{ row, $index }">
  64. <div class="batch-actions" v-if="row.materialList.length > 0">
  65. <el-button @click="batchUpdateDeliveryMethod">批量修改到货方式</el-button>
  66. </div>
  67. <div style="
  68. width: calc(100% - 95px);
  69. min-height: 60px;
  70. margin-left: 95px;
  71. " v-if="row.materialList.length > 0">
  72. <ele-pro-table :toolbar="false" toolsTheme="none" ref="table2" :need-page="false"
  73. :datasource="row.materialList" :columns="columns2" :key="row.categoryId + '-' + $index"
  74. @selection-change="handleSelectionChange">
  75. <template v-slot:sort="{ $index }">
  76. {{ $index + 1 }}
  77. </template>
  78. <template v-slot:unit="{ row }">
  79. {{ row.unit }}
  80. </template>
  81. <template v-slot:demandQuantity="{ row }">
  82. <div>
  83. <!-- 需求数量 -->
  84. <el-input v-model="row.demandQuantity" placeholder="请输入" :readonly="type == 'detail'" @input="
  85. (value) =>
  86. (row.demandQuantity = value.replace(
  87. /^(-)*(\d+)\.(\d\d\d\d\d\d).*$/,
  88. '$1$2.$3'
  89. ))
  90. "></el-input>
  91. </div>
  92. </template>
  93. <template v-slot:purchasingCycle="{ row }">
  94. {{ row.purchasingCycle }}{{ row.purchasingCycleUnit }}
  95. </template>
  96. <template v-slot:purchaseQuantity="{ row }">
  97. <el-input v-model="row.purchaseQuantity" placeholder="请输入" :readonly="type == 'detail'" @input="
  98. (value) =>
  99. (row.purchaseQuantity = value.replace(
  100. /^(-)*(\d+)\.(\d\d\d\d\d\d).*$/,
  101. '$1$2.$3'
  102. ))
  103. "></el-input>
  104. </template>
  105. <template v-slot:deliveryMethod="{ row, $index }">
  106. <el-select clearable class="ele-block" v-model="row.deliveryMethod" placeholder="请选择"
  107. :disabled="type == 'detail'">
  108. <el-option label="一次性到货" :value="1" @click.native="row.timeList = null" />
  109. <el-option label="分批到货" :value="2" @click.native="
  110. handleMethod(row, $index);
  111. row.requireDeliveryTime = null;
  112. " />
  113. </el-select>
  114. </template>
  115. <template v-slot:requireDeliveryTime="{ row, $index }">
  116. <el-date-picker style="width: 100%" clearable v-model="row.requireDeliveryTime" type="date"
  117. v-if="row.deliveryMethod == 1" value-format="yyyy-MM-dd" placeholder="请选择日期"
  118. :readonly="type == 'detail'" :pickerOptions="{
  119. disabledDate: (time) =>
  120. time.getTime() <
  121. new Date(new Date().setHours(0, 0, 0, 0)).getTime()
  122. }">
  123. </el-date-picker>
  124. <el-link type="primary" :underline="false" v-if="row.deliveryMethod == 2"
  125. @click.native="handleMethod(row, $index)">
  126. 设置分批时间
  127. </el-link>
  128. </template>
  129. <template v-slot:imgUrl="{ row }">
  130. <fileUpload v-model="row.imgUrl" module="main" :showLib="false" :limit="1"
  131. :disabled="type == 'detail'" />
  132. </template>
  133. <template v-slot:files="{ row }">
  134. <fileUpload v-model="row.files" module="main" :showLib="false" :limit="1"
  135. :disabled="type == 'detail'" />
  136. </template>
  137. <template v-slot:action="{ row }" v-if="type != 'detail'">
  138. <el-popconfirm class="ele-action" title="确定要删除当前物料吗?" @confirm="remove2(row)">
  139. <template v-slot:reference>
  140. <el-link type="danger" :underline="false" icon="el-icon-delete">
  141. 删除
  142. </el-link>
  143. </template>
  144. </el-popconfirm>
  145. </template>
  146. </ele-pro-table>
  147. </div>
  148. </template>
  149. </ele-pro-table>
  150. </el-form>
  151. <div slot="footer" v-if="type != 'detail'">
  152. <el-button @click="cancel">取消</el-button>
  153. <el-button type="primary" @click="confirm">保存</el-button>
  154. </div>
  155. <produceOrder ref="produceOrderRef" @chooseOrder="chooseOrder"></produceOrder>
  156. <ProductModal ref="productRefs" @chooseModal="chooseModal" />
  157. <ProductionVersion ref="versionRefs" @changeProduct="changeProduct"></ProductionVersion>
  158. <timeDialog ref="timeDialogRef" @chooseTime="chooseTime"></timeDialog>
  159. <ele-modal :visible.sync="batchVisible" title="批量选择" width="25vw" append-to-body @close="handleCancel"
  160. :maxable="true">
  161. <el-form :model="formData2" label-width="100px">
  162. <el-form-item label="到货方式" prop="deliveryMethod">
  163. <el-select clearable v-model="formData2.deliveryMethod" placeholder="请选择">
  164. <el-option label="一次性到货" :value="1" />
  165. <el-option label="分批到货" :value="2" @click.native="
  166. handleMethod();
  167. " />
  168. </el-select>
  169. </el-form-item>
  170. <el-form-item label="要求到货时间" prop="requireDeliveryTime">
  171. <el-date-picker clearable v-model="formData2.requireDeliveryTime" type="date"
  172. v-show="formData2.deliveryMethod == 1" value-format="yyyy-MM-dd" placeholder="请选择日期" :pickerOptions="{
  173. disabledDate: (time) =>
  174. time.getTime() <
  175. new Date(new Date().setHours(0, 0, 0, 0)).getTime()
  176. }">
  177. </el-date-picker>
  178. <el-link type="primary" :underline="false" v-show="formData2.deliveryMethod == 2"
  179. @click.native="handleMethod()">
  180. 设置分批时间
  181. </el-link>
  182. </el-form-item>
  183. </el-form>
  184. <template v-slot:footer>
  185. <el-button @click="handleCancel">取消</el-button>
  186. <el-button type="primary" @click="handleConfirm">确认</el-button>
  187. </template>
  188. </ele-modal>
  189. </ele-modal>
  190. </template>
  191. <script>
  192. import produceOrder from './produceOrder.vue';
  193. import ProductModal from './ProductModal.vue';
  194. import {
  195. listBomByPlanIdsOverride,
  196. listBomBySalesOrderId,
  197. listBomByBomVersionId,
  198. save,
  199. getById
  200. } from '@/api/materialPlan/index';
  201. import ProductionVersion from '@/components/CreatePlan/ProductionVersion2.vue';
  202. import fileUpload from '@/components/upload/fileUpload';
  203. import timeDialog from './timeDialog';
  204. import dictMixins from '@/mixins/dictMixins';
  205. export default {
  206. components: {
  207. produceOrder,
  208. ProductModal,
  209. ProductionVersion,
  210. fileUpload,
  211. timeDialog
  212. },
  213. mixins: [dictMixins],
  214. data() {
  215. return {
  216. formData2: {
  217. deliveryMethod: 1,
  218. requireDeliveryTime: '',
  219. timeList: []
  220. },
  221. batchVisible: false,
  222. multipleSelection: [],
  223. visible: false,
  224. type: 'add',
  225. tableData: [],
  226. xsId: null,
  227. formData: {
  228. demandType: '1',
  229. name: '',
  230. remark: '',
  231. detailRemoveIds: [],
  232. materialRemoveIds: [],
  233. orderType: 2
  234. },
  235. demandTypeList: [
  236. {
  237. dictCode: '1',
  238. dictValue: '生产性物资采购'
  239. },
  240. {
  241. dictCode: '6',
  242. dictValue: '外协自供料采购'
  243. },
  244. {
  245. dictCode: '7',
  246. dictValue: '外协客供料采购'
  247. }
  248. ],
  249. expandedRowKeys: [],
  250. rules: {
  251. demandType: [
  252. {
  253. required: true,
  254. message: '请选择需求类型',
  255. trigger: ['blur', 'change']
  256. }
  257. ],
  258. name: [
  259. {
  260. required: true,
  261. message: '请输入配料计划名称',
  262. trigger: ['blur', 'change']
  263. }
  264. ]
  265. },
  266. };
  267. },
  268. computed: {
  269. // 表格列配置
  270. columns() {
  271. const list = [
  272. {
  273. width: 45,
  274. type: 'expand',
  275. columnKey: 'materialList',
  276. align: 'center',
  277. slot: 'expand'
  278. },
  279. {
  280. width: 50,
  281. label: '序号',
  282. type: 'index',
  283. align: 'center',
  284. slot: 'index'
  285. },
  286. // {
  287. // prop: 'purchaseType',
  288. // label: '采购类型',
  289. // align: 'center',
  290. // showOverflowTooltip: true,
  291. // minWidth: 120,
  292. // sortable: true,
  293. // formatter: (row) => {
  294. // return row.purchaseType == '1' ? '未采购' : '已采购';
  295. // }
  296. // },
  297. {
  298. prop: 'code',
  299. label: '销售订单号',
  300. slot: 'code',
  301. showOverflowTooltip: true,
  302. align: 'center',
  303. minWidth: 170,
  304. sortable: true
  305. },
  306. {
  307. prop: 'customerName',
  308. label: '客户名称',
  309. align: 'center',
  310. showOverflowTooltip: true
  311. },
  312. {
  313. prop: 'deliveryNum',
  314. label: '客户代号',
  315. align: 'center',
  316. showOverflowTooltip: true
  317. },
  318. {
  319. prop: 'productCode',
  320. label: '编码',
  321. align: 'center',
  322. showOverflowTooltip: true,
  323. minWidth: 140
  324. },
  325. {
  326. prop: 'productName',
  327. label: '名称',
  328. align: 'center',
  329. minWidth: 120
  330. },
  331. {
  332. prop: 'model',
  333. label: '型号',
  334. align: 'center',
  335. minWidth: 120
  336. },
  337. {
  338. prop: 'brandNo',
  339. label: '牌号',
  340. align: 'center'
  341. },
  342. {
  343. prop: 'deliveryTime',
  344. label: '交付日期',
  345. align: 'center',
  346. showOverflowTooltip: true
  347. },
  348. {
  349. prop: 'contractNum',
  350. label: '订单数量',
  351. align: 'center'
  352. },
  353. {
  354. prop: 'lackNum',
  355. label: '欠交数量',
  356. align: 'center'
  357. },
  358. {
  359. prop: 'bomId',
  360. label: '选择BOM版本',
  361. slot: 'bomId',
  362. align: 'center',
  363. minWidth: 110
  364. },
  365. this.type != 'detail'
  366. ? {
  367. columnKey: 'action',
  368. label: '操作',
  369. width: 150,
  370. align: 'center',
  371. resizable: false,
  372. slot: 'action',
  373. showOverflowTooltip: true
  374. }
  375. : ''
  376. ].filter(Boolean);
  377. return list;
  378. },
  379. columns2() {
  380. const list = [
  381. {
  382. columnKey: 'selection',
  383. type: 'selection',
  384. width: 50,
  385. align: 'center',
  386. fixed: 'left'
  387. },
  388. {
  389. width: 50,
  390. label: '序号',
  391. prop: 'sort',
  392. slot: 'sort',
  393. align: 'center'
  394. },
  395. {
  396. label: '物料名称',
  397. prop: 'name',
  398. align: 'center',
  399. minWidth: 120,
  400. fixed: 'left'
  401. },
  402. {
  403. label: '物料编码',
  404. prop: 'code',
  405. align: 'center',
  406. minWidth: 120,
  407. fixed: 'left'
  408. },
  409. {
  410. label: '牌号',
  411. prop: 'brandNum',
  412. align: 'center'
  413. },
  414. {
  415. prop: 'specification',
  416. label: '规格',
  417. align: 'center',
  418. showOverflowTooltip: true,
  419. minWidth: 110
  420. },
  421. {
  422. label: '型号',
  423. prop: 'modelType',
  424. align: 'center'
  425. },
  426. {
  427. prop: 'inventoryQuantity',
  428. label: '库存',
  429. showOverflowTooltip: true
  430. },
  431. {
  432. prop: 'secureInventory',
  433. label: '安全库存',
  434. showOverflowTooltip: true
  435. },
  436. {
  437. prop: 'lockQuantity',
  438. label: '锁库数量',
  439. showOverflowTooltip: true
  440. },
  441. {
  442. prop: 'inTransitNum',
  443. label: '在途数量',
  444. showOverflowTooltip: true
  445. },
  446. {
  447. prop: 'inTransitOrdersNum',
  448. label: '在途已关联数量',
  449. showOverflowTooltip: true
  450. },
  451. {
  452. prop: 'availableQuantity',
  453. label: '可用数量',
  454. showOverflowTooltip: true
  455. },
  456. {
  457. prop: 'unit',
  458. label: '计量单位',
  459. showOverflowTooltip: true,
  460. action: 'unit',
  461. slot: 'unit'
  462. },
  463. {
  464. label: '需求数量',
  465. slot: 'demandQuantity',
  466. action: 'demandQuantity',
  467. align: 'center',
  468. minWidth: 120
  469. },
  470. {
  471. label: '采购数量',
  472. slot: 'purchaseQuantity',
  473. action: 'purchaseQuantity',
  474. align: 'center',
  475. minWidth: 120
  476. },
  477. {
  478. label: '到货方式',
  479. slot: 'deliveryMethod',
  480. action: 'deliveryMethod',
  481. align: 'center',
  482. minWidth: 140
  483. },
  484. {
  485. label: '采购周期',
  486. slot: 'purchasingCycle',
  487. action: 'purchasingCycle',
  488. align: 'center',
  489. minWidth: 160
  490. },
  491. {
  492. label: '要求到货时间',
  493. slot: 'requireDeliveryTime',
  494. action: 'requireDeliveryTime',
  495. align: 'center',
  496. minWidth: 180
  497. },
  498. {
  499. label: '图纸',
  500. slot: 'imgUrl',
  501. action: ' imgUrl',
  502. align: 'center',
  503. minWidth: 140
  504. },
  505. {
  506. label: '附件',
  507. slot: 'files',
  508. action: ' files',
  509. align: 'center',
  510. minWidth: 140
  511. },
  512. this.type != 'detail'
  513. ? {
  514. columnKey: 'action',
  515. label: '操作',
  516. width: 70,
  517. align: 'center',
  518. resizable: false,
  519. slot: 'action',
  520. showOverflowTooltip: true
  521. }
  522. : ''
  523. ].filter(Boolean);
  524. return list;
  525. }
  526. },
  527. methods: {
  528. async open(type, row) {
  529. this.type = type;
  530. this.type = type;
  531. this.formData.demandType = '1';
  532. if (this.type == 'add') {
  533. this.formData.demandType = '1';
  534. }
  535. this.formData.orderType = 2;
  536. this.visible = true;
  537. if (row) {
  538. this.getDetail(row.id);
  539. } else {
  540. this.$nextTick(() => {
  541. this.$refs.table.setData([]);
  542. });
  543. }
  544. },
  545. getDetail(id) {
  546. getById(id).then((res) => {
  547. this.$set(this.formData, 'demandType', res.demandType);
  548. this.$set(this.formData, 'name', res.name);
  549. this.$set(this.formData, 'remark', res.remark);
  550. this.formData['id'] = res.id;
  551. if (res.salesOrderList) {
  552. this.$refs.table.setData([...res.salesOrderList]);
  553. // 展开所有行
  554. this.expandedRowKeys = this.$refs.table
  555. .getData()
  556. ?.map((item) => item.id);
  557. }
  558. this.$nextTick(() => {
  559. this.$refs.table.toggleRowExpansionAll();
  560. this.$forceUpdate();
  561. });
  562. });
  563. },
  564. produceAdd() {
  565. this.tableData = this.$refs.table.getData();
  566. this.$refs.produceOrderRef.open(this.tableData);
  567. },
  568. chooseOrder(list) {
  569. let planIds = [];
  570. list.map((m) => {
  571. planIds.push(m.id);
  572. delete m.id;
  573. return {
  574. ...m
  575. };
  576. });
  577. if (planIds.length > 0) {
  578. listBomByPlanIdsOverride({ planIds: planIds }).then((res) => {
  579. res.forEach((m) => {
  580. if (m.materialList.length > 0) {
  581. m.materialList.forEach((p) => {
  582. p.detailId = m.id;
  583. });
  584. }
  585. });
  586. this.$refs.table.setData([...this.tableData, ...res]);
  587. this.$nextTick(() => {
  588. this.$refs.table.toggleRowExpansionAll();
  589. this.$forceUpdate();
  590. });
  591. });
  592. }
  593. },
  594. categorySelect(row) {
  595. this.$refs.productRefs.open(row.materialList, row, this.type);
  596. },
  597. remove(row, index) {
  598. this.formData.detailRemoveIds.push(row.id);
  599. let _arr = this.$refs.table.getData() || [];
  600. _arr.splice(index, 1);
  601. this.$refs.table.setData([..._arr]);
  602. },
  603. chooseModal(data, current) {
  604. data.map((m) => {
  605. m.detailId = current.id;
  606. delete m.id;
  607. return {
  608. ...m
  609. };
  610. });
  611. let tableList = [];
  612. tableList = this.$refs.table.getData();
  613. tableList.forEach((e) => {
  614. if (e.id == current.id) {
  615. if (e.materialList.length == 0) {
  616. e.materialList = data;
  617. } else {
  618. e.materialList = [...e.materialList, ...data];
  619. }
  620. }
  621. });
  622. console.log(tableList);
  623. this.$refs.table.setData([...tableList]);
  624. this.$forceUpdate();
  625. },
  626. remove2(row) {
  627. const data = this.$refs.table.getData() ?? [];
  628. this.formData.materialRemoveIds.push(row.categoryId);
  629. data.forEach((e) => {
  630. if (row.detailId == e.id) {
  631. e.materialList = e.materialList.filter(
  632. (d) => d.categoryId !== row.categoryId
  633. );
  634. }
  635. });
  636. this.$refs.table.setData([...data]);
  637. this.$forceUpdate();
  638. },
  639. changeVersions(row) {
  640. console.log(row, 'row')
  641. listBomByBomVersionId({ bomId: row.bomId, contractNum: row.contractNum, demandType: this.formData.demandType, salesCode: row.code, salesId: row.id }).then(
  642. (res) => {
  643. row.materialList = res || [];
  644. }
  645. );
  646. },
  647. //选择-------------------
  648. openVersion(row) {
  649. this.xsId = row.id;
  650. this.$refs.versionRefs.open();
  651. },
  652. changeProduct(data) {
  653. let param = {
  654. salesOrderIds: [this.xsId],
  655. produceRoutingId: data.id
  656. };
  657. listBomBySalesOrderId(param).then((res) => {
  658. if (!res) return;
  659. const tableList = this.$refs.table.getData();
  660. tableList
  661. .forEach((e) => {
  662. if (e.id == this.xsId) {
  663. res.map((m) => {
  664. m.detailId = this.xsId;
  665. return {
  666. ...m
  667. };
  668. });
  669. e.materialList = res;
  670. this.$nextTick(() => {
  671. this.$refs.table.setData([...tableList]);
  672. this.$refs.table.toggleRowExpansionAll();
  673. });
  674. }
  675. })
  676. .catch((error) => {
  677. console.error('Failed to change product:', error);
  678. });
  679. });
  680. },
  681. // 处理表格选中行的变化
  682. handleSelectionChange(selection) {
  683. this.multipleSelection = selection;
  684. },
  685. handleCancel() {
  686. this.batchVisible = false
  687. },
  688. batchUpdateDeliveryMethod() {
  689. if (this.multipleSelection.length === 0) {
  690. this.$message.warning('请选择要修改的行');
  691. return;
  692. }
  693. this.formData2 = {
  694. deliveryMethod: 1,
  695. requireDeliveryTime: '',
  696. timeList: []
  697. };
  698. this.batchVisible = true;
  699. },
  700. handleMethod(row, index) {
  701. console.log(index, 'index')
  702. if (row) {
  703. this.multipleSelection = [];
  704. }
  705. this.$refs.timeDialogRef.open(row || {}, index);
  706. },
  707. chooseTime(current, timeList, currentIndex) {
  708. const tableList = this.$refs.table.getData();
  709. if (current && current.categoryId) {
  710. // 单独修改逻辑:直接操作当前物料的 timeList
  711. tableList.forEach(item => {
  712. if (item.id === current.detailId) {
  713. const material = item.materialList[currentIndex];
  714. this.$set(material, 'timeList', JSON.parse(JSON.stringify(timeList)));
  715. }
  716. });
  717. } else if (this.multipleSelection.length > 0) {
  718. // 批量修改逻辑
  719. tableList.forEach(item => {
  720. item.materialList.forEach(material => {
  721. if (this.multipleSelection.some(selected => selected.categoryId === material.categoryId)) {
  722. this.$set(material, 'deliveryMethod', this.formData2.deliveryMethod)
  723. this.$set(material, 'timeList', JSON.parse(JSON.stringify(timeList)));
  724. }
  725. });
  726. });
  727. this.$refs.timeDialogRef.handleClose()
  728. this.batchVisible = false;
  729. }
  730. this.$refs.table.setData([...tableList]);
  731. },
  732. handleConfirm() {
  733. const { deliveryMethod, requireDeliveryTime } = this.formData2;
  734. const tableData = this.$refs.table.getData();
  735. // 创建深拷贝的 timeList 模板(假设当前表单中已填写了分批时间)
  736. const timeListTemplate = JSON.parse(JSON.stringify(this.formData2.timeList));
  737. tableData.forEach((item) => {
  738. item.materialList.forEach((m) => {
  739. if (this.multipleSelection.some((selected) => selected.categoryId === m.categoryId)) {
  740. this.$set(m, 'deliveryMethod', deliveryMethod);
  741. if (deliveryMethod === 1) {
  742. //一次性到货逻辑
  743. this.$set(m, 'requireDeliveryTime', requireDeliveryTime)
  744. this.$set(m, 'timeList', null)
  745. } else if (deliveryMethod === 2) {
  746. this.$set(m, 'timeList', JSON.parse(JSON.stringify(timeListTemplate)));
  747. }
  748. }
  749. });
  750. });
  751. this.$refs.table.setData([...tableData]);
  752. this.batchVisible = false;
  753. },
  754. confirm() {
  755. this.$refs.formRef.validate(async (value) => {
  756. if (value) {
  757. let _arr = this.$refs.table.getData() ?? [];
  758. if (_arr.length == 0) {
  759. this.$message.info('请添加生产计划');
  760. return false;
  761. }
  762. let _arr2 = [];
  763. _arr2 = _arr.map((m) => {
  764. if (
  765. Object.prototype.hasOwnProperty.call(m, 'salesOrderId') &&
  766. m.salesOrderId
  767. ) {
  768. } else {
  769. m.salesOrderId = m.id;
  770. m.salesOrderCode = m.code;
  771. delete m.id;
  772. delete m.code;
  773. }
  774. return {
  775. ...m
  776. };
  777. });
  778. this.formData['type'] = 1;
  779. this.formData['salesOrderList'] = _arr2;
  780. this.formData.baitingType = 2;
  781. await save(this.formData);
  782. this.$message.success('保存成功!');
  783. this.$emit('success');
  784. this.cancel();
  785. }
  786. });
  787. },
  788. cancel() {
  789. this.visible = false;
  790. this.formData = {
  791. demandType: '1',
  792. name: '',
  793. remark: '',
  794. detailRemoveIds: [],
  795. materialRemoveIds: [],
  796. orderType: 2
  797. };
  798. this.$refs.table.setData([]);
  799. this.$refs.formRef.resetFields();
  800. },
  801. }
  802. };
  803. </script>
  804. <style lang="scss" scoped>
  805. :deep(.el-table__expanded-cell) {
  806. padding-bottom: 30px !important;
  807. border-bottom: 12px solid #ccffcc !important;
  808. }
  809. .batch-actions {
  810. text-align: right;
  811. margin: 10px;
  812. }
  813. </style>