<template>
  <div>
    <seek-page :seekList="seekList" @search="search"></seek-page>
    <ele-pro-table
      ref="table"
      row-key="id"
      :columns="columns"
      :datasource="datasource"
      :cache-key="cacheKeyUrl"
      :selection.sync="selection"
      autoAmendPage
      height="var(--batch-record-table-height)"
    >
      <template v-slot:action="{ row }">
        <el-link type="primary" :underline="false" @click="goToDetail(row)">
          详情
        </el-link>
      </template>

      <template v-slot:code="{ row }">
        <el-link type="primary" @click="goToDetail(row)">{{
          row.code
        }}</el-link>
      </template>
      <template v-slot:toolbar>
        <exportButton
          fileName="质检工单"
          apiUrl="/qms/quality_work_order/exportBatchRecordPage"
          :params="params"
        ></exportButton>
        <print-selector :options="printOptions" @select="handlePrint" />
      </template>
    </ele-pro-table>

    <product-inspection-report ref="productInspectionReport" />
    <sampling-form ref="samplingForm" />
    <finished-product-original-record ref="finishedProductOriginalRecord" />
  </div>
</template>

<script>
  import dictMixins from '@/mixins/dictMixins';
  import tableColumnsMixin from '@/mixins/tableColumnsMixin';
  import { batchRecordPage, queryPrint } from '@/api/qualityWorkOrder/index.js';
  import exportButton from '@/components/upload/exportButton.vue';
  import printSelector from '../printSelector.vue';
  import productInspectionReport from '../../print/electrodeBatchRecord/productInspectionReport.vue';
  import samplingForm from '../../print/electrodeBatchRecord/samplingForm.vue';
  import finishedProductOriginalRecord from '../../print/electrodeBatchRecord/finishedProductOriginalRecord.vue';

  export default {
    mixins: [dictMixins, tableColumnsMixin],
    components: {
      exportButton,
      printSelector,
      productInspectionReport,
      samplingForm,
      finishedProductOriginalRecord
    },
    props: {
      tableQuery: {
        type: Object,
        default: () => {
          return {};
        }
      }
    },
    data() {
      return {
        columns: [
          {
            width: 45,
            type: 'selection',
            columnKey: 'selection',
            align: 'center',
            fixed: 'left'
          },
          {
            width: 50,
            type: 'index',
            columnKey: 'index',
            align: 'center',
            label: '序号'
          },
          {
            prop: 'code',
            label: '质检工单编码',
            align: 'center',
            minWidth: 110,
            showOverflowTooltip: true,
            slot: 'code'
          },
          {
            prop: 'name',
            label: '质检工单名称',
            align: 'center',
            showOverflowTooltip: true,
            minWidth: 150
          },
          {
            prop: 'sourceCode',
            label: '来源单号',
            align: 'center',
            showOverflowTooltip: true,
            minWidth: 150,
            formatter: (row) => {
              return row.qualityPlanCode
                ? row.qualityPlanCode
                : row.workOrderCode;
            }
          },
          {
            prop: 'qualityType',
            label: '类型',
            align: 'center',
            showOverflowTooltip: true,
            minWidth: 150,
            formatter: (row) => {
              return this.getDictValue('质检计划类型', row.qualityType);
            }
          },
          {
            prop: 'qualityMode',
            label: '质检方式',
            align: 'center',
            showOverflowTooltip: true,
            minWidth: 150,
            formatter: (row) => {
              return this.getDictValue('取样类型', `0${row.qualityMode}`);
            }
          },
          {
            prop: 'qualityName',
            label: '报工人',
            align: 'center',
            showOverflowTooltip: true,
            minWidth: 150
          },
          {
            prop: 'qualityTime',
            label: '质检时间',
            align: 'center',
            showOverflowTooltip: true,
            minWidth: 150
          },
          {
            prop: 'status',
            label: '状态',
            align: 'center',
            showOverflowTooltip: true,
            minWidth: 150,
            formatter: (row) => {
              switch (row.status) {
                case 0:
                  return '未报工';
                case 1:
                  return '已报工';

                default:
                  return '已关闭';
              }
            }
          },
          {
            label: '操作',
            columnKey: 'action',
            slot: 'action',
            showOverflowTooltip: true,
            minWidth: 110,
            align: 'center',
            fixed: 'right'
          }
        ],
        cacheKeyUrl: 'mes-9221130-quality-work-order-table',
        params: {},
        tableData: [],
        selection: [],
        printTypeMap: {
          productInspectionReport: 'PRODUCT_INSPECTION_REPORT',
          samplingForm: 'SAMPLING_SLIP',
          finishedProductOriginalRecord: 'FINISHED_PRODUCT_INSPECTION_RECORD'
        },
        printOptions: [
          {
            key: 'productInspectionReport',
            label: '产品报检单',
            code: 'CG-038'
          },
          { key: 'samplingForm', label: '取样单', code: 'ZL-041' }
          // {
          //   key: 'finishedProductOriginalRecord',
          //   label: '成品检验原始记录',
          //   code: '054-7'
          // }
        ]
      };
    },
    computed: {
      seekList() {
        return [
          {
            label: '生产工单编码',
            value: 'workOrderCode',
            type: 'input',
            placeholder: '请输入',
            labelWidth: 110
          },
          {
            label: '质检工单编码',
            value: 'code',
            type: 'input',
            placeholder: '请输入',
            labelWidth: 110
          },
          {
            label: '质检工单名称',
            value: 'name',
            type: 'input',
            placeholder: '请输入',
            labelWidth: 110
          }
        ];
      }
    },
    created() {
      this.requestDict('质检计划类型');
      this.requestDict('不良品处理类型');
      this.requestDict('取样类型');
    },
    methods: {
      // 刷新表格
      reload(where = {}) {
        this.$refs.table.reload({
          where,
          ...this.tableQuery
        });
      },
      /* 表格数据源 */
      datasource({ page, limit, where, order }) {
        // 参数
        const body = {
          ...where,
          ...order,
          pageNum: page,
          size: limit,
          ...this.tableQuery
        };
        this.params = body;
        const res = batchRecordPage(body);
        Promise.resolve(res).then((data) => {
          this.tableData = data?.list || data?.records || [];
        });
        return res;
      },
      search(where) {
        this.reload(where);
      },
      goToDetail(row) {
        const path = `/page-qms/inspectionWork/details?id=${row.id}&path=&name=工单`;
        window.history.pushState(null, '', path);
      },
      async handlePrint(key) {
        const printType = this.printTypeMap[key];
        if (!printType) {
          this.$message.warning('暂不支持该打印单据');
          return;
        }
        try {
          const ids = this.getPrintIds();
          if (!ids.length) {
            this.$message.warning('未获取到可打印数据的ID');
            return;
          }
          const res = await queryPrint({ ids, printType });
          const data = this.buildPrintData(res, key);
          if (!data) {
            this.$message.warning('未查询到可打印的质检工单数据');
            return;
          }
          if (this.$refs[key]) {
            this.$refs[key].open(data);
          }
        } catch (error) {
          this.$message.error(error.message || '查询打印数据失败');
        }
      },
      buildPrintData(res, key) {
        const list = this.getPrintList(res, key);
        if (!list.length) {
          return null;
        }

        if (key == 'productInspectionReport') {
          const first = list[0];
          const selected = this.getSelectedItem(first, 0);
          const base = this.buildPrintItem(first, selected);
          return {
            ...base,
            code: selected.code || first.workOrderCode || '',
            date: this.formatPrintDate(
              this.getValue(
                first.createTime,
                selected.qualityTime,
                selected.createTime
              )
            ),
            reporter: selected.qualityName || selected.createUserName || '',
            receiver: selected.reviewerName || selected.checkerName || '',
            department: selected.departmentName || selected.workshopName || '',
            items: list.map((item, index) =>
              this.buildPrintItem(
                item,
                this.getSelectedItem(item, index),
                index
              )
            )
          };
        }

        const data = list.map((item, index) => {
          const selected = this.getSelectedItem(item.basicInfo || item, index);
          return key == 'samplingForm'
            ? this.buildSamplingFormData(item, selected)
            : this.buildFinishedProductRecordData(item, selected);
        });
        return data.length == 1 ? data[0] : data;
      },
      getPrintList(res, key) {
        const listMap = {
          productInspectionReport: 'productInspectionReportList',
          samplingForm: 'samplingSlipList',
          finishedProductOriginalRecord: 'finishedProductInspectionRecordList'
        };
        const listKey = listMap[key];
        if (Array.isArray(res?.[listKey])) {
          return res[listKey];
        }
        if (Array.isArray(res)) {
          return res;
        }
        return [];
      },
      getPrintRows() {
        return this.selection.length ? this.selection : this.tableData;
      },
      getPrintIds() {
        return [
          ...new Set(
            this.getPrintRows()
              .map((item) => item.id)
              .filter((id) => this.hasValue(id))
          )
        ];
      },
      getSelectedItem(item = {}, index = 0) {
        const printRows = this.getPrintRows();
        return (
          printRows.find(
            (row) =>
              (this.hasValue(item.id) && row.id == item.id) ||
              (this.hasValue(item.workOrderCode) &&
                row.workOrderCode == item.workOrderCode) ||
              (this.hasValue(item.produceBatch) &&
                row.batchNo == item.produceBatch)
          ) ||
          printRows[index] ||
          printRows[0] ||
          {}
        );
      },
      buildSamplingFormData(item, selected) {
        return {
          ...selected,
          ...item,
          productName: this.getValue(
            item.materialName,
            selected.productName,
            selected.materialName,
            selected.name
          ),
          specification: this.getValue(
            item.specModel,
            selected.specification,
            selected.productModel
          ),
          batchNo: this.getValue(
            item.produceBatch,
            item.batch,
            selected.batchNo
          ),
          sampleSource: this.getValue(
            selected.sampleSource,
            selected.sourceTypeDesc,
            selected.sourceCode,
            selected.workOrderCode
          ),
          sampleLocation: this.getValue(
            selected.samplePlace,
            selected.sampleLocation
          ),
          sampleDate: this.formatPrintDate(
            this.getValue(
              item.createTime,
              selected.qualityTime,
              selected.createTime
            )
          ),
          batchQuantity: this.hasValue(item.batch)
            ? item.batch
            : this.buildQuantityText(item.quantityVerified, item.unit),
          sampleQuantity: this.buildQuantityText(
            this.getValue(item.quantity, selected.sampleQuantity),
            item.unit
          ),
          sampler: this.getValue(
            selected.sampleUserName,
            selected.qualityName,
            selected.createUserName
          ),
          checker: this.getValue(
            selected.checkerName,
            selected.reviewerName,
            selected.approvalUserName
          ),
          remark: this.getValue(item.remark, selected.remark)
        };
      },
      buildFinishedProductRecordData(item, selected) {
        const basicInfo = item.basicInfo || {};
        const detailList = Array.isArray(item.detailList)
          ? item.detailList
          : [];
        const inspectionItems = detailList.map((detail) => ({
          ...detail,
          name: detail.inspectionItem || '',
          standard: detail.standardRequirement || '',
          result: detail.inspectionResult || '',
          conclusion: ''
        }));
        return {
          ...selected,
          ...basicInfo,
          productName: this.getValue(
            basicInfo.productName,
            selected.productName,
            selected.name
          ),
          productCode: this.getValue(
            selected.productCode,
            selected.materialCode
          ),
          specification: this.getValue(
            basicInfo.specModel,
            selected.specification,
            selected.productModel
          ),
          packageSpec: basicInfo.packageSpec || '',
          batchNo: this.getValue(basicInfo.produceBatch, selected.batchNo),
          sterilizationBatchNo: basicInfo.sterilizationBatch || '',
          submitQuantity: this.getValue(
            basicInfo.productQuantity,
            selected.submitQuantity
          ),
          sampleQuantity: this.getValue(
            basicInfo.samplingQuantity,
            selected.sampleQuantity
          ),
          inspectionBasis: this.getValue(
            basicInfo.inspectionBasis,
            selected.inspectionBasis
          ),
          inspectionDate: this.formatPrintDate(
            this.getValue(
              basicInfo.reportDate,
              basicInfo.productionDate,
              basicInfo.createTime,
              selected.qualityTime
            )
          ),
          appearanceItems: inspectionItems,
          performanceItems: [],
          packagingItems: [],
          conclusion: this.getValue(
            selected.conclusion,
            selected.inspectionResult
          ),
          inspector: this.getValue(
            selected.qualityName,
            selected.createUserName
          ),
          checker: this.getValue(selected.checkerName, selected.reviewerName),
          remark: selected.remark || ''
        };
      },
      buildPrintItem(item, selected = {}, index = 0) {
        return {
          ...item,
          seq: index + 1,
          productCode: item.materialCode || selected.productCode || '',
          productName:
            item.productName ||
            item.materialName ||
            selected.productName ||
            selected.name ||
            '',
          materialCode: item.materialCode || '',
          materialName: item.materialName || '',
          specification:
            [item.specification, item.modelType].filter(Boolean).join('/') ||
            item.specModel ||
            selected.specification ||
            '',
          sterilizationBatchNo:
            item.sterilizationBatch || selected.sterilizationBatchNo || '',
          productionBatchNo: item.produceBatch || selected.batchNo || '',
          batchNo: item.produceBatch || item.batch || selected.batchNo || '',
          unit: item.unit || selected.unit || '',
          quantity: this.getValue(item.quantity, selected.quantity),
          processOrderCode:
            item.workOrderCode ||
            selected.workOrderCode ||
            selected.sourceCode ||
            '',
          inspectionCode: selected.code || ''
        };
      },
      buildQuantityText(quantity, unit) {
        if (!this.hasValue(quantity)) {
          return '';
        }
        return `${quantity}${unit || ''}`;
      },
      hasValue(value) {
        return value !== undefined && value !== null && value !== '';
      },
      getValue(...values) {
        const value = values.find((item) => this.hasValue(item));
        return value === undefined ? '' : value;
      },
      formatPrintDate(value) {
        if (!this.hasValue(value)) {
          return '';
        }
        const source = value;
        if (typeof source == 'string') {
          return source.slice(0, 10);
        }
        if (this.$util?.toDateString) {
          return this.$util.toDateString(source, 'yyyy-MM-dd');
        }
        return new Date(source).toISOString().slice(0, 10);
      }
    }
  };
</script>

<style></style>
