gaoluyang
2 天以前 e2317a1bcab0134f0c1b1aec99eb4d78dfddf1b8
src/views/personnelManagement/employeeRecord/components/NewOrEditFormDia.vue
@@ -1,321 +1,322 @@
<template>
  <div>
    <el-dialog
        v-model="dialogFormVisible"
        :title="operationType === 'add' ? '新增入职' : '编辑人员'"
        width="70%"
        @close="closeDia"
    >
      <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="员工编号:" prop="staffNo">
              <el-input v-model="form.staffNo" placeholder="请输入" clearable :disabled="operationType !== 'add'"/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="姓名:" prop="staffName">
              <el-input v-model="form.staffName" placeholder="请输入" clearable/>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="性别:" prop="sex">
              <el-select v-model="form.sex">
                <el-option label="男" value="男" />
                <el-option label="女" value="女" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="户籍住址:" prop="nativePlace">
              <el-input v-model="form.nativePlace" placeholder="请输入" clearable/>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="岗位:" prop="sysPostId">
              <el-select v-model="form.sysPostId" placeholder="请选择岗位" clearable>
                <el-option
                    v-for="item in postOptions"
                    :key="item.postId"
                    :label="item.postName"
                    :value="item.postId"
                    :disabled="item.status === '1'"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="现住址:" prop="adress">
              <el-input v-model="form.adress" placeholder="请输入" clearable/>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="部门:" prop="sysDeptId">
              <el-tree-select
                  v-model="form.sysDeptId"
                  :data="deptOptions"
                  :props="{ value: 'id', label: 'label', children: 'children' }"
                  value-key="id"
                  placeholder="请选择部门"
                  check-strictly
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="年龄:" prop="age">
              <el-input-number v-model="form.age" :precision="0" :step="1" style="width: 100%"/>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="第一学历:" prop="firstStudy">
              <el-input v-model="form.firstStudy" placeholder="请输入" clearable/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="专业:" prop="profession">
              <el-input v-model="form.profession" placeholder="请输入" clearable/>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="联系电话:" prop="phone">
              <el-input v-model="form.phone" placeholder="请输入" clearable/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="紧急联系人:" prop="emergencyContact">
              <el-input v-model="form.emergencyContact" placeholder="请输入" clearable/>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="紧急联系人联系电话:" prop="emergencyContactPhone">
              <el-input v-model="form.emergencyContactPhone" placeholder="请输入" clearable/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="合同年限:" prop="contractTerm">
              <el-input-number v-model="form.contractTerm" :precision="0" :step="1" style="width: 100%" :disabled="true"/>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="合同开始日期:" prop="contractStartTime">
              <el-date-picker
                  v-model="form.contractStartTime"
                  type="date"
                  placeholder="请选择日期"
                  value-format="YYYY-MM-DD"
                  format="YYYY-MM-DD"
                  clearable
                  style="width: 100%"
                           @change="calculateContractTerm"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="合同结束日期:" prop="contractEndTime">
              <el-date-picker
                  v-model="form.contractEndTime"
                  type="date"
                  placeholder="请选择日期"
                  value-format="YYYY-MM-DD"
                  format="YYYY-MM-DD"
                  clearable
                  style="width: 100%"
                           @change="calculateContractTerm"
              />
            </el-form-item>
          </el-col>
        </el-row>
  <FormDialog
    v-model="dialogFormVisible"
    :operation-type="operationType"
    :title="dialogTitle"
    width="90%"
    @close="closeDia"
    @confirm="submitForm"
    @cancel="closeDia"
  >
    <div class="form-dia-body">
      <el-form
        ref="formRef"
        :model="form"
        :rules="rules"
        label-position="top"
      >
        <BasicInfoSection
          :form="form"
          :operation-type="operationType"
          :role-options="roleOptions"
        />
        <JobInfoSection
          :form="form"
          :post-options="postOptions"
          :dept-options="deptOptions"
        />
        <EducationWorkSection :form="form" />
        <EmergencyAndAttachmentSection :form="form" />
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确认</el-button>
          <el-button @click="closeDia">取消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
    </div>
  </FormDialog>
</template>
<script setup>
import {ref, onMounted} from "vue";
import {findPostOptions} from "@/api/system/post.js";
import {listDept} from "@/api/system/dept.js";
import {staffOnJobInfo, createStaffOnJob, updateStaffOnJob} from "@/api/personnelManagement/staffOnJob.js";
import {deptTreeSelect} from "@/api/system/user.js";
const { proxy } = getCurrentInstance()
const emit = defineEmits(['close'])
import {
  ref,
  reactive,
  toRefs,
  onMounted,
  getCurrentInstance,
  nextTick,
} from "vue";
import FormDialog from "@/components/Dialog/FormDialog.vue";
import { findPostOptions } from "@/api/system/post.js";
import { deptTreeSelect, getUser } from "@/api/system/user.js";
import {
  staffOnJobInfo,
  createStaffOnJob,
  updateStaffOnJob,
} from "@/api/personnelManagement/staffOnJob.js";
import BasicInfoSection from "./BasicInfoSection.vue";
import JobInfoSection from "./JobInfoSection.vue";
import EducationWorkSection from "./EducationWorkSection.vue";
import EmergencyAndAttachmentSection from "./EmergencyAndAttachmentSection.vue";
const { proxy } = getCurrentInstance();
const emit = defineEmits(["close"]);
const dialogFormVisible = ref(false);
const operationType = ref('')
const id = ref(0)
const data = reactive({
  form: {
    staffNo: "",
    staffName: "",
    sex: "",
    nativePlace: "",
    postJob: "",
    adress: "",
    firstStudy: "",
    profession: "",
    age: 0,
    phone: "",
    emergencyContact: "",
    emergencyContactPhone: "",
    contractTerm: 0,
    contractStartTime: "",
    contractEndTime: "",
    staffState: "",
    sysPostId: undefined,
    sysDeptId: undefined,
  },
  rules: {
    staffNo: [{ required: true, message: "请输入", trigger: "blur" },],
    staffName: [{ required: true, message: "请输入", trigger: "blur" }],
    sex: [{ required: true, message: "请输入", trigger: "blur" }],
    nativePlace: [{ required: true, message: "请输入", trigger: "blur" }],
    postJob: [{ required: true, message: "请输入", trigger: "blur" }],
    adress: [{ required: true, message: "请输入", trigger: "blur" }],
    firstStudy: [{ required: true, message: "请输入", trigger: "blur" }],
    profession: [{ required: true, message: "请输入", trigger: "blur" }],
    age: [{ required: true, message: "请输入", trigger: "blur" }],
    phone: [{ required: true, message: "请输入", trigger: "blur" }],
    emergencyContact: [{ required: true, message: "请输入", trigger: "blur" }],
    emergencyContactPhone: [{ required: true, message: "请输入", trigger: "blur" }],
    contractTerm: [{ required: true, message: "请输入", trigger: "blur" }],
    contractStartTime: [{ required: true, message: "请输入", trigger: "blur" }],
    contractEndTime: [{ required: true, message: "请输入", trigger: "blur" }],
  },
  postOptions: [], // 岗位选项
  deptOptions: [], // 部门选项
});
const { form, rules, postOptions, deptOptions } = toRefs(data);
const operationType = ref("add");
const id = ref(0);
const formRef = ref(null);
// 打开弹框
const dialogTitle = () =>
  operationType.value === "add" ? "新增入职" : "编辑人员";
const createEmptyEducation = () => ({
  degree: "",
  school: "",
  admissionDate: "",
  graduationDate: "",
  major: "",
  academicDegree: "",
});
const createEmptyWork = () => ({
  company: "",
  department: "",
  position: "",
  startDate: "",
  endDate: "",
  description: "",
});
const createEmptyEmergency = () => ({
  name: "",
  relation: "",
  phone: "",
  address: "",
});
const createDefaultForm = () => ({
  id: undefined,
  // 基本信息
  staffNo: "",
  staffName: "",
  aliasName: "",
  phone: "",
  sex: "",
  birthDate: "",
  age: undefined,
  nativePlace: "",
  nation: "",
  maritalStatus: "",
  politicalStatus: "",
  firstWorkDate: "",
  workingYears: undefined,
  idCardNo: "",
  hukouType: "",
  email: "",
  currentAddress: "",
  // 在职信息
  jobNo: "",
  staffType: "",
  entryDate: "",
  probationPeriod: undefined,
  regularDate: "",
  sysDeptId: undefined,
  directLeader: "",
  sysPostId: undefined,
  jobLevel: "",
  basicSalary: undefined,
  // 银行卡信息
  bankName: "",
  bankCardNo: "",
  // 教育经历
  educationList: [createEmptyEducation()],
  // 工作经历
  workExperienceList: [createEmptyWork()],
  // 紧急联系人
  emergencyContacts: [createEmptyEmergency()],
  emergencyContact: "",
  emergencyContactPhone: "",
  // 角色
  roleIds: [],
  // 材料附件(仅前端展示)
  attachments: [],
});
const state = reactive({
  form: createDefaultForm(),
  rules: {
    staffNo: [{ required: true, message: "请输入员工编号", trigger: "blur" }],
    staffName: [{ required: true, message: "请输入姓名", trigger: "blur" }],
    phone: [{ required: true, message: "请输入手机", trigger: "blur" }],
    sex: [{ required: true, message: "请选择性别", trigger: "change" }],
    birthDate: [
      { required: true, message: "请选择出生日期", trigger: "change" },
    ],
    jobNo: [{ required: true, message: "请输入工号", trigger: "blur" }],
    staffType: [
      { required: true, message: "请选择员工类型", trigger: "change" },
    ],
    entryDate: [
      { required: true, message: "请选择入职日期", trigger: "change" },
    ],
    sysDeptId: [
      { required: true, message: "请选择部门", trigger: "change" },
    ],
    roleIds: [
      {
        required: true,
        type: "array",
        min: 1,
        message: "请至少选择一个角色",
        trigger: "change",
      },
    ],
  },
  postOptions: [],
  deptOptions: [],
});
const { form, rules, postOptions, deptOptions } = toRefs(state);
const roleOptions = ref([]);
const resetForm = () => {
  Object.assign(form.value, createDefaultForm());
  nextTick(() => {
    formRef.value?.clearValidate();
  });
};
const fetchPostOptions = () => {
  findPostOptions().then((res) => {
    postOptions.value = res.data || [];
  });
};
const fetchDeptOptions = () => {
  deptTreeSelect().then((response) => {
    deptOptions.value = filterDisabledDept(
      JSON.parse(JSON.stringify(response.data || []))
    );
  });
};
const fetchRoleOptions = () => {
  getUser().then((res) => {
    roleOptions.value = res.roles || [];
  });
};
function filterDisabledDept(deptList) {
  return deptList.filter((dept) => {
    if (dept.disabled) {
      return false;
    }
    if (dept.children && dept.children.length) {
      dept.children = filterDisabledDept(dept.children);
    }
    return true;
  });
}
const syncEmergencyToLegacyField = () => {
  const first = form.value.emergencyContacts?.[0];
  form.value.emergencyContact = first?.name || "";
  form.value.emergencyContactPhone = first?.phone || "";
};
const openDialog = (type, row) => {
  operationType.value = type;
  dialogFormVisible.value = true;
  if (operationType.value === 'edit') {
    id.value = row.id
    staffOnJobInfo(id.value, {}).then(res => {
      form.value = {...res.data}
      if (form.value.sysPostId === 0) {
        form.value.sysPostId = undefined
  fetchPostOptions();
  fetchDeptOptions();
  fetchRoleOptions();
  resetForm();
  if (type === "edit" && row?.id) {
    id.value = row.id;
    staffOnJobInfo(id.value, {}).then((res) => {
      const d = res.data || {};
      Object.assign(form.value, {
        ...form.value,
        ...d,
      });
      if (!Array.isArray(form.value.educationList) || !form.value.educationList.length) {
        form.value.educationList = [createEmptyEducation()];
      }
      // 编辑时也计算一次合同年限
      calculateContractTerm();
    })
  } else {
      form.value.id = ''
   }
      if (
        !Array.isArray(form.value.workExperienceList) ||
        !form.value.workExperienceList.length
      ) {
        form.value.workExperienceList = [createEmptyWork()];
      }
      if (
        !Array.isArray(form.value.emergencyContacts) ||
        !form.value.emergencyContacts.length
      ) {
        form.value.emergencyContacts = [createEmptyEmergency()];
      }
      if (form.value.sysPostId === 0) {
        form.value.sysPostId = undefined;
      }
      if (form.value.sysDeptId === 0) {
        form.value.sysDeptId = undefined;
      }
    });
  }
};
}
onMounted(() => {
  fetchPostOptions()
  fetchDeptOptions()
})
  fetchPostOptions();
  fetchDeptOptions();
});
const fetchPostOptions = () => {
  findPostOptions().then(res => {
    postOptions.value = res.data
  })
}
// 查询部门列表
const fetchDeptOptions = () => {
  deptTreeSelect().then(response => {
    deptOptions.value = filterDisabledDept(JSON.parse(JSON.stringify(response.data)))
  })
}
/** 过滤禁用的部门 */
function filterDisabledDept(deptList) {
  return deptList.filter(dept => {
    if (dept.disabled) {
      return false
    }
    if (dept.children && dept.children.length) {
      dept.children = filterDisabledDept(dept.children)
    }
    return true
  })
}
// 提交产品表单
const submitForm = () => {
  if (!form.value.sysPostId) {
    form.value.sysPostId = 0;
    form.value.sysPostId = undefined;
  }
  proxy.$refs.formRef.validate(valid => {
  if (!form.value.sysDeptId) {
    form.value.sysDeptId = undefined;
  }
  syncEmergencyToLegacyField();
  formRef.value?.validate((valid) => {
    if (valid) {
      form.value.staffState = 1
      if (operationType.value === "add") {
        createStaffOnJob(form.value).then(res => {
        createStaffOnJob(form.value).then(() => {
          proxy.$modal.msgSuccess("提交成功");
          closeDia();
        })
        });
      } else {
        updateStaffOnJob(id.value, form.value).then(res => {
        updateStaffOnJob(id.value, form.value).then(() => {
          proxy.$modal.msgSuccess("提交成功");
          closeDia();
        })
        });
      }
    }
  })
}
// 计算合同年限
const calculateContractTerm = () => {
  if (form.value.contractStartTime && form.value.contractEndTime) {
    const startDate = new Date(form.value.contractStartTime);
    const endDate = new Date(form.value.contractEndTime);
    if (endDate > startDate) {
      // 计算年份差
      const yearDiff = endDate.getFullYear() - startDate.getFullYear();
      const monthDiff = endDate.getMonth() - startDate.getMonth();
      const dayDiff = endDate.getDate() - startDate.getDate();
      let years = yearDiff;
      // 如果结束日期的月日小于开始日期的月日,则减去1年
      if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0)) {
        years = yearDiff - 1;
      }
      form.value.contractTerm = Math.max(0, years);
    } else {
      form.value.contractTerm = 0;
    }
  } else {
    form.value.contractTerm = 0;
  }
  });
};
// 关闭弹框
const closeDia = () => {
  proxy.resetForm("formRef");
  formRef.value?.resetFields();
  dialogFormVisible.value = false;
  emit('close')
  emit("close");
};
defineExpose({
  openDialog,
});
</script>
<style scoped>
.form-dia-body {
  padding: 0;
}
.card-title-line {
  color: #f56c6c;
  margin-right: 4px;
}
.form-card {
  margin-bottom: 16px;
}
.dialog-footer {
  text-align: right;
}
</style>