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.

562 lines
18 KiB

2 years ago
1 year ago
1 year ago
2 years ago
1 year ago
2 years ago
1 year ago
2 years ago
1 year ago
2 years ago
1 year ago
2 years ago
1 year ago
2 years ago
1 year ago
2 years ago
1 year ago
2 years ago
1 year 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
1 year 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
1 year ago
2 years ago
1 year ago
2 years ago
1 year ago
1 year 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
1 year ago
1 year ago
2 years ago
1 year ago
1 year ago
1 year ago
2 years 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
2 years 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
2 years ago
1 year ago
2 years ago
1 year ago
1 year ago
2 years ago
1 year ago
1 year ago
1 year ago
2 years ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year 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
  1. <script>
  2. import {
  3. queryQuoteDetailBomTree,
  4. queryQuoteDetailBomTreeLevel,
  5. queryQuoteDetailBomTreeAlternative
  6. } from "@/api/quote/quoteDetailBomTree";
  7. import {queryQuoteDetailBom} from "@/api/quote/quoteDetailBom";
  8. import {changeQuoteDetailBomTree} from "../../../../../api/quote/quoteDetailBomTree";
  9. export default {
  10. name: "quoteDetailBom",
  11. props: {
  12. quoteDetail: {
  13. type: Object,
  14. required: true
  15. },
  16. },
  17. model: {
  18. prop: "quoteDetail",
  19. event: "update"
  20. },
  21. data() {
  22. return {
  23. isAllBom: false,
  24. dataList: [],
  25. treeData: [],
  26. columns: [
  27. {
  28. userId: this.$store.state.user.name,
  29. functionId: 5011,
  30. serialNumber: '5011Table4LineSequence',
  31. tableId: "5011Table4",
  32. tableName: "报价材料信息",
  33. columnProp: 'lineSequence',
  34. headerAlign: "center",
  35. align: "center",
  36. columnLabel: '序号',
  37. columnHidden: false,
  38. columnImage: false,
  39. columnSortable: false,
  40. sortLv: 0,
  41. status: true,
  42. fixed: '',
  43. columnWidth: 50,
  44. }, {
  45. userId: this.$store.state.user.name,
  46. functionId: 5011,
  47. serialNumber: '5011Table4PartNo',
  48. tableId: "5011Table4",
  49. tableName: "报价材料信息",
  50. columnProp: 'partNo',
  51. headerAlign: "center",
  52. align: "left",
  53. columnLabel: '产品编码',
  54. columnHidden: false,
  55. columnImage: false,
  56. columnSortable: false,
  57. sortLv: 0,
  58. status: true,
  59. fixed: '',
  60. columnWidth: 120,
  61. }, {
  62. userId: this.$store.state.user.name,
  63. functionId: 5011,
  64. serialNumber: '5011Table4ComponentPart',
  65. tableId: "5011Table4",
  66. tableName: "报价材料信息",
  67. columnProp: 'componentPart',
  68. headerAlign: "center",
  69. align: "left",
  70. columnLabel: '零部件编码',
  71. columnHidden: false,
  72. columnImage: false,
  73. columnSortable: false,
  74. sortLv: 0,
  75. status: true,
  76. fixed: '',
  77. columnWidth: 120,
  78. }, {
  79. userId: this.$store.state.user.name,
  80. functionId: 5011,
  81. serialNumber: '5011Table4PartDesc',
  82. tableId: "5011Table4",
  83. tableName: "报价材料信息",
  84. columnProp: 'partDesc',
  85. headerAlign: "center",
  86. align: "left",
  87. columnLabel: '物料名称',
  88. columnHidden: false,
  89. columnImage: false,
  90. columnSortable: false,
  91. sortLv: 0,
  92. status: true,
  93. fixed: '',
  94. columnWidth: 160,
  95. }, {
  96. userId: this.$store.state.user.name,
  97. functionId: 5011,
  98. serialNumber: '5011Table4QtyPerAssembly',
  99. tableId: "5011Table4",
  100. tableName: "报价材料信息",
  101. columnProp: 'qtyPerAssembly',
  102. headerAlign: "center",
  103. align: "right",
  104. columnLabel: '单位用量',
  105. columnHidden: false,
  106. columnImage: false,
  107. columnSortable: false,
  108. sortLv: 0,
  109. status: true,
  110. fixed: '',
  111. columnWidth: 90,
  112. }, {
  113. userId: this.$store.state.user.name,
  114. functionId: 5011,
  115. serialNumber: '5011Table4ComponentScrap',
  116. tableId: "5011Table4",
  117. tableName: "报价材料信息",
  118. columnProp: 'componentScrap',
  119. headerAlign: "center",
  120. align: "right",
  121. columnLabel: '调机用量',
  122. columnHidden: false,
  123. columnImage: false,
  124. columnSortable: false,
  125. sortLv: 0,
  126. status: true,
  127. fixed: '',
  128. columnWidth: 90,
  129. }, {
  130. userId: this.$store.state.user.name,
  131. functionId: 5011,
  132. serialNumber: '5011Table4ShrinkageFactor',
  133. tableId: "5011Table4",
  134. tableName: "报价材料信息",
  135. columnProp: 'shrinkageFactor',
  136. headerAlign: "center",
  137. align: "right",
  138. columnLabel: '损耗率%',
  139. columnHidden: false,
  140. columnImage: false,
  141. columnSortable: false,
  142. sortLv: 0,
  143. status: true,
  144. fixed: '',
  145. columnWidth: 90,
  146. }, {
  147. userId: this.$store.state.user.name,
  148. functionId: 5011,
  149. serialNumber: '5011Table4PrintUnitName',
  150. tableId: "5011Table4",
  151. tableName: "报价材料信息",
  152. columnProp: 'printUnit',
  153. headerAlign: "center",
  154. align: "center",
  155. columnLabel: '单位',
  156. columnHidden: false,
  157. columnImage: false,
  158. columnSortable: false,
  159. sortLv: 0,
  160. status: true,
  161. fixed: '',
  162. columnWidth: 90,
  163. }, {
  164. userId: this.$store.state.user.name,
  165. functionId: 5011,
  166. serialNumber: '5011Table4NoteText',
  167. tableId: "5011Table4",
  168. tableName: "报价材料信息",
  169. columnProp: 'noteText',
  170. headerAlign: "center",
  171. align: "left",
  172. columnLabel: '备注',
  173. columnHidden: false,
  174. columnImage: false,
  175. columnSortable: false,
  176. sortLv: 0,
  177. status: true,
  178. fixed: '',
  179. columnWidth: 90,
  180. },
  181. {
  182. userId: this.$store.state.user.name,
  183. functionId: 5011,
  184. serialNumber: '5011Table4UnitPrice',
  185. tableId: "5011Table4",
  186. tableName: "报价材料信息",
  187. columnProp: 'unitPrice',
  188. headerAlign: "center",
  189. align: "right",
  190. columnLabel: '单位标准成本',
  191. columnHidden: false,
  192. columnImage: false,
  193. columnSortable: false,
  194. sortLv: 0,
  195. status: true,
  196. fixed: '',
  197. columnWidth: 90,
  198. },
  199. {
  200. userId: this.$store.state.user.name,
  201. functionId: 5011,
  202. serialNumber: '5011Table4ActualPrice',
  203. tableId: "5011Table4",
  204. tableName: "报价材料信息",
  205. columnProp: 'actualPrice',
  206. headerAlign: "center",
  207. align: "right",
  208. columnLabel: '单位报价成本',
  209. columnHidden: false,
  210. columnImage: false,
  211. columnSortable: false,
  212. sortLv: 0,
  213. status: true,
  214. fixed: '',
  215. columnWidth: 90,
  216. },
  217. {
  218. userId: this.$store.state.user.name,
  219. functionId: 5011,
  220. serialNumber: '5011Table4QuoteUnitPrice',
  221. tableId: "5011Table4",
  222. tableName: "报价材料信息",
  223. columnProp: 'quoteUnitPrice',
  224. headerAlign: "center",
  225. align: "right",
  226. columnLabel: '材料标准总成本',
  227. columnHidden: false,
  228. columnImage: false,
  229. columnSortable: false,
  230. sortLv: 0,
  231. status: true,
  232. fixed: 'right',
  233. columnWidth: 100,
  234. },
  235. {
  236. userId: this.$store.state.user.name,
  237. functionId: 5011,
  238. serialNumber: '5011Table4ActualQuotePrice',
  239. tableId: "5011Table4",
  240. tableName: "报价材料信息",
  241. columnProp: 'actualQuotePrice',
  242. headerAlign: "center",
  243. align: "right",
  244. columnLabel: '材料报价总成本',
  245. columnHidden: false,
  246. columnImage: false,
  247. columnSortable: false,
  248. sortLv: 0,
  249. status: true,
  250. fixed: 'right',
  251. columnWidth: 100,
  252. },
  253. ],
  254. props: {
  255. children: 'list',
  256. label: (data, node) => {
  257. return `${data.partNo}-${data.engChgLevel}-${data.alternativeNo}-${data.bomType}`;
  258. },
  259. },
  260. queryLoading: false,
  261. queryTreeLoading: false,
  262. versionVisible: false,
  263. versionList: [],
  264. alternativeList: [],
  265. bomEngChgLevel: {
  266. partNo: '',
  267. bomType: '',
  268. buNo: '',
  269. site: '',
  270. engChgLevel: null,
  271. }
  272. }
  273. },
  274. methods: {
  275. handleQueryQuoteDetailBomTree() {
  276. let params = {
  277. id: this.quoteDetail.id,
  278. }
  279. this.queryTreeLoading = true;
  280. queryQuoteDetailBomTree(params).then(({data}) => {
  281. if (data && data.code === 0) {
  282. this.treeData = data.rows;
  283. if (this.treeData.length > 0) {
  284. this.$nextTick(() => {
  285. this.$refs.tree.setCurrentKey(this.treeData[0].id);
  286. this.handleQueryQuoteDetailBom();
  287. })
  288. }
  289. this.queryTreeLoading = false;
  290. } else {
  291. this.$message.warning(data.msg);
  292. this.queryTreeLoading = false;
  293. }
  294. }).catch((error) => {
  295. this.$message.error(error);
  296. })
  297. },
  298. nodeClick(data) {
  299. this.handleQueryQuoteDetailBom();
  300. },
  301. handleQueryQuoteDetailBom() {
  302. let params = {
  303. quoteDetailId: this.quoteDetail.id,
  304. treeId: this.$refs.tree.getCurrentKey(),
  305. allTree: this.isAllBom,
  306. }
  307. this.queryLoading = true;
  308. queryQuoteDetailBom(params).then(({data}) => {
  309. if (data && data.code === 0) {
  310. this.dataList = data.rows;
  311. } else {
  312. this.$message.warning(data.msg);
  313. }
  314. this.queryLoading = false;
  315. }).catch((error) => {
  316. this.$message.error(error);
  317. this.queryLoading = false;
  318. })
  319. },
  320. handleCheckedVersion() {
  321. this.handleQueryQuoteDetailBomTreeVersion();
  322. let node = this.$refs.tree.getCurrentNode();
  323. if (node) {
  324. this.bomEngChgLevel = {
  325. partNo: node.partNo,
  326. bomType: node.bomType,
  327. buNo: node.buNo,
  328. site: node.site,
  329. engChgLevel: node.engChgLevel,
  330. alternativeNo: node.alternativeNo,
  331. }
  332. }
  333. this.versionVisible = true
  334. },
  335. handleQueryQuoteDetailBomTreeVersion() {
  336. let node = this.$refs.tree.getCurrentNode();
  337. let params = {
  338. site: this.quoteDetail.site,
  339. partNo: this.quoteDetail.partNo,
  340. buNo: this.quoteDetail.buNo,
  341. }
  342. if (node) {
  343. params = {
  344. site: node.site,
  345. partNo: node.partNo,
  346. bomType: node.bomType,
  347. buNo: node.buNo,
  348. }
  349. }
  350. queryQuoteDetailBomTreeLevel(params).then(({data}) => {
  351. if (data && data.code === 0) {
  352. this.versionList = data.rows;
  353. } else {
  354. this.$message.warning(data.msg);
  355. }
  356. }).catch((error) => {
  357. this.$message.error(error);
  358. })
  359. },
  360. levelRowStyle({row}) {
  361. if (row.engChgLevel === this.bomEngChgLevel.engChgLevel) {
  362. return {'background-color': '#E8F7F6'};
  363. }
  364. },
  365. alternativeRowStyle({row}) {
  366. let node = this.$refs.tree.getCurrentNode();
  367. if (row.engChgLevel === this.bomEngChgLevel.engChgLevel && row.alternativeNo === this.bomEngChgLevel.alternativeNo) {
  368. return {'background-color': '#E8F7F6'};
  369. }
  370. },
  371. levelRowClick(row) {
  372. this.bomEngChgLevel.partNo = row.partNo;
  373. this.bomEngChgLevel.buNo = row.buNo;
  374. this.bomEngChgLevel.site = row.site;
  375. this.bomEngChgLevel.engChgLevel = row.engChgLevel;
  376. this.bomEngChgLevel.bomType = row.bomType;
  377. let params = {
  378. ...this.bomEngChgLevel
  379. }
  380. queryQuoteDetailBomTreeAlternative(params).then(({data}) => {
  381. if (data && data.code === 0) {
  382. this.alternativeList = data.rows;
  383. } else {
  384. this.$message.warning(data.msg);
  385. }
  386. }).catch((error) => {
  387. this.$message.error(error);
  388. })
  389. },
  390. handleChangeVersion(row) {
  391. let node = this.$refs.tree.getCurrentNode();
  392. let params = {
  393. partNo: row.partNo,
  394. bomType: row.bomType,
  395. buNo: row.buNo,
  396. site: row.site,
  397. engChgLevel: row.engChgLevel,
  398. alternativeNo: row.alternativeNo,
  399. createBy: this.$store.state.user.name,
  400. quoteId: this.quoteDetail.quoteId,
  401. quoteDetailId: this.quoteDetail.id,
  402. quoteNo: this.quoteDetail.quoteNo,
  403. quoteDetailItemNo: this.quoteDetail.itemNo,
  404. versionNo:this.quoteDetail.versionNo,
  405. }
  406. if (node) {
  407. params.id = node.id
  408. params.partNo = node.partNo
  409. params.bomType = node.bomType
  410. params.buNo = node.buNo
  411. params.site = node.site
  412. }
  413. changeQuoteDetailBomTree(params).then(({data}) => {
  414. if (data && data.code === 0) {
  415. this.$message.success(data.msg);
  416. this.versionVisible = false;
  417. this.handleQueryQuoteDetailBomTree();
  418. } else {
  419. this.$message.warning(data.msg);
  420. }
  421. }).catch((error) => {
  422. this.$message.error(error);
  423. })
  424. },
  425. handleJumpToBom(row){
  426. if (this.$router.resolve('part-bomManagement').resolved.name === '404') {
  427. this.$alert('权限不足,访问失败', '警告', {confirmButtonText: '确定',});
  428. } else {
  429. this.$emit('close')
  430. let params = {
  431. name: "part-bomManagement",
  432. params: {
  433. type:'quote',
  434. partNo:row.partNo,
  435. bomType:row.bomType,
  436. engChgLevel:row.engChgLevel,
  437. alternativeNo:row.alternativeNo,
  438. }
  439. }
  440. this.$router.push(params)
  441. }
  442. }
  443. },
  444. created() {
  445. if (this.quoteDetail && this.quoteDetail.id) {
  446. this.handleQueryQuoteDetailBomTree();
  447. }
  448. },
  449. watch: {
  450. 'quoteDetail.id'(newVal, oldVal) {
  451. this.handleQueryQuoteDetailBomTree();
  452. },
  453. isAllBom(newVal, oldVal) {
  454. this.handleQueryQuoteDetailBom();
  455. },
  456. 'bomEngChgLevel.engChgLevel'(newVal, oldVal) {
  457. if (newVal) {
  458. let node = this.$refs.tree.getCurrentNode();
  459. let row = {
  460. partNo: this.quoteDetail.partNo,
  461. buNo: this.quoteDetail.buNo,
  462. site: this.quoteDetail.site,
  463. engChgLevel: newVal,
  464. }
  465. if (node) {
  466. row.partNo = node.partNo;
  467. row.bomType = node.bomType;
  468. row.buNo = node.buNo;
  469. row.site = node.site;
  470. }
  471. this.levelRowClick(row)
  472. }
  473. }
  474. }
  475. }
  476. </script>
  477. <template>
  478. <div>
  479. <div style="margin-bottom: 10px">
  480. <el-link style="margin-right: 20px;cursor: pointer" @click="handleCheckedVersion" v-if="quoteDetail.status === '草稿'">切换版本</el-link>
  481. <el-checkbox v-model="isAllBom">全级BOM结构</el-checkbox>
  482. </div>
  483. <el-container>
  484. <el-aside width="300px" v-loading="queryTreeLoading">
  485. <el-tree
  486. :data="treeData"
  487. :props="props"
  488. :default-expand-all="true"
  489. :expand-on-click-node="false"
  490. node-key="id"
  491. highlight-current
  492. @node-click="nodeClick" ref="tree">
  493. </el-tree>
  494. </el-aside>
  495. <el-main style="padding: 0">
  496. <el-table :data="dataList" v-loading="queryLoading" border style="width: 100%" :height="420">
  497. <el-table-column
  498. v-for="(item,index) in columns" :key="index"
  499. :sortable="item.columnSortable"
  500. :prop="item.columnProp"
  501. :header-align="item.headerAlign"
  502. :show-overflow-tooltip="item.showOverflowTooltip"
  503. :align="item.align"
  504. :fixed="item.fixed===''?false:item.fixed"
  505. :min-width="item.columnWidth"
  506. :label="item.columnLabel">
  507. <template slot-scope="scope">
  508. <template v-if="item.columnProp === 'partNo'">
  509. <el-link @click="handleJumpToBom(scope.row)">{{ scope.row[item.columnProp] }}</el-link>
  510. </template>
  511. <template v-else>
  512. <span v-if="!item.columnHidden">{{ scope.row[item.columnProp] }}</span>
  513. <span v-if="item.columnImage"><img :src="scope.row[item.columnProp]" style="width: 100px; height: 80px"/></span>
  514. </template>
  515. </template>
  516. </el-table-column>
  517. </el-table>
  518. </el-main>
  519. </el-container>
  520. <el-dialog title="BOM版本切换" :visible.sync="versionVisible" append-to-body :close-on-click-modal="false" v-drag
  521. width="900px">
  522. <el-table :data="versionList" :row-style="levelRowStyle" @row-click="levelRowClick" ref="versionTable"
  523. style="width: 100%" border :height="240">
  524. <el-table-column label="物料编码" prop="partNo" header-align="center" align="center" show-overflow-tooltip
  525. min-width="140"/>
  526. <el-table-column label="物料描述" prop="partDesc" header-align="center" align="left" show-overflow-tooltip
  527. min-width="200"/>
  528. <el-table-column label="版本" prop="engChgLevel" header-align="center" align="center" show-overflow-tooltip
  529. min-width="60"/>
  530. <el-table-column label="类型" prop="bomType" header-align="center" align="center" show-overflow-tooltip
  531. min-width="100"/>
  532. </el-table>
  533. <el-table :data="alternativeList" :row-style="alternativeRowStyle" ref="versionTable"
  534. style="width: 100%;margin-top: 20px" border :height="240">
  535. <el-table-column label="物料编码" prop="partNo" header-align="center" align="center" show-overflow-tooltip
  536. min-width="140"/>
  537. <el-table-column label="物料描述" prop="partDesc" header-align="center" align="left" show-overflow-tooltip
  538. min-width="200"/>
  539. <el-table-column label="版本" prop="engChgLevel" header-align="center" align="center" show-overflow-tooltip
  540. min-width="60"/>
  541. <el-table-column label="替代编码" prop="alternativeNo" header-align="center" align="left" show-overflow-tooltip
  542. min-width="60"/>
  543. <el-table-column label="类型" prop="bomType" header-align="center" align="center" show-overflow-tooltip
  544. min-width="100"/>
  545. <el-table-column label="操作" header-align="center" align="center" min-width="100">
  546. <template slot-scope="scope">
  547. <a @click="handleChangeVersion(scope.row)">选择</a>
  548. </template>
  549. </el-table-column>
  550. </el-table>
  551. </el-dialog>
  552. </div>
  553. </template>
  554. <style scoped>
  555. </style>