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.

545 lines
17 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
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
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
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
1 year ago
1 year ago
1 year ago
1 year ago
1 year 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. {
  165. userId: this.$store.state.user.name,
  166. functionId: 5011,
  167. serialNumber: '5011Table4UnitPrice',
  168. tableId: "5011Table4",
  169. tableName: "报价材料信息",
  170. columnProp: 'unitPrice',
  171. headerAlign: "center",
  172. align: "right",
  173. columnLabel: '单位标准成本',
  174. columnHidden: false,
  175. columnImage: false,
  176. columnSortable: false,
  177. sortLv: 0,
  178. status: true,
  179. fixed: '',
  180. columnWidth: 90,
  181. },
  182. {
  183. userId: this.$store.state.user.name,
  184. functionId: 5011,
  185. serialNumber: '5011Table4ActualPrice',
  186. tableId: "5011Table4",
  187. tableName: "报价材料信息",
  188. columnProp: 'actualPrice',
  189. headerAlign: "center",
  190. align: "right",
  191. columnLabel: '单位报价成本',
  192. columnHidden: false,
  193. columnImage: false,
  194. columnSortable: false,
  195. sortLv: 0,
  196. status: true,
  197. fixed: '',
  198. columnWidth: 90,
  199. },
  200. {
  201. userId: this.$store.state.user.name,
  202. functionId: 5011,
  203. serialNumber: '5011Table4QuoteUnitPrice',
  204. tableId: "5011Table4",
  205. tableName: "报价材料信息",
  206. columnProp: 'quoteUnitPrice',
  207. headerAlign: "center",
  208. align: "right",
  209. columnLabel: '材料标准总成本',
  210. columnHidden: false,
  211. columnImage: false,
  212. columnSortable: false,
  213. sortLv: 0,
  214. status: true,
  215. fixed: 'right',
  216. columnWidth: 100,
  217. },
  218. {
  219. userId: this.$store.state.user.name,
  220. functionId: 5011,
  221. serialNumber: '5011Table4ActualQuotePrice',
  222. tableId: "5011Table4",
  223. tableName: "报价材料信息",
  224. columnProp: 'actualQuotePrice',
  225. headerAlign: "center",
  226. align: "right",
  227. columnLabel: '材料报价总成本',
  228. columnHidden: false,
  229. columnImage: false,
  230. columnSortable: false,
  231. sortLv: 0,
  232. status: true,
  233. fixed: 'right',
  234. columnWidth: 100,
  235. },
  236. ],
  237. props: {
  238. children: 'list',
  239. label: (data, node) => {
  240. return `${data.partNo}-${data.engChgLevel}-${data.alternativeNo}-${data.bomType}`;
  241. },
  242. },
  243. queryLoading: false,
  244. queryTreeLoading: false,
  245. versionVisible: false,
  246. versionList: [],
  247. alternativeList: [],
  248. bomEngChgLevel: {
  249. partNo: '',
  250. bomType: '',
  251. buNo: '',
  252. site: '',
  253. engChgLevel: null,
  254. }
  255. }
  256. },
  257. methods: {
  258. handleQueryQuoteDetailBomTree() {
  259. let params = {
  260. id: this.quoteDetail.id,
  261. }
  262. this.queryTreeLoading = true;
  263. queryQuoteDetailBomTree(params).then(({data}) => {
  264. if (data && data.code === 0) {
  265. this.treeData = data.rows;
  266. if (this.treeData.length > 0) {
  267. this.$nextTick(() => {
  268. this.$refs.tree.setCurrentKey(this.treeData[0].id);
  269. this.handleQueryQuoteDetailBom();
  270. })
  271. }
  272. this.queryTreeLoading = false;
  273. } else {
  274. this.$message.warning(data.msg);
  275. this.queryTreeLoading = false;
  276. }
  277. }).catch((error) => {
  278. this.$message.error(error);
  279. })
  280. },
  281. nodeClick(data) {
  282. this.handleQueryQuoteDetailBom();
  283. },
  284. handleQueryQuoteDetailBom() {
  285. let params = {
  286. quoteDetailId: this.quoteDetail.id,
  287. treeId: this.$refs.tree.getCurrentKey(),
  288. allTree: this.isAllBom,
  289. }
  290. this.queryLoading = true;
  291. queryQuoteDetailBom(params).then(({data}) => {
  292. if (data && data.code === 0) {
  293. this.dataList = data.rows;
  294. } else {
  295. this.$message.warning(data.msg);
  296. }
  297. this.queryLoading = false;
  298. }).catch((error) => {
  299. this.$message.error(error);
  300. this.queryLoading = false;
  301. })
  302. },
  303. handleCheckedVersion() {
  304. this.handleQueryQuoteDetailBomTreeVersion();
  305. let node = this.$refs.tree.getCurrentNode();
  306. if (node) {
  307. this.bomEngChgLevel = {
  308. partNo: node.partNo,
  309. bomType: node.bomType,
  310. buNo: node.buNo,
  311. site: node.site,
  312. engChgLevel: node.engChgLevel,
  313. alternativeNo: node.alternativeNo,
  314. }
  315. }
  316. this.versionVisible = true
  317. },
  318. handleQueryQuoteDetailBomTreeVersion() {
  319. let node = this.$refs.tree.getCurrentNode();
  320. let params = {
  321. site: this.quoteDetail.site,
  322. partNo: this.quoteDetail.partNo,
  323. buNo: this.quoteDetail.buNo,
  324. }
  325. if (node) {
  326. params = {
  327. site: node.site,
  328. partNo: node.partNo,
  329. bomType: node.bomType,
  330. buNo: node.buNo,
  331. }
  332. }
  333. queryQuoteDetailBomTreeLevel(params).then(({data}) => {
  334. if (data && data.code === 0) {
  335. this.versionList = data.rows;
  336. } else {
  337. this.$message.warning(data.msg);
  338. }
  339. }).catch((error) => {
  340. this.$message.error(error);
  341. })
  342. },
  343. levelRowStyle({row}) {
  344. if (row.engChgLevel === this.bomEngChgLevel.engChgLevel) {
  345. return {'background-color': '#E8F7F6'};
  346. }
  347. },
  348. alternativeRowStyle({row}) {
  349. let node = this.$refs.tree.getCurrentNode();
  350. if (row.engChgLevel === this.bomEngChgLevel.engChgLevel && row.alternativeNo === this.bomEngChgLevel.alternativeNo) {
  351. return {'background-color': '#E8F7F6'};
  352. }
  353. },
  354. levelRowClick(row) {
  355. this.bomEngChgLevel.partNo = row.partNo;
  356. this.bomEngChgLevel.buNo = row.buNo;
  357. this.bomEngChgLevel.site = row.site;
  358. this.bomEngChgLevel.engChgLevel = row.engChgLevel;
  359. this.bomEngChgLevel.bomType = row.bomType;
  360. let params = {
  361. ...this.bomEngChgLevel
  362. }
  363. queryQuoteDetailBomTreeAlternative(params).then(({data}) => {
  364. if (data && data.code === 0) {
  365. this.alternativeList = data.rows;
  366. } else {
  367. this.$message.warning(data.msg);
  368. }
  369. }).catch((error) => {
  370. this.$message.error(error);
  371. })
  372. },
  373. handleChangeVersion(row) {
  374. let node = this.$refs.tree.getCurrentNode();
  375. let params = {
  376. partNo: row.partNo,
  377. bomType: row.bomType,
  378. buNo: row.buNo,
  379. site: row.site,
  380. engChgLevel: row.engChgLevel,
  381. alternativeNo: row.alternativeNo,
  382. createBy: this.$store.state.user.name,
  383. quoteId: this.quoteDetail.quoteId,
  384. quoteDetailId: this.quoteDetail.id,
  385. quoteNo: this.quoteDetail.quoteNo,
  386. quoteDetailItemNo: this.quoteDetail.itemNo,
  387. versionNo:this.quoteDetail.versionNo,
  388. }
  389. if (node) {
  390. params.id = node.id
  391. params.partNo = node.partNo
  392. params.bomType = node.bomType
  393. params.buNo = node.buNo
  394. params.site = node.site
  395. }
  396. changeQuoteDetailBomTree(params).then(({data}) => {
  397. if (data && data.code === 0) {
  398. this.$message.success(data.msg);
  399. this.versionVisible = false;
  400. this.handleQueryQuoteDetailBomTree();
  401. } else {
  402. this.$message.warning(data.msg);
  403. }
  404. }).catch((error) => {
  405. this.$message.error(error);
  406. })
  407. },
  408. handleJumpToBom(row){
  409. if (this.$router.resolve('part-bomManagement').resolved.name === '404') {
  410. this.$alert('权限不足,访问失败', '警告', {confirmButtonText: '确定',});
  411. } else {
  412. this.$emit('close')
  413. let params = {
  414. name: "part-bomManagement",
  415. params: {
  416. type:'quote',
  417. partNo:row.partNo,
  418. bomType:row.bomType,
  419. engChgLevel:row.engChgLevel,
  420. alternativeNo:row.alternativeNo,
  421. }
  422. }
  423. this.$router.push(params)
  424. }
  425. }
  426. },
  427. created() {
  428. if (this.quoteDetail && this.quoteDetail.id) {
  429. this.handleQueryQuoteDetailBomTree();
  430. }
  431. },
  432. watch: {
  433. 'quoteDetail.id'(newVal, oldVal) {
  434. this.handleQueryQuoteDetailBomTree();
  435. },
  436. isAllBom(newVal, oldVal) {
  437. this.handleQueryQuoteDetailBom();
  438. },
  439. 'bomEngChgLevel.engChgLevel'(newVal, oldVal) {
  440. if (newVal) {
  441. let node = this.$refs.tree.getCurrentNode();
  442. let row = {
  443. partNo: this.quoteDetail.partNo,
  444. buNo: this.quoteDetail.buNo,
  445. site: this.quoteDetail.site,
  446. engChgLevel: newVal,
  447. }
  448. if (node) {
  449. row.partNo = node.partNo;
  450. row.bomType = node.bomType;
  451. row.buNo = node.buNo;
  452. row.site = node.site;
  453. }
  454. this.levelRowClick(row)
  455. }
  456. }
  457. }
  458. }
  459. </script>
  460. <template>
  461. <div>
  462. <div style="margin-bottom: 10px">
  463. <el-link style="margin-right: 20px;cursor: pointer" @click="handleCheckedVersion" v-if="quoteDetail.status === '草稿'">切换版本</el-link>
  464. <el-checkbox v-model="isAllBom">全级BOM结构</el-checkbox>
  465. </div>
  466. <el-container>
  467. <el-aside width="300px" v-loading="queryTreeLoading">
  468. <el-tree
  469. :data="treeData"
  470. :props="props"
  471. :default-expand-all="true"
  472. :expand-on-click-node="false"
  473. node-key="id"
  474. highlight-current
  475. @node-click="nodeClick" ref="tree">
  476. </el-tree>
  477. </el-aside>
  478. <el-main style="padding: 0">
  479. <el-table :data="dataList" v-loading="queryLoading" border style="width: 100%" :height="420">
  480. <el-table-column
  481. v-for="(item,index) in columns" :key="index"
  482. :sortable="item.columnSortable"
  483. :prop="item.columnProp"
  484. :header-align="item.headerAlign"
  485. :show-overflow-tooltip="item.showOverflowTooltip"
  486. :align="item.align"
  487. :fixed="item.fixed===''?false:item.fixed"
  488. :min-width="item.columnWidth"
  489. :label="item.columnLabel">
  490. <template slot-scope="scope">
  491. <template v-if="item.columnProp === 'partNo'">
  492. <el-link @click="handleJumpToBom(scope.row)">{{ scope.row[item.columnProp] }}</el-link>
  493. </template>
  494. <template v-else>
  495. <span v-if="!item.columnHidden">{{ scope.row[item.columnProp] }}</span>
  496. <span v-if="item.columnImage"><img :src="scope.row[item.columnProp]" style="width: 100px; height: 80px"/></span>
  497. </template>
  498. </template>
  499. </el-table-column>
  500. </el-table>
  501. </el-main>
  502. </el-container>
  503. <el-dialog title="BOM版本切换" :visible.sync="versionVisible" append-to-body :close-on-click-modal="false" v-drag
  504. width="900px">
  505. <el-table :data="versionList" :row-style="levelRowStyle" @row-click="levelRowClick" ref="versionTable"
  506. style="width: 100%" border :height="240">
  507. <el-table-column label="物料编码" prop="partNo" header-align="center" align="center" show-overflow-tooltip
  508. min-width="140"/>
  509. <el-table-column label="物料描述" prop="partDesc" header-align="center" align="left" show-overflow-tooltip
  510. min-width="200"/>
  511. <el-table-column label="版本" prop="engChgLevel" header-align="center" align="center" show-overflow-tooltip
  512. min-width="60"/>
  513. <el-table-column label="类型" prop="bomType" header-align="center" align="center" show-overflow-tooltip
  514. min-width="100"/>
  515. </el-table>
  516. <el-table :data="alternativeList" :row-style="alternativeRowStyle" ref="versionTable"
  517. style="width: 100%;margin-top: 20px" border :height="240">
  518. <el-table-column label="物料编码" prop="partNo" header-align="center" align="center" show-overflow-tooltip
  519. min-width="140"/>
  520. <el-table-column label="物料描述" prop="partDesc" header-align="center" align="left" show-overflow-tooltip
  521. min-width="200"/>
  522. <el-table-column label="版本" prop="engChgLevel" header-align="center" align="center" show-overflow-tooltip
  523. min-width="60"/>
  524. <el-table-column label="替代编码" prop="alternativeNo" header-align="center" align="left" show-overflow-tooltip
  525. min-width="60"/>
  526. <el-table-column label="类型" prop="bomType" header-align="center" align="center" show-overflow-tooltip
  527. min-width="100"/>
  528. <el-table-column label="操作" header-align="center" align="center" min-width="100">
  529. <template slot-scope="scope">
  530. <a @click="handleChangeVersion(scope.row)">选择</a>
  531. </template>
  532. </el-table-column>
  533. </el-table>
  534. </el-dialog>
  535. </div>
  536. </template>
  537. <style scoped>
  538. </style>