addDialog.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  1. <template>
  2. <div>
  3. <el-form ref="form" :model="form" :rules="rules" label-width="120px">
  4. <headerTitle title="基本信息"></headerTitle>
  5. <el-row>
  6. <el-col :span="12">
  7. <el-form-item
  8. label="采购计划单名称"
  9. prop="planCode"
  10. style="margin-bottom: 22px"
  11. >
  12. <el-input
  13. @click.native="handParent"
  14. v-model="form.planName"
  15. placeholder="请选择"
  16. ></el-input>
  17. </el-form-item>
  18. </el-col>
  19. <el-col :span="12">
  20. <el-form-item
  21. label="询价单名称"
  22. prop="inquiryName"
  23. style="margin-bottom: 22px"
  24. >
  25. <el-input v-model="form.inquiryName"></el-input>
  26. </el-form-item>
  27. </el-col>
  28. <el-col :span="12">
  29. <el-form-item prop="remark" label="是否接受拆单" label-width="120px">
  30. <el-select
  31. v-model="form.acceptUnpack"
  32. clearable
  33. style="width: 100%"
  34. disabled
  35. >
  36. <el-option
  37. v-for="item in acceptUnpackList"
  38. :key="item.value"
  39. :label="item.label"
  40. :value="item.value"
  41. >
  42. </el-option>
  43. </el-select>
  44. </el-form-item>
  45. </el-col>
  46. <el-col :span="12">
  47. <el-form-item prop="files" label="附件">
  48. <fileMain v-model="form.files"></fileMain>
  49. <!-- <fileUpload-->
  50. <!-- v-model="form.files"-->
  51. <!-- module="main"-->
  52. <!-- :showLib="false"-->
  53. <!-- :limit="1"-->
  54. <!-- />-->
  55. </el-form-item>
  56. </el-col>
  57. <el-col :span="12">
  58. <el-form-item prop="remark" label="备注">
  59. <el-input
  60. type="textarea"
  61. resize="none"
  62. v-model="form.remark"
  63. :rows="2"
  64. placeholder="请输入"
  65. size="small"
  66. maxlength="200"
  67. ></el-input>
  68. </el-form-item>
  69. </el-col>
  70. </el-row>
  71. </el-form>
  72. <headerTitle title="物品清单" style="margin-top: 15px"></headerTitle>
  73. <el-button type="primary" @click="openSupplier">新增供应商</el-button>
  74. <inventoryTable
  75. ref="inventoryTable"
  76. @delList="delList"
  77. :acceptUnpack="form.acceptUnpack"
  78. @supplierSelect="supplierSelect"
  79. ></inventoryTable>
  80. <headerTitle title="报价清单" style="margin-top: 15px"></headerTitle>
  81. <inquiryManageList
  82. ref="inquiryManageRef"
  83. @changeInquiryManageList="changeInquiryManageList"
  84. @supplierSelect="supplierSelect"
  85. @supplierManageChange="supplierManageChange"
  86. ></inquiryManageList>
  87. <supplierManageDialog
  88. ref="supplierManageDialogRef"
  89. @supplierManageChange="supplierManageChange"
  90. ></supplierManageDialog>
  91. <inquiryTable
  92. @removeSupplier="removeSupplier"
  93. :ref="'inquiryTable' + item.supplierId"
  94. v-for="item in supplierList"
  95. :key="item.supplierId"
  96. style="margin-top: 15px"
  97. :obj="item"
  98. :isUpdate="isUpdate"
  99. @deliveryDateChange="deliveryDateChange"
  100. ></inquiryTable>
  101. </div>
  102. </template>
  103. <script>
  104. import inventoryTable from './inventoryTable.vue';
  105. import inquiryTable from './inquiryTable.vue';
  106. import inquiryManageList from './inquiryManage-list.vue';
  107. import supplierManageDialog from './supplierManageDialog.vue';
  108. import fileUpload from '@/components/upload/fileUpload';
  109. import dictMixins from '@/mixins/dictMixins';
  110. import { deepClone } from '@/utils';
  111. import { getplanDetail } from '@/api/bpm/components/purchasingManage/purchasePlanManage';
  112. import {
  113. getpurchaseinquiry,
  114. chooseWinner
  115. } from '@/api/bpm/components/purchasingManage/inquiryManage';
  116. import { copyObj } from '@/utils/util';
  117. import { getFile } from '@/api/system/file';
  118. import { contactQueryByCategoryIdsAPI } from '@/api/bpm/components/supplierManage/contact';
  119. import { contactDetail } from '@/api/bpm/components/saleManage/contact';
  120. import fileMain from '@/components/addDoc/index.vue';
  121. export default {
  122. mixins: [dictMixins],
  123. components: {
  124. fileMain,
  125. fileUpload,
  126. inventoryTable,
  127. inquiryManageList,
  128. supplierManageDialog,
  129. inquiryTable
  130. },
  131. props: {
  132. businessId: {
  133. default: ''
  134. }
  135. },
  136. data() {
  137. let formDef = {
  138. id: '',
  139. planCode: null,
  140. planName: null,
  141. inquiryName: null,
  142. remark: null,
  143. planId: '',
  144. detailList: '',
  145. resultList: [],
  146. supplierName: '',
  147. files: [],
  148. acceptUnpack: ''
  149. };
  150. return {
  151. visible: false,
  152. supplierVisible: false,
  153. title: '',
  154. supplierList: [],
  155. detailList: [],
  156. list: [],
  157. delDetailIds: [],
  158. supplierProducts: {},
  159. formDef,
  160. rawList: [],
  161. outputList: [],
  162. acceptUnpackList: [
  163. {
  164. label: '接受',
  165. value: 1
  166. },
  167. {
  168. label: '不接受',
  169. value: 0
  170. }
  171. ],
  172. form: copyObj(formDef),
  173. rules: {
  174. responsibleName: [
  175. { required: true, message: '请选择负责人', trigger: 'change' }
  176. ],
  177. requireDeptId: [
  178. { required: true, message: '请选择需求部门', trigger: 'change' }
  179. ],
  180. inquiryName: [
  181. { required: true, message: '请输入询价单名称', trigger: 'blur' }
  182. ]
  183. },
  184. // 提交状态
  185. loading: false,
  186. // 是否是修改
  187. isUpdate: false
  188. };
  189. },
  190. created() {
  191. this.getDetailData(this.businessId, 'init');
  192. },
  193. methods: {
  194. openSupplier() {
  195. if (this.list.length == 0) {
  196. this.$message.warning('请先选择采购计划');
  197. return;
  198. }
  199. this.$refs.supplierManageDialogRef.open();
  200. },
  201. //获取询价详情
  202. async getDetailData(id, type) {
  203. this.loading = true;
  204. let data = await getpurchaseinquiry(id);
  205. this.loading = false;
  206. if (data) {
  207. this.form = data;
  208. this.supplierList = data.supplierList;
  209. let supplierObj = await this.getSupplierObj(
  210. data.detailList,
  211. 'productId'
  212. );
  213. data.detailList.forEach((item) => {
  214. item.supplierList = supplierObj[item.productId] || [];
  215. });
  216. this.list = [...data.detailList, ...data.rawList, ...data.outputList];
  217. this.rawList = data.rawList;
  218. this.outputList = data.outputList;
  219. this.supplierList = data.supplierList;
  220. this.$nextTick(() => {
  221. this.$refs.inventoryTable &&
  222. this.$refs.inventoryTable.putTableValue(data.detailList);
  223. // this.setIsInquiry()
  224. });
  225. if (type == 'init') {
  226. this.getplanData(data.planId, type);
  227. }
  228. // console.log(this.form, 'this.form');
  229. // this.$nextTick(() => {
  230. // });
  231. }
  232. },
  233. deliveryDateChange(fn) {
  234. let data = this.$refs.inventoryTable.getTableValue() || [];
  235. fn(data);
  236. },
  237. setIsInquiry(supplierList) {
  238. // let supplierList = [];
  239. this.$nextTick(() => {
  240. // this.supplierList.forEach((item) => {
  241. // supplierList.push(
  242. // this.$refs['inquiryTable' + item.supplierId][0].getTableValue()
  243. // );
  244. // });
  245. this.$refs.inventoryTable.setIsInquiry(supplierList);
  246. });
  247. },
  248. //获取计划详情
  249. async getplanData(id, type) {
  250. this.loading = true;
  251. let data = await getplanDetail(id);
  252. this.rawList = data.rawDetailList;
  253. this.outputList = data.outputDetailList;
  254. this.loading = false;
  255. if (data) {
  256. let supplierObj = await this.getSupplierObj(
  257. data.detailList,
  258. 'productId'
  259. );
  260. data.detailList.forEach((item) => {
  261. if (item.arrivalWay == 2 && item.arrivalBatch.length > 0) {
  262. item.expectReceiveDate =
  263. item.arrivalBatch[item.arrivalBatch.length - 1].arriveDate;
  264. }
  265. item.supplierList = supplierObj[item.productId] || [];
  266. if (item.supplierList.length === 1) {
  267. item.supplierIds = [item.supplierList[0].id];
  268. // this.supplierSelect(item)
  269. }
  270. });
  271. this.$set(this.form, 'acceptUnpack', data.acceptUnpack);
  272. this.form.planId = data.id;
  273. this.form.planCode = data.planCode;
  274. this.form.planName = data.planName;
  275. // if (type == 'change') {
  276. // this.supplierList.forEach((item) => {
  277. // this.$refs['inquiryTable' + item.supplierId][0].putTableValue(
  278. // data.detailList
  279. // );
  280. // });
  281. // }
  282. if (type == 'init') {
  283. return;
  284. }
  285. this.list = [
  286. ...data.detailList,
  287. ...data.rawDetailList,
  288. ...data.outputDetailList
  289. ];
  290. this.$nextTick(() => {
  291. this.$refs.inventoryTable &&
  292. this.$refs.inventoryTable.putTableValue(data.detailList);
  293. });
  294. }
  295. },
  296. async getSupplierObj(productList, queryName) {
  297. try {
  298. let categoryIds = productList.map((item) => item[queryName]);
  299. return await contactQueryByCategoryIdsAPI({ categoryIds });
  300. } catch (e) {
  301. return Promise.resolve({});
  302. }
  303. },
  304. getValidate() {
  305. let promises = [];
  306. this.supplierList.forEach((item) => {
  307. promises.push(
  308. new Promise((resolve, reject) => {
  309. this.$refs['inquiryTable' + item.supplierId][0].validateForm(
  310. (valid) => {
  311. if (!valid) {
  312. reject(false);
  313. } else {
  314. resolve(true);
  315. }
  316. }
  317. );
  318. })
  319. );
  320. });
  321. return Promise.all([
  322. new Promise((resolve, reject) => {
  323. this.$refs.form.validate((valid) => {
  324. if (!valid) {
  325. reject(false);
  326. } else {
  327. resolve(true);
  328. }
  329. });
  330. }),
  331. ...promises
  332. ]);
  333. },
  334. //计划删除
  335. delList(productCode) {
  336. this.supplierList.forEach((item) => {
  337. this.$refs['inquiryTable' + item.supplierId][0].remove(productCode);
  338. });
  339. },
  340. removeSupplier(supplierId) {
  341. this.supplierList = this.supplierList.filter(
  342. (item) => item.supplierId != supplierId
  343. );
  344. // this.setIsInquiry()
  345. },
  346. //选择产品
  347. handParent() {
  348. this.$refs.inquiryManageRef.open(this.form.planCode);
  349. },
  350. changeInquiryManageList(data) {
  351. this.getplanData(data.id, 'change');
  352. },
  353. async supplierSelect(row) {
  354. let supplierIds = Object.keys(this.supplierProducts);
  355. const promises = [];
  356. row.supplierIds.forEach((item) => {
  357. if (!supplierIds.includes(item)) {
  358. promises.push(contactDetail(item));
  359. } else {
  360. this.productSetSupplier(this.supplierProducts[item], row);
  361. }
  362. });
  363. Promise.all(promises).then((results) => {
  364. results.forEach((data, index) => {
  365. this.supplierProducts[data.base.id] = data;
  366. this.productSetSupplier(this.supplierProducts[data.base.id], row);
  367. });
  368. });
  369. },
  370. productSetSupplier(data, row) {
  371. let obj = deepClone(row);
  372. obj.supplierProductName = data.productList.find(
  373. (item) => item.productCode == row.productCode
  374. )?.productName;
  375. obj.supplierProductCode = data.productList.find(
  376. (item) => item.productCode == row.productCode
  377. )?.productCode;
  378. obj.supplierName = data.base.name;
  379. let params = {
  380. ...data.base,
  381. supplierId: data.base.id,
  382. supplierName: data.base.name,
  383. supplierCode: data.base.code,
  384. files: [],
  385. preferentialPrice: '',
  386. settlementMode: '',
  387. settlementModeName: '',
  388. taxRate: '',
  389. totalPrice: '',
  390. resultList: [obj]
  391. };
  392. let supplierIds = this.supplierList.map((item) => item.supplierId);
  393. let supplierIndex = supplierIds.indexOf(data.base.id);
  394. if (supplierIndex == -1) {
  395. this.supplierList.push(params);
  396. } else {
  397. let isHave = this.supplierList[supplierIndex].resultList.some(
  398. (item) => item.productCode == obj.productCode
  399. );
  400. if (!isHave) {
  401. // putTableValue
  402. //this.supplierList[supplierIndex].resultList.push(obj)
  403. this.$set(this.supplierList[supplierIndex], 'resultList', [
  404. ...this.supplierList[supplierIndex].resultList,
  405. obj
  406. ]);
  407. this.$nextTick(() => {
  408. this.$refs['inquiryTable' + data.base.id][0]?.putTableValue(
  409. this.supplierList[supplierIndex].resultList
  410. );
  411. this.$refs['inquiryTable' + data.base.id][0]?.getSpanArr();
  412. });
  413. }
  414. }
  415. },
  416. //供应商回调
  417. supplierManageChange(data) {
  418. let supplierIds = this.supplierList.map((item) => item.supplierId);
  419. data.forEach((item) => {
  420. item['files'] = [];
  421. item['supplierName'] = item.name;
  422. item['preferentialPrice'] = '';
  423. item['settlementMode'] = '';
  424. item['settlementModeName'] = '';
  425. item['taxRate'] = '';
  426. item['totalPrice'] = '';
  427. item['resultList'] = copyObj(this.$refs.inventoryTable.selection);
  428. item['resultList'].forEach((val) => {
  429. val['remark'] = '';
  430. item['deliveryDate'] = val.expectReceiveDate;
  431. val.supplierName = item.name;
  432. });
  433. let supplierIndex = supplierIds.indexOf(item.supplierId);
  434. if (supplierIndex == -1) {
  435. this.supplierList.push(item);
  436. } else {
  437. item['resultList'].forEach((val) => {
  438. let isHave = this.supplierList[supplierIndex].resultList.some(
  439. (i) => i.productCode == val.productCode
  440. );
  441. console.log(isHave, supplierIndex);
  442. if (!isHave) {
  443. this.$set(this.supplierList[supplierIndex], 'resultList', [
  444. ...this.supplierList[supplierIndex].resultList,
  445. val
  446. ]);
  447. this.$refs['inquiryTable' + item.id][0]?.putTableValue(
  448. this.supplierList[supplierIndex].resultList
  449. );
  450. this.$nextTick(() => {
  451. this.$refs['inquiryTable' + item.id][0]?.getSpanArr();
  452. });
  453. }
  454. });
  455. }
  456. });
  457. },
  458. async getTableValue() {
  459. try {
  460. await this.getValidate();
  461. let supplierList = [];
  462. this.supplierList.forEach((item) => {
  463. supplierList.push(
  464. this.$refs['inquiryTable' + item.supplierId][0].getTableValue()
  465. );
  466. });
  467. this.setIsInquiry(supplierList);
  468. let is = false;
  469. supplierList.forEach((item) => {
  470. item.resultList.forEach((val) => {
  471. val['technicalDrawings'] = [];
  472. if (val.minimumOrderQuantity > val.totalCount) {
  473. is = true;
  474. }
  475. });
  476. });
  477. if (is) {
  478. this.$message.warning('购买数量不能小于最低订购量!');
  479. return;
  480. }
  481. this.form.detailList = this.list;
  482. this.form.supplierList = supplierList;
  483. // 表单验证通过,执行保存操作
  484. this.loading = true;
  485. if (this.$refs.inventoryTable.getTableValue().length == 0) {
  486. this.$message.warning('物品清单不能为空');
  487. return;
  488. }
  489. this.form.supplierList.forEach((item) => {
  490. item.resultList = [
  491. ...item.resultList,
  492. ...this.rawList,
  493. ...this.outputList
  494. ];
  495. });
  496. this.form.files = this.form.files || [];
  497. return this.form;
  498. } catch (error) {
  499. console.log(error);
  500. // 表单验证未通过,不执行保存操作
  501. }
  502. },
  503. downloadFile(file) {
  504. getFile({ objectName: file.storePath }, file.name);
  505. }
  506. }
  507. };
  508. </script>
  509. <style scoped lang="scss">
  510. .TotalAmount {
  511. font-size: 16px;
  512. padding-right: 30px;
  513. }
  514. </style>