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.

532 lines
17 KiB

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