| | |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="开户行:" prop="bankAccountName"> |
| | | <el-input |
| | | v-model="form.bankAccountName" |
| | | placeholder="请输入" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="账号:" prop="bankAccountNum"> |
| | | <el-input |
| | | v-model="form.bankAccountNum" |
| | | placeholder="请输入" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="联系人:" prop="contactUserName"> |
| | | <el-input |
| | | v-model="form.contactUserName" |
| | |
| | | label: "联系方式", |
| | | prop: "companyPhone", |
| | | width:150 |
| | | }, |
| | | { |
| | | label: "开户行", |
| | | prop: "bankAccountName", |
| | | width: 220, |
| | | }, |
| | | { |
| | | label: "账号", |
| | | prop: "bankAccountNum", |
| | | width: 220, |
| | | }, |
| | | { |
| | | label: "联系人", |
| | |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="开户行:" prop="bankAccountName"> |
| | | <el-input |
| | | v-model="form.bankAccountName" |
| | | placeholder="请输入" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="账号:" prop="bankAccountNum"> |
| | | <el-input |
| | | v-model="form.bankAccountNum" |
| | | placeholder="请输入" |
| | | clearable |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="联系人:" prop="contactUserName"> |
| | | <el-input |
| | | v-model="form.contactUserName" |
| | |
| | | label: "联系方式", |
| | | prop: "companyPhone", |
| | | width:150 |
| | | }, |
| | | { |
| | | label: "开户行", |
| | | prop: "bankAccountName", |
| | | width: 220, |
| | | }, |
| | | { |
| | | label: "账号", |
| | | prop: "bankAccountNum", |
| | | width: 220, |
| | | }, |
| | | { |
| | | label: "联系人", |
| | |
| | | } |
| | | }, |
| | | { |
| | | name: "问答", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | openChatDialog(row); |
| | | } |
| | | }, |
| | | { |
| | | name: "详情", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | |
| | | <el-form-item label="班次" |
| | | prop="shift"> |
| | | <el-select v-model="form.shift" |
| | | placeholder="请选择班次" |
| | | placeholder="请选择或输入班次" |
| | | filterable |
| | | allow-create |
| | | default-first-option |
| | | :disabled="operationType === 'view'" |
| | | style="width: 100%"> |
| | | <el-option v-for="item in shifts_list" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | :disabled=" |
| | | operationType === 'add' && |
| | | (String(item.label || '').includes('假') || |
| | | String(item.label || '').includes('休')) |
| | | " /> |
| | | :value="item.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="打卡范围(m)" |
| | |
| | | // 获取班次字典值 |
| | | const { shifts_list } = useDict("shifts_list"); |
| | | |
| | | const selectedShiftLabel = computed(() => { |
| | | const item = shifts_list.value?.find( |
| | | s => String(s.value) === String(form.shift) |
| | | ); |
| | | return item?.label || ""; |
| | | }); |
| | | |
| | | const hideClockFields = computed(() => { |
| | | if (props.operationType === "view") return false; |
| | | return ( |
| | | selectedShiftLabel.value.includes("假") || |
| | | selectedShiftLabel.value.includes("休") |
| | | ); |
| | | const shiftName = form.shift || ""; |
| | | return shiftName.includes("假") || shiftName.includes("休"); |
| | | }); |
| | | |
| | | // 表单数据 |
| | |
| | | </el-form-item> |
| | | <el-form-item label="班次:" |
| | | prop="shift"> |
| | | <el-select v-model="searchForm.shift" |
| | | placeholder="请选择班次" |
| | | clearable |
| | | style="width: 200px"> |
| | | <el-option |
| | | v-for="item in shifts_list" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | <el-input v-model="searchForm.shift" |
| | | placeholder="请输入班次" |
| | | clearable |
| | | style="width: 200px" |
| | | @keyup.enter="handleSearch" /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" |
| | |
| | | // 查询班次列表 |
| | | const fetchData = () => { |
| | | tableLoading.value = true; |
| | | getAttendanceRules({ ...page, ...searchForm }) |
| | | const params = { ...page }; |
| | | if (searchForm.sysDeptId) params.sysDeptId = searchForm.sysDeptId; |
| | | if (searchForm.shift) params.shift = searchForm.shift; |
| | | getAttendanceRules(params) |
| | | .then(res => { |
| | | const records = Array.isArray(res?.data?.records) ? res.data.records : []; |
| | | tableData.value = records.filter(r => String(r?.id) !== "999"); |
| | |
| | | class="shift-dropdown"> |
| | | <div class="shift-box" |
| | | :class="{ |
| | | 'shift-box-early': m.shift === '早班', |
| | | 'shift-box-mid': m.shift === '中班', |
| | | 'shift-box-night': m.shift === '夜班', |
| | | 'shift-box-early': m.shift && m.shift.includes('早班'), |
| | | 'shift-box-mid': m.shift && m.shift.includes('中班'), |
| | | 'shift-box-night': m.shift && m.shift.includes('夜班'), |
| | | 'shift-box-rest': !m.shift || m.shift === '休息', |
| | | 'shift-box-leave': m.shift === '请假', |
| | | 'shift-box-other': m.shift === '夜11', |
| | |
| | | </div> |
| | | <template #dropdown> |
| | | <el-dropdown-menu> |
| | | <el-dropdown-item v-for="(n, j) in classType" |
| | | <el-dropdown-item v-for="(n, j) in getRowClassType(item)" |
| | | :key="'h' + j" |
| | | :command="n.id">{{ n.shift || '—' |
| | | }}</el-dropdown-item> |
| | |
| | | if (!schedulingQuery.deptId) return classType.value || []; |
| | | return (classType.value || []).filter(item => { |
| | | if (["998", "999"].includes(String(item?.id))) return true; |
| | | const itemDeptId = item.deptId ?? item.sysDeptId ?? item.dept_id; |
| | | const itemDeptId = item.sysDeptId ?? item.deptId ?? item.dept_id; |
| | | return String(itemDeptId) === String(schedulingQuery.deptId); |
| | | }); |
| | | }); |
| | | |
| | | // 格子内改班次时,按该员工的部门过滤可选班次(避免不同部门的同名班次混淆) |
| | | const getRowClassType = row => { |
| | | const list = classType.value || []; |
| | | const staffId = row?.userId ?? row?.user_id ?? row?.id; |
| | | const staff = (personListAll.value || []).find( |
| | | item => String(item.id) === String(staffId) |
| | | ); |
| | | const deptId = staff?.sysDeptId ?? staff?.deptId ?? staff?.dept_id; |
| | | if (!deptId) return list; |
| | | return list.filter(item => { |
| | | if (["998", "999"].includes(String(item?.id))) return true; |
| | | const itemDeptId = item.sysDeptId ?? item.deptId ?? item.dept_id; |
| | | return String(itemDeptId) === String(deptId); |
| | | }); |
| | | }; |
| | | |
| | | // 列表数据 |
| | | const listForm = ref([]); |
| | |
| | | const node = findDeptNodeById(schedulingQuery.deptId); |
| | | const deptIds = new Set(collectDeptIds(node)); |
| | | personList.value = (personListAll.value || []).filter(item => { |
| | | const itemDeptId = item.deptId ?? item.sysDeptId ?? item.dept_id; |
| | | const itemDeptId = item.sysDeptId ?? item.deptId ?? item.dept_id; |
| | | return deptIds.has(String(itemDeptId)) && !isEmployeeBlockedByLeaveDate(item); |
| | | }); |
| | | }; |
| | |
| | | prop: "contractStartTime", |
| | | }, |
| | | { |
| | | label: "合同结束日期", |
| | | prop: "contractEndTime", |
| | | }, |
| | | { |
| | | dataType: "action", |
| | | label: "操作", |
| | | align: "center", |
| | |
| | | <span class="search_title">姓名:</span> |
| | | <el-input v-model="searchForm.staffName" style="width: 240px" placeholder="请输入姓名搜索" @change="handleQuery" |
| | | clearable :prefix-icon="Search" /> |
| | | <span style="margin-left: 10px" class="search_title">合同结束日期:</span> |
| | | <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange" |
| | | placeholder="请选择" clearable @change="changeDaterange" /> |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px">搜索</el-button> |
| | | </div> |
| | | <div> |
| | |
| | | <div class="table_list"> |
| | | <PIMTable rowKey="id" :column="tableColumn" :tableData="tableData" :page="page" :isSelection="true" |
| | | @selection-change="handleSelectionChange" :tableLoading="tableLoading" @pagination="pagination" |
| | | :total="page.total"></PIMTable> |
| | | :total="page.total"> |
| | | <template #age="{ row }"> |
| | | <span>{{ calcAge(row.birthDate) }}</span> |
| | | </template> |
| | | <template #contractTime="{ row }"> |
| | | <span>{{ formatContractTime(row) }}</span> |
| | | </template> |
| | | </PIMTable> |
| | | </div> |
| | | <form-dia ref="formDia" @close="handleQuery"></form-dia> |
| | | <renew-contract |
| | |
| | | |
| | | <script setup> |
| | | import { Search } from "@element-plus/icons-vue"; |
| | | import dayjs from "dayjs"; |
| | | import { onMounted, ref, defineAsyncComponent } from "vue"; |
| | | import FormDia from "@/views/personnelManagement/contractManagement/components/formDia.vue"; |
| | | const RenewContract = defineAsyncComponent(() => import("@/views/personnelManagement/employeeRecord/components/RenewContract.vue")); |
| | | import { ElMessageBox } from "element-plus"; |
| | | import { staffOnJobListPage } from "@/api/personnelManagement/staffOnJob.js"; |
| | | import dayjs from "dayjs"; |
| | | import { getToken } from "@/utils/auth.js"; |
| | | import FilesDia from "./filesDia.vue"; |
| | | const data = reactive({ |
| | | searchForm: { |
| | | staffName: "", |
| | | entryDate: null, // 录入日期 |
| | | entryDateStart: undefined, |
| | | entryDateEnd: undefined, |
| | | }, |
| | | }); |
| | | const { searchForm } = toRefs(data); |
| | |
| | | prop: "sex", |
| | | }, |
| | | { |
| | | label: "户籍住址", |
| | | prop: "nativePlace", |
| | | label: "年龄", |
| | | prop: "age", |
| | | dataType: "slot", |
| | | slot: "age", |
| | | }, |
| | | // { |
| | | // label: "岗位", |
| | |
| | | // width: 200 |
| | | // }, |
| | | { |
| | | label: "第一学历", |
| | | prop: "firstStudy", |
| | | }, |
| | | { |
| | | label: "专业", |
| | | prop: "profession", |
| | | width: 100 |
| | | }, |
| | | { |
| | | label: "年龄", |
| | | prop: "age", |
| | | }, |
| | | { |
| | | label: "联系电话", |
| | | prop: "phone", |
| | | width: 150 |
| | | }, |
| | | { |
| | | label: "合同时间", |
| | | prop: "contractTime", |
| | | dataType: "slot", |
| | | slot: "contractTime", |
| | | width: 200, |
| | | }, |
| | | // { |
| | | // label: "紧急联系人", |
| | |
| | | // prop: "contractStartTime", |
| | | // width: 120 |
| | | // }, |
| | | { |
| | | label: "合同结束日期", |
| | | prop: "contractExpireTime", |
| | | width: 120 |
| | | }, |
| | | { |
| | | dataType: "action", |
| | | label: "操作", |
| | |
| | | const formDia = ref() |
| | | const { proxy } = getCurrentInstance() |
| | | |
| | | const changeDaterange = (value) => { |
| | | searchForm.value.entryDateStart = undefined; |
| | | searchForm.value.entryDateEnd = undefined; |
| | | if (value) { |
| | | searchForm.value.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD"); |
| | | searchForm.value.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD"); |
| | | // 根据出生日期计算年龄 |
| | | const calcAge = (birth) => { |
| | | if (!birth) return "-"; |
| | | const birthDay = dayjs(birth); |
| | | const now = dayjs(); |
| | | let age = now.year() - birthDay.year(); |
| | | if (now.month() < birthDay.month() || (now.month() === birthDay.month() && now.date() < birthDay.date())) { |
| | | age--; |
| | | } |
| | | getList(); |
| | | return age; |
| | | }; |
| | | |
| | | // 合同时间(开始 ~ 结束) |
| | | const formatContractTime = (row) => { |
| | | const start = row.contractStartTime; |
| | | const end = row.contractEndTime; |
| | | if (start && end) return `${start} ~ ${end}`; |
| | | return start || end || "-"; |
| | | }; |
| | | |
| | | // 打开附件弹框 |
| | | const openFilesFormDia = (row) => { |
| | | console.log(row) |
| | |
| | | const getList = () => { |
| | | tableLoading.value = true; |
| | | const params = { ...searchForm.value, ...page }; |
| | | params.entryDate = undefined |
| | | params.staffState = 1 |
| | | staffOnJobListPage(params).then(res => { |
| | | tableLoading.value = false; |