plm前端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1216 lines
39 KiB

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
10 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
9 months ago
1 year ago
9 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
10 months ago
1 year ago
10 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
10 months ago
9 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
10 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
9 months ago
9 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
10 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
  1. <script>
  2. import {
  3. againQuoteDetail,
  4. deleteQuoteDetail,
  5. queryQuoteDetail,
  6. saveQuoteDetail,
  7. updateQuoteDetail
  8. } from "../../../../api/quote/quoteDetail";
  9. import {getProjectPartList} from "../../../../api/project/project";
  10. import QuoteDetailCost from "./primary/quoteDetailCost.vue";
  11. import QuoteDetailTool from "./primary/quoteDetailTool.vue";
  12. import QuoteDetailBom from "./primary/quoteDetailBom.vue";
  13. import QuoteDetailRouting from "./primary/quoteDetailRouting.vue";
  14. import QuoteDetailOtherCost from "./primary/quoteDetailOtherCost.vue";
  15. import DictDataSelect from "../../sys/dict-data-select.vue";
  16. import QuoteDetailTest from "./primary/quoteDetailTest.vue";
  17. import QuoteDetailOther from "./primary/quoteDetailOther.vue";
  18. export default {
  19. name: "quoteDetail",
  20. components: {
  21. QuoteDetailOther,
  22. QuoteDetailTest,
  23. DictDataSelect,
  24. QuoteDetailOtherCost,
  25. QuoteDetailRouting,
  26. QuoteDetailBom,
  27. QuoteDetailTool,
  28. QuoteDetailCost,
  29. },
  30. props:{
  31. quote:{
  32. type:Object,
  33. required:true
  34. },
  35. height:{
  36. type:[Number,String],
  37. default:300
  38. },
  39. authFlag:{
  40. type:Boolean,
  41. default:false
  42. },
  43. quoteGroupDetail:{
  44. type:Object,
  45. },
  46. saveAuth:{
  47. type:Boolean,
  48. default:true
  49. },
  50. isExport:{
  51. type:Boolean,
  52. default:false
  53. },
  54. },
  55. data(){
  56. return{
  57. quoteDetail:{
  58. id:null,
  59. partNo:'',
  60. partDesc:'',
  61. projectNo:'',
  62. projectDesc:'',
  63. buNo: '*',
  64. qty:null,
  65. quoteCount:1,
  66. partCost:0,
  67. adjustPartCost:0,
  68. labourCost:0,
  69. adjustLabourCost:0,
  70. fabricateCost:0,
  71. adjustFabricateCost:0,
  72. toolCost:0,
  73. adjustToolCost:0,
  74. machineCost:0,
  75. adjustMachineCost:0,
  76. otherCost:0,
  77. manageCost:0,
  78. totalCost:0,
  79. profitRate:0,
  80. profitAmount:0,
  81. totalPrice:0,
  82. unitPrice:0,
  83. taxRate:13,
  84. taxTotalPrice:0,
  85. taxUnitPrice:0,
  86. quoteTotalCost:0,
  87. quoteProfitRate:0,
  88. quoteProfitAmount:0,
  89. quoteTotalPrice:0,
  90. quoteUnitPrice:0,
  91. quoteTaxRate:0,
  92. quoteTaxTotalPrice:0,
  93. quoteTaxUnitPrice:0,
  94. currency1:undefined,
  95. currency2:undefined,
  96. exchangeRate1:undefined,
  97. exchangeRate2:undefined,
  98. currencyTotalCost1:0,
  99. currencyTotalCost2:0,
  100. quoteCurrencyTotalCost1:0,
  101. quoteCurrencyTotalCost2:0,
  102. // moq:'Standard 250K',
  103. moq:'',
  104. calculatedItems:'工具,测试,其他,包装,运输',
  105. testCost:0,
  106. adjustTestCost:0,
  107. elseCost:0,
  108. adjustElseCost:0,
  109. remark:'',
  110. },
  111. saveQuoteDetail:{
  112. },
  113. dataList:[],
  114. saveLoading:false,
  115. queryLoading:false,
  116. saveVisible:false,
  117. saveQuoteDetailRules:{
  118. partNo: [{required: true, message: '请输入物料编码', trigger: ['blur','change']}],
  119. partDesc: [{required: true, message: '请输入物料名称', trigger: ['blur','change']}],
  120. qty: [{required: true, message: '请输入数量', trigger: ['blur','change']}],
  121. currency1: [{required: true, message: '请选择币种', trigger: ['blur','change']}],
  122. },
  123. columns: [
  124. {
  125. userId: this.$store.state.user.name,
  126. functionId: 5011,
  127. serialNumber: '5011Table2PartNo',
  128. tableId: '5011Table2',
  129. tableName: '报价详情信息表',
  130. columnProp: 'plmPartNo',
  131. headerAlign: 'center',
  132. align: 'left',
  133. columnLabel: 'PLM物料编码',
  134. columnHidden: false,
  135. columnImage: false,
  136. columnSortable: false,
  137. sortLv: 0,
  138. status: true,
  139. fixed: '',
  140. columnWidth: 120
  141. },
  142. {
  143. userId: this.$store.state.user.name,
  144. functionId: 5011,
  145. serialNumber: '5011Table2PartNo',
  146. tableId: '5011Table2',
  147. tableName: '报价详情信息表',
  148. columnProp: 'ifsPartNo',
  149. headerAlign: 'center',
  150. align: 'left',
  151. columnLabel: 'IFS物料编码',
  152. columnHidden: false,
  153. columnImage: false,
  154. columnSortable: false,
  155. sortLv: 0,
  156. status: true,
  157. fixed: '',
  158. columnWidth: 120
  159. },
  160. {
  161. userId: this.$store.state.user.name,
  162. functionId: 5011,
  163. serialNumber: '5011Table2PartDesc',
  164. tableId: '5011Table2',
  165. tableName: '报价详情信息表',
  166. columnProp: 'partDesc',
  167. headerAlign: 'center',
  168. align: 'left',
  169. columnLabel: '物料名称',
  170. columnHidden: false,
  171. columnImage: false,
  172. columnSortable: false,
  173. sortLv: 0,
  174. status: true,
  175. fixed: '',
  176. columnWidth: 240
  177. },
  178. {
  179. userId: this.$store.state.user.name,
  180. functionId: 5011,
  181. serialNumber: '5011Table2Qty',
  182. tableId: '5011Table2',
  183. tableName: '报价详情信息表',
  184. columnProp: 'qty',
  185. headerAlign: 'center',
  186. align: 'right',
  187. columnLabel: 'MOQ',
  188. columnHidden: false,
  189. columnImage: false,
  190. columnSortable: false,
  191. sortLv: 0,
  192. status: true,
  193. fixed: '',
  194. columnWidth: 100
  195. },
  196. {
  197. userId: this.$store.state.user.name,
  198. functionId: 5011,
  199. serialNumber: '5011Table2AdjustPartCost',
  200. tableId: '5011Table2',
  201. tableName: '报价详情信息表',
  202. columnProp: 'adjustPartCost',
  203. headerAlign: 'center',
  204. align: 'right',
  205. columnLabel: '材料成本',
  206. columnHidden: false,
  207. columnImage: false,
  208. columnSortable: false,
  209. sortLv: 0,
  210. status: true,
  211. fixed: '',
  212. columnWidth: 130
  213. },
  214. {
  215. userId: this.$store.state.user.name,
  216. functionId: 5011,
  217. serialNumber: '5011Table2AdjustLabourCost',
  218. tableId: '5011Table2',
  219. tableName: '报价详情信息表',
  220. columnProp: 'adjustLabourCost',
  221. headerAlign: 'center',
  222. align: 'right',
  223. columnLabel: '人工成本',
  224. columnHidden: false,
  225. columnImage: false,
  226. columnSortable: false,
  227. sortLv: 0,
  228. status: true,
  229. fixed: '',
  230. columnWidth: 120
  231. },
  232. {
  233. userId: this.$store.state.user.name,
  234. functionId: 5011,
  235. serialNumber: '5011Table2AdjustMachineCost',
  236. tableId: '5011Table2',
  237. tableName: '报价详情信息表',
  238. columnProp: 'adjustMachineCost',
  239. headerAlign: 'center',
  240. align: 'right',
  241. columnLabel: '机器成本',
  242. columnHidden: false,
  243. columnImage: false,
  244. columnSortable: false,
  245. sortLv: 0,
  246. status: true,
  247. fixed: '',
  248. columnWidth: 120
  249. },
  250. {
  251. userId: this.$store.state.user.name,
  252. functionId: 5011,
  253. serialNumber: '5011Table2AdjustToolCost',
  254. tableId: '5011Table2',
  255. tableName: '报价详情信息表',
  256. columnProp: 'adjustToolCost',
  257. headerAlign: 'center',
  258. align: 'right',
  259. columnLabel: '工具成本',
  260. columnHidden: false,
  261. columnImage: false,
  262. columnSortable: false,
  263. sortLv: 0,
  264. status: true,
  265. fixed: '',
  266. columnWidth: 120
  267. },
  268. {
  269. userId: this.$store.state.user.name,
  270. functionId: 5011,
  271. serialNumber: '5011Table2AdjustTestCost',
  272. tableId: '5011Table2',
  273. tableName: '报价详情信息表',
  274. columnProp: 'adjustTestCost',
  275. headerAlign: 'center',
  276. align: 'right',
  277. columnLabel: '测试成本',
  278. columnHidden: false,
  279. columnImage: false,
  280. columnSortable: false,
  281. sortLv: 0,
  282. status: true,
  283. fixed: '',
  284. columnWidth: 120
  285. },
  286. {
  287. userId: this.$store.state.user.name,
  288. functionId: 5011,
  289. serialNumber: '5011Table2AdjustElseCost',
  290. tableId: '5011Table2',
  291. tableName: '报价详情信息表',
  292. columnProp: 'adjustElseCost',
  293. headerAlign: 'center',
  294. align: 'right',
  295. columnLabel: '其他成本',
  296. columnHidden: false,
  297. columnImage: false,
  298. columnSortable: false,
  299. sortLv: 0,
  300. status: true,
  301. fixed: '',
  302. columnWidth: 120
  303. },
  304. {
  305. userId: this.$store.state.user.name,
  306. functionId: 5011,
  307. serialNumber: '5011Table2TotalCost',
  308. tableId: '5011Table2',
  309. tableName: '报价详情信息表',
  310. columnProp: 'totalCost',
  311. headerAlign: 'center',
  312. align: 'right',
  313. columnLabel: '总成本',
  314. columnHidden: false,
  315. columnImage: false,
  316. columnSortable: false,
  317. sortLv: 0,
  318. status: true,
  319. fixed: '',
  320. columnWidth: 80
  321. },
  322. {
  323. userId: this.$store.state.user.name,
  324. functionId: 5011,
  325. serialNumber: '5011Table2QuoteProfitRate',
  326. tableId: '5011Table2',
  327. tableName: '报价详情信息表',
  328. columnProp: 'quoteProfitRate',
  329. headerAlign: 'center',
  330. align: 'right',
  331. columnLabel: 'VA%',
  332. columnHidden: false,
  333. columnImage: false,
  334. columnSortable: false,
  335. sortLv: 0,
  336. status: true,
  337. fixed: '',
  338. columnWidth: 80
  339. },
  340. {
  341. userId: this.$store.state.user.name,
  342. functionId: 5011,
  343. serialNumber: '5011Table2QuoteProfitAmount',
  344. tableId: '5011Table2',
  345. tableName: '报价详情信息表',
  346. columnProp: 'quoteProfitAmount',
  347. headerAlign: 'center',
  348. align: 'right',
  349. columnLabel: 'Contribution%',
  350. columnHidden: false,
  351. columnImage: false,
  352. columnSortable: false,
  353. sortLv: 0,
  354. status: true,
  355. fixed: '',
  356. columnWidth: 100
  357. },
  358. {
  359. userId: this.$store.state.user.name,
  360. functionId: 5011,
  361. serialNumber: '5011Table2QuoteTaxRate',
  362. tableId: '5011Table2',
  363. tableName: '报价详情信息表',
  364. columnProp: 'quoteTaxRate',
  365. headerAlign: 'center',
  366. align: 'right',
  367. columnLabel: 'Margin%',
  368. columnHidden: false,
  369. columnImage: false,
  370. columnSortable: false,
  371. sortLv: 0,
  372. status: true,
  373. fixed: '',
  374. columnWidth: 80
  375. },
  376. {
  377. userId: this.$store.state.user.name,
  378. functionId: 5011,
  379. serialNumber: '5011Table2QuoteTaxTotalPrice',
  380. tableId: '5011Table2',
  381. tableName: '报价详情信息表',
  382. columnProp: 'quoteTaxTotalPrice',
  383. headerAlign: 'center',
  384. align: 'right',
  385. columnLabel: 'Price ¥(ex VAT)',
  386. columnHidden: false,
  387. columnImage: false,
  388. columnSortable: false,
  389. sortLv: 0,
  390. status: true,
  391. fixed: '',
  392. columnWidth: 100
  393. },
  394. {
  395. userId: this.$store.state.user.name,
  396. functionId: 5011,
  397. serialNumber: '5011Table2Qty',
  398. tableId: '5011Table2',
  399. tableName: '报价详情信息表',
  400. columnProp: 'unitPrice',
  401. headerAlign: 'center',
  402. align: 'right',
  403. columnLabel: '未税单价',
  404. columnHidden: false,
  405. columnImage: false,
  406. columnSortable: false,
  407. sortLv: 0,
  408. status: true,
  409. fixed: '',
  410. columnWidth: 100
  411. },
  412. {
  413. userId: this.$store.state.user.name,
  414. functionId: 5011,
  415. serialNumber: '5011Table2Qty',
  416. tableId: '5011Table2',
  417. tableName: '报价详情信息表',
  418. columnProp: 'taxRate',
  419. headerAlign: 'center',
  420. align: 'right',
  421. columnLabel: '税率',
  422. columnHidden: false,
  423. columnImage: false,
  424. columnSortable: false,
  425. sortLv: 0,
  426. status: true,
  427. fixed: '',
  428. columnWidth: 100
  429. },
  430. {
  431. userId: this.$store.state.user.name,
  432. functionId: 5011,
  433. serialNumber: '5011Table2Qty',
  434. tableId: '5011Table2',
  435. tableName: '报价详情信息表',
  436. columnProp: 'exchangeRate1',
  437. headerAlign: 'center',
  438. align: 'right',
  439. columnLabel: '其他税率',
  440. columnHidden: false,
  441. columnImage: false,
  442. columnSortable: false,
  443. sortLv: 0,
  444. status: true,
  445. fixed: '',
  446. columnWidth: 100
  447. },
  448. {
  449. userId: this.$store.state.user.name,
  450. functionId: 5011,
  451. serialNumber: '5011Table2Qty',
  452. tableId: '5011Table2',
  453. tableName: '报价详情信息表',
  454. columnProp: 'taxUnitPrice',
  455. headerAlign: 'center',
  456. align: 'right',
  457. columnLabel: '含税单价(CNY)',
  458. columnHidden: false,
  459. columnImage: false,
  460. columnSortable: false,
  461. sortLv: 0,
  462. status: true,
  463. fixed: '',
  464. columnWidth: 100
  465. },
  466. {
  467. userId: this.$store.state.user.name,
  468. functionId: 5011,
  469. serialNumber: '5011Table2Qty',
  470. tableId: '5011Table2',
  471. tableName: '报价详情信息表',
  472. columnProp: 'currencyDesc2',
  473. headerAlign: 'center',
  474. align: 'right',
  475. columnLabel: '币种',
  476. columnHidden: false,
  477. columnImage: false,
  478. columnSortable: false,
  479. sortLv: 0,
  480. status: true,
  481. fixed: '',
  482. columnWidth: 100
  483. },
  484. {
  485. userId: this.$store.state.user.name,
  486. functionId: 5011,
  487. serialNumber: '5011Table2Qty',
  488. tableId: '5011Table2',
  489. tableName: '报价详情信息表',
  490. columnProp: 'exchangeRate2',
  491. headerAlign: 'center',
  492. align: 'right',
  493. columnLabel: '汇率',
  494. columnHidden: false,
  495. columnImage: false,
  496. columnSortable: false,
  497. sortLv: 0,
  498. status: true,
  499. fixed: '',
  500. columnWidth: 100
  501. },
  502. {
  503. userId: this.$store.state.user.name,
  504. functionId: 5011,
  505. serialNumber: '5011Table2Qty',
  506. tableId: '5011Table2',
  507. tableName: '报价详情信息表',
  508. columnProp: 'currencyTotalCost2',
  509. headerAlign: 'center',
  510. align: 'right',
  511. columnLabel: '含税单价',
  512. columnHidden: false,
  513. columnImage: false,
  514. columnSortable: false,
  515. sortLv: 0,
  516. status: true,
  517. fixed: '',
  518. columnWidth: 100
  519. },
  520. {
  521. userId: this.$store.state.user.name,
  522. functionId: 5011,
  523. serialNumber: '5011Table2Remark',
  524. tableId: '5011Table2',
  525. tableName: '报价详情信息表',
  526. columnProp: 'remark',
  527. headerAlign: 'center',
  528. align: 'left',
  529. columnLabel: '备注',
  530. columnHidden: false,
  531. columnImage: false,
  532. columnSortable: false,
  533. sortLv: 0,
  534. status: true,
  535. fixed: '',
  536. columnWidth: 120
  537. },
  538. ],
  539. partVisible:false,
  540. activeName:'bom',
  541. projectPart:{
  542. },
  543. projectPartList:[],
  544. pageNo:1,
  545. pageSize:20,
  546. pageTotal:0,
  547. partQueryLoading:false,
  548. projectPartColumns:[
  549. {
  550. userId: this.$store.state.user.name,
  551. functionId: 5011,
  552. serialNumber: '5011Table3TestPartNo',
  553. tableId: '5011Table3',
  554. tableName: '项目物料表',
  555. columnProp: 'testPartNo',
  556. headerAlign: 'center',
  557. align: 'left',
  558. columnLabel: '物料编码',
  559. columnHidden: false,
  560. columnImage: false,
  561. columnSortable: false,
  562. sortLv: 0,
  563. status: true,
  564. fixed: '',
  565. columnWidth: 150
  566. },
  567. {
  568. userId: this.$store.state.user.name,
  569. functionId: 5011,
  570. serialNumber: '5011Table3PartDesc',
  571. tableId: '5011Table3',
  572. tableName: '项目物料表',
  573. columnProp: 'partDesc',
  574. headerAlign: 'center',
  575. align: 'left',
  576. columnLabel: '物料名称',
  577. columnHidden: false,
  578. columnImage: false,
  579. columnSortable: false,
  580. sortLv: 0,
  581. status: true,
  582. fixed: '',
  583. columnWidth: 120
  584. },
  585. {
  586. userId: this.$store.state.user.name,
  587. functionId: 5011,
  588. serialNumber: '5011Table3FinalPartNo',
  589. tableId: '5011Table3',
  590. tableName: '项目物料表',
  591. columnProp: 'finalPartNo',
  592. headerAlign: 'center',
  593. align: 'left',
  594. columnLabel: 'IFS物料编码',
  595. columnHidden: false,
  596. columnImage: false,
  597. columnSortable: false,
  598. sortLv: 0,
  599. status: true,
  600. fixed: '',
  601. columnWidth: 150
  602. },
  603. {
  604. userId: this.$store.state.user.name,
  605. functionId: 5011,
  606. serialNumber: '5011Table3CustomerPartNo',
  607. tableId: '5011Table3',
  608. tableName: '项目物料表',
  609. columnProp: 'customerPartNo',
  610. headerAlign: 'center',
  611. align: 'left',
  612. columnLabel: '客户物料编码',
  613. columnHidden: false,
  614. columnImage: false,
  615. columnSortable: false,
  616. sortLv: 0,
  617. status: true,
  618. fixed: '',
  619. columnWidth: 150
  620. },
  621. {
  622. userId: this.$store.state.user.name,
  623. functionId: 5011,
  624. serialNumber: '5011Table3Type',
  625. tableId: '5011Table3',
  626. tableName: '项目物料表',
  627. columnProp: 'type',
  628. headerAlign: 'center',
  629. align: 'left',
  630. columnLabel: '制造类型',
  631. columnHidden: false,
  632. columnImage: false,
  633. columnSortable: false,
  634. sortLv: 0,
  635. status: true,
  636. fixed: '',
  637. columnWidth: 120
  638. },
  639. {
  640. userId: this.$store.state.user.name,
  641. functionId: 5011,
  642. serialNumber: '5011Table3UmId',
  643. tableId: '5011Table3',
  644. tableName: '项目物料表',
  645. columnProp: 'umId',
  646. headerAlign: 'center',
  647. align: 'left',
  648. columnLabel: '单位',
  649. columnHidden: false,
  650. columnImage: false,
  651. columnSortable: false,
  652. sortLv: 0,
  653. status: true,
  654. fixed: '',
  655. columnWidth: 100
  656. },
  657. ],
  658. exportData:[],
  659. exportName: '报价条目明细'+this.dayjs().format('YYYYMMDDHHmmss'),
  660. exportHeader: ["报价条目明细"],
  661. exportFooter: [],
  662. }
  663. },
  664. methods:{
  665. handleSaveQuoteDetail(row){
  666. this.$nextTick(()=>{
  667. if (this.$refs.handleSaveQuoteDetailClick){
  668. this.$refs.saveQuoteDetailForm.clearValidate();
  669. }
  670. })
  671. if (row){
  672. this.saveQuoteDetail = {
  673. ...row
  674. }
  675. }else {
  676. this.saveQuoteDetail = {
  677. ...this.quoteDetail,
  678. createBy:this.$store.state.user.name,
  679. status:'草稿',
  680. active:'Y',
  681. qty:1,
  682. isDetail:false,
  683. }
  684. if (this.quoteGroupDetail){
  685. this.saveQuoteDetail.partNo = this.quoteGroupDetail.partNo
  686. this.saveQuoteDetail.partDesc = this.quoteGroupDetail.partDesc
  687. }
  688. this.$nextTick(()=>{
  689. this.saveQuoteDetail.projectNo = this.quote.projectNo
  690. })
  691. }
  692. this.activeName = 'bom';
  693. this.saveVisible = true;
  694. },
  695. handleDetail(row){
  696. this.saveQuoteDetail = {
  697. ...row
  698. }
  699. this.activeName = 'bom';
  700. this.saveVisible = true;
  701. },
  702. handleDeleteQuoteDetail(row){
  703. this.$alert('确认删除该条报价明细吗?', '提示', {
  704. confirmButtonText: '确定',
  705. cancelButtonText: '取消',
  706. type: 'warning'
  707. }).then(() => {
  708. let params = {
  709. id: row.id,
  710. }
  711. deleteQuoteDetail(params).then(({data}) => {
  712. if (data && data.code === 0) {
  713. this.$message.success(data.msg);
  714. this.handleQueryQuoteDetail();
  715. } else {
  716. this.$message.warning(data.msg);
  717. }
  718. }).catch((error) => {
  719. this.$message.error(error);
  720. })
  721. }).catch(() => {
  722. })
  723. },
  724. handlePartNoBlur(){
  725. let params = {
  726. site:this.$store.state.user.site,
  727. testPartNo:this.saveQuoteDetail.partNo,
  728. projectId: this.quote.projectNo,
  729. no:1,
  730. size:20,
  731. }
  732. getProjectPartList(params).then(({data})=>{
  733. if (data && data.code === 0){
  734. if (data.rows && data.rows.length === 1){
  735. this.dblClickProjectPartTable(data.rows[0])
  736. }else {
  737. this.saveQuoteDetail.partDesc = ''
  738. }
  739. }
  740. })
  741. },
  742. handleQueryQuoteDetail(){
  743. let params = {
  744. quoteId: this.quote.id,
  745. }
  746. if (this.quoteGroupDetail){
  747. params.quoteGroupDetailId=this.quoteGroupDetail.id;
  748. }
  749. this.queryLoading = true;
  750. queryQuoteDetail(params).then(({data})=>{
  751. if (data && data.code === 0){
  752. this.dataList = data.rows
  753. }else {
  754. this.$message.warning(data.msg);
  755. }
  756. this.queryLoading = false;
  757. }).catch((error)=>{
  758. this.$message.error(error);
  759. this.queryLoading = false;
  760. })
  761. },
  762. handleSaveQuoteDetailClick(){
  763. this.$refs.saveQuoteDetailForm.validate((valid,obj) => {
  764. if (valid){
  765. if (this.saveQuoteDetail.id){
  766. this.handleUpdate();
  767. }else {
  768. this.handleSave();
  769. }
  770. }else {
  771. let i = 1;
  772. for (let key in obj) {
  773. this.$message.error(obj[key][0].message);
  774. if (i === 1){
  775. return
  776. }
  777. i++;
  778. }
  779. }
  780. })
  781. },
  782. handleSave(){
  783. let params = {
  784. ...this.saveQuoteDetail,
  785. quoteId: this.quote.id,
  786. quoteNo:this.quote.quoteNo,
  787. site:this.quote.site,
  788. buNo:this.quote.buNo,
  789. versionNo:this.quote.versionNo,
  790. createBy:this.saveQuoteDetail.createBy,
  791. active:'Y',
  792. status:'草稿',
  793. internalInquiryNo:this.quote.insideInquiryNo,
  794. }
  795. if (this.quoteGroupDetail){
  796. params.quoteGroupDetailId=this.quoteGroupDetail.id;
  797. }
  798. this.saveLoading = true;
  799. saveQuoteDetail(params).then(({data})=>{
  800. if (data && data.code === 0){
  801. this.$message.success(data.msg);
  802. this.handleQueryQuoteDetail();
  803. if (this.saveQuoteDetail.isDetail){
  804. this.saveQuoteDetail = {
  805. ...data.row,
  806. }
  807. }else {
  808. this.saveVisible = false;
  809. }
  810. }else {
  811. this.$message.warning(data.msg);
  812. }
  813. this.saveLoading = false
  814. }).catch((error)=>{
  815. this.$message.error(error);
  816. this.saveLoading = false
  817. })
  818. },
  819. handleUpdate(){
  820. let params = {
  821. ...this.saveQuoteDetail,
  822. updateBy:this.$store.state.user.name,
  823. }
  824. updateQuoteDetail(params).then(({data})=>{
  825. if (data && data.code === 0){
  826. this.$message.success(data.msg);
  827. this.handleQueryQuoteDetail();
  828. this.saveVisible = false;
  829. }else {
  830. this.$message.warning(data.msg);
  831. }
  832. }).catch((error)=>{
  833. this.$message.error(error);
  834. })
  835. },
  836. handleClickTab(tab){
  837. if (this.activeName === 'routing'){
  838. this.$refs.routing.handleQueryQuoteDetailBomTree()
  839. }else if (this.activeName === 'tool'){
  840. this.$refs.tool.handleQueryQuoteDetailTool();
  841. }
  842. },
  843. againQuoteDetail(row){
  844. let params = {
  845. ...row
  846. }
  847. againQuoteDetail(params).then(({data})=>{
  848. if (data && data.code === 0){
  849. this.handleQueryQuoteDetail();
  850. this.$message.success(data.msg);
  851. }else {
  852. this.$message.warning(data.msg);
  853. }
  854. }).catch((error)=>{
  855. this.$message.error(error);
  856. })
  857. },
  858. handleQueryPartList(){
  859. this.projectPart = {
  860. testPartNo:this.saveQuoteDetail.partNo,
  861. partDesc:'',
  862. finalPartNo:'',
  863. customerPartNo:'',
  864. site:this.$store.state.user.site,
  865. }
  866. this.partVisible = true;
  867. this.getProjectPartList();
  868. },
  869. getProjectPartList(){
  870. let params = {
  871. ...this.projectPart,
  872. no:this.pageNo,
  873. size:this.pageSize,
  874. }
  875. params.projectId = this.quote.projectNo
  876. this.partQueryLoading = true;
  877. getProjectPartList(params).then(({data})=>{
  878. if (data && data.code === 0){
  879. this.projectPartList = data.rows;
  880. this.pageTotal = data.total;
  881. }
  882. this.partQueryLoading = false;
  883. }).catch((error)=>{
  884. this.partQueryLoading = false;
  885. })
  886. },
  887. handleSizeChange(val){
  888. this.pageSize = val;
  889. this.getProjectPartList();
  890. },
  891. handleCurrentChange(val){
  892. this.pageNo = val;
  893. this.getProjectPartList();
  894. },
  895. dblClickProjectPartTable(row){
  896. this.saveQuoteDetail.partNo = row.testPartNo;
  897. this.saveQuoteDetail.partDesc = row.partDesc;
  898. this.partVisible = false;
  899. },
  900. handleClose(){
  901. this.$emit('close');
  902. this.saveVisible = false;
  903. },
  904. fields() {
  905. let json = "{"
  906. this.columns.forEach((item, index) => {
  907. if (index === this.columns.length - 1) {
  908. json += "\"" + item.columnLabel + "\"" + ":" + "\"" + item.columnProp + "\""
  909. } else {
  910. json += "\"" + item.columnLabel + "\"" + ":" + "\"" + item.columnProp + "\"" + ","
  911. }
  912. })
  913. json += "}"
  914. return eval("(" + json + ")")
  915. },
  916. createExportData() {
  917. return this.dataList;
  918. },
  919. toPartMenu (partNo) {
  920. if (this.$router.resolve(`/part-partInformation`).resolved.name === '404') {
  921. this.$alert('权限不足,访问失败', '警告', {confirmButtonText: '确定',})
  922. } else {
  923. this.$router.push({name:`part-partInformation`,params:{partNo:partNo},})
  924. }
  925. },
  926. },
  927. watch:{
  928. quote(newVal,oldVal){
  929. if (newVal.id){
  930. this.quoteDetail.profitRate = this.quote.markup
  931. this.quoteDetail.quoteProfitRate = this.quote.markup
  932. this.handleQueryQuoteDetail();
  933. }else {
  934. this.dataList = [];
  935. }
  936. },
  937. "saveQuoteDetail.partNo"(newVal,oldVal){
  938. if (newVal){
  939. this.saveQuoteDetail.partNo = newVal.toUpperCase();
  940. }
  941. },
  942. partVisible(newVal,oldVal){
  943. if (newVal === false){
  944. this.partQueryLoading = false
  945. this.pageNo = 1;
  946. this.projectPartList = [];
  947. }
  948. },
  949. quoteGroupDetail(newVal,oldVal){
  950. if (newVal){
  951. this.quoteDetail.profitRate = this.quote.markup
  952. this.quoteDetail.quoteProfitRate = this.quote.markup
  953. this.handleQueryQuoteDetail();
  954. }
  955. },
  956. 'quoteGroupDetail.currentQuoteDetailItemNo'(newVal,oldVal){
  957. // console.log(this.quoteGroupDetail)
  958. // emit事件触发修改
  959. if (this.quoteGroupDetail && this.quoteGroupDetail.currentQuoteDetailItemNo){
  960. this.$emit('currentQuoteDetailItemNo',oldVal);
  961. }
  962. }
  963. },
  964. created() {
  965. this.quoteDetail.profitRate = this.quote.markup
  966. this.quoteDetail.quoteProfitRate = this.quote.markup
  967. this.handleQueryQuoteDetail();
  968. }
  969. }
  970. </script>
  971. <template>
  972. <div>
  973. <template v-if="saveAuth">
  974. <el-button type="primary" v-if="!authFlag" :disabled="quote.status === '下达' || !quote.status" @click="handleSaveQuoteDetail(null)">新增</el-button>
  975. </template>
  976. <template v-if="isExport">
  977. <download-excel
  978. :fields="fields()"
  979. :data="exportData"
  980. type="xls"
  981. :name="exportName"
  982. :header="exportHeader"
  983. :footer="exportFooter"
  984. :fetch="createExportData"
  985. worksheet="导出信息"
  986. class="el-button el-button--primary el-button--medium">
  987. {{ '导出' }}
  988. </download-excel>
  989. </template>
  990. <el-table v-loading="queryLoading" border :data="dataList" style="width: 100%;margin-top: 5px" :height="height">
  991. <el-table-column width="80" align="center" label="默认报价行" v-if="quoteGroupDetail && quoteGroupDetail.status === '草稿'">
  992. <template slot-scope="{row}">
  993. <el-radio
  994. class="radio"
  995. :label="row.itemNo"
  996. :disabled="!isAuth('5011:group:current')"
  997. v-model="quoteGroupDetail.currentQuoteDetailItemNo"
  998. ></el-radio>
  999. </template>
  1000. </el-table-column>·
  1001. <el-table-column type="index" width="55" align="center" label="序号"></el-table-column>
  1002. <el-table-column
  1003. v-for="(item,index) in columns" :key="index"
  1004. :sortable="item.columnSortable"
  1005. :prop="item.columnProp"
  1006. :header-align="item.headerAlign"
  1007. :show-overflow-tooltip="item.showOverflowTooltip"
  1008. :align="item.align"
  1009. :fixed="item.fixed === ''?false:item.fixed"
  1010. :min-width="item.columnWidth"
  1011. :label="item.columnLabel">
  1012. <template slot-scope="scope">
  1013. <template v-if="!quoteGroupDetail && item.columnProp === 'partNo'">
  1014. <el-link style="cursor:pointer;" v-if="!item.columnHidden" @click="toPartMenu(scope.row.partNo)"> {{ scope.row[item.columnProp] }}</el-link>
  1015. <span v-if="item.columnImage"><img :src="scope.row[item.columnProp]" style="width: 100px; height: 80px"/></span>
  1016. </template>
  1017. <template v-else>
  1018. <span v-if="!item.columnHidden">{{ scope.row[item.columnProp] }}</span>
  1019. <span v-if="item.columnImage"><img :src="scope.row[item.columnProp]"
  1020. style="width: 100px; height: 80px"/></span>
  1021. </template>
  1022. </template>
  1023. </el-table-column>
  1024. <el-table-column label="操作" v-if="!authFlag" fixed="right" align="center" width="160">
  1025. <template slot-scope="{row,$index}">
  1026. <template v-if="isAuth('5011:detail:update')">
  1027. <a type="text" v-if="row.status === '草稿'" @click="handleSaveQuoteDetail(row)">编辑</a>
  1028. </template>
  1029. <template v-if="isAuth('5011:detail:remove')">
  1030. <a type="text" v-if="row.status === '草稿'" @click="handleDeleteQuoteDetail(row)">删除</a>
  1031. </template>
  1032. <template v-if="isAuth('5011:detail:again')">
  1033. <a type="text" v-if="row.status !== '下达'" @click="againQuoteDetail(row)">复制明细</a>
  1034. </template>
  1035. <template v-if="isAuth('5011:detail:detail')">
  1036. <a type="text" v-if="row.status === '下达'" @click="handleDetail(row)">详情</a>
  1037. </template>
  1038. </template>
  1039. </el-table-column>
  1040. </el-table>
  1041. <el-dialog :title="`报价明细`" top="10vh" v-drag :visible.sync="saveVisible" append-to-body :width="`${saveQuoteDetail.id?1200:600}px`" :close-on-click-modal="false">
  1042. <el-form :model="saveQuoteDetail" ref="saveQuoteDetailForm" :rules="saveQuoteDetailRules" label-position="top" v-if="!saveQuoteDetail.id">
  1043. <el-row :gutter="20">
  1044. <el-col :span="8">
  1045. <el-form-item label="物料编码" prop="partNo" :show-message="false">
  1046. <span slot="label" v-if="!quoteGroupDetail">
  1047. <a @click="handleQueryPartList">物料编码</a>
  1048. </span>
  1049. <el-input v-model="saveQuoteDetail.partNo" :disabled="quoteGroupDetail" @change="handlePartNoBlur"></el-input>
  1050. </el-form-item>
  1051. </el-col>
  1052. <el-col :span="16">
  1053. <el-form-item label="物料描述" prop="partDesc" :show-message="false">
  1054. <el-input v-model="saveQuoteDetail.partDesc" disabled></el-input>
  1055. </el-form-item>
  1056. </el-col>
  1057. <el-col :span="8">
  1058. <el-form-item label="MOQ" prop="qty" :show-message="false">
  1059. <el-input-number style="width: 100%;" v-model="saveQuoteDetail.qty" :min="1" :step="0" :precision="0" :controls="false"></el-input-number>
  1060. </el-form-item>
  1061. </el-col>
  1062. <el-col :span="8">
  1063. <el-form-item label="币种" prop="currency1" :show-message="false">
  1064. <dict-data-select style="width: 100%" v-if="saveVisible" dict-type="plm_customer_information_customer_customer_currency" v-model="saveQuoteDetail.currency1"></dict-data-select>
  1065. </el-form-item>
  1066. </el-col>
  1067. </el-row>
  1068. <el-row :gutter="20">
  1069. <el-col :span="8">
  1070. <el-form-item label="" :show-message="false">
  1071. <el-checkbox v-model="saveQuoteDetail.isDetail">保存进入报价页面</el-checkbox>
  1072. </el-form-item>
  1073. </el-col>
  1074. <el-col :span="24">
  1075. <el-form-item label="备注" class="auto" :show-message="false">
  1076. <el-input type="textarea" v-model="saveQuoteDetail.remark" :autosize="{minRows: 3, maxRows: 3}"></el-input>
  1077. </el-form-item>
  1078. </el-col>
  1079. </el-row>
  1080. </el-form>
  1081. <el-form v-else :model="saveQuoteDetail" ref="saveQuoteDetailForm" :rules="saveQuoteDetailRules" label-position="top">
  1082. <el-row :gutter="20">
  1083. <el-col :span="4">
  1084. <el-form-item label="物料编码" prop="partNo" :show-message="false">
  1085. <el-input v-model="saveQuoteDetail.partNo" disabled></el-input>
  1086. </el-form-item>
  1087. </el-col>
  1088. <el-col :span="6">
  1089. <el-form-item label="物料描述" prop="partDesc" :show-message="false">
  1090. <el-input v-model="saveQuoteDetail.partDesc" disabled></el-input>
  1091. </el-form-item>
  1092. </el-col>
  1093. <el-col :span="3">
  1094. <el-form-item label="MOQ" prop="qty" :show-message="false">
  1095. <el-input-number v-model="saveQuoteDetail.qty" style="width: 100%;" :controls="false" :disabled="saveQuoteDetail.status === '下达'"></el-input-number>
  1096. </el-form-item>
  1097. </el-col>
  1098. <el-col :span="3">
  1099. <el-form-item label="币种" prop="currency1" :show-message="false">
  1100. <dict-data-select :disabled="saveQuoteDetail.status === '下达'" style="width: 100%" dict-type="plm_customer_information_customer_customer_currency" v-model="saveQuoteDetail.currency1"></dict-data-select>
  1101. </el-form-item>
  1102. </el-col>
  1103. </el-row>
  1104. <el-row :gutter="20">
  1105. <el-col :span="16">
  1106. <el-form-item label="备注" class="auto" :show-message="false">
  1107. <el-input type="textarea" resize="none" :autosize="{minRows: 3, maxRows: 3}" v-model="saveQuoteDetail.remark" :disabled="saveQuoteDetail.status === '下达'"></el-input>
  1108. </el-form-item>
  1109. </el-col>
  1110. </el-row>
  1111. </el-form>
  1112. <el-tabs v-model="activeName" v-if="saveQuoteDetail.id" @tab-click="handleClickTab">
  1113. <el-tab-pane label="材料" name="bom">
  1114. <quote-detail-bom v-if="saveVisible" @close="handleClose" v-model:quoteDetail="saveQuoteDetail"></quote-detail-bom>
  1115. </el-tab-pane>
  1116. <el-tab-pane label="工艺" name="routing">
  1117. <quote-detail-routing ref="routing" v-if="saveVisible" @close="handleClose" v-model:quoteDetail="saveQuoteDetail"></quote-detail-routing>
  1118. </el-tab-pane>
  1119. <el-tab-pane label="工具" name="tool">
  1120. <quote-detail-tool ref="tool" v-if="saveVisible" v-model:quoteDetail="saveQuoteDetail"></quote-detail-tool>
  1121. </el-tab-pane>
  1122. <el-tab-pane label="测试" name="test">
  1123. <quote-detail-test v-if="saveVisible" v-model:quoteDetail="saveQuoteDetail"></quote-detail-test>
  1124. </el-tab-pane>
  1125. <el-tab-pane label="包装&运输" name="otherCost">
  1126. <quote-detail-other-cost v-if="saveVisible" v-model:quoteDetail="saveQuoteDetail"></quote-detail-other-cost>
  1127. </el-tab-pane>
  1128. <el-tab-pane label="其他" name="other">
  1129. <quote-detail-other v-if="saveVisible" v-model:quoteDetail="saveQuoteDetail"></quote-detail-other>
  1130. </el-tab-pane>
  1131. <el-tab-pane label="成本&价格" name="cost">
  1132. <quote-detail-cost v-if="saveVisible" ref="cost" v-model:quoteDetail="saveQuoteDetail"></quote-detail-cost>
  1133. </el-tab-pane>
  1134. </el-tabs>
  1135. <div slot="footer" class="dialog-footer">
  1136. <el-button type="primary" v-if="saveQuoteDetail.status === '草稿'" :loading="saveLoading" @click="handleSaveQuoteDetailClick"> </el-button>
  1137. <el-button @click="saveVisible = false"> </el-button>
  1138. </div>
  1139. </el-dialog>
  1140. <el-dialog v-drag title="物料信息" append-to-body :close-on-click-modal="false" :visible.sync="partVisible">
  1141. <!--搜索条件-->
  1142. <el-form :model="projectPart" ref="projectPartDataForm" :inline="true" label-position="top">
  1143. <el-form-item label="物料编码" prop="testPartNo">
  1144. <el-input v-model="projectPart.testPartNo" clearable/>
  1145. </el-form-item>
  1146. <el-form-item label="物料名称" prop="partDesc">
  1147. <el-input v-model="projectPart.partDesc" clearable/>
  1148. </el-form-item>
  1149. <el-form-item label="IFS物料编码" prop="finalPartNo">
  1150. <el-input v-model="projectPart.finalPartNo" clearable/>
  1151. </el-form-item>
  1152. <el-form-item label="客户物料编码" prop="customerPartNo">
  1153. <el-input v-model="projectPart.customerPartNo" clearable/>
  1154. </el-form-item>
  1155. <el-form-item label=" ">
  1156. <el-button @click="getProjectPartList" type="primary"> </el-button>
  1157. </el-form-item>
  1158. </el-form>
  1159. <el-table height="300px" v-loading="partQueryLoading" stripe border @row-dblclick="dblClickProjectPartTable" :data="projectPartList" ref="projectPartDataTable" :style="{marginTop:'10px'}">
  1160. <el-table-column
  1161. v-for="(item,index) in projectPartColumns" :key="index"
  1162. :sortable="item.columnSortable"
  1163. :prop="item.columnProp"
  1164. :header-align="item.headerAlign"
  1165. :show-overflow-tooltip="item.showOverflowTooltip"
  1166. :align="item.align"
  1167. :fixed="item.fixed===''?false:item.fixed"
  1168. :min-width="item.columnWidth"
  1169. :label="item.columnLabel">
  1170. <template slot-scope="scope">
  1171. <span v-if="!item.columnHidden">{{scope.row[item.columnProp]}}</span>
  1172. <span v-if="item.columnImage"><img :src="scope.row[item.columnProp]" style="width: 100px; height: 80px"/></span>
  1173. </template>
  1174. </el-table-column>
  1175. </el-table>
  1176. <el-pagination style="margin-top: 0"
  1177. @size-change="handleSizeChange"
  1178. @current-change="handleCurrentChange"
  1179. :current-page="pageNo"
  1180. :page-sizes="[20, 50, 100, 200, 500]"
  1181. :page-size="pageSize"
  1182. :total="pageTotal"
  1183. layout="total,sizes, prev, pager, next, jumper">
  1184. </el-pagination>
  1185. </el-dialog>
  1186. <!-- <part-table v-if="saveVisible" v-model="partVisible" :is-page="true" :part-no="saveQuoteDetail.partNo" @dblclick="handleDblClick"></part-table>-->
  1187. <!-- <project-part-table v-if="saveVisible" v-model="partVisible" :project-no="saveQuoteDetail.projectNo" :part-no="saveQuoteDetail.partNo" @dblclick="handleDblClick"></project-part-table>-->
  1188. </div>
  1189. </template>
  1190. <style scoped>
  1191. .el-table /deep/ .cell{
  1192. height: auto;
  1193. line-height: 1.5;
  1194. }
  1195. .auto /deep/ .el-form-item__content{
  1196. height: auto;
  1197. line-height: 1.5;
  1198. }
  1199. .radio /deep/ .el-radio__label{
  1200. display: none;
  1201. }
  1202. </style>