Browse Source

在订单明细-生成发货情况,增加打印签收单功能

wenningning 2 months ago
parent
commit
046fe20a91

+ 2 - 0
manager-admin/src/views/dashboard/index.vue

@@ -11,6 +11,8 @@
     <el-divider></el-divider>
     <el-card>
       <div>
+        <b>202500422-wnn</b>
+        <p>- 在订单明细-生成发货情况,增加打印签收单功能</p>
         <b>20250103-wnn</b>
         <p>- 订单里面的服务相关信息重新梳理</p>
         <b>20250102-wnn</b>

+ 292 - 1
manager-admin/src/views/pjOrder/shipped.vue

@@ -7,6 +7,7 @@
       <div slot="toolbar" class="inner-toolbar">
         <div v-if="boolFounder || permissions.filter(p => p === 'pjOrderShip').length > 0" class="toolbar-btns">
           <el-button type="primary" @click="dialogVisible = true">添加</el-button>
+          <el-button type="primary" @click="handlePrint">打印签收单</el-button>
         </div>
       </div>
 
@@ -68,14 +69,165 @@
         <el-button type="primary" @click="handleAdd">确定</el-button>
       </div>
     </el-dialog>
+
+    <!-- 添加打印选择对话框 -->
+    <el-dialog title="选择打印项目" :visible.sync="printDialogVisible" width="80%">
+      <el-table
+        :data="orderItems"
+        @selection-change="handleSelectionChange"
+        border>
+        <el-table-column
+          type="selection"
+          width="55">
+        </el-table-column>
+        <el-table-column
+          prop="name"
+          label="商品名称"
+          min-width="200">
+        </el-table-column>
+        <el-table-column
+          prop="code"
+          label="型号"
+          min-width="150">
+        </el-table-column>
+        <el-table-column
+          prop="qty"
+          label="数量"
+          width="100">
+        </el-table-column>
+        <el-table-column
+          label="本次发货数量"
+          width="150">
+          <template slot-scope="scope">
+            <el-input-number 
+              v-model="scope.row.printQty" 
+              :min="1" 
+              :max="scope.row.qty"
+              size="small"
+              controls-position="right"
+              @change="handleQtyChange(scope.row)">
+            </el-input-number>
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="备注"
+          min-width="250">
+          <template slot-scope="scope">
+            <el-input
+              type="textarea"
+              :rows="2"
+              placeholder="请输入备注"
+              v-model="scope.row.printRemark"
+              resize="none">
+            </el-input>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div style="margin-top: 20px; padding: 0 20px;">
+        <el-form :model="printForm" label-width="100px">
+          <el-form-item label="出库时间">
+            <el-date-picker
+              v-model="printForm.shipped_time"
+              type="date"
+              placeholder="选择日期"
+              value-format="yyyy-MM-dd"
+              style="width: 200px;">
+            </el-date-picker>
+          </el-form-item>
+          <el-form-item label="收货地址">
+            <el-input
+              type="textarea"
+              :rows="2"
+              placeholder="请输入收货地址"
+              v-model="printForm.address"
+              style="width: 100%;">
+            </el-input>
+          </el-form-item>
+        </el-form>
+      </div>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="printDialogVisible = false">取 消</el-button>
+        <el-button type="primary" @click="handlePrintConfirm">确认打印</el-button>
+      </div>
+    </el-dialog>
+
     <el-dialog :visible.sync="dialogImage">
       <img width="100%" :src="dialogImageUrl" alt="">
     </el-dialog>
+    <div id="printContent" style="display: none;">
+      <div style="position: relative; margin-bottom: 10px;">
+        <div style="position: absolute; top: 0; left: 0;">
+          <img src="../../assets/logo_images/logo-javashop-rectangle-light.png" style="width: 150px; height: auto;" />
+        </div>
+        <div style="text-align: center;">
+          <h2 style="margin: 3px 0;">深圳市维鼎康联信息技术有限公司</h2>
+          <h3 style="margin: 3px 0;">签收单</h3>
+        </div>
+      </div>
+      <div style="margin-bottom: 10px;">
+        <div style="display: flex; justify-content: space-between; margin-bottom: 5px;">
+          <div>项目名称:{{ orderInfo.name || '未填写' }}</div>
+          <div>出库时间:{{ printForm.shipped_time || '未填写' }}</div>
+        </div>
+        <div>收货地址:{{ printForm.address || '未填写' }}</div>
+      </div>
+      <table border="1" cellspacing="0" cellpadding="2" style="width: 100%; border-collapse: collapse;">
+        <thead>
+          <tr>
+            <th>序号</th>
+            <th>商品名称</th>
+            <th>型号</th>
+            <th>数量</th>
+            <th>备注</th>
+          </tr>
+        </thead>
+        <tbody>
+          <tr v-for="(item, index) in selectedItems" :key="index">
+            <td>{{ index + 1 }}</td>
+            <td>{{ item.name }}</td>
+            <td>{{ item.code }}</td>
+            <td>{{ item.printQty }}</td>
+            <td style="max-width: 200px; word-break: break-all;">{{ item.printRemark || '无' }}</td>
+          </tr>
+          <tr v-for="index in (7 - selectedItems.length)" :key="'empty-' + index">
+            <td>{{ selectedItems.length + index }}</td>
+            <td></td>
+            <td></td>
+            <td></td>
+            <td></td>
+          </tr>
+        </tbody>
+      </table>
+      <div style="margin-top: 10px; line-height: 1.5;">
+        <p style="margin: 3px 0;">如对以上货品名规格,数量验收无误,请签字或盖章回传给我们。</p>
+        <p style="margin: 3px 0;">如有异议,请立刻联系我司,自货物签收之日起,三日内未收到任何异议,视为品名数量无误。</p>
+        <div style="margin-top: 10px; text-align: right;">
+          <div style="display: flex; justify-content: flex-end; align-items: center;">
+            <span style="margin-right: 20px;">收货单位及经手人(盖章):_________________</span>
+            <span>签收日期:_________________</span>
+          </div>
+        </div>
+      </div>
+      <div style="margin-top: 15px;">
+        <div style="display: flex; justify-content: center; margin-bottom: 5px;">
+          <div style="width: 33.33%; text-align: left;">收货负责:{{ adminUser.realname }}</div>
+          <div style="width: 33.33%; text-align: left;">下单:{{ orderInfo.sales || '未填写' }}</div>
+          <div style="width: 33.33%; text-align: left;">电话:0755-83204332</div>
+        </div>
+        <div style="display: flex; justify-content: center;">
+          <div style="width: 33.33%; text-align: left;">第一联(白):存根</div>
+          <div style="width: 33.33%; text-align: left;">第二联(红):客户签收单</div>
+          <div style="width: 33.33%; text-align: left;">第三联(黄):客户</div>
+        </div>
+      </div>
+    </div>
   </div>
 </template>
 
 <script>
 import * as API_Shipped from '@/api/pjShipped'
+import * as API_OrderItems from '@/api/pjOrderItems'
+import * as API_Order from '@/api/pjOrder'
 import Storage from '../../utils/storage'
 
 export default {
@@ -90,6 +242,7 @@ export default {
     return {
       boolFounder: JSON.parse(Storage.getItem('admin_user')).founder === 1,
       permissions: [],
+      adminUser: JSON.parse(Storage.getItem('admin_user')),
       /** 列表loading状态 */
       loading: false,
       /** 列表参数 */
@@ -102,9 +255,17 @@ export default {
       /** 列表数据 */
       tableData: '',
       dialogVisible: false,
+      printDialogVisible: false,
+      selectedItems: [],
       addModel: {},
       dialogImage: false,
-      dialogImageUrl: ''
+      dialogImageUrl: '',
+      orderItems: [],
+      orderInfo: {},
+      printForm: {
+        shipped_time: '',
+        address: ''
+      }
     }
   },
   mounted() {
@@ -138,8 +299,138 @@ export default {
       API_Shipped.getList(this.params).then(response => {
         this.loading = false
         this.tableData = response
+        this.getOrderItems()
       }).catch(() => (this.loading = false))
     },
+    getOrderItems() {
+      const params = {
+        page_no: 1,
+        page_size: 1000,
+        fixedCondition: "order_no='" + this.orderNo + "'"
+      }
+      API_OrderItems.getList(params).then(response => {
+        this.orderItems = response.data
+        this.getOrderInfo()
+      })
+    },
+    getOrderInfo() {
+      const params = {
+        page_no: 1,
+        page_size: 1,
+        fixedCondition: "order_no='" + this.orderNo + "'"
+      }
+      API_Order.getList(params).then(response => {
+        if (response.data && response.data.length > 0) {
+          this.orderInfo = response.data[0]
+        }
+      })
+    },
+    handlePrint() {
+      // 初始化打印数据
+      const items = this.orderItems.map(item => ({
+        ...item,
+        printQty: Number(item.qty),
+        printRemark: item.remark || ''
+      }))
+      this.orderItems = items
+      
+      // 初始化打印表单数据
+      const today = new Date()
+      const year = today.getFullYear()
+      const month = String(today.getMonth() + 1).padStart(2, '0')
+      const day = String(today.getDate()).padStart(2, '0')
+      this.printForm = {
+        shipped_time: `${year}-${month}-${day}`,
+        address: this.orderInfo.address || ''
+      }
+      
+      this.printDialogVisible = true
+    },
+    handleSelectionChange(val) {
+      this.selectedItems = val
+    },
+    handleQtyChange(row) {
+      // 可以在这里添加数量变化的处理逻辑
+      console.log('数量已修改:', row.printQty)
+    },
+    handlePrintConfirm() {
+      if (this.selectedItems.length === 0) {
+        this.$message.warning('请至少选择一项商品')
+        return
+      }
+      if (this.selectedItems.length > 7) {
+        this.$message.warning('最多只能选择7项商品')
+        return
+      }
+      if (!this.printForm.shipped_time) {
+        this.$message.warning('请选择出库时间')
+        return
+      }
+      if (!this.printForm.address) {
+        this.$message.warning('请填写收货地址')
+        return
+      }
+      this.printDialogVisible = false
+      this.doPrint()
+    },
+    doPrint() {
+      const printContent = document.getElementById('printContent')
+      const printWindow = window.open('', '_blank')
+      printWindow.document.write(`
+        <html>
+          <head>
+            <title>签收单</title>
+            <style>
+              body { 
+                font-family: Arial, sans-serif;
+                font-size: 12px;
+                margin: 0;
+                padding: 5mm;
+              }
+              table { 
+                width: 100%; 
+                border-collapse: collapse;
+                font-size: 11px;
+              }
+              th, td { 
+                border: 1px solid #000; 
+                padding: 2px; 
+                text-align: center; 
+              }
+              h2 { 
+                font-size: 16px;
+                margin: 5px 0;
+              }
+              h3 { 
+                font-size: 14px;
+                margin: 5px 0;
+              }
+              p { 
+                margin: 5px 0;
+                font-size: 11px;
+              }
+              .signature-area { margin-top: 10px; }
+              .logo-container { position: relative; }
+              .logo { position: absolute; top: 0; right: 0; }
+              #printContent {
+                width: 230mm;
+                height: 130mm;
+                margin: 0 auto;
+              }
+            </style>
+          </head>
+          <body>
+            ${printContent.innerHTML}
+          </body>
+        </html>
+      `)
+      printWindow.document.close()
+      printWindow.focus()
+      setTimeout(() => {
+        printWindow.print()
+        printWindow.close()
+      }, 500)
+    },
     handleUploadBefore(file) {
       let _this = this
       return new Promise((resolve, reject) => {