Эх сурвалжийг харах

Merge branch 'dev' of http://110.41.163.243:9980/kd-aiot/kd-aiot-frontend-wt into dev

yusheng 2 сар өмнө
parent
commit
35ad574115
29 өөрчлөгдсөн 2243 нэмэгдсэн , 1335 устгасан
  1. 2 1
      .claude/settings.local.json
  2. 18 12
      src/BIZComponents/enventSubmitDialog/processSubmitDialog.vue
  3. 6 8
      src/BIZComponents/inventoryTable.vue
  4. 168 36
      src/BIZComponents/paymentCollectionPlan/Index.vue
  5. 30 13
      src/BIZComponents/processSubmitDialog/processSubmitDialog.vue
  6. 134 32
      src/BIZComponents/setProduct.js
  7. 14 10
      src/api/bpm/components/equipmentDisposal/index.js
  8. 13 0
      src/api/bpm/components/purchasingManage/purchaseOrder.js
  9. 7 0
      src/api/pda/index.js
  10. 21 0
      src/api/warehouseManagement/index.js
  11. 110 0
      src/directives/tableScrollSync.js
  12. 3 0
      src/main.js
  13. 5 0
      src/views/bpm/handleTask/components/allocate/detailDialog.vue
  14. 5 0
      src/views/bpm/handleTask/components/contractBook/detailDialog.vue
  15. 209 0
      src/views/bpm/handleTask/components/ehsEquipmentDisposal/edit.vue
  16. 102 0
      src/views/bpm/handleTask/components/ehsEquipmentDisposal/submit.vue
  17. 30 6
      src/views/bpm/handleTask/components/productionWarehousing/detailDialog.vue
  18. 416 589
      src/views/bpm/handleTask/components/productionWarehousing/storage.vue
  19. 100 2
      src/views/bpm/handleTask/components/purchaseOrder/detailDialog.vue
  20. 32 16
      src/views/bpm/handleTask/components/purchaseOrder/invoice/receiptInfo.vue
  21. 12 0
      src/views/bpm/handleTask/components/purchaseOrder/submit.vue
  22. 19 1
      src/views/bpm/handleTask/components/saleOrder/saleReturnGoods/detailDialog.vue
  23. 33 6
      src/views/bpm/handleTask/components/selectedCollectionOutbound/boxTabPage.vue
  24. 96 0
      src/views/bpm/handleTask/components/selectedCollectionOutbound/ehsDetailDialog.vue
  25. 14 0
      src/views/bpm/outgoingManagement/components/AssetsDialog.vue
  26. 60 16
      src/views/bpm/outgoingManagement/outbound.vue
  27. 580 583
      src/views/bpm/stockManagement/storage.vue
  28. 2 2
      src/views/bpm/tickets/work/index.vue
  29. 2 2
      vue.config.js

+ 2 - 1
.claude/settings.local.json

@@ -2,7 +2,8 @@
   "permissions": {
     "allow": [
       "Bash(python *)",
-      "Bash(node *)"
+      "Bash(node *)",
+      "mcp__ide__getDiagnostics"
     ]
   }
 }

+ 18 - 12
src/BIZComponents/enventSubmitDialog/processSubmitDialog.vue

@@ -152,7 +152,9 @@
         v-click-once
         >提交并发布</el-button
       >
-      <el-button size="small" @click="isCloseRefresh ? cancel() : cancel1()">关闭</el-button>
+      <el-button size="small" @click="isCloseRefresh ? cancel() : cancel1()"
+        >关闭</el-button
+      >
     </div>
   </ele-modal>
 </template>
@@ -210,7 +212,7 @@
       isCloseRefresh: {
         type: Boolean,
         default: true
-      },
+      }
     },
     data() {
       return {
@@ -294,7 +296,7 @@
     methods: {
       init(row = {}) {
         this.form = { ...this.form, ...row };
-        console.log(row)
+        console.log(row);
         // this.form.businessId = row.id;
         // this.form.businessKey = row.businessKey;
         // this.form.formCreateUserId = row.createUserId;
@@ -361,6 +363,12 @@
               return roleOption.name;
             }
           }
+        } else if (row.type == 11) {
+          for (const roleOption of this.roleOptions) {
+            if (roleOption.id === option) {
+              return roleOption.name;
+            }
+          }
         } else if (row.type === 20 || row.type === 21) {
           for (const deptOption of this.deptOptions) {
             if (deptOption.id === option) {
@@ -393,11 +401,9 @@
         } else if (row.type === 70) {
           let data = JSON.parse(row.variableName);
           if (data.direction == 1) {
-            return topLevel2.find((item) => item.value == data.topLevel)
-              ?.label;
+            return topLevel2.find((item) => item.value == data.topLevel)?.label;
           } else {
-            return topLevel1.find((item) => item.value == data.topLevel)
-              ?.label;
+            return topLevel1.find((item) => item.value == data.topLevel)?.label;
           }
         }
         return '未知(' + option + ')';
@@ -461,10 +467,10 @@
         }
         this.loading = true;
         try {
-          console.log(this.form)
-          
+          console.log(this.form);
+
           let params = {
-          ...this.form,
+            ...this.form,
             variables: {
               // businessName: data.supplierName,
               ...this.form.variables
@@ -496,8 +502,8 @@
       },
       cancel1() {
         this.$emit('update:processSubmitDialogFlag', false);
-      },
+      }
     }
   };
 </script>
-<style scoped lang="scss"></style>
+<style scoped lang="scss"></style>

+ 6 - 8
src/BIZComponents/inventoryTable.vue

@@ -296,7 +296,6 @@
             v-model="scope.row.modelKey"
             :isOne="scope.$index === 0"
             :key="scope.$index + '物品机型'"
-            multiple
             filterable
             allow-create
             default-first-option
@@ -311,7 +310,6 @@
             clearable
             v-model="scope.row.colorKey"
             :isOne="scope.$index === 0"
-            multiple
             filterable
             allow-create
             default-first-option
@@ -1261,10 +1259,10 @@
             );
           }
           if (v.modelKey) {
-            v.modelKey = v.modelKey.toString();
+            v.modelKey = v.modelKey;
           }
           if (v.colorKey) {
-            v.colorKey = v.colorKey.toString();
+            v.colorKey = v.colorKey;
           }
           v.technicalDrawings = v.technicalDrawings ? v.technicalDrawings : [];
           v.customerReqFiles = v.customerReqFiles || [];
@@ -1340,10 +1338,10 @@
         if (productList) {
           productList.forEach((item) => {
             if (item.modelKey) {
-              item.modelKey = item.modelKey.split(',');
+              item.modelKey = item.modelKey;
             }
             if (item.colorKey) {
-              item.colorKey = item.colorKey.split(',');
+              item.colorKey = item.colorKey;
             }
             item.guaranteePeriodUnitCode = item.guaranteePeriodUnitCode
               ? item.guaranteePeriodUnitCode + ''
@@ -1442,10 +1440,10 @@
           this.$set(parasm, 'singleWeight', item.netWeight);
           this.$set(parasm, 'pricingWay', item.pricingWay || 1);
           if (item.modelKey) {
-            this.$set(parasm, 'modelKey', item.modelKey.split(','));
+            this.$set(parasm, 'modelKey', item.modelKey);
           }
           if (item.colorKey) {
-            this.$set(parasm, 'colorKey', item.colorKey.split(','));
+            this.$set(parasm, 'colorKey', item.colorKey);
           }
           this.$set(parasm, 'imgCode', item.imgCode);
           this.$set(parasm, 'produceType', item.produceType);

+ 168 - 36
src/BIZComponents/paymentCollectionPlan/Index.vue

@@ -11,20 +11,22 @@
       <!-- 表头工具栏 -->
       <template v-slot:toolbar>
         <div class="headbox">
-            <el-button
-            size="small"
-            type="primary"
-            icon="el-icon-plus"
-            class="ele-btn-icon"
-            @click="handlAdd"
-            v-if="type!='view'"
-            >
-            新增
-            </el-button>
+            <div>
+              <el-button
+                size="small"
+                type="primary"
+                icon="el-icon-plus"
+                class="ele-btn-icon"
+                @click="handlAdd"
+                v-if="showAddBtn"
+              >
+                新增
+              </el-button>
+            </div>
 
             <div class="pricebox">
                 <span class="amount">比例合计:{{ allRatio }}%</span>
-                <span class="amount">计划{{ menu === 'purchase' ? '收款' : '付款' }}金额合计:{{ allPrice }}元</span>
+                <span class="amount">计划{{ menu === 'purchase' ? '付款' : '收款' }}金额合计:{{ allPrice }}元</span>
 
                 <!-- <el-form-item
                     style="width: 300px"
@@ -122,7 +124,7 @@
             placeholder="请选择"
             style="width: 100%"
             :disabled="type=='view'"
-
+            @change="(val) => typeChange(val, scope.$index)"
           >
             <el-option
               v-for="item in paymentTypeOp"
@@ -155,7 +157,7 @@
             <el-input
                 type="number"
                 :min="0"
-                :disabled="type=='view'"
+                disabled
                 v-model="scope.row.price"
                 style="width: 100%"
                 placeholder="请输入"
@@ -177,7 +179,7 @@
           <el-date-picker
             style="width: 140px"
             v-model="scope.row.deadLine"
-            :disabled="type=='view'"
+            :disabled="!showAddBtn"
             type="date"
             placeholder="选择日期"
           >
@@ -220,6 +222,7 @@
 <script>
   import { emailReg, phoneReg, numberReg } from 'ele-admin';
   import { paymentTypeOp } from '@/enum/dict';
+  import { formatPrice } from '@/BIZComponents/setProduct.js';
   export default {
     props: {
       delDetailIds: Array,
@@ -231,6 +234,10 @@
       discountTotalPrice: {
         type: [Number, String],
         default: 0
+      },
+      info: {
+        type: Object,
+        default: () => {}
       }
     },
     data() {
@@ -242,6 +249,7 @@
         ratio: null,
         remark: '',
         type: '',
+        typeName: '',
         issueNumber: null
       };
       return {
@@ -254,14 +262,19 @@
           datasource: []
         },
         paymentTypeOp,
-
-        rules: {}
+        rules: {},
+        isLoadingFromApi: false
       };
     },
     computed: {
       canHandl() {
         return this.form.datasource.length;
       },
+      showAddBtn() {
+        // console.log('showAddBtn~~~~', this.type, this.info);
+        // console.log('showAddBtn!!!!',!['1', '2'].includes(this.info.settlementMode) || this.type != 'view');
+        return !(['1', '2'].includes(this.info?.settlementMode)) && this.type != 'view' 
+      },
       columns() {
         return [
           {
@@ -334,42 +347,68 @@
             resizable: false,
             slot: 'action',
             showOverflowTooltip: true,
-            show: this.type != 'view'
+            show: this.showAddBtn
           }
         ];
       },
       allRatio() {
-        return this.form.datasource.reduce((acc, cur) => acc + Number(cur.ratio), 0).toFixed(2);
+        return formatPrice(this.form.datasource.reduce((acc, cur) => acc + Number(cur.ratio), 0));
       },
       allPrice() {
-        return this.form.datasource.reduce((acc, cur) => acc + Number(cur.price), 0).toFixed(2);
+        // 使用分进行计算,避免浮点数精度问题
+        return formatPrice(this.form.datasource.reduce((acc, cur) => acc + Math.round(Number(cur.price) * 100), 0) / 100);
       },
     },
     watch: {
       discountAmount(newval) {
-        if (newval) {
+        if (newval && !this.isLoadingFromApi) {
           this.refreshprice();
         }
+      },
+      info: {
+        handler(newval) {
+          // if (newval && newval.receiptPaymentList) {
+          //   this.isLoadingFromApi = true;
+          //   this.form.datasource = newval.receiptPaymentList;
+          //   if (newval.payAmount) {
+          //     this.discountAmount = newval.payAmount;
+          //   }
+          //   setTimeout(() => {
+          //     this.isLoadingFromApi = false;
+          //   }, 100);
+          // }
+        },
+        deep: true
       }
     },
     methods: {
       setDiscountAmount(val) {
         console.log(val, '000000');
         this.discountAmount = val;
+        // 立即更新价格,无需设置isLoadingFromApi为true
+        this.refreshprice();
+      },
+      typeChange(val, index = null) {
+        // console.log(val, index, '55555');
+        if (val) {
+          this.$set(this.form.datasource[index], 'typeName', this.paymentTypeOp.find(item => item.value === val).label);
+        }
       },
       //输入比例更新金额
       async ratioInput(val, index = null) {
-        console.log(this.discountAmount, '77777');
+        // console.log(this.discountAmount, '77777');
+        // console.log(val, '5555555');
         val = Number(val);
         try {
           if (index != null) {
             await this.checkRatio();
           }
           let newval = (val / 100).toFixed(2);
-          let price = (this.discountAmount * newval).toFixed(2);
-          console.log(newval, price, index, '88888');
+          // console.log('newval~~~', newval)
+          let price = formatPrice(this.discountAmount * newval);
+          // console.log(newval, price, index, '88888');
           if (index != null) {
-            console.log(newval, price, index, '999999');
+            // console.log(newval, price, index, '999999');
             this.$set(this.form.datasource[index], 'price', price);
           } else {
             return price;
@@ -390,7 +429,7 @@
               sum += Number(r.ratio);
             }
           });
-          console.log(sum, '3333333');
+          // console.log(sum, '3333333');
           if (sum > 100) {
             this.$message.error('总共比例不能超过100');
             this.$set(
@@ -403,20 +442,72 @@
               'price',
               0.0
             );
-            reject(false);
+            resolve(true);
           } else {
             resolve(true);
           }
         });
       },
       refreshprice() {
-        let newData = this.form.datasource;
-        newData.forEach(async (r, index) => {
+        // 如果正在从API加载数据,则不执行刷新操作
+        if (this.isLoadingFromApi) {
+          return;
+        }
+        
+        // 创建一个新的数组,避免直接修改原数组
+        let newData = JSON.parse(JSON.stringify(this.form.datasource));
+        console.log('newData after copy:', newData);
+        
+        // 先根据比例计算所有价格
+        for (let i = 0; i < newData.length; i++) {
+          const r = newData[i];
           if (r.ratio) {
-            console.log(this.ratioInput(Number(r.ratio)), '9999888888');
-            r.price = await this.ratioInput(Number(r.ratio));
+            // 直接计算价格,避免使用async/await的forEach
+            let val = Number(r.ratio);
+            let newval = (val / 100).toFixed(2);
+            let price = formatPrice(this.discountAmount * newval);
+            newData[i] = {
+              ...r,
+              price: price
+            };
           }
-        });
+        }
+        
+        // 验证并调整最后一行价格,确保总和等于优惠后的总金额
+        // 使用分进行计算,避免浮点数精度问题
+        const allPriceSum = newData.reduce((acc, cur) => acc + Math.round(Number(cur.price || 0) * 100), 0) / 100;
+        const discountAmount = Number(this.discountAmount);
+        // 直接计算比例总和,避免字符串转换问题
+        const allRatio = newData.reduce((acc, cur) => acc + Number(cur.ratio || 0), 0);
+        
+        console.log('allPriceSum:', allPriceSum, 'discountAmount:', discountAmount, 'allRatio:', allRatio);
+        
+        // 检查是否所有数据都有price且比例合计为100%
+        const allHavePrice = newData.every(item => item.price != null && item.price !== '');
+        
+        console.log('allHavePrice:', allHavePrice);
+        
+        if (allHavePrice && Math.abs(allRatio - 100) < 0.01 && Math.abs(allPriceSum - discountAmount) >= 0.01) {
+          // 调整最后一行的价格
+          if (newData.length > 0) {
+            const lastIndex = newData.length - 1;
+            // 使用分进行计算,避免浮点数精度问题
+            const otherPriceSum = newData.slice(0, lastIndex).reduce((acc, cur) => acc + Math.round(Number(cur.price || 0) * 100), 0) / 100;
+            // 计算最后一行应该有的价格
+            const lastPrice = Math.round((discountAmount - otherPriceSum) * 100) / 100;
+            newData[lastIndex] = {
+              ...newData[lastIndex],
+              price: formatPrice(lastPrice)
+            };
+            console.log('adjusted last item price:', lastPrice);
+          }
+        }
+        
+        console.log('newData before update:', newData);
+        
+        // 确保更新this.form.datasource,触发Vue的响应式更新
+        this.form.datasource = newData;
+        console.log('after update, datasource:', this.form.datasource);
       },
       // 返回列表数据
       getTableValue() {
@@ -424,7 +515,7 @@
       },
       //修改回显
       putTableValue(data) {
-        console.log('data~~~~', data);
+        console.log('data~~~~111', data);
         if (data) {
           this.form.datasource = data.receiptPaymentList;
           this.setDiscountAmount(data.payAmount);
@@ -438,6 +529,7 @@
           if (row.id) {
             this.delDetailIds.push(row.id);
           }
+          this.$emit('getIssueNumber', this.form.datasource.length);
         }
       },
       // 清空表格
@@ -451,7 +543,7 @@
         });
       },
       defaultList(method, issueNumber, dateRange) {
-        console.log('method, issueNumber', method, issueNumber);
+        // console.log('method, issueNumber', method, issueNumber, dateRange);
         const tempList = []
         if(dateRange) {
           this.setDefaultList(dateRange, issueNumber);
@@ -463,6 +555,7 @@
             let item = JSON.parse(JSON.stringify(this.defaultForm));
               item.moneyName = i < params.length ? params[i] : '';
               item.type = i < params.length ? this.paymentTypeOp[i].value : '';
+              item.typeName = i < params.length ? this.paymentTypeOp[i].label : '';
               item.key = i + 1;
               item.issueNumber = i + 1;
               tempList.push(item);
@@ -486,15 +579,34 @@
           // });
           for(let i = 0; i < issueNumber; i++) {
             let item = JSON.parse(JSON.stringify(this.defaultForm));
+            if(issueNumber == 1) {
+              item.moneyName = '';
+              item.type = 2;
+              item.typeName = '交货款';
+              item.ratio = 100;
+              item.key = i + 1;
+              item.issueNumber = i + 1;
+            } else {
               item.moneyName = '';
               item.type = '';
+              item.typeName = '';
+              item.ratio = '';
               item.key = i + 1;
               item.issueNumber = i + 1;
-              tempList.push(item);
+            }
+            tempList.push(item);
           }
         }
         console.log('tempList~~~', tempList);
-        this.form.datasource = tempList;
+        // 清空原数组并逐个添加新元素,确保Vue能够检测到变化
+        this.form.datasource = [];
+        this.$nextTick(() => {
+          this.form.datasource = tempList;
+          console.log('form.datasource after update:', this.form.datasource);
+          // 强制组件重新渲染
+          this.$forceUpdate();
+          console.log('forceUpdate called');
+        });
       },
 
       transformDaysFun(date) {
@@ -559,18 +671,30 @@
         return allMonthDates;
       },
       setDefaultList(dateRange, issueNumber) {
+        // console.log('setDefaultList-dateRange~~~', dateRange);
         const tempPeriod = issueNumber || 0;
 
         // 计算基本比例
         const basicRatio = 100 / tempPeriod;
         let totalRatio = 0;
         
+        // 保存原有数据
+        const existingData = [...this.form.datasource];
+        
         // 生成付款计划列表项
         const tempList = [];
         
         // 根据传入的period参数生成付款计划
         for (let i = 0; i < tempPeriod; i++) {
           let item = JSON.parse(JSON.stringify(this.defaultForm));
+          // let item;
+          // // 如果原有数据中有对应项,则保留原有数据
+          // if (i < existingData.length) {
+          //   item = JSON.parse(JSON.stringify(existingData[i]));
+          // } else {
+          //   item = JSON.parse(JSON.stringify(this.defaultForm));
+          // }
+          
           // 获取日期:如果i小于日期数组长度则使用对应日期,否则设为空
           const deadLine = i < dateRange.length ? dateRange[i] : '';
           const ratio = parseFloat(basicRatio.toFixed(2));
@@ -592,9 +716,16 @@
         // }
         
         console.log('付款计划列表:~~', tempList);
-        this.form.datasource = tempList;
         // this.$set(this.form, 'datasource', tempList);
         console.log('付款计划列表:', this.form.datasource);
+        this.form.datasource = [];
+        this.$nextTick(() => {
+          this.form.datasource = tempList;
+          console.log('form.datasource after update:', this.form.datasource);
+          // 强制组件重新渲染
+          this.$forceUpdate();
+          console.log('forceUpdate called');
+        });
       },
       // 添加
       handlAdd() {
@@ -602,6 +733,7 @@
         item.key = this.form.datasource.length + 1;
         item.issueNumber = this.form.datasource.length + 1;
         this.form.datasource.push(item);
+        this.$emit('getIssueNumber', this.form.datasource.length);
       },
 
       // validateForm(callback) {

+ 30 - 13
src/BIZComponents/processSubmitDialog/processSubmitDialog.vue

@@ -383,7 +383,9 @@
       <!--        @click="() => (active = 0)"-->
       <!--        >上一步-->
       <!--      </el-button>-->
-      <el-button type="primary" size="small" v-click-once @click="submit">提交</el-button>
+      <el-button type="primary" size="small" v-click-once @click="submit"
+        >提交</el-button
+      >
       <el-button size="small" @click="cancel">关闭</el-button>
       <!--      <visibility-range-dialog-->
       <!--        :visibilityRangeDialogFlag.sync="visibilityRangeDialogFlag"-->
@@ -731,7 +733,7 @@ this.postOptions.push(...response.data);
         parameterGetByCode({
           code: 'wt_collaborative_bpm'
         }).then((res) => {
-          if (!res.value||res.value=='1') {
+          if (!res.value || res.value == '1') {
             this.form.FQLC = info?.id;
             this.form.name = this.title;
             this.form.key = info?.key;
@@ -787,6 +789,12 @@ this.postOptions.push(...response.data);
               return roleOption.name;
             }
           }
+        } else if (row.type == 11) {
+          for (const roleOption of this.roleOptions) {
+            if (roleOption.id === option) {
+              return roleOption.name;
+            }
+          }
         } else if (row.type === 20 || row.type === 21) {
           for (const deptOption of this.deptOptions) {
             if (deptOption.id === option) {
@@ -886,13 +894,16 @@ this.postOptions.push(...response.data);
         });
       },
       generateFormValid(validate = true) {
-        return this.$refs.generateForm.getData(validate).then((data) => {
-          return data;
-        }).catch((err) => {
-          this.$message.error(err);
-          console.log(err);
-          throw err;
-        });
+        return this.$refs.generateForm
+          .getData(validate)
+          .then((data) => {
+            return data;
+          })
+          .catch((err) => {
+            this.$message.error(err);
+            console.log(err);
+            throw err;
+          });
       },
       handleTreeChange() {
         this.$nextTick(() => {
@@ -950,7 +961,11 @@ this.postOptions.push(...response.data);
 
           // 如果有未填写的组件,显示提示信息
           if (emptyComponents.length > 0) {
-            this.$message.warning(`请填写完整信息:${emptyComponents.map(comp => this.getComponentName(comp)).join('、')}`);
+            this.$message.warning(
+              `请填写完整信息:${emptyComponents
+                .map((comp) => this.getComponentName(comp))
+                .join('、')}`
+            );
             // this.$message.warning(`请填写完整信息`);
             return false;
           }
@@ -976,11 +991,13 @@ this.postOptions.push(...response.data);
           console.log('this.form.dictList', this.dictList);
           await processInstanceCreateAPI({
             ...this.form,
-            variables: { 
-              ...this.form.valueJson, 
+            variables: {
+              ...this.form.valueJson,
               businessCode: this.form.code,
               businessName: this.form.name,
-              businessType: this.dictList['collaborative_type']?.find(item => item.value == this.form.dictType)?.label
+              businessType: this.dictList['collaborative_type']?.find(
+                (item) => item.value == this.form.dictType
+              )?.label
             }
           });
           this.$message('提交审核成功');

+ 134 - 32
src/BIZComponents/setProduct.js

@@ -6,54 +6,129 @@ export function formatPrice(price, decimals = 4) {
 }
 
 //改变数量
-export function changeCount(row, countObj,noDiscountSingle) {
-  let total = row[countObj.countKey] || 0;
-  let data = row;
-  let endIndex = row.packageDispositionList.findIndex(
-    (ite) => row[countObj.unitIdKey] == ite.id
-  );
-  for (; 0 < endIndex; endIndex--) {
-    total = Vue.prototype.$math.format(
-      row.packageDispositionList[endIndex].packageCell * total,
-      14
+export function changeCount(row, countObj, noDiscountSingle, weightType) {
+  
+  let data = JSON.parse(JSON.stringify(row));
+  // console.log('changeCount~~', data);
+  let total = data[countObj.countKey] || 0;
+
+  let _endIndex = 0; //计算单重需要
+  if (data.packageDispositionList) {
+    let endIndex = data.packageDispositionList.findIndex(
+      (ite) => data[countObj.unitIdKey] == ite.id
+    );
+    _endIndex = endIndex;
+    let packageData = data.packageDispositionList.find(
+      (ite) => data[countObj.unitIdKey] == ite.id
     );
+    data[countObj.unitKey] = packageData.conversionUnit;
+    if (data.weightUnit == data.measuringUnit && data.singleWeight) {
+      data.packageDispositionList[1].packageCell = data.singleWeight;
+    }
+    for (; 0 < endIndex; endIndex--) {
+      total = Vue.prototype.$math.format(
+        data.packageDispositionList[endIndex].packageCell * total,
+        14
+      );
+    }
   }
   data['totalCount'] = total;
-  data['discountSinglePrice'] = !noDiscountSingle
-    ? data.singlePrice
-    : data.discountSinglePrice;
+  // data['discountSinglePrice'] = !noDiscountSingle
+  //   ? data.singlePrice
+  //   : data.discountSinglePrice;
+
+  data['discountSinglePrice'] = data.singlePrice && data.discountRatio ? formatPrice(+data.singlePrice * (+data.discountRatio /100)) : data.singlePrice;
+  // console.log('discountSinglePrice~~~', data.singlePrice, data.discountRatio);
 
-  setWeight(data);
-  if (row.totalCount && row.singlePrice) {
-    data['totalPrice'] = row.totalCount * row.singlePrice;
-    data['discountTotalPrice'] = !noDiscountSingle
-      ? data.totalPrice
-      : data.discountTotalPrice;
+  if (weightType == 'totalWeight') {
+    console.log('weightType~~', 1);
+    setSingleWeight(data, countObj, _endIndex);
+  } else {
+    console.log('weightType~~', 2);
+    setWeight(data, countObj);
   }
-  // getNotaxSinglePrice(data);
+
+  data['totalPrice'] = 0;
+  data['discountTotalPrice'] = 0;
+  if (data.pricingWay == 2 || data.pricingWay == 3) {
+    if (data.totalWeight && data.singlePrice) {
+      data['totalPrice'] = formatPrice(data.totalWeight * data.singlePrice);
+    }
+  } else {
+    if (data[countObj.countKey] && data.singlePrice) {
+      data['totalPrice'] = formatPrice(data[countObj.countKey] * data.singlePrice);
+    }
+  }
+  // data['discountTotalPrice'] = !noDiscountSingle
+  //   ? data.totalPrice
+  //   : data.discountTotalPrice;
+  data['discountTotalPrice'] = data['totalPrice'] && data.discountRatio ? formatPrice(+data['totalPrice'] * (data.discountRatio /100)) : data['totalPrice'];
   return data;
-  // if (row) {
-  //   singleWeightChange(row, index);
-  // }
-  // return getNumTotalPrice(arr, noDiscountSingle);
 }
-function setWeight(row) {
+// 计算总重
+function setWeight(row, countObj) {
+  // return
   if (row.weightUnit == row.measuringUnit) {
     row['totalWeight'] = row.totalCount;
   } else if (row.totalCount && row.singleWeight) {
-    row['totalWeight'] = row.totalCount * row.singleWeight;
+    row['totalWeight'] = Number((row.totalCount * row.singleWeight).toFixed(2));
   } else {
     row['totalWeight'] = 0;
   }
+  // if (row.weightUnit == row[countObj.unitKey]) {
+  //   row['totalWeight'] = row.totalCount;
+  // } else if (row[countObj.countKey] && row.singleWeight) {
+  //   row['totalWeight'] = (row[countObj.countKey] * row.singleWeight).toFixed(2);
+  // } else {
+  //   row['totalWeight'] = 0;
+  // }
+  // if (row.weightUnit == row.measuringUnit) {
+  //   row['totalCount'] = row.totalWeight;
+  // }
+  console.log(row['totalCount'], 'dsds');
 }
-export function getAllPrice(arr){
+// 计算单重
+function setSingleWeight(row, countObj, endIndex) {
+  console.log('setSingleWeight~~', row);
+  //  if (row.totalWeight && row[countObj.countKey]) {
+  //     row['singleWeight'] = (row.totalWeight / row[countObj.countKey]).toFixed(2);
+  //     console.log('singleWeight~~', row['singleWeight']);
+  //   } else {
+  //     row['singleWeight'] = 0;
+  //   }
+  // console.log(endIndex, 'endIndex');
+  if (row.weightUnit == row.measuringUnit) {
+    let totalWeight = row['totalWeight'];
+    for (; 1 < endIndex; endIndex--) {
+      totalWeight = Vue.prototype.$math.format(
+        totalWeight / row.packageDispositionList[endIndex].packageCell,
+        14
+      );
+    }
+    // console.log(totalWeight, 'totalWeight');
+    row['singleWeight'] = Number(totalWeight / row[countObj.countKey]).toFixed(
+      2
+    );
+  } else if (row.totalWeight && row.totalCount) {
+    row['singleWeight'] = Number((row.totalWeight / row.totalCount).toFixed(2));
+  } else {
+    row['singleWeight'] = 0;
+  }
+  if (row.weightUnit == row.measuringUnit) {
+    row['totalCount'] = row.totalWeight;
+  }
+  if (row.weightUnit == row[countObj.unitKey]) {
+    row[countObj.countKey] = row.totalWeight;
+  }
+}
+export function getAllPrice(arr) {
   let sum = 0;
-  arr.forEach(item=>{
-    if(item.totalPrice){
-      sum+=Number(item.totalPrice)
+  arr.forEach((item) => {
+    if (item.totalPrice) {
+      sum += Number(item.totalPrice);
     }
-  })
-  return sum
+  });
+  return isNaN(sum) ? 0 : formatPrice(sum);
 }
 
 export function getAllQuantity(arr, countObj) {
@@ -66,6 +141,33 @@ export function getAllQuantity(arr, countObj) {
   });
   return isNaN(sum) ? 0 : formatPrice(sum);
 }
+
+// 获取优惠后总金额
+export function getAllDiscountPrice(arr) {
+  let sum = 0;
+  arr.forEach((item) => {
+    if (item.discountTotalPrice) {
+      sum += Number(item.discountTotalPrice);
+    }
+  });
+  return isNaN(sum) ? 0 : formatPrice(sum);
+}
+
+//获取折让合计
+export function getDiscountTotalPrice(row) {
+  let num = 0;
+  num =
+    Number(row.discountSinglePrice) * Number(row[countObj.countKey]);
+  return isNaN(num) ? '' : formatPrice(num);
+}
+
+//获取折让单价
+export function getDiscountSinglePrice(row) {
+  let num =
+    Number(row.discountTotalPrice) *
+    Number(row[countObj.countKey]);
+  return isNaN(num) ? '' : formatPrice(num);
+}
 // //计算不含税单价
 // function getNotaxSinglePrice(row) {
 //   if (row.singlePrice && row.taxRate) {

+ 14 - 10
src/api/bpm/components/equipmentDisposal/index.js

@@ -1,7 +1,5 @@
 import request from '@/utils/request';
 
-
-
 // 保存or更新
 export async function save(data) {
   const res = await request.post(`/eam/management_template/update`, data);
@@ -11,30 +9,36 @@ export async function save(data) {
   return Promise.reject(new Error(res.data.message));
 }
 
-
-
 /**
  * 列表
  */
-export async function getDisposalList (data) {
-  const res = await request.post('/eam/disposal_management_template/page', data);
+export async function getDisposalList(data) {
+  const res = await request.post(
+    '/eam/disposal_management_template/page',
+    data
+  );
   if (res.data.code == 0) {
     return res.data.data;
   }
   return Promise.reject(new Error(res.data.message));
 }
 
-
-
 // // 详情
-export async function getById (id) {
+export async function getById(id) {
   const res = await request.get(`/eam/management_template/getById/${id}`);
   if (res.data.code == 0) {
     return res.data.data;
   }
   return Promise.reject(new Error(res.data.message));
 }
-
+// // 详情
+export async function ehsGetById(id) {
+  const res = await request.get(`/ehs/ehsdisposalmanagement/getById/${id}`);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
 
 // 获取实体列表分页
 export async function getAssetList(data) {

+ 13 - 0
src/api/bpm/components/purchasingManage/purchaseOrder.js

@@ -40,3 +40,16 @@ export async function cancel(data) {
   }
   return Promise.reject(new Error(res.data.message));
 }
+
+/**
+ * 更新采购订单
+ */
+export async function updateProductPrice(data) {
+  const res = await request.put(`/eom/purchaseorder/v1/updateProductPrice`, data);
+  if (res.data.code == 0) {
+    return Promise.resolve(res.data);
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+

+ 7 - 0
src/api/pda/index.js

@@ -7,3 +7,10 @@ export async function getPickOrderById(id) {
   }
   return Promise.reject(new Error(res.data.message));
 }
+export async function getEhsPickOrderById(id) {
+  const res = await request.get('/ehs/ehspickorder/getById/' + id);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}

+ 21 - 0
src/api/warehouseManagement/index.js

@@ -302,5 +302,26 @@ export default {
       return res.data.data;
     }
     return Promise.reject(new Error(res.data.message));
+  },
+
+  //释放锁库数量
+  lockOrderRelease: async (orderNo) => {
+    const res = await request.get(
+      `/wms/lockOrder/v1/release/${orderNo}`,
+    );
+    if (res.data.code == 0) {
+      return res.data.data;
+    }
+    return Promise.reject(new Error(res.data.message));
+  },
+  //释放锁库数量
+  isLocked: async (orderNo) => {
+    const res = await request.get(
+      `/wms/lockOrder/v1/isLocked/${orderNo}`,
+    );
+    if (res.data.code == 0) {
+      return res.data.data;
+    }
+    return Promise.reject(new Error(res.data.message));
   }
 };

+ 110 - 0
src/directives/tableScrollSync.js

@@ -0,0 +1,110 @@
+// 工具函数:获取 .el-table__body-wrapper 下的滚动容器
+function getBodyWrapper(el) {
+  return el.querySelector('.el-table__body-wrapper');
+}
+
+// 创建滚动条并绑定事件,返回清理函数
+function setupScrollSync(el) {
+  const table = el; // el 就是容器元素
+  if (!table) return null;
+
+  const outerWidth = table.offsetWidth;
+  // 取第一个内部 table 的宽度作为内容宽度
+  const innerTable = table.querySelector('table');
+  const contentWidth = innerTable ? innerTable.offsetWidth : outerWidth;
+
+  const bodyWrapper = getBodyWrapper(table);
+  if (!bodyWrapper) {
+    console.warn('未找到 .el-table__body-wrapper,无法创建滚动同步');
+    return null;
+  }
+  // 隐藏原生横向滚动条,但保留纵向滚动条
+  bodyWrapper.style.overflowX = 'hidden';
+  bodyWrapper.style.overflowY = 'auto';
+  
+  // 创建自定义样式标签来隐藏横向滚动条
+  const styleId = 'v-scroll-sync-hide-x-scrollbar';
+  let styleEl = document.getElementById(styleId);
+  if (!styleEl) {
+    styleEl = document.createElement('style');
+    styleEl.id = styleId;
+    styleEl.textContent = `
+      .el-table__body-wrapper.v-scroll-sync-hide-x::-webkit-scrollbar {
+        width: 6px;
+        height: 0;
+      }
+      .el-table__body-wrapper.v-scroll-sync-hide-x::-webkit-scrollbar-track {
+        background: transparent;
+      }
+      .el-table__body-wrapper.v-scroll-sync-hide-x::-webkit-scrollbar-thumb {
+        background: #d9d9d9;
+        border-radius: 3px;
+      }
+    `;
+    document.head.appendChild(styleEl);
+  }
+  bodyWrapper.classList.add('v-scroll-sync-hide-x');
+  // 避免重复创建
+  const existingDiv = table.querySelector('.v-scroll-sync-bar');
+  if (existingDiv) existingDiv.remove();
+
+  const div = document.createElement('div');
+  div.className = 'v-scroll-sync-bar';
+  div.style.width = outerWidth + 'px';
+  div.style.height = '12px';
+  div.style.overflowX = 'auto';
+  div.innerHTML = `<div style="width:${contentWidth}px; height:1px;"></div>`;
+
+  const onScroll = () => {
+    bodyWrapper.scrollLeft = div.scrollLeft;
+  };
+  div.addEventListener('scroll', onScroll);
+
+  const tableContainer = table.querySelector('.el-table');
+
+  // 在tableContainer后面插入div(作为兄弟元素)
+  tableContainer.insertAdjacentElement('afterend', div);
+
+  // table.appendChild(div);
+
+  // 返回清理函数和事件引用
+  return {
+    div,
+    bodyWrapper,
+    handler: onScroll,
+    destroy() {
+      div.removeEventListener('scroll', onScroll);
+      if (div.parentNode) div.parentNode.removeChild(div);
+      // 移除添加的class
+      bodyWrapper.classList.remove('v-scroll-sync-hide-x');
+    }
+  };
+}
+
+// Vue 2 自定义指令
+const tableScrollSync = {
+  bind(el) {
+    // bind 时可能未插入文档,先不做操作,统一在 inserted 中处理
+    el._scrollSyncData = null;
+  },
+  inserted(el) {
+    // 元素插入 DOM 后初始化
+    el._scrollSyncData = setupScrollSync(el);
+  },
+  update(el) {
+    // 当表格数据变化导致内容宽度改变时(如切换分页、动态列),重新初始化
+    if (el._scrollSyncData) {
+      el._scrollSyncData.destroy();
+    }
+    el._scrollSyncData = setupScrollSync(el);
+  },
+  unbind(el) {
+    // 指令解绑时销毁
+    if (el._scrollSyncData) {
+      el._scrollSyncData.destroy();
+      el._scrollSyncData = null;
+    }
+  }
+};
+
+export default tableScrollSync;

+ 3 - 0
src/main.js

@@ -42,6 +42,9 @@ Vue.component('seekPage', seekPage);
 import clickOnce from './utils/clickOnce.js';
 Vue.directive('click-once', clickOnce);
 
+import tableScrollSync from '@/directives/tableScrollSync';
+Vue.directive('table-scroll-sync', tableScrollSync);
+
 import Tooltip from './utils/tooltip'; // 引入封装的工具
 Vue.prototype.$tooltip = Tooltip;
 Vue.use(elTableInfiniteScroll);

+ 5 - 0
src/views/bpm/handleTask/components/allocate/detailDialog.vue

@@ -153,6 +153,11 @@
               prop="specification"
               :show-overflow-tooltip="true"
             ></el-table-column>
+            <el-table-column
+              label="颜色"
+              prop="colorKey"
+              :show-overflow-tooltip="true"
+            ></el-table-column>
             <el-table-column
               v-if="infoData.inventoryDimension == 3"
               label="包装编码"

+ 5 - 0
src/views/bpm/handleTask/components/contractBook/detailDialog.vue

@@ -324,6 +324,11 @@
             code: 7,
             name: '销售订单',
             parentId: '1'
+          },
+          {
+            code: 8,
+            name: '危险危物处置单',
+            parentId: '2'
           }
         ],
         receiptPaymentListcolumns: [

+ 209 - 0
src/views/bpm/handleTask/components/ehsEquipmentDisposal/edit.vue

@@ -0,0 +1,209 @@
+<template>
+  <div>
+    <headerTitle title="基本信息" style="margin-top: 15px"></headerTitle>
+
+    <el-form
+      ref="form"
+      :model="form"
+      :rules="rules"
+      label-width="100px"
+      class="create-form"
+    >
+      <el-row :gutter="15">
+        <el-col v-bind="styleResponsive ? { lg: 8, md: 12 } : { span: 8 }">
+          <el-form-item label="处置方式:" prop="disposalType">
+            <DictSelection
+              dictName="设备处置方式"
+              v-model="form.disposalType"
+              disabled
+              @change="disposalTypeChange"
+            ></DictSelection>
+          </el-form-item>
+        </el-col>
+        <el-col v-bind="styleResponsive ? { lg: 8, md: 12 } : { span: 8 }">
+          <el-form-item label="编码:" prop="code">
+            <el-input v-model="form.code" disabled />
+          </el-form-item>
+        </el-col>
+        <el-col v-bind="styleResponsive ? { lg: 8, md: 12 } : { span: 8 }">
+          <el-form-item label="名称:" prop="name">
+            <el-input v-model="form.name" disabled />
+          </el-form-item>
+        </el-col>
+
+       </el-row
+    ></el-form>
+    <headerTitle title="处置对象" style="margin-top: 15px"></headerTitle>
+    <ele-pro-table
+      ref="table"
+      :columns="columns"
+      :datasource="form.detailList"
+      row-key="id"
+      height="30vh"
+      :needPage="false"
+    >
+    </ele-pro-table>
+    <headerTitle title="处置业务" style="margin-top: 15px"> </headerTitle>
+    <el-form label-width="150px" class="create-form">
+      <el-row :gutter="15">
+        <el-col
+          v-bind="styleResponsive ? { lg: 24, md: 24 } : { span: 24 }"
+          v-for="item in form.disposalTypeList"
+          :key="item.id"
+        >
+          <el-form-item :label="item.name + ':'">
+            <div style="width: 95%; display: inline-block">
+              <formContent :type="item.type" v-model="item.value" disabled />
+            </div>
+          </el-form-item>
+        </el-col> </el-row
+    ></el-form>
+
+    <!-- 选择产品 -->
+  </div>
+</template>
+
+<script>
+  import formContent from '@/views/bpm/handleTask/components/equipmentDisposal/formContent.vue';
+  import { ehsGetById } from '@/api/bpm/components/equipmentDisposal';
+
+  const defForm = {
+    name: '',
+    id: '', //
+    disposalType: '',
+    managementCategory: '',
+    processId: '',
+    code: '',
+    disposalTypeList: [],
+    deviceList: []
+  };
+  export default {
+    components: {
+      formContent
+    },
+    props: {
+      businessId: {
+        default: ''
+      },
+
+      taskDefinitionKey: {
+        default: ''
+      }
+    },
+    data() {
+      return {
+        visible: false,
+        loading: false,
+        infoDisposalVisible: false,
+        title: '物品处置',
+        type: 'detail',
+        form: { ...defForm },
+        rules: {
+          name: [{ required: true, message: '请选择', trigger: 'change' }],
+          type: [{ required: true, message: '请选择', trigger: 'change' }],
+          disposalType: [
+            { required: true, message: '请选择', trigger: 'change' }
+          ]
+        },
+
+        columns: [
+          {
+            columnKey: 'index',
+            label: '序号',
+            type: 'index',
+            width: 55,
+            align: 'center',
+            showOverflowTooltip: true,
+            fixed: 'left'
+          },
+
+          {
+            prop: 'categoryCode',
+            label: '编码',
+            width: 100,
+            fixed: 'left',
+            showOverflowTooltip: true,
+            align: 'center'
+          },
+          {
+            prop: 'categoryName',
+            width: 120,
+            fixed: 'left',
+            showOverflowTooltip: true,
+            label: '名称',
+            align: 'center'
+          },
+          {
+            prop: 'measureQuantity',
+            width: 120,
+            fixed: 'left',
+            showOverflowTooltip: true,
+            label: '计量数量',
+            align: 'center'
+          },
+          {
+            prop: 'measureUnit',
+            width: 120,
+            fixed: 'left',
+            showOverflowTooltip: true,
+            label: '计量单位',
+            align: 'center'
+          },
+          {
+            prop: 'categoryModel',
+            showOverflowTooltip: true,
+            label: '型号',
+            align: 'center'
+          },
+          {
+            prop: 'specification',
+            showOverflowTooltip: true,
+            slot: 'specification',
+            label: '规格',
+            align: 'center'
+          },
+          {
+            prop: 'warehouseName',
+            label: '出库仓库',
+            showOverflowTooltip: true,
+            minWidth: 110,
+            align: 'center'
+          }
+        ]
+      };
+    },
+
+    computed: {},
+    created() {
+      this.open();
+    },
+    methods: {
+      async open() {
+        const data = await ehsGetById(this.businessId);
+        this.form = data;
+
+        this.form.disposalType = this.form.disposalType + '';
+        this.form.managementCategory = this.form.managementCategory + '';
+      }
+    }
+  };
+</script>
+<style lang="scss" scoped>
+  .basic-details-title {
+    margin: 10px 0;
+  }
+  .title {
+    font-size: 16px;
+    line-height: 45px;
+  }
+  .add-product {
+    width: 100%;
+    display: flex;
+    align-items: center;
+    // justify-content: flex-end;
+    font-size: 30px;
+    color: #1890ff;
+    margin: 10px 0;
+    cursor: pointer;
+  }
+</style>

+ 102 - 0
src/views/bpm/handleTask/components/ehsEquipmentDisposal/submit.vue

@@ -0,0 +1,102 @@
+<template>
+  <el-col :span="16" :offset="6">
+    <el-form label-width="100px" ref="formRef" :model="form">
+      <el-form-item
+        label="审批建议"
+        style="margin-bottom: 20px"
+        :rules="{
+          required: true,
+          message: '请选择',
+          trigger: 'change'
+        }"
+      >
+        <el-input
+          type="textarea"
+          v-model="form.reason"
+          placeholder="请输入审批建议"
+        />
+      </el-form-item>
+    </el-form>
+    <div style="margin-left: 10%; margin-bottom: 20px; font-size: 14px">
+      <el-button
+        icon="el-icon-edit-outline"
+        type="success"
+        size="mini"
+        v-click-once
+        @click="handleAudit(1)"
+        >通过
+      </el-button>
+
+      <el-button
+        icon="el-icon-circle-close"
+        type="danger"
+        size="mini"
+        v-click-once
+        @click="handleAudit(0)"
+        v-if="taskDefinitionKey != 'starter'"
+        >驳回
+      </el-button>
+    </div>
+  </el-col>
+</template>
+
+<script>
+  import { approveTaskWithVariables, rejectTask } from '@/api/bpm/task';
+  import dictMixins from '@/mixins/dictMixins';
+  // 流程实例的详情页,可用于审批
+  export default {
+    mixins: [dictMixins],
+
+    name: '',
+    components: {
+      //   Parser
+    },
+    props: {
+      businessId: {
+        default: ''
+      },
+      taskId: {
+        default: ''
+      },
+      id: {
+        default: ''
+      },
+      taskDefinitionKey: {
+        default: ''
+      }
+    },
+    data() {
+      return {
+        form: {
+          reason: '同意'
+        }
+      };
+    },
+    created() {},
+    methods: {
+      async handleAudit(status) {
+        await this._approveTaskWithVariables(status);
+      },
+      async _approveTaskWithVariables(status) {
+        let variables = {
+          pass: !!status
+        };
+        let API = !!status ? approveTaskWithVariables : rejectTask;
+        API({
+          id: this.taskId,
+          reason: this.form.reason,
+          variables
+        }).then((res) => {
+          if (res.data.code != '-1') {
+            this.$emit('handleAudit', {
+              status,
+              title: status === 0 ? '驳回' : ''
+            });
+          }
+        });
+      }
+    }
+  };
+</script>
+
+<style lang="scss"></style>

+ 30 - 6
src/views/bpm/handleTask/components/productionWarehousing/detailDialog.vue

@@ -65,11 +65,29 @@
       </el-form>
     </div>
     <keep-alive>
+      <newAdd
+        ref="add"
+        :form="form"
+        :bizType="form.type || 1"
+        v-if="form.code && !isDetail && clientEnvironmentId != 9"
+        :sourceBizNo="form.code"
+        :detailList="form.detailList"
+        :isMoreProduct="form.type == 3 ? true : false"
+      ></newAdd>
+      <newAdd
+        ref="add"
+        :form="form"
+        :bizType="form.type || 1"
+        v-if="form.code && isDetail && clientEnvironmentId != 9"
+        :sourceBizNo="form.code"
+        :saleProductList="form.detailList"
+      ></newAdd>
+
       <add
         ref="add"
         :form="form"
         :bizType="form.type || 1"
-        v-if="form.code && !isDetail"
+        v-if="form.code && !isDetail && clientEnvironmentId == 9"
         :sourceBizNo="form.code"
         :detailList="form.detailList"
         :isMoreProduct="form.type == 3 ? true : false"
@@ -78,7 +96,7 @@
         ref="add"
         :form="form"
         :bizType="form.type || 1"
-        v-if="form.code && isDetail"
+        v-if="form.code && isDetail && clientEnvironmentId == 9"
         :sourceBizNo="form.code"
         :saleProductList="form.detailList"
       ></add>
@@ -92,7 +110,7 @@
   import { reviewStatusEnum } from '@/enum/dict';
   import add from './storage.vue';
 
-  // import add from '@/views/bpm/stockManagement/storage.vue';
+  import newAdd from '@/views/bpm/stockManagement/storage.vue';
 
   export default {
     props: {
@@ -107,7 +125,8 @@
       }
     },
     components: {
-      add
+      add,
+      newAdd
     },
     mixins: [dictMixins],
     data() {
@@ -124,10 +143,14 @@
         totalPackage: '',
         totalCount: '',
         isDetail: false,
-        dataSource: []
+        dataSource: [],
+        clientEnvironmentId: ''
       };
     },
     async created() {
+      this.clientEnvironmentId =
+        this.$store.state.user.info.clientEnvironmentId;
+      // this.clientEnvironmentId = 9;
       await this.getDetailData(this.businessId);
     },
 
@@ -199,7 +222,8 @@
             return {
               ...item,
               productName: item.categoryName,
-              productCode: item.categoryCode
+              productCode: item.categoryCode,
+              productId: item.categoryId
             };
           });
         }

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 416 - 589
src/views/bpm/handleTask/components/productionWarehousing/storage.vue


+ 100 - 2
src/views/bpm/handleTask/components/purchaseOrder/detailDialog.vue

@@ -196,7 +196,7 @@
         <ele-pro-table
           ref="table"
           :needPage="false"
-          :columns="competAnalysisListcolumns"
+          :columns="columns"
           :datasource="detailData.productList"
           row-key="id"
           tool-class="ele-toolbar-form"
@@ -209,6 +209,19 @@
               <span class="amount">应付金额:{{ detailData.payAmount }}元</span>
             </div>
           </template>
+          <template v-slot:singlePrice="scope">
+            <el-input
+              v-if="$hasPermission('wt:todo:purchaseSingePrice')"
+              slot="reference"
+              v-model="scope.row.singlePrice"
+              type="number"
+              placeholder="请输入"
+              @input="changeCount(scope.row, scope.$index)"
+            >
+              <!-- <template slot="append">元</template> -->
+            </el-input>
+            <span v-else>{{ scope.row.singlePrice }}</span>
+      </template>
           <template v-slot:technicalDrawings="{ row }">
             <fileMain v-model="row.technicalDrawings" type="view"></fileMain>
           </template>
@@ -276,6 +289,7 @@
   import tableColumnsMixin from '@/mixins/tableColumnsMixin.js';
   import { shippingModePurchaseOp, transactionMethodsOp } from '@/enum/dict.js';
   import PaymentCollectionPlan from '@/BIZComponents/paymentCollectionPlan/Index.vue'
+  import { changeCount, getAllPrice, getAllDiscountPrice, formatPrice } from '@/BIZComponents/setProduct.js';
   export default {
     mixins: [dictMixins, tableColumnsMixin],
     components: { PaymentCollectionPlan },
@@ -346,7 +360,7 @@
             slot: 'remark'
           }
         ],
-        competAnalysisListcolumns: [
+        columns: [
           {
             width: 45,
             type: 'index',
@@ -909,6 +923,76 @@
       this.getDetailData(this.businessId);
     },
     methods: {
+      //改变数量
+      changeCount(row, index, weightType) {
+        // if (this.detailType) {
+        //   return;
+        // }
+
+        let countObj = {
+          countKey: 'purchaseCount',
+          unitKey: 'purchaseUnit',
+          unitIdKey: 'purchaseUnitId',
+          type: 'purchase'
+        };
+        if (!row) {
+          this.detailData.productList.forEach((item, index) => {
+            this.$set(this.detailData.productList, index, changeCount(item, countObj));
+            this.setIncreaseTotalWeight(item, index);
+          });
+        } else {
+          console.log(changeCount(row, countObj, false, weightType), '556644');
+
+          this.$set(
+            this.detailData.productList,
+            index,
+            changeCount(row, countObj, false, weightType)
+          );
+          this.setIncreaseTotalWeight(row, index);
+        }
+
+        this.$nextTick(() => {
+          this.getNotaxSinglePrice();
+          this.changeAll();
+          this.$forceUpdate();
+        })
+      },
+      setIncreaseTotalWeight(row, index) {
+        if (row.pricingWay == 3) {
+          this.$set(
+            this.form.datasource[index],
+            'totalPrice',
+            ((row.increaseTotalWeight || 0) * row.singlePrice).toFixed(2)
+          );
+          this.changeAll();
+        }
+      },
+      //计算不含税单价
+      getNotaxSinglePrice() {
+        this.detailData.productList.forEach((item, index) => {
+          if (item.singlePrice && item.taxRate) {
+            this.$set(
+              this.detailData.productList[index],
+              'notaxSinglePrice',
+              formatPrice(
+                item.singlePrice / (1 + item.taxRate / 100)
+              )
+            );
+          } else {
+            this.$set(this.detailData.productList[index], 'notaxSinglePrice', '');
+          }
+        });
+      },
+      changeAll() {
+        this.detailData.totalAmount = getAllPrice(this.detailData.productList) || 0;
+        this.detailData.payAmount = getAllDiscountPrice(this.detailData.productList) || 0;
+        this.form.totalAmount = this.detailData.totalAmount;
+        this.form.payAmount = this.detailData.payAmount;
+        this.$refs.paymentCollectionPlanRef?.setDiscountAmount(this.detailData.payAmount);
+        // this.$store.commit('concact/setDiscountAmount', this.form.discountTotalPrice);
+        // this.$store.commit('order/setAllcountAmount', this.allPrice);
+        // this.$emit('orderDiscountAmount', this.detailData.discountTotalPrice);
+      },
       downloadFile(file) {
         getFile({ objectName: file.storePath }, file.name);
       },
@@ -922,6 +1006,20 @@
           this.detailData = data;
           this.$refs.paymentCollectionPlanRef && this.$refs.paymentCollectionPlanRef.putTableValue(data);
         }
+      },
+      getTableValue() {
+        return new Promise(async (resolve, reject) => {
+          // 判断 productList 中的单价是否填写
+          const emptyPriceList = this.detailData.productList.filter(item => !item.singlePrice);
+          console.log(this.$hasPermission('wt:todo:purchaseSingePrice'));
+          if (emptyPriceList.length > 0) {
+            this.$message.warning('请填写产品单价');
+            reject(new Error('产品单价未填写'));
+          } else {
+            // let data = await UpdateInformation(this.detailData);
+            resolve(this.detailData);
+          }
+        })
       }
     }
   };

+ 32 - 16
src/views/bpm/handleTask/components/purchaseOrder/invoice/receiptInfo.vue

@@ -78,19 +78,24 @@
       </el-row>
     </el-form>
     <div class="fontSize" style="margin-bottom: 12px">物品清单</div>
-    <ele-pro-table
-      ref="table"
-      :needPage="false"
-      :columns="columns"
-      :toolkit="[]"
-      :datasource="detailData.productList"
-      row-key="id"
-      max-height="500px"
-    >
-      <template v-slot:technicalDrawings="{ row }">
-        <fileMain v-model="row.receiveFiles" type="view"></fileMain>
-      </template>
-    </ele-pro-table>
+    <div v-table-scroll-sync>
+      <ele-pro-table
+        ref="table"
+        :needPage="false"
+        :columns="columns"
+        :datasource="detailData.productList"
+        :cache-key="cacheKeyUrl"
+        @columns-change="handleColumnChange"
+        row-key="id"
+        max-height="500px"
+        show-summary
+        :summary-method="getSummaries"
+      >
+        <template v-slot:technicalDrawings="{ row }">
+          <fileMain v-model="row.receiveFiles" type="view"></fileMain>
+        </template>
+      </ele-pro-table>
+    </div>
     <!-- </el-card> -->
   </div>
 </template>
@@ -101,10 +106,12 @@
   import { lbjtList } from '@/enum/dict.js';
   import { levelList,pricingWayList } from '@/enum/dict.js';
   import { parameterGetByCode } from '@/api/main/index.js';
+  import tabMixins from '@/mixins/tableColumnsMixin';
+  import { getSummaries } from '@/utils/util.js';
   // import fileMain from '@/components/addDoc/index.vue';
   export default {
     // components: { fileMain },
-    mixins: [dictMixins],
+    mixins: [dictMixins, tabMixins],
 
     props: {
       form: { type: Object, default: () => {} },
@@ -114,6 +121,7 @@
 
     data() {
       return {
+        cacheKeyUrl: '202605141437-receiptInfoTableColumns',
         reviewStatusEnum,
         isHidePrice: 0
       };
@@ -159,7 +167,7 @@
 
         const list = [
           {
-            width: 45,
+            width: 50,
             type: 'index',
             columnKey: 'index',
             align: 'center',
@@ -511,7 +519,15 @@
         this.isHidePrice = res.value;
       });
     },
-    methods: {}
+    methods: {
+      getSummaries(param) {
+        return getSummaries(
+          param,
+          ['purchaseCount'],
+          ' '
+        );
+      },
+    }
   };
 </script>
 

+ 12 - 0
src/views/bpm/handleTask/components/purchaseOrder/submit.vue

@@ -130,6 +130,8 @@
       },
 
       async handleAudit(status) {
+
+        // return;
         //发起人补充
         if (this.taskDefinitionKey === 'starter') {
           let arr = await this.getTableValue();
@@ -145,6 +147,16 @@
             return;
           }
         }
+        if(this.$hasPermission('wt:todo:purchaseSingePrice')) {
+          let arr = await this.getTableValue();
+          console.log('status~~~', status, arr);
+          let data = await UpdateInformation(arr);
+          if (data.code != '0') {
+            this.$message.warning(data.message);
+            return;
+          }
+        }
+        
         this._approveTaskWithVariables(status);
       },
       async _approveTaskWithVariables(status) {

+ 19 - 1
src/views/bpm/handleTask/components/saleOrder/saleReturnGoods/detailDialog.vue

@@ -437,7 +437,8 @@
             slot: 'remark',
             align: 'center'
           }
-        ]
+        ],
+        tempData: []
       };
     },
     props: {
@@ -517,6 +518,23 @@
             item['packingWeight'] = item.receiveTotalWeight;
             item['quantity'] = item.totalCount;
           });
+          const tempData = this.form.productList.filter((item) => item.packageId);
+          // 合并 productCode + orderNo + colorKey 相同的项
+          const mergedList = [];
+          tempData.forEach((item) => {
+            const key = `${item.productCode}_${item.orderNo}_${item.colorKey}`;
+            const existIndex = mergedList.findIndex(
+              (m) => `${m.productCode}_${m.orderNo}_${m.colorKey}` === key
+            );
+            if (existIndex > -1) {
+              mergedList[existIndex].quantity += item.quantity;
+              mergedList[existIndex].packingWeight += item.packingWeight;
+            } else {
+              mergedList.push({ ...item });
+            }
+          });
+          this.tempData = mergedList;
+
           this.$nextTick(() => {
             if (this.taskDefinitionKey == 'storemanApprove') {
               this.activeComp = 'inoutBound';

+ 33 - 6
src/views/bpm/handleTask/components/selectedCollectionOutbound/boxTabPage.vue

@@ -14,13 +14,16 @@
 
 <script>
   import { deepClone } from '@/components/FormGenerator/utils/index';
-  import { getPickOrderById } from '@/api/pda';
+
+  import { getPickOrderById, getEhsPickOrderById } from '@/api/pda';
+
   export default {
     name: 'boxTabPage',
     components: {
       tab1: () => import('./detailDialog.vue'),
       tab2: () => import('@/views/bpm/outgoingManagement/outbound.vue'),
-      tab3: () => import('@/views/bpm/outgoingManagement/details.vue')
+      tab3: () => import('@/views/bpm/outgoingManagement/details.vue'),
+      tab4: () => import('./ehsDetailDialog.vue')
     },
     props: {
       taskDefinitionKey: {
@@ -39,6 +42,10 @@
         type: String,
         default: ''
       },
+      processDefinitionId: {
+        type: String,
+        default: ''
+      },
       isView: ''
     },
     data() {
@@ -52,16 +59,23 @@
     },
     computed: {
       tabOption() {
+        //processDefinitionId==ehs_pick_out_approve 安全管理 危险危物特殊处理
+
         let list = [
           {
             label: '领料单详情',
-            name: 'tab1',
+            name: this.processDefinitionId.includes('ehs_pick_out_approve')
+              ? 'tab4'
+              : 'tab1',
             isShow: true
           },
           {
             label: '出库',
             name: this.isView ? 'tab3' : 'tab2',
-            isShow: this.isView || this.taskDefinitionKey == 'storeman' ||  this.taskDefinitionKey == 'storemanAudit'
+            isShow:
+              this.isView ||
+              this.taskDefinitionKey == 'storeman' ||
+              this.taskDefinitionKey == 'storemanAudit'
           }
         ];
         return list.filter((item) => item.isShow);
@@ -69,7 +83,12 @@
     },
     async created() {
       this.getPickOrderDetail();
-      console.log('tabOption~~', this.tabOption, this.taskDefinitionKey, this.isView);
+      console.log(
+        'tabOption~~',
+        this.tabOption,
+        this.taskDefinitionKey,
+        this.isView
+      );
     },
     methods: {
       activeNameProps(activeName) {
@@ -93,6 +112,11 @@
             return {
               businessId: this.form.code
             };
+          case 'tab4':
+            return {
+              businessId: this.businessId,
+              form: this.form
+            };
         }
       },
       isValidComponent(componentName) {
@@ -118,7 +142,10 @@
         };
       },
       getPickOrderDetail() {
-        getPickOrderById(this.businessId).then((data) => {
+        let api = this.processDefinitionId.includes('ehs_pick_out_approve')
+          ? getEhsPickOrderById
+          : getPickOrderById;
+        api(this.businessId).then((data) => {
           data.detailList = data.detailList.map((item) => {
             item.code = data.code;
             return item;

+ 96 - 0
src/views/bpm/handleTask/components/selectedCollectionOutbound/ehsDetailDialog.vue

@@ -0,0 +1,96 @@
+<template>
+  <div class="ele-body">
+    <headerTitle title="领料单信息"></headerTitle>
+    <el-form :model="form" ref="formRef" label-width="120px">
+      <el-row :gutter="20">
+        <el-col :span="8">
+          <el-form-item label="领料单名称" prop="name">
+            <el-input v-model="form.name" disabled></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="领料单号" prop="code">
+            <el-input v-model="form.code" disabled></el-input>
+          </el-form-item>
+        </el-col>
+
+        <el-col :span="8">
+          <el-form-item label="类型" prop="type">
+            <el-input :value="'自建领料'" disabled></el-input>
+ 
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+    <headerTitle title="领料清单"></headerTitle>
+    <el-table :data="form.detailList" style="width: 100%">
+      <el-table-column
+        prop="workOrderCode"
+        width="50"
+        align="center"
+        label="序号"
+      >
+        <template slot-scope="{ row, $index }">
+          {{ $index + 1 }}
+        </template>
+      </el-table-column>
+
+      <el-table-column prop="categoryCode" label="物品编码" align="center">
+      </el-table-column>
+      <el-table-column prop="categoryName" label="物品名称" align="center">
+      </el-table-column>
+      <el-table-column prop="batchNo" label="批次号" align="center">
+      </el-table-column>
+      <el-table-column label="数量" align="center">
+        <template slot-scope="{ row }">
+          {{ row.demandQuantity }}/{{ row.unit }}
+        </template>
+      </el-table-column>
+      <el-table-column label="领料仓库" align="center">
+        <template slot-scope="{ row }">
+          {{ row.warehouseName }}
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<script>
+  export default {
+    components: {},
+    props: {
+      businessId: {
+        default: ''
+      },
+      form: {
+        default: {}
+      }
+    },
+    data() {
+      return {
+        detailId: '',
+        list: []
+      };
+    }
+  };
+</script>
+
+<style scoped lang="scss">
+  .ele-dialog-form {
+    .el-form-item {
+      margin-bottom: 10px;
+    }
+  }
+
+  .headbox {
+    display: flex;
+    justify-content: flex-start;
+    align-items: center;
+
+    .amount {
+      font-size: 14px;
+      font-weight: bold;
+      margin-right: 20px;
+    }
+  }
+</style>

+ 14 - 0
src/views/bpm/outgoingManagement/components/AssetsDialog.vue

@@ -124,6 +124,15 @@
             ></el-input>
           </el-form-item>
         </el-col>
+        <el-col :span="6">
+          <el-form-item label="颜色">
+            <el-input
+              type="text"
+              placeholder="搜索颜色"
+              v-model="searchForm.colorKey"
+            ></el-input>
+          </el-form-item>
+        </el-col>
         <el-col style="text-align: right">
           <el-button type="primary" @click="doSearch">搜索</el-button>
           <el-button icon="el-icon-refresh-left" @click="reset">重置</el-button>
@@ -229,6 +238,11 @@
             label="规格"
             :show-overflow-tooltip="true"
           ></el-table-column>
+          <el-table-column
+            prop="colorKey"
+            label="颜色"
+            :show-overflow-tooltip="true"
+          ></el-table-column>
           <template v-if="dimension == 1">
             <el-table-column
               v-for="(item, index) in newColumns"

+ 60 - 16
src/views/bpm/outgoingManagement/outbound.vue

@@ -167,24 +167,37 @@
           style="margin-bottom: 20px; float: right; margin-right: 20px"
           type="primary"
           @click="addStock"
-          v-if="isEdit"
+          v-if="isEdit && !stockError"
           >添加</el-button
         >
+
+        <el-popconfirm
+          v-if="showLocked"
+          style="margin-bottom: 20px; float: right; margin-right: 20px"
+          class="ele-action"
+          title="该单已锁库存,释放后无法还原?"
+          @confirm="lockRelease"
+        >
+          <template v-slot:reference>
+            <el-button type="primary" plain>释放锁库</el-button>
+          </template>
+        </el-popconfirm>
       </div>
       <div class="material">
         <div>
           <header-title title="出库物品清单"></header-title>
           <div class="mt10 form-table">
             <ele-pro-table
-            ref="table"
-            :columns="columns"
-            :datasource="productList"
-            height="200"
-            full-height="calc(100vh - 116px)"
-            tool-class="ele-toolbar-form"
-            @columns-change="handleColumnChange"
-            :cache-key="cacheKeyUrl"
-          >
+              ref="table"
+              :columns="columns"
+              :datasource="productList"
+              height="300"
+              full-height="calc(100vh - 116px)"
+              tool-class="ele-toolbar-form"
+              @columns-change="handleColumnChange"
+              :cache-key="cacheKeyUrl"
+              :needPage="false"
+            >
               <!-- 单价列 -->
               <template v-if="isPrice == 1" v-slot:price="{ row }">
                 {{ row.price ? row.price : ' ' + '元' }}/{{ row.measureUnit }}
@@ -423,8 +436,10 @@
     },
     data() {
       return {
-        cacheKeyUrl: 'wt-outbound-table',
-        newColumns: [], // 动态表头
+        stockError: false,
+        stockErrorMsg: '',
+        cacheKeyUrl: '202605181721-wt-outbound-table',
+        dColumns: [], // 动态表头
         goodsLists: [], // 商品列表
         productList: [], // 产品列表
         showPackingList: [], // 展示的包装列表
@@ -484,7 +499,9 @@
           }
         },
         llrLsit: [],
-        isPrice: 1
+        isPrice: 1,
+        showLocked: false,
+        tabMixinsInit: false
       };
     },
     computed: {
@@ -552,7 +569,7 @@
         );
         
         // 动态列
-        this.newColumns.forEach(item => {
+        this.dColumns.forEach(item => {
           columns.push({
             label: item.label,
             prop: item.prop,
@@ -719,6 +736,23 @@
       });
     },
     methods: {
+      checkLock() {
+        storageApi.isLocked(this.formData.sourceBizNo).then((res) => {
+          console.log(res, 'isLocked-res');
+          this.showLocked = res;
+        });
+      },  
+      lockRelease() {
+        storageApi.lockOrderRelease(this.formData.sourceBizNo).then((res) => {
+          console.log(res, 'lockOrderRelease-res');
+            this.$message({
+              message: '释放成功',
+              type: 'success'
+            });
+        }).catch(() => {
+
+        });
+      },
       // 获取当前时间函数
       getNowDate() {
         let date = new Date(),
@@ -755,7 +789,8 @@
               showOverflowTooltip: true
             };
           });
-          this.newColumns = [...newRes];
+          this.dColumns = [...newRes];
+          this.getColumns();
         });
       },
       userSlected(data) {
@@ -965,6 +1000,9 @@
       async getReturnStorage() {
         return new Promise((resolve) => {
           console.log(this.formData);
+          if(this.stockError){
+            return this.$message.error(this.stockErrorMsg);
+          }
           this.$refs.formName.validate(async (valid) => {
             if (!this.productList?.length) {
               return this.$message.error('请添加出库明细!');
@@ -1092,6 +1130,7 @@
         this.formData.bizType = this.bizType;
         // 添加单据来源
         this.formData.sourceBizNo = this.sourceBizNo || this.form?.code;
+        this.checkLock();
         // 将出库状态改成出库状态 2出库 1入库
         this.formData.type = 2;
         // 入库登记人
@@ -1132,6 +1171,9 @@
                 console.log(res, 'form没有executorDeptId有createUserId');
                 this.$set(this.formData, 'fromUser', res.name);
                 this.$set(this.formData.extInfo, 'verifyDeptCode', res.groupId);
+                if( res.groupId){
+                  this.getStaffList({id: res.groupId})
+                }
                 this.$set(
                   this.formData.extInfo,
                   'verifyDeptName',
@@ -1233,7 +1275,9 @@
               this.detailData(data, this.dimension);
             })
             .catch((err) => {
-              console.log(err);
+              console.log('err~~~', err);
+              this.stockError = true;
+              this.stockErrorMsg = err;
             });
           return;
         }

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 580 - 583
src/views/bpm/stockManagement/storage.vue


+ 2 - 2
src/views/bpm/tickets/work/index.vue

@@ -148,12 +148,12 @@
         // 加载状态
         loading: false,
         planOrderId: '',
-        userInfo: {}
+        // userInfo: {}
       };
     },
     computed: {
       userInfo() {
-        return this.$store.getters.user.info;
+        return this.$store.state.user.info || {};
       }
     },
     created() {

+ 2 - 2
vue.config.js

@@ -38,11 +38,11 @@ module.exports = {
         // target: 'http://124.71.68.31:50001', // 测试环境
         // target: 'http://124.71.68.31:50001',
         // target: 'http://192.168.1.105:18086',
-        // target: 'http://192.168.1.3:18086',
+        target: 'http://192.168.1.125:18086',
         // target: 'http://192.168.1.116:18086',
         // target: 'http://192.168.1.3:18086',
         // target: 'http://192.168.1.251:18186',
-        target: 'http://192.168.1.251:18086',
+        // target: 'http://192.168.1.251:18086',
         // target: 'http://192.168.1.3:18086',
         // target: 'http://aiot.zoomwin.com.cn:51001/api',
         // target: 'http://192.168.1.3:18086',

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно