index.tsx 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349
  1. import { ref, reactive, computed, toRefs, nextTick } from "vue";
  2. import { ColumnProps } from "@/components/LjVxeTable/interface";
  3. import { GetSoftBedMxList, SaveSoftBedQuote, GetSoftBedConfigureList } from "@/api/modules/quote";
  4. import { ALLOW_EDIT_STATE } from "@/config/index";
  5. import { ElButton, ElMessage, ElMessageBox, ElRow, ElCol, ElNotification } from "element-plus";
  6. import { AuditSoftBedQuote, DeleteSoftBedQuote } from "@/api/modules/quote";
  7. import { getDeptList } from "@/api/modules/saleprice";
  8. import { CommonDynamicSelect } from "@/api/modules/common";
  9. import SoftBedSelect from "@/views/system/selector/softbedTemplate/select.vue";
  10. import { cloneDeep } from "lodash-es";
  11. import { getCurrentRecords } from "@/utils/index";
  12. import MtrldefErpSelect from "@/views/system/selector/mtrldefErp/select.vue";
  13. interface defaultState {
  14. /**
  15. * @description 单据当前状态
  16. */
  17. orderStatus: string;
  18. /**
  19. * @description 列表Ref
  20. */
  21. VxeTableRef: any;
  22. /**
  23. * @description 详情页Ref
  24. */
  25. LjDetailRef: any;
  26. /**
  27. * @description 详情页明细表格Ref
  28. */
  29. VxeTableHeadBoardMxRef: any;
  30. /**
  31. * @description 详情页明细表格Ref
  32. */
  33. VxeTableNightStandMxRef: any;
  34. /**
  35. * @description 详情页明细表格Ref
  36. */
  37. VxeTableBedFrameMxRef: any;
  38. /**
  39. *
  40. */
  41. initParams: any;
  42. /**
  43. * @description 详情页主表数据
  44. */
  45. softBed: any;
  46. /**
  47. * @description 详情页主表明细数据
  48. */
  49. softBedMx: any[];
  50. /**
  51. * @description 详情页主表明细数据-床头
  52. */
  53. headBoardMx: any[];
  54. /**
  55. * @description 详情页主表明细数据-床头柜
  56. */
  57. nightStandMx: any[];
  58. /**
  59. * @description 详情页主表明细数据-床架
  60. */
  61. bedFrameMx: any[];
  62. /**
  63. * @description 详情页模板报价弹窗对象
  64. */
  65. SoftBedTemplateDialogRef: any;
  66. /**
  67. * @description 详情页模板报价弹窗入参
  68. */
  69. SoftBedTemplateDialogProps: any;
  70. /**
  71. * @description 详情页部件配置选择弹窗
  72. */
  73. isModalVisible: boolean;
  74. /**
  75. * @description 详情页部件配置选择弹窗
  76. */
  77. showHeadboard: boolean;
  78. /**
  79. * @description 详情页部件配置选择弹窗
  80. */
  81. showNightstand: boolean;
  82. /**
  83. * @description 详情页部件配置选择弹窗
  84. */
  85. showBedframe: boolean;
  86. partsConfig: any;
  87. headboardConfigOptions: any[];
  88. nightstandConfigOptions: any[];
  89. bedframeConfigOptions: any[];
  90. configValueOptionsMap: any;
  91. MtrldefDialogRef: any;
  92. MtrldefDialogProps: any;
  93. }
  94. /**
  95. * @description 表格多选数据操作
  96. * @param {String} rowKey 当表格可以多选时,所指定的 id
  97. * */
  98. export const useHooks = (t?: any) => {
  99. const state = reactive<defaultState>({
  100. orderStatus: "",
  101. VxeTableRef: null,
  102. LjDetailRef: null,
  103. VxeTableHeadBoardMxRef: null,
  104. VxeTableBedFrameMxRef: null,
  105. VxeTableNightStandMxRef: null,
  106. softBed: {},
  107. softBedMx: [],
  108. headBoardMx: [],
  109. nightStandMx: [],
  110. bedFrameMx: [],
  111. SoftBedTemplateDialogRef: null,
  112. SoftBedTemplateDialogProps: null,
  113. isModalVisible: false,
  114. showHeadboard: false,
  115. showNightstand: false,
  116. showBedframe: false,
  117. initParams: { arg_softbed_id: 0 },
  118. partsConfig: {
  119. headboard: [],
  120. nightstand: [],
  121. bedframe: []
  122. },
  123. headboardConfigOptions: [],
  124. nightstandConfigOptions: [],
  125. bedframeConfigOptions: [],
  126. configValueOptionsMap: {},
  127. MtrldefDialogRef: null,
  128. MtrldefDialogProps: {}
  129. });
  130. // 表格配置项
  131. const columns: ColumnProps<any>[] = [
  132. { type: "checkbox", width: 40, fixed: "left" },
  133. {
  134. field: "pid",
  135. title: "序",
  136. width: 40,
  137. basicinfo: {
  138. span: 1,
  139. row: 1
  140. }
  141. },
  142. {
  143. field: "softbed_code",
  144. title: "报价唯一码",
  145. basicinfo: {
  146. span: 1,
  147. row: 1,
  148. order: 1,
  149. group: "单据信息"
  150. }
  151. },
  152. {
  153. field: "deptid",
  154. title: "部门",
  155. enum: () =>
  156. getDeptList({}).then(res => {
  157. return res.datatable.map(t => {
  158. return { ...t, label: t.deptname, value: t.deptid };
  159. });
  160. }),
  161. // fieldNames: { label: "deptname", value: "deptid" },
  162. search: {
  163. el: "select",
  164. key: "arg_deptid",
  165. props: {
  166. filterable: true,
  167. onChange: val => {
  168. state.initParams.arg_deptid = val;
  169. }
  170. },
  171. order: 1
  172. },
  173. basicinfo: {
  174. el: "select",
  175. span: 1,
  176. row: 1,
  177. order: 1,
  178. group: "单据信息",
  179. editable: (scope: any) => {
  180. if (ALLOW_EDIT_STATE.includes(scope.status) && Number(scope.searchParam.softbed_id) <= 0) {
  181. return true;
  182. }
  183. return false;
  184. },
  185. rules: [{ required: true, message: "请先选择部门", trigger: "change" }],
  186. props: {
  187. filterable: true,
  188. clearable: false,
  189. onChange: val => {
  190. wf_get_moneyrate_discount(val);
  191. }
  192. }
  193. }
  194. },
  195. {
  196. field: "is_template",
  197. title: "模板报价",
  198. datatype: "checkbox",
  199. basicinfo: {
  200. el: "checkbox",
  201. props: {
  202. trueValue: 1,
  203. falseValue: 0
  204. },
  205. span: 1,
  206. row: 1,
  207. order: 2,
  208. group: "单据信息"
  209. }
  210. },
  211. {
  212. field: "create_date",
  213. title: "报价日期",
  214. format: "yyyy-MM-dd HH:mm",
  215. basicinfo: {
  216. span: 1,
  217. row: 1,
  218. order: 3,
  219. group: "单据信息"
  220. }
  221. },
  222. {
  223. field: "template_code",
  224. title: "模板编号",
  225. basicinfo: {
  226. el: "select",
  227. span: 1,
  228. row: 1,
  229. order: 4,
  230. group: "单据信息",
  231. render: (scope: any) => {
  232. const { column, searchParam: row, status } = scope;
  233. let params = {
  234. arg_template_id: row.template_id
  235. };
  236. let _disabled = !(ALLOW_EDIT_STATE.includes(state.orderStatus) && !Number(scope.searchParam.is_template));
  237. return (
  238. <>
  239. <SoftBedSelect
  240. value={row.template_code}
  241. {...params}
  242. clearable
  243. disabled={_disabled}
  244. placeholder={row.template_code}
  245. onOpenModal={() => fModelChoseTemplate(row, params)}
  246. onSelect={(val: any) => rModelSetTemplate(row, val)}
  247. onClear={() => rModelClearTemplate(row)}
  248. >
  249. {{
  250. label: () => row.template_code
  251. }}
  252. </SoftBedSelect>
  253. </>
  254. );
  255. }
  256. }
  257. },
  258. {
  259. field: "softbed_name",
  260. title: "报价名称",
  261. basicinfo: {
  262. el: "input",
  263. editable: ALLOW_EDIT_STATE,
  264. span: 1,
  265. row: 1,
  266. order: 5,
  267. group: "单据信息"
  268. }
  269. },
  270. {
  271. field: "template_name",
  272. title: "模板名称",
  273. basicinfo: {
  274. el: "input",
  275. span: 1,
  276. row: 1,
  277. order: 6,
  278. group: "单据信息",
  279. editable: (scope: any) => {
  280. if (ALLOW_EDIT_STATE.includes(scope.status) && !Number(scope.searchParam.is_template)) {
  281. return true;
  282. }
  283. return false;
  284. }
  285. }
  286. },
  287. {
  288. field: "softbed_relcode",
  289. title: "报价编码",
  290. basicinfo: {
  291. el: "input",
  292. editable: ALLOW_EDIT_STATE,
  293. span: 1,
  294. row: 1,
  295. order: 7,
  296. group: "单据信息"
  297. }
  298. },
  299. {
  300. field: "mtrlmode",
  301. title: "物料规格",
  302. basicinfo: {
  303. span: 1,
  304. row: 1,
  305. order: 8,
  306. group: "单据信息"
  307. }
  308. },
  309. {
  310. field: "create_emp",
  311. title: "报价人",
  312. basicinfo: {
  313. span: 1,
  314. row: 1,
  315. order: 9,
  316. group: "单据信息"
  317. }
  318. },
  319. {
  320. field: "mtrltype",
  321. title: "物料类别",
  322. basicinfo: {
  323. span: 1,
  324. row: 1,
  325. order: 10,
  326. group: "单据信息"
  327. }
  328. },
  329. {
  330. field: "has_type",
  331. title: "类型",
  332. visible: false,
  333. basicinfo: {
  334. span: 2,
  335. row: 1,
  336. order: 10,
  337. group: "单据信息",
  338. labelHidden: true,
  339. render: (scope: any) => {
  340. let _disabled = !ALLOW_EDIT_STATE.includes(state.orderStatus);
  341. let _type = _disabled ? "info" : "primary";
  342. return (
  343. <>
  344. <ElRow>
  345. <ElCol span={16}>
  346. <el-checkbox
  347. v-model={scope.searchParam.has_headboard}
  348. true-value={1}
  349. false-value={0}
  350. disabled={_disabled}
  351. label="床头"
  352. class="mr-8"
  353. // onChange={val => autoLoadExtraData_chai(val, "if_m_chai")}
  354. />
  355. <el-checkbox
  356. v-model={scope.searchParam.has_nightstand}
  357. true-value={1}
  358. false-value={0}
  359. disabled={_disabled}
  360. label="床头柜"
  361. class="mr-8"
  362. // onChange={val => autoLoadExtraData_chai(val, "if_z_chai")}
  363. />
  364. <el-checkbox
  365. v-model={scope.searchParam.has_bedframe}
  366. true-value={1}
  367. false-value={0}
  368. disabled={_disabled}
  369. label="床架"
  370. // onChange={val => autoLoadExtraData_chai(val, "if_d_chai")}
  371. />
  372. </ElCol>
  373. <ElCol span={8}>
  374. <ElButton type={_type} size="small" disabled={_disabled} onClick={onOpenConfigureDialog}>
  375. 选择部件配置
  376. </ElButton>
  377. </ElCol>
  378. </ElRow>
  379. </>
  380. );
  381. }
  382. }
  383. },
  384. {
  385. field: "has_headboard",
  386. width: 44,
  387. align: "center",
  388. title: "床头",
  389. basicinfo: {
  390. span: 1,
  391. row: 1,
  392. order: 10,
  393. group: "单据信息",
  394. visible: false
  395. }
  396. },
  397. {
  398. field: "has_nightstand",
  399. width: 58,
  400. align: "center",
  401. title: "床头柜",
  402. basicinfo: {
  403. span: 1,
  404. row: 1,
  405. order: 11,
  406. group: "单据信息",
  407. visible: false
  408. }
  409. },
  410. {
  411. field: "has_bedframe",
  412. basicinfo: {
  413. span: 1,
  414. row: 1,
  415. order: 12,
  416. group: "单据信息",
  417. visible: false
  418. },
  419. width: 44,
  420. align: "center",
  421. title: "床架"
  422. },
  423. {
  424. field: "other_rate",
  425. format: "cutNumber",
  426. basicinfo: {
  427. el: "input-number",
  428. span: 1,
  429. row: 1,
  430. order: 19,
  431. group: "费用信息",
  432. editable: ALLOW_EDIT_STATE
  433. },
  434. title: "额外点数"
  435. },
  436. {
  437. field: "taxes",
  438. title: "税金",
  439. format: "cutNumber",
  440. enum: [
  441. {
  442. label: "不含税",
  443. value: 1
  444. },
  445. {
  446. label: "含税",
  447. value: 1.07
  448. }
  449. ],
  450. basicinfo: {
  451. el: "select",
  452. span: 1,
  453. row: 1,
  454. order: 20,
  455. group: "费用信息",
  456. editable: ALLOW_EDIT_STATE,
  457. render: (scope: any) => {
  458. let optionRender = [];
  459. let _disabled = !ALLOW_EDIT_STATE.includes(scope.status);
  460. scope.enum.map(item => {
  461. optionRender.push(<el-option label={item.label} value={item.value} />);
  462. });
  463. let slotprefix = {
  464. prefix: () => {
  465. return <>{scope.searchParam.taxrate}</>;
  466. }
  467. };
  468. let _taxrate = Number(scope.searchParam.taxrate);
  469. return (
  470. <el-select
  471. v-model={_taxrate}
  472. v-slots={slotprefix}
  473. class="select-text-right"
  474. disabled={_disabled}
  475. onChange={val => funcTaxrateChange(val, scope.searchParam)}
  476. >
  477. {optionRender}
  478. </el-select>
  479. );
  480. }
  481. }
  482. },
  483. {
  484. field: "extras_cost",
  485. format: "cutNumber",
  486. basicinfo: {
  487. el: "input-number",
  488. span: 1,
  489. row: 1,
  490. order: 21,
  491. group: "费用信息",
  492. editable: ALLOW_EDIT_STATE
  493. },
  494. title: "额外费用"
  495. },
  496. {
  497. field: "moneyrate",
  498. title: "币种",
  499. enum: () => {
  500. return GetMoneyRateMapper().then(res => {
  501. return res.datatable;
  502. });
  503. },
  504. render: (scope: any) => {
  505. return (
  506. <>
  507. <div class="flx-justify-between">
  508. <span>
  509. <>{scope.row.moneyrate > 1 ? `美元` : "人民币"}</>
  510. </span>
  511. {scope.row.moneyrate > 1 && (
  512. <span>
  513. <>{scope.row.moneyrate}</>
  514. </span>
  515. )}
  516. </div>
  517. </>
  518. );
  519. },
  520. basicinfo: {
  521. el: "select",
  522. span: 1,
  523. row: 1,
  524. order: 22,
  525. group: "费用信息",
  526. editable: ALLOW_EDIT_STATE,
  527. render: (scope: any) => {
  528. let optionRender = [];
  529. let _disabled = !ALLOW_EDIT_STATE.includes(scope.status);
  530. scope.enum.map(item => {
  531. optionRender.push(<el-option label={item.label} value={item.value} />);
  532. });
  533. let slotprefix = {
  534. prefix: () => {
  535. return <>{scope.searchParam.moneyrate}</>;
  536. }
  537. };
  538. return (
  539. <el-select
  540. v-model={scope.searchParam.money_type}
  541. v-slots={slotprefix}
  542. class="select-text-right"
  543. disabled={_disabled}
  544. onChange={val => wf_get_moneyrate_discount(val)}
  545. >
  546. {optionRender}
  547. </el-select>
  548. );
  549. }
  550. }
  551. },
  552. {
  553. field: "commission",
  554. format: "cutNumber",
  555. basicinfo: {
  556. el: "input-number",
  557. span: 1,
  558. row: 1,
  559. order: 23,
  560. group: "费用信息",
  561. editable: ALLOW_EDIT_STATE
  562. },
  563. title: "佣金"
  564. },
  565. {
  566. field: "dscrp",
  567. title: "备注",
  568. basicinfo: {
  569. el: "input",
  570. editable: ALLOW_EDIT_STATE,
  571. span: 1,
  572. row: 1,
  573. order: 24,
  574. group: "费用信息",
  575. props: {
  576. type: "textarea"
  577. }
  578. }
  579. },
  580. {
  581. field: "foreign_cost",
  582. format: "cutNumber",
  583. basicinfo: {
  584. span: 1,
  585. row: 1,
  586. order: 25,
  587. group: "报价信息",
  588. visible: true,
  589. ishidden: false
  590. },
  591. title: "外币价"
  592. },
  593. {
  594. field: "nottax_dept_cost",
  595. format: "cutNumber",
  596. basicinfo: {
  597. span: 1,
  598. row: 1,
  599. order: 26,
  600. group: "报价信息",
  601. visible: true,
  602. ishidden: false
  603. },
  604. title: "部门售价(不含税)"
  605. },
  606. {
  607. field: "dept_cost",
  608. format: "cutNumber",
  609. basicinfo: {
  610. span: 1,
  611. row: 1,
  612. order: 27,
  613. group: "报价信息",
  614. visible: true,
  615. ishidden: false
  616. },
  617. title: "部门含税价"
  618. },
  619. {
  620. field: "nottax_factory_cost",
  621. format: "cutNumber",
  622. basicinfo: {
  623. span: 1,
  624. row: 1,
  625. order: 28,
  626. group: "报价信息",
  627. visible: true,
  628. ishidden: false
  629. },
  630. title: "不含税出厂价"
  631. },
  632. {
  633. field: "costamt",
  634. format: "cutNumber",
  635. basicinfo: {
  636. span: 1,
  637. row: 1,
  638. order: 29,
  639. group: "报价信息",
  640. visible: true,
  641. ishidden: false
  642. },
  643. title: "报价金额"
  644. },
  645. {
  646. field: "bi_nottax_dept_cost",
  647. basicinfo: {
  648. span: 1,
  649. row: 1,
  650. order: 31,
  651. group: "成本信息",
  652. visible: true,
  653. ishidden: false
  654. },
  655. title: "财务底价"
  656. },
  657. {
  658. field: "total_material_cost",
  659. basicinfo: {
  660. span: 1,
  661. row: 1,
  662. order: 32,
  663. group: "成本信息",
  664. visible: true,
  665. ishidden: false
  666. },
  667. title: "总材料成本"
  668. },
  669. {
  670. field: "total_hr_cost",
  671. basicinfo: {
  672. span: 1,
  673. row: 1,
  674. order: 33,
  675. group: "成本信息",
  676. visible: true,
  677. ishidden: false
  678. },
  679. title: "总人力成本"
  680. },
  681. {
  682. field: "total_cost",
  683. basicinfo: {
  684. span: 1,
  685. row: 1,
  686. order: 34,
  687. group: "成本信息",
  688. visible: true,
  689. ishidden: false
  690. },
  691. title: "总成本"
  692. },
  693. {
  694. field: "flag",
  695. basicinfo: {
  696. span: 1,
  697. row: 1,
  698. order: 30,
  699. group: "其他",
  700. visible: true,
  701. ishidden: false
  702. },
  703. width: 44,
  704. align: "center",
  705. datatype: "checkbox",
  706. title: "审核"
  707. },
  708. {
  709. field: "audit_date",
  710. format: "yyyy-MM-dd HH:mm",
  711. width: 160,
  712. basicinfo: {
  713. span: 1,
  714. row: 1,
  715. order: 31,
  716. group: "其他",
  717. visible: true,
  718. ishidden: false
  719. },
  720. title: "审核日期",
  721. colorder: 26
  722. },
  723. {
  724. field: "audit_emp",
  725. basicinfo: {
  726. span: 1,
  727. row: 1,
  728. order: 32,
  729. group: "其他",
  730. visible: true,
  731. ishidden: false
  732. },
  733. title: "审核人"
  734. },
  735. {
  736. field: "update_date",
  737. format: "yyyy-MM-dd HH:mm",
  738. width: 160,
  739. basicinfo: {
  740. span: 1,
  741. row: 1,
  742. order: 33,
  743. group: "其他",
  744. visible: true,
  745. ishidden: false
  746. },
  747. title: "更新日期"
  748. },
  749. {
  750. field: "update_emp",
  751. basicinfo: {
  752. span: 1,
  753. row: 1,
  754. order: 34,
  755. group: "其他",
  756. visible: true,
  757. ishidden: false
  758. },
  759. title: "更新人"
  760. }
  761. ];
  762. // 明细表格配置项
  763. const columnsMx: ColumnProps<any>[] = [
  764. {
  765. field: "printid",
  766. title: "行号",
  767. width: 50
  768. },
  769. {
  770. field: "allow_edit",
  771. title: "业务修改",
  772. width: 80,
  773. align: "center",
  774. datatype: "checkbox",
  775. editRender: {},
  776. editColRender: (scope: any) => {
  777. const { column, row, status } = scope;
  778. if (Number(row.allow_edit) == 0) {
  779. row.allow_edit = 0;
  780. }
  781. return (
  782. <>
  783. <el-checkbox v-model={row.allow_edit} true-value={1} false-value={0} class="vxe-edit-col-middle"></el-checkbox>
  784. </>
  785. );
  786. }
  787. },
  788. {
  789. field: "pzname",
  790. title: "部件选配项",
  791. visible: false
  792. },
  793. {
  794. field: "pznamemx",
  795. title: "部件选配项值",
  796. editRender: {},
  797. editColRender: (scope: any) => {
  798. const { row } = scope;
  799. const { _mainData } = state.LjDetailRef;
  800. const _disabled = !row.allow_edit && !_mainData.is_template;
  801. const partTypes = {
  802. 1: "headboardConfigOptions",
  803. 2: "nightstandConfigOptions",
  804. 8: "bedframeConfigOptions"
  805. };
  806. const targetArray = partTypes[row.has_type] || "headboardConfigOptions";
  807. const options = state[targetArray]?.map(item => <el-option key={item.pzid} label={item.pzname} value={item} />) || [];
  808. return (
  809. <el-select v-model={row.pzid} disabled={_disabled} valueKey={"pzid"} clearable={true}>
  810. {options}
  811. </el-select>
  812. );
  813. }
  814. },
  815. {
  816. field: "mtrlcode",
  817. title: "物料编码"
  818. },
  819. {
  820. field: "mtrlname",
  821. title: "物料名称规格",
  822. width: 400,
  823. editRender: {},
  824. editColRender: (scope: any) => {
  825. const { $table, column, row, status } = scope;
  826. let field = column.field;
  827. let _label = column.title;
  828. let params = {
  829. keyword: row.mtrlcode
  830. };
  831. return (
  832. <MtrldefErpSelect
  833. value={row.mtrlid}
  834. {...params}
  835. clearable
  836. placeholder={_label}
  837. onOpenModal={() => fModelChoseMtrlErp(row, params)}
  838. onSelect={val => rModelSetMtrlErp(row, val)}
  839. onClear={() => rModelClearMtrlErp(row)}
  840. >
  841. {{
  842. label: () => `${row.mtrlname} ${row.mtrlmode}`
  843. }}
  844. </MtrldefErpSelect>
  845. );
  846. }
  847. },
  848. {
  849. field: "unit",
  850. title: "物料单位"
  851. },
  852. {
  853. field: "cutting_length",
  854. title: "下料长(mm)",
  855. datatype: "number",
  856. editRender: {},
  857. editColRender: (scope: any) => {
  858. const { $table, column, row, status } = scope;
  859. const { _mainData } = state.LjDetailRef;
  860. let _disabled = !Boolean(row.allow_edit) && !Boolean(_mainData.is_template);
  861. return <el-input v-model={scope.row.cutting_length} type="number" disabled={_disabled}></el-input>;
  862. }
  863. },
  864. {
  865. field: "cutting_width",
  866. title: "下料宽(mm)",
  867. datatype: "number",
  868. editRender: {},
  869. editColRender: (scope: any) => {
  870. const { $table, column, row, status } = scope;
  871. const { _mainData } = state.LjDetailRef;
  872. let _disabled = !Boolean(row.allow_edit) && !Boolean(_mainData.is_template);
  873. return <el-input v-model={scope.row.cutting_width} type="number" disabled={_disabled}></el-input>;
  874. }
  875. },
  876. {
  877. field: "cutting_qty",
  878. title: "下料数量",
  879. datatype: "number",
  880. editRender: {},
  881. editColRender: (scope: any) => {
  882. const { $table, column, row, status } = scope;
  883. const { _mainData } = state.LjDetailRef;
  884. let _disabled = !Boolean(row.allow_edit) && !Boolean(_mainData.is_template);
  885. return <el-input v-model={scope.row.cutting_qty} type="number" disabled={_disabled}></el-input>;
  886. }
  887. },
  888. {
  889. field: "useqty",
  890. title: "理论用料量",
  891. datatype: "number"
  892. },
  893. {
  894. field: "use_formula",
  895. title: "用料量公式"
  896. },
  897. {
  898. field: "use_formula_str",
  899. title: "用料量文本公式"
  900. },
  901. {
  902. field: "actual_useqty",
  903. title: "实际用量",
  904. datatype: "number"
  905. },
  906. {
  907. field: "loss_rate",
  908. title: "损耗率",
  909. datatype: "number",
  910. editRender: {},
  911. editColRender: (scope: any) => {
  912. const { $table, column, row, status } = scope;
  913. const { _mainData } = state.LjDetailRef;
  914. let _disabled = !Boolean(row.allow_edit) && !Boolean(_mainData.is_template);
  915. return <el-input v-model={scope.row.loss_rate} type="number" disabled={_disabled}></el-input>;
  916. }
  917. },
  918. {
  919. field: "price",
  920. title: "材料单价",
  921. datatype: "number",
  922. editRender: {},
  923. editColRender: (scope: any) => {
  924. const { $table, column, row, status } = scope;
  925. const { _mainData } = state.LjDetailRef;
  926. let _disabled = !Boolean(row.allow_edit) && !Boolean(_mainData.is_template);
  927. return <el-input v-model={scope.row.loss_rate} type="number" disabled={_disabled}></el-input>;
  928. }
  929. },
  930. {
  931. field: "price_formula",
  932. title: "单价公式"
  933. },
  934. {
  935. field: "price_formula_str",
  936. title: "单价文本公式"
  937. },
  938. {
  939. field: "cost_price",
  940. title: "成本单价",
  941. datatype: "number"
  942. },
  943. {
  944. field: "cost_amt",
  945. title: "成本金额",
  946. datatype: "number"
  947. }
  948. ];
  949. /**
  950. * 详细页获取数据
  951. */
  952. const detail_getData = async (params: any) => {
  953. const result = await GetSoftBedMxList(params);
  954. if (state.orderStatus === "new") {
  955. result.softbed.taxrate = 1;
  956. }
  957. state.softBed = [result.softbed];
  958. state.softBedMx = result.mxList;
  959. state.headBoardMx = result.mxList.filter(item => item.has_type === 1);
  960. state.nightStandMx = result.mxList.filter(item => item.has_type === 2);
  961. state.bedFrameMx = result.mxList.filter(item => item.has_type === 4);
  962. };
  963. /**
  964. * 打开部件配置弹窗
  965. */
  966. const onOpenConfigureDialog = async () => {
  967. const { _mainData } = state.LjDetailRef;
  968. const result = await GetSoftBedConfigureList({ softbed: _mainData });
  969. state.nightstandConfigOptions = [];
  970. state.bedframeConfigOptions = [];
  971. state.headboardConfigOptions = [];
  972. if (result.typeList?.length > 0) {
  973. for (const item of result.typeList) {
  974. if (item.contfigtypename.includes("床头柜")) {
  975. handleConfigItem(item, state.nightstandConfigOptions);
  976. } else if (item.contfigtypename.includes("床架")) {
  977. handleConfigItem(item, state.bedframeConfigOptions);
  978. } else if (item.contfigtypename.includes("床头")) {
  979. handleConfigItem(item, state.headboardConfigOptions);
  980. }
  981. }
  982. }
  983. nextTick(() => {
  984. state.showHeadboard = Boolean(_mainData.has_headboard);
  985. state.showNightstand = Boolean(_mainData.has_nightstand);
  986. state.showBedframe = Boolean(_mainData.has_bedframe);
  987. state.isModalVisible = true;
  988. });
  989. };
  990. const handleConfigItem = (item: any, targetArray: any[]) => {
  991. if (item.codeList?.length > 0) {
  992. for (const code of item.codeList) {
  993. targetArray.push({ pzid: code.pzid, pzname: code.name });
  994. if (code.pzid && code.pzid > 0) {
  995. state.configValueOptionsMap[code.pzid] = [];
  996. if (code.codeMxList?.length > 0) {
  997. state.configValueOptionsMap[code.pzid].push(...code.codeMxList.filter(t => t.pzid === code.pzid));
  998. }
  999. }
  1000. }
  1001. }
  1002. };
  1003. /**
  1004. * 确认部件配置项值
  1005. * @param params 返回内容
  1006. */
  1007. const onConfirmConfigureDialog = (params: any) => {
  1008. const { _mainData } = state.LjDetailRef;
  1009. console.log("partsConfig :>>> ", state.partsConfig);
  1010. nextTick(() => {
  1011. _mainData.has_headboard = Number(state.showHeadboard);
  1012. _mainData.has_nightstand = Number(state.showNightstand);
  1013. _mainData.has_bedframe = Number(state.showBedframe);
  1014. state.isModalVisible = false;
  1015. });
  1016. };
  1017. /**
  1018. * 保存报价
  1019. */
  1020. const onSave = async cb => {
  1021. const { _mainData } = state.LjDetailRef;
  1022. const headboard_table = state.VxeTableHeadBoardMxRef.element.getTableData();
  1023. const nightstand_table = state.VxeTableNightStandMxRef.element.getTableData();
  1024. const bedframe_table = state.VxeTableBedFrameMxRef.element.getTableData();
  1025. const _softbed = cloneDeep(_mainData);
  1026. const _mxList = [];
  1027. _softbed.mxList = _mxList;
  1028. if (headboard_table && headboard_table.length > 0) _mxList.push(headboard_table);
  1029. if (nightstand_table && nightstand_table.length > 0) _mxList.push(nightstand_table);
  1030. if (bedframe_table && bedframe_table.length > 0) _mxList.push(bedframe_table);
  1031. transformData(_softbed);
  1032. const params: any = {
  1033. softbed: _softbed
  1034. };
  1035. try {
  1036. await SaveSoftBedQuote(params)
  1037. .then((res: any) => {
  1038. ElNotification({
  1039. title: "温馨提示",
  1040. message: t("sys.api.sueccessToSave"),
  1041. type: "success"
  1042. });
  1043. cb && cb(res);
  1044. })
  1045. .catch(error => {
  1046. console.log("error !! :>> ", error);
  1047. });
  1048. } catch (error) {
  1049. ElMessage.error(t("sys.api.operationFailed"));
  1050. }
  1051. };
  1052. const transformData = (data: any) => {
  1053. for (let key in data) {
  1054. if (typeof data[key] === "boolean") data[key] = Number(data[key]);
  1055. }
  1056. };
  1057. /**
  1058. * 审核报价
  1059. */
  1060. const onAudit = (list: any) => {
  1061. ElMessageBox.confirm("是否确定要审核单据吗?", "询问", {
  1062. confirmButtonText: "是",
  1063. cancelButtonText: "否",
  1064. type: "warning"
  1065. })
  1066. .then(() => {
  1067. AuditSoftBedQuote({ list, type: 1 }).then(() => {
  1068. ElMessage.success(t("sys.api.operationSuccess"));
  1069. state.VxeTableRef.refresh();
  1070. });
  1071. })
  1072. .catch((e: TypeError) => {
  1073. ElMessage({
  1074. type: "info",
  1075. message: "操作取消"
  1076. });
  1077. });
  1078. };
  1079. /**
  1080. * 撤审报价
  1081. */
  1082. const onCAudit = (list: any) => {
  1083. ElMessageBox.confirm("是否确定要撤审单据吗?", "询问", {
  1084. confirmButtonText: "是",
  1085. cancelButtonText: "否",
  1086. type: "warning"
  1087. })
  1088. .then(() => {
  1089. AuditSoftBedQuote({ list, type: 0 }).then(() => {
  1090. ElMessage.success(t("sys.api.operationSuccess"));
  1091. state.VxeTableRef.refresh();
  1092. });
  1093. })
  1094. .catch((e: TypeError) => {
  1095. ElMessage({
  1096. type: "info",
  1097. message: "操作取消"
  1098. });
  1099. });
  1100. };
  1101. /**
  1102. * 删除报价
  1103. */
  1104. const onDelete = (list: any, cb?: Function) => {
  1105. ElMessageBox.confirm(`是否确定要删除${list.length}张报价单吗?`, "询问", {
  1106. confirmButtonText: t("common.delText"),
  1107. cancelButtonText: "否",
  1108. type: "warning"
  1109. })
  1110. .then(() => {
  1111. DeleteSoftBedQuote({ list }).then(() => {
  1112. ElMessage.success(t("sys.api.operationSuccess"));
  1113. cb && cb();
  1114. state.VxeTableRef.refresh();
  1115. });
  1116. })
  1117. .catch((e: TypeError) => {
  1118. ElMessage({
  1119. type: "info",
  1120. message: "操作取消"
  1121. });
  1122. });
  1123. };
  1124. /**
  1125. * 复制报价
  1126. */
  1127. const onCopyQuote = () => {};
  1128. /**
  1129. * 显示公式
  1130. */
  1131. const onShowFormula = () => {};
  1132. const GetMoneyRateMapper = async () => {
  1133. return CommonDynamicSelect({ dsname: "_Mapper_if_moneyrate", queryparams: {} });
  1134. };
  1135. /**
  1136. * @description 获取部门汇率 和 折扣率
  1137. */
  1138. const wf_get_moneyrate_discount = (val: any) => {
  1139. const { _mainData, enumMap } = state.LjDetailRef;
  1140. let deptEnum = enumMap.get("deptid");
  1141. console.log("deptEnum :>> ", deptEnum);
  1142. if (deptEnum) {
  1143. let depItem = deptEnum.find((item: any) => item.deptid == _mainData.deptid);
  1144. if (depItem) {
  1145. let _moneyrate = !depItem.moneyrate || Number(depItem.moneyrate) == 0 ? 1 : depItem.moneyrate;
  1146. if (val == 0 || !_mainData.money_type) {
  1147. _mainData.money_type = 0;
  1148. _mainData.moneyrate = 1;
  1149. } else {
  1150. _mainData.moneyrate = _moneyrate;
  1151. }
  1152. _mainData.discount = depItem.discount;
  1153. }
  1154. }
  1155. };
  1156. const funcTaxrateChange = async (val: any, data) => {
  1157. data.taxrate = val;
  1158. };
  1159. /**
  1160. * @description 弹窗模块:客户选择
  1161. * @param data 当前数据
  1162. * @param status 当前订单状态
  1163. * @returns Promise
  1164. */
  1165. const fModelChoseTemplate = (data: any, params: any) => {
  1166. return new Promise((resolve, reject) => {
  1167. let _params = {
  1168. arg_search: ""
  1169. };
  1170. state.SoftBedTemplateDialogProps = {
  1171. onSubmit: (res: any) => {
  1172. // submit
  1173. nextTick(() => {
  1174. rModelSetTemplate(data, res.value[0]);
  1175. resolve(1);
  1176. });
  1177. },
  1178. onCancel: (error: any) => {
  1179. // cancel 回调
  1180. }
  1181. };
  1182. state.SoftBedTemplateDialogRef.show(_params);
  1183. });
  1184. };
  1185. /**
  1186. * @description 数据赋值: 联系人
  1187. * @param data 当前数据
  1188. * @param item 当前选择的数据
  1189. */
  1190. const rModelSetTemplate = (data: any, item: any) => {
  1191. data.template_id = Number(item.softbed_id);
  1192. data.template_code = item.softbed_code;
  1193. data.template_name = item.softbed_name;
  1194. };
  1195. /**
  1196. * 清空选择参数
  1197. * @param data
  1198. */
  1199. const rModelClearTemplate = (data: any) => {
  1200. data.template_id = 0;
  1201. data.template_code = "";
  1202. data.template_name = "";
  1203. };
  1204. const toAddMx = async (tableRef: any) => {
  1205. const { _mainData } = state.LjDetailRef;
  1206. const $table = tableRef.element;
  1207. if ($table) {
  1208. // 新增
  1209. const records = {
  1210. softbed_id: _mainData.softbed_id,
  1211. has_type: getHasType(tableRef),
  1212. mtrlname: "",
  1213. mtrlcode: "",
  1214. mtrlmode: "",
  1215. unit: "",
  1216. allow_edit: 0,
  1217. cutting_length: 0,
  1218. cutting_width: 0,
  1219. cutting_qty: 0,
  1220. loss_rate: 0,
  1221. price: 0
  1222. };
  1223. const { row } = await $table.insertAt(records, -1);
  1224. await $table.setCurrentRow(row);
  1225. await $table.setEditRow(row);
  1226. }
  1227. };
  1228. const toDelMx = (tableRef: any) => {
  1229. const { $table } = getCurrentRecords(tableRef);
  1230. ElMessageBox.confirm(`是否确定要删除明细吗?`, "询问", {
  1231. confirmButtonText: t("common.delText"),
  1232. cancelButtonText: "否",
  1233. type: "error"
  1234. })
  1235. .then(() => {
  1236. $table.removeCurrentRow();
  1237. })
  1238. .catch((e: TypeError) => {
  1239. ElMessage({
  1240. type: "info",
  1241. message: "操作取消"
  1242. });
  1243. });
  1244. };
  1245. const getHasType = (tableRef: any) => {
  1246. return tableRef === state.VxeTableHeadBoardMxRef ? 1 : tableRef === state.VxeTableNightStandMxRef ? 2 : 4;
  1247. };
  1248. /**
  1249. * @description 弹窗模块:客户选择
  1250. * @param data 当前数据
  1251. * @param status 当前订单状态
  1252. * @returns Promise
  1253. */
  1254. const fModelChoseMtrlErp = (data: any, params: any) => {
  1255. return new Promise((resolve, reject) => {
  1256. // if (!ALLOW_EDIT_STATE.includes(status)) return;
  1257. let _params = {
  1258. keyword: ""
  1259. };
  1260. state.MtrldefDialogProps = {
  1261. onSubmit: (res: any) => {
  1262. // submit
  1263. console.log("openCustDialog res", res);
  1264. nextTick(() => {
  1265. rModelSetMtrlErp(data, res.value[0]);
  1266. resolve(1);
  1267. });
  1268. },
  1269. onCancel: (error: any) => {
  1270. // cancel 回调
  1271. console.log("openCustDialog error", error);
  1272. }
  1273. };
  1274. state.MtrldefDialogRef.show(_params);
  1275. });
  1276. };
  1277. /**
  1278. * @description 数据赋值: 联系人
  1279. * @param data 当前数据
  1280. * @param item 当前选择的数据
  1281. */
  1282. const rModelSetMtrlErp = (data: any, item: any) => {
  1283. data.mtrlid = Number(item.mtrlid);
  1284. data.mtrlname = item.mtrlname;
  1285. data.mtrlcode = item.mtrlcode;
  1286. data.mtrlmode = item.mtrlmode;
  1287. data.unit = item.unit;
  1288. };
  1289. const rModelClearMtrlErp = (data: any) => {
  1290. data.mtrlid = 0;
  1291. data.mtrlname = "";
  1292. data.mtrlcode = "";
  1293. data.mtrlmode = "";
  1294. data.unit = "";
  1295. };
  1296. return {
  1297. ...toRefs(state),
  1298. columns,
  1299. columnsMx,
  1300. detail_getData,
  1301. toAddMx,
  1302. toDelMx,
  1303. onSave,
  1304. onAudit,
  1305. onCAudit,
  1306. onDelete,
  1307. onCopyQuote,
  1308. onShowFormula,
  1309. onConfirmConfigureDialog
  1310. };
  1311. };