Newer
Older
xc-business-system / src / views / business / taskMeasure / measureData / components / templateFormAndTable.vue
<!-- 检定数据管理详情表单和表格模板 -->
<script lang="ts" setup name="MeasureDataTemplateDetail">
import { ref } from 'vue'
import { ElLoading, ElMessage } from 'element-plus'
import dayjs from 'dayjs'
import selectStandard from '../dialog/selectStandardDialog.vue'
import type { ITempelateForm } from '../measureData-interface'
import useUserStore from '@/store/modules/user'
import { getDictByCode } from '@/api/system/dict'
import type { dictType } from '@/global'
import type { TableColumn } from '@/components/NormalTable/table_interface'
import { getEquipmentList } from '@/api/equipment/standard/book'
import { useUniqueArray } from '@/utils/useUniqueArray'
import { getClassificationList } from '@/api/business/measure/classification'
import { getLocationList } from '@/api/business/taskMeasure/measureData'

const props = defineProps({
  infoId: String, // id
  dataNo: String, // 检定数据编号
  pageType: { // 页面类型
    type: String,
    default: 'detail',
  },
})
const emits = defineEmits(['giveInfoId'])
const user = useUserStore() // 用户信息
const $router = useRouter() // 关闭页面使用
const $route = useRoute() // 路由参数
const ruleFormRef = ref() // 表单ref
const form = ref<ITempelateForm>({
  dataNo: '', // 检定数据编号
  measureCategory: '', // 检校类别
  measureCategoryName: '', // 检校类别名称
  customerName: '', // 委托单位
  traceDate: '', // 测试、校准或检定日期
  measureValidDate: '', // 检定有效期
  measureAddress: '', // 测试、校准或检定地点
  temperature: '', // 温度
  humidity: '', // 相对湿度
  orderId: '', // 任务单id
  orderNo: '', // 任务单编号
  technologyFile: '', // 依据的技术文件(编号、名称)
  createUserId: '', // 检定员id
  createUserName: '', // 检定员
  dataSource: '', // 数据来源
  conclusion: '', // 结论
  restrictionInstruction: '', // 限用说明

  itemCategoryName: '', // 检定项分类名称
  itemCategoryId: '', // 检定项分类id
})
const validateHumidity = (rule: any, value: any, callback: any) => {
  const type = rule.field === 'humidity' ? '相对湿度' : '温度'
  const reg = /(^-?\d\d*\.\d*$)|(^-?\d\d*$)|(^-?\.\d\d*$)/
  if (!reg.test(value)) {
    callback(new Error(`${type}只能为数字`))
  }
  if (!value && value?.length) {
    callback(new Error(`${type}不能为空`))
  }
  else {
    if (Number(value) > 100) {
      callback(new Error(`${type}不能大于100`))
    }
    callback()
  }
}
// 校验规则
const rules = ref({
  measureCategory: [{ required: true, message: '检校类别不能为空', trigger: ['blur', 'change'] }],
  // customerName: [{ required: true, message: '委托单位不能为空', trigger: ['blur', 'change'] }],
  traceDate: [{ required: true, message: '测试、校准或检定日期不能为空', trigger: ['blur', 'change'] }],
  measureValidDate: [{ required: true, message: '检定有效期不能为空', trigger: ['blur', 'change'] }],
  measureAddress: [{ required: true, message: '测试、校准或检定地点不能为空', trigger: ['blur', 'change'] }],
  temperature: [{ required: true, validator: validateHumidity, trigger: ['blur', 'change'] }],
  humidity: [{ required: true, validator: validateHumidity, trigger: ['blur', 'change'] }],
  // orderNo: [{ required: true, message: '任务单编号不能为空', trigger: ['blur', 'change'] }],
  // technologyFile: [{ required: true, message: '依据的技术文件不能为空', trigger: ['blur', 'change'] }],
  createUserName: [{ required: true, message: '检定员不能为空', trigger: ['blur', 'change'] }],
  conclusion: [{ required: true, message: '结论不能为空', trigger: ['blur', 'change'] }],
  restrictionInstruction: [{ required: true, message: '限用说明不能为空', trigger: ['blur', 'change'] }],
  appearanceFunctionCheck: [{ required: true, message: '外观及功能性检查不能为空', trigger: ['blur', 'change'] }],
})

// -------------------------------------------字典---------------------------------------------+
const conclusionList = ref<dictType[]>([]) // 结论
const measureCategoryList = ref<dictType[]>([]) // 检校类别
const positionList = ref([]) as any // 测试、校准或检定地点

// 获取字典值
async function getDict() {
  // 结论
  getDictByCode('bizConclusion').then((response) => {
    conclusionList.value = response.data
  })
  // 检校类别
  getDictByCode('measureCategory').then((response) => {
    measureCategoryList.value = response.data
  })

  // 测试、校准或检定地点
  getLocationList({
    locationName: '', // 地点名称
    locationNo: '', // 地点编号
    limit: 999999,
    offset: 1,
  }).then((res) => {
    positionList.value = res.data.rows.map((item: { id: string; locationName: string; temperature: string; humidity: string }) => {
      return {
        id: item.id,
        name: item.locationName, // 地点名称
        temperature: `${item.temperature}` || '', // 温度
        humidity: `${item.humidity}` || '', // 湿度
      }
    })
  })
}

// --------------------------------------被检件信息--------------------------------------------------------
const sampleList = ref([]) as any // 被检件
const columns = ref<TableColumn[]>([ // 表头
  { text: '设备名称', value: 'sampleName', align: 'center' },
  { text: '规格型号', value: 'sampleModel', align: 'center' },
  { text: '出厂编号', value: 'manufactureNo', align: 'center' },
  { text: '制造厂家', value: 'manufacturer', align: 'center' },
  { text: '设备检定项分类', value: 'categoryName', align: 'center' },
])
// --------------------------------------所使用的标准,主要测量设备--------------------------------------------------------
const measureEquipmentList = ref([]) as any // 列表
const selectStandardRef = ref() // 所使用的标准,主要测量设备组件ref
const checkoutMeasureDataCalibratorList = ref([]) as any // 选中列表
const tableLoading = ref(false) // 表格loading
const measureDataCalibratorColumns = ref<TableColumn[]>([ // 表头
  { text: '设备名称', value: 'equipmentName', align: 'center' },
  { text: '规格型号', value: 'model', align: 'center' },
  { text: '出厂编号', value: 'manufactureNo', align: 'center' },
  { text: '不确定度或允许误差极限或准确度等级', value: 'uncertainty', align: 'center' },
  { text: '证书有效期', value: 'measureValidDate', align: 'center' },
])

// 用标准装置id获取标准配套设备查询条件
const listQuery = ref({
  standardId: '',
  offset: 1,
  limit: 999999,
})

// 批量增加
const multiFilesAdd = () => {
  selectStandardRef.value.initDialog()
}

// 选好标准装置
const confirmSelectStandard = (val: any) => {
  if (val.length) {
    const allRequest = [] as any // 所有的请求
    let tempEquipmentList = [] as any // 临时变量-选择的标准装置所对应的配套设备
    val.forEach((item: { id: string }) => {
      tableLoading.value = true // 表格loading
      listQuery.value.standardId = item.id // 标准装置id
      const request = getEquipmentList(listQuery.value).then((res) => { // 请求
        const tempArr = [] as any
        res.data.rows.forEach((item: any) => {
          if (!item.technicalTargetList.length) {
            tempArr.push(item)
          }
          else {
            let tempUncertainty = ''
            item.technicalTargetList.forEach((i: any) => {
              tempUncertainty = `${tempUncertainty}${i.uncertainty}; `
            })
            tempArr.push({
              ...item,
              uncertainty: tempUncertainty,
            })
          }
        })
        tempEquipmentList = tempEquipmentList.concat(tempArr)
      })
      allRequest.push(request) // 集合所有请求
    })
    Promise.all(allRequest).then(() => { // 等待所有请求完成
      let tempList = [] as any // 临时数组
      tempList = tempList.concat(tempEquipmentList)
      measureEquipmentList.value = useUniqueArray(tempList) // 数组去重
      tableLoading.value = false
    })
  }
}

// 表格多选
const handleSelectionChange = (e: any) => {
  checkoutMeasureDataCalibratorList.value = e
}

// 删除行
const delRow = () => {
  if (checkoutMeasureDataCalibratorList.value.length <= 0) {
    ElMessage({
      message: '请选中要删除的行',
      type: 'warning',
    })
  }
  else {
    checkoutMeasureDataCalibratorList.value.forEach((item: any) => {
      measureEquipmentList.value.forEach((element: any, index: number) => {
        if (element.equipmentNo === item.equipmentNo) {
          measureEquipmentList.value.splice(index, 1)
        }
      })
    })
  }
}
// ----------------------------------------查询依据的技术文件--------------------------------------
// 获取检定项分类的技术文件
// 查询条件
const fetchClassificationListQuery = ref({
  belongStandardEquipment: '', // 检校标准装置
  categoryName: '', // 检定项分类名称
  categoryNo: '', // 检定项分类编号
  deviceType: '', // 设备分类
  measureCategory: '', // 检校类别
  limit: 20,
  offset: 1,
})

// 数据查询
function fetchClassificationData(isNowPage = false, categoryName = '', belongStandardEquipment = '') {
  if (!isNowPage) {
    // 是否显示当前页,否则跳转第一页
    listQuery.value.offset = 1
  }
  fetchClassificationListQuery.value.categoryName = categoryName // 设备分类型名称
  fetchClassificationListQuery.value.belongStandardEquipment = belongStandardEquipment // 检校标准装置名称
  getClassificationList(fetchClassificationListQuery.value).then((response) => {
    if (response.data.rows.length) {
      form.value.technologyFile = response.data.rows[0].technologyFile.split(';')
    }
  })
}

// ----------------------------------------校验------------------------------------------------
const checkout = () => {
  if (!measureEquipmentList.value.length) {
    ElMessage.warning('所使用的标准,主要测量设备不能为空')
    return false
  }
  return true
}

// -------------------------------------地点变化事件--------------------------------------------
const handleChangeAddress = (id: string) => {
  if (id) {
    const index = positionList.value.findIndex((item: { id: string }) => item.id === id)
    if (index !== -1) {
      form.value.temperature = positionList.value[index].temperature
      form.value.humidity = positionList.value[index].humidity
    }
  }
}

// -----------------------------------------钩子-----------------------------------------------
// watch(() => props.infoId, (newValue) => {
//   if (newValue) {
//     infoId.value = newValue
//     // fetchInfo()
//   }
// }, { immediate: true })

watch(() => props.dataNo, (newValue) => {
  if (newValue) {
    form.value.dataNo = newValue
  }
}, { immediate: true })

onMounted(async () => {
  getDict().then(() => {
    if (props.pageType === 'add') { // 从我的任务跳转过来(新增)
      form.value.orderId = $route.query.orderId as string // 任务单id
      form.value.orderNo = $route.query.orderNo as string // 任务单编号
      form.value.customerName = $route.query.customerName as string // 委托单位
      form.value.traceDate = dayjs().format('YYYY-MM-DD') // 测试校准检定日期默认今天
      form.value.measureValidDate = `${dayjs().add(Number($route.query.checkCycle), 'month').subtract(1, 'day')}` // 检定有效期--今天 + 检定周期 - 1天
      form.value.measureValidDate = dayjs(form.value.measureValidDate).format('YYYY-MM-DD')
      form.value.createUserName = user.name // 检定员
      form.value.itemId = $route.query.itemId as string// 检定项id
      form.value.itemCategoryName = $route.query.itemCategoryName as string// 设备检定项分类名称
      form.value.itemCategoryId = $route.query.itemCategoryId as string// 设备检定项分类名称id
      form.value.belongStandardEquipment = $route.query.belongStandardEquipment as string// 标准装置code
      form.value.belongStandardEquipmentName = $route.query.belongStandardEquipmentName as string// 标准装置名称
      sampleList.value = [{ // 被检设备
        sampleId: $route.query.sampleId, // 设备id
        sampleName: $route.query.sampleName, // 设备名称
        sampleModel: $route.query.sampleModel, // 规格型号
        manufactureNo: $route.query.manufactureNo, // 出厂编号
        manufacturer: $route.query.manufacturer, // 制造厂家(生产厂家)
        categoryName: $route.query.itemCategoryName, // 设备检定项分类
      }]
      form.value.itemCategoryName = $route.query.itemCategoryName as string // 设备检定项分类名称
      // 查依据的技术文件(编号、名称)
      fetchClassificationData(false, $route.query.itemCategoryName! as string, $route.query.belongStandardEquipment as string)
    }
    else {
      form.value.itemCategoryName = $route.query.itemCategoryName as string// 设备检定项分类名称
      form.value.itemCategoryId = $route.query.itemCategoryId as string// 设备检定项分类名称id
      form.value.belongStandardEquipment = $route.query.belongStandardEquipment as string || ''// 标准装置code
      form.value.belongStandardEquipmentName = $route.query.belongStandardEquipmentName as string || ''// 标准装置名称
    }
  })
})

watch(() => form.value.itemCategoryName, (newValue) => {
  if (newValue) {
    // 查依据的技术文件(编号、名称)
    fetchClassificationData(false, $route.query.itemCategoryName! as string, $route.query.belongStandardEquipment as string)
  }
})

defineExpose({ form, measureEquipmentList, ruleFormRef, sampleList, checkout })
</script>

<template>
  <div class="templateFormAndTable">
    <!-- 表单  -->
    <detail-block title="">
      <el-form
        ref="ruleFormRef"
        :model="form"
        label-width="180"
        label-position="right"
        :rules="rules"
      >
        <el-row :gutter="24">
          <el-col :span="8">
            <el-form-item label="检定数据编号:" prop="dataNo">
              <el-input v-model="form.dataNo" disabled placeholder="系统自动生成" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="检校类别:" prop="measureCategory">
              <el-select
                v-model="form.measureCategory"
                placeholder="检校类别"
                filterable
                :disabled="pageType === 'detail'"
                class="full-width-input"
              >
                <el-option v-for="item in measureCategoryList" :key="item.id" :label="item.name" :value="item.value" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="委托单位:" prop="customerName">
              <el-input v-model="form.customerName" disabled :placeholder="pageType === 'detail' ? ' ' : '系统自动生成'" />
            </el-form-item>
          </el-col>

          <el-col :span="8">
            <el-form-item label="测试、校准或检定日期:" prop="traceDate">
              <el-date-picker
                v-model="form.traceDate"
                type="date"
                format="YYYY-MM-DD"
                value-format="YYYY-MM-DD"
                :placeholder="pageType === 'detail' ? ' ' : '请选择日期'"
                :disabled="pageType === 'detail'"
                class="full-width-input"
              />
            </el-form-item>
          </el-col>

          <el-col :span="8">
            <el-form-item label="检定有效期:" prop="measureValidDate">
              <el-date-picker
                v-model="form.measureValidDate"
                type="date"
                format="YYYY-MM-DD"
                value-format="YYYY-MM-DD"
                :placeholder="pageType === 'detail' ? ' ' : '请选择日期'"
                :disabled="pageType === 'detail'"
                class="full-width-input"
              />
            </el-form-item>
          </el-col>

          <el-col :span="8">
            <el-form-item label="测试、校准或检定地点:" prop="measureAddress">
              <el-select
                v-model="form.measureAddress"
                placeholder="测试、校准或检定地点"
                filterable
                :disabled="pageType === 'detail'"
                class="full-width-input"
                @change="handleChangeAddress"
              >
                <el-option v-for="item in positionList" :key="item.id" :label="item.name" :value="item.id" />
              </el-select>
            </el-form-item>
          </el-col>

          <el-col :span="8">
            <el-form-item label="温度(℃):" prop="temperature">
              <el-input v-model="form.temperature" :disabled="pageType === 'detail'" :placeholder="pageType === 'detail' ? ' ' : '请输入温度'" />
            </el-form-item>
          </el-col>

          <el-col :span="8">
            <el-form-item label="相对湿度(%):" prop="humidity">
              <el-input v-model="form.humidity" :disabled="pageType === 'detail'" :placeholder="pageType === 'detail' ? ' ' : '请输入相对湿度'" />
            </el-form-item>
          </el-col>

          <el-col :span="8">
            <el-form-item label="任务单编号:" prop="orderNo">
              <el-input v-model="form.orderNo" disabled placeholder="任务单编号" />
            </el-form-item>
          </el-col>

          <el-col :span="8">
            <el-form-item label="检定员:" prop="dacreateUserNametaNo">
              <el-input v-model="form.createUserName" disabled placeholder="检定员" />
            </el-form-item>
          </el-col>

          <el-col :span="8">
            <el-form-item label="数据来源:" prop="dataSource">
              <el-input v-model="form.dataSource" disabled placeholder="数据来源" />
            </el-form-item>
          </el-col>

          <el-col :span="8">
            <el-form-item label="结论:" prop="conclusion">
              <el-select
                v-model="form.conclusion"
                placeholder="请选择结论"
                filterable
                :disabled="pageType === 'detail'"
                class="full-width-input"
              >
                <el-option v-for="item in conclusionList" :key="item.id" :label="item.name" :value="item.value" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col v-if="form.conclusion === '除*外其余所检项目合格'" :span="16">
            <el-form-item label="限用说明:" prop="restrictionInstruction">
              <el-input v-model="form.restrictionInstruction" type="textarea" autosize :disabled="pageType === 'detail'" placeholder="请输入限用说明" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="24" class="marg">
          <el-col :span="24">
            <el-form-item label="依据的技术文件:" prop="technologyFile">
              <div v-for="(item, index) in form.technologyFile" :key="index" style="display: flex;">
                <show-photo :minio-file-name="item" style="margin-right: 10px;" />
              </div>
              <span v-if="pageType === 'detail' && !form.technologyFile">无</span>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
    </detail-block>
    <!-- 被检件信息 -->
    <detail-block title="被检件信息">
      <el-table
        :data="sampleList"
        border
        style="width: 100%;"
      >
        <el-table-column align="center" label="序号" width="80" type="index" />
        <el-table-column
          v-for="item in columns"
          :key="item.value"
          :prop="item.value"
          :label="item.text"
          align="center"
        />
      </el-table>
    </detail-block>

    <detail-block title="所使用的标准,主要测量设备">
      <template v-if="pageType !== 'detail'" #btns>
        <el-button type="primary" @click="multiFilesAdd">
          批量添加
        </el-button>
        <el-button type="info" @click="delRow">
          删除行
        </el-button>
      </template>
      <el-table
        v-loading="tableLoading"
        :data="measureEquipmentList"
        border
        style="width: 100%;"
        @selection-change="handleSelectionChange"
      >
        <el-table-column
          v-if="pageType !== 'detail'"
          type="selection"
          width="38"
        />
        <el-table-column align="center" label="序号" width="80" type="index" />
        <el-table-column
          v-for="item in measureDataCalibratorColumns"
          :key="item.value"
          :prop="item.value"
          :label="item.text"
          :width="item.width"
          align="center"
        />
      </el-table>
    </detail-block>
  </div>

  <!-- 选择标准装置组件 -->
  <select-standard ref="selectStandardRef" :is-multi="true" @confirm="confirmSelectStandard" />
</template>

<style lang="scss" scoped>
.setBottom {
  padding-bottom: 20px;
}
</style>

<style lang="scss">
.templateFormAndTable {
  .el-radio__label {
    display: block !important;
  }
}
</style>