2023-06-01 16:20:29 +08:00

884 lines
25 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="overview">
<el-dialog :title="props.title" show-close v-model="visible1" style="min-width: 1500px">
<el-form ref="ruleFormRef" :model="form" :rules="rules" label-width="200px" class="form" size="default">
<!-- 基础信息 -->
<div>
<div class="form-title">
<div>基础信息</div>
</div>
<div class="row">
<el-form-item label="姓名:" prop="personName">
<el-input placeholder="请输入" v-model="form.personName" />
</el-form-item>
<el-form-item label="性别:" prop="sex">
<el-radio-group placeholder="请选择" v-model="form.sex">
<el-radio :label="1">男</el-radio>
<el-radio :label="2">女</el-radio>
</el-radio-group>
</el-form-item>
</div>
<div class="row">
<el-form-item label="出生日期:" prop="birthday">
<el-date-picker
v-model="form.birthday"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
type="datetime"
placeholder="请选择时间"
/>
</el-form-item>
<el-form-item label="民族:" prop="nation">
<el-input placeholder="请输入" v-model="form.nation" />
</el-form-item>
</div>
<el-form-item label="住址:" prop="registerAddress">
<el-input placeholder="请输入" v-model="form.registerAddress" />
</el-form-item>
<div class="row">
<el-form-item label="身份证号:" prop="idCard">
<el-input placeholder="请输入" v-model="form.idCard" />
</el-form-item>
</div>
<div class="row">
<el-form-item label="签发机关:" prop="issuingAuthorityForIdCard">
<el-input placeholder="请输入" v-model="form.issuingAuthorityForIdCard" />
</el-form-item>
<el-form-item label="身份证有效期:" prop="idCardExpireDate">
<div class="date-select">
<el-date-picker
style="width: 62%; margin-right: 8px"
v-model="form.idCardExpireDate"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
v-if="changeType == 1"
/>
<div v-else>长期</div>
<el-radio-group v-model="changeType">
<el-radio-button label="1">日期</el-radio-button>
<el-radio-button label="2">长期</el-radio-button>
</el-radio-group>
</div>
</el-form-item>
</div>
<div class="row">
<el-form-item label="身份证:">
<div class="idCard-img">
<el-upload
class="avatar-uploader"
:action="`${baseUrl}` + '/xmgl/file/upload'"
:show-file-list="false"
:on-success="(response, uploadFile) => handleAvatarSuccess(response, uploadFile, 1)"
:before-upload="beforeAvatarFrontUpload"
accept="image/jpg, image/jpeg, image/png"
>
<img v-if="form.idCardFront" :src="form.idCardFront" class="avatar" />
<span v-else class="text-tip">上传身份证人像面</span>
</el-upload>
<el-upload
class="avatar-uploader"
:action="`${baseUrl}` + '/xmgl/file/upload'"
:show-file-list="false"
:on-success="(response, uploadFile) => handleAvatarSuccess(response, uploadFile, 2)"
:before-upload="beforeAvatarBackUpload"
accept="image/jpg, image/jpeg, image/png"
>
<img v-if="form.idCardBack" :src="form.idCardBack" class="avatar" />
<span v-else class="text-tip">上传身份证国徽面</span>
</el-upload>
</div>
<div class="idCard-tip">请上传清晰、完善、无遮挡物的身份证照片</div>
</el-form-item>
<el-form-item label="人像信息:">
<div class="face-img">
<el-upload
class="face-uploader"
:action="`${baseUrl}` + '/xmgl/file/upload'"
:show-file-list="false"
:on-success="(response, uploadFile) => handleAvatarSuccess(response, uploadFile, 3)"
:before-upload="beforeAvatarUpload"
accept="image/jpg, image/jpeg, image/png"
>
<img v-if="form.portrait" :src="form.portrait" class="face-avatar" />
<el-icon v-else><plus /></el-icon>
</el-upload>
<div class="face-tip">
<span>人员照片示例</span>
<el-popover placement="right" :width="371" title="注册照片示例" trigger="hover">
<template #reference>
<div class="tip-circle">?</div>
</template>
<div class="face-register">
<div class="face-top">
<div class="face-top-left">
<img src="@/assets/images/projectLogon/vector.png" alt="" />
</div>
<div class="face-top-right">
<span>1.简单背景;</span>
<span>2.正脸表情;</span>
<span>3.正常镜片无反光;</span>
<span>4.面部光照强度适中;</span>
<span>5.面部明暗均匀;</span>
</div>
</div>
<div class="face-bottom">
<div class="face-bottom-title">照片要求</div>
<div class="face-bottom-require">
<span>1.小于400k;</span>
<span>2.面部区域像素不低于128X128,面部大小占整张照片1/3以上;</span>
<span>3.确保所有注册照为同一人,否则无法成功注册;</span>
</div>
</div>
</div>
</el-popover>
</div>
</div>
</el-form-item>
</div>
</div>
<div>
<!-- 进场信息 -->
<div class="form-title">
<div>进场信息</div>
</div>
<div class="row">
<el-form-item label="手机号:" prop="phone">
<el-input placeholder="请输入" v-model="form.phone" />
</el-form-item>
<el-form-item label="现居住地 :" prop="address">
<el-input placeholder="请输入" v-model="form.address" />
</el-form-item>
</div>
<div class="row">
<el-form-item label="参建单位:" prop="companySn">
<el-select v-model="form.companySn" placeholder="请选择" style="width: 100%">
<el-option v-for="item in unitList" :key="item.value" :label="item.label" :value="item.value"> </el-option>
</el-select>
</el-form-item>
<el-form-item label="班组 :" prop="teamSn">
<el-select v-model="form.teamSn" placeholder="请选择" style="width: 100%">
<el-option v-for="item in groupList" :key="item.value" :label="item.label" :value="item.value"> </el-option>
</el-select>
</el-form-item>
</div>
<div class="row">
<el-form-item label="工种 :" prop="workerType">
<el-select v-model="form.workerType" placeholder="请选择" style="width: 100%">
<el-option v-for="item in workList" :key="item.value" :label="item.label" :value="item.value"> </el-option>
</el-select>
</el-form-item>
<el-form-item label="人员类别:">
<el-radio-group placeholder="请选择" v-model="form.personType">
<el-radio :label="1">管理</el-radio>
<el-radio :label="2">工人</el-radio>
</el-radio-group>
</el-form-item>
</div>
<div class="row">
<el-form-item label="是否参与安全教育:">
<el-radio-group placeholder="请选择" v-model="form.safetyEducation">
<el-radio :label="1">合格</el-radio>
<el-radio :label="2">不合格</el-radio>
<el-radio :label="3">未培训</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="是否购买工伤和意外保险:">
<el-radio-group placeholder="请选择" v-model="form.isPurchaseInsurance">
<el-radio :label="1">是</el-radio>
<el-radio :label="0">否</el-radio>
</el-radio-group>
</el-form-item>
</div>
<div class="row">
<el-form-item label="有无合同 :">
<el-radio-group placeholder="请选择" v-model="form.isContract">
<el-radio :label="1">是</el-radio>
<el-radio :label="0">否</el-radio>
</el-radio-group>
<el-upload
v-model:file-list="filelist"
class="upload-demo"
:action="`${baseUrl}` + '/xmgl/file/upload'"
multiple
:limit="1"
:on-success="uploadSuccess"
style="display: flex; align-items: center; justify-content: center; margin-left: 22px"
v-if="form.isContract == 1"
>
<el-button plain color="#47A99D" size="small">选择文件</el-button>
<template #tip>
<div v-show="!form.contractImage" style="margin-left: 10px; color: #aeaeae">未选择任何文件</div>
</template>
</el-upload>
</el-form-item>
<el-form-item label="是否体检:">
<el-radio-group placeholder="请选择" v-model="form.isPhysicalExamination">
<el-radio :label="1">是</el-radio>
<el-radio :label="0">否</el-radio>
</el-radio-group>
</el-form-item>
</div>
</div>
<!-- 银行卡与社保 -->
<div>
<div class="form-title">
<div>银行卡和社保</div>
</div>
<div class="row">
<el-form-item label="银行类型:">
<el-select v-model="form.bankType" placeholder="请选择" style="width: 100%">
<el-option v-for="item in bankTypeList" :key="item.value" :label="item.label" :value="item.value"> </el-option>
</el-select>
</el-form-item>
<el-form-item label="银行卡号:" prop="bankCard">
<el-input placeholder="请输入" v-model="form.bankCard" />
</el-form-item>
</div>
<div class="row">
<el-form-item label="实名制卡号:">
<el-input placeholder="请输入" v-model="form.realNameCardNumber" />
</el-form-item>
<el-form-item label="开户支行名称:">
<el-input placeholder="请输入" v-model="form.bankName" />
</el-form-item>
</div>
<div class="row">
<el-form-item label="开户支行代号:">
<el-input placeholder="请输入" v-model="form.bankCode" />
</el-form-item>
</div>
</div>
<!-- 其他信息 -->
<div>
<div class="form-title">
<div>其他信息</div>
</div>
<div class="row">
<el-form-item label="政治面貌:" prop="politicsStatus">
<el-select v-model="form.politicsStatus" placeholder="请选择" style="width: 100%">
<el-option v-for="item in politicsStatusList" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="学历:" prop="educationLevel">
<el-select v-model="form.educationLevel" placeholder="请选择" style="width: 100%">
<el-option
v-for="item in educationLevelList"
:key="item.dictValue"
:label="item.dictValue"
:value="item.dictLabel"
>
</el-option>
</el-select>
</el-form-item>
</div>
<div class="row">
<el-form-item label="学位:" prop="academicDegree">
<el-select v-model="form.academicDegree" placeholder="请选择" style="width: 100%">
<el-option v-for="item in academicDegreeList" :key="item.label" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="是否有重大病史:">
<el-radio-group placeholder="请选择" v-model="form.haveMedicalHistory">
<el-radio :label="1">是</el-radio>
<el-radio :label="0">否</el-radio>
</el-radio-group>
</el-form-item>
</div>
<div class="row">
<el-form-item label="户口性质:">
<el-radio-group placeholder="请选择" v-model="form.natureOfAccount">
<el-radio :label="1">非农户口</el-radio>
<el-radio :label="2">农业户口</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="婚姻状况:" prop="maritalStatus">
<el-select v-model="form.maritalStatus" placeholder="请选择" style="width: 100%">
<el-option v-for="item in maritalStatusList" :key="item.label" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-form-item>
</div>
<div class="row">
<el-form-item label="紧急联系人:">
<el-input placeholder="请输入" v-model="form.contacts" />
</el-form-item>
<el-form-item label="紧急联系电话:" prop="contactsTel">
<el-input placeholder="请输入" v-model="form.contactsTel" />
</el-form-item>
</div>
<div class="row">
<el-form-item label="开始工作日期:">
<el-date-picker
v-model="form.entryTime"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
type="datetime"
placeholder="请选择"
/>
</el-form-item>
<el-form-item label="岗前培训日期:">
<el-date-picker
v-model="form.trainingTime"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
type="datetime"
placeholder="请选择"
/>
</el-form-item>
</div>
<div class="row">
<el-form-item label="邮箱:" prop="personEmail">
<el-input placeholder="请输入" v-model="form.personEmail" />
</el-form-item>
</div>
</div>
<footer class="footer flx-center" v-if="title == '新增人员'">
<el-button class="cancelButtonStyle" @click="visible1 = false">取消</el-button>
<el-button type="primary" @click="submitForm(form)">保存</el-button>
</footer>
</el-form>
</el-dialog>
</div>
</template>
<script lang="ts" setup>
import { onMounted, ref, watch, reactive } from "vue";
import type { FormInstance, UploadProps } from "element-plus";
import { ElMessage } from "element-plus";
import { getDicList } from "@/api/modules/jxjview";
import { getBuildUnitAll, getClassGroupAll, getworkTypeAll } from "@/api/modules/project";
const baseUrl = import.meta.env.VITE_API_URL;
const props = defineProps({
newMemberDialog: Boolean,
engineeringSn: String,
title: String,
formData: Object
});
const visible1 = ref(false);
const changeType = ref(1);
const filelist = ref([]);
const emits = defineEmits(["update:newMemberDialog", "confirm"]);
const ruleFormRef = ref<FormInstance>();
const rules = ref({
personName: [
{
required: true,
message: "请输入",
trigger: "blur"
}
],
sex: [
{
required: true,
message: "请选择",
trigger: "change"
}
],
birthday: [
{
required: true,
message: "请选择",
trigger: "change"
}
],
nation: [
{
required: true,
message: "请输入",
trigger: "blur"
}
],
registerAddress: [
{
required: true,
message: "请输入",
trigger: "blur"
}
],
idCard: [
{
required: true,
pattern: /^[1-9]\d{5}(19|20)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/i,
message: "请输入正确的身份证号码",
trigger: "blur"
}
],
issuingAuthorityForIdCard: [
{
required: true,
message: "请输入",
trigger: "blur"
}
],
phone: [
{
pattern: /^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}$/,
message: "请输入合法手机号",
trigger: "blur"
}
],
contactsTel: [
{
pattern: /^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}$/,
message: "请输入合法手机号",
trigger: "blur"
}
],
companySn: [
{
message: "请选择",
trigger: "change"
}
],
teamSn: [
{
message: "请选择",
trigger: "change"
}
],
workerType: [
{
message: "请选择",
trigger: "change"
}
],
legalPersonCard: [
{
pattern: /^[1-9]\d{5}(19|20)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/i,
message: "请输入正确的身份证号码",
trigger: "change"
}
],
personEmail: [
{
type: "email",
message: "请输入正确的邮箱格式",
trigger: "change"
}
]
});
const politicsStatusList = ref([
{ label: "中共党员", value: 1 },
{ label: "共青团团员", value: 2 },
{ label: "普通居民", value: 3 },
{ label: "其他党派人士", value: 4 }
]);
const academicDegreeList = ref([
{ label: "学士", value: 1 },
{ label: "硕士", value: 2 },
{ label: "博士", value: 3 }
]);
const maritalStatusList = ref([
{ label: "未婚", value: 1 },
{ label: "已婚", value: 2 }
]);
const educationLevelList: any = ref([]);
const unitList: any = ref([]);
const groupList: any = ref([]);
const workList: any = ref([]);
const bankTypeList: any = ref([
{ label: "工商银行", value: 1 },
{ label: "建设银行", value: 2 },
{ label: "农业银行", value: 3 },
{ label: "交通银行", value: 4 },
{ label: "中国银行", value: 5 },
{ label: "招商银行", value: 6 },
{ label: "浦发银行", value: 7 },
{ label: "兴业银行", value: 8 },
{ label: "民生银行", value: 9 },
{ label: "光大银行", value: 10 },
{ label: "广发银行", value: 11 },
{ label: "华夏银行", value: 12 },
{ label: "平安银行", value: 13 },
{ label: "邮政储蓄银行", value: 14 },
{ label: "浙商银行", value: 15 }
]);
const form = ref();
// 图片上传成功后的钩子
const handleAvatarSuccess: UploadProps["onSuccess"] = (response, uploadFile, index) => {
console.log(response.result.url);
console.log(response, uploadFile, index);
switch (index) {
case 1:
form.value.idCardFront = response.result.url;
break;
case 2:
form.value.idCardBack = response.result.url;
break;
case 3:
form.value.portrait = response.result.url;
break;
}
};
const beforeAvatarUpload: UploadProps["beforeUpload"] = rawFile => {
if (rawFile.type !== "image/png" && rawFile.type !== "image/jpg" && rawFile.type !== "image/jpeg") {
console.log(rawFile.type);
ElMessage.error("请上传jpg或者png格式的图片");
return false;
}
// 限制文件大小
// else if (rawFile.size / 1024 / 1024 > 2) {
// ElMessage.error('Avatar picture size can not exceed 2MB!')
// return false
// }
return true;
};
const uploadSuccess = (response: any) => {
ElMessage.success("上传成功");
// ruleForm.businessLicense = response.result.originalFilename;
form.value.contractImage = response.result.url;
// ruleForm.businessLicenseOriginalName = response.result.originalFilename;
// businessLicense.value = [{ name: response.result.originalFilename, url: response.result.downloadPath }];
};
// TODO: 提交表单操作
const submitForm = async (data: any) => {
console.log(data.value);
const formEl = ruleFormRef.value;
if (!formEl) return;
await formEl.validate((valid, fields) => {
if (valid) {
if (changeType.value == 2) {
delete data.businessLicenseLifespan;
}
data.idCardExpireDate = data.idCardExpireDate + "";
data.engineeringSn = props.engineeringSn;
emits("confirm", data);
} else {
console.log("error submit!", fields);
}
visible1.value = false;
});
};
// 获取参建单位列表
const getUnitList = async () => {
const res = await getBuildUnitAll({ engineeringSn: props.engineeringSn });
console.log(res);
unitList.value = res.result.map(item => {
console.log(item);
return {
label: item.companyName,
value: item.companySn
};
});
};
// 获取班组管理列表
const getGroupList = async () => {
const res = await getClassGroupAll({ engineeringSn: props.engineeringSn });
console.log(res);
groupList.value = res.result.map(item => {
console.log(item);
return {
label: item.teamName,
value: item.teamSn
};
});
};
// 获取工种管理列表
const getTypeList = async () => {
const res = await getworkTypeAll({ engineeringSn: props.engineeringSn });
console.log(res);
workList.value = res.result.map(item => {
console.log(item);
return {
label: item.typeName,
value: item.id
};
});
};
const getDicMainList = async () => {
// 获取学历字典
const { result } = await getDicList({ dictType: "education_level" });
educationLevelList.value.length = 0;
educationLevelList.value.push(...result);
};
// 重置表单
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return;
formEl.resetFields();
};
// 监听父组件的visible用来简介控制el-dialog的弹框开关一般是用于开
watch(
() => props.newMemberDialog,
(n, o) => {
visible1.value = n;
if (n) {
getUnitList();
getGroupList();
getTypeList();
}
}
);
// 监听el-dialog显示状态再通过@update:visible 通知父组件,一般是用于关
watch(visible1, (n, o) => {
emits("update:newMemberDialog", n);
});
watch(
() => props.formData,
(n, o) => {
resetForm(ruleFormRef.value);
console.log(props.formData);
form.value = reactive(n);
}
);
onMounted(() => {
getDicMainList();
// 初始化 配置formData
console.log(props.formData);
form.value = reactive(props.formData);
});
</script>
<style lang="scss" scoped>
@mixin fullwidth {
width: -webkit-fill-available;
width: -moz-available;
width: stretch;
}
.overview {
// background-color: #fff;
flex: 1;
.form {
background-color: #fff;
.form-title {
display: flex;
flex-direction: column;
background-color: #fff;
margin-bottom: 32px;
div {
position: relative;
padding-left: 6px;
font-size: 14px;
font-weight: 400;
color: #333333;
border-left: 3px solid #008bff;
}
}
.date-select {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
}
.idCard-img {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
.avatar-uploader {
width: 178px;
height: 115px;
line-height: 150px;
text-align: center;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
.text-tip {
font-size: 10px;
font-family: Source Han Sans CN-Regular, Source Han Sans CN;
font-weight: 400;
color: #616161;
}
}
.avatar-uploader:hover {
border-color: #409eff;
}
.avatar-uploader:first-child {
background: url("@/assets/images/projectLogon/idCard-face.png") center center no-repeat;
}
.avatar-uploader:last-child {
background: url("@/assets/images/projectLogon/idCard-badge.png") center center no-repeat;
}
.avatar {
width: 178px;
height: 115px;
display: block;
}
}
.idCard-tip {
font-size: 12px;
font-family: Source Han Sans CN-Regular, Source Han Sans CN;
font-weight: 400;
color: #616161;
}
.face-img {
width: 100%;
align-self: flex-start;
:deep(.face-uploader .el-upload) {
border: 1px dashed #d9d9d9 !important;
border-radius: 6px !important;
cursor: pointer !important;
position: relative !important;
overflow: hidden !important;
}
.face-uploader .el-upload:hover {
border-color: #409eff !important;
}
:deep(.el-icon) {
font-size: 28px;
color: #8c939d;
width: 53px;
height: 53px;
line-height: 53px;
text-align: center;
}
.face-avatar {
width: 53px;
height: 53px;
display: block;
}
.face-tip {
display: flex;
align-items: center;
font-size: 12px;
.tip-circle {
width: 15px;
height: 15px;
text-align: center;
line-height: 15px;
background: #008bff;
opacity: 1;
border-radius: 50%;
color: white;
margin-left: 4px;
}
}
}
.row {
display: flex;
justify-content: space-between;
> :first-child,
> :last-child {
width: 45%;
}
}
:deep(.el-input--default) {
width: 100%;
}
.select {
width: 100%;
}
.continuous {
@include fullwidth;
box-sizing: border-box;
display: flex;
gap: 5px;
align-items: center;
justify-content: space-around;
width: 90%;
min-height: 40px;
padding-inline: 10px;
border: 1px solid #dddddd;
border-radius: 5px;
.label {
display: flex;
flex: 1;
align-items: center;
span {
flex-shrink: 0;
margin-right: 4px;
font-size: 12px;
}
}
}
.calendar {
position: absolute;
inset-block: 1px;
right: 1px;
display: flex;
align-items: center;
justify-content: center;
width: 41px;
height: 31px;
cursor: pointer;
background-color: #008aff;
border-top-right-radius: 2px;
border-bottom-right-radius: 2px;
.icon {
font-size: 20px;
color: #ffffff;
}
}
v-deep {
.date {
@include fullwidth;
}
.el-input__prefix {
display: none;
}
}
}
.footer {
display: flex;
justify-content: center;
margin: 40px;
}
}
.face-register {
.face-top {
display: flex;
&-left {
width: 90px;
height: 91px;
background: #ffffff;
border-radius: 6px 6px 6px 6px;
opacity: 1;
border: 1px solid #e5e5e5;
display: flex;
align-items: center;
justify-content: center;
}
&-right {
width: 130px;
height: 91px;
line-height: 19px !important;
display: flex;
flex-direction: column;
margin-left: 10px;
}
}
.face-bottom {
display: flex;
flex-direction: column;
margin-top: 20px;
&-title {
font-size: 16px;
font-family: Source Han Sans CN-Medium, Source Han Sans CN;
font-weight: 700;
color: #333333;
line-height: 16px;
}
&-require {
width: 100%;
height: 91px;
display: flex;
flex-direction: column;
margin-top: 10px;
}
}
}
.test :deep(.el-input__wrapper) {
box-shadow: 0 0 0 0;
}
.test :deep(.el-input__inner) {
text-align: center;
}
:deep(.el-table__empty-text) {
min-height: 200px;
display: flex;
justify-content: center;
align-items: center;
}
</style>