Преглед изворни кода

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

lucw пре 8 месеци
родитељ
комит
873f336dad

+ 12 - 0
src/api/produce/index.js

@@ -196,3 +196,15 @@ export async function checkRepeatFeed(data) {
   }
   return Promise.reject(new Error(res.data.message));
 }
+
+//查询产品许可证信息
+export async function queryProductLicense(data) {
+  const res = await request.post(
+    `/main/identityphoto/getIdentityPhotoByCategoryId`,
+    data
+  );
+  if (res.data.code == 0) {
+    return res.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}

+ 246 - 0
src/views/materialReturn/components/flow.vue

@@ -0,0 +1,246 @@
+<template>
+  <el-dialog title="流程" :before-close="handleClose" :visible.sync="dialogVisible" :close-on-click-modal="false"
+    :append-to-body="true" width="80%">
+    <div class="app-container" style="padding: 15px">
+      <!-- 审批记录 -->
+      <el-card class="box-card" v-loading="tasksLoad">
+        <div slot="header" class="clearfix">
+          <span class="el-icon-picture-outline">审批记录</span>
+        </div>
+        <el-col :span="16" :offset="4">
+          <div class="block">
+            <el-timeline>
+              <el-timeline-item v-for="(item, index) in tasks" :key="index" :icon="getTimelineItemIcon(item)"
+                :type="getTimelineItemType(item)">
+                <p style="font-weight: 700">任务:{{ item.name }}</p>
+                <el-card :body-style="{ padding: '10px' }">
+                  <label v-if="item.assigneeUser" style="font-weight: normal; margin-right: 30px">
+                    审批人:{{ item.assigneeUser.nickname }}
+                    <el-tag type="info" size="mini">{{
+                      item.assigneeUser.deptName
+                    }}</el-tag>
+                  </label>
+                  <label style="font-weight: normal" v-if="item.createTime">创建时间:</label>
+                  <label style="color: #8a909c; font-weight: normal">{{
+                    item.createTime
+                  }}</label>
+                  <label v-if="item.endTime" style="margin-left: 30px; font-weight: normal">审批时间:</label>
+                  <label v-if="item.endTime" style="color: #8a909c; font-weight: normal">
+                    {{ item.endTime }}</label>
+                  <label v-if="item.durationInMillis" style="margin-left: 30px; font-weight: normal">耗时:</label>
+                  <label v-if="item.durationInMillis" style="color: #8a909c; font-weight: normal">
+                    {{ getDateStar(item.durationInMillis) }}
+                  </label>
+                  <p v-if="item.reason">
+                    <el-tag :type="getTimelineItemType(item)">{{
+                      item.reason
+                    }}</el-tag>
+                  </p>
+                </el-card>
+              </el-timeline-item>
+            </el-timeline>
+          </div>
+        </el-col>
+      </el-card>
+      <!-- 高亮流程图 -->
+      <el-card class="box-card" v-loading="processInstanceLoading">
+        <div slot="header" class="clearfix">
+          <span class="el-icon-picture-outline">流程图1</span>
+        </div>
+
+        <my-process-viewer key="designer" v-model="bpmnXML" v-bind="bpmnControlForm" :activityData="activityList"
+          :processInstanceData="processInstance" :taskData="tasks" />
+      </el-card>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import { getProcessDefinitionBpmnXML } from '@/api/bpm/index';
+import store from '@/store';
+import { getProcessInstance } from '@/api/bpm/index';
+import { getDate } from '@/utils/dateUtils';
+import dictMixins from '@/mixins/dictMixins';
+import { getTaskListByProcessInstanceId } from '@/api/bpm/index';
+import { getActivityList } from '@/api/bpm/index';
+// import Vue from 'vue';
+
+// 流程实例的详情页,可用于审批
+export default {
+  name: 'outsourcing',
+  mixins: [dictMixins],
+
+  components: {},
+  data() {
+    return {
+      // 遮罩层
+      processInstanceLoading: true,
+      dialogVisible: false,
+
+      // 流程实例
+      id: undefined, // 流程实例的编号
+      processInstance: {},
+
+      // BPMN 数据
+      bpmnXML: null,
+      bpmnControlForm: {
+        prefix: 'flowable'
+      },
+      activityList: [],
+
+      // 审批记录
+      tasksLoad: true,
+      tasks: []
+    };
+  },
+  created() {
+    // this.id = this.$route.query.id;
+    // if (!this.id) {
+    //   this.$message.error('未传递 id 参数,无法查看流程信息');
+    //   return;
+    // }
+    // this.getDetail();
+  },
+  methods: {
+    open(id) {
+      this.id = id;
+      this.dialogVisible = true;
+      this.getDetail();
+    },
+    /** 获得流程实例 */
+    getDetail() {
+      // 获得流程实例相关
+      this.processInstanceLoading = true;
+      getProcessInstance(this.id).then((response) => {
+        if (!response) {
+          this.$message.error('查询不到流程信息!');
+          return;
+        }
+        // 设置流程信息
+        this.processInstance = response;
+
+        // //将业务表单,注册为动态组件
+        // const path = this.processInstance.processDefinition.formCustomViewPath;
+        // Vue.component("async-biz-form-component", function (resolve) {
+        //   require([`@/views${path}`], resolve);
+        // });
+        // 加载流程图
+        getProcessDefinitionBpmnXML(
+          this.processInstance.processDefinition.id
+        ).then((response) => {
+          this.bpmnXML = response;
+        });
+        // 加载活动列表
+        getActivityList({
+          processInstanceId: this.processInstance.id
+        }).then((response) => {
+          console.log(response, 'response');
+          this.activityList = response;
+        });
+
+        // 取消加载中
+        this.processInstanceLoading = false;
+      });
+
+      // 获得流程任务列表(审批记录)
+      this.tasksLoad = true;
+      getTaskListByProcessInstanceId(this.id).then((response) => {
+        // 审批记录
+        this.tasks = [];
+        // 移除已取消的审批
+        response.forEach((task) => {
+          if (task.result !== 4) {
+            this.tasks.push(task);
+          }
+        });
+        // 排序,将未完成的排在前面,已完成的排在后面;
+        this.tasks.sort((a, b) => {
+          // 有已完成的情况,按照完成时间倒序
+          if (a.endTime && b.endTime) {
+            return b.endTime - a.endTime;
+          } else if (a.endTime) {
+            return 1;
+          } else if (b.endTime) {
+            return -1;
+            // 都是未完成,按照创建时间倒序
+          } else {
+            return b.createTime - a.createTime;
+          }
+        });
+
+        // 需要审核的记录
+        const userId = store.getters.userId;
+        this.tasks.forEach((task) => {
+          if (task.result !== 1 && task.result !== 6) {
+            // 只有待处理才需要
+            return;
+          }
+          if (!task.assigneeUser || task.assigneeUser.id !== userId) {
+            // 自己不是处理人
+            return;
+          }
+        });
+
+        // 取消加载中
+        this.tasksLoad = false;
+      });
+    },
+    getDateStar(ms) {
+      return getDate(ms);
+    },
+    getTimelineItemIcon(item) {
+      if (item.result === 1) {
+        return 'el-icon-time';
+      }
+      if (item.result === 2) {
+        return 'el-icon-check';
+      }
+      if (item.result === 3) {
+        return 'el-icon-close';
+      }
+      if (item.result === 4) {
+        return 'el-icon-remove-outline';
+      }
+      if (item.result === 5) {
+        return 'el-icon-back';
+      }
+      return '';
+    },
+    getTimelineItemType(item) {
+      if (item.result === 1) {
+        return 'primary';
+      }
+      if (item.result === 2) {
+        return 'success';
+      }
+      if (item.result === 3) {
+        return 'danger';
+      }
+      if (item.result === 4) {
+        return 'info';
+      }
+      if (item.result === 5) {
+        return 'warning';
+      }
+      if (item.result === 6) {
+        return 'default';
+      }
+      return '';
+    },
+    handleClose() {
+      this.dialogVisible = false;
+    }
+  }
+};
+</script>
+
+<style lang="scss">
+.my-process-designer {
+  height: calc(100vh - 200px);
+}
+
+.box-card {
+  width: 100%;
+  margin-bottom: 20px;
+}
+</style>

+ 18 - 4
src/views/materialReturn/index.vue

@@ -14,6 +14,7 @@
         :parse-data="parseData"
         :selection.sync="selection"
         :height="tableHeight"
+        :pageSize="20"
         @fullscreen-change="fullscreenChange"
       >
         <template v-slot:toolbar>
@@ -36,6 +37,9 @@
           <el-button type="text" size="mini" @click="handDetailed(row)"
             >详情</el-button
           >
+          <el-button type="text" size="mini" @click="checkProcess(row)"
+            >流程</el-button
+          >
         </template>
       </ele-pro-table>
     </el-card>
@@ -46,21 +50,23 @@
       @close="close"
       :sceneList="sceneList"
     ></returnPop>
+
+    <flow ref="flowRef"></flow>
   </div>
 </template>
 
 <script>
   import { returnPage } from '@/api/materialReturn/index.js';
-
   import returnSearch from './components/return-search.vue';
-
+  import flow from './components/flow.vue';
   import returnPop from './components/returnPop.vue';
   import { getByCode } from '@/api/system/dictionary-data';
 
   export default {
     components: {
       returnSearch,
-      returnPop
+      returnPop,
+      flow
     },
     data() {
       return {
@@ -123,7 +129,7 @@
           {
             prop: '',
             label: '操作',
-            width: 80,
+            width: 160,
             align: 'center',
             resizable: false,
             fixed: 'right',
@@ -168,6 +174,14 @@
         this.returnShow = true;
       },
 
+      //查看流程
+      checkProcess(row) {
+        if (!row.storageInfo || !row.storageInfo.processInstanceId) {
+          return this.$message.warning('暂无流程图');
+        }
+        this.$refs.flowRef.open(row.storageInfo.processInstanceId);
+      },
+
       getByCodeFn() {
         getByCode('returnScenario').then((res) => {
           let _arr = [];

+ 7 - 0
src/views/pick/pickApply/components/selfDetailed.vue

@@ -279,6 +279,13 @@
               align: 'center',
               showOverflowTooltip: true
             },
+            {
+              width: 150,
+              prop: 'supplierName',
+              label: '供应商',
+              align: 'center',
+              showOverflowTooltip: true
+            },
             {
               width: 150,
               prop: 'status',

+ 3 - 3
src/views/produce/components/bom/components/attribute.vue

@@ -124,7 +124,7 @@
         <el-col :span="8" label-width="100px">
           <el-form-item label="生产类型:" prop="produceType">
             <el-select
-              v-model="attributeData?.category.produceType"
+              v-model="attributeData.produceType"
               disabled
               filterable
               multiple
@@ -143,7 +143,7 @@
         <el-col :span="8" label-width="100px">
           <el-form-item label="存货类型:" prop="attributeType">
             <el-select
-              v-model="attributeData.category.attributeType"
+              v-model="attributeData.attributeType"
               disabled
               class="ele-block"
             >
@@ -159,7 +159,7 @@
         <el-col :span="8" label-width="100px">
           <el-form-item label="属性类型:" prop="componentAttribute">
             <el-select
-              v-model="attributeData.category.componentAttribute"
+              v-model="attributeData.componentAttribute"
               disabled
               filterable
               multiple

+ 17 - 1
src/views/produce/components/feeding/index.vue

@@ -12,9 +12,11 @@
           <el-date-picker
             v-model="executorTime"
             type="datetime"
+            format="yyyy-MM-dd HH:mm:ss"
             value-format="yyyy-MM-dd HH:mm:ss"
             placeholder="选择日期"
             @change="handleCreate"
+            :picker-options="pickerOptions"
           >
           </el-date-picker>
         </div>
@@ -78,9 +80,11 @@
             <el-date-picker
               v-model="item.executorTime"
               type="datetime"
+              format="yyyy-MM-dd HH:mm:ss"
               value-format="yyyy-MM-dd HH:mm:ss"
               placeholder="选择日期"
               style="margin-right: 25px; width: 190px"
+              :picker-options="pickerOptions"
             >
             </el-date-picker>
 
@@ -358,7 +362,19 @@
         executorIdList: [],
         teamId: '',
         isDefaultExecutor: false,
-        checked: false
+        checked: false,
+        pickerOptions: {
+          disabledDate(time) {
+            // 禁止选择大于当前时间的日期
+            return time.getTime() > Date.now();
+          }
+          // selectableRange: (() => {
+          //   const now = new Date();
+          //   const start = '00:00:00';
+          //   const end = now.toTimeString().split(' ')[0];
+          //   return `${start} - ${end}`;
+          // })()
+        }
         // feedExistNum: '',
         // feedNeedAridRegion: '',
         // feedNeedAuxiliaryEquipment: '',

+ 99 - 2
src/views/produce/components/jobBooking/components/batchSemiProductJobBom.vue

@@ -17,6 +17,8 @@
             >打印条码</el-button
           >
         </div>
+        <!-- <el-button type="text" size="mini" @click="prit()">打印条码</el-button> -->
+
         <div
           v-if="!isDetails && isEngrave"
           class="rx-bc"
@@ -670,6 +672,44 @@
 
     <juRenPackOne ref="juRenPackOneRef" />
     <juRenPack ref="juRenPackRef" />
+    <!-- <te-rui-print-one ref="teRuiPrintOneRef" />
+    <te-rui-print-two ref="teRuiPrintTwoRef" />
+    <te-rui-print-three ref="teRuiPrintThreeRef" /> -->
+
+    <el-dialog
+      title="条码信息"
+      :visible.sync="barcodeVisible"
+      v-if="barcodeVisible"
+      width="30%"
+      :before-close="handleClose"
+      append-to-body
+    >
+      <el-form
+        ref="form"
+        :model="barcodeForm"
+        label-width="120px"
+        label-position="right"
+      >
+        <el-form-item label="短条码">
+          <el-input
+            v-model="barcodeForm.shortBarcode"
+            placeholder="请输入短条码"
+            style="width: 220px"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="长条码">
+          <el-input
+            v-model="barcodeForm.longBarcode"
+            placeholder="请输入长条码"
+            style="width: 220px"
+          ></el-input>
+        </el-form-item>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="barcodeVisible = false">取 消</el-button>
+        <el-button type="primary" @click="getBarcodeParam">确 定</el-button>
+      </span>
+    </el-dialog>
   </div>
 </template>
 
@@ -679,17 +719,27 @@
     getComputeParam,
     saveParam
   } from '@/api/produce/job';
+  import { queryProductLicense } from '@/api/produce';
   import tabMixins from '@/mixins/tableColumnsMixin';
   import { parameterGetByCode } from '@/api/system/dictionary-data';
   import { splitBatch } from '@/api/produce/feeding';
   import { juRenPrint, isJuRen } from '@/api/produce';
   import juRenPackOne from '../../juRenPackOne.vue';
   import juRenPack from '../../juRenPack.vue';
+  // import teRuiPrintOne from '../../teRuiPrintOne.vue';
+  // import teRuiPrintTwo from '../../teRuiPrintTwo.vue';
+  // import teRuiPrintThree from '../../teRuiPrintThree.vue';
 
   export default {
     name: 'semiProductJobBom',
     mixins: [tabMixins],
-    components: { juRenPackOne, juRenPack },
+    components: {
+      juRenPackOne,
+      juRenPack
+      // teRuiPrintOne,
+      // teRuiPrintTwo,
+      // teRuiPrintThree
+    },
     props: {
       list: {
         type: Array,
@@ -1245,7 +1295,13 @@
         },
         lossVisible: false,
         lossData: {},
-        lossIndex: ''
+        lossIndex: '',
+        teRuiData: {},
+        barcodeVisible: false,
+        barcodeForm: {
+          shortBarcode: '',
+          longBarcode: ''
+        }
       };
     },
 
@@ -1398,6 +1454,7 @@
         this.dialogEngrave = false;
         this.batchVisible = false;
         this.lossVisible = false;
+        this.barcodeVisible = false;
       },
 
       batchEngrave() {
@@ -1970,6 +2027,46 @@
           // this.$refs.juRenPackRef.open(this.printData);
         }
       }
+
+      // prit() {
+      //   this.getTeruiPrintData();
+
+      //   // const totalNum = this.list.reduce((acc, pro) => {
+      //   //   return acc + (Number(pro.feedQuantity) || 0);
+      //   // }, 0);
+
+      //   this.barcodeVisible = true;
+
+      //   // console.log(this.teRuiData, '88888888888');
+
+      //   // this.$refs.teRuiPrintThreeRef.open();
+      // },
+
+      // getBarcodeParam() {
+      //   if (
+      //     !this.barcodeForm.shortBarcode.trim() ||
+      //     !this.barcodeForm.longBarcode.trim()
+      //   ) {
+      //     return this.$message.warning(`短条码或长条码不能为空`);
+      //   }
+
+      //   const totalNum = this.list.reduce((acc, pro) => {
+      //     return acc + (Number(pro.feedQuantity) || 0);
+      //   }, 0);
+
+      //   this.$refs.teRuiPrintThreeRef.open(
+      //     this.teRuiData,
+      //     this.barcodeForm.shortBarcode,
+      //     this.barcodeForm.longBarcode,
+      //     totalNum
+      //   );
+      // },
+
+      // async getTeruiPrintData() {
+      //   await juRenPrint({ workOrderId: this.item.workOrderId }).then((res) => {
+      //     this.teRuiData = res.data;
+      //   });
+      // }
     },
 
     created() {

+ 47 - 1
src/views/produce/components/jobBooking/index.vue

@@ -13,9 +13,12 @@
             range-separator="至"
             start-placeholder="开始时间"
             end-placeholder="结束时间"
+            format="yyyy-MM-dd HH:mm:ss"
             value-format="yyyy-MM-dd HH:mm:ss"
             align="right"
             @change="changeBatchReportTime"
+            :picker-options="pickerOptionsTwo"
+            @calendar-change="handleCalendarChange"
           >
           </el-date-picker>
         </div>
@@ -25,9 +28,11 @@
           <el-date-picker
             v-model="executorTime"
             type="datetime"
+            format="yyyy-MM-dd HH:mm:ss"
             value-format="yyyy-MM-dd HH:mm:ss"
             placeholder="选择日期"
             @change="handleCreate"
+            :picker-options="pickerOptions"
           >
           </el-date-picker>
         </div>
@@ -107,10 +112,13 @@
               range-separator="至"
               start-placeholder="开始时间"
               end-placeholder="结束时间"
+              format="yyyy-MM-dd HH:mm:ss"
               value-format="yyyy-MM-dd HH:mm:ss"
               align="right"
               style="margin-right: 10px"
               @change="changeReportTime(index)"
+              :picker-options="pickerOptionsTwo"
+              @calendar-change="handleCalendarChange"
             >
             </el-date-picker>
 
@@ -169,9 +177,11 @@
             <el-date-picker
               v-model="item.workReportInfo.executorTime"
               type="datetime"
+              format="yyyy-MM-dd HH:mm:ss"
               value-format="yyyy-MM-dd HH:mm:ss"
               placeholder="选择日期"
               style="margin-right: 25px; width: 190px"
+              :picker-options="pickerOptions"
             >
             </el-date-picker>
 
@@ -663,7 +673,26 @@
         checked: false,
         isReportTime: false,
         reportTime: '',
-        workHour: ''
+        workHour: '',
+        pickerOptions: {
+          disabledDate(time) {
+            // 禁止选择大于当前时间的日期
+            return time.getTime() > Date.now();
+          }
+          // selectableRange: (() => {
+          //   const now = new Date();
+          //   const start = '00:00:00';
+          //   const end = now.toTimeString().split(' ')[0];
+          //   return `${start} - ${end}`;
+          // })()
+        },
+        pickerOptionsTwo: {
+          disabledDate: (time) => {
+            // 禁止选择当前时间之后的所有日期时间
+            return time.getTime() > Date.now();
+          },
+          selectableRange: '00:00:00 - 23:59:59' // 默认全天可选,后面会动态修改
+        }
       };
     },
 
@@ -1322,6 +1351,23 @@
         }
       },
 
+      handleCalendarChange(val) {
+        if (!val || val.length === 0) return;
+        const selected = val[val.length - 1]; // 当前选中的日期
+        const now = new Date();
+        const todayStr = now.toDateString();
+        const selectedStr = new Date(selected).toDateString();
+
+        if (todayStr === selectedStr) {
+          // 如果选中的是今天,只能选择到当前时分秒
+          const end = now.toTimeString().split(' ')[0];
+          this.pickerOptions.selectableRange = `00:00:00 - ${end}`;
+        } else {
+          // 其他日期不限
+          this.pickerOptions.selectableRange = '00:00:00 - 23:59:59';
+        }
+      },
+
       async save(type) {
         const required = await parameterGetByCode({
           code: 'mes_report_engrave_required'

+ 7 - 0
src/views/produce/components/picking/detailed.vue

@@ -338,6 +338,13 @@
               align: 'center',
               showOverflowTooltip: true
             },
+            {
+              width: 150,
+              prop: 'supplierName',
+              label: '供应商',
+              align: 'center',
+              showOverflowTooltip: true
+            },
             {
               width: 150,
               prop: 'status',

+ 37 - 4
src/views/produce/components/picking/index.vue

@@ -78,6 +78,9 @@
                 @click="openPicking(item.id, item)"
                 >新增</el-button
               >
+              <el-button type="primary" size="mini" @click="batchDelete"
+                >批量删除</el-button
+              >
             </div>
           </div>
         </div>
@@ -92,7 +95,10 @@
             style="width: 100%"
             stripe
             border
+            @selection-change="handleSelectionChange"
           >
+            <el-table-column type="selection" width="55" align="center">
+            </el-table-column>
             <el-table-column label="序号" type="index" width="60">
               <template slot-scope="{ row, $index }">
                 {{ $index + 1 }}
@@ -369,7 +375,8 @@
         },
         isFullscreen: false,
         tabalHeight: 300,
-        treeId: []
+        treeId: [],
+        selectionData: []
         // warehouseIdList: []
       };
     },
@@ -607,6 +614,32 @@
         this.$forceUpdate();
       },
 
+      handleSelectionChange(val) {
+        this.selectionData = val;
+      },
+
+      batchDelete() {
+        if (this.selectionData.length == 0) {
+          return this.$message.warning('请选择需要删除的领料数据!');
+        }
+
+        this.$confirm('此操作将删除领料数据, 是否继续?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        })
+          .then(() => {
+            for (let item of this.selectionData) {
+              const findIndex = this.workList[0].pickList.findIndex(
+                (it) => item.id == it.id
+              );
+
+              this.workList[0].pickList.splice(findIndex, 1);
+            }
+          })
+          .catch(() => {});
+      },
+
       warehouseChangeNum(item, index) {
         item.warehousePick.forEach((it) => {
           if (Number(it.demandQuantity) > Number(it.availableCountBase)) {
@@ -859,10 +892,10 @@
     }
 
     .col {
-      width: calc(100% / 5);
+      width: calc(100% / 5) !important;
       display: flex;
       align-items: center;
-      min-width: 200px;
+      // min-width: 200px;
       min-height: 32px;
       border-bottom: 1px solid #e3e5e5;
       border-right: 1px solid #e3e5e5;
@@ -875,7 +908,7 @@
         display: flex;
         align-items: center;
         padding: 4px;
-        width: 80px;
+        width: 60px;
         height: 100%;
         background-color: #d0e4d5;
         color: #000;

+ 5 - 0
src/views/produce/components/picking/outboundDetail.vue

@@ -92,6 +92,11 @@
           <template slot="label"> 仓库名称 </template>
           {{ outboundData.warehouseName }}
         </el-descriptions-item>
+
+        <el-descriptions-item>
+          <template slot="label"> 供应商 </template>
+          {{ outboundData.supplierName }}
+        </el-descriptions-item>
         <!-- <el-descriptions-item>
           <template slot="label"> 订单重量 </template>
           {{}}

+ 433 - 0
src/views/produce/components/teRuiPrintOne.vue

@@ -0,0 +1,433 @@
+<template>
+  <ele-modal
+    title="打印标签"
+    :visible.sync="QRvisible"
+    v-if="QRvisible"
+    width="800px"
+    :maxable="true"
+  >
+    <div id="printSection">
+      <div
+        style="
+          border: 1px solid #000;
+          padding: 20px 0;
+          width: 85mm;
+          height: 60mm;
+          box-sizing: border-box;
+          font-weight: 700;
+          font-size: 6px;
+          color: #333;
+          margin: 0 auto;
+        "
+      >
+        <!-- 第一行信息 -->
+        <div style="display: flex; flex-direction: row; padding: 0 20px">
+          <div
+            style="
+              display: flex;
+              flex: 1;
+              flex-direction: column;
+              flex-wrap: wrap;
+            "
+          >
+            <div style="margin: 2px 0">产品名称:{{ productName }}</div>
+            <div style="margin: 2px 0">生产批号:{{ batchNo }}</div>
+            <div style="margin: 2px 0">生产日期:{{ createDate }}</div>
+            <div style="margin: 2px 0">失效日期:2029-11-11</div>
+            <div style="margin: 2px 0">产品数量:5套</div>
+            <div style="margin: 2px 0">刃径:Φ4.2</div>
+          </div>
+          <div
+            style="
+              display: flex;
+              flex: 2;
+              flex-direction: column;
+              align-items: center;
+            "
+          >
+            <div>
+              规格型号:A07SF
+              <input type="checkbox" checked style="width: 8px; height: 8px" />
+              A07SS
+              <input type="checkbox" style="width: 8px; height: 8px" /> A07ST
+              <input type="checkbox" style="width: 8px; height: 8px" />
+            </div>
+            <!-- 刀刃图示 -->
+            <table
+              style="
+                border-collapse: collapse;
+                width: 100%;
+                margin: 8px 0;
+                text-align: center;
+                font-size: 6px;
+              "
+            >
+              <thead>
+                <tr>
+                  <th style="border: 1px solid #000; padding: 4px">刀刃形状</th>
+                  <th style="border: 1px solid #000; padding: 4px">外刃图示</th>
+                  <th style="border: 1px solid #000; padding: 4px">内刃图示</th>
+                </tr>
+              </thead>
+              <tbody style="height: 30px">
+                <tr>
+                  <td
+                    style="width: 25px; border: 1px solid #000; padding: 4px"
+                    >{{ productName }}</td
+                  >
+                  <td style="width: 33px; border: 1px solid #000; padding: 4px"
+                    ><img src="outer.png" alt="外刃"
+                  /></td>
+                  <td style="width: 33px; border: 1px solid #000; padding: 4px"
+                    ><img src="inner.png" alt="内刃"
+                  /></td>
+                </tr>
+              </tbody>
+            </table>
+          </div>
+        </div>
+
+        <div style="display: flex; flex-direction: row; padding: 0 20px">
+          <div style="flex: 1; margin-right: 5px">
+            <p style="padding: 0; margin: 1px 0"
+              >医疗器械注册证编号:{{ enforceStandards }}</p
+            >
+            <p style="padding: 0; margin: 1px 0"
+              >生产许可证编号:湘食药监械生产许20170012号</p
+            >
+            <p style="padding: 0; margin: 1px 0"
+              >注册人/生产企业名称:{{ enterpriseDTO.name }}</p
+            >
+            <p style="padding: 0; margin: 1px 0">
+              注册人/生产企业住址:{{ enterpriseDTO.address }}
+            </p>
+          </div>
+
+          <div style="flex: 1">
+            <p style="padding: 0; margin: 0">
+              生产地址:{{ purchaseOrigins }}
+            </p>
+            <div style="width: 100%; display: flex; justify-content: flex-end">
+              <canvas
+                id="barCodeOne"
+                style="width: 70px; height: 20px; margin-top: 8px"
+              ></canvas>
+            </div>
+          </div>
+        </div>
+
+        <div style="display: flex; flex-direction: row; padding: 0 20px">
+          <div style="width: 160px">
+            <p style="margin: 0; padding: 0"
+              >联系电话:{{ enterpriseDTO.tel }}</p
+            >
+            <p style="margin: 0; padding: 0"
+              >其他内容详见说明书<span>合格</span></p
+            >
+          </div>
+          <div style="display: flex; width: 100%; justify-content: flex-end">
+            <canvas id="barCodeTwo" style="width: 170px; height: 35px"></canvas>
+          </div>
+        </div>
+
+        <!-- 图标与条码 -->
+        <div style="display: flex; gap: 10px; padding: 0 20px">
+          {{ notice }}
+          <!-- <span>STERILE EO</span>
+          <span>经环氧乙烷灭菌</span>
+          <span>不得二次使用</span>
+          <span>包装破损时切勿使用</span>
+          <span>查阅使用说明</span> -->
+        </div>
+
+        <!-- 标签尺寸 -->
+        <!-- <div class="size">标签尺寸:60*90</div> -->
+        <!-- 有效期 -->
+        <!-- <div
+      style="
+        display: flex;
+        text-align: left;
+        font-size: 14px;
+        font-weight: normal;
+        align-items: center;
+        margin-left: 10px;
+      "
+      >有效期变更为 <strong>5 </strong>年</div
+    > -->
+      </div>
+    </div>
+    <div slot="footer">
+      <el-button @click="print">打印预览</el-button>
+      <el-button @click="close">关闭</el-button>
+    </div>
+  </ele-modal>
+</template>
+
+<script>
+  import JsBarcode from 'jsbarcode';
+  export default {
+    data() {
+      return {
+        QRvisible: false,
+        batchNo: '', //批次号
+        productName: '', //产品名称
+        createDate: '', //生产日期
+        enforceStandards: '', //执行标准
+        warrantyPeriodUnit: '', //保质日期单位
+        layBy: '', //贮藏
+        specification: '', //规格
+        purchaseOrigins: '', //产地
+        notice: '', //注意
+        enterpriseDTO: {},
+        expiryDate: '' //失效日期
+      };
+    },
+
+    methods: {
+      open(item, shortBarcode, longBarcode) {
+        this.batchNo = item.batchNo;
+        this.productName = item.productName;
+        this.createDate = item.createDate;
+        this.enforceStandards = item.enforceStandards;
+        this.warrantyPeriodUnit = item.warrantyPeriodUnit;
+        this.layBy = item.layBy;
+        this.specification = item.specification;
+        this.notice = item.notice;
+        this.enterpriseDTO = item.enterpriseDTO;
+
+        const newData = this.createDate.join('-')
+        
+
+        this.QRvisible = true;
+
+        this.$nextTick(() => {
+          JsBarcode('#barCodeOne', shortBarcode, {
+            format: 'CODE128',
+            width: 2,
+            height: 40,
+            displayValue: true
+          });
+
+          JsBarcode('#barCodeTwo', longBarcode, {
+            format: 'CODE128',
+            width: 2,
+            height: 40,
+            displayValue: true
+          });
+        });
+      },
+
+      close() {
+        this.QRvisible = false;
+      },
+
+      print() {
+        const printSection = document.getElementById('printSection');
+
+        const canvasOne = document.getElementById('barCodeOne');
+        const imgOne = document.createElement('img');
+        imgOne.src = canvasOne.toDataURL('image/png');
+        imgOne.style.width = '70px';
+        imgOne.style.height = '20px';
+
+        // const tempOne = canvasOne.cloneNode(true);
+        canvasOne.parentNode.replaceChild(imgOne, canvasOne);
+
+        const canvasTwo = document.getElementById('barCodeTwo');
+        const imgTwo = document.createElement('img');
+        imgTwo.src = canvasTwo.toDataURL('image/png');
+        imgTwo.style.width = '170px';
+        imgTwo.style.height = '35px';
+
+        // const tempTwo = canvasTwo.cloneNode(true);
+        canvasTwo.parentNode.replaceChild(imgTwo, canvasTwo);
+
+        // 创建打印任务
+        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();
+        // };
+        // 4. 等待图片加载完再打印
+        printWindow.onload = function () {
+          setTimeout(() => {
+            printWindow.print();
+            // printWindow.close();
+          }, 500);
+        };
+      }
+    }
+  };
+</script>
+
+<style scoped lang="scss">
+  .label-container {
+    border: 1px solid #000;
+    padding: 20px 0;
+    width: 85mm;
+    height: 63mm;
+    box-sizing: border-box;
+    font-weight: 700;
+    font-size: 6px;
+    color: #333;
+  }
+
+  .label-title {
+    display: flex;
+    flex-direction: row;
+    padding: 0 20px;
+  }
+  .label-info-left {
+    display: flex;
+    flex: 1;
+    flex-direction: column;
+    flex-wrap: wrap;
+
+    div {
+      margin: 2px 0;
+    }
+  }
+
+  .label-info-right {
+    display: flex;
+    flex: 2;
+    flex-direction: column;
+    align-items: center;
+
+    input {
+      width: 8px;
+      height: 8px;
+    }
+  }
+
+  .row {
+    display: flex;
+    justify-content: space-between;
+    margin-bottom: 4px;
+  }
+
+  .knife-table {
+    border-collapse: collapse;
+    width: 100%;
+    margin: 8px 0;
+    text-align: center;
+  }
+
+  .knife-table th,
+  .knife-table td {
+    border: 1px solid #000;
+    padding: 4px;
+  }
+
+  .knife-table tbody {
+    height: 30px;
+
+    .knife-title {
+      width: 33px;
+    }
+  }
+
+  .knife-table img {
+    height: 80px;
+  }
+
+  .info {
+    display: flex;
+    flex-direction: row;
+    padding: 0 20px;
+    .info-left-box {
+      flex: 1;
+      margin-right: 5px;
+
+      p {
+        padding: 0;
+        margin: 1px 0;
+      }
+    }
+
+    .info-right-box {
+      flex: 1;
+
+      p {
+        padding: 0;
+        margin: 0;
+      }
+
+      .canvas-box {
+        width: 100%;
+        display: flex;
+        justify-content: flex-end;
+
+        canvas {
+          width: 70px;
+          height: 20px;
+          margin-top: 8px;
+        }
+      }
+    }
+  }
+
+  .phone-box {
+    display: flex;
+    flex-direction: row;
+    padding: 0 20px;
+    div {
+      width: 160px;
+
+      p {
+        margin: 0;
+        padding: 0;
+        span {
+          margin-left: 20px;
+          font-size: 12px;
+          border: 1px solid #333;
+        }
+      }
+    }
+
+    .phone-canvas-box {
+      display: flex;
+      width: 100%;
+      justify-content: flex-end;
+      canvas {
+        width: 170px;
+        height: 35px;
+      }
+    }
+  }
+
+  .icons {
+    display: flex;
+    gap: 10px;
+    padding: 0 20px;
+  }
+
+  .barcode {
+    text-align: center;
+    margin: 10px 0;
+  }
+
+  .size {
+    text-align: center;
+    font-size: 8px;
+    font-weight: normal;
+    margin-top: 8px;
+  }
+
+  .expiry {
+    display: flex;
+    text-align: left;
+    font-size: 14px;
+    font-weight: normal;
+    align-items: center;
+    margin-left: 10px;
+  }
+</style>

+ 463 - 0
src/views/produce/components/teRuiPrintThree.vue

@@ -0,0 +1,463 @@
+<template>
+  <ele-modal
+    title="打印标签"
+    :visible.sync="QRvisible"
+    v-if="QRvisible"
+    width="800px"
+    :maxable="true"
+  >
+    <div id="printSection">
+      <div
+        style="
+          width: 100mm;
+          height: 72mm;
+          box-sizing: border-box;
+          font-weight: 700;
+          font-size: 10px;
+          color: #333;
+          margin: 0 auto;
+        "
+      >
+        <!-- 第一行信息 -->
+        <div
+          style="
+            display: flex;
+            flex-direction: row;
+            padding: 0 45px;
+            box-sizing: border-box;
+          "
+        >
+          <div
+            style="
+              display: flex;
+              flex: 1;
+              flex-direction: column;
+              flex-wrap: wrap;
+            "
+          >
+            <div>产品名称:{{ productName }}</div>
+            <div>生产批号:{{ batchNo }}</div>
+            <div>生产日期:{{ createDate }}</div>
+          </div>
+          <div style="display: flex; flex: 1; flex-direction: column">
+            <div>规格型号:{{ specification }}</div>
+            <div>产品数量:5套</div>
+            <div>失效日期:{{ expiryDate }}</div>
+          </div>
+        </div>
+
+        <div
+          style="
+            display: flex;
+            flex-direction: column;
+            padding: 0 62px 0 45px;
+            box-sizing: border-box;
+          "
+        >
+          <p style="padding: 0; margin: 0">储存条件和维护方法:{{ layBy }}</p>
+          <p style="padding: 0; margin: 0"
+            >医疗器械注册证编号:{{ enforceStandards }}</p
+          >
+          <p style="padding: 0; margin: 0"
+            >生产许可证编号:湘食药监械生产许20170012号</p
+          >
+          <p style="padding: 0; margin: 0"
+            >注册人/生产企业名称:{{ enterpriseDTO.name }}</p
+          >
+          <p style="padding: 0; margin: 0">
+            注册人/生产企业住址:{{ enterpriseDTO.address }}
+          </p>
+          <p style="padding: 0; margin: 0"> 生产地址:{{ purchaseOrigins }} </p>
+        </div>
+
+        <div
+          style="
+            display: flex;
+            flex-direction: row;
+            padding: 0 62px 0 45px;
+            align-items: center;
+            justify-content: center;
+            box-sizing: border-box;
+          "
+        >
+          <div
+            style="
+              width: 220px;
+              display: flex;
+              flex-direction: column;
+              align-items: center;
+            "
+          >
+            <canvas id="barCodeOne" style="width: 100px; height: 55px"></canvas>
+            <p
+              style="margin: 0; padding: 0; font-size: 9px; font-weight: normal"
+              >联系电话:{{ enterpriseDTO.tel }}</p
+            >
+          </div>
+          <div
+            style="
+              display: flex;
+              width: 100%;
+              justify-content: flex-end;
+              flex-direction: column;
+              align-items: center;
+            "
+          >
+            <canvas id="barCodeTwo" style="width: 150px; height: 55px"></canvas>
+            <p
+              style="
+                margin: 0;
+                padding: 0;
+                font-size: 10px;
+                font-weight: normal;
+              "
+              >其他内容详见说明书</p
+            >
+          </div>
+        </div>
+
+        <!-- 图标与条码 -->
+        <div
+          style="
+            display: flex;
+            gap: 3px;
+            padding: 0 62px 0 45px;
+            margin-top: 10px;
+            box-sizing: border-box;
+            font-size: 8px;
+          "
+        >
+          {{ notice }}
+          <!-- <span>STERILE</span>
+          <span>经环氧乙烷灭菌</span>
+          <span>不得二次使用</span>
+          <span>包装破损时切勿使用</span>
+          <span>查阅使用说明</span> -->
+        </div>
+
+        <!-- 标签尺寸 -->
+        <!-- <div class="size">标签尺寸:100*80</div> -->
+        <!-- <hr /> -->
+        <!-- 有效期 -->
+        <!-- <div class="expiry">有效期变更为 <strong>5 </strong>年</div> -->
+      </div>
+    </div>
+    <div slot="footer">
+      <el-button @click="print">打印预览</el-button>
+      <el-button @click="close">关闭</el-button>
+    </div>
+  </ele-modal>
+</template>
+
+<script>
+  import JsBarcode from 'jsbarcode';
+  export default {
+    data() {
+      return {
+        QRvisible: false,
+        batchNo: '', //批次号
+        productName: '', //产品名称
+        createDate: '', //生产日期
+        enforceStandards: '', //执行标准
+        warrantyPeriodUnit: '', //保质日期单位
+        layBy: '', //贮藏
+        specification: '', //规格
+        purchaseOrigins: '', //产地
+        notice: '', //注意
+        enterpriseDTO: {},
+        expiryDate: '', //失效日期
+        unit: '' //单位
+      };
+    },
+
+    methods: {
+      open(item, shortBarcode, longBarcode) {
+        this.batchNo = item.batchNo;
+        this.productName = item.productName;
+        this.createDate = item.createDate;
+        this.enforceStandards = item.enforceStandards;
+        this.warrantyPeriodUnit = item.warrantyPeriodUnit;
+        this.layBy = item.layBy;
+        this.specification = item.specification;
+        this.notice = item.notice;
+        this.enterpriseDTO = item.enterpriseDTO;
+        this.unit = item.unit;
+
+        if (this.warrantyPeriodUnit) {
+          const warrantyPeriod = item.warrantyPeriod;
+          if (warrantyPeriod) {
+            if (this.warrantyPeriodUnit == '3') {
+              this.expiryDate = this.getEndDate(
+                this.createDate,
+                Number(warrantyPeriod)
+              );
+            } else if (this.warrantyPeriodUnit == '4') {
+              this.expiryDate = this.getEndDateByMonths(
+                this.createDate,
+                Number(warrantyPeriod)
+              );
+            } else if (this.warrantyPeriodUnit == '5') {
+              this.expiryDate = this.getEndDateByYears(
+                this.createDate,
+                Number(warrantyPeriod)
+              );
+            }
+          }
+        }
+
+        this.QRvisible = true;
+        this.$nextTick(() => {
+          JsBarcode('#barCodeOne', shortBarcode, {
+            format: 'CODE128',
+            width: 2,
+            height: 40,
+            displayValue: true
+          });
+
+          JsBarcode('#barCodeTwo', longBarcode, {
+            format: 'CODE128',
+            width: 2,
+            height: 40,
+            displayValue: true
+          });
+        });
+      },
+
+      getEndDate(startDateStr, days) {
+        const startDate = new Date(startDateStr);
+        startDate.setDate(startDate.getDate() + days);
+        const year = startDate.getFullYear();
+        const month = String(startDate.getMonth() + 1).padStart(2, '0');
+        const day = String(startDate.getDate()).padStart(2, '0');
+
+        return `${year}-${month}-${day}`;
+      },
+
+      getEndDateByMonths(startDateStr, months) {
+        const startDate = new Date(startDateStr);
+        startDate.setMonth(startDate.getMonth() + months);
+        const year = startDate.getFullYear();
+        const month = String(startDate.getMonth() + 1).padStart(2, '0');
+        const day = String(startDate.getDate()).padStart(2, '0');
+
+        return `${year}-${month}-${day}`;
+      },
+
+      getEndDateByYears(startDateStr, years) {
+        const startDate = new Date(startDateStr);
+        startDate.setFullYear(startDate.getFullYear() + years);
+        const year = startDate.getFullYear();
+        const month = String(startDate.getMonth() + 1).padStart(2, '0');
+        const day = String(startDate.getDate()).padStart(2, '0');
+
+        return `${year}-${month}-${day}`;
+      },
+
+      close() {
+        this.QRvisible = false;
+      },
+
+      print() {
+        const printSection = document.getElementById('printSection');
+
+        const canvasOne = document.getElementById('barCodeOne');
+        const imgOne = document.createElement('img');
+        imgOne.src = canvasOne.toDataURL('image/png');
+        imgOne.style.width = '100px';
+        imgOne.style.height = '55px';
+
+        // const tempOne = canvasOne.cloneNode(true);
+        canvasOne.parentNode.replaceChild(imgOne, canvasOne);
+
+        const canvasTwo = document.getElementById('barCodeTwo');
+        const imgTwo = document.createElement('img');
+        imgTwo.src = canvasTwo.toDataURL('image/png');
+        imgTwo.style.width = '150px';
+        imgTwo.style.height = '55px';
+
+        // const tempTwo = canvasTwo.cloneNode(true);
+        canvasTwo.parentNode.replaceChild(imgTwo, canvasTwo);
+        // 创建打印任务
+        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 () {
+        //   setTimeout(() => printWindow.print(), 2000);
+        //   // printWindow.print();
+        // };
+
+        // 4. 等待图片加载完再打印
+        printWindow.onload = function () {
+          setTimeout(() => {
+            printWindow.print();
+            // printWindow.close();
+          }, 500);
+        };
+
+        // 打印后恢复原canvas
+        // imgOne.parentNode.replaceChild(tempOne, imgOne);
+        // imgTwo.parentNode.replaceChild(tempTwo, imgTwo);
+      }
+    }
+  };
+</script>
+
+<style scoped lang="scss">
+  .label-container {
+    width: 100mm;
+    height: 72mm;
+    box-sizing: border-box;
+    font-weight: 700;
+    font-size: 10px;
+    color: #333;
+    margin: 0 auto;
+  }
+
+  .label-title {
+    display: flex;
+    flex-direction: row;
+    padding: 0 45px;
+    box-sizing: border-box;
+  }
+  .label-info-left {
+    display: flex;
+    flex: 1;
+    flex-direction: column;
+    flex-wrap: wrap;
+  }
+
+  .label-info-right {
+    display: flex;
+    flex: 1;
+    flex-direction: column;
+
+    input {
+      width: 8px;
+      height: 8px;
+    }
+  }
+
+  .row {
+    display: flex;
+    justify-content: space-between;
+    margin-bottom: 4px;
+  }
+
+  .knife-table {
+    border-collapse: collapse;
+    width: 100%;
+    margin: 8px 0;
+    text-align: center;
+  }
+
+  .knife-table th,
+  .knife-table td {
+    border: 1px solid #000;
+    padding: 4px;
+  }
+
+  .knife-table tbody {
+    height: 30px;
+
+    .knife-title {
+      width: 60px;
+    }
+  }
+
+  .knife-table img {
+    height: 80px;
+  }
+
+  .info {
+    display: flex;
+    flex-direction: column;
+    padding: 0 62px 0 45px;
+    box-sizing: border-box;
+
+    p {
+      padding: 0;
+      margin: 0;
+    }
+  }
+
+  .phone-box {
+    display: flex;
+    flex-direction: row;
+    padding: 0 62px 0 45px;
+    align-items: center;
+    justify-content: center;
+    box-sizing: border-box;
+
+    .phone-canvas-left-box {
+      width: 220px;
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      canvas {
+        width: 100px;
+        height: 55px;
+      }
+
+      p {
+        margin: 0;
+        padding: 0;
+        font-size: 9px;
+        font-weight: normal;
+      }
+    }
+
+    .phone-canvas-right-box {
+      display: flex;
+      width: 100%;
+      justify-content: flex-end;
+      flex-direction: column;
+      align-items: center;
+      canvas {
+        width: 150px;
+        height: 55px;
+      }
+
+      p {
+        margin: 0;
+        padding: 0;
+        font-size: 10px;
+        font-weight: normal;
+      }
+    }
+  }
+
+  .icons {
+    display: flex;
+    gap: 3px;
+    padding: 0 62px 0 45px;
+    margin-top: 10px;
+    box-sizing: border-box;
+    font-size: 8px;
+  }
+
+  .barcode {
+    text-align: center;
+  }
+
+  .size {
+    text-align: center;
+    font-size: 8px;
+    font-weight: normal;
+    margin-top: 8px;
+  }
+
+  .expiry {
+    display: flex;
+    text-align: left;
+    font-size: 14px;
+    font-weight: normal;
+    align-items: center;
+  }
+</style>

+ 271 - 0
src/views/produce/components/teRuiPrintTwo.vue

@@ -0,0 +1,271 @@
+<template>
+  <ele-modal
+    title="打印标签"
+    :visible.sync="QRvisible"
+    v-if="QRvisible"
+    width="800px"
+    :maxable="true"
+  >
+    <div id="printSection">
+      <div
+        style="
+          width: 60mm;
+          border: 1px solid #000;
+          font-size: 6px;
+          background-color: #fff;
+          font-weight: 700;
+          box-sizing: border-box;
+          margin: 0 auto;
+        "
+      >
+        <div
+          style="
+            padding: 10px 10px 0;
+            position: relative;
+            box-sizing: border-box;
+          "
+        >
+          <p style="margin: 2px 0">产品名称:{{ productName }}</p>
+          <p style="margin: 2px 0">规格型号:{{ specification }}</p>
+          <p style="margin: 2px 0">产品数量:1套</p>
+          <p style="margin: 2px 0">生产批号:{{ batchNo }}</p>
+          <p style="margin: 2px 0">生产日期:{{ createDate }}</p>
+          <p style="margin: 2px 0">失效日期:2029-11-11</p>
+          <p style="margin: 2px 0"
+            >医疗器械注册证编号:{{ enforceStandards }}</p
+          >
+          <p style="margin: 2px 0">生产许可证编号:湘药监械生产许20170012号</p>
+          <p style="margin: 2px 0">注册人/生产企业:{{ enterpriseDTO.name }}</p>
+          <p style="margin: 2px 0">
+            注册人/生产企业住所:{{ enterpriseDTO.address }}
+          </p>
+          <canvas
+            id="barCodeOne"
+            style="
+              position: absolute;
+              right: 0;
+              top: 0;
+              margin: 15px 20px;
+              width: 100px;
+              height: 30px;
+            "
+          ></canvas>
+        </div>
+
+        <div
+          style="
+            text-align: center;
+            display: flex;
+            flex-direction: row;
+            align-items: center;
+            padding: 0 5px;
+            box-sizing: border-box;
+          "
+        >
+          <canvas id="barCodeTwo" style="width: 80%; height: 50px"></canvas>
+          <span
+            style="
+              font-size: 8px;
+              padding: 2px;
+              margin-left: 2px;
+              box-sizing: border-box;
+              border: 2px solid #333;
+            "
+            >合格</span
+          >
+        </div>
+
+        <!-- <div class="size">标签尺寸:100*80</div> -->
+        <!-- <hr /> -->
+
+        <!-- <div class="footer">
+      <p>有效期更改为 <strong>5</strong> 年</p>
+    </div> -->
+      </div>
+    </div>
+    <div slot="footer">
+      <el-button @click="print">打印预览</el-button>
+      <el-button @click="close">关闭</el-button>
+    </div>
+  </ele-modal>
+</template>
+
+<script>
+  import JsBarcode from 'jsbarcode';
+  export default {
+    data() {
+      return {
+        QRvisible: false,
+        batchNo: '', //批次号
+        productName: '', //产品名称
+        createDate: '', //生产日期
+        enforceStandards: '', //执行标准
+        warrantyPeriodUnit: '', //保质日期单位
+        layBy: '', //贮藏
+        specification: '', //规格
+        purchaseOrigins: '', //产地
+        notice: '', //注意
+        enterpriseDTO: {},
+        expiryDate: '' //失效日期
+      };
+    },
+
+    methods: {
+      open(item, shortBarcode, longBarcode) {
+        this.batchNo = item.batchNo;
+        this.productName = item.productName;
+        this.createDate = item.createDate;
+        this.enforceStandards = item.enforceStandards;
+        this.warrantyPeriodUnit = item.warrantyPeriodUnit;
+        this.layBy = item.layBy;
+        this.specification = item.specification;
+        this.notice = item.notice;
+        this.enterpriseDTO = item.enterpriseDTO;
+
+        this.QRvisible = true;
+        this.$nextTick(() => {
+          JsBarcode('#barCodeOne', shortBarcode, {
+            format: 'CODE128',
+            width: 2,
+            height: 40,
+            displayValue: true
+          });
+
+          JsBarcode('#barCodeTwo', longBarcode, {
+            format: 'CODE128',
+            width: 2,
+            height: 40,
+            displayValue: true
+          });
+        });
+      },
+
+      close() {
+        this.QRvisible = false;
+      },
+
+      print() {
+        const printSection = document.getElementById('printSection');
+
+        const canvasOne = document.getElementById('barCodeOne');
+        const imgOne = document.createElement('img');
+        imgOne.src = canvasOne.toDataURL('image/png');
+        imgOne.style.width = '100px';
+        imgOne.style.height = '55px';
+
+        // const tempOne = canvasOne.cloneNode(true);
+        canvasOne.parentNode.replaceChild(imgOne, canvasOne);
+
+        const canvasTwo = document.getElementById('barCodeTwo');
+        const imgTwo = document.createElement('img');
+        imgTwo.src = canvasTwo.toDataURL('image/png');
+        imgTwo.style.width = '150px';
+        imgTwo.style.height = '55px';
+
+        // const tempTwo = canvasTwo.cloneNode(true);
+        canvasTwo.parentNode.replaceChild(imgTwo, canvasTwo);
+
+        // 创建打印任务
+        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();
+        // };
+
+        // 4. 等待图片加载完再打印
+        printWindow.onload = function () {
+          setTimeout(() => {
+            printWindow.print();
+            // printWindow.close();
+          }, 500);
+        };
+      }
+    }
+  };
+</script>
+
+<style scoped lang="scss">
+  .label {
+    width: 60mm;
+    border: 1px solid #000;
+    font-size: 6px;
+    background-color: #fff;
+    font-weight: 700;
+    box-sizing: border-box;
+    margin: 0 auto;
+  }
+
+  .product-info {
+    padding: 10px 10px 0;
+    position: relative;
+    box-sizing: border-box;
+
+    p {
+      margin: 2px 0;
+    }
+    canvas {
+      position: absolute;
+      right: 0;
+      top: 0;
+      margin: 15px 20px;
+      width: 100px;
+      height: 30px;
+    }
+  }
+
+  .barcode-box {
+    text-align: center;
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    padding: 0 5px;
+    box-sizing: border-box;
+
+    canvas {
+      width: 80%;
+      height: 50px;
+    }
+
+    span {
+      font-size: 8px;
+      padding: 2px;
+      margin-left: 2px;
+      box-sizing: border-box;
+      border: 2px solid #333;
+    }
+  }
+
+  .status {
+    border: 1px solid #000;
+    width: 40px;
+    text-align: center;
+    padding: 2px 0;
+    margin: 10px 0;
+    font-weight: bold;
+  }
+
+  .size {
+    text-align: center;
+    font-size: 12px;
+    font-weight: normal;
+  }
+
+  .footer {
+    font-size: 16px;
+    font-weight: normal;
+    margin-left: 10px;
+
+    p {
+      margin: 0;
+      padding: 0;
+    }
+  }
+</style>

+ 17 - 1
src/views/produce/components/warehousing/index.vue

@@ -13,9 +13,11 @@
         <el-date-picker
           v-model="executorTime"
           type="datetime"
+          format="yyyy-MM-dd HH:mm:ss"
           value-format="yyyy-MM-dd HH:mm:ss"
           placeholder="选择日期"
           @change="handleCreate"
+          :picker-options="pickerOptions"
         >
         </el-date-picker>
       </div>
@@ -43,9 +45,11 @@
           <el-date-picker
             v-model="item.workReportInfo.executorTime"
             type="datetime"
+            format="yyyy-MM-dd HH:mm:ss"
             value-format="yyyy-MM-dd HH:mm:ss"
             placeholder="选择日期"
             style="margin-right: 25px; width: 190px"
+            :picker-options="pickerOptions"
           >
           </el-date-picker>
           执行人:
@@ -594,7 +598,19 @@
         teamUserList: [],
         executorIdList: [],
         teamId: '',
-        checked: false
+        checked: false,
+        pickerOptions: {
+          disabledDate(time) {
+            // 禁止选择大于当前时间的日期
+            return time.getTime() > Date.now();
+          }
+          // selectableRange: (() => {
+          //   const now = new Date();
+          //   const start = '00:00:00';
+          //   const end = now.toTimeString().split(' ')[0];
+          //   return `${start} - ${end}`;
+          // })()
+        }
       };
     },
 

+ 2 - 2
src/views/produce/index.vue

@@ -1284,7 +1284,7 @@
       width: calc(100% / 5);
       display: flex;
       align-items: center;
-      min-width: 200px;
+      // min-width: 200px;
       min-height: 32px;
       border-bottom: 1px solid #e3e5e5;
       border-right: 1px solid #e3e5e5;
@@ -1297,7 +1297,7 @@
         display: flex;
         align-items: center;
         padding: 4px;
-        width: 80px;
+        width: 60px;
         height: 100%;
         background-color: #d0e4d5;
         color: #000;

+ 7 - 0
src/views/produceOrder/index.vue

@@ -670,6 +670,13 @@
             showOverflowTooltip: true,
             minWidth: 110
           },
+          {
+            prop: 'factoriesName',
+            label: '所属工厂',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 110
+          },
           {
             prop: 'formingWeight',
             label: '要求生产重量',