index.vue 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086
  1. <template>
  2. <div class="tenant">
  3. <!-- <Banner /> -->
  4. <div class="content">
  5. <byTable
  6. :source="sourceList.data"
  7. :pagination="sourceList.pagination"
  8. :config="config"
  9. :loading="loading"
  10. highlight-current-row
  11. :selectConfig="selectConfig"
  12. :table-events="{
  13. //element talbe事件都能传
  14. select: selectRow,
  15. 'select-all': selectRow,
  16. }"
  17. :action-list="[
  18. {
  19. text: '出货',
  20. disabled: selectData.length === 0,
  21. action: () => openModalOne(),
  22. },
  23. {
  24. text: '产品装箱',
  25. action: () => openModal(),
  26. },
  27. ]"
  28. @get-list="getList"
  29. >
  30. <template #code="{ item }">
  31. <div>
  32. <div
  33. v-for="(item, index) in getData(item.codeAPName, 'code')"
  34. :key="index"
  35. >
  36. {{ item }}
  37. </div>
  38. </div>
  39. </template>
  40. <template #productName="{ item }">
  41. <div>
  42. <div
  43. v-for="(item, index) in getData(item.codeAPName, 'productName')"
  44. :key="index"
  45. >
  46. {{ item }}
  47. </div>
  48. </div>
  49. </template>
  50. <template #netWeight="{ item }">
  51. <div>
  52. <div v-for="(i, index) in item.dataJsonListCopy" :key="index">
  53. {{ i.netWeight + " kg" }}
  54. </div>
  55. </div>
  56. </template>
  57. <template #roughWeight="{ item }">
  58. <div>
  59. <div v-for="(i, index) in item.dataJsonListCopy" :key="index">
  60. {{ i.roughWeight + " kg" }}
  61. </div>
  62. </div>
  63. </template>
  64. <template #boxLong="{ item }">
  65. <div>
  66. <div v-for="(i, index) in item.dataJsonListCopy" :key="index">
  67. {{ i.boxLong + " cm" }}
  68. </div>
  69. </div>
  70. </template>
  71. <template #boxWide="{ item }">
  72. <div>
  73. <div v-for="(i, index) in item.dataJsonListCopy" :key="index">
  74. {{ i.boxWide + " cm" }}
  75. </div>
  76. </div>
  77. </template>
  78. <template #boxHigh="{ item }">
  79. <div>
  80. <div v-for="(i, index) in item.dataJsonListCopy" :key="index">
  81. {{ i.boxHigh + " cm" }}
  82. </div>
  83. </div>
  84. </template>
  85. <template #bomVolume="{ item }">
  86. <div>
  87. <div v-for="(i, index) in item.dataJsonListCopy" :key="index">
  88. {{ i.bomVolume + " m³" }}
  89. </div>
  90. </div>
  91. </template>
  92. </byTable>
  93. </div>
  94. <el-dialog
  95. title="产品装箱"
  96. v-model="dialogVisible"
  97. width="800"
  98. v-loading="loading"
  99. >
  100. <el-form
  101. :model="formData.data"
  102. :rules="rules"
  103. ref="formDom"
  104. label-position="top"
  105. >
  106. <el-row :gutter="10">
  107. <el-col :span="8">
  108. <el-form-item label="客户名称" prop="customerId">
  109. <el-select
  110. v-model="formData.data.customerId"
  111. placeholder="请选择"
  112. @change="handleChangeCustomer"
  113. filterable
  114. style="width: 100%"
  115. >
  116. <el-option
  117. v-for="item in customerList"
  118. :label="item.name"
  119. :value="item.id"
  120. >
  121. </el-option>
  122. </el-select>
  123. </el-form-item>
  124. </el-col>
  125. </el-row>
  126. <el-form-item label="选择合同" prop="contractIds">
  127. <el-select
  128. v-model="formData.data.contractIds"
  129. placeholder="请选择"
  130. @change="handleChangeContract"
  131. filterable
  132. style="width: 100%"
  133. multiple
  134. >
  135. <el-option
  136. v-for="item in contractData"
  137. :label="item.code"
  138. :value="item.id"
  139. >
  140. </el-option>
  141. </el-select>
  142. </el-form-item>
  143. <el-form-item label="合同明细" prop="contractProductData">
  144. <el-table
  145. :data="formData.data.contractProductData"
  146. @select="handleSelectProduct"
  147. @select-all="handleSelectProduct"
  148. ref="tableDom"
  149. >
  150. <el-table-column type="selection" label="" width="50" />
  151. <el-table-column prop="contractCode" label="合同编码" />
  152. <el-table-column prop="productName" label="产品名称" />
  153. <el-table-column prop="cpQuantity" label="合同数量" />
  154. <el-table-column prop="waitQuantity" label="待装箱数量" />
  155. <el-table-column prop="quantity" label="装箱数量" min-width="150">
  156. <template #default="{ row, $index }">
  157. <el-form-item
  158. :prop="'contractProductData.' + $index + '.quantity'"
  159. :inline-message="true"
  160. >
  161. <el-input-number
  162. v-model="row.quantity"
  163. :precision="4"
  164. :controls="false"
  165. :min="0"
  166. onmousewheel="return false;"
  167. />
  168. </el-form-item>
  169. </template>
  170. </el-table-column>
  171. </el-table>
  172. <el-button
  173. type="primary"
  174. style="margin-top: 10px; width: 100%"
  175. @click="handleClickPacking"
  176. >
  177. 装箱
  178. </el-button>
  179. </el-form-item>
  180. <el-form-item label="装箱明细" prop="packDetailList">
  181. <div
  182. class="box"
  183. v-for="(item, index) in formData.data.packDetailList"
  184. :key="index"
  185. >
  186. <div ref="">箱规</div>
  187. <el-row :gutter="10">
  188. <el-col :span="5">
  189. <el-form-item
  190. label="箱数"
  191. :prop="'packDetailList.' + index + '.packQuantity'"
  192. :rules="rules.packQuantity"
  193. >
  194. <el-input-number
  195. v-model="item.packQuantity"
  196. :precision="0"
  197. :controls="false"
  198. :min="1"
  199. placeholder="请输入"
  200. onmousewheel="return false;"
  201. @change="(val) => handleChangePackQuantity(val, index)"
  202. />
  203. </el-form-item>
  204. </el-col>
  205. <el-col :span="5">
  206. <el-form-item
  207. label="净重(kg)"
  208. :prop="'packDetailList.' + index + '.netWeight'"
  209. :rules="rules.netWeight"
  210. >
  211. <el-input-number
  212. v-model="item.netWeight"
  213. :precision="2"
  214. :controls="false"
  215. :min="0"
  216. placeholder="请输入"
  217. onmousewheel="return false;"
  218. />
  219. </el-form-item>
  220. </el-col>
  221. <el-col :span="5">
  222. <el-form-item
  223. label="毛重(kg)"
  224. :prop="'packDetailList.' + index + '.roughWeight'"
  225. :rules="rules.roughWeight"
  226. >
  227. <el-input-number
  228. v-model="item.roughWeight"
  229. :precision="2"
  230. :controls="false"
  231. :min="0"
  232. placeholder="请输入"
  233. onmousewheel="return false;"
  234. />
  235. </el-form-item>
  236. </el-col>
  237. <el-col :span="9">
  238. <el-row>
  239. <el-form-item label="尺寸(cm³)" required>
  240. <el-col :span="1"></el-col>
  241. <el-col :span="7">
  242. <el-form-item
  243. label=""
  244. :prop="'packDetailList.' + index + '.boxLong'"
  245. :rules="rules.boxLong"
  246. >
  247. <el-input-number
  248. v-model="item.boxLong"
  249. placeholder="长"
  250. :precision="2"
  251. :controls="false"
  252. :min="0"
  253. onmousewheel="return false;"
  254. ></el-input-number>
  255. </el-form-item>
  256. </el-col>
  257. <el-col :span="1" style="text-align: center"> * </el-col>
  258. <el-col :span="7">
  259. <el-form-item
  260. label=""
  261. :prop="'packDetailList.' + index + '.boxWide'"
  262. :rules="rules.boxWide"
  263. >
  264. <el-input-number
  265. v-model="item.boxWide"
  266. placeholder="宽"
  267. :precision="2"
  268. :controls="false"
  269. :min="0"
  270. onmousewheel="return false;"
  271. ></el-input-number>
  272. </el-form-item>
  273. </el-col>
  274. <el-col :span="1" style="text-align: center"> * </el-col>
  275. <el-col :span="7">
  276. <el-form-item
  277. label=""
  278. :prop="'packDetailList.' + index + '.boxHigh'"
  279. :rules="rules.boxHigh"
  280. >
  281. <el-input-number
  282. v-model="item.boxHigh"
  283. placeholder="高"
  284. :precision="2"
  285. :controls="false"
  286. :min="0"
  287. onmousewheel="return false;"
  288. ></el-input-number>
  289. </el-form-item>
  290. </el-col>
  291. </el-form-item>
  292. </el-row>
  293. </el-col>
  294. </el-row>
  295. <div class="line"></div>
  296. <el-form-item label="关联合同产品">
  297. <div class="flex-box">
  298. <div
  299. class="item"
  300. v-for="(product, j) in item.packDetailProductList"
  301. :key="j"
  302. >
  303. <div>合同编码:{{ product.contractCode }}</div>
  304. <div>产品名称:{{ product.productName }}</div>
  305. <div>每箱数量:{{ product.quantity }}</div>
  306. </div>
  307. </div>
  308. </el-form-item>
  309. <div
  310. class="bottom-arrow"
  311. v-show="!item.isShow"
  312. @click="item.isShow = !item.isShow"
  313. >
  314. <span style="margin-right: 5px"> 自定义装箱明细</span>
  315. <el-icon><ArrowDownBold /></el-icon>
  316. </div>
  317. <div
  318. class="bottom-arrow"
  319. v-show="item.isShow"
  320. @click="item.isShow = !item.isShow"
  321. >
  322. <span style="margin-right: 5px"> 收起</span>
  323. <el-icon><ArrowUpBold /></el-icon>
  324. </div>
  325. <el-form-item prop="packDetailGoodsList" v-show="item.isShow">
  326. <el-button
  327. type="primary"
  328. style="margin-bottom: 10px"
  329. @click="handleCustomPush(index)"
  330. >
  331. 添加行
  332. </el-button>
  333. <el-table :data="item.packDetailGoodsList">
  334. <el-table-column label="货物描述">
  335. <template #default="{ row, $index }">
  336. <el-form-item
  337. :prop="[
  338. 'packDetailList',
  339. index,
  340. 'packDetailGoodsList',
  341. $index,
  342. 'remark',
  343. ]"
  344. :rules="rules.remark"
  345. :inline-message="true"
  346. >
  347. <el-input v-model="row.remark" placeholder="请输入" />
  348. </el-form-item>
  349. </template>
  350. </el-table-column>
  351. <el-table-column label="单位" width="150">
  352. <template #default="{ row, $index }">
  353. <el-form-item
  354. :prop="[
  355. 'packDetailList',
  356. index,
  357. 'packDetailGoodsList',
  358. $index,
  359. 'unit',
  360. ]"
  361. :rules="rules.unit"
  362. :inline-message="true"
  363. >
  364. <el-input v-model="row.unit" placeholder="请输入" />
  365. </el-form-item>
  366. </template>
  367. </el-table-column>
  368. <el-table-column label="数量" width="150">
  369. <template #default="{ row, $index }">
  370. <el-form-item
  371. :prop="[
  372. 'packDetailList',
  373. index,
  374. 'packDetailGoodsList',
  375. $index,
  376. 'quantity',
  377. ]"
  378. :rules="rules.quantityOne"
  379. :inline-message="true"
  380. >
  381. <el-input-number
  382. v-model="row.quantity"
  383. :precision="4"
  384. :controls="false"
  385. :min="0"
  386. onmousewheel="return false;"
  387. />
  388. </el-form-item>
  389. </template>
  390. </el-table-column>
  391. <el-table-column prop="zip" label="操作" width="100">
  392. <template #default="{ $index }">
  393. <el-button
  394. type="primary"
  395. link
  396. @click="handleCustomRemove(index, $index)"
  397. >删除</el-button
  398. >
  399. </template>
  400. </el-table-column>
  401. </el-table>
  402. </el-form-item>
  403. </div>
  404. </el-form-item>
  405. </el-form>
  406. <template #footer>
  407. <el-button @click="handleClose" size="large">取 消</el-button>
  408. <el-button
  409. type="primary"
  410. @click="submitForm()"
  411. size="large"
  412. :loading="submitLoading"
  413. >
  414. 确 定
  415. </el-button>
  416. </template>
  417. </el-dialog>
  418. <el-dialog
  419. title="合并出货"
  420. v-model="dialogVisibleOne"
  421. width="400"
  422. v-loading="loadingOne"
  423. >
  424. <byForm
  425. :formConfig="formConfig"
  426. :formOption="formOption"
  427. v-model="formData.dataOne"
  428. :rules="rules"
  429. ref="byform"
  430. >
  431. </byForm>
  432. <template #footer>
  433. <el-button @click="dialogVisibleOne = false" size="large"
  434. >取 消</el-button
  435. >
  436. <el-button
  437. type="primary"
  438. @click="submitFormOne()"
  439. size="large"
  440. :loading="submitLoading"
  441. >
  442. 确 定
  443. </el-button>
  444. </template>
  445. </el-dialog>
  446. </div>
  447. </template>
  448. <script setup>
  449. /* eslint-disable vue/no-unused-components */
  450. import { ElMessage, ElMessageBox } from "element-plus";
  451. import byTable from "@/components/byTable/index";
  452. import byForm from "@/components/byForm/index";
  453. import FileUpload from "@/components/FileUpload/index";
  454. import { computed, defineComponent, ref } from "vue";
  455. import { getToken } from "@/utils/auth";
  456. const uploadFileUrl = ref(import.meta.env.VITE_APP_BASE_API + "/common/upload"); // 上传文件服务器地址
  457. const headers = ref({ Authorization: "Bearer " + getToken() });
  458. const uploadData = ref({});
  459. const loading = ref(false);
  460. const loadingOne = ref(false);
  461. const submitLoading = ref(false);
  462. const sourceList = ref({
  463. data: [],
  464. pagination: {
  465. total: 3,
  466. pageNum: 1,
  467. pageSize: 10,
  468. status: "",
  469. },
  470. });
  471. let dialogVisible = ref(false);
  472. let dialogVisibleOne = ref(false);
  473. let modalType = ref("add");
  474. let fileList = ref([]);
  475. let rules = ref({
  476. contractIds: [{ required: true, message: "请选择合同", trigger: "change" }],
  477. packQuantity: [{ required: true, message: "请输入箱数", trigger: "blur" }],
  478. netWeight: [{ required: true, message: "请输入净重", trigger: "blur" }],
  479. roughWeight: [{ required: true, message: "请输入毛重", trigger: "blur" }],
  480. boxLong: [{ required: true, message: "请输入长", trigger: "blur" }],
  481. boxWide: [{ required: true, message: "请输入宽", trigger: "blur" }],
  482. boxHigh: [{ required: true, message: "请输入高", trigger: "blur" }],
  483. quantity: [{ required: true, message: "请输入装箱数量", trigger: "blur" }],
  484. quantityOne: [{ required: true, message: "请输入数量", trigger: "blur" }],
  485. unit: [{ required: true, message: "请输入单位", trigger: "blur" }],
  486. remark: [{ required: true, message: "请输入货物描述", trigger: "blur" }],
  487. contractId: [{ required: true, message: "请选择主合同", trigger: "change" }],
  488. });
  489. const { proxy } = getCurrentInstance();
  490. const selectConfig = reactive([
  491. {
  492. label: "出货状态",
  493. prop: "shipmentStatus",
  494. data: [
  495. {
  496. label: "未出货",
  497. value: "0",
  498. },
  499. {
  500. label: "已出货",
  501. value: "1",
  502. },
  503. ],
  504. },
  505. ]);
  506. const config = computed(() => {
  507. return [
  508. {
  509. type: "selection",
  510. attrs: {
  511. checkAtt: "isCheck",
  512. },
  513. },
  514. {
  515. attrs: {
  516. label: "合同号",
  517. prop: "codeAPName",
  518. slot: "code",
  519. },
  520. },
  521. {
  522. attrs: {
  523. label: "产品名称",
  524. prop: "codeAPName",
  525. slot: "productName",
  526. },
  527. },
  528. {
  529. attrs: {
  530. label: "总箱数",
  531. prop: "packQuantity",
  532. width: 90,
  533. },
  534. },
  535. {
  536. attrs: {
  537. label: "净重",
  538. slot: "netWeight",
  539. width: 90,
  540. },
  541. },
  542. {
  543. attrs: {
  544. label: "毛重",
  545. slot: "roughWeight",
  546. width: 90,
  547. },
  548. },
  549. {
  550. attrs: {
  551. label: "长",
  552. slot: "boxLong",
  553. width: 90,
  554. },
  555. },
  556. {
  557. attrs: {
  558. label: "宽",
  559. slot: "boxWide",
  560. width: 90,
  561. },
  562. },
  563. {
  564. attrs: {
  565. label: "高",
  566. slot: "boxHigh",
  567. width: 90,
  568. },
  569. },
  570. {
  571. attrs: {
  572. label: "体积",
  573. slot: "bomVolume",
  574. width: 90,
  575. },
  576. },
  577. {
  578. attrs: {
  579. label: "总净重",
  580. prop: "netWeight",
  581. width: 120,
  582. },
  583. render(netWeight) {
  584. return netWeight + " kg";
  585. },
  586. },
  587. {
  588. attrs: {
  589. label: "总毛重",
  590. prop: "roughWeight",
  591. width: 120,
  592. },
  593. render(roughWeight) {
  594. return roughWeight + " kg";
  595. },
  596. },
  597. {
  598. attrs: {
  599. label: "总体积",
  600. prop: "bomVolume",
  601. width: 120,
  602. },
  603. render(bomVolume) {
  604. return bomVolume + " m³";
  605. },
  606. },
  607. {
  608. attrs: {
  609. label: "出货状态",
  610. prop: "shipmentStatus",
  611. width: 90,
  612. },
  613. render(status) {
  614. return status == 1 ? "已出货" : status == 0 ? "未出货" : "";
  615. },
  616. },
  617. {
  618. attrs: {
  619. label: "出货时间",
  620. prop: "shipmentTime",
  621. width: 155,
  622. },
  623. render(shipmentTime) {
  624. if (shipmentTime) {
  625. return shipmentTime.slice(5, 10);
  626. } else {
  627. return "";
  628. }
  629. },
  630. },
  631. {
  632. attrs: {
  633. label: "操作",
  634. width: "90",
  635. align: "center",
  636. },
  637. // 渲染 el-button,一般用在最后一列。
  638. renderHTML(row) {
  639. return [
  640. // {
  641. // attrs: {
  642. // label: "打印",
  643. // type: "primary",
  644. // text: true,
  645. // },
  646. // el: "button",
  647. // click() {
  648. // getDtl(row);
  649. // },
  650. // },
  651. // {
  652. // attrs: {
  653. // label: "删除",
  654. // type: "primary",
  655. // text: true,
  656. // disabled: row.status != 30,
  657. // },
  658. // el: "button",
  659. // click() {
  660. // ElMessageBox.confirm(
  661. // "此操作将永久作废该数据, 是否继续?",
  662. // "提示",
  663. // {
  664. // confirmButtonText: "确定",
  665. // cancelButtonText: "取消",
  666. // type: "warning",
  667. // }
  668. // ).then(() => {
  669. // // 删除
  670. // proxy
  671. // .post("/subscribeDetail/edit", {
  672. // ...row,
  673. // status: 99,
  674. // })
  675. // .then((res) => {
  676. // ElMessage({
  677. // message: "作废成功",
  678. // type: "success",
  679. // });
  680. // getList();
  681. // });
  682. // });
  683. // },
  684. // },
  685. ];
  686. },
  687. },
  688. ];
  689. });
  690. const formDom = ref(null);
  691. let formData = reactive({
  692. data: {},
  693. dataOne: {},
  694. });
  695. const formOption = reactive({
  696. inline: true,
  697. labelWidth: 100,
  698. itemWidth: 100,
  699. rules: [],
  700. });
  701. const byform = ref(null);
  702. const treeData = ref([]);
  703. const formConfig = reactive([
  704. {
  705. type: "select",
  706. prop: "contractId",
  707. label: "主合同",
  708. required: true,
  709. data: [],
  710. },
  711. ]);
  712. const getList = async (req) => {
  713. selectData.value = [];
  714. sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
  715. loading.value = true;
  716. proxy.post("/packDetail/page", sourceList.value.pagination).then((res) => {
  717. for (let i = 0; i < res.rows.length; i++) {
  718. const e = res.rows[i];
  719. e.isCheck = e.shipmentStatus == 1 ? false : true;
  720. let arr = [];
  721. let newArr = [];
  722. arr = e.dataJsonList.split("_");
  723. for (let j = 0; j < arr.length; j++) {
  724. const jele = arr[j];
  725. const jarr = jele.split(",");
  726. const obj = {
  727. bomVolume: jarr[0],
  728. boxLong: jarr[1],
  729. boxWide: jarr[2],
  730. boxHigh: jarr[3],
  731. roughWeight: jarr[4],
  732. netWeight: jarr[5],
  733. };
  734. let createArr = new Array(Number(jarr[6])).fill(obj);
  735. newArr = [...newArr, ...createArr];
  736. }
  737. e.dataJsonListCopy = newArr;
  738. }
  739. sourceList.value.data = res.rows;
  740. sourceList.value.pagination.total = res.total;
  741. loading.value = false;
  742. });
  743. };
  744. const openModal = () => {
  745. modalType.value = "add";
  746. formData.data = {
  747. packDetailList: [],
  748. contractIds: [],
  749. };
  750. dialogVisible.value = true;
  751. handleChangeCustomer("");
  752. };
  753. const openModalOne = () => {
  754. formData.dataOne = {
  755. ids: [],
  756. contractId: "",
  757. };
  758. let ids = []; //合同id
  759. let idsOne = []; //包装id
  760. const list = selectData.value;
  761. for (let i = 0; i < list.length; i++) {
  762. const e = list[i];
  763. ids = [...ids, ...e.contractIds.split(",")];
  764. idsOne = [...idsOne, ...e.ids.split(",")];
  765. }
  766. formData.dataOne.ids = idsOne;
  767. proxy.post(`/contract/getByIds`, ids).then((res) => {
  768. formConfig[0].data = res.map((x) => ({
  769. label: x.code,
  770. value: x.id,
  771. }));
  772. dialogVisibleOne.value = true;
  773. });
  774. };
  775. const submitForm = () => {
  776. formDom.value.validate((vaild) => {
  777. if (vaild) {
  778. if (!formData.data.packDetailList.length > 0) {
  779. return ElMessage({
  780. message: "请添加装箱明细!",
  781. type: "info",
  782. });
  783. }
  784. submitLoading.value = true;
  785. loadingOne.value = true;
  786. for (let i = 0; i < formData.data.packDetailList.length; i++) {
  787. const e = formData.data.packDetailList[i];
  788. e.bomVolume = (e.boxLong * e.boxWide * e.boxHigh) / 1000000;
  789. }
  790. formData.data.contractIds = formData.data.contractIds.join(",");
  791. proxy.post("/pack/" + modalType.value, formData.data).then(
  792. (res) => {
  793. ElMessage({
  794. message: modalType.value == "add" ? "添加成功" : "编辑成功",
  795. type: "success",
  796. });
  797. dialogVisible.value = false;
  798. submitLoading.value = false;
  799. loadingOne.value = false;
  800. getList();
  801. },
  802. (err) => {
  803. submitLoading.value = false;
  804. loading.value = false;
  805. }
  806. );
  807. }
  808. });
  809. };
  810. const table = ref(null);
  811. const submitFormOne = () => {
  812. byform.value.handleSubmit((valid) => {
  813. loading.value = true;
  814. submitLoading.value = true;
  815. proxy.post("/packDetail/shipment", formData.dataOne).then(
  816. (res) => {
  817. ElMessage({
  818. message: "出货成功",
  819. type: "success",
  820. });
  821. dialogVisibleOne.value = false;
  822. submitLoading.value = false;
  823. loading.value = false;
  824. getList();
  825. selectData.value = [];
  826. },
  827. (err) => {
  828. submitLoading.value = false;
  829. loading.value = false;
  830. }
  831. );
  832. });
  833. };
  834. const selectData = ref([]);
  835. const selectRow = (data) => {
  836. selectData.value = data;
  837. };
  838. const selectProductData = ref([]);
  839. const handleSelectProduct = (data) => {
  840. selectProductData.value = data;
  841. };
  842. const tableDom = ref(null);
  843. const handleClickPacking = () => {
  844. if (selectProductData.value.length > 0) {
  845. const list = selectProductData.value;
  846. for (let i = 0; i < list.length; i++) {
  847. const e = list[i];
  848. if (!e.quantity) {
  849. return ElMessage({
  850. message: "请输入装箱数量",
  851. type: "info",
  852. });
  853. }
  854. }
  855. for (let i = 0; i < list.length; i++) {
  856. const e = list[i];
  857. for (let j = 0; j < formData.data.contractProductData.length; j++) {
  858. const jele = formData.data.contractProductData[j];
  859. if (e.id === jele.id && e.quantity > Number(jele.waitQuantity)) {
  860. return ElMessage({
  861. message: "装箱数量不可大于袋装箱数量",
  862. type: "info",
  863. });
  864. }
  865. }
  866. }
  867. const packDetailProductList = list.map((x) => ({
  868. contractCode: x.contractCode,
  869. contractId: x.contractId,
  870. contractProductId: x.id,
  871. quantity: x.quantity,
  872. productId: x.productId,
  873. productName: x.productName,
  874. }));
  875. const customerId = formData.data.customerId ? formData.data.customerId : "";
  876. const contractIds = formData.data.contractIds
  877. ? formData.data.contractIds.join(",")
  878. : "";
  879. let item = {
  880. customerId: customerId,
  881. contractIds: contractIds,
  882. packQuantity: 1,
  883. netWeight: null,
  884. roughWeight: null,
  885. boxLong: null,
  886. boxWide: null,
  887. boxHigh: null,
  888. bomVolume: "",
  889. remark: "",
  890. packDetailGoodsList: [],
  891. packDetailProductList: packDetailProductList,
  892. isShow: false,
  893. };
  894. formData.data.packDetailList.push(item);
  895. handleChangePackQuantity(
  896. item.packQuantity,
  897. formData.data.packDetailList.length - 1
  898. );
  899. tableDom.value.clearSelection();
  900. selectProductData.value = [];
  901. table.value.clearSelection();
  902. } else {
  903. return ElMessage({
  904. message: "请选择产品 !",
  905. type: "info",
  906. });
  907. }
  908. };
  909. const handleChangePackQuantity = (val, index) => {
  910. const obj = {};
  911. for (let i = 0; i < formData.data.contractProductData.length; i++) {
  912. const e = formData.data.contractProductData[i];
  913. obj[e.contractId + "_" + e.productId + ""] =
  914. Number(e.cpQuantity) - Number(e.sumPackQuantity);
  915. }
  916. // 计算数量 即装箱数量 * 箱数 新增字段放在最外层
  917. for (let i = 0; i < formData.data.packDetailList.length; i++) {
  918. const ele = formData.data.packDetailList[i];
  919. for (let j = 0; j < ele.packDetailProductList.length; j++) {
  920. const jele = ele.packDetailProductList[j];
  921. ele[jele.contractId + "_" + jele.productId + ""] =
  922. Number(ele.packQuantity) * jele.quantity;
  923. }
  924. }
  925. // 计算新的待装箱数量
  926. for (let i = 0; i < formData.data.packDetailList.length; i++) {
  927. const e = formData.data.packDetailList[i];
  928. for (const key in obj) {
  929. if (e.hasOwnProperty(key)) {
  930. obj[key] = obj[key] - e[key];
  931. if (obj[key] < 0) {
  932. e.packQuantity = null;
  933. handleChangePackQuantity(null, index);
  934. return ElMessage({
  935. message: "装箱数量 * 箱数不可大于待装箱数量",
  936. type: "info",
  937. });
  938. }
  939. }
  940. }
  941. }
  942. // 赋值
  943. for (let i = 0; i < formData.data.contractProductData.length; i++) {
  944. const e = formData.data.contractProductData[i];
  945. for (const key in obj) {
  946. if (e.contractId + "_" + e.productId + "" === key) {
  947. e.waitQuantity = obj[key];
  948. }
  949. }
  950. }
  951. // }
  952. };
  953. const handleCustomPush = (index) => {
  954. formData.data.packDetailList[index].packDetailGoodsList.push({
  955. unit: "",
  956. quantity: "",
  957. remark: "",
  958. });
  959. };
  960. const handleCustomRemove = (index, sonIndex) => {
  961. formData.data.packDetailList[index].packDetailGoodsList.splice(sonIndex, 1);
  962. };
  963. const customerList = ref([]);
  964. const getSelectData = () => {
  965. proxy.post("/customer/page", { pageNum: 1, pageSize: 999 }).then((res) => {
  966. customerList.value = res.rows.map((item) => {
  967. return {
  968. ...item,
  969. label: item.name,
  970. value: item.id,
  971. };
  972. });
  973. });
  974. };
  975. const contractData = ref([]);
  976. const handleChangeCustomer = (val) => {
  977. proxy
  978. .get(`/contract/getNoPackContractByCustomerId?customerId=${val}`)
  979. .then((res) => {
  980. contractData.value = res.data;
  981. formData.data.contractIds = [];
  982. });
  983. };
  984. const handleChangeContract = (val) => {
  985. const customerId = formData.data.customerId ? formData.data.customerId : "";
  986. proxy
  987. .get(
  988. `/contractProduct/getNoPackContractProductById?customerId=${customerId}&contractIds=${val}`
  989. )
  990. .then((res) => {
  991. formData.data.contractProductData = res.data.map((x) => ({
  992. ...x,
  993. waitQuantity: Number(x.cpQuantity) - Number(x.sumPackQuantity),
  994. quantity: null,
  995. }));
  996. handleChangePackQuantity();
  997. });
  998. };
  999. const getData = (data, type) => {
  1000. if (!data) return [];
  1001. const arr = data.split(",");
  1002. if (arr && arr.length > 0) {
  1003. const arrOne = [];
  1004. for (let i = 0; i < arr.length; i++) {
  1005. const e = arr[i];
  1006. if (type === "code") {
  1007. arrOne.push(e.split("_")[0]);
  1008. } else if (type === "productName") {
  1009. arrOne.push(e.split("_")[1]);
  1010. }
  1011. }
  1012. return arrOne;
  1013. }
  1014. return [];
  1015. };
  1016. const handleClose = () => {
  1017. dialogVisible.value = false;
  1018. selectProductData.value = [];
  1019. };
  1020. getSelectData();
  1021. getList();
  1022. </script>
  1023. <style lang="scss" scoped>
  1024. .tenant {
  1025. padding: 20px;
  1026. }
  1027. :deep(.el-collapse-item__header) {
  1028. background-color: #fde6c8;
  1029. border: none;
  1030. }
  1031. :deep(.el-collapse-item__wrap) {
  1032. background-color: #fde6c8;
  1033. border: none;
  1034. }
  1035. .box {
  1036. padding: 15px;
  1037. background: #fde6c8;
  1038. border: 1px solid #7fb5e3;
  1039. margin-bottom: 10px;
  1040. .flex-box {
  1041. width: 100%;
  1042. display: flex;
  1043. flex-wrap: wrap;
  1044. .item {
  1045. width: 50%;
  1046. margin-bottom: 10px;
  1047. div {
  1048. line-height: 22px;
  1049. }
  1050. }
  1051. }
  1052. .line {
  1053. width: 100%;
  1054. height: 1px;
  1055. background: #7fb5e3;
  1056. margin: 20px 0;
  1057. }
  1058. .bottom-arrow {
  1059. text-align: center;
  1060. cursor: pointer;
  1061. color: #0084ff;
  1062. }
  1063. }
  1064. </style>