Newer
Older
xc-business-system / src / views / quality / internal / workManage / components / addFileDialog.vue
liyaguang on 17 Nov 2023 6 KB feat(*): 内部审核计划调试
<!-- 添加文件弹窗 -->
<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'
const emits = defineEmits(['confirm'])
const dataFormRef = ref()
const dialogFormVisible = ref(false) // 对话框是否显示
// 表单
const areaForm = ref({
  fileType: '',
  fileCode: '',
  fileName: '',
  filePath: '',
})
// 附件名称
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'] }],
}
// 重置表单
const resetForm = () => {
  areaForm.value = {
    fileType: '',
    fileCode: '',
    fileName: '',
    filePath: '',
  }
  uploadName.value = ''
}
// 获取字典
const fileTypeList = ref<{ id: string; value: string; name: string }[]>([])
const fetchDict = () => {
  getDictByCode('auditManagementFileType').then((res) => {
    fileTypeList.value = res.data
  })
}
fetchDict()
// 保存按钮
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,
        createTime: dayjs().format('YYYY-MM-DD hh:mm'),
      })
      dialogFormVisible.value = false
    }
  })
}
// 初始化对话框
const initDialog = (row: any = {}) => {
  dialogFormVisible.value = true
  resetForm()
  nextTick(() => {
    dataFormRef.value?.clearValidate()
  })
  if (row.fileType) {
    areaForm.value = row
    // 展示上传文件名称
    const data = row.filePath.split('/')
    uploadName.value = data[data.length - 1]
  }
}
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]
        })
      }
    })
  }
}
// 导入
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" style="width: 100%;" />
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="文件名称" prop="fileName">
            <el-input v-model="areaForm.fileName" style="width: 100%;" />
          </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">
              {{ areaForm.filePath }}
              <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>