index.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622
  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. }"
  15. :action-list="[]"
  16. @get-list="getList"
  17. >
  18. <template #fileSlot="{ item }">
  19. <div
  20. style="cursor: pointer; color: #409eff"
  21. @click="handleClickFile(item)"
  22. >
  23. {{ item.fileName }}
  24. </div>
  25. </template>
  26. </byTable>
  27. </div>
  28. <el-dialog
  29. :title="modalType === 'add' ? '发货登记' : '到货通知'"
  30. v-model="dialogVisible"
  31. width="800"
  32. v-loading="loading"
  33. >
  34. <byForm
  35. :formConfig="formConfig"
  36. :formOption="formOption"
  37. v-model="formData.data"
  38. :rules="rules"
  39. ref="byform"
  40. >
  41. <template #detailSlot>
  42. <div style="width: 100%">
  43. <el-table
  44. :data="
  45. modalType === 'add'
  46. ? formData.data.deliverGoodsDetailsList
  47. : formData.data.arrivalDetailList
  48. "
  49. >
  50. <el-table-column
  51. prop="productType"
  52. label="货品类型"
  53. :formatter="(row) => (row.productType == 1 ? '产品' : '物料')"
  54. />
  55. <el-table-column prop="productCode" label="货品编码" />
  56. <el-table-column prop="productName" label="货品名称" />
  57. <el-table-column prop="productSpec" label="规格型号" />
  58. <el-table-column prop="productUnit" label="单位" />
  59. <el-table-column prop="count" label="采购数量" />
  60. <el-table-column
  61. prop="alreadyDeliverGoodsQuantity"
  62. label="累计发货"
  63. v-if="modalType === 'add'"
  64. />
  65. <el-table-column
  66. prop="deliverGoodsQuantity"
  67. label="本次发货"
  68. min-width="150"
  69. v-if="modalType === 'add'"
  70. >
  71. <template #default="{ row, $index }">
  72. <el-form-item
  73. :prop="
  74. 'deliverGoodsDetailsList.' +
  75. $index +
  76. '.deliverGoodsQuantity'
  77. "
  78. :rules="rules.deliverGoodsQuantity"
  79. :inline-message="true"
  80. >
  81. <el-input-number
  82. v-model="row.deliverGoodsQuantity"
  83. :precision="4"
  84. :controls="false"
  85. :min="0"
  86. />
  87. </el-form-item>
  88. </template>
  89. </el-table-column>
  90. <el-table-column
  91. prop="transitQuantity"
  92. label="剩余在途"
  93. v-if="modalType === 'edit'"
  94. />
  95. <el-table-column
  96. prop="deliverGoodsQuantity"
  97. label="本次到货"
  98. v-if="modalType === 'edit'"
  99. />
  100. </el-table>
  101. </div>
  102. </template>
  103. </byForm>
  104. <template #footer>
  105. <el-button @click="dialogVisible = false" size="large">取 消</el-button>
  106. <el-button
  107. type="primary"
  108. @click="submitForm()"
  109. size="large"
  110. :loading="submitLoading"
  111. >
  112. 确 定
  113. </el-button>
  114. </template>
  115. </el-dialog>
  116. </div>
  117. </template>
  118. <script setup>
  119. import { ElMessage, ElMessageBox } from "element-plus";
  120. import byTable from "@/components/byTable/index";
  121. import byForm from "@/components/byForm/index";
  122. import { watch } from "vue";
  123. const loading = ref(false);
  124. const submitLoading = ref(false);
  125. const sourceList = ref({
  126. data: [],
  127. pagination: {
  128. total: 3,
  129. pageNum: 1,
  130. pageSize: 10,
  131. },
  132. });
  133. let dialogVisible = ref(false);
  134. let modalType = ref("add");
  135. let rules = ref({
  136. deliverGoodsId: [
  137. { required: true, message: "请选择快递单号", trigger: "change" },
  138. ],
  139. logisticsCompanyCode: [
  140. { required: true, message: "请选择物流公司", trigger: "change" },
  141. ],
  142. code: [{ required: true, message: "请输入物流/快递单号", trigger: "blur" }],
  143. deliverGoodsQuantity: [
  144. { required: true, message: "请输入本次发货", trigger: "blur" },
  145. ],
  146. });
  147. const { proxy } = getCurrentInstance();
  148. const selectConfig = reactive([
  149. {
  150. label: "采购状态",
  151. prop: "purchaseStatus",
  152. data: [
  153. {
  154. label: "审批中",
  155. value: "10",
  156. },
  157. {
  158. label: "已驳回",
  159. value: "20",
  160. },
  161. {
  162. label: "已采购",
  163. value: "30",
  164. },
  165. ],
  166. },
  167. {
  168. label: "到货状态",
  169. prop: "arrivalStatus",
  170. data: [
  171. {
  172. label: "未到货",
  173. value: "0",
  174. },
  175. {
  176. label: "部分到货",
  177. value: "10",
  178. },
  179. {
  180. label: "已到货",
  181. value: "20",
  182. },
  183. ],
  184. },
  185. {
  186. label: "付款状态",
  187. prop: "payStatus",
  188. data: [
  189. {
  190. label: "未付款",
  191. value: "1",
  192. },
  193. {
  194. label: "部分付款",
  195. value: "2",
  196. },
  197. {
  198. label: "已付款",
  199. value: "3",
  200. },
  201. ],
  202. },
  203. ]);
  204. const config = computed(() => {
  205. return [
  206. {
  207. attrs: {
  208. label: "采购单号",
  209. prop: "code",
  210. },
  211. },
  212. {
  213. attrs: {
  214. label: "供应商",
  215. prop: "supplyName",
  216. },
  217. },
  218. {
  219. attrs: {
  220. label: "收获仓库",
  221. prop: "supplyName",
  222. },
  223. },
  224. {
  225. attrs: {
  226. label: "采购金额",
  227. prop: "amount",
  228. },
  229. render(amount) {
  230. return proxy.moneyFormat(amount, 2);
  231. },
  232. },
  233. {
  234. attrs: {
  235. label: "采购人",
  236. prop: "purchaseName",
  237. },
  238. },
  239. {
  240. attrs: {
  241. label: "采购时间",
  242. prop: "createTime",
  243. },
  244. },
  245. {
  246. attrs: {
  247. label: "采购状态",
  248. prop: "purchaseStatus",
  249. },
  250. },
  251. {
  252. attrs: {
  253. label: "到货状态",
  254. prop: "arrivalStatus",
  255. },
  256. },
  257. {
  258. attrs: {
  259. label: "付款状态",
  260. prop: "payStatus",
  261. },
  262. },
  263. {
  264. attrs: {
  265. label: "操作",
  266. width: "240",
  267. align: "right",
  268. },
  269. renderHTML(row) {
  270. return [
  271. {
  272. attrs: {
  273. label: "发货登记",
  274. type: "primary",
  275. text: true,
  276. },
  277. el: "button",
  278. click() {
  279. handleArrival(row, "add");
  280. },
  281. },
  282. {
  283. attrs: {
  284. label: "到货通知",
  285. type: "primary",
  286. text: true,
  287. },
  288. el: "button",
  289. click() {
  290. handleArrival(row, "edit");
  291. },
  292. },
  293. {
  294. attrs: {
  295. label: "作废",
  296. type: "primary",
  297. text: true,
  298. },
  299. el: "button",
  300. click() {
  301. handleEdit(row, 88);
  302. },
  303. },
  304. {
  305. attrs: {
  306. label: "终止",
  307. type: "primary",
  308. text: true,
  309. },
  310. el: "button",
  311. click() {
  312. handleEdit(row, 99);
  313. },
  314. },
  315. ];
  316. },
  317. },
  318. ];
  319. });
  320. let formData = reactive({
  321. data: {},
  322. });
  323. const formOption = reactive({
  324. inline: true,
  325. labelWidth: 100,
  326. itemWidth: 100,
  327. });
  328. const byform = ref(null);
  329. let formConfig = reactive([]);
  330. const configData = [
  331. [
  332. {
  333. type: "input",
  334. prop: "supplyName",
  335. label: "供应商",
  336. disabled: true,
  337. itemWidth: 50,
  338. },
  339. {
  340. type: "input",
  341. prop: "purchaseCode",
  342. label: "采购单号",
  343. disabled: true,
  344. itemWidth: 50,
  345. },
  346. {
  347. type: "select",
  348. label: "物流信息",
  349. prop: "logisticsCompanyCode",
  350. itemWidth: 50,
  351. style: {
  352. width: "100%",
  353. },
  354. },
  355. {
  356. type: "input",
  357. label: " ",
  358. prop: "code",
  359. itemWidth: 50,
  360. },
  361. {
  362. type: "slot",
  363. slotName: "detailSlot",
  364. label: "发货明细",
  365. },
  366. ],
  367. [
  368. {
  369. type: "input",
  370. prop: "supplyName",
  371. label: "供应商",
  372. disabled: true,
  373. itemWidth: 50,
  374. },
  375. {
  376. type: "input",
  377. prop: "purchaseCode",
  378. label: "采购单号",
  379. disabled: true,
  380. itemWidth: 50,
  381. },
  382. {
  383. type: "select",
  384. label: "物流/快递单号",
  385. prop: "deliverGoodsId",
  386. itemWidth: 50,
  387. style: {
  388. width: "100%",
  389. },
  390. },
  391. {
  392. type: "slot",
  393. slotName: "detailSlot",
  394. label: "发货明细",
  395. },
  396. ],
  397. ];
  398. const deliverData = ref([]);
  399. const getList = async (req) => {
  400. sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
  401. loading.value = true;
  402. proxy.post("/purchase/page", sourceList.value.pagination).then((message) => {
  403. console.log(message);
  404. sourceList.value.data = message.rows;
  405. sourceList.value.pagination.total = message.total;
  406. setTimeout(() => {
  407. loading.value = false;
  408. }, 200);
  409. });
  410. };
  411. const submitForm = () => {
  412. byform.value.handleSubmit((valid) => {
  413. if (modalType.value === "add") {
  414. const list = formData.data.deliverGoodsDetailsList;
  415. const total = list.reduce(
  416. (total, x) => (total += Number(x.deliverGoodsQuantity)),
  417. 0
  418. );
  419. if (!(total > 0)) {
  420. return ElMessage({
  421. message: `本次发货不能为0!`,
  422. type: "info",
  423. });
  424. }
  425. for (let i = 0; i < list.length; i++) {
  426. const e = list[i];
  427. if (
  428. Number(e.alreadyDeliverGoodsQuantity) +
  429. Number(e.deliverGoodsQuantity) >
  430. Number(e.count)
  431. ) {
  432. return ElMessage({
  433. message: `本次发货加累计发货不可大于采购数量!`,
  434. type: "info",
  435. });
  436. }
  437. }
  438. loading.value = true;
  439. formData.data.deliverGoodsDetailsList = list.map((x) => ({
  440. purchaseDetailId: x.purchaseDetailId,
  441. deliverGoodsQuantity: x.deliverGoodsQuantity,
  442. }));
  443. proxy.post("/deliverGoods/add", formData.data).then((res) => {
  444. ElMessage({
  445. message: `操作成功!`,
  446. type: "success",
  447. });
  448. dialogVisible.value = false;
  449. loading.value = false;
  450. getList();
  451. });
  452. } else if (modalType.value === "edit") {
  453. loading.value = true;
  454. formData.data.arrivalDetailList = formData.data.arrivalDetailList.map(
  455. (x) => ({
  456. bussinessId: x.bussinessId,
  457. purchaseDetailId: x.purchaseDetailId,
  458. deliverGoodsDetailsId: x.deliverGoodsDetailsId,
  459. count: x.deliverGoodsQuantity,
  460. })
  461. );
  462. const victoriatouristJson = {
  463. deliverGoodsId: formData.data.deliverGoodsId,
  464. logisticsCompanyCode: formData.data.logisticsCompanyCode,
  465. code: formData.data.code,
  466. };
  467. formData.data.victoriatouristJson = JSON.stringify(victoriatouristJson);
  468. proxy.post("/arrival/addByWdly", formData.data).then((res) => {
  469. ElMessage({
  470. message: `操作成功!`,
  471. type: "success",
  472. });
  473. dialogVisible.value = false;
  474. loading.value = false;
  475. getList();
  476. });
  477. }
  478. });
  479. };
  480. const getDtl = (row) => {
  481. modalType.value = "edit";
  482. proxy.post("/productionProcesses/detail", { id: row.id }).then((res) => {
  483. formData.data = res;
  484. dialogVisible.value = true;
  485. });
  486. };
  487. const handleEdit = (row, status) => {
  488. let purchaseStatusName = status == 88 ? "作废" : "终止";
  489. const data = { ...row, purchaseStatus: status };
  490. // 弹窗提示是否删除
  491. ElMessageBox.confirm(
  492. `此操作将${purchaseStatusName}该数据, 是否继续?`,
  493. "提示",
  494. {
  495. confirmButtonText: "确定",
  496. cancelButtonText: "取消",
  497. type: "warning",
  498. }
  499. ).then(() => {
  500. // 删除
  501. proxy.post("/purchase/edit", data).then((res) => {
  502. ElMessage({
  503. message: `${purchaseStatusName}成功`,
  504. type: "success",
  505. });
  506. getList();
  507. });
  508. });
  509. };
  510. // 获取供应商数据
  511. const supplierData = ref([]);
  512. const getSupplierList = async (req) => {
  513. proxy
  514. .post("/supplierInfo/page", { pageNum: 1, pageSize: 9999 })
  515. .then((res) => {
  516. supplierData.value = res.rows;
  517. });
  518. };
  519. const logisticsData = ref([]);
  520. const getLogisticsData = (row) => {
  521. proxy.post("/companyInfo/list", { pageNum: 1, pageSize: 999 }).then((res) => {
  522. logisticsData.value = res.reverse().slice(0, 100); //截取前100
  523. });
  524. };
  525. const handleArrival = (row, type) => {
  526. modalType.value = type;
  527. if (type === "add") {
  528. formConfig = configData[0];
  529. formConfig[2].data = logisticsData.value.map((x) => ({
  530. label: x.name,
  531. value: x.code,
  532. }));
  533. proxy.post("/deliverGoodsDetails/detail", { id: row.id }).then((res) => {
  534. formData.data = {
  535. purchaseId: row.id,
  536. supplyName: row.supplyName,
  537. purchaseCode: row.code,
  538. supplyId: res.supplyId,
  539. code: "",
  540. logisticsCompanyCode: "",
  541. deliverGoodsDetailsList: res.map((x) => ({
  542. ...x,
  543. purchaseDetailId: x.id,
  544. alreadyDeliverGoodsQuantity: x.deliverGoodsQuantity,
  545. deliverGoodsQuantity: 0,
  546. })),
  547. };
  548. dialogVisible.value = true;
  549. });
  550. } else if (type === "edit") {
  551. formConfig = configData[1];
  552. proxy.post("/deliverGoods/list", { id: row.id }).then((res) => {
  553. deliverData.value = res;
  554. formConfig[2].data = res.map((x) => ({
  555. ...x,
  556. label: x.code,
  557. value: x.id,
  558. }));
  559. formData.data = {
  560. purchaseId: row.id,
  561. supplyName: row.supplyName,
  562. purchaseCode: row.code,
  563. supplyId: row.supplyId,
  564. code: "",
  565. logisticsCompanyCode: "",
  566. deliverGoodsId: "",
  567. arrivalDetailList: [],
  568. };
  569. dialogVisible.value = true;
  570. });
  571. }
  572. };
  573. watch(
  574. () => formData.data.deliverGoodsId,
  575. (val) => {
  576. if (val) {
  577. const current = deliverData.value.find((x) => x.id === val);
  578. formData.data.logisticsCompanyCode = current
  579. ? current.logisticsCompanyCode
  580. : "";
  581. formData.data.code = current ? current.code : "";
  582. // formData.data.logisticsCompanyName = current ? current.logisticsCompanyCode : "";
  583. proxy.post("/deliverGoods/detail", { id: val }).then((res) => {
  584. formData.data.arrivalDetailList = res.map((x) => ({
  585. count: x.count,
  586. productName: x.name,
  587. productSpec: x.spec,
  588. productUnit: x.unit,
  589. productType: x.type,
  590. productCode: x.code,
  591. bussinessId: x.id,
  592. purchaseDetailId: x.purchaseDetailId,
  593. deliverGoodsDetailsId: x.deliverGoodsId,
  594. transitQuantity: x.transitQuantity,
  595. deliverGoodsQuantity: x.deliverGoodsQuantity,
  596. }));
  597. });
  598. }
  599. }
  600. );
  601. getList();
  602. getLogisticsData();
  603. </script>
  604. <style lang="scss" scoped>
  605. .tenant {
  606. padding: 20px;
  607. }
  608. </style>