Newer
Older
xc-business-system / src / views / quality / review / work / components / addFileDialog.vue
<!-- 添加文件弹窗 -->
<script lang="ts" setup name="EditArea">
import type { Ref } from 'vue'
import { defineExpose, nextTick, reactive, ref } from 'vue'
import type { FormInstance, FormRules } from 'element-plus'
import { ElMessage, ElMessageBox } from 'element-plus'
import dayjs from 'dayjs'
import { getDictByCode } from '@/api/system/dict'
import { UploadFile, getPhotoUrl } from '@/api/file'
import { getSearchDept } from '@/api/quality/supervise/record'
const emits = defineEmits(['confirm'])
const dataFormRef = ref()
const dialogFormVisible = ref(false) // 对话框是否显示
// 表单
const areaForm = ref({
  fileTypeName: '',
  fileType: '',
  fileName: '',
  fileCode: '',
  bizLabCode: '',
  bizLabCodeName: '',
  deptId: '',
  deptName: '',
  createTime: '',
  filePath: '',
  handlerType: '',
  handlerIndex: '',
})
// 附件名称
const uploadName = ref('')
// 前端校验规则
const rules: FormRules = {
  fileType: [{ required: true, message: '文件类型必选', trigger: ['blur', 'change'] }],
  fileName: [{ required: true, message: '文件名称必填', trigger: ['blur', 'change'] }],
  filePath: [{ required: true, message: '附件必须上传', trigger: ['blur', 'change'] }],
  fileCode: [{ required: true, message: '文件编号必填', trigger: ['blur', 'change'] }],
  bizLabCode: [{ required: true, message: '实验室必选', trigger: ['blur', 'change'] }],
  deptId: [{ required: true, message: '部门必须按', trigger: ['blur', 'change'] }],
}
// 重置表单
const resetForm = () => {
  areaForm.value = {
    fileTypeName: '',
    fileType: '',
    fileName: '',
    fileCode: '',
    bizLabCode: '',
    bizLabCodeName: '',
    deptId: '',
    deptName: '',
    createTime: '',
    filePath: '',
    handlerType: '',
    handlerIndex: '',
  }
  uploadName.value = ''
}
// 获取字典
const fileTypeList = ref<{ id: string; value: string; name: string }[]>([])
const deptList = ref<{ deptName: string; deptId: string }[]>([]) // 部门列表
const labelList = ref<{ id: string; value: string; name: string }[]>([])// 实验室
const fetchDict = () => {
  getDictByCode('qualityManagementReviewFileType').then((res) => {
    fileTypeList.value = res.data
  })
  // 获取实验室字典
  getDictByCode('bizLabCode').then((res) => {
    labelList.value = res.data
  })
  // 部门
  getSearchDept({ labCode: '' }).then((res) => {
    deptList.value = res.data
  })
}
fetchDict()
const flag = ref(true)
watch(() => areaForm.value.bizLabCode, (newVal) => {
  if (flag.value) {
    return
  }
  if (newVal) {
    areaForm.value.deptId = ''
    getSearchDept({ labCode: newVal }).then((res) => {
      deptList.value = res.data
    })
  }
  else {
    getSearchDept({ }).then((res) => {
      deptList.value = res.data
    })
  }
}, {
  deep: true,
})
// 保存按钮
const saveForm = async (formEl: FormInstance | undefined) => {
  if (!formEl) { return }
  await formEl.validate((valid, fields) => {
    if (valid) {
      emits('confirm', {
        ...areaForm.value,
        fileTypeName: fileTypeList.value.filter(item => item.value === areaForm.value.fileType)[0].name,
        bizLabCodeName: labelList.value.filter(item => item.value === areaForm.value.bizLabCode)[0].name,
        deptName: deptList.value.filter(item => item.deptId === areaForm.value.deptId)[0].deptName,
        createTime: dayjs().format('YYYY-MM-DD hh:mm'),
        handlerType: areaForm.value.handlerType ? areaForm.value.handlerType : 'add',
        handlerIndex: areaForm.value.handlerType ? areaForm.value.handlerIndex : '',
      })
      dialogFormVisible.value = false
    }
  })
}
// 初始化对话框
const initDialog = (row: any = {}) => {
  if (!flag.value) {
    flag.value = true
  }
  dialogFormVisible.value = true
  resetForm()
  nextTick(() => {
    dataFormRef.value?.clearValidate()
  })
  if (row.fileTypeName) {
    areaForm.value = row
    // 展示上传文件名称
    const data = row.filePath.split('/')
    uploadName.value = data[data.length - 1]
    areaForm.value.handlerType = 'update'
    areaForm.value.handlerIndex = row.handlerIndex
  }
  setTimeout(() => {
    flag.value = false
  }, 500)
}
defineExpose({
  initDialog,
})

const cancel = () => {
  dialogFormVisible.value = false
  // this.$emit('watchChild')
}
// 上传附件
const fileRef = ref() // 文件上传input,获取input的引用
const onFileChange = (event: any) => {
  // 原生上传
  if (event.target.files?.length !== 0) {
    const fd = new FormData()
    fd.append('multipartFile', event.target.files[0])
    UploadFile(fd).then((res1) => {
      fileRef.value.value = ''
      if (res1.code === 200) {
        ElMessage.success('上传成功')
        getPhotoUrl(res1.data[0]).then((res) => {
          areaForm.value.filePath = res.data
          // 展示上传文件名称
          const data = res.data.split('/')
          uploadName.value = data[data.length - 1]
          dataFormRef.value?.clearValidate('filePath')
        })
      }
    })
  }
}
// 导入
const importList = () => {
  fileRef.value.click()
}
// 删除
const close = () => {
  areaForm.value.filePath = ''
}
</script>

<template>
  <el-dialog v-model="dialogFormVisible" title="添加文件" append-to-body width="30%">
    <el-form ref="dataFormRef" :rules="rules" :model="areaForm" label-position="right" label-width="80px">
      <el-row :gutter="24">
        <el-col :span="24">
          <el-form-item label="文件类型" prop="fileType">
            <el-select v-model="areaForm.fileType" placeholder="文件类型">
              <el-option
                v-for="item in fileTypeList"
                :key="item.value"
                :label="item.name"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="文件编号" prop="fileCode">
            <el-input v-model="areaForm.fileCode" placeholder="文件编号" style="width: 100%;" />
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="文件名称" prop="fileName">
            <el-input v-model="areaForm.fileName" placeholder="文件名称" style="width: 100%;" />
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="实验室" prop="bizLabCode">
            <el-select
              v-model="areaForm.bizLabCode"
              placeholder="实验室"
              class="short-input"
              filterable
              style="width: 100%;"
            >
              <el-option v-for="item in labelList" :key="item.id" :label="item.name" :value="item.value" />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="部门" prop="deptId">
            <el-select
              v-model="areaForm.deptId"
              placeholder="部门"
              class="short-input"
              filterable
              style="width: 100%;"
            >
              <el-option v-for="item in deptList" :key="item.deptId" :label="item.deptName" :value="item.deptId" />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="附件" prop="filePath">
            <!-- <el-input-number v-model="areaForm.fileName" style="width: 100%;" /> -->
            <a class="link" :href="areaForm.filePath" type="primary" style="margin-right: 10px;" target="_blank">
              {{ uploadName }}
              <span v-if="!$route.path.includes('detail')" class="close" @click.stop.capture.prevent="close">x</span>
            </a>
            <el-button v-if="!areaForm.filePath" type="primary" @click="importList">
              上传
            </el-button>
            <input ref="fileRef" style="display: none;" type="file" accept=".doc,.docx,.pdf,.xls,.xlsx" @change="onFileChange">
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-button type="primary" @click="saveForm(dataFormRef)">
          保存
        </el-button>
        <el-button @click="cancel">
          取消
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<style lang="scss" scoped>
.el-dialog {
  width: 700px;
}

.el-select {
  width: 100%;
}

.link {
  position: relative;
  color: #5d93ff;
  // display: inline-block;
  font-size: 16px;
  text-decoration: none;
  // margin-right: 10px;
  padding-right: 10px;
  // height: 33px;
  line-height: 33px;

  &:hover {
    text-decoration: underline;

    .close {
      display: block;
    }
  }

  .close {
    position: absolute;
    top: -20px;
    right: -10px;
    display: none;
    z-index: 99;
    height: 40px;
    width: 40px;
    color: rgb(121 118 115);
    // background-color: #ccc;
    text-align: center;
  }
  // &::before {
  //   content: "x";
  //   width: 15px;
  //   height: 15px;
  //   position: absolute;
  //   right: -4px;
  //   top: -16px;
  //   color: #817d7d;
  //   font-size: 16px;
  //   // background-color: #ccc;
  //   // border-radius: 50%;
  //   display: none;
  // }

  // &:hover {
  //   &::before {
  //     display: block;
  //   }
  // }
}
</style>