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.

536 lines
19 KiB

1 year 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
1 year ago
2 years ago
1 year ago
1 year ago
  1. <script>
  2. import {
  3. batchDeleteQuotationTool,
  4. deleteQuotationTool, saveQuotationTool,
  5. searchQuotationTool
  6. } from "../../../../../api/quotation/quotationHeader";
  7. import {Decimal} from "decimal.js";
  8. import {searchTool, searchToolHeader} from "../../../../../api/part/toolHeader";
  9. export default {
  10. name:'toolQuotation',
  11. props:{
  12. detail:{
  13. type:Object,
  14. request:true,
  15. },
  16. height:{
  17. type:Number,
  18. default:400,
  19. },
  20. totalCost: {
  21. type:Number,
  22. default:0,
  23. }
  24. },
  25. data(){
  26. const validateToolNo = (rule, value, callback) => {
  27. if (this.saveQuotationToolFlag !== true){
  28. return;
  29. }
  30. if (value === '' || value === null || value === undefined){
  31. callback(new Error(' '))
  32. return
  33. }
  34. if (value === '*'){
  35. callback();
  36. return;
  37. }
  38. this.toolHeader.toolNo = value;
  39. searchTool(this.toolHeader).then(({data})=>{
  40. if (data.code === 200) {
  41. if (data.data.length === 1){
  42. callback()
  43. return
  44. }
  45. }
  46. this.toolHeader.toolNo = null;
  47. this.$message.error("工具编码不存在!")
  48. callback(new Error(' '))
  49. }).catch((error)=>{
  50. this.toolHeader.toolNo = null;
  51. callback(new Error(' '))
  52. })
  53. };
  54. return{
  55. saveQuotationToolFlag:false,
  56. quotationToolList:[],
  57. initQuotationToolLoading:false,
  58. toolHeaderDialogFlag:false,
  59. selectionQuotationToolList:[],
  60. saveQuotationToolLoading:false,
  61. selectionToolHeaderList:[],
  62. toolHeaderList:[],
  63. quotationTool: {
  64. quotationToolId: undefined,
  65. site: this.$store.state.user.site,
  66. toolNo: "",
  67. toolDescription: "",
  68. toolQuantity: 1,
  69. unitCost: 1,
  70. quotationUnitCost:0,
  71. expectedServiceLife: 1,
  72. remark: "",
  73. },
  74. // 工具列表筛选对象
  75. toolHeader:{
  76. site:this.$store.state.user.site,
  77. toolNo:undefined,// 编号
  78. toolDescription:undefined,// 描述
  79. },
  80. // 报价工具表单校验
  81. quotationToolRules: {
  82. toolNo: [{required: true, message:" ", trigger: 'change'}],
  83. toolDescription: [{required: true, message: ' ', trigger: ['change','blur']}],
  84. toolQuantity: [{required: true,pattern:/^[1-9]\d{0,14}(\.\d{1,16})?$|^0(\.\d{1,16})?$/, message: ' ', trigger: ['change','blur']}],
  85. unitCost: [{required: true,pattern:/^[1-9]\d{0,14}(\.\d{1,16})?$|^0(\.\d{1,16})?$/, message: ' ', trigger: ['change','blur']}],
  86. expectedServiceLife: [{required: true,pattern:/^[1-9]\d{0,14}(\.\d{1,16})?$|^0(\.\d{1,16})?$/, message: ' ', trigger: ['change','blur']}],
  87. },
  88. // 工具列表
  89. quotationToolColumns: [
  90. {label: "toolNo", value: "工具编码",},
  91. {label: "toolDescription", value: "工具描述",},
  92. {label: "toolQuantity", value: "工具数量",},
  93. {label: "unitCost", value: "单位成本",},
  94. {label: "itemNo", value: "序号",},
  95. {label: "expectedServiceLife", value: "预计使用寿命",},
  96. ],
  97. columnList: [
  98. {
  99. userId: this.$store.state.user.name,
  100. functionId: 102003,
  101. serialNumber: '102003ToolNo',
  102. tableId: '102003Table6',
  103. tableName: '工具信息表',
  104. columnProp: 'toolNo',
  105. headerAlign: 'center',
  106. align: 'center',
  107. columnLabel: '工具编码',
  108. columnHidden: false,
  109. columnImage: false,
  110. columnSortable: false,
  111. sortLv: 0,
  112. status: true,
  113. fixed: '',
  114. columnWidth: 120
  115. },{
  116. userId: this.$store.state.user.name,
  117. functionId: 102003,
  118. serialNumber: '102003ToolDescription',
  119. tableId: '102003Table6',
  120. tableName: '工具信息表',
  121. columnProp: 'toolDescription',
  122. headerAlign: 'center',
  123. align: 'left',
  124. columnLabel: '工具描述',
  125. columnHidden: false,
  126. columnImage: false,
  127. columnSortable: false,
  128. sortLv: 0,
  129. status: true,
  130. fixed: '',
  131. columnWidth: 120
  132. },{
  133. userId: this.$store.state.user.name,
  134. functionId: 102003,
  135. serialNumber: '102003ToolQuantity',
  136. tableId: '102003Table6',
  137. tableName: '工具信息表',
  138. columnProp: 'toolQuantity',
  139. headerAlign: 'center',
  140. align: 'right',
  141. columnLabel: '工具数量',
  142. columnHidden: false,
  143. columnImage: false,
  144. columnSortable: false,
  145. sortLv: 0,
  146. status: true,
  147. fixed: '',
  148. columnWidth: 100
  149. },{
  150. userId: this.$store.state.user.name,
  151. functionId: 102003,
  152. serialNumber: '102003UnitCost',
  153. tableId: '102003Table6',
  154. tableName: '工具信息表',
  155. columnProp: 'unitCost',
  156. headerAlign: 'center',
  157. align: 'right',
  158. columnLabel: '单位成本',
  159. columnHidden: false,
  160. columnImage: false,
  161. columnSortable: false,
  162. sortLv: 0,
  163. status: true,
  164. fixed: '',
  165. columnWidth: 120
  166. },{
  167. userId: this.$store.state.user.name,
  168. functionId: 102003,
  169. serialNumber: '102003ExpectedServiceLife',
  170. tableId: '102003Table6',
  171. tableName: '工具信息表',
  172. columnProp: 'expectedServiceLife',
  173. headerAlign: 'center',
  174. align: 'right',
  175. columnLabel: '预计使用寿命',
  176. columnHidden: false,
  177. columnImage: false,
  178. columnSortable: false,
  179. sortLv: 0,
  180. status: true,
  181. fixed: '',
  182. columnWidth: 120
  183. },{
  184. userId: this.$store.state.user.name,
  185. functionId: 102003,
  186. serialNumber: '102003QuotationUnitCost',
  187. tableId: '102003Table6',
  188. tableName: '工具信息表',
  189. columnProp: 'quotationUnitCost',
  190. headerAlign: 'center',
  191. align: 'right',
  192. columnLabel: '单位报价成本',
  193. columnHidden: false,
  194. columnImage: false,
  195. columnSortable: false,
  196. sortLv: 0,
  197. status: true,
  198. fixed: '',
  199. columnWidth: 120
  200. },{
  201. userId: this.$store.state.user.name,
  202. functionId: 102003,
  203. serialNumber: '102003Remark',
  204. tableId: '102003Table6',
  205. tableName: '工具信息表',
  206. columnProp: 'remark',
  207. headerAlign: 'center',
  208. align: 'left',
  209. columnLabel: '备注',
  210. columnHidden: false,
  211. columnImage: false,
  212. columnSortable: false,
  213. sortLv: 0,
  214. status: true,
  215. fixed: '',
  216. columnWidth: 120
  217. },
  218. ],
  219. }
  220. },
  221. created() {
  222. // this.initQuotationToolData();
  223. },
  224. methods:{
  225. getQuotationToolList(){
  226. // this.initQuotationToolData();
  227. // 计算成本
  228. return this.quotationToolList.reduce((total, currentValue) => {
  229. return total + new Decimal(currentValue.quotationUnitCost).toNumber();
  230. }, 0);
  231. },
  232. initQuotationToolData() {
  233. let params = {
  234. quotationDetailId: this.detail.quotationDetailId,
  235. }
  236. this.initQuotationToolLoading = true;
  237. searchQuotationTool(params).then(({data}) => {
  238. this.initQuotationToolLoading = false;
  239. if (data && data.code === 200) {
  240. this.quotationToolList = data.data;
  241. this.$emit("update:totalCost",this.getQuotationToolList());
  242. }else {
  243. this.$message.warning(data.msg)
  244. }
  245. }).catch((error)=>{
  246. this.initQuotationToolLoading = false;
  247. })
  248. },
  249. handleSelectionChangeQuotationToolTable(selection){
  250. this.selectionQuotationToolList = selection;
  251. },
  252. clickEditToolTableBtn(row){
  253. this.quotationTool = JSON.parse(JSON.stringify(row));
  254. this.saveQuotationToolFlag= true;
  255. },
  256. clickDeleteToolTableBtn(row){
  257. this.$confirm('确定要删除该记录吗?', '提示', {
  258. confirmButtonText: '确定',
  259. cancelButtonText: '取消',
  260. type: 'warning'
  261. }).then(() => {
  262. deleteQuotationTool(row).then(({data})=>{
  263. if (data.code === 200){
  264. this.initQuotationToolData();
  265. this.$message.success(data.msg);
  266. }else {
  267. this.$message.error(data.msg);
  268. }
  269. })
  270. })
  271. },
  272. deleteSelectionQuotationTool(){
  273. if (this.selectionQuotationToolList.length === 0) {
  274. this.$message.warning("请选择要删除的工具记录")
  275. return;
  276. }
  277. this.$confirm('确定要删除该记录吗?', '提示', {
  278. confirmButtonText: '确定',
  279. cancelButtonText: '取消',
  280. type: 'warning'
  281. }).then(() => {
  282. batchDeleteQuotationTool(this.selectionQuotationToolList).then(({data})=>{
  283. if (data.code === 200){
  284. this.initQuotationToolData();
  285. this.$message.success(data.msg);
  286. }else {
  287. this.$message.error(data.msg);
  288. }
  289. })
  290. })
  291. },
  292. // 关闭 报价工具 新增弹框
  293. closeQuotationToolDialog() {
  294. this.$refs['quotationToolForm'].resetFields();
  295. this.quotationTool = {
  296. quotationToolId: undefined,
  297. site: this.$store.state.user.site,
  298. toolNo: "",
  299. toolDescription: "",
  300. toolQuantity: 1,
  301. unitCost: 1,
  302. quotationUnitCost: 0,
  303. expectedServiceLife: 1,
  304. remark: "",
  305. };
  306. if (this.selectionToolHeaderList.length > 0){
  307. this.$refs.toolHeaderForm.resetFields();
  308. }
  309. this.selectionQuotationToolList = [];
  310. if (this.$refs.toolHeaderTable) {
  311. this.$refs.toolHeaderTable.clearSelection();
  312. }
  313. },
  314. openQuotationToolDialog(){
  315. this.computeToolQuotationUnitCost(this.quotationTool);
  316. },
  317. computeToolQuotationUnitCost(row){
  318. //单位报价成本 = 单位成本 * 工具数量 / 预计使用寿命
  319. if (!row.expectedServiceLife || row.expectedServiceLife <= 0){
  320. this.quotationTool.expectedServiceLife = 1;
  321. }
  322. if (!row.toolQuantity || row.toolQuantity <= 0){
  323. this.quotationTool.toolQuantity = 1;
  324. }
  325. if (!row.unitCost || row.unitCost < 0){
  326. this.quotationTool.unitCost = 0;
  327. }
  328. if (!row.expectedServiceLife || !row.toolQuantity || !row.unitCost){
  329. row.quotationUnitCost = 0;
  330. return
  331. }
  332. row.quotationUnitCost = new Decimal(new Decimal(row.unitCost).mul(new Decimal(row.toolQuantity)).div(new Decimal(row.expectedServiceLife)).toFixed(4,Decimal.ROUND_HALF_UP)).toSignificantDigits().toNumber();
  333. },
  334. saveQuotationTool() {
  335. this.$refs['quotationToolForm'].validate((validate, object) => {
  336. if (validate) {
  337. this.saveQuotationToolLoading = true;
  338. this.quotationTool.quotationDetailId = this.detail.quotationDetailId;
  339. this.insertQuotationToolData();
  340. } else {
  341. this.rulesValidateLabel(object, this.quotationToolColumns);// 校验提示
  342. }
  343. })
  344. },
  345. insertQuotationToolData(){
  346. saveQuotationTool(this.quotationTool).then(({data}) => {
  347. this.saveQuotationToolLoading = false;
  348. if (data.code === 200) {
  349. this.initQuotationToolData();
  350. this.$message.success(data.msg);
  351. this.saveQuotationToolFlag = false;// 关闭弹框
  352. } else {
  353. this.$message.error(data.msg);
  354. }
  355. }).catch((error)=>{
  356. this.saveQuotationToolLoading = false;
  357. })
  358. },
  359. // 打开 工具信息弹框
  360. openToolHeaderDialog(){
  361. if (this.selectionToolHeaderList.length > 0) {
  362. this.$refs.quotationToolForm.resetFields();
  363. }
  364. },
  365. initToolHeader(){
  366. searchToolHeader(this.toolHeader).then(({data})=>{
  367. if (data.code === 200) {
  368. this.toolHeaderList = data.data;
  369. this.toolHeaderList = this.toolHeaderList.map(item =>{
  370. let utilObj = {
  371. toolNo:item.toolId,
  372. toolDescription:item.toolDescription,
  373. unitCost:item.standardCost,
  374. }
  375. return utilObj;
  376. })
  377. }
  378. })
  379. },
  380. handleSelectionChangeToolHeaderTable(selection){
  381. this.selectionToolHeaderList = selection;
  382. },
  383. dblclickToolHeader(row){
  384. row = JSON.parse(JSON.stringify(row));
  385. this.quotationTool.toolNo = row.toolNo;
  386. this.quotationTool.toolDescription = row.toolDescription;
  387. this.quotationTool.unitCost = row.unitCost ? row.unitCost : 0;
  388. this.computeToolQuotationUnitCost(this.quotationTool)
  389. this.toolHeaderDialogFlag= false;
  390. },
  391. // 校验处理
  392. rulesValidateLabel(objects, labels) {
  393. for (let filed in objects) {
  394. for (let i = 0; i < labels.length; i++) {
  395. let quotationToolColumn = labels[i];
  396. if (quotationToolColumn.label === filed) {
  397. this.$message.warning(quotationToolColumn.value+"为空或填写不正确");
  398. return
  399. }
  400. }
  401. }
  402. },
  403. },
  404. }
  405. </script>
  406. <template>
  407. <div>
  408. <div>
  409. <el-button type="primary" @click="saveQuotationToolFlag = true"> </el-button>
  410. <el-button type="primary" @click="deleteSelectionQuotationTool"> </el-button>
  411. </div>
  412. <el-table style="margin-top: 5px" ref="quotationToolTable"
  413. v-loading="initQuotationToolLoading"
  414. element-loading-text = "数据正在加载中"
  415. @selection-change="handleSelectionChangeQuotationToolTable"
  416. :data="quotationToolList" :height="height" stripe border>
  417. <el-table-column
  418. type="selection"
  419. align="center"
  420. width="55">
  421. </el-table-column>
  422. <el-table-column label="操作" width="120" align="center" >
  423. <template slot-scope="{row,$index}">
  424. <el-link style="cursor: pointer" @click="clickEditToolTableBtn(row)">编辑</el-link>
  425. <!-- <el-link style="cursor: pointer" @click="clickDeleteToolTableBtn(row)">删除</el-link>-->
  426. </template>
  427. </el-table-column>
  428. <el-table-column
  429. v-for="(item,index) in columnList" :key="index"
  430. :sortable="item.columnSortable"
  431. :prop="item.columnProp"
  432. :header-align="item.headerAlign"
  433. :show-overflow-tooltip="item.showOverflowTooltip"
  434. :align="item.align"
  435. :fixed="item.fixed===''?false:item.fixed"
  436. :min-width="item.columnWidth"
  437. :label="item.columnLabel">
  438. <template slot-scope="scope" >
  439. <span v-if="!item.columnHidden"> {{ scope.row[item.columnProp]}}</span>
  440. <span v-if="item.columnImage"><img :src="scope.row[item.columnProp]" style="width: 100px; height: 80px"/></span>
  441. </template>
  442. </el-table-column>
  443. </el-table>
  444. <el-dialog title="报价工具" v-drag
  445. @close="closeQuotationToolDialog"
  446. @open="openQuotationToolDialog"
  447. :visible.sync="saveQuotationToolFlag" width="40%"
  448. :close-on-click-modal="false"
  449. top="15vh" append-to-body>
  450. <el-form :rules="quotationToolRules" ref="quotationToolForm" :model="quotationTool" label-position="top"
  451. style="height: 260px">
  452. <el-row>
  453. <el-col :span="8">
  454. <el-form-item label="工具编码" prop="toolNo">
  455. <span slot="label" @click="toolHeaderDialogFlag = true" style="cursor: pointer"><a>工具编码</a></span>
  456. <el-input v-model="quotationTool.toolNo" clearable/>
  457. </el-form-item>
  458. </el-col>
  459. <el-col :span="12" :offset="2">
  460. <el-form-item label="工具描述" prop="toolDescription">
  461. <el-input v-model="quotationTool.toolDescription" :disabled="quotationTool.toolNo !== '*'" clearable/>
  462. </el-form-item>
  463. </el-col>
  464. </el-row>
  465. <el-row>
  466. <el-col :span="8">
  467. <el-form-item label="工具数量" prop="toolQuantity">
  468. <el-input-number style="margin-top: -5px;width: 100%;" v-model="quotationTool.toolQuantity" :controls="false" :min="1" @input="computeToolQuotationUnitCost(quotationTool)"></el-input-number>
  469. </el-form-item>
  470. </el-col>
  471. <el-col :span="12" :offset="2">
  472. <el-form-item label="预计使用寿命" prop="expectedServiceLife">
  473. <el-input-number style="margin-top: -5px;width: 100%" v-model="quotationTool.expectedServiceLife" :controls="false" :min="1" @input="computeToolQuotationUnitCost(quotationTool)"></el-input-number>
  474. </el-form-item>
  475. </el-col>
  476. </el-row>
  477. <el-row>
  478. <el-col :span="8">
  479. <el-form-item label="单位成本" prop="unitCost">
  480. <el-input-number style="margin-top: -5px;width: 100%" v-model="quotationTool.unitCost" :disabled="quotationTool.toolNo !== '*'" :controls="false" :min="1" @input="computeToolQuotationUnitCost(quotationTool)"></el-input-number>
  481. </el-form-item>
  482. </el-col>
  483. <el-col :span="12" :offset="2">
  484. <el-form-item label="单位报价成本" prop="unitCost">
  485. <el-input-number disabled style="margin-top: -5px;width: 100%" v-model="quotationTool.quotationUnitCost" :controls="false" :min="1"></el-input-number>
  486. </el-form-item>
  487. </el-col>
  488. </el-row>
  489. <el-form-item label="备注" prop="remark" style="height: 90px">
  490. <el-input v-model="quotationTool.remark" resize="none" type="textarea" :autosize="{minRows: 3, maxRows: 3}" style="width: 93%"/>
  491. </el-form-item>
  492. </el-form>
  493. <span slot="footer" class="dialog-footer" style="margin-top: 5px">
  494. <el-button type="primary" :loading="saveQuotationToolLoading" @click="saveQuotationTool"> </el-button>
  495. <el-button @click="saveQuotationToolFlag= false"> </el-button>
  496. </span>
  497. </el-dialog>
  498. <!--tool列表-->
  499. <el-dialog v-drag title="工具信息"
  500. @open="openToolHeaderDialog"
  501. width="40%" top="15vh" append-to-body
  502. :close-on-click-modal="false"
  503. :visible.sync="toolHeaderDialogFlag">
  504. <!--搜索条件-->
  505. <el-form :model="toolHeader" ref="toolHeaderForm" :inline="true" label-position="top">
  506. <el-form-item label="工具编号" prop="toolNo">
  507. <el-input v-model="toolHeader.toolNo" clearable/>
  508. </el-form-item>
  509. <el-form-item label="工具描述" prop="toolDescription">
  510. <el-input v-model="toolHeader.toolDescription" clearable/>
  511. </el-form-item>
  512. <el-form-item label=" ">
  513. <el-button type="primary" @click="initToolHeader"> </el-button>
  514. </el-form-item>
  515. </el-form>
  516. <!--筛选的数据-->
  517. <el-table :data="toolHeaderList" ref="toolHeaderTable" :style="{marginTop:'10px'}"
  518. height="300px" stripe border @selection-change="handleSelectionChangeToolHeaderTable"
  519. @row-dblclick="dblclickToolHeader">
  520. <el-table-column label="工具编号" prop="toolNo"/>
  521. <el-table-column label="工具描述" prop="toolDescription"/>
  522. </el-table>
  523. </el-dialog>
  524. </div>
  525. </template>
  526. <style scoped>
  527. .el-input-number /deep/ .el-input__inner{
  528. text-align: right;
  529. padding-right: 5px !important;
  530. }
  531. </style>