Newer
Older
BJgas-metering-front / src / views / person / personEdit.vue
liyaguang on 28 Apr 2023 8 KB feat(*): 人员管理模块完成
<!--
  Description: 人员管理页面
  Author: 李亚光
  Date: 2023-04-23
 -->
<script lang="ts" setup name="personEdit">
import type { FormInstance, FormRules, UploadProps, UploadUserFile } from 'element-plus'
import { ElMessage, ElMessageBox, ElTable } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'
import photograph from './photograph.vue'
import { getDeptTreeList } from '@/api/system/dept'
import { toTreeList } from '@/utils/structure'
import { getDictByCode } from '@/api/system/dict'
import { addPerson, updatePerson, uploadApi } from '@/api/person'
const $route = useRoute()
const $router = useRouter()
const ruleFormRef = ref<FormInstance>() // from组件
const ruleForm: { [key: string]: string | any } = ref({
  workerName: '', // 姓名
  gender: '',
  deptId: '', // 所属部门
  phoneNumber: '', // 联系方式
  workerAvatar: '', // 照片
  idCardNumber: '', // 身份证号
  workerType: '1',
}) // 表单
// 图片地址
const photoUrl = computed(() => {
  return `${import.meta.env.VITE_APP_API_BASEURL}/static/${ruleForm.value.workerAvatar}`
})
const photographRef = ref()
// 身份证号码验证规则
const validateIDcard = (rule: any, value: any, callback: any) => {
  const rr = /^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[X])$)$/
  if (rr.test(value)) {
    callback()
  }
  else {
    callback(new Error('验证失败'))
  }
}
const rules = ref({
  workerName: [{ required: true, message: '姓名不能为空', trigger: 'blur' }],
  gender: [{ required: true, message: '性别不能为空', trigger: 'blur' }],
  deptId: [{ required: true, message: '所属部门不能为空', trigger: 'blur' }],
  phoneNumber: [{ required: true, message: '联系方式不能为空', trigger: 'blur' }],
  idCardNumber: [{ required: true, message: '身份证号码不符合规范', trigger: 'blur', validator: validateIDcard }],
}) // 表单验证规则

// 图片上传请求
const uploadQuarterlyEvaluateFile: any = (file: any) => {
  const fd = new FormData()
  fd.append('file', file.file)
  uploadApi(fd).then((res) => {
    if (res.code === 200) {
      console.log(res.data, '123')
      ElMessage.success('上传成功')
      ruleForm.value.workerAvatar = res.data
    }
  })
}
// 图片上传之前的验证
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
  if (rawFile.type !== 'image/jpeg' && rawFile.type !== 'image/png' && rawFile.type !== 'image/jpg') {
    ElMessage.error('只能上传png/jpeg/jpg格式的图片')
    return false
  }
  else if (rawFile.size / 1024 / 1024 > 2) {
    ElMessage.error('图片不能大于2MB')
    return false
  }
  return true
}
// 拍照功能
const tackPhoto = ref(false)
const register = () => {
  photographRef.value.initDialog()
  tackPhoto.value = true
}
// 关闭摄像头
const offPthot = (url: string) => {
  if (url) {
    ruleForm.value.workerAvatar = url
  }
  tackPhoto.value = false
}
// 提交
const submitForm = async (formEl: FormInstance | undefined) => {
  if (!formEl) { return }
  // 当前选中的证书基本信息列表
  await formEl.validate((valid, fields) => {
    if (valid) {
      ElMessageBox.confirm(
        '确认提交吗?',
        '提示',
        {
          confirmButtonText: '确认',
          cancelButtonText: '取消',
          type: 'warning',
        },
      ).then(() => {
        // 更新或者新增
        ($route.query.type === 'add' ? addPerson(ruleForm.value) : updatePerson(ruleForm.value)).then((res) => {
          if (res.code === 200) {
            ElMessage.success('操作成功')
            $router.go(-1)
          }
        })
      })
    }
  })
}
// 取消
const resetForm = () => {
  $router.go(-1)
}
const deptTreeList = ref([])
// 加载组织机构树形下拉
const fetchDeptTree = () => {
  getDeptTreeList().then((res) => {
    if (res.data) { // 将列表转树结构
      deptTreeList.value = toTreeList(res.data, '0', true)
    }
  })
}
fetchDeptTree()
const sexList = ref<{ id: string; value: string; name: string }[]>()
// 获取性别
const getSexList = () => {
  getDictByCode('sysSex').then((response) => {
    sexList.value = response.data
  })
}
getSexList()
const title = ref('')
onMounted(() => {
  const type = $route.query.type
  if (type === 'update') {
    title.value = '人员编辑'
    const row = JSON.parse($route.query.row as string)
    ruleForm.value = row
  }
  else {
    title.value = '人员新增'
  }
})
</script>

<template>
  <app-container>
    <!-- 拍照组件 -->
    <photograph ref="photographRef" :tack-photo="tackPhoto" @off="offPthot" />
    <detail-page :title="title">
      <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-position="right" label-width="110px" border
        stripe>
        <el-row :gutter="24">
          <el-col :span="6">
            <el-form-item>
              <el-upload class="avatar-uploader" :show-file-list="false" :http-request="uploadQuarterlyEvaluateFile"
                :before-upload="beforeAvatarUpload" accept="image/png, image/jpeg,image/jpg">
                <img v-if="ruleForm.workerAvatar" :src="photoUrl" class="avatar">
                <el-icon v-else class="avatar-uploader-icon">
                  <plus />
                </el-icon>
              </el-upload>
              <el-button type="primary" style="margin-top: 20px; display: block; width: 190px;"
                @click="register">人脸注册</el-button>
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="姓名" prop="workerName" style="margin-top: 40px;">
              <el-input v-model.trim="ruleForm.workerName" placeholder="姓名">
              </el-input>
            </el-form-item>
            <el-form-item label="所属部门" prop="deptId" class="marg-item" style="margin-top: 40px;">
              <dept-select v-model="ruleForm.deptId" :data="deptTreeList" placeholder="所属部门" style="width: 100%;" />
            </el-form-item>
            <el-form-item label="职务" prop="name" style="margin-top: 40px;">
              <el-input v-model.trim="ruleForm.name" placeholder="职务" :disabled="title === '详情'">
              </el-input>
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="性别" prop="gender" class="marg-item" style="margin-top: 40px;">
              <el-select v-model="ruleForm.gender" placeholder="请选择性别" :disabled="title === '详情'" style="width: 100%;">
                <el-option v-for="item in sexList" :key="item.id" :label="item.name" :value="item.value" />
              </el-select>
            </el-form-item>
            <el-form-item label="联系方式" prop="phoneNumber" style="margin-top: 40px;">
              <el-input v-model.trim="ruleForm.phoneNumber" placeholder="联系方式" :disabled="title === '详情'">
              </el-input>
            </el-form-item>
            <el-form-item label="证件号码" prop="idCardNumber" style="margin-top: 40px;">
              <el-input v-model.trim="ruleForm.idCardNumber" placeholder="证件号码" :disabled="title === '详情'">
              </el-input>
            </el-form-item>
          </el-col>

        </el-row>
      </el-form>
      <div class="dialog-footer">
        <el-button style="margin-left: 30px;" @click="resetForm">
          取消
        </el-button>
        <el-button type="primary" @click="submitForm(ruleFormRef)">
          保存
        </el-button>
      </div>
    </detail-page>
  </app-container>
</template>

<style lang="scss" scoped>
.dialog-footer {
  display: flex;
  justify-items: end;
  flex-direction: row-reverse;
}

:deep(.el-radio__label) {
  display: none;
}

:deep(.el-icon.avatar-uploader-icon) {
  font-size: 28px;
  color: #8c939d;
  width: 190px;
  height: 250px;
  text-align: center;
}

:deep(.avatar-uploader .avatar) {
  width: 190px;
  height: 250px;
  display: block;
}

.isDetail {
  ::v-deep {

    .el-form-item.is-required:not(.is-no-asterisk) .el-form-item__label-wrap>.el-form-item__label::before,
    .el-form-item.is-required:not(.is-no-asterisk)>.el-form-item__label::before {
      display: none;
    }
  }
}
</style>

<style scoped>
.avatar-uploader .avatar {
  width: 190px;
  height: 250px;
  display: block;
}
</style>

<style>
.avatar-uploader .el-upload {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
  border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 190px;
  height: 250px;
  text-align: center;
}
</style>