| | |
| | | <el-tab-pane label="假期设置" name="holiday"> |
| | | <div class="tab-content"> |
| | | <el-button type="primary" @click="openDialog('holiday', 'add')">新增假期</el-button> |
| | | |
| | | |
| | | <el-table :data="holidayData" border style="width: 100%; margin-top: 20px;"> |
| | | <el-table-column prop="name" label="假期名称" /> |
| | | <el-table-column prop="type" label="假期类型"> |
| | |
| | | </el-table-column> |
| | | <el-table-column label="操作" fixed="right"> |
| | | <template #default="scope"> |
| | | <el-button type="primary" link @click="openDialog('holiday', 'edit', scope.row)">编辑</el-button> |
| | | <el-button type="danger" link @click="deleteItem('holiday', scope.row)">删除</el-button> |
| | | <el-button type="primary" size="small" @click="openDialog('holiday', 'edit', scope.row)">编辑</el-button> |
| | | <el-button type="danger" size="small" @click="deleteItem('holiday', scope.row)">删除</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | |
| | | <el-tab-pane label="年假设置" name="annual"> |
| | | <div class="tab-content"> |
| | | <el-button type="primary" @click="openDialog('annual', 'add')">新增年假规则</el-button> |
| | | |
| | | |
| | | <el-table :data="annualData" border style="width: 100%; margin-top: 20px;"> |
| | | <el-table-column prop="employeeType" label="员工类型"/> |
| | | <el-table-column prop="employeeType" label="员工类型"> |
| | | <template #default="scope"> |
| | | <el-tag :type="getTagType(scope.row.employeeType)">{{ getTypeLabel(scope.row.employeeType) }}</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="workYears" label="工作年限" /> |
| | | <el-table-column prop="annualDays" label="年假天数" align="center" /> |
| | | <el-table-column prop="maxCarryOver" label="最大结转天数" align="center" /> |
| | |
| | | </el-table-column> |
| | | <el-table-column label="操作" fixed="right"> |
| | | <template #default="scope"> |
| | | <el-button type="primary" link @click="openDialog('annual', 'edit', scope.row)">编辑</el-button> |
| | | <el-button type="danger" link @click="deleteItem('annual', scope.row)">删除</el-button> |
| | | <el-button type="primary" size="small" @click="openDialog('annual', 'edit', scope.row)">编辑</el-button> |
| | | <el-button type="danger" size="small" @click="deleteItem('annual', scope.row)">删除</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | |
| | | <el-tab-pane label="加班设置" name="overtime"> |
| | | <div class="tab-content"> |
| | | <el-button type="primary" @click="openDialog('overtime', 'add')">新增加班规则</el-button> |
| | | |
| | | |
| | | <el-table :data="overtimeData" border style="width: 100%; margin-top: 20px;"> |
| | | <el-table-column prop="name" label="规则名称" /> |
| | | <el-table-column prop="type" label="加班类型" > |
| | |
| | | </el-table-column> |
| | | <el-table-column label="操作" fixed="right"> |
| | | <template #default="scope"> |
| | | <el-button type="primary" link @click="openDialog('overtime', 'edit', scope.row)">编辑</el-button> |
| | | <el-button type="danger" link @click="deleteItem('overtime', scope.row)">删除</el-button> |
| | | <el-button type="primary" size="small" @click="openDialog('overtime', 'edit', scope.row)">编辑</el-button> |
| | | <el-button type="danger" size="small" @click="deleteItem('overtime', scope.row)">删除</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | |
| | | <el-tab-pane label="上班时间设置" name="worktime"> |
| | | <div class="tab-content"> |
| | | <el-button type="primary" @click="openDialog('worktime', 'add')">新增时间段</el-button> |
| | | |
| | | |
| | | <el-table :data="worktimeData" border style="width: 100%; margin-top: 20px;"> |
| | | <el-table-column prop="name" label="时间段名称" /> |
| | | <el-table-column prop="startTime" label="上班时间"/> |
| | | <el-table-column prop="endTime" label="下班时间" /> |
| | | <el-table-column prop="flexibleStart" label="弹性上班"> |
| | | <template #default="scope"> |
| | | <el-tag :type="scope.row.flexibleStart ? 'success' : 'info'"> |
| | | {{ scope.row.flexibleStart ? '是' : '否' }} |
| | | <el-tag :type="scope.row.flexibleStart === 'true' ? 'success' : 'info'"> |
| | | {{ scope.row.flexibleStart === 'true' ? '是' : '否' }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | |
| | | </el-table-column> |
| | | <el-table-column label="操作" fixed="right"> |
| | | <template #default="scope"> |
| | | <el-button type="primary" link @click="openDialog('worktime', 'edit', scope.row)">编辑</el-button> |
| | | <el-button type="danger" link @click="deleteItem('worktime', scope.row)">删除</el-button> |
| | | <el-button type="primary" size="small" @click="openDialog('worktime', 'edit', scope.row)">编辑</el-button> |
| | | <el-button type="danger" size="small" @click="deleteItem('worktime', scope.row)">删除</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | </el-tab-pane> |
| | | |
| | | <!-- 打卡记录 --> |
| | | <el-tab-pane label="打卡记录" name="attendance"> |
| | | <div class="tab-content"> |
| | | <div style="margin-bottom: 20px;"> |
| | | <el-date-picker |
| | | v-model="attendanceDate" |
| | | type="date" |
| | | placeholder="选择日期" |
| | | format="YYYY-MM-DD" |
| | | value-format="YYYY-MM-DD" |
| | | style="margin-right: 10px;" |
| | | @change="filterAttendanceData" |
| | | /> |
| | | <el-select |
| | | v-model="attendanceStatus" |
| | | placeholder="选择状态" |
| | | style="width: 120px; margin-right: 10px;" |
| | | @change="filterAttendanceData" |
| | | > |
| | | <el-option label="全部" value="" /> |
| | | <el-option label="正常" value="normal" /> |
| | | <el-option label="迟到" value="late" /> |
| | | <el-option label="早退" value="early" /> |
| | | <el-option label="缺勤" value="absent" /> |
| | | </el-select> |
| | | <el-button type="primary" @click="exportAttendance">导出记录</el-button> |
| | | </div> |
| | | |
| | | <el-table :data="filteredAttendanceData" border style="width: 100%;"> |
| | | <el-table-column prop="employeeName" label="员工姓名" width="120" /> |
| | | <el-table-column prop="department" label="部门" width="120" /> |
| | | <el-table-column prop="date" label="日期" width="120" /> |
| | | <el-table-column prop="clockInTime" label="上班打卡" width="120" /> |
| | | <el-table-column prop="clockOutTime" label="下班打卡" width="120" /> |
| | | <el-table-column prop="workHours" label="工作时长" width="100" align="center" /> |
| | | <el-table-column prop="status" label="状态" width="100" align="center"> |
| | | <template #default="scope"> |
| | | <el-tag :type="getAttendanceTagType(scope.row.status)">{{ getAttendanceStatusLabel(scope.row.status) }}</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="location" label="打卡地点" width="150" /> |
| | | <el-table-column prop="remark" label="备注" min-width="150" /> |
| | | </el-table> |
| | | </div> |
| | | </el-tab-pane> |
| | |
| | | <el-form-item label="名称" prop="name" v-if="currentType !== 'annual'"> |
| | | <el-input v-model="form.name" placeholder="请输入名称" /> |
| | | </el-form-item> |
| | | |
| | | |
| | | <el-form-item label="类型" prop="type" v-if="currentType === 'holiday' || currentType === 'overtime'"> |
| | | <el-select v-model="form.type" placeholder="请选择类型" style="width: 100%"> |
| | | <el-option |
| | | v-for="option in getTypeOptions()" |
| | | :key="option.value" |
| | | :label="option.label" |
| | | :value="option.value" |
| | | <el-option |
| | | v-for="option in getTypeOptions()" |
| | | :key="option.value" |
| | | :label="option.label" |
| | | :value="option.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="员工类型" prop="employeeType" v-if="currentType === 'annual'"> |
| | | <el-select v-model="form.employeeType" placeholder="请选择员工类型" style="width: 100%"> |
| | | <el-option label="正式员工" value="regular" /> |
| | | <!-- <el-option label="正式员工" value="regular" /> |
| | | <el-option label="试用期员工" value="probation" /> |
| | | <el-option label="实习生" value="intern" /> |
| | | <el-option label="实习生" value="intern" /> --> |
| | | <el-option |
| | | v-for="option in getTypeOptions()" |
| | | :key="option.value" |
| | | :label="option.label" |
| | | :value="option.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | |
| | | @change="validateTimeField('startTime')" |
| | | /> |
| | | </el-form-item> |
| | | |
| | | |
| | | <el-form-item label="结束时间" prop="endTime" v-if="currentType === 'overtime'"> |
| | | <el-time-picker |
| | | v-model="form.endTime" |
| | |
| | | <el-input-number v-model="form.flexibleMinutes" :min="0" :max="120" style="width: 100%" /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="状态" prop="status"> |
| | | <el-form-item label="状态" prop="status"> |
| | | <el-radio-group v-model="form.status"> |
| | | <el-radio value="active">启用</el-radio> |
| | | <el-radio value="inactive">停用</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button @click="dialogVisible = false">取消</el-button> |
| | |
| | | <script setup> |
| | | import { ref, reactive, onMounted, onUnmounted } from 'vue' |
| | | import { ElMessage, ElMessageBox } from 'element-plus' |
| | | import { listHolidaySettings, addHolidaySettings, updateHolidaySettings, delHolidaySettings, listAnnualLeaveSettingList, addAnnualLeaveSetting, updateAnnualLeaveSetting, delAnnualLeaveSetting, listOvertimeSettingList, addOvertimeSetting, updateOvertimeSetting, delOvertimeSetting, listWorkingHoursSettingList, addWorkingHoursSetting, updateWorkingHoursSetting, delWorkingHoursSetting } from '@/api/collaborativeApproval/attendanceManagement.js' |
| | | |
| | | // 当前激活的标签页 |
| | | const activeTab = ref('holiday') |
| | |
| | | const currentAction = ref('') |
| | | const currentEditId = ref('') |
| | | const formRef = ref() |
| | | const page = { |
| | | current: 1, |
| | | size: 20, |
| | | total: 0, |
| | | } |
| | | const holidayData = ref([]) |
| | | const annualData = ref([]) |
| | | const overtimeData = ref([]) |
| | | const worktimeData = ref([]) |
| | | |
| | | // 打卡记录相关数据 |
| | | const attendanceData = ref([]) |
| | | const filteredAttendanceData = ref([]) |
| | | const attendanceDate = ref('') |
| | | const attendanceStatus = ref('') |
| | | |
| | | // 表单数据 |
| | | const form = reactive({ |
| | | name: '', |
| | | type: '', |
| | | dateRange: [], |
| | | startDate: '', |
| | | endDate: '', |
| | | days: 0, |
| | | employeeType: '', |
| | | workYears: '', |
| | |
| | | workYears: [{ required: true, message: '请输入工作年限', trigger: 'blur' }], |
| | | annualDays: [{ required: true, message: '请输入年假天数', trigger: 'blur' }], |
| | | maxCarryOver: [{ required: true, message: '请输入最大结转天数', trigger: 'blur' }], |
| | | startTime: [{ |
| | | required: true, |
| | | message: '请选择开始时间', |
| | | startTime: [{ |
| | | required: true, |
| | | message: '请选择开始时间', |
| | | trigger: 'change', |
| | | validator: (rule, value, callback) => { |
| | | if (!value) { |
| | |
| | | } |
| | | } |
| | | }], |
| | | endTime: [{ |
| | | required: true, |
| | | message: '请选择结束时间', |
| | | endTime: [{ |
| | | required: true, |
| | | message: '请选择结束时间', |
| | | trigger: 'change', |
| | | validator: (rule, value, callback) => { |
| | | if (!value) { |
| | |
| | | } |
| | | } |
| | | }], |
| | | workStartTime: [{ |
| | | required: true, |
| | | message: '请选择上班时间', |
| | | workStartTime: [{ |
| | | required: true, |
| | | message: '请选择上班时间', |
| | | trigger: 'change', |
| | | validator: (rule, value, callback) => { |
| | | if (!value) { |
| | |
| | | } |
| | | } |
| | | }], |
| | | workEndTime: [{ |
| | | required: true, |
| | | message: '请选择下班时间', |
| | | workEndTime: [{ |
| | | required: true, |
| | | message: '请选择下班时间', |
| | | trigger: 'change', |
| | | validator: (rule, value, callback) => { |
| | | if (!value) { |
| | |
| | | }], |
| | | rate: [{ required: true, message: '请输入倍率', trigger: 'blur' }] |
| | | } |
| | | |
| | | // 模拟数据 |
| | | const holidayData = ref([ |
| | | { id: '1', name: '春节', type: 'legal', startDate: '2024-02-10', endDate: '2024-02-17', days: 8, status: 'active' }, |
| | | { id: '2', name: '清明节', type: 'legal', startDate: '2024-04-05', endDate: '2024-04-05', days: 1, status: 'active' }, |
| | | { id: '3', name: '劳动节', type: 'legal', startDate: '2024-05-01', endDate: '2024-05-05', days: 5, status: 'active' } |
| | | ]) |
| | | |
| | | const annualData = ref([ |
| | | { id: '1', employeeType: 'regular', workYears: '1-3年', annualDays: 5, maxCarryOver: 2, status: 'active' }, |
| | | { id: '2', employeeType: 'regular', workYears: '3-5年', annualDays: 10, maxCarryOver: 5, status: 'active' }, |
| | | { id: '3', employeeType: 'regular', workYears: '5年以上', annualDays: 15, maxCarryOver: 10, status: 'active' } |
| | | ]) |
| | | |
| | | const overtimeData = ref([ |
| | | { id: '1', name: '工作日加班', type: 'weekday', startTime: '18:00', endTime: '22:00', rate: 1.5, status: 'active' }, |
| | | { id: '2', name: '周末加班', type: 'weekend', startTime: '09:00', endTime: '18:00', rate: 2.0, status: 'active' }, |
| | | { id: '3', name: '深夜加班', type: 'night', startTime: '22:00', endTime: '06:00', rate: 2.5, status: 'active' } |
| | | ]) |
| | | |
| | | const worktimeData = ref([ |
| | | { id: '1', name: '标准工作时间', startTime: '09:00', endTime: '18:00', flexibleStart: true, flexibleMinutes: 30, status: 'active' }, |
| | | { id: '2', name: '早班时间', startTime: '08:00', endTime: '17:00', flexibleStart: false, flexibleMinutes: 0, status: 'active' }, |
| | | { id: '3', name: '晚班时间', startTime: '14:00', endTime: '23:00', flexibleStart: false, flexibleMinutes: 0, status: 'active' } |
| | | ]) |
| | | |
| | | // 工具函数 |
| | | const getTagType = (type) => { |
| | | const tagMap = { |
| | | legal: 'success', adjustment: 'warning', special: 'info', company: 'primary', |
| | | weekday: 'primary', weekend: 'warning', holiday: 'danger', night: 'info' |
| | | weekday: 'primary', weekend: 'warning', holiday: 'danger', night: 'info', |
| | | regular: 'success', probation: 'info', intern: 'danger' |
| | | } |
| | | return tagMap[type] || 'info' |
| | | } |
| | |
| | | const getTypeLabel = (type) => { |
| | | const labelMap = { |
| | | legal: '法定节假日', adjustment: '调休日', special: '特殊假期', company: '公司假期', |
| | | weekday: '工作日加班', weekend: '周末加班', holiday: '节假日加班', night: '深夜加班' |
| | | weekday: '工作日加班', weekend: '周末加班', holiday: '节假日加班', night: '深夜加班', |
| | | regular: '正式员工', probation: '试用期员工', intern: '实习生' |
| | | } |
| | | return labelMap[type] || type |
| | | } |
| | | |
| | | // 打卡记录相关工具函数 |
| | | const getAttendanceTagType = (status) => { |
| | | const tagMap = { |
| | | normal: 'success', |
| | | late: 'warning', |
| | | early: 'warning', |
| | | absent: 'danger' |
| | | } |
| | | return tagMap[status] || 'info' |
| | | } |
| | | |
| | | const getAttendanceStatusLabel = (status) => { |
| | | const labelMap = { |
| | | normal: '正常', |
| | | late: '迟到', |
| | | early: '早退', |
| | | absent: '缺勤' |
| | | } |
| | | return labelMap[status] || status |
| | | } |
| | | |
| | | const getTypeOptions = () => { |
| | |
| | | { label: '节假日加班', value: 'holiday' }, |
| | | { label: '深夜加班', value: 'night' } |
| | | ] |
| | | } else if (currentType.value === 'annual') { |
| | | return [ |
| | | { label: '正式员工', value: 'regular' }, |
| | | { label: '试用期员工', value: 'probation' }, |
| | | { label: '实习生', value: 'intern' } |
| | | ] |
| | | } |
| | | return [] |
| | | } |
| | |
| | | if (form.dateRange && form.dateRange.length === 2 && form.dateRange[0] && form.dateRange[1]) { |
| | | const start = new Date(form.dateRange[0]) |
| | | const end = new Date(form.dateRange[1]) |
| | | |
| | | form.startDate = start.toISOString().split('T')[0] |
| | | form.endDate = end.toISOString().split('T')[0] |
| | | |
| | | if (isNaN(start.getTime()) || isNaN(end.getTime())) { |
| | | console.warn('无效的日期格式') |
| | | return |
| | | } |
| | | |
| | | |
| | | const diffTime = Math.abs(end - start) |
| | | const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)) + 1 |
| | | form.days = diffDays |
| | |
| | | } |
| | | |
| | | // 验证时间格式 |
| | | const validateTime = (time) => { |
| | | if (!time) return '' |
| | | if (typeof time === 'string') return time |
| | | if (time instanceof Date) { |
| | | return time.toTimeString().slice(0, 5) |
| | | } |
| | | return '' |
| | | } |
| | | // const validateTime = (time) => { |
| | | // if (!time) return '' |
| | | // if (typeof time === 'string') return time |
| | | // if (time instanceof Date) { |
| | | // return time.toTimeString().slice(0, 5) |
| | | // } |
| | | // return '' |
| | | // } |
| | | |
| | | // 验证时间字段 |
| | | const validateTimeField = (fieldName) => { |
| | |
| | | try { |
| | | currentType.value = type |
| | | currentAction.value = action |
| | | |
| | | |
| | | if (action === 'add') { |
| | | dialogTitle.value = `新增${getTypeName(type)}` |
| | | currentEditId.value = '' |
| | |
| | | currentEditId.value = row.id |
| | | fillForm(row) |
| | | } |
| | | |
| | | |
| | | dialogVisible.value = true |
| | | } catch (error) { |
| | | console.error('打开弹窗失败:', error) |
| | |
| | | name: '', |
| | | type: '', |
| | | dateRange: [], |
| | | startDate: '', |
| | | endDate: '', |
| | | days: 0, |
| | | employeeType: '', |
| | | workYears: '', |
| | |
| | | name: row.name, |
| | | type: row.type, |
| | | dateRange: [new Date(row.startDate), new Date(row.endDate)], |
| | | startDate: row.startDate, |
| | | endDate: row.endDate, |
| | | days: row.days, |
| | | status: row.status |
| | | }) |
| | |
| | | ElMessage.error('表单引用不存在') |
| | | return |
| | | } |
| | | |
| | | |
| | | await formRef.value.validate() |
| | | |
| | | |
| | | if (currentAction.value === 'add') { |
| | | addItem() |
| | | } else if (currentAction.value === 'edit') { |
| | | editItem() |
| | | } |
| | | |
| | | |
| | | dialogVisible.value = false |
| | | ElMessage.success('操作成功') |
| | | } catch (error) { |
| | |
| | | } |
| | | |
| | | const addItem = () => { |
| | | const newItem = { ...form, id: Date.now().toString() } |
| | | |
| | | |
| | | if (currentType.value === 'holiday') { |
| | | newItem.startDate = form.dateRange[0].toISOString().split('T')[0] |
| | | newItem.endDate = form.dateRange[1].toISOString().split('T')[0] |
| | | holidayData.value.push(newItem) |
| | | const params = { |
| | | name: form.name, |
| | | type: form.type, |
| | | startDate: form.startDate, |
| | | endDate: form.endDate, |
| | | days: form.days, |
| | | status: form.status |
| | | } |
| | | addHolidaySettings(params).then(res => { |
| | | if(res.code == 200){ |
| | | ElMessage.success("添加成功"); |
| | | // dialogVisible.value = false; |
| | | getHolidaySettingsList() |
| | | } |
| | | }).catch(err => { |
| | | ElMessage.error(err.msg); |
| | | }) |
| | | } else if (currentType.value === 'annual') { |
| | | annualData.value.push(newItem) |
| | | // annualData.value.push(newItem) |
| | | const params = { |
| | | employeeType: form.employeeType, |
| | | workYears: form.workYears, |
| | | annualDays: form.annualDays, |
| | | maxCarryOver: form.maxCarryOver, |
| | | status: form.status |
| | | } |
| | | addAnnualLeaveSetting(params).then(res => { |
| | | if(res.code == 200){ |
| | | ElMessage.success("添加成功"); |
| | | // dialogVisible.value = false; |
| | | getAnnualLeaveSettingList() |
| | | } |
| | | }).catch(err => { |
| | | ElMessage.error(err.msg); |
| | | }) |
| | | } else if (currentType.value === 'overtime') { |
| | | newItem.startTime = form.startTime || '' |
| | | newItem.endTime = form.endTime || '' |
| | | overtimeData.value.push(newItem) |
| | | const params = { |
| | | name: form.name, |
| | | type: form.type, |
| | | startTime: form.startTime || '', |
| | | endTime: form.endTime || '', |
| | | rate: form.rate, |
| | | status: form.status |
| | | } |
| | | addOvertimeSetting(params).then(res => { |
| | | if(res.code == 200){ |
| | | ElMessage.success("添加成功"); |
| | | // dialogVisible.value = false; |
| | | getOvertimeSettingList() |
| | | } |
| | | }).catch(err => { |
| | | ElMessage.error(err.msg); |
| | | }) |
| | | // newItem.startTime = form.startTime || '' |
| | | // newItem.endTime = form.endTime || '' |
| | | // overtimeData.value.push(newItem) |
| | | } else if (currentType.value === 'worktime') { |
| | | newItem.startTime = form.workStartTime || '' |
| | | newItem.endTime = form.workEndTime || '' |
| | | worktimeData.value.push(newItem) |
| | | const params = { |
| | | name: form.name, |
| | | startTime: form.workStartTime || '', |
| | | endTime: form.workEndTime || '', |
| | | flexibleStart: form.flexibleStart, |
| | | flexibleMinutes: form.flexibleMinutes, |
| | | status: form.status |
| | | } |
| | | addWorkingHoursSetting(params).then(res => { |
| | | if(res.code == 200){ |
| | | ElMessage.success("添加成功"); |
| | | getWorkingHoursSettingList() |
| | | } |
| | | }).catch(err => { |
| | | ElMessage.error(err.msg); |
| | | }) |
| | | // newItem.startTime = form.workStartTime || '' |
| | | // newItem.endTime = form.workEndTime || '' |
| | | // worktimeData.value.push(newItem) |
| | | } |
| | | } |
| | | |
| | | const editItem = () => { |
| | | let dataArray |
| | | let index |
| | | |
| | | |
| | | if (currentType.value === 'holiday') { |
| | | dataArray = holidayData.value |
| | | index = dataArray.findIndex(item => item.id === currentEditId.value) |
| | | if (index > -1) { |
| | | dataArray[index] = { |
| | | ...dataArray[index], |
| | | name: form.name, |
| | | type: form.type, |
| | | startDate: form.dateRange[0].toISOString().split('T')[0], |
| | | endDate: form.dateRange[1].toISOString().split('T')[0], |
| | | days: form.days, |
| | | status: form.status |
| | | } |
| | | const params = { |
| | | id: currentEditId.value, |
| | | name: form.name, |
| | | type: form.type, |
| | | startDate: form.dateRange[0].toISOString().split('T')[0], |
| | | endDate: form.dateRange[1].toISOString().split('T')[0], |
| | | days: form.days, |
| | | status: form.status |
| | | } |
| | | updateHolidaySettings(params).then(res => { |
| | | if(res.code == 200){ |
| | | ElMessage.success("更新成功"); |
| | | // dialogVisible.value = false; |
| | | getHolidaySettingsList() |
| | | } |
| | | }).catch(err => { |
| | | ElMessage.error(err.msg); |
| | | }) |
| | | } else if (currentType.value === 'annual') { |
| | | dataArray = annualData.value |
| | | index = dataArray.findIndex(item => item.id === currentEditId.value) |
| | | if (index > -1) { |
| | | dataArray[index] = { |
| | | ...dataArray[index], |
| | | employeeType: form.employeeType, |
| | | workYears: form.workYears, |
| | | annualDays: form.annualDays, |
| | | maxCarryOver: form.maxCarryOver, |
| | | status: form.status |
| | | } |
| | | const params = { |
| | | id: currentEditId.value, |
| | | employeeType: form.employeeType, |
| | | workYears: form.workYears, |
| | | annualDays: form.annualDays, |
| | | maxCarryOver: form.maxCarryOver, |
| | | status: form.status |
| | | } |
| | | updateAnnualLeaveSetting(params).then(res => { |
| | | if(res.code == 200){ |
| | | ElMessage.success("更新成功"); |
| | | getAnnualLeaveSettingList() |
| | | } |
| | | }).catch(err => { |
| | | ElMessage.error(err.msg); |
| | | }) |
| | | } else if (currentType.value === 'overtime') { |
| | | dataArray = overtimeData.value |
| | | index = dataArray.findIndex(item => item.id === currentEditId.value) |
| | | if (index > -1) { |
| | | dataArray[index] = { |
| | | ...dataArray[index], |
| | | name: form.name, |
| | | type: form.type, |
| | | startTime: form.startTime || '', |
| | | endTime: form.endTime || '', |
| | | rate: form.rate, |
| | | status: form.status |
| | | } |
| | | const params = { |
| | | id: currentEditId.value, |
| | | name: form.name, |
| | | type: form.type, |
| | | startTime: form.startTime || '', |
| | | endTime: form.endTime || '', |
| | | rate: form.rate, |
| | | status: form.status |
| | | } |
| | | updateOvertimeSetting(params).then(res => { |
| | | if(res.code == 200){ |
| | | ElMessage.success("更新成功"); |
| | | getOvertimeSettingList() |
| | | } |
| | | }).catch(err => { |
| | | ElMessage.error(err.msg); |
| | | }) |
| | | |
| | | // dataArray = overtimeData.value |
| | | // index = dataArray.findIndex(item => item.id === currentEditId.value) |
| | | // if (index > -1) { |
| | | // dataArray[index] = { |
| | | // ...dataArray[index], |
| | | // name: form.name, |
| | | // type: form.type, |
| | | // startTime: form.startTime || '', |
| | | // endTime: form.endTime || '', |
| | | // rate: form.rate, |
| | | // status: form.status |
| | | // } |
| | | // } |
| | | } else if (currentType.value === 'worktime') { |
| | | dataArray = worktimeData.value |
| | | index = dataArray.findIndex(item => item.id === currentEditId.value) |
| | | if (index > -1) { |
| | | dataArray[index] = { |
| | | ...dataArray[index], |
| | | name: form.name, |
| | | startTime: form.workStartTime || '', |
| | | endTime: form.workEndTime || '', |
| | | flexibleStart: form.flexibleStart, |
| | | flexibleMinutes: form.flexibleMinutes, |
| | | status: form.status |
| | | } |
| | | const params = { |
| | | id: currentEditId.value, |
| | | name: form.name, |
| | | startTime: form.workStartTime || '', |
| | | endTime: form.workEndTime || '', |
| | | flexibleStart: form.flexibleStart, |
| | | flexibleMinutes: form.flexibleMinutes, |
| | | status: form.status |
| | | } |
| | | updateWorkingHoursSetting(params).then(res => { |
| | | if(res.code == 200){ |
| | | ElMessage.success("更新成功"); |
| | | getWorkingHoursSettingList() |
| | | } |
| | | }).catch(err => { |
| | | ElMessage.error(err.msg); |
| | | }) |
| | | // dataArray = worktimeData.value |
| | | // index = dataArray.findIndex(item => item.id === currentEditId.value) |
| | | // if (index > -1) { |
| | | // dataArray[index] = { |
| | | // ...dataArray[index], |
| | | // name: form.name, |
| | | // startTime: form.workStartTime || '', |
| | | // endTime: form.workEndTime || '', |
| | | // flexibleStart: form.flexibleStart, |
| | | // flexibleMinutes: form.flexibleMinutes, |
| | | // status: form.status |
| | | // } |
| | | // } |
| | | } |
| | | } |
| | | |
| | | // 打卡记录过滤功能 |
| | | const filterAttendanceData = () => { |
| | | let filtered = attendanceData.value |
| | | |
| | | // 按日期过滤 |
| | | if (attendanceDate.value) { |
| | | filtered = filtered.filter(item => item.date === attendanceDate.value) |
| | | } |
| | | |
| | | // 按状态过滤 |
| | | if (attendanceStatus.value) { |
| | | filtered = filtered.filter(item => item.status === attendanceStatus.value) |
| | | } |
| | | |
| | | filteredAttendanceData.value = filtered |
| | | } |
| | | |
| | | // 导出打卡记录 |
| | | const exportAttendance = () => { |
| | | ElMessage.success('导出功能开发中...') |
| | | } |
| | | |
| | | // 初始化打卡记录假数据 |
| | | const initAttendanceData = () => { |
| | | const mockData = [ |
| | | { |
| | | id: 1, |
| | | employeeName: '陈志强', |
| | | department: '技术部', |
| | | date: '2025-08-15', |
| | | clockInTime: '09:00:00', |
| | | clockOutTime: '18:00:00', |
| | | workHours: '8.0h', |
| | | status: 'normal', |
| | | location: '公司总部', |
| | | remark: '' |
| | | }, |
| | | { |
| | | id: 2, |
| | | employeeName: '李雪梅', |
| | | department: '市场部', |
| | | date: '2025-08-16', |
| | | clockInTime: '08:58:00', |
| | | clockOutTime: '18:05:00', |
| | | workHours: '8.12h', |
| | | status: 'normal', |
| | | location: '公司总部', |
| | | remark: '' |
| | | }, |
| | | { |
| | | id: 3, |
| | | employeeName: '王建华', |
| | | department: '人事部', |
| | | date: '2025-08-16', |
| | | clockInTime: '09:02:00', |
| | | clockOutTime: '18:00:00', |
| | | workHours: '7.97h', |
| | | status: 'normal', |
| | | location: '公司总部', |
| | | remark: '' |
| | | }, |
| | | { |
| | | id: 4, |
| | | employeeName: '赵晓丽', |
| | | department: '财务部', |
| | | date: '2025-09-02', |
| | | clockInTime: '08:55:00', |
| | | clockOutTime: '18:10:00', |
| | | workHours: '8.25h', |
| | | status: 'normal', |
| | | location: '公司总部', |
| | | remark: '' |
| | | }, |
| | | { |
| | | id: 5, |
| | | employeeName: '张国庆', |
| | | department: '技术部', |
| | | date: '2025-09-02', |
| | | clockInTime: '09:00:00', |
| | | clockOutTime: '18:30:00', |
| | | workHours: '8.5h', |
| | | status: 'normal', |
| | | location: '公司总部', |
| | | remark: '加班' |
| | | }, |
| | | { |
| | | id: 6, |
| | | employeeName: '刘明辉', |
| | | department: '运营部', |
| | | date: '2025-09-03', |
| | | clockInTime: '09:05:00', |
| | | clockOutTime: '18:00:00', |
| | | workHours: '7.92h', |
| | | status: 'normal', |
| | | location: '公司总部', |
| | | remark: '' |
| | | }, |
| | | { |
| | | id: 7, |
| | | employeeName: '孙丽华', |
| | | department: '设计部', |
| | | date: '2025-09-03', |
| | | clockInTime: '08:59:00', |
| | | clockOutTime: '18:02:00', |
| | | workHours: '8.05h', |
| | | status: 'normal', |
| | | location: '公司总部', |
| | | remark: '' |
| | | }, |
| | | { |
| | | id: 8, |
| | | employeeName: '周建军', |
| | | department: '销售部', |
| | | date: '2025-09-04', |
| | | clockInTime: '09:15:00', |
| | | clockOutTime: '18:00:00', |
| | | workHours: '7.75h', |
| | | status: 'late', |
| | | location: '公司总部', |
| | | remark: '交通堵塞' |
| | | }, |
| | | { |
| | | id: 9, |
| | | employeeName: '吴小芳', |
| | | department: '客服部', |
| | | date: '2025-09-04', |
| | | clockInTime: '09:01:00', |
| | | clockOutTime: '18:00:00', |
| | | workHours: '7.98h', |
| | | status: 'normal', |
| | | location: '公司总部', |
| | | remark: '' |
| | | }, |
| | | { |
| | | id: 10, |
| | | employeeName: '马文杰', |
| | | department: '技术部', |
| | | date: '2025-09-05', |
| | | clockInTime: '08:57:00', |
| | | clockOutTime: '17:30:00', |
| | | workHours: '7.55h', |
| | | status: 'early', |
| | | location: '公司总部', |
| | | remark: '有急事提前离开' |
| | | }, |
| | | { |
| | | id: 11, |
| | | employeeName: '林晓东', |
| | | department: '行政部', |
| | | date: '2025-09-05', |
| | | clockInTime: '09:03:00', |
| | | clockOutTime: '18:08:00', |
| | | workHours: '8.08h', |
| | | status: 'normal', |
| | | location: '公司总部', |
| | | remark: '' |
| | | }, |
| | | { |
| | | id: 12, |
| | | employeeName: '黄美玲', |
| | | department: '财务部', |
| | | date: '2025-09-06', |
| | | clockInTime: '', |
| | | clockOutTime: '', |
| | | workHours: '0h', |
| | | status: 'absent', |
| | | location: '', |
| | | remark: '请病假' |
| | | }, |
| | | { |
| | | id: 13, |
| | | employeeName: '郑海涛', |
| | | department: '市场部', |
| | | date: '2025-08-14', |
| | | clockInTime: '09:00:00', |
| | | clockOutTime: '18:00:00', |
| | | workHours: '8.0h', |
| | | status: 'normal', |
| | | location: '公司总部', |
| | | remark: '' |
| | | }, |
| | | { |
| | | id: 14, |
| | | employeeName: '谢丽娟', |
| | | department: '人事部', |
| | | date: '2025-08-20', |
| | | clockInTime: '08:58:00', |
| | | clockOutTime: '18:03:00', |
| | | workHours: '8.08h', |
| | | status: 'normal', |
| | | location: '公司总部', |
| | | remark: '' |
| | | }, |
| | | { |
| | | id: 15, |
| | | employeeName: '何志伟', |
| | | department: '技术部', |
| | | date: '2025-08-21', |
| | | clockInTime: '09:10:00', |
| | | clockOutTime: '18:00:00', |
| | | workHours: '7.83h', |
| | | status: 'late', |
| | | location: '公司总部', |
| | | remark: '' |
| | | }, |
| | | { |
| | | id: 16, |
| | | employeeName: '许雅芳', |
| | | department: '设计部', |
| | | date: '2025-08-22', |
| | | clockInTime: '09:01:00', |
| | | clockOutTime: '18:00:00', |
| | | workHours: '7.98h', |
| | | status: 'normal', |
| | | location: '公司总部', |
| | | remark: '' |
| | | }, |
| | | { |
| | | id: 17, |
| | | employeeName: '邓建平', |
| | | department: '运营部', |
| | | date: '2025-09-10', |
| | | clockInTime: '08:59:00', |
| | | clockOutTime: '18:05:00', |
| | | workHours: '8.1h', |
| | | status: 'normal', |
| | | location: '公司总部', |
| | | remark: '' |
| | | }, |
| | | { |
| | | id: 18, |
| | | employeeName: '曾小红', |
| | | department: '客服部', |
| | | date: '2025-09-11', |
| | | clockInTime: '09:02:00', |
| | | clockOutTime: '18:00:00', |
| | | workHours: '7.97h', |
| | | status: 'normal', |
| | | location: '公司总部', |
| | | remark: '' |
| | | } |
| | | ] |
| | | |
| | | attendanceData.value = mockData |
| | | filteredAttendanceData.value = mockData |
| | | } |
| | | |
| | | // 删除项目 |
| | |
| | | cancelButtonText: '取消', |
| | | type: 'warning' |
| | | }).then(() => { |
| | | let ids = []; |
| | | let dataArray |
| | | if (type === 'holiday') dataArray = holidayData.value |
| | | else if (type === 'annual') dataArray = annualData.value |
| | | else if (type === 'overtime') dataArray = overtimeData.value |
| | | else if (type === 'worktime') dataArray = worktimeData.value |
| | | |
| | | const index = dataArray.findIndex(item => item.id === row.id) |
| | | if (index > -1) { |
| | | dataArray.splice(index, 1) |
| | | ElMessage.success('删除成功') |
| | | if (type === 'holiday') { |
| | | ids.push(row.id) |
| | | delHolidaySettings(ids).then(res => { |
| | | if(res.code == 200){ |
| | | ElMessage.success("删除成功"); |
| | | ids = [] |
| | | getHolidaySettingsList() |
| | | } |
| | | }).catch(err => { |
| | | ElMessage.error(err.msg); |
| | | }) |
| | | } |
| | | else if (type === 'annual') { |
| | | ids.push(row.id) |
| | | delAnnualLeaveSetting(ids).then(res => { |
| | | if(res.code == 200){ |
| | | ElMessage.success("删除成功"); |
| | | ids = [] |
| | | getAnnualLeaveSettingList() |
| | | } |
| | | }).catch(err => { |
| | | ElMessage.error(err.msg); |
| | | }) |
| | | } |
| | | else if (type === 'overtime') { |
| | | ids.push(row.id) |
| | | delOvertimeSetting(ids).then(res => { |
| | | if(res.code == 200){ |
| | | ElMessage.success("删除成功"); |
| | | ids = [] |
| | | getOvertimeSettingList() |
| | | } |
| | | }).catch(err => { |
| | | ElMessage.error(err.msg); |
| | | }) |
| | | } |
| | | else if (type === 'worktime') { |
| | | ids.push(row.id) |
| | | delWorkingHoursSetting(ids).then(res => { |
| | | if(res.code == 200){ |
| | | ElMessage.success("删除成功"); |
| | | ids = [] |
| | | getWorkingHoursSettingList() |
| | | } |
| | | }).catch(err => { |
| | | ElMessage.error(err.msg); |
| | | }) |
| | | } |
| | | |
| | | // const index = dataArray.findIndex(item => item.id === row.id) |
| | | // if (index > -1) { |
| | | // dataArray.splice(index, 1) |
| | | // ElMessage.success('删除成功') |
| | | // } |
| | | }) |
| | | } |
| | | // 获取假期设置列表 |
| | | const getHolidaySettingsList = () => { |
| | | // tableLoading.value = true; |
| | | listHolidaySettings({...page.value}) |
| | | .then(res => { |
| | | // tableLoading.value = false; |
| | | holidayData.value = res.data.records |
| | | page.total = res.data.total; |
| | | }).catch(err => { |
| | | // tableLoading.value = false; |
| | | }) |
| | | }; |
| | | // 获取年假规则列表 |
| | | const getAnnualLeaveSettingList = () => { |
| | | |
| | | listAnnualLeaveSettingList({...page.value}) |
| | | .then(res => { |
| | | // console.log(res.data) |
| | | annualData.value = res.data.records |
| | | page.total = res.data.total; |
| | | }).catch(err => { |
| | | }) |
| | | }; |
| | | // 获取加班规则列表 |
| | | const getOvertimeSettingList = () => { |
| | | |
| | | listOvertimeSettingList({...page.value}) |
| | | .then(res => { |
| | | // console.log(res.data) |
| | | overtimeData.value = res.data.records |
| | | page.total = res.data.total; |
| | | }).catch(err => { |
| | | }) |
| | | }; |
| | | // 获取工作时间规则列表 |
| | | const getWorkingHoursSettingList = () => { |
| | | |
| | | listWorkingHoursSettingList({...page.value}) |
| | | .then(res => { |
| | | // console.log(res.data) |
| | | worktimeData.value = res.data.records |
| | | page.total = res.data.total; |
| | | }).catch(err => { |
| | | }) |
| | | }; |
| | | onMounted(() => { |
| | | getHolidaySettingsList() |
| | | getAnnualLeaveSettingList() |
| | | getOvertimeSettingList() |
| | | getWorkingHoursSettingList() |
| | | initAttendanceData() |
| | | console.log('考勤管理页面加载完成') |
| | | }) |
| | | |