Ver código fonte

放行单记录保存功能完成

lucw 8 meses atrás
pai
commit
dccf2820ac

+ 38 - 0
src/api/checklistrecord/index.js

@@ -10,3 +10,41 @@ export async function checklistrecordPage(data) {
   }
   return Promise.reject(new Error(res.data.message));
 }
+
+// /mes/checklistrecord/save 保存
+export async function checklistrecordSave(data) {
+  const res = await request.post('/mes/checklistrecord/save', data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// /mes/checklistrecord/update 修改
+export async function checklistrecordUpdate(data) {
+  const res = await request.put('/mes/checklistrecord/update', data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// /mes/checklistrecord/delete 删除
+export async function checklistrecordDelete(data) {
+  const res = await request.delete('/mes/checklistrecord/logicDeleteByIds', {
+    data
+  });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// /mes/checklistrecord/getById/{id} 根据ID查询
+export async function checklistrecordGetById(id) {
+  const res = await request.get(`/mes/checklistrecord/getById/${id}`);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}

+ 550 - 0
src/components/selectWorkOrder/selectWorkOrder.vue

@@ -0,0 +1,550 @@
+<template>
+  <ele-modal
+    :title="title"
+    :visible.sync="visible"
+    :close-on-click-modal="false"
+    @close="handleClose"
+    resizable
+    maxable
+    append-to-body
+    width="90%"
+  >
+    <div>
+      <seek-page :seekList="seekList" @search="search"></seek-page>
+      <ele-pro-table
+        ref="table"
+        key="id"
+        :columns="basicColumns"
+        :datasource="datasource"
+        row-key="code"
+        :selection.sync="selection"
+        autoAmendPage
+        :cache-key="cacheKeyUrl"
+      >
+        <template v-slot:code="{ row }">
+          <el-link type="primary" :underline="false" @click="goDetail(row)">
+            {{ row.code }}
+          </el-link>
+        </template>
+
+        <template v-slot:QRcode="{ row }">
+          <el-link type="primary" :underline="false" @click="handleQRcode(row)"
+            >生成二维码
+          </el-link>
+        </template>
+
+        <template v-slot:apsWorkOrderCode="{ row }">
+          <label>{{ row.apsWorkOrderCode || '' }}</label>
+        </template>
+
+        <template v-slot:formingNum="{ row }">
+          <span> {{ row.formingNum }} </span>
+        </template>
+
+        <template v-slot:formingWeight="{ row }">
+          <span> {{ row.formingWeight }} {{ row.weightUnit }} </span>
+        </template>
+
+        <template v-slot:singleReport="{ row }">
+          <span v-if="row.singleReport == 0">批量报工</span>
+          <span v-if="row.singleReport == 1">单个报工</span>
+        </template>
+
+        <template v-slot:outsourceStatus="{ row }">
+          <div v-if="row.outsourceStatus">
+            <span v-if="row.outsourceStatus == 1">未委外</span>
+            <span v-if="row.outsourceStatus == 2">委外中</span>
+            <span v-if="row.outsourceStatus == 3">完成委外</span>
+          </div>
+        </template>
+
+        <template v-slot:status="{ row }">
+          <span :class="{ 'ele-text-danger': row.status == 3 }">
+            {{ statusFormatter(row.status) }}
+          </span>
+        </template>
+      </ele-pro-table>
+    </div>
+
+    <template v-slot:footer>
+      <el-button type="primary" @click="submit">选 择</el-button>
+      <el-button @click="handleClose">取 消</el-button>
+    </template>
+  </ele-modal>
+</template>
+
+<script>
+  import dictMixins from '@/mixins/dictMixins';
+  import tableColumnsMixin from '@/mixins/tableColumnsMixin';
+  import { getPage } from '@/api/produceOrder/index.js';
+
+  export default {
+    mixins: [dictMixins, tableColumnsMixin],
+    props: {
+      // 额外的过滤条件
+      where: {
+        type: Object,
+        default: () => ({})
+      },
+      // 选择后是否自动关闭弹窗
+      autoClose: {
+        type: Boolean,
+        default: true
+      }
+    },
+    data() {
+      return {
+        visible: false,
+        title: '选择生产工单',
+        statusOpt: {
+          first: [
+            { label: '所有状态', value: '5,4' },
+            { label: '待生产', value: '4' },
+            { label: '生产中', value: '5' }
+            // { label: '已延期', value: '7' }
+          ],
+          second: [{ label: '已完成', value: '6' }]
+        },
+        planType: [
+          { label: '所有计划类型', value: null },
+          { label: '内销计划', value: '1' },
+          { label: '外销计划', value: '2' },
+          { label: '预制计划', value: '3' }
+        ],
+        cacheKeyUrl: 'public-2025926-select-work-order',
+        selection: []
+      };
+    },
+    computed: {
+      // 表格列配置
+      seekList() {
+        return [
+          {
+            label: '关键字:',
+            value: 'keyWord',
+            type: 'input',
+            placeholder: ''
+          },
+          {
+            label: '生产工单号:',
+            value: 'code',
+            type: 'input',
+            placeholder: '',
+            labelWidth: 100
+          },
+          {
+            label: '生产订单号:',
+            value: 'apsWorkOrderCode',
+            type: 'input',
+            labelWidth: 100
+          },
+          {
+            label: '计划编号:',
+            value: 'productionPlanCode',
+            type: 'input',
+            width: 240
+          },
+          {
+            label: '计划类型:',
+            value: 'planType',
+            type: 'select',
+
+            placeholder: '',
+            width: 240,
+            // 加载状态
+            planList: this.planType
+          },
+          {
+            label: '工艺路线',
+            value: 'produceRoutingName',
+            type: 'input',
+
+            placeholder: '',
+            width: 240
+          },
+          {
+            label: '产品编码',
+            value: 'productCode',
+            type: 'input',
+
+            placeholder: '',
+            width: 240
+          },
+
+          {
+            label: '产品名称:',
+            value: 'productName',
+            type: 'input',
+
+            placeholder: '',
+            width: 240
+          },
+          {
+            label: '牌号',
+            value: 'brandNo',
+            type: 'input',
+
+            placeholder: '',
+            width: 240
+          },
+          {
+            label: '型号',
+            value: 'model',
+            type: 'input',
+
+            placeholder: '',
+            width: 240
+          },
+          // {
+          //   label: '班组:',
+          //   value: 'teamId',
+          //   type: 'select',
+          //   multiple: false, // 是否多选
+          //   filterable: true, // 是否可搜索
+          //   placeholder: '',
+          //   width: 240,
+          //   // 加载状态
+          //   planList: this.statusOpt.first
+          // },
+          {
+            label: '创建时间:',
+            value: 'createTime',
+            type: 'date',
+            dateType: 'daterange',
+            placeholder: '',
+            width: 240,
+            // 加载状态
+            planList: this.statusOpt.first
+          }
+        ];
+      },
+      basicColumns() {
+        const num = this.columnsVersion;
+        const opt = {
+          first: [
+            // {
+            //   prop: 'deliveryTime',
+            //   label: '预测交货日期',
+            //   align: 'center',
+            //   showOverflowTooltip: true,
+            //   minWidth: 110
+            // }
+          ],
+          second: [
+            {
+              prop: 'completeTime',
+              label: '完成时间',
+              align: 'center'
+            },
+            {
+              prop: 'cycle',
+              label: '生产周期',
+              align: 'center'
+            }
+          ]
+        };
+
+        return [
+          {
+            width: 45,
+            type: 'selection',
+            columnKey: 'selection',
+            align: 'center',
+            fixed: 'left'
+          },
+
+          {
+            slot: 'code',
+            label: '生产工单号',
+            align: 'center',
+            minWidth: 110,
+            showOverflowTooltip: true
+          },
+          // {
+          //   prop: 'originalCode',
+          //   label: '原始工单号',
+          //   align: 'center',
+          //   minWidth: 110
+          // },
+          {
+            prop: 'batchNo',
+            label: '批次号',
+            align: 'center',
+            minWidth: 130,
+            showOverflowTooltip: true
+          },
+          {
+            label: '生产订单号',
+            slot: 'apsWorkOrderCode',
+            align: 'center',
+            minWidth: 110,
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'productionPlanCode',
+            label: '计划编号',
+            align: 'center',
+            minWidth: 110,
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'planType',
+            label: '计划类型',
+            align: 'center',
+            showOverflowTooltip: true,
+            formatter: (row) => {
+              const obj = this.planType.find((i) => i.value == row.planType);
+              return obj && obj.label;
+            }
+          },
+          {
+            prop: 'bomType',
+            label: '生产类型',
+            align: 'center',
+            width: 120,
+            formatter: (row) => {
+              if (row.bomType == 1) {
+                return '产品(PBOM)';
+              }
+              if (row.bomType == 2) {
+                return '加工(MBOM)';
+              }
+              if (row.bomType == 3) {
+                return '装配(ABOM)';
+              }
+              // if (row.bomType == 4) {
+              //   return '装配(EBOM)';
+              // }
+              return '';
+            }
+          },
+          {
+            prop: 'bomCategoryName',
+            label: 'BOM版本',
+            align: 'center',
+            width: 130,
+            showOverflowTooltip: true,
+            formatter: (row) => {
+              if (row.bomCategoryName) {
+                return `${row.bomCategoryName} (V${row.bomCategoryVersions}.0)`;
+              }
+              return '';
+            }
+          },
+          {
+            prop: 'produceRoutingName',
+            label: '工艺路线',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'productCode',
+            label: '编码',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'productName',
+            label: '名称',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'model',
+            label: '型号',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'specification',
+            label: '规格',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'productionCodes',
+            label: '生产编号',
+            align: 'center',
+            minWidth: 150,
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'lineNumber',
+            label: '行号',
+            align: 'center',
+            minWidth: 130,
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'brandNo',
+            label: '牌号',
+            align: 'center'
+          },
+          {
+            prop: 'taskName',
+            label: '工序进度',
+            align: 'center'
+          },
+          {
+            prop: 'singleReport',
+            slot: 'singleReport',
+            label: '报工类型',
+            align: 'center'
+          },
+          {
+            prop: 'outsourceStatus',
+            label: '委外状态',
+            align: 'center',
+            slot: 'outsourceStatus',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'formingNum',
+            label: '要求生产数量',
+            align: 'center',
+            slot: 'formingNum',
+            showOverflowTooltip: true,
+            minWidth: 110
+          },
+          {
+            prop: 'formingWeight',
+            label: '要求生产重量',
+            slot: 'formingWeight',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 110
+          },
+          {
+            prop: 'formedNum',
+            label: '已生产数量',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 110
+          },
+          {
+            prop: 'formedWeight',
+            label: '已生产重量',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 110
+          },
+          {
+            prop: 'planStartTime',
+            label: '计划开始时间',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 150,
+            sortable: 'custom'
+          },
+          {
+            prop: 'planCompleteTime',
+            label: '计划结束时间',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 150,
+            sortable: 'custom'
+          },
+          {
+            prop: 'startTime',
+            label: '实际开始时间',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 150,
+            sortable: 'custom'
+          },
+          {
+            prop: 'completeTime',
+            label: '实际完成时间',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 150,
+            sortable: 'custom'
+          },
+          {
+            prop: 'createTime',
+            label: '创建时间',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 150,
+            sortable: 'custom'
+          },
+          // {
+          //   prop: 'status',
+          //   slot: 'status',
+          //   label: '状态',
+          //   align: 'center',
+          //   formatter: (row) => {
+          //     const obj = this.statusOpt[this.activeName].find(
+          //       (i) => i.value == row.status
+          //     );
+          //     return obj && obj.label;
+          //   }
+          // },
+          {
+            prop: 'deviceName',
+            slot: 'deviceName',
+            label: '设备名称',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'crewNames',
+            slot: 'crewNames',
+            label: '报工人员',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+
+          {
+            prop: 'teamName',
+            label: '班组',
+            align: 'center',
+            showOverflowTooltip: true
+          }
+        ];
+      }
+    },
+    methods: {
+      // 外部调用,打开弹窗
+      open(data) {
+        this.visible = true;
+      },
+      // 关闭时清理表单
+      handleClose() {
+        this.visible = false;
+      },
+      // 提交 选择
+      submit() {
+        console.log('this.selection', this.selection);
+        this.$emit('confirm', this.selection);
+        if (this.autoClose) {
+          this.handleClose();
+        }
+      },
+      /* 表格数据源 */
+      datasource({ page, limit, where, order }) {
+        return getPage({
+          ...where,
+          ...order,
+          pageNum: page,
+          size: limit,
+          queryTermination: 0,
+          ...this.where
+        });
+      },
+      /* 刷新表格 */
+      reload(where = {}) {
+        this.$refs.table.reload({ page: 1, where });
+      },
+      search(e) {
+        if (Array.isArray(e.createTime) && e.createTime.length) {
+          e.createTimeStart = e.createTime[0];
+          e.createTimeEnd = e.createTime[1];
+        }
+        this.reload(e);
+      }
+    }
+  };
+</script>
+
+<style scoped lang="scss"></style>

+ 91 - 33
src/views/checklistManagement/checklist.vue

@@ -11,29 +11,47 @@
         autoAmendPage
       >
         <template v-slot:toolbar>
-          <el-button type="primary" size="mini">新建</el-button>
-          <el-button type="primary" size="mini">导入</el-button>
-          <el-button size="mini">导出</el-button>
+          <el-button type="primary" size="mini" @click="openCheckAdd('add')"
+            >新建</el-button
+          >
         </template>
         <template v-slot:action="{ row }">
-          <el-button type="text" size="mini">编辑</el-button>
-          <el-button type="text" size="mini">提交</el-button>
-          <el-button type="text" size="mini">处理</el-button>
-          <el-button type="text" size="mini">详情</el-button>
-          <el-button type="text" size="mini">删除</el-button>
+          <el-link type="text">编辑</el-link>
+          <el-link type="text">提交</el-link>
+          <el-link type="text">处理</el-link>
+          <el-link type="text">详情</el-link>
+          <el-popconfirm
+            title="您确定要删除这条数据吗?"
+            @confirm="deleteRow(row)"
+          >
+            <el-link style="margin-left: 10px" slot="reference" type="text"
+              >删除</el-link
+            >
+          </el-popconfirm>
         </template>
       </ele-pro-table>
     </el-card>
+    <checkAdd
+      ref="checkAddRef"
+      @confirm="checkAddConfirm('add', $event)"
+    ></checkAdd>
+    <checkDetails ref="checkDetailsRef" @reload="reload"></checkDetails>
   </div>
 </template>
 
 <script>
   import dictMixins from '@/mixins/dictMixins';
   import tableColumnsMixin from '@/mixins/tableColumnsMixin';
-  import { checklistrecordPage } from '@/api/checklistrecord/index';
+  import {
+    checklistrecordPage,
+    checklistrecordDelete
+  } from '@/api/checklistrecord/index';
+  import checkAdd from './components/checkAdd.vue';
+  import checkDetails from './components/checkDetails.vue';
 
   export default {
     mixins: [dictMixins, tableColumnsMixin],
+    components: { checkAdd, checkDetails },
     data() {
       return {
         columns: [
@@ -52,7 +70,7 @@
             showOverflowTooltip: true
           },
           {
-            prop: 'code',
+            prop: 'name',
             label: '放行单名称',
             align: 'center',
             minWidth: 110,
@@ -63,66 +81,87 @@
             label: '产品编码',
             align: 'center',
             minWidth: 110,
-            showOverflowTooltip: true
+            showOverflowTooltip: true,
+            formatter: (row) => {
+              return row.orders.map((i) => i.productCode).join(', ');
+            }
           },
           {
             prop: 'productName',
             label: '产品名称',
             align: 'center',
             minWidth: 110,
-            showOverflowTooltip: true
+            showOverflowTooltip: true,
+            formatter: (row) => {
+              return row.orders.map((i) => i.productName).join(', ');
+            }
           },
           {
             prop: 'batchNo',
             label: '批次号',
             align: 'center',
             minWidth: 110,
-            showOverflowTooltip: true
+            showOverflowTooltip: true,
+            formatter: (row) => {
+              return row.orders.map((i) => i.batchNo).join(', ');
+            }
           },
           {
-            prop: 'code',
+            prop: 'code1',
             label: '生产工单号',
             align: 'center',
             minWidth: 110,
-            showOverflowTooltip: true
+            showOverflowTooltip: true,
+            formatter: (row) => {
+              return row.orders.map((i) => i.id).join(', ');
+            }
           },
           {
-            prop: 'code',
+            prop: 'code2',
             label: '数量',
             align: 'center',
             minWidth: 110,
-            showOverflowTooltip: true
+            showOverflowTooltip: true,
+            formatter: (row) => {
+              return row.orders.map((i) => i.formingNum).join(', ');
+            }
           },
           {
-            prop: 'code',
+            prop: 'code3',
             label: '规格',
             align: 'center',
             minWidth: 110,
-            showOverflowTooltip: true
+            showOverflowTooltip: true,
+            formatter: (row) => {
+              return row.orders.map((i) => i.specification).join(', ');
+            }
           },
           {
             prop: 'productModel',
             label: '型号',
             align: 'center',
             minWidth: 110,
-            showOverflowTooltip: true
+            showOverflowTooltip: true,
+            formatter: (row) => {
+              return row.orders.map((i) => i.productModel).join(', ');
+            }
           },
           {
-            prop: 'status',
-            label: '状态',
+            prop: 'approvalStatus',
+            label: '审核',
             align: 'center',
             showOverflowTooltip: true,
             minWidth: 150,
             formatter: (row) => {
-              switch (row.status) {
+              switch (row.approvalStatus) {
                 case 0:
-                  return '未领料';
+                  return '未提交';
                 case 1:
-                  return '已领料';
+                  return '审核中';
                 case 2:
-                  return '已出库';
+                  return '审核通过';
                 case 3:
-                  return '部分出库';
+                  return '审核不通过';
                 default:
                   return '';
               }
@@ -154,21 +193,27 @@
         return [
           {
             label: '放行单编码:',
-            value: 'releaseOrderCode',
+            value: 'code',
             type: 'input',
             placeholder: '请输入'
           },
           {
             label: '放行单名称:',
-            value: 'releaseOrderName',
+            value: 'name',
             type: 'input',
             placeholder: '请输入'
           },
           {
             label: '审核状态:',
-            value: 'releaseOrderStatus',
-            type: 'input',
-            placeholder: '请输入'
+            value: 'approvalStatus',
+            type: 'select',
+            placeholder: '请输入',
+            planList: [
+              { label: '未提交', value: 0 },
+              { label: '审核中', value: 1 },
+              { label: '审核通过', value: 2 },
+              { label: '审核不通过', value: 3 }
+            ]
           }
         ];
       }
@@ -176,7 +221,7 @@
     methods: {
       // 刷新表格
       reload(where = {}) {
-        this.refs.table.reload({
+        this.$refs.table.reload({
           where
         });
       },
@@ -193,6 +238,19 @@
       },
       search(where) {
         this.reload(where);
+      },
+      // 打开添加弹窗
+      openCheckAdd(type) {
+        this.$refs.checkAddRef?.open(type);
+      },
+      checkAddConfirm(type, data) {
+        this.$refs.checkDetailsRef?.open(type, data);
+      },
+      // 删除
+      async deleteRow(row) {
+        await checklistrecordDelete([row.id]);
+        this.$message.success('删除成功');
+        this.reload();
       }
     }
   };

+ 155 - 0
src/views/checklistManagement/components/checkAdd.vue

@@ -0,0 +1,155 @@
+<template>
+  <ele-modal
+    :title="title"
+    :visible.sync="visible"
+    :close-on-click-modal="false"
+    @close="handleClose"
+    resizable
+    maxable
+    width="500px"
+  >
+    <el-form ref="formRef" :model="form" :rules="rules" label-width="130px">
+      <el-form-item label="放行类型" prop="checklistType">
+        <DictSelection
+          dictName="放行类型"
+          clearable
+          v-model="form.checklistType"
+          @change="checklistTypeChange"
+        >
+        </DictSelection>
+      </el-form-item>
+      <el-form-item label="放行单模板名称" prop="templateId">
+        <el-select
+          style="width: 100%"
+          v-model="form.templateId"
+          placeholder="请选择,来源于放行单模板"
+          filterable
+          remote
+          :remote-method="remoteMethod"
+          @change="handleTemplateChange"
+        >
+          <el-option
+            v-for="item in templateIdList"
+            :key="item.id"
+            :label="item.templateName"
+            :value="item.id"
+          >
+          </el-option>
+        </el-select>
+      </el-form-item>
+    </el-form>
+
+    <template v-slot:footer>
+      <el-button type="primary" @click="submit">提 交</el-button>
+      <el-button @click="handleClose">取 消</el-button>
+    </template>
+  </ele-modal>
+</template>
+
+<script>
+  import dictMixins from '@/mixins/dictMixins';
+  import { checklisttemplatePage } from '@/api/checklisttemplate/index';
+
+  export default {
+    mixins: [dictMixins],
+    components: {},
+    data() {
+      const formBaseData = {
+        // 	放行单类型,1-成品放行,2-商品放行,3-物料放行
+        checklistType: '',
+        templateId: null,
+        templateName: ''
+      };
+
+      return {
+        visible: false,
+        title: '新增放行单',
+        formBaseData,
+        form: JSON.parse(JSON.stringify(formBaseData)),
+        rules: {
+          checklistType: [
+            { required: true, message: '请选择放行类型', trigger: 'blur' },
+            { required: true, message: '请选择放行类型', trigger: 'change' }
+          ],
+          templateId: [
+            { required: true, message: '请选择放行单模板', trigger: 'blur' },
+            { required: true, message: '请选择放行单模板', trigger: 'change' }
+          ]
+        },
+        //模板列表
+        templateIdList: [],
+      };
+    },
+    created() {},
+    methods: {
+      // 外部调用,打开弹窗
+      open(type, data) {
+        console.log('data type', type, data);
+
+        if (type == 'add') {
+          this.title = '新增放行单';
+        } else {
+          this.title = '编辑放行单';
+        }
+        this.visible = true;
+      },
+      // 关闭时清理表单
+      handleClose() {
+        this.visible = false;
+        this.form = JSON.parse(JSON.stringify(this.formBaseData));
+        this.$refs.formRef && this.$refs.formRef.resetFields();
+      },
+      // 提交
+      submit() {
+        this.$refs.formRef.validate((valid) => {
+          if (valid) {
+            this.$emit('submit', this.form);
+            // 下一步 放行单申请
+            this.$emit('confirm', this.form);
+            this.handleClose();
+          }
+        });
+      },
+      // 远程搜索
+      remoteMethod(query) {
+        if (query !== '') {
+          this.fetchTemplateList(query);
+        } else {
+          this.fetchTemplateList();
+        }
+      },
+      // 查询模板列表
+      async fetchTemplateList(templateName = '') {
+        if (this.form.checklistType == '') {
+          this.templateIdList = [];
+          return;
+        }
+        const data = await checklisttemplatePage({
+          pageNum: 1,
+          size: 99,
+          templateName: templateName,
+          checklistType: this.form.checklistType
+        });
+        this.templateIdList = data.list;
+        console.log('data', data);
+      },
+      // 选择模板
+      handleTemplateChange(id) {
+        const selected = this.templateIdList.find((item) => item.id === id);
+        if (selected) {
+          this.form.templateName = selected.templateName;
+        } else {
+          this.form.templateName = '';
+        }
+      },
+      // 选择放行单类型
+      checklistTypeChange() {
+        this.fetchTemplateList();
+        this.form.templateId = null;
+        this.form.templateName = '';
+      }
+    }
+  };
+</script>
+
+<style scoped lang="scss"></style>

+ 520 - 0
src/views/checklistManagement/components/checkDetails.vue

@@ -0,0 +1,520 @@
+<template>
+  <ele-modal
+    :title="title"
+    :visible.sync="visible"
+    :close-on-click-modal="false"
+    @close="handleClose"
+    resizable
+    maxable
+    width="80%"
+  >
+    <el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
+      <header-title title="基本信息"></header-title>
+
+      <el-row :gutter="10">
+        <el-col :span="8">
+          <el-form-item label="放行单编码">
+            <el-input
+              v-model="form.code"
+              placeholder="系统自动生成"
+              disabled
+            ></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="放行单名称" prop="name">
+            <el-input v-model="form.name" placeholder="请输入"></el-input>
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <header-title title="物品清单">
+        <el-button type="primary" icon="el-icon-plus" @click="openAddModel">
+          添加
+        </el-button>
+      </header-title>
+
+      <ele-pro-table
+        ref="table"
+        row-key="userId"
+        :columns="ordersColumns"
+        :datasource="form.orders"
+      >
+        <template v-slot:action="{ row }">
+          <el-link icon="el-icon-edit" type="primary" :underline="false"
+            >详情</el-link
+          >
+          <el-link
+            icon="el-icon-delete"
+            type="danger"
+            :underline="false"
+            @click="deleteRow(row)"
+            >删除</el-link
+          >
+        </template>
+      </ele-pro-table>
+
+      <el-button type="primary" style="margin-bottom: 15px">
+        规则齐套检查
+      </el-button>
+
+      <header-title title="生产放行规则"> </header-title>
+
+      <ele-pro-table
+        ref="scTable"
+        row-key="id"
+        :columns="detailsColumns"
+        :datasource="scDetails"
+      >
+        <template v-slot:isPass="{ row }">
+          <el-radio-group v-model="row.isPass">
+            <el-radio :label="1">是</el-radio>
+            <el-radio :label="2">否</el-radio>
+          </el-radio-group>
+        </template>
+        <template v-slot:remark="{ row }">
+          <el-input
+            type="textarea"
+            v-model="row.remark"
+            placeholder="请输入备注"
+            :rows="1"
+          ></el-input>
+        </template>
+      </ele-pro-table>
+
+      <table class="detail-table" style="width: 500px; margin: 15px 0">
+        <tr>
+          <td>结论</td>
+          <td>
+            <el-radio-group v-model="form.workConclution">
+              <el-radio :label="0">不符合规定</el-radio>
+              <el-radio :label="1">符合规定</el-radio>
+            </el-radio-group>
+          </td>
+        </tr>
+        <tr>
+          <td>验收人</td>
+          <td>
+            <el-input
+              v-model="form.workCheckUserName"
+              placeholder="请输入"
+            ></el-input>
+          </td>
+        </tr>
+        <tr>
+          <td>验收时间</td>
+          <td>
+            <el-date-picker
+              v-model="form.workCheckTime"
+              type="datetime"
+              placeholder="选择日期时间"
+              style="width: 100%"
+            ></el-date-picker>
+          </td>
+        </tr>
+      </table>
+
+      <header-title title="质检放行规则"></header-title>
+
+      <ele-pro-table
+        ref="zjTable"
+        row-key="id"
+        :columns="detailsColumns"
+        :datasource="zjDetails"
+      >
+        <template v-slot:isPass="{ row }">
+          <el-radio-group v-model="row.isPass">
+            <el-radio :label="1">是</el-radio>
+            <el-radio :label="2">否</el-radio>
+          </el-radio-group>
+        </template>
+        <template v-slot:remark="{ row }">
+          <el-input
+            type="textarea"
+            v-model="row.remark"
+            placeholder="请输入备注"
+            :rows="1"
+          ></el-input>
+        </template>
+      </ele-pro-table>
+
+      <table class="detail-table" style="width: 500px; margin: 15px 0">
+        <tr>
+          <td>结论</td>
+          <td>
+            <el-radio-group v-model="form.qualityConclution">
+              <el-radio :label="0">不符合规定</el-radio>
+              <el-radio :label="1">符合规定</el-radio>
+            </el-radio-group>
+          </td>
+        </tr>
+        <tr>
+          <td>验收人</td>
+          <td>
+            <el-input
+              v-model="form.qualityCheckUserName"
+              placeholder="请输入"
+            ></el-input>
+          </td>
+        </tr>
+        <tr>
+          <td>验收时间</td>
+          <td>
+            <el-date-picker
+              v-model="form.qualityCheckTime"
+              type="datetime"
+              placeholder="选择日期时间"
+              style="width: 100%"
+            ></el-date-picker>
+          </td>
+        </tr>
+      </table>
+
+      <selectWorkOrder
+        ref="selectWorkOrderRef"
+        :where="workOrderWhere"
+        :autoClose="false"
+        @confirm="selectWorkOrderConfirm"
+      ></selectWorkOrder>
+    </el-form>
+
+    <template v-slot:footer>
+      <el-button type="primary" @click="submit" :loading="butLoading"
+        >提 交</el-button
+      >
+      <el-button type="primary" @click="submit('save')" :loading="butLoading"
+        >保存</el-button
+      >
+      <el-button @click="handleClose">取 消</el-button>
+    </template>
+  </ele-modal>
+</template>
+
+<script>
+  import dictMixins from '@/mixins/dictMixins';
+  import selectWorkOrder from '@/components/selectWorkOrder/selectWorkOrder.vue';
+  import { checklisttemplateGetById } from '@/api/checklisttemplate/index';
+  import { checklistrecordSave } from '@/api/checklistrecord/index';
+
+  export default {
+    mixins: [dictMixins],
+    components: { selectWorkOrder },
+    data() {
+      const formBaseData = {
+        approvalStatus: 0,
+        checklistType: 0,
+        code: '',
+        createUserName: '',
+        details: [],
+        name: '',
+        orders: [],
+        processInstanceId: '',
+        qualityCheckTime: '',
+        qualityCheckUserId: 0,
+        qualityCheckUserName: '',
+        qualityConclution: 0,
+        templateId: 0,
+        templateName: '',
+        workCheckTime: '',
+        workCheckUserId: 0,
+        workCheckUserName: '',
+        workConclution: 0
+      };
+
+      return {
+        visible: false,
+        title: '放行申请单',
+        formBaseData,
+        form: JSON.parse(JSON.stringify(formBaseData)),
+        rules: {
+          name: [
+            { required: true, message: '请输入放行单名称', trigger: 'blur' },
+            { required: true, message: '请输入放行单名称', trigger: 'change' }
+          ]
+        },
+        // 类型 add / edit / detail
+        type: '',
+        // 生产工单查询条件
+        workOrderWhere: {
+          statusList: ['6']
+        },
+        loading: false,
+        butLoading: false
+      };
+    },
+    computed: {
+      ordersColumns() {
+        return [
+          {
+            width: 55,
+            type: 'index',
+            columnKey: 'index',
+            label: '序号',
+            align: 'center'
+          },
+          {
+            prop: 'batchNo',
+            label: '批次号',
+            align: 'center',
+            minWidth: 110,
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'productCode',
+            label: '产品编码',
+            align: 'center',
+            minWidth: 110,
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'productName',
+            label: '产品名称',
+            align: 'center',
+            minWidth: 110,
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'workOrderId',
+            label: '生产工单号',
+            align: 'center',
+            minWidth: 110,
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'formingNum',
+            label: '数量',
+            align: 'center',
+            minWidth: 110,
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'specification',
+            label: '规格',
+            align: 'center',
+            minWidth: 110,
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'productModel',
+            label: '型号',
+            align: 'center',
+            minWidth: 110,
+            showOverflowTooltip: true
+          },
+          {
+            label: '操作',
+            columnKey: 'action',
+            slot: 'action',
+            minWidth: 120
+          }
+        ];
+      },
+      // 生产放行规则
+      scDetails() {
+        return this.form.details.filter((item) => item.checkType == 1);
+      },
+      // 质检放行规则
+      zjDetails() {
+        return this.form.details.filter((item) => item.checkType == 2);
+      },
+      detailsColumns() {
+        return [
+          {
+            width: 55,
+            type: 'index',
+            columnKey: 'index',
+            label: '序号',
+            align: 'center'
+          },
+          {
+            prop: 'targetDefinitionName',
+            label: '指标名称',
+            align: 'center',
+            minWidth: 110,
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'isPass',
+            label: '审核结果',
+            align: 'center',
+            slot: 'isPass',
+            minWidth: 110,
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'remark',
+            label: '备注',
+            align: 'center',
+            slot: 'remark',
+            minWidth: 110,
+            showOverflowTooltip: true
+          }
+        ];
+      }
+    },
+    methods: {
+      // 外部调用,打开弹窗
+      open(type, data) {
+        console.log('data , type', data, type);
+        if (type == 'add') {
+          this.title = '放行申请单';
+          // 生产放心单名称 = 模版名称+年月日+3位数
+          this.form.name = `${data.templateName}${new Date()
+            .toLocaleDateString()
+            .replace(/\//g, '')}${String(
+            Math.floor(Math.random() * 1000)
+          ).padStart(3, '0')}`;
+
+          this.form.templateId = data.templateId;
+          this.form.templateName = data.templateName;
+
+          // 根据模版id 查询模版详情
+          this.getTemplateDetails(data.templateId);
+        } else if (type == 'edit') {
+          this.title = '放行申请单';
+        } else if (type == 'detail') {
+          this.title = '放行单详情';
+        } else {
+          this.title = '审批';
+        }
+        this.visible = true;
+      },
+      // 关闭时清理表单
+      handleClose() {
+        this.visible = false;
+        this.form = JSON.parse(JSON.stringify(this.formBaseData));
+        this.$refs.formRef && this.$refs.formRef.resetFields();
+      },
+      // 提交
+      submit(type) {
+        console.log('this.form', this.form);
+        this.$refs.formRef.validate(async (valid, invalidFields) => {
+          if (valid) {
+            // 必须要有物品清单
+            if (this.form.orders.length == 0) {
+              this.$message.warning('请添加物品清单');
+              return;
+            }
+
+            this.butLoading = true;
+            try {
+              if (type == 'save') {
+                await checklistrecordSave(this.form);
+              } else {
+              }
+              this.$message.success('操作成功');
+              this.butLoading = false;
+              this.$emit('reload');
+            } catch (error) {
+              this.butLoading = false;
+            }
+            this.handleClose();
+          } else {
+            // 转换为数组
+            const firstErrorField = Object.values(invalidFields);
+            if (firstErrorField.length > 0) {
+              this.$message.warning(firstErrorField[0][0].message);
+            }
+
+            return false;
+          }
+        });
+      },
+      // 选择生产工单
+      openAddModel() {
+        this.$refs.selectWorkOrderRef?.open();
+      },
+      // 选择生产工单确认
+      selectWorkOrderConfirm(selection) {
+        const selectList = selection.map((i) => {
+          return {
+            batchNo: i.batchNo,
+            createUserName: i.createUserName,
+            formingNum: i.formingNum,
+            produceRoutingId: i.produceRoutingId,
+            produceRoutingName: i.produceRoutingName,
+            productCode: i.productCode,
+            productModel: i.productModel,
+            productName: i.productName,
+            recordId: i.recordId,
+            specification: i.specification,
+            workOrderCode: i.code,
+            workOrderId: i.id
+          };
+        });
+
+        console.log('selectList', selectList);
+        // 判断是否同一产品 同一批次
+        if (selectList.length != 0) {
+          const productCode = selectList[0].productCode;
+          const batchNo = selectList[0].batchNo;
+          const isSame = selectList.every(
+            (item) =>
+              item.productCode === productCode && item.batchNo === batchNo
+          );
+
+          const isSameOrders = this.form.orders.every(
+            (item) =>
+              item.productCode === productCode && item.batchNo === batchNo
+          );
+
+          if (!isSame || !isSameOrders) {
+            this.$message.warning('请选择同产品同批次号工单发起批量放行');
+            return;
+          }
+
+          // 去重
+          const existingWorkOrderIds = this.form.orders.map(
+            (order) => order.workOrderId
+          );
+          const newOrders = selectList.filter(
+            (item) => !existingWorkOrderIds.includes(item.workOrderId)
+          );
+          this.form.orders = [...this.form.orders, ...newOrders];
+        }
+        // 关闭弹窗
+        this.$refs.selectWorkOrderRef?.handleClose();
+      },
+      // 删除行
+      deleteRow(row) {
+        this.form.orders = this.form.orders.filter(
+          (item) => item.workOrderId !== row.workOrderId
+        );
+      },
+      async getTemplateDetails(id) {
+        this.loading = true;
+        try {
+          const data = await checklisttemplateGetById(id);
+          console.log('模板详情', data);
+          // 详情
+          this.form.details = data.details;
+
+          this.loading = false;
+        } catch (error) {
+          this.loading = false;
+        }
+      }
+    }
+  };
+</script>
+
+<style scoped lang="scss">
+  .detail-table {
+    border: 1px solid #ebeef5;
+    // 实线边框
+    border-collapse: collapse;
+
+    td {
+      border: none;
+      padding: 10px 15px;
+      border: 1px solid #ebeef5;
+
+      &:first-child {
+        font-weight: 600;
+        background: #f5f7fa;
+        width: 130px;
+        text-align: center;
+      }
+    }
+  }
+</style>

+ 2 - 1
src/views/checklistManagement/components/templateAdd.vue

@@ -400,6 +400,7 @@
         } else {
           // 克隆
           this.title = '编辑放行单模版';
+          this.getDetails(data.id);
         }
         this.visible = true;
       },
@@ -467,7 +468,7 @@
 
             try {
               if (type == 'add' || type == 'clone') {
-                this.form.createUserName = this.$store.state.user?.userName;
+                this.form.createUserName = this.$store.state.user?.info.name;
                 this.form.id = null;
                 // 重置id
                 this.form.details.forEach((item) => {

+ 15 - 9
src/views/checklistManagement/templatelist.vue

@@ -14,11 +14,13 @@
           <el-button type="primary" size="mini" @click="openAddDialog('add')"
             >新建</el-button
           >
-          <el-button type="primary" size="mini">导入</el-button>
-          <el-button size="mini">导出</el-button>
+          <!-- <el-button type="primary" size="mini">导入</el-button>
+          <el-button size="mini">导出</el-button> -->
         </template>
         <template v-slot:action="{ row }">
-          <el-link type="text"  @click="openAddDialog('clone', row)">克隆</el-link>
+          <el-link type="text" @click="openAddDialog('clone', row)"
+            >克隆</el-link
+          >
           <el-link
             type="text"
             @click="openAddDialog('edit', row)"
@@ -27,7 +29,7 @@
           >
           <el-popconfirm
             v-if="row.enable == 0"
-            title="这是一段内容确定删除吗?"
+            title="您确定要删除这条数据吗?"
             @confirm="deleteRow(row)"
           >
             <el-link slot="reference" type="danger">删除</el-link>
@@ -136,25 +138,29 @@
         return [
           {
             label: '编码:',
-            value: 'releaseOrderCode',
+            value: 'templateCode',
             type: 'input',
             placeholder: '请输入'
           },
           {
             label: '名称:',
-            value: 'releaseOrderName',
+            value: 'templateName',
             type: 'input',
             placeholder: '请输入'
           },
           {
             label: '放行类型:',
-            value: 'releaseOrderStatus',
-            type: 'input',
-            placeholder: '请输入'
+            value: 'checklistType',
+            type: 'select',
+            placeholder: '请输入',
+            planList: this.getDictListByName('放行类型')
           }
         ];
       }
     },
+    created() {
+      this.requestDict('放行类型');
+    },
     methods: {
       // 刷新表格
       reload(where = {}) {

+ 2 - 1
vue.config.js

@@ -12,6 +12,7 @@ module.exports = {
   lintOnSave: false,
   productionSourceMap: false,
   configureWebpack: {
+    devtool: 'source-map',
     performance: {
       maxAssetSize: 2000000,
       maxEntrypointSize: 2000000
@@ -43,7 +44,7 @@ module.exports = {
         // target: 'http://192.168.1.33:18086',
         // target: 'http://192.168.1.251:18186',
         // target: 'http://192.168.1.251:18087',
-        // target: 'http://192.168.1.116:18086',
+        target: 'http://192.168.1.116:18086',
         changeOrigin: true, // 只有这个值为true的情况下 才表示开启跨域
         pathRewrite: {
           '^/api': ''