Просмотр исходного кода

feat:在菜单项中添加首件两检管理

xieyong 1 месяц назад
Родитель
Сommit
e41503dc00
2 измененных файлов с 385 добавлено и 0 удалено
  1. 1 0
      src/components/common/seekPage.vue
  2. 384 0
      src/views/firstCheck/index.vue

+ 1 - 0
src/components/common/seekPage.vue

@@ -227,6 +227,7 @@
       /** 重置 */
       reset() {
         this.defaultWhere = {};
+        this.$emit('reset');
         this.search();
       }
     }

+ 384 - 0
src/views/firstCheck/index.vue

@@ -0,0 +1,384 @@
+<template>
+  <div class="ele-body first-check-page">
+    <el-card class="first-check-card" shadow="never" v-loading="loading">
+      <!-- 产品 / 批次号(支持远程搜索 + 联动) + 工序 / 状态(seekPage)放同一行 -->
+      <div class="first-check-search">
+        <el-form ref="searchFormRef" :model="searchForm" label-width="80px" class="product-form" size="small">
+          <el-form-item label="产品:">
+            <el-select v-model="searchForm.productCode" filterable remote :remote-method="searchProducts"
+              :loading="productLoading" placeholder="输入产品编码或名称搜索" clearable style="width: 180px"
+              @change="onProductChange">
+              <el-option v-for="item in productList" :key="item.productCode"
+                :label="`${item.productCode} / ${item.productName}`" :value="item.productCode" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="批次号:">
+            <el-select v-model="searchForm.batchNo" placeholder="请先选择产品" clearable :disabled="!searchForm.productCode"
+              style="width: 180px">
+              <el-option v-for="item in batchNoList" :key="item" :label="item" :value="item" />
+            </el-select>
+          </el-form-item>
+        </el-form>
+
+        <!-- 工序 + 状态(复用 seekPage,其内置重置按钮会联动清空顶部表单) -->
+        <seek-page class="seek-page-inline" :seekList="seekList" @search="search" @reset="onSeekReset"></seek-page>
+      </div>
+
+      <ele-pro-table ref="table" :columns="columns" :datasource="datasource" @columns-change="handleColumnChange"
+        :cache-key="cacheKeyUrl" height="calc(100vh - 360px)">
+        <template v-slot:status="{ row }">
+          <el-tag v-if="row.status == 0">待自检</el-tag>
+          <el-tag v-if="row.status == 2">待专检</el-tag>
+          <el-tag v-if="row.status == 3">已完成</el-tag>
+        </template>
+
+        <template v-slot:toolbar>
+          <exportButton fileName="首件两检" apiUrl="/mes/firstarticledualinspectionrecord/exportBatchRecordPage"
+            :params="params"></exportButton>
+        </template>
+
+        <template v-slot:selfCheck="{ row }">
+          <el-button type="primary" size="mini" v-if="row.status == 0" @click="reportClick(row, 1) && $hasPermission(
+            'mes:firstarticledualinspectionitem:selfreport'
+          )">自检报工</el-button>
+          <el-button type="primary" size="mini" v-if="row.status == 2 || row.status == 3"
+            @click="reportClick(row, 1, 'detail')">详情</el-button>
+        </template>
+
+        <template v-slot:specialInspection="{ row }">
+          <el-button type="primary" size="mini" v-if="
+            row.status == 2 &&
+            $hasPermission(
+              'mes:firstarticledualinspectionitem:specialreport'
+            )
+          " @click="reportClick(row, 2)">专检报工</el-button>
+          <el-button type="primary" size="mini" v-if="row.status == 3"
+            @click="reportClick(row, 2, 'detail')">详情</el-button>
+        </template>
+      </ele-pro-table>
+
+      <self-inspection-reporting ref="selfReportingRef" @success="reload" @cancel="reload"></self-inspection-reporting>
+    </el-card>
+  </div>
+</template>
+
+<script>
+import dictMixins from '@/mixins/dictMixins';
+import tableColumnsMixin from '@/mixins/tableColumnsMixin';
+import seekPage from '@/components/common/seekPage.vue';
+import exportButton from '@/components/upload/exportButton.vue';
+import selfInspectionReporting from '@/views/produce/components/qualityInspection/components/selfInspectionReporting.vue';
+import { getBatchRecordList } from '@/api/produce/qualityInspection';
+import { produceTask } from '@/api/InTheSystem/index';
+import { getAllProductInWorkOrder } from '@/api/produce/workOrder';
+
+export default {
+  name: 'firstCheck',
+  mixins: [dictMixins, tableColumnsMixin],
+  components: {
+    seekPage,
+    exportButton,
+    selfInspectionReporting
+  },
+  props: {
+    // 作 batchRecord tab 时由父级注入;独立访问时不传
+    tableQuery: {
+      type: Object,
+      default: () => ({})
+    }
+  },
+  data() {
+    return {
+      loading: false,
+      // 顶部独立表单(产品 / 批次号)
+      searchForm: {
+        productCode: '',
+        batchNo: ''
+      },
+      productList: [],
+      productLoading: false,
+      batchNoList: [],
+      // seekPage 用到的工序下拉
+      routList: [],
+      // 导出参数缓存(随 datasource 同步)
+      params: {},
+      cacheKeyUrl: 'firstCheckTable-2026-09-22',
+      columns: [
+        {
+          width: 50,
+          type: 'index',
+          columnKey: 'index',
+          label: '序号',
+          align: 'center'
+        },
+        {
+          prop: 'name',
+          label: '名称',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 150
+        },
+        {
+          prop: 'assignObjectName',
+          label: '工位名称',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 150
+        },
+
+        {
+          prop: 'deviceName',
+          label: '设备名称',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 150
+        },
+
+        {
+          prop: 'produceTaskName',
+          label: '工序名称',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 150
+        },
+
+        {
+          prop: 'selfCheckUserName',
+          label: '自检报工人',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 120
+        },
+        {
+          prop: 'selfCheckTime',
+          label: '自检时间',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 120
+        },
+
+        {
+          prop: 'specialCheckUserName',
+          label: '专检报工人',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 120
+        },
+
+        {
+          prop: 'specialCheckTime',
+          label: '专检时间',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 120
+        },
+
+        {
+          prop: 'status',
+          slot: 'status',
+          label: '状态',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 100
+        },
+        {
+          label: '自检报工',
+          align: 'center',
+          width: 150,
+          fixed: 'right',
+          slot: 'selfCheck'
+        },
+        {
+          label: '专检报工',
+          align: 'center',
+          width: 150,
+          fixed: 'right',
+          slot: 'specialInspection'
+        }
+      ],
+    };
+  },
+  computed: {
+    seekList() {
+      return [
+        {
+          label: '工序:',
+          value: 'produceTaskId',
+          type: 'select',
+          placeholder: '请选择',
+          planList: this.routList
+        },
+        // {
+        //   label: '状态:',
+        //   value: 'status',
+        //   type: 'select',
+        //   placeholder: '请选择',
+        //   planList: [
+        //     { label: '待自检', value: 0 },
+        //     { label: '待专检', value: 2 },
+        //     { label: '已完成', value: 3 }
+        //   ]
+        // }
+      ];
+    }
+  },
+  created() {
+    this.getTaskList();
+    this.searchProducts('');
+  },
+  methods: {
+    // 触发表格刷新,导出参数同步
+    reload(where = {}) {
+      this.params = this.buildParams(where);
+      this.$refs.table.reload({ where: this.params });
+    },
+    // seekPage 的 @search 事件:where 已包含工序 / 状态
+    search(where) {
+      this.reload(where);
+    },
+    // seekPage 的 @reset 事件:清空顶部表单(产品 / 批次号)
+    // seekPage 紧接着会 emit search({}),走 reload → buildParams 空条件 → 表格刷新
+    onSeekReset() {
+      this.searchForm.productCode = '';
+      this.searchForm.batchNo = '';
+      this.batchNoList = [];
+    },
+    // 构建请求 body:合并顶部表单 + seekPage where + tableQuery(父级)
+    buildParams(where = {}) {
+      const result = { ...where };
+      // 1) 内部顶部表单(独立访问时使用)
+      if (this.searchForm.productCode) {
+        result.productCode = this.searchForm.productCode;
+      }
+      if (this.searchForm.batchNo) {
+        result.batchNo = this.searchForm.batchNo;
+      }
+      // 2) 父级 tableQuery 优先级最高(作 batchRecord tab 时生效)
+      if (this.tableQuery && this.tableQuery.productCode) {
+        result.productCode = this.tableQuery.productCode;
+      }
+      if (this.tableQuery && this.tableQuery.batchNo) {
+        result.batchNo = this.tableQuery.batchNo;
+      }
+      // 状态字段单选直接透传(value 为 0/2/3 数字,seekPage 单选模式)
+      return result;
+    },
+    // ele-pro-table 的数据源
+    datasource({ page, limit, where, order }) {
+      const body = {
+        ...this.buildParams(where),
+        ...order,
+        pageNum: page,
+        size: limit
+      };
+      this.params = body;
+      return getBatchRecordList(body);
+    },
+    // 报工入口:弹窗模式打开 selfInspectionReporting
+    // mode 为 'detail' 时进入只读详情模式;其他值(缺省/空)为可报工模式
+    reportClick(row, type, mode) {
+      this.$refs.selfReportingRef.open(row, type, mode || '', 'dialog');
+    },
+    // 拉工序下拉
+    async getTaskList() {
+      try {
+        const res = await produceTask({ pageNum: 1, size: -1 });
+        this.routList = (res.list || []).map((item) => ({
+          label: item.name,
+          value: item.id
+        }));
+      } catch (e) {
+        this.routList = [];
+      }
+    },
+    // 产品远程搜索(带空关键字时拉第一页)
+    async searchProducts(keyword) {
+      try {
+        this.productLoading = true;
+        const { list = [] } = await getAllProductInWorkOrder({
+          param: keyword || '',
+          pageNum: 1,
+          size: 50
+        });
+        this.productList = list;
+        // 若当前选中的产品已不在结果集,清空选中
+        if (
+          this.searchForm.productCode &&
+          !list.some((p) => p.productCode === this.searchForm.productCode)
+        ) {
+          this.searchForm.productCode = '';
+          this.batchNoList = [];
+        }
+      } catch (e) {
+        this.productList = [];
+      } finally {
+        this.productLoading = false;
+      }
+    },
+    // 选中产品后联动批次号
+    onProductChange(productCode) {
+      if (!productCode) {
+        this.batchNoList = [];
+        this.searchForm.batchNo = '';
+        return;
+      }
+      const product = this.productList.find(
+        (p) => p.productCode === productCode
+      );
+      this.batchNoList = product?.batchNos || [];
+      // 已选批次号若不在新批次号列表中则清空
+      if (
+        this.searchForm.batchNo &&
+        !this.batchNoList.includes(this.searchForm.batchNo)
+      ) {
+        this.searchForm.batchNo = '';
+      }
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.first-check-page {
+  height: 100%;
+  min-height: 0;
+  box-sizing: border-box;
+  overflow: hidden;
+}
+
+.first-check-card {
+  height: 100%;
+  box-sizing: border-box;
+
+  :deep(.el-card__body) {
+    height: 100%;
+    min-height: 0;
+    box-sizing: border-box;
+    overflow: hidden;
+    display: flex;
+    flex-direction: column;
+  }
+}
+
+.first-check-search {
+  display: flex;
+  align-items: flex-start;
+  flex-wrap: wrap;
+  margin-bottom: 0;
+
+  .product-form {
+    flex-shrink: 0;
+    display: flex;
+    align-items: center;
+
+    :deep(.el-form-item) {
+      margin-bottom: 12px;
+    }
+  }
+
+  .seek-page-inline {
+    flex: 1;
+    min-width: 0;
+  }
+}
+</style>