gaoluyang
2025-11-07 a72eca88f85e0a2e1b7383697002817d3c8ae01b
合同管理加下载合同功能
已修改5个文件
370 ■■■■ 文件已修改
src/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/personnelManagement/contractManagement/index.vue 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/personnelManagement/employeeRecord/components/formDia.vue 153 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/personnelManagement/onboarding/components/formDiaXJHT.vue 97 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/personnelManagement/onboarding/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue
@@ -39,6 +39,63 @@
            </el-form-item>
          </el-col>
        </el-row>
        <!-- 请假时间(仅当 approveType 为 2 时显示) -->
        <el-row :gutter="30" v-if="props.approveType == 2">
          <el-col :span="12">
            <el-form-item label="请假开始时间:" prop="leaveStartTime">
              <el-date-picker
                  v-model="form.leaveStartTime"
                  type="date"
                  placeholder="请选择开始日期"
                  value-format="YYYY-MM-DD"
                  format="YYYY-MM-DD"
                  clearable
                  style="width: 100%"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="请假结束时间:" prop="leaveEndTime">
              <el-date-picker
                  v-model="form.leaveEndTime"
                  type="date"
                  placeholder="请选择结束日期"
                  value-format="YYYY-MM-DD"
                  format="YYYY-MM-DD"
                  clearable
                  style="width: 100%"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <!-- 报销金额(仅当 approveType 为 4 时显示) -->
        <el-row v-if="props.approveType == 4">
          <el-col :span="24">
            <el-form-item label="报销金额:" prop="reimbursementAmount">
              <el-input-number
                  v-model="form.reimbursementAmount"
                  placeholder="请输入报销金额"
                  :min="0"
                  :precision="2"
                  :step="0.01"
                  style="width: 100%"
                  clearable
              />
            </el-form-item>
          </el-col>
        </el-row>
        <!-- 出差地点(仅当 approveType 为 3 时显示) -->
        <el-row v-if="props.approveType == 3">
          <el-col :span="24">
            <el-form-item label="出差地点:" prop="businessTripLocation">
              <el-input
                  v-model="form.businessTripLocation"
                  placeholder="请输入出差地点"
                  clearable
              />
            </el-form-item>
          </el-col>
        </el-row>
        <!-- 审批人选择(动态节点) -->
        <el-row>
          <el-col :span="24">
@@ -175,7 +232,11 @@
    approveReason: "",
    checkResult: "",
    tempFileIds: [],
    approverList: [] // 新增字段,存储所有节点的审批人id
    approverList: [], // 新增字段,存储所有节点的审批人id
    leaveStartTime: "", // 请假开始时间
    leaveEndTime: "", // 请假结束时间
    reimbursementAmount: null, // 报销金额
    businessTripLocation: "" // 出差地点
  },
  rules: {
    approveTime: [{ required: false, message: "请输入", trigger: "change" },],
@@ -184,6 +245,10 @@
        approveDeptId: [{ required: true, message: "请输入", trigger: "blur" }],
    approveReason: [{ required: true, message: "请输入", trigger: "blur" }],
    checkResult: [{ required: false, message: "请输入", trigger: "blur" }],
    leaveStartTime: [{ required: true, message: "请选择请假开始时间", trigger: "change" }],
    leaveEndTime: [{ required: true, message: "请选择请假结束时间", trigger: "change" }],
    reimbursementAmount: [{ required: true, message: "请输入报销金额", trigger: "blur" }],
    businessTripLocation: [{ required: true, message: "请输入出差地点", trigger: "blur" }],
  },
});
const { form, rules } = toRefs(data);
@@ -211,7 +276,6 @@
// 打开弹框
const openDialog = (type, row) => {
  console.log('openDialog', type, row)
  operationType.value = type;
  dialogFormVisible.value = true;
    userListNoPageByTenantId().then((res) => {
@@ -278,6 +342,36 @@
    proxy.$modal.msgError("请为所有审批节点选择审批人!")
    return
  }
  // 当 approveType 为 2 时,校验请假时间
  if (props.approveType == 2) {
    if (!form.value.leaveStartTime) {
      proxy.$modal.msgError("请选择请假开始时间!")
      return
    }
    if (!form.value.leaveEndTime) {
      proxy.$modal.msgError("请选择请假结束时间!")
      return
    }
    // 校验结束时间不能早于开始时间
    if (new Date(form.value.leaveEndTime) < new Date(form.value.leaveStartTime)) {
      proxy.$modal.msgError("请假结束时间不能早于开始时间!")
      return
    }
  }
  // 当 approveType 为 3 时,校验出差地点
  if (props.approveType == 3) {
    if (!form.value.businessTripLocation || form.value.businessTripLocation.trim() === '') {
      proxy.$modal.msgError("请输入出差地点!")
      return
    }
  }
  // 当 approveType 为 4 时,校验报销金额
  if (props.approveType == 4) {
    if (!form.value.reimbursementAmount || form.value.reimbursementAmount <= 0) {
      proxy.$modal.msgError("请输入有效的报销金额!")
      return
    }
  }
  proxy.$refs.formRef.validate(valid => {
    if (valid) {
      if (operationType.value === "add" || currentApproveStatus.value == 3) {
src/views/personnelManagement/contractManagement/index.vue
@@ -70,8 +70,8 @@
</template>
<script setup>
import { Search } from "@element-plus/icons-vue";
import { onMounted, ref } from "vue";
import { Search, UploadFilled } from "@element-plus/icons-vue";
import { onMounted, ref, reactive, toRefs, getCurrentInstance, nextTick } from "vue";
import FormDia from "@/views/personnelManagement/contractManagement/components/formDia.vue";
import { ElMessageBox } from "element-plus";
import { staffOnJobListPage } from "@/api/personnelManagement/employeeRecord.js";
@@ -183,7 +183,7 @@
    label: "操作",
    align: "center",
    fixed: 'right',
    width: 120,
    width: 180,
    operation: [
      {
        name: "详情",
@@ -197,6 +197,13 @@
        type: "text",
        clickFun: (row) => {
          openFilesFormDia(row);
        },
      },
      {
        name: "下载合同",
        type: "text",
        clickFun: (row) => {
          handleDownloadContract(row);
        },
      },
    ],
@@ -278,6 +285,11 @@
      proxy.$modal.msg("已取消");
    });
};
// 下载合同
const handleDownloadContract = (row) => {
  const fileName = `${row.staffName}劳动合同.xlsx`;
  proxy.download("/staff/staffOnJob/exportCopy", { ...row }, fileName);
};
const upload = reactive({
  // 是否显示弹出层(合同导入)
  open: false,
src/views/personnelManagement/employeeRecord/components/formDia.vue
@@ -6,16 +6,58 @@
        width="70%"
        @close="closeDia"
    >
      <PIMTable
          rowKey="id"
          :column="tableColumn"
          :tableData="tableData"
          :tableLoading="tableLoading"
          height="600"
      ></PIMTable>
      <el-descriptions class="detail-descriptions" :column="2" border size="small">
        <el-descriptions-item label="员工编号">{{ formData.staffNo || '-' }}</el-descriptions-item>
        <el-descriptions-item label="姓名">{{ formData.staffName || '-' }}</el-descriptions-item>
        <el-descriptions-item label="性别">{{ formData.sex || '-' }}</el-descriptions-item>
        <el-descriptions-item label="年龄">{{ formData.age || '-' }}</el-descriptions-item>
        <el-descriptions-item label="身份证号">{{ formData.identityCard || '-' }}</el-descriptions-item>
        <el-descriptions-item label="户籍住址" :span="2">{{ formData.nativePlace || '-' }}</el-descriptions-item>
        <el-descriptions-item label="现住址" :span="2">{{ formData.adress || '-' }}</el-descriptions-item>
        <el-descriptions-item label="岗位">{{ formData.postJob || '-' }}</el-descriptions-item>
        <el-descriptions-item label="第一学历">{{ formData.firstStudy || '-' }}</el-descriptions-item>
        <el-descriptions-item label="专业">{{ formData.profession || '-' }}</el-descriptions-item>
        <el-descriptions-item label="联系电话">{{ formData.phone || '-' }}</el-descriptions-item>
        <el-descriptions-item label="紧急联系人">{{ formData.emergencyContact || '-' }}</el-descriptions-item>
        <el-descriptions-item label="紧急联系人电话">{{ formData.emergencyContactPhone || '-' }}</el-descriptions-item>
        <el-descriptions-item label="合同签订日期">{{ formData.signDate || '-' }}</el-descriptions-item>
        <el-descriptions-item label="劳动合同期限选择">
          <span v-if="formData.dateSelect === 'A'">A、有固定期限</span>
          <span v-else-if="formData.dateSelect === 'B'">B、无固定期限</span>
          <span v-else-if="formData.dateSelect === 'C'">C、以完成一定工作任务为期限</span>
          <span v-else>-</span>
        </el-descriptions-item>
        <el-descriptions-item label="合同年限">{{ formattedContractTerm }}</el-descriptions-item>
        <el-descriptions-item label="试用期开始日期" v-if="formData.dateSelect === 'A' || formData.dateSelect === 'B'">
          {{ formData.trialStartDate || '-' }}
        </el-descriptions-item>
        <el-descriptions-item label="试用期结束日期" v-if="formData.dateSelect === 'A' || formData.dateSelect === 'B'">
          {{ formData.trialEndDate || '-' }}
        </el-descriptions-item>
        <el-descriptions-item label="试用期工资" v-if="formData.dateSelect === 'A' || formData.dateSelect === 'B'">
          {{ formData.proSalary ? formData.proSalary.toFixed(2) : '-' }}
        </el-descriptions-item>
        <el-descriptions-item label="合同开始日期">{{ formData.contractStartTime || '-' }}</el-descriptions-item>
        <el-descriptions-item label="合同结束日期" v-if="formData.dateSelect === 'A'">
          {{ formData.contractEndTime || '-' }}
        </el-descriptions-item>
        <el-descriptions-item label="工资报酬" :span="2">
          <span v-if="formData.salarySelect === 'A'">
            A、乙方的工资报酬按照甲方依法制定的规章制度中的内部工资分配办法确定,根据乙方的工作岗位确定其每月工资。
          </span>
          <span v-else-if="formData.salarySelect === 'B'">
            B、甲方对乙方实行基本工资和绩效工资相结合的内部工资分配办法,乙方的收入包括基本工资、误餐、交通、生活住宿等各项补助,如有变动根据内部工资分配办法调整其工资;绩效工资根据乙方的工作业绩、劳动成果和实际贡献按照内部分配办法考核确定。
          </span>
          <span v-else-if="formData.salarySelect === 'C'">
            C、甲方实行计件工资制,以甲方接到订单及公司生产计划,按照定额和计件单价,根据乙方完成的业绩,按时足额支付乙方的工资报酬。
          </span>
          <span v-else>-</span>
        </el-descriptions-item>
        <el-descriptions-item label="福利待遇" :span="2">{{ formData.remark || '-' }}</el-descriptions-item>
      </el-descriptions>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="closeDia">取消</el-button>
          <el-button @click="closeDia">关闭</el-button>
        </div>
      </template>
    </el-dialog>
@@ -23,38 +65,67 @@
</template>
<script setup>
import {ref} from "vue";
import {staffOnJobInfo} from "@/api/personnelManagement/employeeRecord.js";
const { proxy } = getCurrentInstance()
import {ref, reactive, computed} from "vue";
const emit = defineEmits(['close'])
const dialogFormVisible = ref(false);
const operationType = ref('')
const tableColumn = ref([
  // {
  //   label: "合同年限",
  //   prop: "contractTerm",
  // },
  {
    label: "合同开始日期",
    prop: "contractStartTime",
  },
  {
    label: "合同结束日期",
    prop: "contractEndTime",
  },
]);
const tableData = ref([]);
const tableLoading = ref(false);
const formData = reactive({
  staffNo: "",
  staffName: "",
  sex: "",
  identityCard: "",
  nativePlace: "",
  postJob: "",
  adress: "",
  firstStudy: "",
  profession: "",
  age: 0,
  phone: "",
  emergencyContact: "",
  emergencyContactPhone: "",
  dateSelect: "",
  trialStartDate: "",
  trialEndDate: "",
  proSalary: null,
  signDate: "",
  salarySelect: "",
  contractStartTime: "",
  contractEndTime: "",
  contractTerm: null,
  remark: "",
});
const formattedContractTerm = computed(() => {
  const value = formData.contractTerm;
  if (value === null || value === undefined || value === "") {
    return "-";
  }
  const numberValue = Number(value);
  if (!isNaN(numberValue)) {
    return `${numberValue}年`;
  }
  return value;
});
// 打开弹框
const openDialog = (type, row) => {
  operationType.value = type;
  dialogFormVisible.value = true;
  if (operationType.value === 'edit') {
    staffOnJobInfo({staffNo: row.staffNo}).then(res => {
      tableData.value = res.data
    })
  // 重置表单数据
  Object.keys(formData).forEach(key => {
    if (key === 'age') {
      formData[key] = 0;
    } else if (["proSalary", "contractTerm"].includes(key)) {
      formData[key] = null;
    } else {
      formData[key] = "";
    }
  });
  if (operationType.value === 'edit' && row) {
    // 直接使用 row 数据赋值
    Object.assign(formData, row);
  }
}
@@ -69,5 +140,25 @@
</script>
<style scoped>
.detail-descriptions {
  margin-bottom: 16px;
  border-radius: 6px;
  overflow: hidden;
}
.detail-descriptions :deep(.el-descriptions__cell) {
  padding: 12px 16px !important;
}
.detail-descriptions :deep(.el-descriptions__label) {
  width: 140px;
  color: #606266;
  background-color: #f7f9fc;
  font-weight: 500;
}
.detail-descriptions :deep(.el-descriptions__content) {
  color: #303133;
  line-height: 20px;
}
</style>
src/views/personnelManagement/onboarding/components/formDiaXJHT.vue
@@ -60,6 +60,11 @@
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
                        <el-form-item label="身份证号:" prop="identityCard">
                            <el-input v-model="form.identityCard" placeholder="请输入身份证号码" clearable maxlength="18" />
                        </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>
@@ -84,9 +89,9 @@
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="合同签订日期:" prop="trialStartDate">
            <el-form-item label="合同签订日期:" prop="signDate">
              <el-date-picker
                  v-model="form.trialStartDate"
                  v-model="form.signDate"
                  type="date"
                  placeholder="请选择日期"
                  value-format="YYYY-MM-DD"
@@ -116,9 +121,9 @@
        </el-row>
        <el-row :gutter="30" v-if="showProbationDates">
          <el-col :span="12">
            <el-form-item label="试用期开始日期:" prop="signDate">
            <el-form-item label="试用期开始日期:" prop="trialStartDate">
              <el-date-picker
                  v-model="form.signDate"
                  v-model="form.trialStartDate"
                  type="date"
                  placeholder="请选择日期"
                  value-format="YYYY-MM-DD"
@@ -142,13 +147,13 @@
            </el-form-item>
          </el-col>
        </el-row>
<!--        <el-row :gutter="30">-->
<!--          <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="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">
@@ -160,6 +165,7 @@
                  format="YYYY-MM-DD"
                  clearable
                  style="width: 100%"
                                    @change="calculateContractTerm"
              />
            </el-form-item>
          </el-col>
@@ -173,6 +179,7 @@
                  format="YYYY-MM-DD"
                  clearable
                  style="width: 100%"
                                    @change="calculateContractTerm"
              />
            </el-form-item>
          </el-col>
@@ -234,6 +241,7 @@
    staffNo: "",
    staffName: "",
    sex: "",
    identityCard: "",
    nativePlace: "",
    postJob: "",
    adress: "",
@@ -244,12 +252,12 @@
    emergencyContact: "",
    emergencyContactPhone: "",
    dateSelect: "",
    signDate: "",
        trialStartDate: "",
    trialEndDate: "",
    proSalary: null,
    trialStartDate: "",
    signDate: "",
    salarySelect: "",
    // contractTerm: 0,
    contractTerm: 0,
    contractStartTime: "",
    contractEndTime: "",
    staffState: "",
@@ -258,6 +266,7 @@
    staffNo: [{ required: true, message: "请输入", trigger: "blur" },],
    staffName: [{ required: true, message: "请输入", trigger: "blur" }],
    sex: [{ required: true, message: "请输入", trigger: "blur" }],
    identityCard: [{ required: true, message: "请输入身份证号码", trigger: "blur" }],
    nativePlace: [{ required: true, message: "请输入", trigger: "blur" }],
    postJob: [{ required: true, message: "请输入", trigger: "blur" }],
    adress: [{ required: true, message: "请输入", trigger: "blur" }],
@@ -268,11 +277,11 @@
    emergencyContact: [{ required: true, message: "请输入", trigger: "blur" }],
        remark: [{ required: false, message: "请输入", trigger: "blur" }],
    dateSelect: [{ required: true, message: "请选择劳动合同期限", trigger: "change" }],
    signDate: [{ required: true, message: "请选择", trigger: "change" }],
    trialEndDate: [{ required: true, message: "请选择", trigger: "change" }],
    trialStartDate: [{ required: true, message: "请选择", trigger: "change" }],
    trialEndDate: [{ required: true, message: "请选择", trigger: "change" }],
    signDate: [{ required: true, message: "请选择", trigger: "change" }],
    salarySelect: [{ required: true, message: "请选择工资报酬方式", trigger: "change" }],
    // contractTerm: [{ required: true, message: "请输入", trigger: "blur" }],
    contractTerm: [{ required: true, message: "请输入", trigger: "blur" }],
    contractStartTime: [{ required: true, message: "请输入", trigger: "blur" }],
    contractEndTime: [{ required: true, message: "请输入", trigger: "blur" }],
  },
@@ -302,7 +311,7 @@
    getStaffJoinInfo(row.id).then(res => {
      form.value = {...res.data}
      // 编辑时也计算一次合同年限
      // calculateContractTerm();
      calculateContractTerm();
    })
  }
}
@@ -326,32 +335,32 @@
  })
}
// 计算合同年限
// 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 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 = () => {
src/views/personnelManagement/onboarding/index.vue
@@ -57,8 +57,8 @@
<script setup>
import { Search } from "@element-plus/icons-vue";
import {onMounted, ref} from "vue";
import FormDia from "@/views/personnelManagement/onboarding/components/formDia.vue";
// import FormDia from "@/views/personnelManagement/onboarding/components/formDiaXJHT.vue"; // 新疆食品公司用的表单
// import FormDia from "@/views/personnelManagement/onboarding/components/formDia.vue";
import FormDia from "@/views/personnelManagement/onboarding/components/formDiaXJHT.vue"; // 新疆食品公司用的表单
import {staffJoinDel, staffJoinListPage} from "@/api/personnelManagement/onboarding.js";
import {ElMessageBox} from "element-plus";
import dayjs from "dayjs";