Newer
Older
xc-business-system / src / views / equipement / resume / encasement / edit.vue
<!-- 设备装箱详情 -->
<script lang="ts" setup name="EquipementResumeEncasementDetail">
import { ref } from 'vue'
import dayjs from 'dayjs'
import { ElLoading, ElMessage } from 'element-plus'
import type { IBoxList, IEquipmentList, IForm } from './encasement-interface'
import { getStaffList } from '@/api/resource/register'
import useUserStore from '@/store/modules/user'
import { getDictByCode } from '@/api/system/dict'
import type { dictType } from '@/global'
import SelectEquipmentDialog from '@/views/business/fieldTest/approve/dialog/selectEquipmentDialog.vue'
import { useCheckList } from '@/commonMethods/useCheckList'
import { useArrayDataUnique } from '@/commonMethods/useArrayDataUnique'
import { useDoubleClickTableRow, useSetAllRowReadable } from '@/commonMethods/useSetAllRowReadable'
import { addResumeEncasementList, getInfo, updateResumeEncasementList } from '@/api/equipment/resume/encasement'
// import type { IOptions } from '@/views/device/standardEquipment/standard_interface'
const user = useUserStore() // 用户信息
const textMap: { [key: string]: string } = {
  edit: '编辑',
  add: '新建',
  detail: '详情',
}// 字典
const $router = useRouter() // 关闭页面使用
const $route = useRoute() // 路由参数
const pageType = ref('add') // 页面类型: add, edit, detail
const infoId = ref('') // 列表id
const ruleFormRef = ref() // 表单ref
const form = ref<IForm>({
  labCode: '', // 实验室
  groupCode: '',	// 部门(字典code)
  groupCodeName: '',	// 部门(字典value)
  formNo: '', // 装箱单编号
  formName: '', // 装箱单名称
  createUserId: '', // 创建人id
  createUserName: '', // 创建人
  createTime: '', // 创建时间
  packingTime: '', // 装箱日期
  transportType: '', // 运输类型
})
// 校验规则
const formRules = ref({
  labCode: [{ required: true, message: '实验室不能为空', trigger: ['blur', 'change'] }],
  groupCode: [{ required: true, message: '部门不能为空', trigger: ['blur', 'change'] }],
  packingTime: [{ required: true, message: '装箱时间不能为空', trigger: ['blur', 'change'] }],
  transportType: [{ required: true, message: '运输类型不能为空', trigger: ['blur', 'change'] }],
})
const isMulti = ref(false) // 是否多选
// -------------------------------------------字典------------------------------------------
const userList = ref<{ [key: string]: string }[]>([]) // 用户列表
const labCodeList = ref<dictType[]>([]) // 实验室
const groupCodeList = ref<dictType[]>([]) // 部门
const transportTypeList = ref<dictType[]>([]) // 运输类型
// 获取字典值
async function getDict() {
  // 实验室
  // getDictByCode('bizLabCode').then((response) => {
  getDictByCode('bizGroupCodeEquipment').then((response) => {
    labCodeList.value = response.data
  })
  // 部门
  getDictByCode('bizGroupCode').then((response) => {
    groupCodeList.value = response.data
  })
  // 运输类型
  getDictByCode('bizTransportType').then((response) => {
    transportTypeList.value = response.data
  })
}
// ----------------------------------路由参数--------------------------------------------
if ($route.params && $route.params.type) {
  pageType.value = $route.params.type as string
  console.log(pageType.value)

  if ($route.params.id) {
    infoId.value = $route.params.id as string
  }
}
// ----------------------------------------包装箱-----------------------------------------------
const list = ref<IBoxList[]>([]) // 装箱内容
const table = ref()
const checkoutEquipment = ref<IBoxList[]>([]) // 选中设备
const columns = [ // 表头
  // { text: '统一编号', value: 'equipmentNo', align: 'center', required: true },
  { text: '设备名称', value: 'equipmentName', align: 'center', required: true },
  { text: '规格型号', value: 'model', align: 'center', required: true },
  { text: '出厂编号', value: 'equipmentNo', align: 'center', required: true },
  { text: '数量', value: 'quantity', align: 'center', required: true },
]
const addObj = {
  id: '', // 更新/删除使用参数
  packageNo: '', //	包装箱号
  packageUser: user.name, //	装箱人
  packingId: '', //	装箱单id
  traceFlag: 0, // 是否是设备溯源任务(1/0)默认否
  checked: false, // 默认不被选中
  packIndex: 1, // 包装箱索引
  attachment: '', // 附件及资料
}

// 检查包装箱列表是否符合规范
const checkPackList = () => {
  list.value.forEach((item) => {
    if (!item.packageNo) {
      ElMessage.warning(`第${item.packIndex}个包装箱的的包装箱号不能为空`)
      // eslint-disable-next-line no-throw-literal
      throw false
    }
    else if (!item.packageUser) {
      ElMessage.warning(`第${item.packIndex}个包装箱的的装箱人不能为空`)
      // eslint-disable-next-line no-throw-literal
      throw false
    }
    else if (!item.equipmentList.length) {
      ElMessage.warning(`第${item.packIndex}个包装箱的的设备不能为空`)
      // eslint-disable-next-line no-throw-literal
      throw false
    }
    else {
      if (!useCheckList(item.equipmentList, columns, `第${item.packIndex}个包装箱`)) {
        // eslint-disable-next-line no-throw-literal
        throw false
      }
    }
  })
}
// 新增包装箱
const add = () => {
  checkPackList()
  list.value.unshift({ ...addObj, packIndex: list.value.length + 1, equipmentList: [] })
}
// 删除包装箱
const del = () => {
  const delArr = list.value.filter(item => item.checked)
  if (!delArr.length) {
    ElMessage.warning('请选中要删除的包装箱')
    return false
  }
  list.value = list.value.filter(item => !item.checked) // 删除
  // 刷新索引
  list.value = list.value.map((item, index) => {
    return {
      ...item,
      packIndex: list.value.length - index,
    }
  })
}

// 点击增加行
const addRow = (index: number) => {
  if (useCheckList(list.value[index].equipmentList, columns, `第${list.value[index].packIndex}个包装箱`)) {
    isMulti.value = false
    useSetAllRowReadable(list.value[index].equipmentList)
    list.value[index].equipmentList.push({
      equipmentId: '', //	设备id(外部设备该字段为空)
      equipmentName: '', //	设备名称
      equipmentNo: '', //	设备编号传出厂编号(编号、名称、型号、数量都要传)
      model: '', //	规格型号
      quantity: '', //	数量
      editable: true,
    })
  }
}
// 点击删除行
const deleteRow = (index: number) => {
  if (!checkoutEquipment.value.length) {
    ElMessage.warning('请选中要删除的行')
    return false
  }
  list.value[index].equipmentList = list.value[index].equipmentList.filter((item: any) => {
    return !checkoutEquipment.value.includes(item)
  })

  // 清除选中
  for (let i = 0; i < table.value.length; i++) {
    table.value[i].clearSelection()
  }
}

// 选中设备
const handleTechSelectionChange = (e: any) => {
  checkoutEquipment.value = e
}

// 双击行
const rowDblclick = (row: IEquipmentList, index: number) => {
  if (pageType.value !== 'detail') {
    useDoubleClickTableRow(row, list.value[index].equipmentList)
  }
}

// -----------------------------------------批量增加设备----------------------------------------
const selectEquipmentDialogRef = ref() // 选择设备编号组件ref
const multiAddIndex = ref(0) // 批量增加索引(第几个包装箱)
// 确定选择设备
const confirmSelectEquipment = (val: any) => {
  if (val.length) {
    val.forEach((item: any) => {
      list.value[multiAddIndex.value].equipmentList.push({
        equipmentId: item.id, // 设备id
        equipmentNo: item.manufactureNo, // 设备编号传出厂编号
        equipmentName: item.equipmentName, // 设备名称
        model: item.model, // 规格型号
        quantity: '', //	数量
        editable: true,
      })
    })
  }
}

// 点击批量增加
const multiAddRow = (index: number) => {
  isMulti.value = true
  multiAddIndex.value = index
  selectEquipmentDialogRef.value.initDialog()
}
// -------------------------------------------按钮----------------------------------------------
// 关闭新增页面的回调
const close = () => {
  $router.back()
}

// 点击编辑按钮
const edit = () => {
  pageType.value = 'edit'
}

// 保存
const save = () => {
  if (!list.value.length) {
    ElMessage.warning('装箱内容不能为空')
    return false
  }

  checkPackList() // 检查装箱内容

  if (!checkArrayPackageNoUnique()) {
    return false
  }

  if (!checkArrayPackageNoUnique()) {
    return false
  }

  if (!checkArrayDataUnique()) {
    return false
  }

  ruleFormRef.value!.validate((valid: boolean) => {
    if (valid) {
      const loading = ElLoading.service({
        lock: true,
        background: 'rgba(255, 255, 255, 0.8)',
      })
      const tempArr = [] as any
      list.value.forEach((item) => {
        if (item.equipmentList.length) {
          item.equipmentList.forEach((i) => {
            tempArr.push({
              ...item,
              ...i,
              traceFlag: item.traceFlag == 1,
              packageNo: item.packageNo, //	包装箱号
              packageUser: item.packageUser, //	装箱人
              attachment: item.attachment, // 附件及资料
            })
          })
        }
      })
      const params = {
        ...form.value,
        id: infoId.value,
        thingList: tempArr,
        formNo: '',
      }
      // 新建
      if (pageType.value === 'add') { // 新建
        addResumeEncasementList(params).then((res) => {
          ElMessage.success('保存成功')
          form.value.formNo = res.data.formNo // 记录表单号
          infoId.value = res.data.id // id
          pageType.value = 'detail'
          loading.close()
        }).catch(() => {
          loading.close()
        })
      }
      // 保存
      else if (pageType.value === 'edit') { // 编辑
        updateResumeEncasementList(params).then((res) => {
          ElMessage.success('保存成功')
          pageType.value = 'detail'
          loading.close()
        }).catch(() => {
          loading.close()
        })
      }
    }
    else {
      console.log('表单校验不通过')
    }
  })
}

// -------------------------------------------获取详情信息--------------------------------------------------
// 获取详情信息
const fetchInfo = () => {
  const loading = ElLoading.service({
    lock: true,
    background: 'rgba(255, 255, 255, 0.8)',
  })
  getInfo({ id: infoId.value }).then((res) => {
    form.value = res.data
    list.value = res.data.detailThingList.map((item: any, index: number) => {
      return {
        ...item,
        packIndex: index + 1,
        traceFlag: item.traceFlag == 1,
        attachment: item.equipmentList[0].attachment, // 附件及资料
      }
    })
    if (pageType.value === 'edit') {
      list.value = list.value.reverse()
    }
    loading.close()
  })
}

// 包装箱号重复
function checkArrayPackageNoUnique() {
  const tempList = list.value
  for (let i = 0; i < tempList.length; i++) {
    for (let j = 0; j < tempList.length; j++) {
      if (i !== j && tempList[i].packageNo === tempList[j].packageNo) {
        ElMessage.warning(`第${i + 1}和第${j + 1}个包装箱的 包装箱号 重复`)
        return false
      }
    }
  }
  return true
}

// 不同的包装箱不能有同一个设备
function checkArrayDataUnique() {
  const compArr = [] as any
  list.value.forEach((item) => {
    if (item.equipmentList.length) {
      item.equipmentList.forEach((i: any) => {
        compArr.push({
          ...i,
          packIndex: item.packIndex, // 包装箱索引
          packageNo: item.packageNo, // 包装箱号
        })
      })
    }
  })
  for (let i = 0; i < compArr.length; i++) {
    for (let j = 0; j < compArr.length; j++) {
      if (i !== j && compArr[i].equipmentId === compArr[j].equipmentId) {
        ElMessage.warning(`第${compArr[i].packIndex}个包装箱,箱号:【${compArr[i].packageNo}】 和 第${compArr[j].packIndex}个包装箱,箱号:【${compArr[j].packageNo}】不能同时含有设备 【${compArr[i].equipmentNo}-${compArr[i].equipmentName}-${compArr[i].model}】`)
        return false
      }
    }
  }
  return true
}

onMounted(async () => {
  getDict().then(() => {
    // await fetchStaffList()
    form.value.createUserId = user.id// 创建人
    form.value.createUserName = user.name // 创建人名字
    form.value.formName = '设备运输装箱清单' // 记录单名称
    form.value.createTime = dayjs().format('YYYY-MM-DD HH-mm:ss')// 创建时间
    if (pageType.value !== 'add') {
      fetchInfo()
    }
    else { // 新建
      form.value.labCode = user.bizLabCode // 实验室
      form.value.groupCode = user.groupNo // 部门名称
    }
  })
})
</script>

<template>
  <div class="resume-encasement">
    <app-container>
      <detail-page :title="`设备运输装箱管理-${textMap[pageType]}`">
        <template #btns>
          <el-button v-if="pageType !== 'detail'" type="primary" @click="save">
            保存
          </el-button>
          <el-button v-if="pageType === 'detail'" type="primary" @click="edit">
            编辑
          </el-button>
          <el-button type="info" @click="close">
            关闭
          </el-button>
        </template>
        <el-form
          ref="ruleFormRef"
          :model="form"
          label-width="120"
          label-position="right"
          :rules="formRules"
        >
          <el-row :gutter="24">
            <el-col :span="6">
              <el-form-item label="文件编号:" prop="formNo">
                <el-input v-model="form.formNo" class="full-width-input" disabled placeholder="系统自动生成" />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="文件名称:" prop="formName">
                <el-input v-model="form.formName" class="full-width-input" disabled placeholder="请输入记录单名称" />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="创建人:" prop="createUserName">
                <el-input
                  v-model="form.createUserName"
                  class="full-width-input"
                  :placeholder="pageType === 'detail' ? '' : '创建人'"
                  disabled
                />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="创建时间:" prop="createTime">
                <el-date-picker
                  v-model="form.createTime"
                  type="datetime"
                  format="YYYY-MM-DD HH:mm:ss"
                  value-format="YYYY-MM-DD HH:mm:ss"
                  class="full-width-input"
                  disabled
                />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="实验室" prop="labCode">
                <el-select v-model="form.labCode" :placeholder="pageType === 'detail' ? ' ' : '请选择实验室'" :disabled="pageType === 'detail'" class="full-width-input">
                  <el-option v-for="item in labCodeList" :key="item.id" :label="item.name" :value="item.value" />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="部门" prop="groupCode">
                <el-select v-model="form.groupCode" :placeholder="pageType === 'detail' ? ' ' : '请选择部门'" :disabled="pageType === 'detail'" class="full-width-input">
                  <el-option v-for="item in groupCodeList" :key="item.id" :label="item.name" :value="item.value" />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="装箱时间:" prop="packingTime">
                <el-date-picker
                  v-model="form.packingTime"
                  type="datetime"
                  format="YYYY-MM-DD HH:mm:ss"
                  value-format="YYYY-MM-DD HH:mm:ss"
                  class="full-width-input"
                  placeholder="请选择装箱时间"
                  :disabled="pageType === 'detail'"
                />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="运输类型:" prop="transportType">
                <el-radio-group v-model="form.transportType" :disabled="pageType === 'detail'">
                  <el-radio label="1">
                    设备出实验室
                  </el-radio>
                  <el-radio label="2">
                    设备回实验室
                  </el-radio>
                </el-radio-group>
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
      </detail-page>
      <detail-block title="装箱内容" style="padding-bottom: 10px;">
        <template v-if="pageType !== 'detail'" #btns>
          <el-button type="primary" @click="add">
            增加包装箱
          </el-button>
          <el-button type="info" @click="del">
            删除包装箱
          </el-button>
        </template>
      </detail-block>
      <detail-block v-for="(item, index) in list" :key="index" title="" style="padding-bottom: 20px;">
        <div style="display: flex;">
          <el-checkbox v-if="pageType !== 'detail'" v-model="item.checked" />
          <div class="step">
            {{ item.packIndex }}
          </div>
        </div>

        <div style="display: flex; justify-content: space-between;align-items: center;">
          <div style="display: flex;align-items: center;margin-bottom: 20px;">
            <div style="display: flex;margin-right: 20px;align-items: center;">
              <span style="white-space: nowrap;margin-right: 10px;">包装箱号:</span>
              <el-input v-model.trim="item.packageNo" class="full-width-input" :disabled="pageType === 'detail'" :placeholder="pageType === 'detail' ? ' ' : '请输入包装箱号'" />
            </div>
            <div style="display: flex;margin-right: 30px;align-items: center;">
              <span style="white-space: nowrap;margin-right: 10px;">装箱人:</span>
              <el-input v-model="item.packageUser" class="full-width-input" :disabled="pageType === 'detail'" :placeholder="pageType === 'detail' ? ' ' : '请输入装箱人'" />
            </div>
            <el-checkbox v-model="item.traceFlag" :disabled="pageType === 'detail'">
              是否是设备溯源任务
            </el-checkbox>
            <div style="display: flex;margin: 0 30px;align-items: center;">
              <span style="white-space: nowrap;margin-right: 10px;">附件及资料:</span>
              <el-input v-model="item.attachment" type="textarea" autosize class="full-width-input" :disabled="pageType === 'detail'" :placeholder="pageType === 'detail' ? ' ' : '请输入附件及资料'" />
            </div>
          </div>
          <div v-if="pageType !== 'detail'">
            <el-button type="primary" @click="multiAddRow(index)">
              批量增加
            </el-button>
            <el-button type="primary" @click="addRow(index)">
              增加行
            </el-button>
            <el-button type="info" @click="deleteRow(index)">
              删除行
            </el-button>
          </div>
        </div>

        <el-table
          ref="table"
          :data="item.equipmentList"
          border
          style="width: 100%;"
          @selection-change="handleTechSelectionChange"
          @row-dblclick="(row: any) => rowDblclick(row, index)"
        >
          <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 columns"
            :key="item.value"
            :prop="item.value"
            :label="item.text"
            align="center"
          >
            <template #header>
              <span v-show="item.required" style="color: red;">*</span><span>{{ item.text }}</span>
            </template>
            <template #default="scope">
              <el-input
                v-if="pageType !== 'detail' && item.value !== 'quantity' && !scope.row.equipmentId"
                v-model="scope.row[item.value]"
                :autofocus="true"
                :placeholder="`${item.text}`"
                class="input"
              />
              <el-input-number
                v-if="pageType !== 'detail' && item.value === 'quantity'"
                v-model="scope.row[item.value]"
                :placeholder="`${item.text}`"
                :min="1"
                :step="1"
                :precision="0"
              />
              <span
                v-if="(pageType !== 'detail' && item.value !== 'quantity' && scope.row.equipmentId) || pageType === 'detail'"
              >{{ scope.row[item.value] }}</span>

              <!-- <span v-if="(!scope.row.editable || pageType === 'detail') || (isMulti && (item.value === 'equipmentNo' || item.value === 'equipmentName' || item.value === 'model'))">{{ scope.row[item.value] }}</span> -->
              <!-- <el-input v-else v-model="scope.row[item.value]" :autofocus="true" :placeholder="`${item.text}`" class="input" /> -->
            </template>
          </el-table-column>
        </el-table>
      </detail-block>
    </app-container>
    <!-- 选择设备台账 -->
    <select-equipment-dialog ref="selectEquipmentDialogRef" :is-multi="true" @confirm="confirmSelectEquipment" />
  </div>
</template>

<style lang="scss" scoped>
.step {
  line-height: 28px;
  font-size: 20px;
  color: #3d7eff;
  font-weight: bold;
  margin-bottom: 5px;
  width: fit-content;
}
</style>

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