index.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617
  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: () => openModal(),
  22. },
  23. {
  24. text: '产品装箱',
  25. action: () => openModal(),
  26. },
  27. ]"
  28. @get-list="getList"
  29. >
  30. <template #fileSlot="{ item }">
  31. <div
  32. style="cursor: pointer; color: #409eff"
  33. @click="handleClickFile(item)"
  34. >
  35. {{ item.fileName }}
  36. </div>
  37. </template>
  38. </byTable>
  39. </div>
  40. <el-dialog
  41. title="产品装箱"
  42. v-model="dialogVisible"
  43. width="800"
  44. v-loading="loading"
  45. >
  46. <el-form
  47. :model="formData.data"
  48. :rules="rules"
  49. ref="formDom"
  50. label-position="top"
  51. >
  52. <el-row :gutter="10">
  53. <el-col :span="8">
  54. <el-form-item label="客户名称" prop="customerId">
  55. <el-select
  56. v-model="formData.data.customerId"
  57. placeholder="请选择"
  58. @change="handleChangeCustomer"
  59. filterable
  60. style="width: 100%"
  61. >
  62. <el-option
  63. v-for="item in customerList"
  64. :label="item.name"
  65. :value="item.id"
  66. >
  67. </el-option>
  68. </el-select>
  69. </el-form-item>
  70. </el-col>
  71. </el-row>
  72. <el-form-item label="选择合同" prop="contractIds">
  73. <el-select
  74. v-model="formData.data.contractIds"
  75. placeholder="请选择"
  76. @change="handleChangeContract"
  77. filterable
  78. style="width: 100%"
  79. >
  80. <el-option
  81. v-for="item in contractData"
  82. :label="item.code"
  83. :value="item.id"
  84. >
  85. </el-option>
  86. </el-select>
  87. </el-form-item>
  88. <el-form-item label="合同明细" prop="contractProductData">
  89. <el-table :data="contractProductData" @select="handleSelectProduct">
  90. <el-table-column type="selection" label="" width="50" />
  91. <el-table-column prop="code" label="合同编码" />
  92. <el-table-column prop="productName" label="产品名称" />
  93. <el-table-column prop="cpQuantity" label="合同数量" />
  94. <el-table-column prop="waitQuantity" label="待装箱数量" />
  95. <el-table-column prop="quantity" label="装箱数量" min-width="150">
  96. <template #default="{ row, $index }">
  97. <el-form-item
  98. :prop="'contractProductData.' + $index + '.quantity'"
  99. :rules="rules.quantity"
  100. :inline-message="true"
  101. >
  102. <el-input-number
  103. v-model="row.quantity"
  104. :precision="4"
  105. :controls="false"
  106. :min="0"
  107. />
  108. </el-form-item>
  109. </template>
  110. </el-table-column>
  111. </el-table>
  112. <el-button
  113. type="primary"
  114. style="margin-top: 10px; width: 100%"
  115. @click="handleClickPacking"
  116. >
  117. 装箱
  118. </el-button>
  119. </el-form-item>
  120. <el-form-item label="装箱明细">
  121. <div class="box">
  122. <div ref="">箱规</div>
  123. <el-row :gutter="10">
  124. <el-col :span="5">
  125. <el-form-item label="箱数" prop="supplyId">
  126. <el-input
  127. v-model="formData.data.a"
  128. placeholder="请输入"
  129. ></el-input>
  130. </el-form-item>
  131. </el-col>
  132. <el-col :span="5">
  133. <el-form-item label="净重(kg)" prop="supplyId">
  134. <el-input
  135. v-model="formData.data.a"
  136. placeholder="请输入"
  137. ></el-input>
  138. </el-form-item>
  139. </el-col>
  140. <el-col :span="5">
  141. <el-form-item label="毛重(kg)" prop="supplyId">
  142. <el-input
  143. v-model="formData.data.a"
  144. placeholder="请输入"
  145. ></el-input>
  146. </el-form-item>
  147. </el-col>
  148. <el-col :span="9">
  149. <el-row>
  150. <el-form-item label="尺寸(cm³)" required>
  151. <el-col :span="1"></el-col>
  152. <el-col :span="7">
  153. <el-input
  154. v-model="formData.data.a"
  155. placeholder="长"
  156. ></el-input>
  157. </el-col>
  158. <el-col :span="1" style="text-align: center"> * </el-col>
  159. <el-col :span="7">
  160. <el-input
  161. v-model="formData.data.a"
  162. placeholder="宽"
  163. ></el-input>
  164. </el-col>
  165. <el-col :span="1" style="text-align: center"> * </el-col>
  166. <el-col :span="7">
  167. <el-input
  168. v-model="formData.data.a"
  169. placeholder="高"
  170. ></el-input>
  171. </el-col>
  172. </el-form-item>
  173. </el-row>
  174. </el-col>
  175. </el-row>
  176. <div class="line"></div>
  177. <el-form-item label="关联合同产品">
  178. <div class="flex-box">
  179. <div class="item">
  180. <div>合同编码:PO-2301-001</div>
  181. <div>产品名称:PO-2301-001</div>
  182. <div>每箱数量:PO-2301-001</div>
  183. </div>
  184. </div>
  185. </el-form-item>
  186. <div class="bottom-arrow" v-show="fade">
  187. <span style="margin-right: 5px"> 自定义装箱明细</span>
  188. <el-icon><ArrowDownBold /></el-icon>
  189. </div>
  190. <div class="bottom-arrow" v-show="true">
  191. <span style="margin-right: 5px"> 收起</span>
  192. <el-icon><ArrowUpBold /></el-icon>
  193. </div>
  194. <el-form-item prop="自定义装箱">
  195. <el-button type="primary" style="margin-bottom: 10px">
  196. 添加行
  197. </el-button>
  198. <el-table :data="formData.data.purchaseDetailList">
  199. <el-table-column prop="count" label="货物描述">
  200. <template #default="{ row, $index }">
  201. <el-form-item
  202. :prop="'purchaseDetailList.' + $index + '.count'"
  203. :rules="rules.count"
  204. :inline-message="true"
  205. >
  206. <el-input v-model="row.count" placeholder="请输入" />
  207. </el-form-item>
  208. </template>
  209. </el-table-column>
  210. <el-table-column prop="count" label="单位" width="150">
  211. <template #default="{ row, $index }">
  212. <el-form-item
  213. :prop="'purchaseDetailList.' + $index + '.count'"
  214. :rules="rules.count"
  215. :inline-message="true"
  216. >
  217. <el-input-number
  218. v-model="row.count"
  219. :precision="4"
  220. :controls="false"
  221. :min="0"
  222. />
  223. </el-form-item>
  224. </template>
  225. </el-table-column>
  226. <el-table-column prop="count" label="数量" width="150">
  227. <template #default="{ row, $index }">
  228. <el-form-item
  229. :prop="'purchaseDetailList.' + $index + '.count'"
  230. :rules="rules.count"
  231. :inline-message="true"
  232. >
  233. <el-input-number
  234. v-model="row.count"
  235. :precision="4"
  236. :controls="false"
  237. :min="0"
  238. />
  239. </el-form-item>
  240. </template>
  241. </el-table-column>
  242. <el-table-column prop="zip" label="操作" width="100">
  243. <template #default="{ $index }">
  244. <el-button type="primary" link @click="handleRemove($index)"
  245. >删除</el-button
  246. >
  247. </template>
  248. </el-table-column>
  249. </el-table>
  250. </el-form-item>
  251. </div>
  252. </el-form-item>
  253. </el-form>
  254. <template #footer>
  255. <el-button @click="dialogVisible = false" size="large">取 消</el-button>
  256. <el-button
  257. type="primary"
  258. @click="submitForm('byform')"
  259. size="large"
  260. :loading="submitLoading"
  261. >
  262. 确 定
  263. </el-button>
  264. </template>
  265. </el-dialog>
  266. </div>
  267. </template>
  268. <script setup>
  269. /* eslint-disable vue/no-unused-components */
  270. import { ElMessage, ElMessageBox } from "element-plus";
  271. import byTable from "@/components/byTable/index";
  272. import byForm from "@/components/byForm/index";
  273. import FileUpload from "@/components/FileUpload/index";
  274. import { computed, defineComponent, ref } from "vue";
  275. import { getToken } from "@/utils/auth";
  276. const uploadFileUrl = ref(import.meta.env.VITE_APP_BASE_API + "/common/upload"); // 上传文件服务器地址
  277. const headers = ref({ Authorization: "Bearer " + getToken() });
  278. const uploadData = ref({});
  279. const loading = ref(false);
  280. const submitLoading = ref(false);
  281. const sourceList = ref({
  282. data: [],
  283. pagination: {
  284. total: 3,
  285. pageNum: 1,
  286. pageSize: 10,
  287. status: "",
  288. },
  289. });
  290. let dialogVisible = ref(false);
  291. let modalType = ref("add");
  292. let fileList = ref([]);
  293. let rules = ref({
  294. quantity: [{ required: true, message: "请输入装箱数量", trigger: "blur" }],
  295. });
  296. const { proxy } = getCurrentInstance();
  297. const selectConfig = reactive([
  298. {
  299. label: "出货状态",
  300. prop: "shipmentStatus",
  301. data: [
  302. {
  303. label: "未出货",
  304. value: "0",
  305. },
  306. {
  307. label: "出货",
  308. value: "1",
  309. },
  310. ],
  311. },
  312. ]);
  313. const config = computed(() => {
  314. return [
  315. {
  316. type: "selection",
  317. // attrs: {
  318. // checkAtt: "isCheck",
  319. // },
  320. },
  321. {
  322. attrs: {
  323. label: "合同号",
  324. prop: "subscribeCode",
  325. },
  326. },
  327. {
  328. attrs: {
  329. label: "产品名称",
  330. prop: "subscribeCode",
  331. },
  332. },
  333. {
  334. attrs: {
  335. label: "总箱数",
  336. prop: "packQuantity",
  337. },
  338. },
  339. {
  340. attrs: {
  341. label: "净重",
  342. prop: "netWeight",
  343. },
  344. },
  345. {
  346. attrs: {
  347. label: "毛重",
  348. prop: "roughWeight",
  349. },
  350. },
  351. {
  352. attrs: {
  353. label: "长",
  354. prop: "boxLong",
  355. },
  356. },
  357. {
  358. attrs: {
  359. label: "宽",
  360. prop: "boxWide",
  361. },
  362. },
  363. {
  364. attrs: {
  365. label: "高",
  366. prop: "boxHigh",
  367. },
  368. },
  369. {
  370. attrs: {
  371. label: "总体积",
  372. prop: "bomVolume",
  373. },
  374. },
  375. {
  376. attrs: {
  377. label: "出货状态",
  378. prop: "shipmentStatus",
  379. },
  380. render(status) {
  381. return status == 1 ? "出货" : "未出货";
  382. },
  383. },
  384. {
  385. attrs: {
  386. label: "操作",
  387. width: "200",
  388. align: "right",
  389. },
  390. // 渲染 el-button,一般用在最后一列。
  391. renderHTML(row) {
  392. return [
  393. {
  394. attrs: {
  395. label: "打印",
  396. type: "primary",
  397. text: true,
  398. },
  399. el: "button",
  400. click() {
  401. getDtl(row);
  402. },
  403. },
  404. {
  405. attrs: {
  406. label: "删除",
  407. type: "danger",
  408. text: true,
  409. disabled: row.status != 30,
  410. },
  411. el: "button",
  412. click() {
  413. // 弹窗提示是否删除
  414. ElMessageBox.confirm(
  415. "此操作将永久作废该数据, 是否继续?",
  416. "提示",
  417. {
  418. confirmButtonText: "确定",
  419. cancelButtonText: "取消",
  420. type: "warning",
  421. }
  422. ).then(() => {
  423. // 删除
  424. proxy
  425. .post("/subscribeDetail/edit", {
  426. ...row,
  427. status: 99,
  428. })
  429. .then((res) => {
  430. ElMessage({
  431. message: "作废成功",
  432. type: "success",
  433. });
  434. getList();
  435. });
  436. });
  437. },
  438. },
  439. ];
  440. },
  441. },
  442. ];
  443. });
  444. let formData = reactive({
  445. data: {},
  446. });
  447. const getList = async (req) => {
  448. sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
  449. loading.value = true;
  450. proxy
  451. .post("/packDetail/page", sourceList.value.pagination)
  452. .then((message) => {
  453. console.log(message);
  454. sourceList.value.data = message.rows.map((x) => ({
  455. ...x,
  456. ...JSON.parse(x.victoriatouristJson),
  457. }));
  458. sourceList.value.pagination.total = message.total;
  459. setTimeout(() => {
  460. loading.value = false;
  461. }, 200);
  462. });
  463. };
  464. const openModal = () => {
  465. formData.data = {};
  466. dialogVisible.value = true;
  467. handleChangeCustomer("");
  468. };
  469. const submitForm = () => {
  470. byform.value.handleSubmit((valid) => {
  471. formData.data.fileList = fileList.value;
  472. submitLoading.value = true;
  473. proxy.post("/productionProcesses/" + modalType.value, formData.data).then(
  474. (res) => {
  475. ElMessage({
  476. message: modalType.value == "add" ? "添加成功" : "编辑成功",
  477. type: "success",
  478. });
  479. fileList.value = [];
  480. dialogVisible.value = false;
  481. submitLoading.value = false;
  482. getList();
  483. },
  484. (err) => {
  485. console.log(err, "aswwwww");
  486. submitLoading.value = false;
  487. }
  488. );
  489. });
  490. };
  491. const selectData = ref([]);
  492. const selectRow = (data) => {
  493. selectData.value = data;
  494. };
  495. const selectProductData = ref([]);
  496. const handleSelectProduct = (data) => {
  497. selectProductData.value = data;
  498. };
  499. const handleClickPacking = () => {
  500. if (selectProductData.value.length > 0) {
  501. const packDetailProductList = selectProductData.value.map((x) => ({
  502. contractId: "",
  503. contractProductId: "",
  504. quantity: "",
  505. }));
  506. this.formData.packDetailList.push({
  507. customerId: "",
  508. contractIds: "",
  509. packQuantity: "",
  510. netWeight: "",
  511. roughWeight: "",
  512. boxLong: "",
  513. boxWide: "",
  514. boxHigh: "",
  515. bomVolume: "",
  516. remark: "",
  517. packDetailGoodsList: [],
  518. packDetailProductList: [],
  519. });
  520. } else {
  521. return ElMessage({
  522. message: "请选择产品 !",
  523. type: "info",
  524. });
  525. }
  526. };
  527. const customerList = ref([]);
  528. const getSelectData = () => {
  529. proxy.post("/customer/page", { pageNum: 1, pageSize: 999 }).then((res) => {
  530. customerList.value = res.rows.map((item) => {
  531. return {
  532. ...item,
  533. label: item.name,
  534. value: item.id,
  535. };
  536. });
  537. });
  538. };
  539. const contractData = ref([]);
  540. const handleChangeCustomer = (val) => {
  541. proxy
  542. .get(`/contract/getNoPackContractByCustomerId?customerId=${val}`)
  543. .then((res) => {
  544. contractData.value = res.data;
  545. formData.data.contractIds = "";
  546. });
  547. };
  548. const contractProductData = ref([]);
  549. const handleChangeContract = (val) => {
  550. proxy
  551. .get(
  552. `/contract/getNoPackContractProductById?customerId=${formData.data.customerId}&contractId=${val}`
  553. )
  554. .then((res) => {
  555. contractProductData.value = res.data.map((x) => ({
  556. ...x,
  557. waitQuantity: Number(x.cpQuantity) - Number(x.sumPackQuantity),
  558. }));
  559. });
  560. };
  561. getSelectData();
  562. getList();
  563. </script>
  564. <style lang="scss" scoped>
  565. .tenant {
  566. padding: 20px;
  567. }
  568. :deep(.el-collapse-item__header) {
  569. background-color: #fde6c8;
  570. border: none;
  571. }
  572. :deep(.el-collapse-item__wrap) {
  573. background-color: #fde6c8;
  574. border: none;
  575. }
  576. .box {
  577. padding: 15px;
  578. background: #fde6c8;
  579. border: 1px solid #7fb5e3;
  580. .flex-box {
  581. width: 100%;
  582. display: flex;
  583. flex-wrap: wrap;
  584. .item {
  585. width: 50%;
  586. div {
  587. line-height: 22px;
  588. }
  589. }
  590. }
  591. .line {
  592. width: 100%;
  593. height: 1px;
  594. background: #7fb5e3;
  595. margin: 10px 0;
  596. }
  597. .bottom-arrow {
  598. text-align: center;
  599. cursor: pointer;
  600. color: #0084ff;
  601. }
  602. }
  603. </style>