Jelajahi Sumber

feat(库存管理): 新增入库单打印模板及权限控制

liujt 7 bulan lalu
induk
melakukan
7a0f5b0916

+ 11 - 0
src/api/bpm/index.js

@@ -49,3 +49,14 @@ export async function getActivityList(query) {
   }
   return Promise.reject(new Error(res.data.message));
 }
+
+/**
+ * 企业信息
+ */
+export async function enterprisePage(params) {
+  const res = await request.get(`/main/enterprise/page`, { params });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}

+ 1 - 1
src/store/modules/user.js

@@ -68,7 +68,7 @@ export default {
     },
     // 设置登录用户的权限
     setAuthorities(state, authorities) {
-      state.authorities = authorities;
+      state.authorities = authorities.map((item) => item.permissionCode);
     },
     // 设置登录用户的权限路由
     setAuthoritiesRouter(state, authoritiesRouter) {

+ 6 - 0
src/views/warehouseManagement/stockLedger/components/item-list.vue

@@ -394,6 +394,12 @@
             align: 'center',
             showOverflowTooltip: true
           },
+          {
+            prop: 'modelKey',
+            label: '机型',
+            align: 'center',
+            showOverflowTooltip: true
+          },
           {
             prop: 'colorKey',
             label: '颜色',

+ 206 - 0
src/views/warehouseManagement/stockManagement/components/print-template-tr.vue

@@ -0,0 +1,206 @@
+<template>
+  <ele-modal
+    title="入库单"
+    :visible.sync="QRvisible"
+    v-if="QRvisible"
+    width="80%"
+    @close="close"
+  >
+    <div
+      id="printSection"
+      style="
+        font-family: SimSun, serif;
+        padding: 20px;
+      "
+    >
+      <!-- 入库单标题 -->
+      <div style="text-align: center; margin-bottom: 20px;">
+        <h2 style="margin: 0; font-size: 24px; font-weight: bold;">采购入库(退厂)单</h2>
+      </div>
+      
+      <!-- 供应商信息 -->
+      <div style="margin-bottom: 20px; width: 100%;">
+        <div style="width: 100%; display: flex;">
+          <div style="width: 40%;">
+            <strong>供应商:</strong>{{ rowList.extInfo?.supplierName || '' }}
+          </div>
+          <div style="width: 30%;">
+            <strong>单据日期:</strong>{{ rowList.storageTime || '' }}
+          </div>
+          <div style="width: 30%;">
+            <strong>单据编号:</strong>{{ rowList.bizNo || '' }}
+          </div>
+        </div>
+      </div>
+      
+      <!-- 入库物品表格 -->
+      <table
+        border="1"
+        cellspacing="0"
+        style="
+          width: 100%;
+          border-collapse: collapse;
+          font-size: 14px;
+        "
+      >
+        <thead>
+          <tr>
+            <th style="border: 1px solid #000; padding: 8px; text-align: center;">序号</th>
+            <th style="border: 1px solid #000; padding: 8px; text-align: center;">编号</th>
+            <th style="border: 1px solid #000; padding: 8px; text-align: center; width: 180px;">名称</th>
+            <th style="border: 1px solid #000; padding: 8px; text-align: center; width: 140px;">规格型号</th>
+            <th style="border: 1px solid #000; padding: 8px; text-align: center;">批号</th>
+            <th style="border: 1px solid #000; padding: 8px; text-align: center;">单位</th>
+            <th style="border: 1px solid #000; padding: 8px; text-align: center;">数量</th>
+            <th style="border: 1px solid #000; padding: 8px; text-align: center;">备注</th>
+          </tr>
+        </thead>
+        <tbody>
+          <tr v-for="(row, index) in rowList.outInDetailList" :key="index">
+            <td style="border: 1px solid #000; padding: 8px; text-align: center;">{{ index + 1 }}</td>
+            <td style="border: 1px solid #000; padding: 8px; text-align: center;">{{ row?.categoryCode || '' }}</td>
+            <td style="border: 1px solid #000; padding: 8px; text-align: center;">{{ row?.categoryName || '' }}</td>
+            <td style="border: 1px solid #000; padding: 8px; text-align: center;">{{ row?.specification || '' }}/{{ row?.categoryModel || '' }}</td>
+            <td style="border: 1px solid #000; padding: 8px; text-align: center;">{{ row?.batchNo || '' }}</td>
+            <td style="border: 1px solid #000; padding: 8px; text-align: center;">{{ row?.measureUnit || '' }}</td>
+            <td style="border: 1px solid #000; padding: 8px; text-align: center;">{{ row?.measureQuantity || '' }}</td>
+            <td style="border: 1px solid #000; padding: 8px; text-align: center;">{{ row?.remark || '' }}</td>
+            
+          </tr>
+          
+          <!-- 合计金额行 -->
+          <tr>
+            <td style="border: 1px solid #000; padding: 8px; text-align: center;" colspan="2">合计:</td>
+            <td style="border: 1px solid #000; padding: 8px; text-align: center;"></td>
+            <td style="border: 1px solid #000; padding: 8px; text-align: center;"></td>
+            <td style="border: 1px solid #000; padding: 8px; text-align: center;"></td>
+            <td style="border: 1px solid #000; padding: 8px; text-align: center;"></td>
+            <td style="border: 1px solid #000; padding: 8px; text-align: center;">{{ totalAmount || '' }}</td>
+            <td style="border: 1px solid #000; padding: 8px; text-align: center;"></td>
+          </tr>
+        </tbody>
+      </table>
+      
+      <!-- 签字区域 -->
+      <div style="margin-top: 20px; display: flex; width: 100%;">
+        <div style="width: 33%;">
+          <strong>经手人:</strong>{{ rowList?.fromUser || '' }}
+        </div>
+        <div style="width: 33%;">
+          <strong>复核人:</strong>{{ rowList?.extInfo?.verifyName || '' }}
+        </div>
+        <div style="width: 33%;">
+          <strong>仓管:</strong>{{ rowList.verifyName || '' }}
+        </div>
+        <!-- <div style="width: 25%;">
+          <strong>仓库:</strong>{{ row?.warehouseName || '' }}
+        </div> -->
+        
+        
+      </div>
+    </div>
+
+    <div slot="footer">
+      <el-button @click="print">打印预览</el-button>
+      <el-button @click="close">关闭</el-button>
+    </div>
+  </ele-modal>
+</template>
+
+<script>
+  import storageApi from '@/api/warehouseManagement';
+  export default {
+    name: 'print',
+    components: {},
+    computed: {
+      // 计算总数量
+      totalAmount() {
+        if (!this.rowList?.outInDetailList || !Array.isArray(this.rowList.outInDetailList)) {
+          return 0;
+        }
+        
+        return this.rowList.outInDetailList.reduce((sum, row) => {
+          const amount = parseFloat(row.measureQuantity || 0);
+          return sum + (isNaN(amount) ? 0 : amount);
+        }, 0);
+      },
+      
+      // 计算总金额
+      totalAllPrice() {
+        if (!this.rowList?.outInDetailList || !Array.isArray(this.rowList.outInDetailList)) {
+          return 0;
+        }
+        
+        return this.rowList.outInDetailList.reduce((sum, row) => {
+          const amount = parseFloat(row.totalMoney || 0);
+          return sum + (isNaN(amount) ? 0 : amount);
+        }, 0);
+      }
+    },
+    props: {
+      groupName: {
+        type: String,
+        default: ''
+      }
+    },
+    data() {
+      return {
+        QRvisible: false,
+        rowList: {},
+        row: {}
+      };
+    },
+
+    methods: {
+
+      async init(id, row) {
+        this.row = row;
+        const res = await storageApi.getInboundDetailsById(id);
+        console.log('res', res);
+        this.rowList = res;
+        this.QRvisible = true;
+      },
+
+      close() {
+        this.rowList = {};
+        this.QRvisible = false;
+      },
+      
+      print() {
+        const printSection = document.getElementById('printSection');
+        
+        // 创建打印任务
+        const printWindow = window.open('', '_blank');
+        printWindow.document.open();
+        printWindow.document.write('<html><head><title>打印预览</title>');
+        printWindow.document.write(
+          '<link rel="stylesheet" href="your-stylesheet-url.css" type="text/css" />'
+        );
+        printWindow.document.write('</head><body>');
+        printWindow.document.write(printSection.innerHTML);
+        printWindow.document.write('</body></html>');
+        printWindow.document.close();
+        printWindow.onload = function () {
+          printWindow.print();
+        };
+      }
+    }
+  };
+</script>
+
+<style scoped lang="scss">
+
+  table {
+    border-collapse: collapse;
+  }
+  th, td {
+    border: 1px solid #000;
+    text-align: center;
+    padding: 8px;
+  }
+  @media print {
+    .no-print {
+      display: none;
+    }
+  }
+</style>

+ 1 - 1
src/views/warehouseManagement/stockManagement/components/printQRCode.vue

@@ -213,7 +213,7 @@
   };
 </script>
 
-<style lang="scss">
+<style lang="scss" scoped>
   #printSection {
     display: flex;
     align-items: center;

+ 41 - 4
src/views/warehouseManagement/stockManagement/index.vue

@@ -189,7 +189,11 @@
             >打印</el-button
           >
 
-          <el-button icon="el-icon-printer" type="primary" @click="printkEnter"
+          <el-button icon="el-icon-printer" type="primary" @click="printkEnter" v-if="$hasPermission('wms:outin:printIn')"
+            >打印入库单</el-button
+          >
+
+          <el-button icon="el-icon-printer" type="primary" @click="handlePrint('printTemplateTrRef')" v-if="$hasPermission('wms:outin:printIn1')"
             >打印入库单</el-button
           >
 
@@ -277,6 +281,7 @@
 
     <printQRCode ref="printQRCodeRef"></printQRCode>
     <printStockEnter ref="printStockEnterRef"></printStockEnter>
+    <printTemplateTr ref="printTemplateTrRef" :groupName="groupName"></printTemplateTr>
 
     <!--  <priceMaintenanceDialog ref="priceMaintenanceDialogRef" /> -->
   </div>
@@ -293,14 +298,16 @@
 
   import printQRCode from './components/printQRCode.vue';
   import printStockEnter from './components/printStockEnter.vue';
+  import printTemplateTr from './components/print-template-tr.vue';
   import {
     warehousingType,
     sceneState,
     auditStatus,
     useDict
   } from '@/utils/dict/index';
+  import { enterprisePage } from '@/api/bpm/index.js';
   export default {
-    components: { printQRCode, printStockEnter },
+    components: { printQRCode, printStockEnter, printTemplateTr },
     data() {
       return {
         auditStatus,
@@ -458,7 +465,8 @@
             slot: 'action',
             showOverflowTooltip: true
           }
-        ]
+        ],
+        groupName:'',
       };
     },
     computed: {
@@ -472,6 +480,7 @@
     },
     created() {
       //仓库出入库是否显示金额(0:不显示 1:显示)
+      console.log('authorities~~~', this.$store.state.user?.authorities)
       parameterGetByCode({
         code: 'wms_price'
       }).then((res) => {
@@ -479,11 +488,22 @@
       });
     },
     mounted() {
+      this.getCompanyInfo();
       this.getTypeList();
       this.getFactoryList();
       this.getTreeData();
     },
     methods: {
+      getCompanyInfo() {
+        enterprisePage({
+          pageNum: 1,
+          size: 200
+        }).then((res) => {
+          if (res.list?.length > 0) {
+            this.groupName = res.list[0].name;
+          }
+        });
+      },
       async getTreeData() {
         this.formData.warehouseId = '';
         try {
@@ -565,7 +585,7 @@
         }
       },
       handleAssetType(r) {
-        let arr = r.split(',');
+        let arr = r?.split(',') || [];
         const filteredData = this.codeList.filter((item) =>
           arr.includes(item.dictCode)
         );
@@ -727,6 +747,23 @@
         }
 
         this.$refs.printStockEnterRef.init(this.currentRow.id, this.currentRow);
+      },
+      handlePrint(refName) {
+        if (!this.currentRow.id) {
+          return this.$message({
+            message: '请先选择单据',
+            type: 'warning',
+            duration: 2000
+          });
+        }
+        if (this.currentRow.verifyStatus !== 2) {
+          return this.$message({
+            message: '该单据未审核通过',
+            type: 'warning',
+            duration: 2000
+          });
+        }
+        this.$refs[refName].init(this.currentRow.id, this.currentRow);
       }
     }
   };