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.

1558 lines
53 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
6 months ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
1 year ago
2 years ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
6 months ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
6 months ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
1 year ago
2 years ago
1 year ago
2 years ago
2 years ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
10 months ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
10 months ago
2 years ago
2 years ago
2 years ago
2 years ago
10 months ago
2 years ago
2 years ago
2 years ago
1 year ago
1 year ago
2 years ago
1 year ago
2 years ago
2 years ago
6 months ago
2 years ago
2 years ago
2 years ago
2 years ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
6 months ago
2 years ago
6 months ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
1 year ago
2 years ago
2 years ago
1 year ago
2 years ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
1 year ago
2 years ago
2 years ago
2 years ago
  1. <script>
  2. import {
  3. againQuoteDetail,
  4. deleteQuoteDetail,
  5. queryQuoteDetail,
  6. saveQuoteDetail,
  7. updateQuoteDetail,
  8. updateQuoteDetailEntry,
  9. updateQuoteDetailShowFlag
  10. } from "../../../../api/quote/quoteDetail";
  11. import {queryQuoteGroupDetail} from "../../../../api/quote/quoteGroupDetail";
  12. import {getProjectPartList} from "../../../../api/project/project";
  13. import QuoteDetailCost from "./primary/quoteDetailCost.vue";
  14. import QuoteDetailTool from "./primary/quoteDetailTool.vue";
  15. import QuoteDetailBom from "./primary/quoteDetailBom.vue";
  16. import QuoteDetailRouting from "./primary/quoteDetailRouting.vue";
  17. import QuoteDetailOtherCost from "./primary/quoteDetailOtherCost.vue";
  18. import DictDataSelect from "../../sys/dict-data-select.vue";
  19. import QuoteDetailTest from "./primary/quoteDetailTest.vue";
  20. import QuoteDetailOther from "./primary/quoteDetailOther.vue";
  21. export default {
  22. name: "quoteDetail",
  23. components: {
  24. QuoteDetailOther,
  25. QuoteDetailTest,
  26. DictDataSelect,
  27. QuoteDetailOtherCost,
  28. QuoteDetailRouting,
  29. QuoteDetailBom,
  30. QuoteDetailTool,
  31. QuoteDetailCost,
  32. },
  33. props:{
  34. quote:{
  35. type:Object,
  36. required:true
  37. },
  38. height:{
  39. type:[Number,String],
  40. default:300
  41. },
  42. authFlag:{
  43. type:Boolean,
  44. default:false
  45. },
  46. quoteGroupDetail:{
  47. type:Object,
  48. },
  49. saveAuth:{
  50. type:Boolean,
  51. default:true
  52. },
  53. isExport:{
  54. type:Boolean,
  55. default:false
  56. },
  57. },
  58. data(){
  59. return{
  60. exportLoading: false,
  61. quoteDetail:{
  62. id:null,
  63. partNo:'',
  64. partDesc:'',
  65. projectNo:'',
  66. projectDesc:'',
  67. buNo: '*',
  68. qty:null,
  69. quoteCount:1,
  70. partCost:0,
  71. adjustPartCost:0,
  72. labourCost:0,
  73. adjustLabourCost:0,
  74. fabricateCost:0,
  75. adjustFabricateCost:0,
  76. toolCost:0,
  77. adjustToolCost:0,
  78. machineCost:0,
  79. adjustMachineCost:0,
  80. otherCost:0,
  81. manageCost:0,
  82. totalCost:0,
  83. profitRate:0,
  84. profitAmount:0,
  85. totalPrice:0,
  86. unitPrice:0,
  87. taxRate:13,
  88. taxTotalPrice:0,
  89. taxUnitPrice:0,
  90. quoteTotalCost:0,
  91. quoteProfitRate:0,
  92. quoteProfitAmount:0,
  93. quoteTotalPrice:0,
  94. quoteUnitPrice:0,
  95. quoteTaxRate:0,
  96. quoteTaxTotalPrice:0,
  97. quoteTaxUnitPrice:0,
  98. currency1:undefined,
  99. finalTransactionPrice:null,
  100. currency2:undefined,
  101. exchangeRate1:undefined,
  102. exchangeRate2:undefined,
  103. currencyTotalCost1:0,
  104. currencyTotalCost2:0,
  105. quoteCurrencyTotalCost1:0,
  106. quoteCurrencyTotalCost2:0,
  107. // moq:'Standard 250K',
  108. moq:'',
  109. calculatedItems:'工具,测试,其他,包装,运输',
  110. testCost:0,
  111. adjustTestCost:0,
  112. elseCost:0,
  113. adjustElseCost:0,
  114. remark:'',
  115. showFlag:'Y',
  116. },
  117. saveQuoteDetail:{
  118. },
  119. dataEntryVisible: false,
  120. dataEntryLoading: false,
  121. dataEntryForm: {
  122. finalTransactionPrice: null,
  123. remark: ''
  124. },
  125. dataList:[],
  126. saveLoading:false,
  127. queryLoading:false,
  128. saveVisible:false,
  129. showModalFlag:false,
  130. showFlagChecked:false,
  131. saveQuoteDetailRules:{
  132. partNo: [{required: true, message: '请输入物料编码', trigger: ['blur','change']}],
  133. partDesc: [{required: true, message: '请输入物料名称', trigger: ['blur','change']}],
  134. qty: [{required: true, message: '请输入数量', trigger: ['blur','change']}],
  135. currency1: [{required: true, message: '请选择币种', trigger: ['blur','change']}],
  136. },
  137. columns: [
  138. {
  139. userId: this.$store.state.user.name,
  140. functionId: 5011,
  141. serialNumber: '5011Table2PartNo',
  142. tableId: '5011Table2',
  143. tableName: '报价详情信息表',
  144. columnProp: 'plmPartNo',
  145. headerAlign: 'center',
  146. align: 'left',
  147. columnLabel: 'PLM物料编码',
  148. columnHidden: false,
  149. columnImage: false,
  150. columnSortable: false,
  151. sortLv: 0,
  152. status: true,
  153. fixed: '',
  154. columnWidth: 120
  155. },
  156. {
  157. userId: this.$store.state.user.name,
  158. functionId: 5011,
  159. serialNumber: '5011Table2PartNo',
  160. tableId: '5011Table2',
  161. tableName: '报价详情信息表',
  162. columnProp: 'ifsPartNo',
  163. headerAlign: 'center',
  164. align: 'left',
  165. columnLabel: 'IFS物料编码',
  166. columnHidden: false,
  167. columnImage: false,
  168. columnSortable: false,
  169. sortLv: 0,
  170. status: true,
  171. fixed: '',
  172. columnWidth: 120
  173. },
  174. {
  175. userId: this.$store.state.user.name,
  176. functionId: 5011,
  177. serialNumber: '5011Table2PartDesc',
  178. tableId: '5011Table2',
  179. tableName: '报价详情信息表',
  180. columnProp: 'partDesc',
  181. headerAlign: 'center',
  182. align: 'left',
  183. columnLabel: '物料名称',
  184. columnHidden: false,
  185. columnImage: false,
  186. columnSortable: false,
  187. sortLv: 0,
  188. status: true,
  189. fixed: '',
  190. columnWidth: 240
  191. },
  192. {
  193. userId: this.$store.state.user.name,
  194. functionId: 5011,
  195. serialNumber: '5011Table2QuoteTaxRate',
  196. tableId: '5011Table2',
  197. tableName: '报价详情信息表',
  198. columnProp: 'customerPartNo',
  199. headerAlign: 'center',
  200. align: 'right',
  201. columnLabel: '客户物料编码',
  202. columnHidden: false,
  203. columnImage: false,
  204. columnSortable: false,
  205. sortLv: 0,
  206. status: true,
  207. fixed: '',
  208. columnWidth: 90
  209. },
  210. {
  211. userId: this.$store.state.user.name,
  212. functionId: 5011,
  213. serialNumber: '5011Table2Qty',
  214. tableId: '5011Table2',
  215. tableName: '报价详情信息表',
  216. columnProp: 'qty',
  217. headerAlign: 'center',
  218. align: 'right',
  219. columnLabel: 'MOQ',
  220. columnHidden: false,
  221. columnImage: false,
  222. columnSortable: false,
  223. sortLv: 0,
  224. status: true,
  225. fixed: '',
  226. columnWidth: 100
  227. },
  228. {
  229. userId: this.$store.state.user.name,
  230. functionId: 5011,
  231. serialNumber: '5011Table2QuoteProfitRate',
  232. tableId: '5011Table2',
  233. tableName: '报价详情信息表',
  234. columnProp: 'quoteProfitRate',
  235. headerAlign: 'center',
  236. align: 'right',
  237. columnLabel: 'VA%',
  238. columnHidden: false,
  239. columnImage: false,
  240. columnSortable: false,
  241. sortLv: 0,
  242. status: true,
  243. fixed: '',
  244. columnWidth: 60
  245. },
  246. // {
  247. // userId: this.$store.state.user.name,
  248. // functionId: 5011,
  249. // serialNumber: '5011Table2QuoteTaxRate',
  250. // tableId: '5011Table2',
  251. // tableName: '报价详情信息表',
  252. // columnProp: 'quoteTaxRate',
  253. // headerAlign: 'center',
  254. // align: 'right',
  255. // columnLabel: 'Margin%',
  256. // columnHidden: false,
  257. // columnImage: false,
  258. // columnSortable: false,
  259. // sortLv: 0,
  260. // status: true,
  261. // fixed: '',
  262. // columnWidth: 60
  263. // },
  264. {
  265. userId: this.$store.state.user.name,
  266. functionId: 5011,
  267. serialNumber: '5011Table2QuoteProfitAmount',
  268. tableId: '5011Table2',
  269. tableName: '报价详情信息表',
  270. columnProp: 'quoteProfitAmount',
  271. headerAlign: 'center',
  272. align: 'right',
  273. columnLabel: 'Contribution%',
  274. columnHidden: false,
  275. columnImage: false,
  276. columnSortable: false,
  277. sortLv: 0,
  278. status: true,
  279. fixed: '',
  280. columnWidth: 100
  281. },
  282. {
  283. userId: this.$store.state.user.name,
  284. functionId: 5011,
  285. serialNumber: '5011Table2Qty',
  286. tableId: '5011Table2',
  287. tableName: '报价详情信息表',
  288. columnProp: 'currencyDesc2',
  289. headerAlign: 'center',
  290. align: 'right',
  291. columnLabel: '币种',
  292. columnHidden: false,
  293. columnImage: false,
  294. columnSortable: false,
  295. sortLv: 0,
  296. status: true,
  297. fixed: '',
  298. columnWidth: 100
  299. },
  300. {
  301. userId: this.$store.state.user.name,
  302. functionId: 5011,
  303. serialNumber: '5011Table2Qty',
  304. tableId: '5011Table2',
  305. tableName: '报价详情信息表',
  306. columnProp: 'currencyTotalCost2',
  307. headerAlign: 'center',
  308. align: 'right',
  309. columnLabel: '含税单价',
  310. columnHidden: false,
  311. columnImage: false,
  312. columnSortable: false,
  313. sortLv: 0,
  314. status: true,
  315. fixed: '',
  316. columnWidth: 100
  317. },
  318. {
  319. userId: this.$store.state.user.name,
  320. functionId: 5011,
  321. serialNumber: '5011Table2Qty',
  322. tableId: '5011Table2',
  323. tableName: '报价详情信息表',
  324. columnProp: 'unitPriceRate',
  325. headerAlign: 'center',
  326. align: 'right',
  327. columnLabel: '未税单价',
  328. columnHidden: false,
  329. columnImage: false,
  330. columnSortable: false,
  331. sortLv: 0,
  332. status: true,
  333. fixed: '',
  334. columnWidth: 100
  335. },
  336. {
  337. userId: this.$store.state.user.name,
  338. functionId: 5011,
  339. serialNumber: '5011Table2Remark',
  340. tableId: '5011Table2',
  341. tableName: '报价详情信息表',
  342. columnProp: 'remark',
  343. headerAlign: 'center',
  344. align: 'left',
  345. columnLabel: '备注',
  346. columnHidden: false,
  347. columnImage: false,
  348. columnSortable: false,
  349. sortLv: 0,
  350. status: true,
  351. fixed: '',
  352. columnWidth: 120
  353. },
  354. {
  355. userId: this.$store.state.user.name,
  356. functionId: 5011,
  357. serialNumber: '5011Table2AdjustPartCost',
  358. tableId: '5011Table2',
  359. tableName: '报价详情信息表',
  360. columnProp: 'adjustPartCost',
  361. headerAlign: 'center',
  362. align: 'right',
  363. columnLabel: '材料成本',
  364. columnHidden: false,
  365. columnImage: false,
  366. columnSortable: false,
  367. sortLv: 0,
  368. status: true,
  369. fixed: '',
  370. columnWidth: 130
  371. },
  372. {
  373. userId: this.$store.state.user.name,
  374. functionId: 5011,
  375. serialNumber: '5011Table2AdjustLabourCost',
  376. tableId: '5011Table2',
  377. tableName: '报价详情信息表',
  378. columnProp: 'adjustLabourCost',
  379. headerAlign: 'center',
  380. align: 'right',
  381. columnLabel: '人工成本',
  382. columnHidden: false,
  383. columnImage: false,
  384. columnSortable: false,
  385. sortLv: 0,
  386. status: true,
  387. fixed: '',
  388. columnWidth: 120
  389. },
  390. // {
  391. // userId: this.$store.state.user.name,
  392. // functionId: 5011,
  393. // serialNumber: '5011Table2AdjustMachineCost',
  394. // tableId: '5011Table2',
  395. // tableName: '报价详情信息表',
  396. // columnProp: 'adjustMachineCost',
  397. // headerAlign: 'center',
  398. // align: 'right',
  399. // columnLabel: '机器成本',
  400. // columnHidden: false,
  401. // columnImage: false,
  402. // columnSortable: false,
  403. // sortLv: 0,
  404. // status: true,
  405. // fixed: '',
  406. // columnWidth: 120
  407. // },
  408. {
  409. userId: this.$store.state.user.name,
  410. functionId: 5011,
  411. serialNumber: '5011Table2AdjustToolCost',
  412. tableId: '5011Table2',
  413. tableName: '报价详情信息表',
  414. columnProp: 'adjustToolCost',
  415. headerAlign: 'center',
  416. align: 'right',
  417. columnLabel: '工具成本',
  418. columnHidden: false,
  419. columnImage: false,
  420. columnSortable: false,
  421. sortLv: 0,
  422. status: true,
  423. fixed: '',
  424. columnWidth: 120
  425. },
  426. {
  427. userId: this.$store.state.user.name,
  428. functionId: 5011,
  429. serialNumber: '5011Table2AdjustTestCost',
  430. tableId: '5011Table2',
  431. tableName: '报价详情信息表',
  432. columnProp: 'adjustTestCost',
  433. headerAlign: 'center',
  434. align: 'right',
  435. columnLabel: '测试成本',
  436. columnHidden: false,
  437. columnImage: false,
  438. columnSortable: false,
  439. sortLv: 0,
  440. status: true,
  441. fixed: '',
  442. columnWidth: 120
  443. },
  444. {
  445. userId: this.$store.state.user.name,
  446. functionId: 5011,
  447. serialNumber: '5011Table2PackCost',
  448. tableId: '5011Table2',
  449. tableName: '报价详情信息表',
  450. columnProp: 'packCost',
  451. headerAlign: 'center',
  452. align: 'right',
  453. columnLabel: '包装成本',
  454. columnHidden: false,
  455. columnImage: false,
  456. columnSortable: false,
  457. sortLv: 0,
  458. status: true,
  459. fixed: '',
  460. columnWidth: 120
  461. },
  462. {
  463. userId: this.$store.state.user.name,
  464. functionId: 5011,
  465. serialNumber: '5011Table2ShippingCost',
  466. tableId: '5011Table2',
  467. tableName: '报价详情信息表',
  468. columnProp: 'shippingCost',
  469. headerAlign: 'center',
  470. align: 'right',
  471. columnLabel: '运输成本',
  472. columnHidden: false,
  473. columnImage: false,
  474. columnSortable: false,
  475. sortLv: 0,
  476. status: true,
  477. fixed: '',
  478. columnWidth: 120
  479. },
  480. {
  481. userId: this.$store.state.user.name,
  482. functionId: 5011,
  483. serialNumber: '5011Table2AdjustElseCost',
  484. tableId: '5011Table2',
  485. tableName: '报价详情信息表',
  486. columnProp: 'adjustElseCost',
  487. headerAlign: 'center',
  488. align: 'right',
  489. columnLabel: '其他成本',
  490. columnHidden: false,
  491. columnImage: false,
  492. columnSortable: false,
  493. sortLv: 0,
  494. status: true,
  495. fixed: '',
  496. columnWidth: 120
  497. },
  498. {
  499. userId: this.$store.state.user.name,
  500. functionId: 5011,
  501. serialNumber: '5011Table2TotalCost',
  502. tableId: '5011Table2',
  503. tableName: '报价详情信息表',
  504. columnProp: 'totalCost',
  505. headerAlign: 'center',
  506. align: 'right',
  507. columnLabel: '总成本',
  508. columnHidden: false,
  509. columnImage: false,
  510. columnSortable: false,
  511. sortLv: 0,
  512. status: true,
  513. fixed: '',
  514. columnWidth: 80
  515. },
  516. {
  517. userId: this.$store.state.user.name,
  518. functionId: 5011,
  519. serialNumber: '5011Table2FinalTransactionPrice',
  520. tableId: '5011Table2',
  521. tableName: '报价详情信息表',
  522. columnProp: 'finalTransactionPrice',
  523. headerAlign: 'center',
  524. align: 'right',
  525. columnLabel: '最终交易价',
  526. columnHidden: false,
  527. columnImage: false,
  528. columnSortable: false,
  529. sortLv: 0,
  530. status: true,
  531. fixed: '',
  532. columnWidth: 80
  533. },
  534. {
  535. userId: this.$store.state.user.name,
  536. functionId: 5011,
  537. serialNumber: '5011Table2QuoteTaxTotalPrice',
  538. tableId: '5011Table2',
  539. tableName: '报价详情信息表',
  540. columnProp: 'quoteTaxTotalPrice',
  541. headerAlign: 'center',
  542. align: 'right',
  543. columnLabel: 'Price ¥(ex VAT)',
  544. columnHidden: false,
  545. columnImage: false,
  546. columnSortable: false,
  547. sortLv: 0,
  548. status: true,
  549. fixed: '',
  550. columnWidth: 100
  551. },
  552. {
  553. userId: this.$store.state.user.name,
  554. functionId: 5011,
  555. serialNumber: '5011Table2Qty',
  556. tableId: '5011Table2',
  557. tableName: '报价详情信息表',
  558. columnProp: 'taxRate',
  559. headerAlign: 'center',
  560. align: 'right',
  561. columnLabel: '税率',
  562. columnHidden: false,
  563. columnImage: false,
  564. columnSortable: false,
  565. sortLv: 0,
  566. status: true,
  567. fixed: '',
  568. columnWidth: 100
  569. },
  570. {
  571. userId: this.$store.state.user.name,
  572. functionId: 5011,
  573. serialNumber: '5011Table2Qty',
  574. tableId: '5011Table2',
  575. tableName: '报价详情信息表',
  576. columnProp: 'exchangeRate1',
  577. headerAlign: 'center',
  578. align: 'right',
  579. columnLabel: '其他税率',
  580. columnHidden: false,
  581. columnImage: false,
  582. columnSortable: false,
  583. sortLv: 0,
  584. status: true,
  585. fixed: '',
  586. columnWidth: 100
  587. },
  588. {
  589. userId: this.$store.state.user.name,
  590. functionId: 5011,
  591. serialNumber: '5011Table2Qty',
  592. tableId: '5011Table2',
  593. tableName: '报价详情信息表',
  594. columnProp: 'taxUnitPrice',
  595. headerAlign: 'center',
  596. align: 'right',
  597. columnLabel: '含税单价(CNY)',
  598. columnHidden: false,
  599. columnImage: false,
  600. columnSortable: false,
  601. sortLv: 0,
  602. status: true,
  603. fixed: '',
  604. columnWidth: 100
  605. },
  606. {
  607. userId: this.$store.state.user.name,
  608. functionId: 5011,
  609. serialNumber: '5011Table2Qty',
  610. tableId: '5011Table2',
  611. tableName: '报价详情信息表',
  612. columnProp: 'exchangeRate2',
  613. headerAlign: 'center',
  614. align: 'right',
  615. columnLabel: '汇率',
  616. columnHidden: false,
  617. columnImage: false,
  618. columnSortable: false,
  619. sortLv: 0,
  620. status: true,
  621. fixed: '',
  622. columnWidth: 100
  623. },
  624. {
  625. userId: this.$store.state.user.name,
  626. functionId: 5011,
  627. serialNumber: '5011Table2Qty',
  628. tableId: '5011Table2',
  629. tableName: '报价详情信息表',
  630. columnProp: 'unitPrice',
  631. headerAlign: 'center',
  632. align: 'right',
  633. columnLabel: '未税单价(CNY)',
  634. columnHidden: false,
  635. columnImage: false,
  636. columnSortable: false,
  637. sortLv: 0,
  638. status: true,
  639. fixed: '',
  640. columnWidth: 100
  641. },
  642. ],
  643. partVisible:false,
  644. activeName:'bom',
  645. projectPart:{
  646. },
  647. projectPartList:[],
  648. pageNo:1,
  649. pageSize:20,
  650. pageTotal:0,
  651. partQueryLoading:false,
  652. projectPartColumns:[
  653. {
  654. userId: this.$store.state.user.name,
  655. functionId: 5011,
  656. serialNumber: '5011Table3TestPartNo',
  657. tableId: '5011Table3',
  658. tableName: '项目物料表',
  659. columnProp: 'testPartNo',
  660. headerAlign: 'center',
  661. align: 'left',
  662. columnLabel: '物料编码',
  663. columnHidden: false,
  664. columnImage: false,
  665. columnSortable: false,
  666. sortLv: 0,
  667. status: true,
  668. fixed: '',
  669. columnWidth: 150
  670. },
  671. {
  672. userId: this.$store.state.user.name,
  673. functionId: 5011,
  674. serialNumber: '5011Table3PartDesc',
  675. tableId: '5011Table3',
  676. tableName: '项目物料表',
  677. columnProp: 'partDesc',
  678. headerAlign: 'center',
  679. align: 'left',
  680. columnLabel: '物料名称',
  681. columnHidden: false,
  682. columnImage: false,
  683. columnSortable: false,
  684. sortLv: 0,
  685. status: true,
  686. fixed: '',
  687. columnWidth: 160
  688. },
  689. {
  690. userId: this.$store.state.user.name,
  691. functionId: 5011,
  692. serialNumber: '5011Table3FinalPartNo',
  693. tableId: '5011Table3',
  694. tableName: '项目物料表',
  695. columnProp: 'finalPartNo',
  696. headerAlign: 'center',
  697. align: 'left',
  698. columnLabel: 'IFS物料编码',
  699. columnHidden: false,
  700. columnImage: false,
  701. columnSortable: false,
  702. sortLv: 0,
  703. status: true,
  704. fixed: '',
  705. columnWidth: 150
  706. },
  707. {
  708. userId: this.$store.state.user.name,
  709. functionId: 5011,
  710. serialNumber: '5011Table3CustomerPartNo',
  711. tableId: '5011Table3',
  712. tableName: '项目物料表',
  713. columnProp: 'customerPartNo',
  714. headerAlign: 'center',
  715. align: 'left',
  716. columnLabel: '客户物料编码',
  717. columnHidden: false,
  718. columnImage: false,
  719. columnSortable: false,
  720. sortLv: 0,
  721. status: true,
  722. fixed: '',
  723. columnWidth: 150
  724. },
  725. {
  726. userId: this.$store.state.user.name,
  727. functionId: 5011,
  728. serialNumber: '5011Table3Type',
  729. tableId: '5011Table3',
  730. tableName: '项目物料表',
  731. columnProp: 'type',
  732. headerAlign: 'center',
  733. align: 'left',
  734. columnLabel: '制造类型',
  735. columnHidden: false,
  736. columnImage: false,
  737. columnSortable: false,
  738. sortLv: 0,
  739. status: true,
  740. fixed: '',
  741. columnWidth: 120
  742. },
  743. {
  744. userId: this.$store.state.user.name,
  745. functionId: 5011,
  746. serialNumber: '5011Table3UmId',
  747. tableId: '5011Table3',
  748. tableName: '项目物料表',
  749. columnProp: 'umId',
  750. headerAlign: 'center',
  751. align: 'left',
  752. columnLabel: '单位',
  753. columnHidden: false,
  754. columnImage: false,
  755. columnSortable: false,
  756. sortLv: 0,
  757. status: true,
  758. fixed: '',
  759. columnWidth: 100
  760. },
  761. ],
  762. exportData:[],
  763. exportName: '报价条目明细'+this.dayjs().format('YYYYMMDDHHmmss'),
  764. exportHeader: ["报价条目明细"],
  765. exportFooter: [],
  766. againVisible:false,
  767. againRow:{},
  768. // 平铺视图(不传 quoteGroupDetail 时)内部维护的 quoteGroupDetailId → currentQuoteDetailItemNo 映射
  769. internalDefaultItemNoMap: {},
  770. }
  771. },
  772. methods:{
  773. handleSaveQuoteDetail(row){
  774. this.$nextTick(()=>{
  775. if (this.$refs.handleSaveQuoteDetailClick){
  776. this.$refs.saveQuoteDetailForm.clearValidate();
  777. }
  778. })
  779. if (row){
  780. this.saveQuoteDetail = {
  781. ...row
  782. }
  783. // 设置勾选状态
  784. this.showFlagChecked = row.showFlag === 'Y'
  785. }else {
  786. this.saveQuoteDetail = {
  787. ...this.quoteDetail,
  788. createBy:this.$store.state.user.name,
  789. status:'草稿',
  790. active:'Y',
  791. qty:1,
  792. isDetail:false,
  793. }
  794. if (this.quoteGroupDetail){
  795. this.saveQuoteDetail.partNo = this.quoteGroupDetail.partNo
  796. this.saveQuoteDetail.partDesc = this.quoteGroupDetail.partDesc
  797. }
  798. this.$nextTick(()=>{
  799. this.saveQuoteDetail.projectNo = this.quote.projectNo
  800. })
  801. // 新建时默认勾选
  802. this.showFlagChecked = true
  803. }
  804. this.saveQuoteDetail.showModalFlag = false
  805. this.activeName = 'bom';
  806. this.saveVisible = true;
  807. this.showModalFlag = false;
  808. },
  809. handleDetail(row){
  810. this.saveQuoteDetail = {
  811. ...row
  812. }
  813. this.saveQuoteDetail.showModalFlag = true
  814. // 设置勾选状态
  815. this.showFlagChecked = row.showFlag === 'Y'
  816. this.activeName = 'bom';
  817. this.saveVisible = true;
  818. this.showModalFlag = true;
  819. },
  820. handleDataEntry() {
  821. this.dataEntryForm = {
  822. finalTransactionPrice: this.saveQuoteDetail.finalTransactionPrice,
  823. remark: this.saveQuoteDetail.remark || ''
  824. }
  825. this.dataEntryVisible = true
  826. },
  827. submitDataEntry() {
  828. this.dataEntryLoading = true
  829. const params = {
  830. id: this.saveQuoteDetail.id,
  831. finalTransactionPrice: this.dataEntryForm.finalTransactionPrice,
  832. remark: this.dataEntryForm.remark,
  833. updateBy: this.$store.state.user.name
  834. }
  835. updateQuoteDetailEntry(params).then(({data}) => {
  836. if (data && data.code === 0) {
  837. this.$message.success('操作成功')
  838. this.saveQuoteDetail.finalTransactionPrice = params.finalTransactionPrice
  839. this.saveQuoteDetail.remark = params.remark
  840. this.dataEntryVisible = false
  841. this.handleQueryQuoteDetail()
  842. } else {
  843. this.$message.error(data.msg)
  844. }
  845. }).finally(() => {
  846. this.dataEntryLoading = false
  847. })
  848. },
  849. handleShowFlagChange(val){
  850. // 勾选变化时直接更新数据库,只修改show_flag字段
  851. if (!this.saveQuoteDetail.id) {
  852. return
  853. }
  854. const newShowFlag = val ? 'Y' : 'N'
  855. const params = {
  856. id: this.saveQuoteDetail.id,
  857. showFlag: newShowFlag
  858. }
  859. updateQuoteDetailShowFlag(params).then(({data}) => {
  860. if (data && data.code === 0) {
  861. this.saveQuoteDetail.showFlag = newShowFlag
  862. this.$message.success('更新成功')
  863. // 刷新列表
  864. this.handleQueryQuoteDetail()
  865. } else {
  866. this.$message.warning(data.msg)
  867. // 恢复勾选状态
  868. this.showFlagChecked = !val
  869. }
  870. }).catch((error) => {
  871. this.$message.error(error)
  872. // 恢复勾选状态
  873. this.showFlagChecked = !val
  874. })
  875. },
  876. handleDeleteQuoteDetail(row){
  877. this.$confirm('确认删除该条报价明细吗?', '提示', {
  878. confirmButtonText: '确定',
  879. cancelButtonText: '取消',
  880. type: 'warning'
  881. }).then(() => {
  882. let params = {
  883. id: row.id,
  884. }
  885. deleteQuoteDetail(params).then(({data}) => {
  886. if (data && data.code === 0) {
  887. this.$message.success(data.msg);
  888. this.handleQueryQuoteDetail();
  889. // 通知父组件刷新主信息
  890. console.log('emit refresh-quote-info event (delete), quoteId:', this.quote.id)
  891. this.$emit('refresh-quote-info', this.quote.id)
  892. } else {
  893. this.$message.warning(data.msg);
  894. }
  895. }).catch((error) => {
  896. this.$message.error(error);
  897. })
  898. }).catch(() => {
  899. })
  900. },
  901. handlePartNoBlur(){
  902. let params = {
  903. site:this.$store.state.user.site,
  904. testPartNo:this.saveQuoteDetail.partNo,
  905. projectId: this.quote.projectNo,
  906. no:1,
  907. size:20,
  908. }
  909. getProjectPartList(params).then(({data})=>{
  910. if (data && data.code === 0){
  911. if (data.rows && data.rows.length === 1){
  912. this.dblClickProjectPartTable(data.rows[0])
  913. }else {
  914. this.saveQuoteDetail.partDesc = ''
  915. }
  916. }
  917. })
  918. },
  919. handleQueryQuoteDetail(){
  920. let params = {
  921. quoteId: this.quote.id,
  922. }
  923. if (this.quoteGroupDetail){
  924. params.quoteGroupDetailId=this.quoteGroupDetail.id;
  925. } else {
  926. // 平铺模式:同步加载各报价明细组的默认条目映射,用于删除保护
  927. this.loadGroupDetailMap();
  928. }
  929. this.queryLoading = true;
  930. queryQuoteDetail(params).then(({data})=>{
  931. if (data && data.code === 0){
  932. this.dataList = data.rows
  933. }else {
  934. this.$message.warning(data.msg);
  935. }
  936. this.queryLoading = false;
  937. }).catch((error)=>{
  938. this.$message.error(error);
  939. this.queryLoading = false;
  940. })
  941. },
  942. // 平铺模式下加载 quoteGroupDetail 映射,用于判断哪些条目行是默认报价行(不允许删除)
  943. loadGroupDetailMap() {
  944. if (!this.quote.id) {
  945. this.internalDefaultItemNoMap = {}
  946. return
  947. }
  948. queryQuoteGroupDetail({ quoteId: this.quote.id }).then(({ data }) => {
  949. if (data && data.code === 0 && data.rows) {
  950. const map = {}
  951. data.rows.forEach(group => {
  952. if (group.currentQuoteDetailItemNo) {
  953. map[group.id] = group.currentQuoteDetailItemNo
  954. }
  955. })
  956. this.internalDefaultItemNoMap = map
  957. } else {
  958. this.internalDefaultItemNoMap = {}
  959. }
  960. }).catch(() => {
  961. this.internalDefaultItemNoMap = {}
  962. })
  963. },
  964. handleSaveQuoteDetailClick(){
  965. this.$refs.saveQuoteDetailForm.validate((valid,obj) => {
  966. if (valid){
  967. if (this.saveQuoteDetail.id){
  968. this.handleUpdate();
  969. }else {
  970. this.handleSave();
  971. }
  972. }else {
  973. let i = 1;
  974. for (let key in obj) {
  975. this.$message.error(obj[key][0].message);
  976. if (i === 1){
  977. return
  978. }
  979. i++;
  980. }
  981. }
  982. })
  983. },
  984. handleSave(){
  985. console.log('handleSave 被调用, quote.id:', this.quote.id)
  986. let params = {
  987. ...this.saveQuoteDetail,
  988. quoteId: this.quote.id,
  989. quoteNo:this.quote.quoteNo,
  990. site:this.quote.site,
  991. buNo:this.quote.buNo,
  992. versionNo:this.quote.versionNo,
  993. createBy:this.saveQuoteDetail.createBy,
  994. active:'Y',
  995. status:'草稿',
  996. internalInquiryNo:this.quote.insideInquiryNo,
  997. }
  998. if (this.quoteGroupDetail){
  999. params.quoteGroupDetailId=this.quoteGroupDetail.id;
  1000. }
  1001. this.saveLoading = true;
  1002. saveQuoteDetail(params).then(({data})=>{
  1003. if (data && data.code === 0){
  1004. this.$message.success(data.msg);
  1005. this.handleQueryQuoteDetail();
  1006. if (this.saveQuoteDetail.isDetail){
  1007. this.saveQuoteDetail = {
  1008. ...data.row,
  1009. }
  1010. this.showFlagChecked = this.saveQuoteDetail.showFlag === 'Y'
  1011. }else {
  1012. this.saveVisible = false;
  1013. }
  1014. // 通知父组件刷新主信息
  1015. console.log('emit refresh-quote-info event (save), quoteId:', this.quote.id)
  1016. this.$emit('refresh-quote-info', this.quote.id)
  1017. }else {
  1018. this.$message.warning(data.msg);
  1019. }
  1020. this.saveLoading = false
  1021. }).catch((error)=>{
  1022. this.$message.error(error);
  1023. this.saveLoading = false
  1024. })
  1025. },
  1026. handleUpdate(){
  1027. let params = {
  1028. ...this.saveQuoteDetail,
  1029. updateBy:this.$store.state.user.name,
  1030. }
  1031. updateQuoteDetail(params).then(({data})=>{
  1032. if (data && data.code === 0){
  1033. this.$message.success(data.msg);
  1034. this.handleQueryQuoteDetail();
  1035. this.saveVisible = false;
  1036. }else {
  1037. this.$message.warning(data.msg);
  1038. }
  1039. }).catch((error)=>{
  1040. this.$message.error(error);
  1041. })
  1042. },
  1043. handleClickTab(tab){
  1044. if (this.activeName === 'routing'){
  1045. this.$refs.routing.handleQueryQuoteDetailBomTree()
  1046. }else if (this.activeName === 'tool'){
  1047. this.$refs.tool.handleQueryQuoteDetailTool();
  1048. }
  1049. },
  1050. handleAgainQuoteDetail(row){
  1051. this.againRow = {
  1052. ...row,
  1053. showFlag: 'Y'
  1054. };
  1055. this.againVisible = true;
  1056. },
  1057. againQuoteDetail(){
  1058. this.$refs.againForm.validate((valid,obj) => {
  1059. if (valid){
  1060. this.queryLoading = true;
  1061. this.saveLoading = true;
  1062. againQuoteDetail(this.againRow).then(({data})=>{
  1063. if (data && data.code === 0){
  1064. this.againVisible = false
  1065. this.handleQueryQuoteDetail();
  1066. this.$message.success(data.msg);
  1067. }else {
  1068. this.$message.warning(data.msg);
  1069. }
  1070. this.queryLoading = false;
  1071. this.saveLoading = false;
  1072. }).catch((error)=>{
  1073. this.$message.error(error);
  1074. this.queryLoading = false;
  1075. this.saveLoading = false;
  1076. })
  1077. }else {
  1078. let i = 1;
  1079. for (let key in obj) {
  1080. this.$message.error(obj[key][0].message);
  1081. if (i === 1){
  1082. return
  1083. }
  1084. i++;
  1085. }
  1086. }
  1087. })
  1088. },
  1089. handleQueryPartList(){
  1090. this.projectPart = {
  1091. testPartNo:this.saveQuoteDetail.partNo,
  1092. partDesc:'',
  1093. finalPartNo:'',
  1094. customerPartNo:'',
  1095. site:this.$store.state.user.site,
  1096. }
  1097. this.partVisible = true;
  1098. this.getProjectPartList();
  1099. },
  1100. getProjectPartList(){
  1101. let params = {
  1102. ...this.projectPart,
  1103. no:this.pageNo,
  1104. size:this.pageSize,
  1105. }
  1106. params.projectId = this.quote.projectNo
  1107. this.partQueryLoading = true;
  1108. getProjectPartList(params).then(({data})=>{
  1109. if (data && data.code === 0){
  1110. this.projectPartList = data.rows;
  1111. this.pageTotal = data.total;
  1112. }
  1113. this.partQueryLoading = false;
  1114. }).catch((error)=>{
  1115. this.partQueryLoading = false;
  1116. })
  1117. },
  1118. handleSizeChange(val){
  1119. this.pageSize = val;
  1120. this.getProjectPartList();
  1121. },
  1122. handleCurrentChange(val){
  1123. this.pageNo = val;
  1124. this.getProjectPartList();
  1125. },
  1126. dblClickProjectPartTable(row){
  1127. this.saveQuoteDetail.partNo = row.testPartNo;
  1128. this.saveQuoteDetail.partDesc = row.partDesc;
  1129. this.partVisible = false;
  1130. },
  1131. handleClose(){
  1132. this.$emit('close');
  1133. this.saveVisible = false;
  1134. }, startDownload() {
  1135. this.exportLoading = true
  1136. },
  1137. finishDownload() {
  1138. this.exportLoading = false
  1139. },
  1140. fields() {
  1141. let fieldsObj = {};
  1142. this.columns.forEach((item) => {
  1143. let label = item.columnLabel;
  1144. while (fieldsObj.hasOwnProperty(label)) {
  1145. label += '\u200B'; // append zero-width space to make it unique
  1146. }
  1147. fieldsObj[label] = item.columnProp;
  1148. });
  1149. return fieldsObj;
  1150. },
  1151. createExportData() {
  1152. return this.dataList.map(item => {
  1153. return {
  1154. ...item,
  1155. unitPriceRate: this.formatDecimal(item.unitPriceRate)
  1156. }
  1157. });
  1158. },
  1159. toPartMenu (partNo) {
  1160. if (this.$router.resolve(`/part-partInformation`).resolved.name === '404') {
  1161. this.$alert('权限不足,访问失败', '警告', {confirmButtonText: '确定',})
  1162. } else {
  1163. this.$router.push({name:`part-partInformation`,params:{partNo:partNo},})
  1164. }
  1165. },
  1166. formatDecimal(value) {
  1167. const num = parseFloat(value);
  1168. return !isNaN(num) ? num.toFixed(4) : value;
  1169. },
  1170. handleSetDefaultQuoteRow(row) {
  1171. if (!this.isAuth('5011:group:current')) {
  1172. return;
  1173. }
  1174. const oldVal = this.quoteGroupDetail.currentQuoteDetailItemNo;
  1175. this.quoteGroupDetail.currentQuoteDetailItemNo = row.itemNo;
  1176. // 直接触发emit事件
  1177. this.$emit('currentQuoteDetailItemNo', oldVal);
  1178. },
  1179. // 判断某行是否为默认报价行(不允许删除)
  1180. // 单组视图(quoteGroupDetail 已传入):对比 quoteGroupDetail.currentQuoteDetailItemNo
  1181. // 平铺视图(quoteGroupDetail 未传):对比内部加载的 internalDefaultItemNoMap
  1182. isDefaultQuoteRow(row) {
  1183. if (this.quoteGroupDetail) {
  1184. return this.quoteGroupDetail.currentQuoteDetailItemNo === row.itemNo;
  1185. }
  1186. const defaultItemNo = this.internalDefaultItemNoMap[row.quoteGroupDetailId]
  1187. return defaultItemNo != null && defaultItemNo === row.itemNo;
  1188. },
  1189. },
  1190. watch:{
  1191. quote(newVal,oldVal){
  1192. if (newVal.id){
  1193. // 只有当 quote.id 真正变化时才重新查询,避免重复查询
  1194. if (newVal.id !== (oldVal && oldVal.id)) {
  1195. this.quoteDetail.profitRate = this.quote.markup
  1196. this.quoteDetail.quoteProfitRate = this.quote.markup
  1197. this.handleQueryQuoteDetail();
  1198. }
  1199. }else {
  1200. this.dataList = [];
  1201. }
  1202. },
  1203. "saveQuoteDetail.partNo"(newVal,oldVal){
  1204. if (newVal){
  1205. this.saveQuoteDetail.partNo = newVal.toUpperCase();
  1206. }
  1207. },
  1208. partVisible(newVal,oldVal){
  1209. if (newVal === false){
  1210. this.partQueryLoading = false
  1211. this.pageNo = 1;
  1212. this.projectPartList = [];
  1213. }
  1214. },
  1215. quoteGroupDetail(newVal,oldVal){
  1216. if (newVal){
  1217. this.quoteDetail.profitRate = this.quote.markup
  1218. this.quoteDetail.quoteProfitRate = this.quote.markup
  1219. this.handleQueryQuoteDetail();
  1220. }
  1221. },
  1222. // 'quoteGroupDetail.currentQuoteDetailItemNo'(newVal,oldVal){
  1223. // // console.log(this.quoteGroupDetail)
  1224. // // emit事件触发修改
  1225. // if (this.quoteGroupDetail && this.quoteGroupDetail.currentQuoteDetailItemNo){
  1226. // this.$emit('currentQuoteDetailItemNo',oldVal);
  1227. // }
  1228. // }
  1229. },
  1230. created() {
  1231. this.quoteDetail.profitRate = this.quote.markup
  1232. this.quoteDetail.quoteProfitRate = this.quote.markup
  1233. // 只有当 quote.id 存在时才查询,避免和 watch 重复查询
  1234. if (this.quote.id) {
  1235. this.handleQueryQuoteDetail();
  1236. }
  1237. }
  1238. }
  1239. </script>
  1240. <template>
  1241. <div>
  1242. <template v-if="saveAuth">
  1243. <el-button type="primary" v-if="!authFlag" :disabled="quote.status === '已完成' || !quote.status" @click="handleSaveQuoteDetail(null)">新增</el-button>
  1244. </template>
  1245. <template v-if="isExport">
  1246. <download-excel
  1247. :fields="fields()"
  1248. :data="exportData"
  1249. type="xls"
  1250. :name="exportName"
  1251. :header="exportHeader"
  1252. :footer="exportFooter"
  1253. :fetch="createExportData"
  1254. :before-generate="startDownload"
  1255. :before-finish="finishDownload"
  1256. worksheet="导出信息"
  1257. :class="['el-button', 'el-button--primary', 'el-button--medium', {'is-loading': exportLoading}]">
  1258. <i v-if="exportLoading" class="el-icon-loading"></i>
  1259. <span>{{ '导出' }}</span>
  1260. </download-excel>
  1261. </template>
  1262. <el-table v-loading="queryLoading" border :data="dataList" style="width: 100%;margin-top: 5px" :height="height">
  1263. <el-table-column width="80" align="center" label="默认报价行" v-if="quoteGroupDetail && (quoteGroupDetail.status === '草稿' || quoteGroupDetail.status === '审批中')">
  1264. <template slot-scope="{row}">
  1265. <div style="cursor: pointer;">
  1266. <el-radio
  1267. class="radio"
  1268. :label="row.itemNo"
  1269. :disabled="!isAuth('5011:group:current')"
  1270. v-model="quoteGroupDetail.currentQuoteDetailItemNo"
  1271. @click.native.prevent="handleSetDefaultQuoteRow(row)"
  1272. ></el-radio>
  1273. </div>
  1274. </template>
  1275. </el-table-column>
  1276. <el-table-column type="index" width="55" align="center" label="序号"></el-table-column>
  1277. <el-table-column
  1278. v-for="(item,index) in columns" :key="index"
  1279. :sortable="item.columnSortable"
  1280. :prop="item.columnProp"
  1281. :header-align="item.headerAlign"
  1282. :show-overflow-tooltip="item.showOverflowTooltip"
  1283. :align="item.align"
  1284. :fixed="item.fixed === ''?false:item.fixed"
  1285. :min-width="item.columnWidth"
  1286. :label="item.columnLabel">
  1287. <template slot-scope="scope">
  1288. <template v-if="item.columnProp === 'unitPriceRate'">
  1289. {{ formatDecimal(scope.row.unitPriceRate) }}
  1290. </template>
  1291. <template v-else-if="!quoteGroupDetail && item.columnProp === 'plmPartNo'">
  1292. <el-link style="cursor:pointer;" v-if="!item.columnHidden" @click="toPartMenu(scope.row.plmPartNo)"> {{ scope.row[item.columnProp] }}</el-link>
  1293. <span v-if="item.columnImage"><img :src="scope.row[item.columnProp]" style="width: 100px; height: 80px"/></span>
  1294. </template>
  1295. <template v-else>
  1296. <span v-if="!item.columnHidden">{{ scope.row[item.columnProp] }}</span>
  1297. <span v-if="item.columnImage"><img :src="scope.row[item.columnProp]"
  1298. style="width: 100px; height: 80px"/></span>
  1299. </template>
  1300. </template>
  1301. </el-table-column>
  1302. <el-table-column label="操作" v-if="!authFlag" fixed="right" align="center" width="160">
  1303. <template slot-scope="{row,$index}">
  1304. <template v-if="isAuth('5011:detail:update')">
  1305. <a type="text" v-if="row.status === '草稿' || row.status === '审批中'" @click="handleSaveQuoteDetail(row)">编辑</a>
  1306. </template>
  1307. <template v-if="isAuth('5011:detail:remove')">
  1308. <a type="text" v-if="(row.status === '草稿' || row.status === '审批中') && !isDefaultQuoteRow(row)" @click="handleDeleteQuoteDetail(row)">删除</a>
  1309. </template>
  1310. <template v-if="isAuth('5011:detail:again')">
  1311. <!-- <a type="text" v-if="row.status !== '已完成'" @click="againQuoteDetail(row)">复制明细</a>-->
  1312. <a type="text" v-if="row.status !== '已完成'" @click="handleAgainQuoteDetail(row)">复制明细</a>
  1313. </template>
  1314. <template v-if="isAuth('5011:detail:detail')">
  1315. <a type="text" @click="handleDetail(row)">详情</a>
  1316. </template>
  1317. </template>
  1318. </el-table-column>
  1319. </el-table>
  1320. <el-dialog :title="`报价明细`" top="10vh" v-drag :visible.sync="saveVisible" append-to-body :width="`${saveQuoteDetail.id?1200:600}px`" :close-on-click-modal="false">
  1321. <el-form :model="saveQuoteDetail" ref="saveQuoteDetailForm" :rules="saveQuoteDetailRules" label-position="top" v-if="!saveQuoteDetail.id">
  1322. <el-row :gutter="20">
  1323. <el-col :span="8">
  1324. <el-form-item label="物料编码" prop="partNo" :show-message="false">
  1325. <span slot="label" v-if="!quoteGroupDetail">
  1326. <a @click="handleQueryPartList">物料编码</a>
  1327. </span>
  1328. <el-input v-model="saveQuoteDetail.partNo" :disabled="quoteGroupDetail" @change="handlePartNoBlur"></el-input>
  1329. </el-form-item>
  1330. </el-col>
  1331. <el-col :span="16">
  1332. <el-form-item label="物料名称" prop="partDesc" :show-message="false">
  1333. <el-input v-model="saveQuoteDetail.partDesc" disabled></el-input>
  1334. </el-form-item>
  1335. </el-col>
  1336. <el-col :span="8">
  1337. <el-form-item label="MOQ" prop="qty" :show-message="false">
  1338. <el-input-number style="width: 100%;" v-model="saveQuoteDetail.qty" :min="1" :step="0" :precision="0" :controls="false"></el-input-number>
  1339. </el-form-item>
  1340. </el-col>
  1341. <el-col :span="8">
  1342. <el-form-item label="币种" prop="currency1" :show-message="false">
  1343. <dict-data-select style="width: 100%" dict-type="plm_customer_information_customer_customer_currency" v-model="saveQuoteDetail.currency1"></dict-data-select>
  1344. </el-form-item>
  1345. </el-col>
  1346. </el-row>
  1347. <el-row :gutter="20">
  1348. <el-col :span="8">
  1349. <el-form-item label="" :show-message="false">
  1350. <el-checkbox v-model="saveQuoteDetail.isDetail">保存进入报价页面</el-checkbox>
  1351. </el-form-item>
  1352. </el-col>
  1353. <el-col :span="24">
  1354. <el-form-item label="备注" class="auto" :show-message="false">
  1355. <el-input type="textarea" v-model="saveQuoteDetail.remark" :autosize="{minRows: 3, maxRows: 3}"></el-input>
  1356. </el-form-item>
  1357. </el-col>
  1358. </el-row>
  1359. </el-form>
  1360. <el-form v-else :model="saveQuoteDetail" ref="saveQuoteDetailForm" :rules="saveQuoteDetailRules" label-position="top">
  1361. <el-row :gutter="20">
  1362. <el-col :span="4">
  1363. <el-form-item label="物料编码" prop="partNo" :show-message="false">
  1364. <el-input v-model="saveQuoteDetail.partNo" disabled></el-input>
  1365. </el-form-item>
  1366. </el-col>
  1367. <el-col :span="6">
  1368. <el-form-item label="物料名称" prop="partDesc" :show-message="false">
  1369. <el-input v-model="saveQuoteDetail.partDesc" disabled></el-input>
  1370. </el-form-item>
  1371. </el-col>
  1372. <el-col :span="2">
  1373. <el-form-item label="MOQ" prop="qty" :show-message="false">
  1374. <el-input-number v-model="saveQuoteDetail.qty" style="width: 100%;" :controls="false" :disabled="showModalFlag||saveQuoteDetail.status === '已完成'"></el-input-number>
  1375. </el-form-item>
  1376. </el-col>
  1377. <el-col :span="3">
  1378. <el-form-item label="币种" prop="currency1" :show-message="false">
  1379. <dict-data-select :disabled="showModalFlag||saveQuoteDetail.status === '已完成'" style="width: 100%" dict-type="plm_customer_information_customer_customer_currency" v-model="saveQuoteDetail.currency1"></dict-data-select>
  1380. </el-form-item>
  1381. </el-col>
  1382. <el-col :span="3">
  1383. <el-form-item label="最终交易价" :show-message="false">
  1384. <el-input-number v-model="saveQuoteDetail.finalTransactionPrice" :controls="false" :disabled="showModalFlag||saveQuoteDetail.status === '已完成'" style="width: 100%"></el-input-number>
  1385. </el-form-item>
  1386. </el-col>
  1387. <el-col :span="4">
  1388. <el-form-item label=" " :show-message="false">
  1389. <el-checkbox v-model="showFlagChecked" :disabled="showModalFlag" @change="handleShowFlagChange">询价申请中展示该条目行</el-checkbox>
  1390. </el-form-item>
  1391. </el-col>
  1392. <el-col :span="2">
  1393. <el-form-item label=" " :show-message="false">
  1394. <el-button v-if="saveQuoteDetail.id && isAuth('5011:detail:dataEntry')" type="warning" @click="handleDataEntry">数据录入</el-button> </el-form-item>
  1395. </el-col>
  1396. </el-row>
  1397. <el-row :gutter="20">
  1398. <el-col :span="24">
  1399. <el-form-item label="备注" class="auto" :show-message="false">
  1400. <el-input type="textarea" resize="none" :autosize="{minRows: 3, maxRows: 3}" v-model="saveQuoteDetail.remark" :disabled="showModalFlag||saveQuoteDetail.status === '已完成'"></el-input>
  1401. </el-form-item>
  1402. </el-col>
  1403. </el-row>
  1404. </el-form>
  1405. <el-tabs v-model="activeName" v-if="saveQuoteDetail.id" @tab-click="handleClickTab">
  1406. <el-tab-pane label="材料" name="bom">
  1407. <quote-detail-bom v-if="saveVisible && activeName === 'bom'" @close="handleClose" v-model:quoteDetail="saveQuoteDetail"></quote-detail-bom>
  1408. </el-tab-pane>
  1409. <el-tab-pane label="工艺" name="routing">
  1410. <quote-detail-routing ref="routing" v-if="saveVisible && activeName === 'routing'" @close="handleClose" v-model:quoteDetail="saveQuoteDetail"></quote-detail-routing>
  1411. </el-tab-pane>
  1412. <el-tab-pane label="工具" name="tool">
  1413. <quote-detail-tool ref="tool" v-if="saveVisible && activeName === 'tool'" v-model:quoteDetail="saveQuoteDetail"></quote-detail-tool>
  1414. </el-tab-pane>
  1415. <el-tab-pane label="测试" name="test">
  1416. <quote-detail-test v-if="saveVisible && activeName === 'test'" v-model:quoteDetail="saveQuoteDetail"></quote-detail-test>
  1417. </el-tab-pane>
  1418. <el-tab-pane label="包装&运输" name="otherCost">
  1419. <quote-detail-other-cost v-if="saveVisible && activeName === 'otherCost'" v-model:quoteDetail="saveQuoteDetail"></quote-detail-other-cost>
  1420. </el-tab-pane>
  1421. <el-tab-pane label="其他" name="other">
  1422. <quote-detail-other v-if="saveVisible && activeName === 'other'" v-model:quoteDetail="saveQuoteDetail"></quote-detail-other>
  1423. </el-tab-pane>
  1424. <el-tab-pane label="成本&价格" name="cost">
  1425. <quote-detail-cost v-if="saveVisible && activeName === 'cost'" ref="cost" v-model:quoteDetail="saveQuoteDetail"></quote-detail-cost>
  1426. </el-tab-pane>
  1427. </el-tabs>
  1428. <div slot="footer" class="dialog-footer">
  1429. <el-button type="primary" v-if="!this.showModalFlag&&(saveQuoteDetail.status === '草稿' || saveQuoteDetail.status === '审批中')" :loading="saveLoading" @click="handleSaveQuoteDetailClick"> </el-button>
  1430. <el-button @click="saveVisible = false"> </el-button>
  1431. </div>
  1432. </el-dialog>
  1433. <el-dialog title="数据录入" v-drag :visible.sync="dataEntryVisible" append-to-body width="500px" :close-on-click-modal="false">
  1434. <el-form :model="dataEntryForm" label-position="top">
  1435. <el-form-item label="最终交易价">
  1436. <el-input-number v-model="dataEntryForm.finalTransactionPrice" :controls="false" style="width: 100%" placeholder="请输入最终交易价"></el-input-number>
  1437. </el-form-item>
  1438. <el-form-item label="备注">
  1439. <el-input type="textarea" v-model="dataEntryForm.remark" :rows="3" resize="none" placeholder="请输入备注"></el-input>
  1440. </el-form-item>
  1441. </el-form>
  1442. <div style="height:35px;margin-top: 55px;text-align:center">
  1443. <el-button type="primary" :loading="dataEntryLoading" @click="submitDataEntry"> </el-button>
  1444. <el-button @click="dataEntryVisible = false"> </el-button>
  1445. </div>
  1446. </el-dialog>
  1447. <el-dialog v-drag title="物料信息" append-to-body :close-on-click-modal="false" :visible.sync="partVisible">
  1448. <!--搜索条件-->
  1449. <el-form :model="projectPart" ref="projectPartDataForm" :inline="true" label-position="top">
  1450. <el-form-item label="物料编码" prop="testPartNo">
  1451. <el-input v-model="projectPart.testPartNo" clearable/>
  1452. </el-form-item>
  1453. <el-form-item label="物料名称" prop="partDesc">
  1454. <el-input v-model="projectPart.partDesc" clearable/>
  1455. </el-form-item>
  1456. <el-form-item label="IFS物料编码" prop="finalPartNo">
  1457. <el-input v-model="projectPart.finalPartNo" clearable/>
  1458. </el-form-item>
  1459. <el-form-item label="客户物料编码" prop="customerPartNo">
  1460. <el-input v-model="projectPart.customerPartNo" clearable/>
  1461. </el-form-item>
  1462. <el-form-item label=" ">
  1463. <el-button @click="getProjectPartList" type="primary"> </el-button>
  1464. </el-form-item>
  1465. </el-form>
  1466. <el-table height="300px" v-loading="partQueryLoading" stripe border @row-dblclick="dblClickProjectPartTable" :data="projectPartList" ref="projectPartDataTable" :style="{marginTop:'10px'}">
  1467. <el-table-column
  1468. v-for="(item,index) in projectPartColumns" :key="index"
  1469. :sortable="item.columnSortable"
  1470. :prop="item.columnProp"
  1471. :header-align="item.headerAlign"
  1472. :show-overflow-tooltip="item.showOverflowTooltip"
  1473. :align="item.align"
  1474. :fixed="item.fixed===''?false:item.fixed"
  1475. :min-width="item.columnWidth"
  1476. :label="item.columnLabel">
  1477. <template slot-scope="scope">
  1478. <span v-if="!item.columnHidden">{{scope.row[item.columnProp]}}</span>
  1479. <span v-if="item.columnImage"><img :src="scope.row[item.columnProp]" style="width: 100px; height: 80px"/></span>
  1480. </template>
  1481. </el-table-column>
  1482. </el-table>
  1483. <el-pagination style="margin-top: 0"
  1484. @size-change="handleSizeChange"
  1485. @current-change="handleCurrentChange"
  1486. :current-page="pageNo"
  1487. :page-sizes="[20, 50, 100, 200, 500]"
  1488. :page-size="pageSize"
  1489. :total="pageTotal"
  1490. layout="total,sizes, prev, pager, next, jumper">
  1491. </el-pagination>
  1492. </el-dialog>
  1493. <el-dialog title="复制明细" v-drag append-to-body :close-on-click-modal="false" :visible.sync="againVisible" width="400px">
  1494. <el-form :model="againRow" label-position="top" ref="againForm" :rules="saveQuoteDetailRules">
  1495. <el-row :gutter="10">
  1496. <el-col :span="8">
  1497. <el-form-item label="物料编码" prop="partNo" :show-message="false">
  1498. <el-input v-model="againRow.partNo" disabled @change="handlePartNoBlur"></el-input>
  1499. </el-form-item>
  1500. </el-col>
  1501. <el-col :span="16">
  1502. <el-form-item label="物料名称" prop="partDesc" :show-message="false">
  1503. <el-input v-model="againRow.partDesc" disabled></el-input>
  1504. </el-form-item>
  1505. </el-col>
  1506. <el-col :span="8">
  1507. <el-form-item label="MOQ" prop="qty" :show-message="false">
  1508. <el-input-number style="width: 100%;" v-model="againRow.qty" :min="1" :step="0" :precision="0" :controls="false"></el-input-number>
  1509. </el-form-item>
  1510. </el-col>
  1511. <el-col :span="8">
  1512. <el-form-item label="币种" prop="currency1" :show-message="false">
  1513. <dict-data-select style="width: 100%" dict-type="plm_customer_information_customer_customer_currency" v-model="againRow.currency1"></dict-data-select>
  1514. </el-form-item>
  1515. </el-col>
  1516. </el-row>
  1517. </el-form>
  1518. <div slot="footer" class="dialog-footer">
  1519. <el-button type="primary" :loading="saveLoading" @click="againQuoteDetail"> </el-button>
  1520. <el-button @click="againVisible = false"> </el-button>
  1521. </div>
  1522. </el-dialog>
  1523. <!-- <part-table v-if="saveVisible" v-model="partVisible" :is-page="true" :part-no="saveQuoteDetail.partNo" @dblclick="handleDblClick"></part-table>-->
  1524. <!-- <project-part-table v-if="saveVisible" v-model="partVisible" :project-no="saveQuoteDetail.projectNo" :part-no="saveQuoteDetail.partNo" @dblclick="handleDblClick"></project-part-table>-->
  1525. </div>
  1526. </template>
  1527. <style scoped>
  1528. .el-table /deep/ .cell{
  1529. height: auto;
  1530. line-height: 1.5;
  1531. }
  1532. .auto /deep/ .el-form-item__content{
  1533. height: auto;
  1534. line-height: 1.5;
  1535. }
  1536. .radio /deep/ .el-radio__label{
  1537. display: none;
  1538. }
  1539. </style>