index.vue 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269
  1. <script>
  2. import orderApi from "@/api/business/purchase/purchase-order";
  3. import {
  4. initColumns,
  5. initDicts,
  6. initRules,
  7. initParams,
  8. } from "@/utils/init/index.js";
  9. // import { Columns, TabColumns } from "./column";
  10. import judgeColumns from "./column";
  11. import { tax, currency } from "@/components/popover-select-v2/fetch";
  12. import VirtualScroll from "el-table-virtual-scroll";
  13. import { VirtualColumn } from "el-table-virtual-scroll";
  14. const { Columns, TabColumns } = judgeColumns();
  15. const NewColumns = initColumns(Columns);
  16. const NewTabColumns = TabColumns.map((element) => ({
  17. ...element,
  18. tableColumns: initColumns(element.tableColumns).map((item, index) => ({
  19. ...item,
  20. hidden: true,
  21. })),
  22. }));
  23. const SelectColumns = NewColumns.filter(
  24. (column) => column.inputType === "Select"
  25. );
  26. NewTabColumns.forEach((column) => {
  27. SelectColumns.push(
  28. ...column.tableColumns.filter((cColumn) => cColumn.inputType === "Select")
  29. );
  30. });
  31. export default {
  32. name: "AddPurchaseOrderDrawer",
  33. props: {},
  34. dicts: initDicts(SelectColumns),
  35. components: {
  36. "virtual-scroll": VirtualScroll,
  37. VirtualColumn,
  38. FileUploadCenter: () => import("../components/FileUploadCenter/index.vue"),
  39. popDialog: () => import("@/components/PopDialog/index.vue"),
  40. BatchImport: () => import("@/components/BatchImport/index.vue"),
  41. ButtonHide: () => import("../components/hide/index.vue"),
  42. },
  43. data() {
  44. return {
  45. visible: false,
  46. loading: false,
  47. tabLoading: false,
  48. columns: NewColumns,
  49. rules: initRules(NewColumns),
  50. count: 0,
  51. params: {
  52. ...initParams(NewColumns),
  53. puOrderItemList: [],
  54. // 执行结果
  55. // puOrderExecuteList: [],
  56. },
  57. tabColumns: NewTabColumns,
  58. tabName: "puOrderItemList",
  59. isCopy: false,
  60. tableData: [], //虚拟滚动加载显示的数据
  61. rowHeight: 60,
  62. size: "mini",
  63. };
  64. },
  65. computed: {
  66. role: {
  67. get() {
  68. let { roles } = this.$store.state.user;
  69. return (
  70. roles.find((item) => item === "syfz-purchaseorder") ||
  71. "procurementManager"
  72. );
  73. },
  74. set() {},
  75. },
  76. tabHeight: {
  77. get() {
  78. return `${
  79. this.params["puOrderItemList"].length
  80. ? this.params["puOrderItemList"].length > 8
  81. ? 500
  82. : this.params["puOrderItemList"].length * 36 + 120
  83. : 120
  84. }px`;
  85. },
  86. set() {},
  87. },
  88. innerColumns: {
  89. get() {
  90. let { tabName, tabColumns } = this;
  91. let obj = tabColumns.find(({ key }) => key === tabName).tableColumns;
  92. return obj;
  93. },
  94. set(value) {
  95. let { tabName, tabColumns } = this;
  96. this.tabColumns = tabColumns.map((item) => {
  97. if (item.key === tabName) {
  98. item.tableColumns = value;
  99. }
  100. return { ...item };
  101. });
  102. this.$nextTick(() => {
  103. this.$refs.puOrderItemList &&
  104. this.$refs.puOrderItemList[0].doLayout();
  105. });
  106. },
  107. },
  108. },
  109. watch: {
  110. // 同步物料信息与执行结果
  111. // "params.puOrderItemList": {
  112. // handler(nVal, oVal) {
  113. // this.visible &&
  114. // this.handleSynchronousMaterial(
  115. // "puOrderItemList",
  116. // "puOrderExecuteList"
  117. // );
  118. // },
  119. // deep: true,
  120. // },
  121. // 执行结果监听
  122. // "params.puOrderExecuteList": {
  123. // handler(nVal, oVal) {
  124. // this.visible &&
  125. // this.handleSynchronousMaterial(
  126. // "puOrderExecuteList",
  127. // "puOrderItemList"
  128. // );
  129. // },
  130. // deep: true,
  131. // },
  132. "params.billType": {
  133. handler(nVal, oVal) {
  134. let billList = ["21-Cxx-02", "21-Cxx-04", "21-Cxx-10", "21-Cxx-14"];
  135. this.params.warehouse = "";
  136. this.params.warehouseName = "";
  137. this.params.goodsAllocation = "";
  138. this.params.goodsAllocationName = "";
  139. if (billList.find((item) => item === nVal)) {
  140. this.rules.warehouseName = [
  141. {
  142. required: true,
  143. message: "WMS入库仓库不能为空",
  144. trigger: "change",
  145. },
  146. ];
  147. } else {
  148. this.rules.warehouseName = null;
  149. }
  150. this.rules.goodsAllocationName = null;
  151. this.count++;
  152. },
  153. },
  154. "params.isBack": {
  155. handler(nVal, oVal) {
  156. if (nVal === "Y") {
  157. this.rules.retReasonName = [
  158. { required: true, message: "退换原因不能为空", trigger: "change" },
  159. ];
  160. this.rules.processTypeName = [
  161. { required: true, message: "处理方式不能为空", trigger: "change" },
  162. ];
  163. } else {
  164. this.rules.retReasonName = null;
  165. this.rules.processTypeName = null;
  166. }
  167. this.count++;
  168. },
  169. },
  170. },
  171. methods: {
  172. beforeOpen() {
  173. if (!this.isCopy) {
  174. const { deptName, deptId, name, nickName, orgName, orgId } =
  175. this.$store.state.user;
  176. this.params.puOrg = orgId;
  177. this.params.puOrgName = orgName;
  178. this.params.buyer = name;
  179. this.params.buyerName = nickName;
  180. this.params.puDept = deptId;
  181. this.params.puDeptName = deptName;
  182. this.params.billDate = new Date().Format("yyyy-MM-dd");
  183. this.params.createTime = new Date().Format("yyyy-MM-dd HH:mm:ss");
  184. console.log(this.params, "this.params");
  185. // this.addTableRow();
  186. }
  187. },
  188. setVisible(prop, iscopy) {
  189. this.visible = prop;
  190. this.isCopy = iscopy;
  191. if (!this.visible) {
  192. this.$refs["orderAddForm"].clearValidate();
  193. }
  194. },
  195. // 复制赋值
  196. async setCopyParams(id) {
  197. try {
  198. this.loading = true;
  199. const { code, msg, data } = await orderApi.details(id);
  200. if (code === 200) {
  201. this.params = {
  202. ...data,
  203. id: "",
  204. code: "",
  205. isEnd: "N",
  206. status: "0",
  207. source: "3",
  208. isClose: "N",
  209. billDate: new Date().Format("yyyy-MM-dd"),
  210. createTime: new Date().Format("yyyy-MM-dd HH:mm:ss"),
  211. closeTime: "",
  212. oaDemandNo: "",
  213. isInvoice: "N",
  214. isSendWms: "N",
  215. rebateMoney: "",
  216. invoiceMoney: "",
  217. paymentMoney: "",
  218. applyPaymentMoney: "",
  219. erpOrderCode: "",
  220. closeReason: "",
  221. };
  222. try {
  223. const { code, rows } = await orderApi.REFER(
  224. {
  225. type: "WAREHOUSE_PARAM",
  226. search: this.params.warehouseName,
  227. isPage: true,
  228. },
  229. { pageNum: 1, pageSize: 10 }
  230. );
  231. if (code == 200) {
  232. this.judgeGoodsAllocation(rows[0].csFlag);
  233. }
  234. } catch (error) {}
  235. for (const key in this.params) {
  236. // if (Array.isArray(this.params[key])) {
  237. // if (key === "puOrderItemList" || key === "puOrderExecuteList") {
  238. if (key === "puOrderItemList") {
  239. this.params[key].forEach((v) => {
  240. v.id = "";
  241. v.demandCode = "";
  242. v.closeReason = "";
  243. v.goodsAllocation = "";
  244. v.goodsAllocationName = "";
  245. v["isInvoice"] && (v["isInvoice"] = "N");
  246. v["isStorage"] && (v["isStorage"] = "N");
  247. v["isArrival"] && (v["isArrival"] = "N");
  248. v["isPayment"] && (v["isPayment"] = "N");
  249. });
  250. }
  251. }
  252. // 清空 累计本币开票金额、
  253. // 累计付款金额、累计付款申请金额、累计开票主数量、最终关闭时间
  254. // 、最终关闭、已同步WMS 、订单抵扣余额金额、订单使用返利金额、 发票标识
  255. }
  256. } catch (err) {
  257. //
  258. } finally {
  259. this.loading = false;
  260. }
  261. },
  262. // 增行
  263. addTableRow(prop) {
  264. for (const key in this.params) {
  265. // if (Array.isArray(this.params[key])) {
  266. // if (key === "puOrderItemList" || key === "puOrderExecuteList") {
  267. if (key === "puOrderItemList") {
  268. const arr = this.tabColumns.find(
  269. (element) => element.key === key
  270. ).tableColumns;
  271. let rowData = initParams(arr, "key", "value");
  272. "rowno" in rowData &&
  273. (rowData["rowno"] = this.params[key].length
  274. ? this.params[key][this.params[key].length - 1]["rowno"] + 1
  275. : this.params[key].length + 1);
  276. // 物料
  277. if ("rowNo" in rowData) {
  278. rowData["rowNo"] = this.params[key].length
  279. ? this.params[key][this.params[key].length - 1]["rowNo"] + 1
  280. : this.params[key].length + 1;
  281. // 扣税类别
  282. rowData["taxDeductClassify"] = "1";
  283. // 折本汇率
  284. rowData["exchangeRate"] = "1";
  285. // 价格类型
  286. rowData["priceType"] = "order";
  287. // 币种
  288. rowData["currency"] = "1002Z0100000000001K1";
  289. rowData["currencyName"] = "人民币";
  290. }
  291. rowData["insertId"] = new Date().getTime();
  292. // 是否完成询价,新增明细行需默认明细为false
  293. // rowData["whetherCompleteInquiry"] = false;
  294. this.params[key].push(rowData);
  295. }
  296. }
  297. // const arr = this.tabColumns.find(
  298. // (element) => element.key === this.tabName
  299. // ).tableColumns;
  300. // prop.push(initParams(arr, "key", "value"));
  301. },
  302. // 删行
  303. // 删除行
  304. async delTableRow(prop, row, name) {
  305. let delNo = name === "puOrderItemList" ? "rowNo" : "rowno";
  306. if (prop.length === 1) {
  307. this.$alert("订单行不允许为空", "提示", {
  308. confirmButtonText: "确定",
  309. callback: (action) => {
  310. // this.$message({
  311. // type: 'info',
  312. // message: `action: ${ action }`
  313. // });
  314. },
  315. });
  316. } else {
  317. for (const key in this.params) {
  318. if (key === "puOrderItemList" || key === "puOrderExecuteList") {
  319. this.params[key].forEach((item, index) => {
  320. let flag = key === "puOrderItemList" ? "rowNo" : "rowno";
  321. // if(item.id && item.id === row.id){
  322. // console.log('删除已有ID的');
  323. // item['delFlag'] = '2';
  324. // }
  325. if (item[flag] && item[flag] === row[delNo]) {
  326. item.id
  327. ? (item["delFlag"] = "2")
  328. : this.params[key].splice(index, 1);
  329. }
  330. });
  331. // this.params[key][index].id ?
  332. // (this.params[key][index]['delFlag'] = '2') :
  333. // this.params[key].splice(index, 1);
  334. }
  335. }
  336. await this.handleGetPrice();
  337. }
  338. },
  339. // 同步子表物料
  340. handleSynchronousMaterial(tableOne, tableTwo) {
  341. let _this = this;
  342. // this.params[tableOne]-- -> this.params[tableTwo]
  343. this.params[tableOne] &&
  344. this.params[tableOne].forEach((item, index) => {
  345. for (const key in item) {
  346. if (!_this.params[tableTwo][index]) {
  347. const arr = _this.tabColumns.find(
  348. (element) => element.key === tableTwo
  349. ).tableColumns;
  350. _this.params[tableTwo].push(initParams(arr, "key", "value"));
  351. }
  352. if (key in _this.params[tableTwo][index]) {
  353. _this.params[tableTwo][index].material = item.material;
  354. key !== "id" && (_this.params[tableTwo][index][key] = item[key]);
  355. }
  356. }
  357. });
  358. },
  359. // 取消
  360. handleCancel() {
  361. this.params = {
  362. ...initParams(this.columns),
  363. puOrderItemList: [],
  364. // puOrderExecuteList: [],
  365. };
  366. this.setVisible(false);
  367. },
  368. // 判断保存条件
  369. judgeSaveCondition(cb) {
  370. this.$refs["orderAddForm"].validate(async (valid) => {
  371. if (valid) {
  372. if (
  373. !this.params["puOrderItemList"].length
  374. // || !this.params["puOrderExecuteList"].length
  375. ) {
  376. this.$notify.error({
  377. title: "错误",
  378. message: "请填写订单行!",
  379. });
  380. return false;
  381. }
  382. // puOrderItemList
  383. // let isPrice = this.params.puOrderItemList.filter(item => !item.whetherCompleteInquiry);
  384. // if(isPrice.length && this.role === 'procurementManager'){
  385. // this.$notify.error({
  386. // title: '错误',
  387. // message: '询价失败!'
  388. // });
  389. // return false
  390. // }
  391. cb();
  392. } else {
  393. this.$notify.error({
  394. title: "错误",
  395. message: "存在必填项未填写",
  396. });
  397. console.log("error submit!!");
  398. return false;
  399. }
  400. });
  401. },
  402. // 保存
  403. handleSava() {
  404. console.log(this.params, "this.params---------");
  405. this.judgeSaveCondition(async () => {
  406. try {
  407. this.loading = true;
  408. const { code, msg } = await orderApi.create(this.params);
  409. if (code === 200) {
  410. this.handleCancel();
  411. }
  412. } catch (err) {
  413. //
  414. } finally {
  415. this.loading = false;
  416. }
  417. });
  418. },
  419. judgeGoodsAllocation(porp) {
  420. if (porp === "Y") {
  421. this.rules.goodsAllocationName = [
  422. { required: true, message: "货位不能为空", trigger: "change" },
  423. ];
  424. } else {
  425. this.rules.goodsAllocationName = null;
  426. }
  427. this.count++;
  428. },
  429. // 主表参照改变之后
  430. async handleReferChange(val, type, source) {
  431. let page = { pageNum: 1, pageSize: 10 };
  432. // 供应商选择
  433. if (type === "SUPPLIER_PARAM") {
  434. let relevanceRefer = [
  435. {
  436. // 供应商联系人
  437. key: "supplierContacts",
  438. params: {
  439. type: "SUPPLIERCONTACTS_PARAM",
  440. supplierId: val.id,
  441. },
  442. },
  443. {
  444. // 供应商业务员
  445. key: "supplierPersonal",
  446. params: {
  447. type: "PSNLICENSE_PARAM",
  448. supplierId: val.id,
  449. pkOrg: source.puOrg,
  450. },
  451. },
  452. ];
  453. try {
  454. let promiseArr = relevanceRefer.map((refer) => {
  455. return new Promise((resolve, reject) => {
  456. orderApi
  457. .REFER(
  458. {
  459. ...refer.params,
  460. search: "",
  461. isPage: true,
  462. },
  463. page
  464. )
  465. .then((res) => {
  466. let { code, rows } = res;
  467. if (code === 200) {
  468. source[refer.key] = rows[0] ? rows[0].id : "";
  469. source[`${refer.key}Name`] = rows[0] ? rows[0].name : "";
  470. resolve();
  471. }
  472. });
  473. });
  474. });
  475. Promise.all(promiseArr).then(async () => {
  476. // 明细不为空的情况下进行询价
  477. let detailList = this.params["puOrderItemList"].filter(
  478. (item) => item.material && item.material != ""
  479. );
  480. if (detailList.length) {
  481. await this.handleGetPrice();
  482. }
  483. });
  484. } catch (error) {}
  485. }
  486. // 组织
  487. if (type === "ORG_PARAM") {
  488. for (const key in this.params) {
  489. // if (Array.isArray(this.params[key])) {
  490. if (key === "puOrderItemList" || key === "puOrderExecuteList") {
  491. this.params[key] = [];
  492. } else if (key === "sysFileRecordList") {
  493. this.params[key] = [];
  494. } else if (
  495. key != "puOrg" &&
  496. key != "puOrgName" &&
  497. // key != "buyer" &&
  498. // key != "buyerName" &&
  499. // key != "puDept" &&
  500. // key != "puDeptName" &&
  501. // key != "status" &&
  502. key != "billDate" &&
  503. key != "createTime"
  504. ) {
  505. this.params[key] = "";
  506. } else {
  507. }
  508. }
  509. }
  510. // WMS仓库
  511. if (type === "WAREHOUSE_PARAM") {
  512. // 货位在表头
  513. // this.judgeGoodsAllocation(val.csFlag);
  514. // source.goodsAllocation = "";
  515. // source.goodsAllocationName = "";
  516. // 货位在表体
  517. this.params.puOrderItemList = this.params.puOrderItemList.map(
  518. (item) => ({
  519. ...item,
  520. goodsAllocation: "",
  521. goodsAllocationName: "",
  522. })
  523. );
  524. }
  525. },
  526. // 下拉框选择改变
  527. handleSelectChange(val, typeName) {
  528. if (val === "billType") {
  529. this.params["billTypeName"] = this.dict.type[typeName].find(
  530. (item) => item.value == this.params[val]
  531. ).label;
  532. }
  533. },
  534. // 子表参照改变之后
  535. async handleTabReferChange(val, props, source) {
  536. // let { type, copy, dataMapping } = props;
  537. let { params, tabName } = this;
  538. console.log(val, "val", props, "props", source, "source");
  539. // // 复制
  540. // if (copy) {
  541. // if (type == "MATERIAL_PARAM") {
  542. // for (let i = 1; i < val.length; i++) {
  543. // this.addTableRow(params[tabName]);
  544. // }
  545. // let value = val.map((item) => {
  546. // let columnValue = {};
  547. // for (let key in dataMapping) {
  548. // columnValue[key] = item[dataMapping[key]];
  549. // }
  550. // return columnValue;
  551. // });
  552. // }
  553. // }
  554. // 触发物料参照询价
  555. if (props == "MATERIAL_PARAM" && source.qty && source.qty != "") {
  556. source["qty"] = 0;
  557. // source['whetherCompleteInquiry'] = false;
  558. source["taxPrice"] = 0;
  559. source["money"] = 0;
  560. source["taxDeductMoneya"] = 0;
  561. source["price"] = 0;
  562. source["notaxMoney"] = 0;
  563. source["tax"] = 0;
  564. this.params["qty"] = 0;
  565. this.params["originalQty"] = 0;
  566. this.params["money"] = 0;
  567. this.params["originalMoney"] = 0;
  568. this.params["notaxMoney"] = 0;
  569. source.isDrug = val.materialMedcine.isDrug == "0" ? "Y" : "N";
  570. // await this.handleGetPrice();
  571. }
  572. // 物料触发税率
  573. if (props == "MATERIAL_PARAM") {
  574. let { rateCode } = source;
  575. console.log(rateCode, "rateCode-------");
  576. try {
  577. // try
  578. this.loading = true;
  579. const { ntaxrate } = await tax(rateCode);
  580. source.tax = ntaxrate === "0E-8" ? 0 : ntaxrate;
  581. } catch (err) {
  582. // catch
  583. console.error(err);
  584. } finally {
  585. // finally
  586. this.loading = false;
  587. }
  588. }
  589. },
  590. // 子表下拉框改变
  591. async handleTabSelectChange(type, row) {
  592. if (type == "priceType" && row.material && row.qty && row.qty != "") {
  593. // row['whetherCompleteInquiry'] = false;
  594. await this.handleGetPrice();
  595. }
  596. },
  597. // 子表inputNumber
  598. handleInputChange(row, type) {
  599. // 物料数量变化----询价
  600. if (
  601. (type == "qty" || type == "taxPrice" || type == "taxDeductMoneya") &&
  602. row.material
  603. ) {
  604. // row['whetherCompleteInquiry'] = false;
  605. this.handleGetPrice();
  606. }
  607. this.$refs.puOrderItemList[0].updateFooter();
  608. // this.$refs.puOrderExecuteList[0].updateFooter();
  609. // if(this.role === 'syfz-purchaseorder' && row.material && (type == "qty" ||type === "taxPrice" )){
  610. // row.money = row.qty * row.taxPrice;
  611. // }
  612. },
  613. // 子表多选框改变
  614. handleTabCheckbox(type, source) {
  615. // 勾选赠品,价税合计更新为0,含税单价、无税单价更新为0
  616. if (
  617. type === "isGift" &&
  618. source.material &&
  619. source.qty &&
  620. source.qty != ""
  621. ) {
  622. // source['whetherCompleteInquiry'] = false;
  623. this.handleGetPrice();
  624. }
  625. },
  626. // 询价 getPrice
  627. async handleGetPrice() {
  628. try {
  629. // action:insert(新增)、revise(修订)、update(编辑)
  630. let { code, data } = await orderApi.getPrice({
  631. ...this.params,
  632. action: "insert",
  633. });
  634. if (code == 200) {
  635. this.params = { ...data };
  636. }
  637. } catch (error) {}
  638. },
  639. async handelImport(fileList) {
  640. try {
  641. let formData = new FormData();
  642. formData.append("file", fileList[0].raw);
  643. let tabList = {
  644. puOrderItemList: [...this.params.puOrderItemList],
  645. warehouse: this.params.warehouse,
  646. // puOrderExecuteList: [...this.params.puOrderExecuteList],
  647. };
  648. const blob = new Blob([JSON.stringify(tabList)], {
  649. type: "application/json",
  650. });
  651. formData.append("tabList", blob);
  652. this.$modal.loading("正在上传文件,请稍候...");
  653. let {
  654. code,
  655. data: { puOrderItemList, puOrderExecuteList },
  656. } = await orderApi.orderImport(formData);
  657. if (code == 200) {
  658. // for (const key in data) {
  659. // this.params[key].push(...data[key]);
  660. // }
  661. this.params["puOrderItemList"] = [...puOrderItemList];
  662. this.params["puOrderExecuteList"] = [...puOrderExecuteList];
  663. let { setVisible } = this.$refs.batchImport;
  664. setVisible(false);
  665. this.handleGetPrice();
  666. }
  667. } catch (error) {
  668. } finally {
  669. this.$modal.closeLoading();
  670. }
  671. },
  672. async handleTemDownload() {
  673. this.download(
  674. "/pu/order/downloadFailData",
  675. {},
  676. `采购订单物料信息模板${new Date().getTime()}.xlsx`
  677. );
  678. },
  679. getSummaries({ columns, data }) {
  680. const means = []; // 合计
  681. let { tabColumns, tabName } = this;
  682. columns.forEach((column, columnIndex) => {
  683. if (columnIndex === 0) {
  684. means.push("合计");
  685. } else {
  686. const values = data.map((item) => Number(item[column.property]));
  687. let sumColumn = tabColumns
  688. .find((tab) => tab.key === tabName)
  689. .tableColumns.filter((item) => item.hidden)
  690. .filter(
  691. ({ key, isSummary }) => isSummary && key === column.property
  692. );
  693. // 合计
  694. // if (!values.every(value => isNaN(value))) {
  695. if (sumColumn.length) {
  696. means[columnIndex] = values.reduce((prev, curr) => {
  697. const value = Number(curr);
  698. if (!isNaN(value)) {
  699. return prev + curr;
  700. } else {
  701. return prev;
  702. }
  703. }, 0);
  704. means[columnIndex] = means[columnIndex].toFixed(2);
  705. } else {
  706. means[columnIndex] = "";
  707. }
  708. }
  709. });
  710. // sums[index] = sums[index] && sums[index].toFixed(2); // 保留2位小数,解决小数合计列
  711. return [means];
  712. },
  713. // 子表-批量复制
  714. async tabCopyChange(prop, { column, source }) {
  715. let { key, referName, dataMapping } = column;
  716. try {
  717. this.tabLoading = true;
  718. if (key === "materialCode") {
  719. let {
  720. code,
  721. data: { puOrderItemList },
  722. } = await orderApi.materialCopy({
  723. materialCode: prop,
  724. puOrderItemList: this.params.puOrderItemList.filter(
  725. (item) => item.rowNo != source.rowNo
  726. ),
  727. // puOrderExecuteList
  728. });
  729. if (code == 200) {
  730. this.params.puOrderItemList = [...puOrderItemList];
  731. // this.params.puOrderExecuteList = [...puOrderExecuteList];
  732. }
  733. } else {
  734. let params = {
  735. searchList: prop,
  736. type: referName,
  737. };
  738. key === "goodsAllocationName" &&
  739. (params["stordocId"] = this.params.warehouse);
  740. let { code, rows } = await orderApi.REFER(params);
  741. if (code == 200) {
  742. !rows.length &&
  743. this.$notify.warning({
  744. message: "粘贴数据检索为空,请检查是否符合要求!",
  745. });
  746. rows = rows.map((item) => {
  747. let obj = {};
  748. for (const key in dataMapping) {
  749. obj[key] = item[dataMapping[key]];
  750. }
  751. return obj;
  752. });
  753. let invariant = this.params.puOrderItemList.filter(
  754. (item) => item.rowNo < source.rowNo
  755. );
  756. let change = this.params.puOrderItemList
  757. .filter((item) => !(item.rowNo < source.rowNo))
  758. .map((item, index) => {
  759. return {
  760. ...item,
  761. ...rows[index],
  762. };
  763. });
  764. this.params.puOrderItemList = [...invariant, ...change];
  765. }
  766. }
  767. } catch (error) {
  768. } finally {
  769. this.tabLoading = false;
  770. }
  771. },
  772. inputTabChange(prop, { column, source }) {
  773. let { key, copy } = column;
  774. // 数量-批量复制
  775. if (copy) {
  776. if (key === "qty") {
  777. let munList = prop.split(/,|,|\s+/);
  778. let invariant = this.params.puOrderItemList.filter(
  779. (item) => item.rowNo < source.rowNo
  780. );
  781. let change = this.params.puOrderItemList
  782. .filter((item) => !(item.rowNo < source.rowNo))
  783. .map((item, index) => {
  784. return {
  785. ...item,
  786. qty: munList[index] || item.qty,
  787. };
  788. });
  789. this.params.puOrderItemList = [...invariant, ...change];
  790. this.handleGetPrice();
  791. }
  792. }
  793. },
  794. onHide(prop) {
  795. this.innerColumns = prop;
  796. },
  797. },
  798. created() {
  799. console.log("ADD CREATED", this.params);
  800. },
  801. mounted() {},
  802. updated() {
  803. this.$nextTick(() => {
  804. // this.$refs.puOrderExecuteList &&
  805. // this.$refs.puOrderExecuteList[0].doLayout();
  806. this.$refs.puOrderItemList && this.$refs.puOrderItemList[0].doLayout();
  807. });
  808. },
  809. destroyed() {},
  810. };
  811. </script>
  812. <template>
  813. <el-drawer
  814. direction="btt"
  815. size="100%"
  816. :with-header="false"
  817. :visible.sync="visible"
  818. @open="beforeOpen"
  819. @close="$emit('close')"
  820. v-loading="loading"
  821. >
  822. <el-form
  823. :size="size"
  824. label-position="right"
  825. ref="orderAddForm"
  826. class="orderAddForm"
  827. label-width="140px"
  828. :model="params"
  829. :rules="rules"
  830. :key="count"
  831. >
  832. <el-card
  833. :body-style="{
  834. padding: '20px 20px 10px',
  835. display: 'flex',
  836. 'flex-wrap': 'wrap',
  837. }"
  838. style="margin: 10px"
  839. >
  840. <div
  841. slot="header"
  842. style="
  843. display: flex;
  844. justify-content: space-between;
  845. align-items: center;
  846. "
  847. >
  848. <h3>新增</h3>
  849. <div style="text-align: right">
  850. <el-button :size="size" type="primary" @click="handleSava"
  851. >保存</el-button
  852. >
  853. <el-button :size="size" @click="handleCancel">取消</el-button>
  854. </div>
  855. </div>
  856. <el-row style="display: flex; flex-wrap: wrap">
  857. <el-col
  858. v-for="(column, index) in columns"
  859. :key="index"
  860. :span="column.span || 6"
  861. >
  862. <el-form-item
  863. :prop="column.key"
  864. :label="column.title"
  865. v-if="column.isShow"
  866. >
  867. <el-input
  868. v-if="column.inputType === 'Input'"
  869. v-model="params[column.key]"
  870. :placeholder="column.placeholder"
  871. :clearable="column.clearable"
  872. :disabled="column.disabled"
  873. style="width: 100%"
  874. >
  875. </el-input>
  876. <dr-popover-select
  877. v-if="column.inputType === 'PopoverSelect'"
  878. v-model="params[column.key]"
  879. :value-key="column.valueKey"
  880. :source.sync="params"
  881. :title="column.title"
  882. :type="column.referName"
  883. :disabled="column.disabled"
  884. :multiple="column.multiple"
  885. :placeholder="column.placeholder"
  886. :data-mapping="column.dataMapping"
  887. :query-params="column.queryParams"
  888. @change="handleReferChange"
  889. ></dr-popover-select>
  890. <el-input
  891. v-if="column.inputType === 'Textarea'"
  892. v-model="params[column.key]"
  893. type="textarea"
  894. :rows="column.rows"
  895. :placeholder="column.placeholder"
  896. :clearable="column.clearable"
  897. :disabled="column.disabled"
  898. style="width: 100%"
  899. ></el-input>
  900. <el-input-number
  901. v-if="column.inputType === 'InputNumber'"
  902. v-model="params[column.key]"
  903. :precision="column.precision"
  904. :controls-position="column.controlsPosition"
  905. :placeholder="column.placeholder"
  906. :clearable="column.clearable"
  907. :disabled="column.disabled"
  908. style="width: 100%"
  909. >
  910. </el-input-number>
  911. <el-select
  912. v-if="column.inputType === 'Select'"
  913. v-model="params[column.key]"
  914. :disabled="column.disabled"
  915. :clearable="column.clearable"
  916. :placeholder="column.placeholder"
  917. style="width: 100%"
  918. filterable
  919. @change="handleSelectChange(column.key, column.referName)"
  920. >
  921. <el-option
  922. v-for="item in dict.type[column.referName]"
  923. :key="item.value"
  924. :label="item.label"
  925. :value="item.value"
  926. ></el-option>
  927. </el-select>
  928. <el-select
  929. v-if="column.inputType === 'TagSelect'"
  930. v-model="params[column.key]"
  931. multiple
  932. clearable
  933. collapse-tags
  934. :placeholder="column.placeholder"
  935. :clearable="column.clearable"
  936. :disabled="column.disabled"
  937. style="width: 100%"
  938. >
  939. <template #prefix>
  940. <el-icon
  941. class="el-icon-view"
  942. style="cursor: pointer"
  943. @click.stop="$message.info(234)"
  944. >
  945. </el-icon>
  946. </template>
  947. <el-option
  948. v-for="item in options"
  949. :key="item.value"
  950. :label="item.label"
  951. :value="item.value"
  952. ></el-option>
  953. </el-select>
  954. <el-date-picker
  955. v-if="column.inputType === 'DatePicker'"
  956. v-model="params[column.key]"
  957. :type="column.type"
  958. :placeholder="column.placeholder"
  959. :clearable="column.clearable"
  960. :disabled="column.disabled"
  961. :picker-options="column.pickerOptions"
  962. style="width: 100%"
  963. ></el-date-picker>
  964. <el-checkbox
  965. v-if="column.inputType === 'Checkbox'"
  966. v-model="params[column.key]"
  967. :disabled="column.disabled"
  968. true-label="Y"
  969. false-label="N"
  970. ></el-checkbox>
  971. <file-upload-center
  972. v-if="column.inputType === 'Upload'"
  973. v-model="params[column.key]"
  974. :file-type="column.fileType"
  975. ></file-upload-center>
  976. </el-form-item>
  977. </el-col>
  978. </el-row>
  979. </el-card>
  980. <el-card
  981. :body-style="{
  982. padding: '20px',
  983. display: 'flex',
  984. 'flex-wrap': 'wrap',
  985. position: 'relative',
  986. }"
  987. style="margin: 10px"
  988. >
  989. <el-tabs v-model="tabName" style="width: 100%" v-loading="tabLoading">
  990. <el-tab-pane
  991. v-for="(column, index) in tabColumns"
  992. :key="index"
  993. :label="column.title"
  994. :name="column.key"
  995. >
  996. <ux-grid
  997. border
  998. use-virtual
  999. keep-source
  1000. show-summary
  1001. show-overflow
  1002. beautify-table
  1003. :ref="column.key"
  1004. :size="size"
  1005. :height="tabHeight"
  1006. style="width: 100%"
  1007. :data="params[column.key]"
  1008. :summary-method="getSummaries"
  1009. :header-row-style="{
  1010. color: '#515a6e',
  1011. }"
  1012. >
  1013. <template slot="empty">暂无数据</template>
  1014. <ux-table-column
  1015. v-for="(cColumn, cIndex) in column.tableColumns.filter(
  1016. (item) => item.hidden
  1017. )"
  1018. :key="cColumn.key + cColumn.hidden"
  1019. :title="cColumn.title"
  1020. :width="cColumn.width || 80"
  1021. :field="cColumn.key"
  1022. resizable
  1023. >
  1024. <template slot="header" slot-scope="scope">
  1025. <span v-if="cColumn.require" style="color: #ff4949">*</span>
  1026. <span>
  1027. {{ cColumn.title }}
  1028. </span>
  1029. </template>
  1030. <template slot-scope="scope">
  1031. <el-form-item label-width="0">
  1032. <el-tag v-if="cColumn.key === 'index'">
  1033. {{ scope.$index + 1 }}
  1034. </el-tag>
  1035. <el-input
  1036. v-if="cColumn.inputType === 'Input'"
  1037. v-model="scope.row[cColumn.key]"
  1038. :placeholder="cColumn.placeholder"
  1039. :clearable="cColumn.clearable"
  1040. :disabled="cColumn.disabled"
  1041. :size="size"
  1042. style="width: 100%"
  1043. @change="
  1044. (prop) =>
  1045. inputTabChange(prop, {
  1046. column: cColumn,
  1047. source: scope.row,
  1048. })
  1049. "
  1050. ></el-input>
  1051. <!-- copy -->
  1052. <dr-popover-select
  1053. v-if="cColumn.inputType === 'PopoverSelect'"
  1054. v-model="scope.row[cColumn.key]"
  1055. :source.sync="scope.row"
  1056. :title="cColumn.title"
  1057. :value-key="cColumn.valueKey"
  1058. :type="cColumn.referName"
  1059. :disabled="cColumn.disabled"
  1060. :multiple="cColumn.multiple"
  1061. :copy="cColumn.copy"
  1062. :placeholder="cColumn.placeholder"
  1063. :data-mapping="cColumn.dataMapping"
  1064. :query-params="
  1065. cColumn.key !== 'goodsAllocationName'
  1066. ? cColumn.queryParams
  1067. : () => ({
  1068. stordocId: params.warehouse,
  1069. pkOrg: params.puOrg,
  1070. })
  1071. "
  1072. @change="handleTabReferChange"
  1073. @copyChange="
  1074. (prop) =>
  1075. tabCopyChange(prop, {
  1076. column: cColumn,
  1077. source: scope.row,
  1078. })
  1079. "
  1080. >
  1081. </dr-popover-select>
  1082. <el-input-number
  1083. v-if="cColumn.inputType === 'InputNumber'"
  1084. v-model="scope.row[cColumn.key]"
  1085. :disabled="cColumn.disabled"
  1086. :clearable="cColumn.clearable"
  1087. :precision="cColumn.precision"
  1088. :placeholder="cColumn.placeholder"
  1089. :controls-position="cColumn.controlsPosition"
  1090. :min="cColumn.key === 'reservedQty' ? 0 : -Infinity"
  1091. :size="size"
  1092. style="width: 100%"
  1093. @change="handleInputChange(scope.row, cColumn.key)"
  1094. ></el-input-number>
  1095. <el-select
  1096. v-if="cColumn.inputType === 'Select'"
  1097. v-model="scope.row[cColumn.key]"
  1098. filterable
  1099. :size="size"
  1100. :disabled="cColumn.disabled"
  1101. :clearable="cColumn.clearable"
  1102. :placeholder="cColumn.placeholder"
  1103. style="width: 100%"
  1104. @change="handleTabSelectChange(cColumn.key, scope.row)"
  1105. >
  1106. <el-option
  1107. v-for="item in dict.type[cColumn.referName]"
  1108. :key="item.value"
  1109. :label="item.label"
  1110. :value="item.value"
  1111. ></el-option>
  1112. </el-select>
  1113. <el-checkbox
  1114. v-if="cColumn.inputType === 'Checkbox'"
  1115. v-model="scope.row[cColumn.key]"
  1116. :disabled="cColumn.disabled"
  1117. true-label="Y"
  1118. false-label="N"
  1119. @change="handleTabCheckbox(cColumn.key, scope.row)"
  1120. ></el-checkbox>
  1121. </el-form-item>
  1122. </template>
  1123. </ux-table-column>
  1124. <ux-table-column fixed="right" label="操作" width="80">
  1125. <template slot-scope="scope">
  1126. <el-button
  1127. @click.native.prevent="
  1128. delTableRow(params[tabName], scope.row, tabName)
  1129. "
  1130. type="text"
  1131. :size="size"
  1132. >
  1133. 删行
  1134. </el-button>
  1135. </template>
  1136. </ux-table-column>
  1137. </ux-grid>
  1138. </el-tab-pane>
  1139. </el-tabs>
  1140. <el-row style="position: absolute; top: 20px; right: 20px">
  1141. <el-button :size="size" @click="addTableRow(params[tabName])"
  1142. >增行</el-button
  1143. >
  1144. <!-- v-if="role === 'procurementManager'" -->
  1145. <BatchImport
  1146. ref="batchImport"
  1147. @import="handelImport"
  1148. @temDownload="handleTemDownload"
  1149. :fileSize="2"
  1150. ></BatchImport>
  1151. </el-row>
  1152. <el-row style="margin-top: 10px">
  1153. <el-col>
  1154. <button-hide v-model="innerColumns" @change="onHide"></button-hide>
  1155. </el-col>
  1156. </el-row>
  1157. </el-card>
  1158. </el-form>
  1159. </el-drawer>
  1160. </template>
  1161. <style scoped>
  1162. .orderAddForm >>> .el-form-item {
  1163. margin-bottom: 5px;
  1164. }
  1165. ::v-deep .singleTable .el-form-item {
  1166. margin-bottom: 0px;
  1167. }
  1168. ::v-deep.uxbeautifyTableClass
  1169. .elx-header--column
  1170. .elx-resizable.is--line:before {
  1171. height: 100%;
  1172. background-color: #dfe6ec;
  1173. }
  1174. </style>