hrm
parent
ed09002861
commit
f4eac55974
|
|
@ -0,0 +1,47 @@
|
|||
import request from '@/config/axios'
|
||||
|
||||
// 考勤记录 VO
|
||||
export interface AttendRecordVO {
|
||||
id: number // 主键ID
|
||||
userId: number // 员工ID
|
||||
deptId: number // 部门ID
|
||||
postId: number // 岗位ID
|
||||
clockStatus: string // 打卡状态(正常、迟到、早退、缺卡等)
|
||||
clockType: string // 打卡类型(正常上下班、加班)
|
||||
clockInTime: Date // 打卡开始时间(上班打卡)
|
||||
clockOutTime: Date // 打卡结束时间(下班打卡)
|
||||
attendanceDuration: number // 日出勤时长(小时)
|
||||
}
|
||||
|
||||
// 考勤记录 API
|
||||
export const AttendRecordApi = {
|
||||
// 查询考勤记录分页
|
||||
getAttendRecordPage: async (params: any) => {
|
||||
return await request.get({ url: `/hrm/attend-record/page`, params })
|
||||
},
|
||||
|
||||
// 查询考勤记录详情
|
||||
getAttendRecord: async (id: number) => {
|
||||
return await request.get({ url: `/hrm/attend-record/get?id=` + id })
|
||||
},
|
||||
|
||||
// 新增考勤记录
|
||||
createAttendRecord: async (data: AttendRecordVO) => {
|
||||
return await request.post({ url: `/hrm/attend-record/create`, data })
|
||||
},
|
||||
|
||||
// 修改考勤记录
|
||||
updateAttendRecord: async (data: AttendRecordVO) => {
|
||||
return await request.put({ url: `/hrm/attend-record/update`, data })
|
||||
},
|
||||
|
||||
// 删除考勤记录
|
||||
deleteAttendRecord: async (id: number) => {
|
||||
return await request.delete({ url: `/hrm/attend-record/delete?id=` + id })
|
||||
},
|
||||
|
||||
// 导出考勤记录 Excel
|
||||
exportAttendRecord: async (params) => {
|
||||
return await request.download({ url: `/hrm/attend-record/export-excel`, params })
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
import request from '@/config/axios'
|
||||
|
||||
// 考勤规则 VO
|
||||
export interface AttendRuleVO {
|
||||
id: number // 主键
|
||||
name: string // 规则名称
|
||||
isOvertimeAllowed: boolean // 是否允许加班
|
||||
overtimeStartAfter: number // 下班多少分钟后算加班
|
||||
restDayMode: number // 休息日打卡规则:1交替一次 2交替多次
|
||||
holidayPunchRequired: boolean // 法定假日是否需要打卡
|
||||
}
|
||||
|
||||
// 考勤规则 API
|
||||
export const AttendRuleApi = {
|
||||
// 查询考勤规则分页
|
||||
getAttendRulePage: async (params: any) => {
|
||||
return await request.get({ url: `/hrm/attend-rule/page`, params })
|
||||
},
|
||||
|
||||
// 查询考勤规则详情
|
||||
getAttendRule: async (id: number) => {
|
||||
return await request.get({ url: `/hrm/attend-rule/get?id=` + id })
|
||||
},
|
||||
|
||||
// 新增考勤规则
|
||||
createAttendRule: async (data: AttendRuleVO) => {
|
||||
return await request.post({ url: `/hrm/attend-rule/create`, data })
|
||||
},
|
||||
|
||||
// 修改考勤规则
|
||||
updateAttendRule: async (data: AttendRuleVO) => {
|
||||
return await request.put({ url: `/hrm/attend-rule/update`, data })
|
||||
},
|
||||
|
||||
// 删除考勤规则
|
||||
deleteAttendRule: async (id: number) => {
|
||||
return await request.delete({ url: `/hrm/attend-rule/delete?id=` + id })
|
||||
},
|
||||
|
||||
// 导出考勤规则 Excel
|
||||
exportAttendRule: async (params) => {
|
||||
return await request.download({ url: `/hrm/attend-rule/export-excel`, params })
|
||||
},
|
||||
|
||||
// ==================== 子表(考勤班次) ====================
|
||||
|
||||
// 获得考勤班次列表
|
||||
getAttendShiftListByRuleId: async (ruleId) => {
|
||||
return await request.get({ url: `/hrm/attend-rule/attend-shift/list-by-rule-id?ruleId=` + ruleId })
|
||||
},
|
||||
|
||||
// ==================== 子表(考勤关系) ====================
|
||||
|
||||
// 获得考勤关系列表
|
||||
getUserAttendRelationListByRuleId: async (ruleId) => {
|
||||
return await request.get({ url: `/hrm/attend-rule/user-attend-relation/list-by-rule-id?ruleId=` + ruleId })
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
import request from '@/config/axios'
|
||||
|
||||
// 考勤排班调度配置 VO
|
||||
export interface AttendScheduleConfigVO {
|
||||
id: number // 主键ID
|
||||
ruleId: number // 所属考勤规则ID
|
||||
scheduleType: number // 调度类型:1=按天,2=按周,3=按月
|
||||
dayIndex: number // 调度下标:日(从1开始),周(1~7),月(1~12)
|
||||
shiftId: number // 班次ID(为空表示休息)
|
||||
isWorkingDay: boolean // 是否工作日(true 表示需打卡)
|
||||
remarks: string // 备注说明
|
||||
}
|
||||
|
||||
// 考勤排班调度配置 API
|
||||
export const AttendScheduleConfigApi = {
|
||||
// 查询考勤排班调度配置分页
|
||||
getAttendScheduleConfigPage: async (params: any) => {
|
||||
return await request.get({ url: `/hrm/attend-schedule-config/page`, params })
|
||||
},
|
||||
|
||||
// 查询考勤排班调度配置详情
|
||||
getAttendScheduleConfig: async (id: number) => {
|
||||
return await request.get({ url: `/hrm/attend-schedule-config/get?id=` + id })
|
||||
},
|
||||
|
||||
// 新增考勤排班调度配置
|
||||
createAttendScheduleConfig: async (data: AttendScheduleConfigVO) => {
|
||||
return await request.post({ url: `/hrm/attend-schedule-config/create`, data })
|
||||
},
|
||||
|
||||
// 修改考勤排班调度配置
|
||||
updateAttendScheduleConfig: async (data: AttendScheduleConfigVO) => {
|
||||
return await request.put({ url: `/hrm/attend-schedule-config/update`, data })
|
||||
},
|
||||
|
||||
// 删除考勤排班调度配置
|
||||
deleteAttendScheduleConfig: async (id: number) => {
|
||||
return await request.delete({ url: `/hrm/attend-schedule-config/delete?id=` + id })
|
||||
},
|
||||
|
||||
// 导出考勤排班调度配置 Excel
|
||||
exportAttendScheduleConfig: async (params) => {
|
||||
return await request.download({ url: `/hrm/attend-schedule-config/export-excel`, params })
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
import request from '@/config/axios'
|
||||
|
||||
// 考勤班次 VO
|
||||
export interface AttendShiftVO {
|
||||
id: number // 主键
|
||||
ruleId: number // 所属考勤规则
|
||||
name: string // 班次名称
|
||||
shiftType: number // 班次类型:1固定班次 2轮班制(三班倒)
|
||||
restIncluded: boolean // 是否包含休息时段
|
||||
}
|
||||
|
||||
// 考勤班次 API
|
||||
export const AttendShiftApi = {
|
||||
// 查询考勤班次分页
|
||||
getAttendShiftPage: async (params: any) => {
|
||||
return await request.get({ url: `/hrm/attend-shift/page`, params })
|
||||
},
|
||||
|
||||
// 查询考勤班次详情
|
||||
getAttendShift: async (id: number) => {
|
||||
return await request.get({ url: `/hrm/attend-shift/get?id=` + id })
|
||||
},
|
||||
|
||||
// 新增考勤班次
|
||||
createAttendShift: async (data: AttendShiftVO) => {
|
||||
return await request.post({ url: `/hrm/attend-shift/create`, data })
|
||||
},
|
||||
|
||||
// 修改考勤班次
|
||||
updateAttendShift: async (data: AttendShiftVO) => {
|
||||
return await request.put({ url: `/hrm/attend-shift/update`, data })
|
||||
},
|
||||
|
||||
// 删除考勤班次
|
||||
deleteAttendShift: async (id: number) => {
|
||||
return await request.delete({ url: `/hrm/attend-shift/delete?id=` + id })
|
||||
},
|
||||
|
||||
// 导出考勤班次 Excel
|
||||
exportAttendShift: async (params) => {
|
||||
return await request.download({ url: `/hrm/attend-shift/export-excel`, params })
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
import request from '@/config/axios'
|
||||
|
||||
// 考勤班次时间 VO
|
||||
export interface AttendShiftTimeVO {
|
||||
id: number // 主键
|
||||
shiftId: number // 关联班次ID
|
||||
startTime: localtime // 上班时间
|
||||
endTime: localtime // 下班时间
|
||||
restStartTime: localtime // 休息开始时间
|
||||
restEndTime: localtime // 休息结束时间
|
||||
seq: number // 时段顺序(如早班、中班、晚班)
|
||||
}
|
||||
|
||||
// 考勤班次时间 API
|
||||
export const AttendShiftTimeApi = {
|
||||
// 查询考勤班次时间分页
|
||||
getAttendShiftTimePage: async (params: any) => {
|
||||
return await request.get({ url: `/hrm/attend-shift-time/page`, params })
|
||||
},
|
||||
|
||||
// 查询考勤班次时间详情
|
||||
getAttendShiftTime: async (id: number) => {
|
||||
return await request.get({ url: `/hrm/attend-shift-time/get?id=` + id })
|
||||
},
|
||||
|
||||
// 新增考勤班次时间
|
||||
createAttendShiftTime: async (data: AttendShiftTimeVO) => {
|
||||
return await request.post({ url: `/hrm/attend-shift-time/create`, data })
|
||||
},
|
||||
|
||||
// 修改考勤班次时间
|
||||
updateAttendShiftTime: async (data: AttendShiftTimeVO) => {
|
||||
return await request.put({ url: `/hrm/attend-shift-time/update`, data })
|
||||
},
|
||||
|
||||
// 删除考勤班次时间
|
||||
deleteAttendShiftTime: async (id: number) => {
|
||||
return await request.delete({ url: `/hrm/attend-shift-time/delete?id=` + id })
|
||||
},
|
||||
|
||||
// 导出考勤班次时间 Excel
|
||||
exportAttendShiftTime: async (params) => {
|
||||
return await request.download({ url: `/hrm/attend-shift-time/export-excel`, params })
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
import request from '@/config/axios'
|
||||
|
||||
// 员工绩效 VO
|
||||
export interface UserPerformanceVO {
|
||||
id: number // 唯一主键
|
||||
userId: number // 员工档案ID(关联 hrm_user_infor)
|
||||
assessmentMonth: Date // 考核月份(格式:YYYY-MM)
|
||||
performanceLevel: number // 绩效等级
|
||||
assessmentScoreTotal: number // 考核得分合计
|
||||
attendanceScore: number // 考勤得分
|
||||
performanceAssessmentScore: number // 业绩考核得分
|
||||
behaviorAssessmentScore: number // 行为考核得分
|
||||
}
|
||||
|
||||
// 员工绩效 API
|
||||
export const UserPerformanceApi = {
|
||||
// 查询员工绩效分页
|
||||
getUserPerformancePage: async (params: any) => {
|
||||
return await request.get({ url: `/hrm/user-performance/page`, params })
|
||||
},
|
||||
|
||||
// 查询员工绩效详情
|
||||
getUserPerformance: async (id: number) => {
|
||||
return await request.get({ url: `/hrm/user-performance/get?id=` + id })
|
||||
},
|
||||
|
||||
// 新增员工绩效
|
||||
createUserPerformance: async (data: UserPerformanceVO) => {
|
||||
return await request.post({ url: `/hrm/user-performance/create`, data })
|
||||
},
|
||||
|
||||
// 修改员工绩效
|
||||
updateUserPerformance: async (data: UserPerformanceVO) => {
|
||||
return await request.put({ url: `/hrm/user-performance/update`, data })
|
||||
},
|
||||
|
||||
// 删除员工绩效
|
||||
deleteUserPerformance: async (id: number) => {
|
||||
return await request.delete({ url: `/hrm/user-performance/delete?id=` + id })
|
||||
},
|
||||
|
||||
// 导出员工绩效 Excel
|
||||
exportUserPerformance: async (params) => {
|
||||
return await request.download({ url: `/hrm/user-performance/export-excel`, params })
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
import request from '@/config/axios'
|
||||
|
||||
// 职位考核信息 VO
|
||||
export interface PostAssessmentVO {
|
||||
id: number // 主键
|
||||
postId: number // 岗位关联ID
|
||||
assessType: string // 考核类型
|
||||
assessName: string // 考核名称
|
||||
assessDetail: string // 考核详情
|
||||
score: number // 分数分值
|
||||
}
|
||||
|
||||
// 职位考核信息 API
|
||||
export const PostAssessmentApi = {
|
||||
// 查询职位考核信息分页
|
||||
getPostAssessmentPage: async (params: any) => {
|
||||
return await request.get({ url: `/system/post-assessment/page`, params })
|
||||
},
|
||||
|
||||
// 查询职位考核信息详情
|
||||
getPostAssessment: async (id: number) => {
|
||||
return await request.get({ url: `/system/post-assessment/get?id=` + id })
|
||||
},
|
||||
|
||||
// 新增职位考核信息
|
||||
createPostAssessment: async (data: PostAssessmentVO) => {
|
||||
return await request.post({ url: `/system/post-assessment/create`, data })
|
||||
},
|
||||
|
||||
// 修改职位考核信息
|
||||
updatePostAssessment: async (data: PostAssessmentVO) => {
|
||||
return await request.put({ url: `/system/post-assessment/update`, data })
|
||||
},
|
||||
|
||||
// 删除职位考核信息
|
||||
deletePostAssessment: async (id: number) => {
|
||||
return await request.delete({ url: `/system/post-assessment/delete?id=` + id })
|
||||
},
|
||||
|
||||
// 导出职位考核信息 Excel
|
||||
exportPostAssessment: async (params) => {
|
||||
return await request.download({ url: `/system/post-assessment/export-excel`, params })
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
import request from '@/config/axios'
|
||||
|
||||
// 任职条件 VO
|
||||
export interface PostRequirementVO {
|
||||
id: number // 唯一主键
|
||||
postId: number // 岗位关联ID
|
||||
requirementName: string // 名称
|
||||
qualificationDescription: string // 资格说明
|
||||
}
|
||||
|
||||
// 任职条件 API
|
||||
export const PostRequirementApi = {
|
||||
// 查询任职条件分页
|
||||
getPostRequirementPage: async (params: any) => {
|
||||
return await request.get({ url: `/system/post-requirement/page`, params })
|
||||
},
|
||||
|
||||
// 查询任职条件详情
|
||||
getPostRequirement: async (id: number) => {
|
||||
return await request.get({ url: `/system/post-requirement/get?id=` + id })
|
||||
},
|
||||
|
||||
// 新增任职条件
|
||||
createPostRequirement: async (data: PostRequirementVO) => {
|
||||
return await request.post({ url: `/system/post-requirement/create`, data })
|
||||
},
|
||||
|
||||
// 修改任职条件
|
||||
updatePostRequirement: async (data: PostRequirementVO) => {
|
||||
return await request.put({ url: `/system/post-requirement/update`, data })
|
||||
},
|
||||
|
||||
// 删除任职条件
|
||||
deletePostRequirement: async (id: number) => {
|
||||
return await request.delete({ url: `/system/post-requirement/delete?id=` + id })
|
||||
},
|
||||
|
||||
// 导出任职条件 Excel
|
||||
exportPostRequirement: async (params) => {
|
||||
return await request.download({ url: `/system/post-requirement/export-excel`, params })
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
import request from '@/config/axios'
|
||||
|
||||
// 岗位职责 VO
|
||||
export interface PostResponsibilityVO {
|
||||
id: number // 唯一主键
|
||||
postId: number // 岗位关联ID
|
||||
responsibility: string // 职责
|
||||
task: string // 任务
|
||||
timeAllocation: string // 时间分配
|
||||
}
|
||||
|
||||
// 岗位职责 API
|
||||
export const PostResponsibilityApi = {
|
||||
// 查询岗位职责分页
|
||||
getPostResponsibilityPage: async (params: any) => {
|
||||
return await request.get({ url: `/system/post-responsibility/page`, params })
|
||||
},
|
||||
|
||||
// 查询岗位职责详情
|
||||
getPostResponsibility: async (id: number) => {
|
||||
return await request.get({ url: `/system/post-responsibility/get?id=` + id })
|
||||
},
|
||||
|
||||
// 新增岗位职责
|
||||
createPostResponsibility: async (data: PostResponsibilityVO) => {
|
||||
return await request.post({ url: `/system/post-responsibility/create`, data })
|
||||
},
|
||||
|
||||
// 修改岗位职责
|
||||
updatePostResponsibility: async (data: PostResponsibilityVO) => {
|
||||
return await request.put({ url: `/system/post-responsibility/update`, data })
|
||||
},
|
||||
|
||||
// 删除岗位职责
|
||||
deletePostResponsibility: async (id: number) => {
|
||||
return await request.delete({ url: `/system/post-responsibility/delete?id=` + id })
|
||||
},
|
||||
|
||||
// 导出岗位职责 Excel
|
||||
exportPostResponsibility: async (params) => {
|
||||
return await request.download({ url: `/system/post-responsibility/export-excel`, params })
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
<template>
|
||||
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
label-width="100px"
|
||||
v-loading="formLoading"
|
||||
>
|
||||
<el-form-item label="员工ID" prop="userId">
|
||||
<el-input v-model="formData.userId" placeholder="请输入员工ID" />
|
||||
</el-form-item>
|
||||
<el-form-item label="部门ID" prop="deptId">
|
||||
<el-input v-model="formData.deptId" placeholder="请输入部门ID" />
|
||||
</el-form-item>
|
||||
<el-form-item label="岗位ID" prop="postId">
|
||||
<el-input v-model="formData.postId" placeholder="请输入岗位ID" />
|
||||
</el-form-item>
|
||||
<el-form-item label="打卡状态(正常、迟到、早退、缺卡等)" prop="clockStatus">
|
||||
<el-select v-model="formData.clockStatus" placeholder="请选择打卡状态(正常、迟到、早退、缺卡等)">
|
||||
<el-option
|
||||
v-for="dict in getStrDictOptions(DICT_TYPE.HRM_ CLOCK_STATUS)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="打卡类型(正常上下班、加班)" prop="clockType">
|
||||
<el-select v-model="formData.clockType" placeholder="请选择打卡类型(正常上下班、加班)">
|
||||
<el-option
|
||||
v-for="dict in getStrDictOptions(DICT_TYPE.HRM_CLOCK_TYPE)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="打卡开始时间(上班打卡)" prop="clockInTime">
|
||||
<el-date-picker
|
||||
v-model="formData.clockInTime"
|
||||
type="date"
|
||||
value-format="x"
|
||||
placeholder="选择打卡开始时间(上班打卡)"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="打卡结束时间(下班打卡)" prop="clockOutTime">
|
||||
<el-date-picker
|
||||
v-model="formData.clockOutTime"
|
||||
type="date"
|
||||
value-format="x"
|
||||
placeholder="选择打卡结束时间(下班打卡)"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="日出勤时长(小时)" prop="attendanceDuration">
|
||||
<el-input v-model="formData.attendanceDuration" placeholder="请输入日出勤时长(小时)" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { getStrDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||
import { AttendRecordApi, AttendRecordVO } from '@/api/hrm/attendrecord'
|
||||
|
||||
/** 考勤记录 表单 */
|
||||
defineOptions({ name: 'AttendRecordForm' })
|
||||
|
||||
const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
|
||||
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||
const dialogTitle = ref('') // 弹窗的标题
|
||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||
const formData = ref({
|
||||
id: undefined,
|
||||
userId: undefined,
|
||||
deptId: undefined,
|
||||
postId: undefined,
|
||||
clockStatus: undefined,
|
||||
clockType: undefined,
|
||||
clockInTime: undefined,
|
||||
clockOutTime: undefined,
|
||||
attendanceDuration: undefined
|
||||
})
|
||||
const formRules = reactive({
|
||||
userId: [{ required: true, message: '员工ID不能为空', trigger: 'blur' }],
|
||||
clockStatus: [{ required: true, message: '打卡状态(正常、迟到、早退、缺卡等)不能为空', trigger: 'change' }],
|
||||
clockType: [{ required: true, message: '打卡类型(正常上下班、加班)不能为空', trigger: 'change' }]
|
||||
})
|
||||
const formRef = ref() // 表单 Ref
|
||||
|
||||
/** 打开弹窗 */
|
||||
const open = async (type: string, id?: number) => {
|
||||
dialogVisible.value = true
|
||||
dialogTitle.value = t('action.' + type)
|
||||
formType.value = type
|
||||
resetForm()
|
||||
// 修改时,设置数据
|
||||
if (id) {
|
||||
formLoading.value = true
|
||||
try {
|
||||
formData.value = await AttendRecordApi.getAttendRecord(id)
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||
|
||||
/** 提交表单 */
|
||||
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||
const submitForm = async () => {
|
||||
// 校验表单
|
||||
await formRef.value.validate()
|
||||
// 提交请求
|
||||
formLoading.value = true
|
||||
try {
|
||||
const data = formData.value as unknown as AttendRecordVO
|
||||
if (formType.value === 'create') {
|
||||
await AttendRecordApi.createAttendRecord(data)
|
||||
message.success(t('common.createSuccess'))
|
||||
} else {
|
||||
await AttendRecordApi.updateAttendRecord(data)
|
||||
message.success(t('common.updateSuccess'))
|
||||
}
|
||||
dialogVisible.value = false
|
||||
// 发送操作成功的事件
|
||||
emit('success')
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 重置表单 */
|
||||
const resetForm = () => {
|
||||
formData.value = {
|
||||
id: undefined,
|
||||
userId: undefined,
|
||||
deptId: undefined,
|
||||
postId: undefined,
|
||||
clockStatus: undefined,
|
||||
clockType: undefined,
|
||||
clockInTime: undefined,
|
||||
clockOutTime: undefined,
|
||||
attendanceDuration: undefined
|
||||
}
|
||||
formRef.value?.resetFields()
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,301 @@
|
|||
<template>
|
||||
<ContentWrap>
|
||||
<!-- 搜索工作栏 -->
|
||||
<el-form
|
||||
class="-mb-15px"
|
||||
:model="queryParams"
|
||||
ref="queryFormRef"
|
||||
:inline="true"
|
||||
label-width="68px"
|
||||
>
|
||||
<el-form-item label="员工ID" prop="userId">
|
||||
<el-input
|
||||
v-model="queryParams.userId"
|
||||
placeholder="请输入员工ID"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="部门ID" prop="deptId">
|
||||
<el-input
|
||||
v-model="queryParams.deptId"
|
||||
placeholder="请输入部门ID"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="岗位ID" prop="postId">
|
||||
<el-input
|
||||
v-model="queryParams.postId"
|
||||
placeholder="请输入岗位ID"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="打卡状态(正常、迟到、早退、缺卡等)" prop="clockStatus">
|
||||
<el-select
|
||||
v-model="queryParams.clockStatus"
|
||||
placeholder="请选择打卡状态(正常、迟到、早退、缺卡等)"
|
||||
clearable
|
||||
class="!w-240px"
|
||||
>
|
||||
<el-option
|
||||
v-for="dict in getStrDictOptions(DICT_TYPE.HRM_ CLOCK_STATUS)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="打卡类型(正常上下班、加班)" prop="clockType">
|
||||
<el-select
|
||||
v-model="queryParams.clockType"
|
||||
placeholder="请选择打卡类型(正常上下班、加班)"
|
||||
clearable
|
||||
class="!w-240px"
|
||||
>
|
||||
<el-option
|
||||
v-for="dict in getStrDictOptions(DICT_TYPE.HRM_CLOCK_TYPE)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="打卡开始时间(上班打卡)" prop="clockInTime">
|
||||
<el-date-picker
|
||||
v-model="queryParams.clockInTime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
type="daterange"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||
class="!w-220px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="打卡结束时间(下班打卡)" prop="clockOutTime">
|
||||
<el-date-picker
|
||||
v-model="queryParams.clockOutTime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
type="daterange"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||
class="!w-220px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="日出勤时长(小时)" prop="attendanceDuration">
|
||||
<el-input
|
||||
v-model="queryParams.attendanceDuration"
|
||||
placeholder="请输入日出勤时长(小时)"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间" prop="createTime">
|
||||
<el-date-picker
|
||||
v-model="queryParams.createTime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
type="daterange"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||
class="!w-220px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
@click="openForm('create')"
|
||||
v-hasPermi="['hrm:attend-record:create']"
|
||||
>
|
||||
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||
</el-button>
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
@click="handleExport"
|
||||
:loading="exportLoading"
|
||||
v-hasPermi="['hrm:attend-record:export']"
|
||||
>
|
||||
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 列表 -->
|
||||
<ContentWrap>
|
||||
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||
<el-table-column label="主键ID" align="center" prop="id" />
|
||||
<el-table-column label="员工ID" align="center" prop="userId" />
|
||||
<el-table-column label="部门ID" align="center" prop="deptId" />
|
||||
<el-table-column label="岗位ID" align="center" prop="postId" />
|
||||
<el-table-column label="打卡状态(正常、迟到、早退、缺卡等)" align="center" prop="clockStatus">
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.HRM_ CLOCK_STATUS" :value="scope.row.clockStatus" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="打卡类型(正常上下班、加班)" align="center" prop="clockType">
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.HRM_CLOCK_TYPE" :value="scope.row.clockType" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="打卡开始时间(上班打卡)"
|
||||
align="center"
|
||||
prop="clockInTime"
|
||||
:formatter="dateFormatter"
|
||||
width="180px"
|
||||
/>
|
||||
<el-table-column
|
||||
label="打卡结束时间(下班打卡)"
|
||||
align="center"
|
||||
prop="clockOutTime"
|
||||
:formatter="dateFormatter"
|
||||
width="180px"
|
||||
/>
|
||||
<el-table-column label="日出勤时长(小时)" align="center" prop="attendanceDuration" />
|
||||
<el-table-column
|
||||
label="创建时间"
|
||||
align="center"
|
||||
prop="createTime"
|
||||
:formatter="dateFormatter"
|
||||
width="180px"
|
||||
/>
|
||||
<el-table-column label="操作" align="center" min-width="120px">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
@click="openForm('update', scope.row.id)"
|
||||
v-hasPermi="['hrm:attend-record:update']"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row.id)"
|
||||
v-hasPermi="['hrm:attend-record:delete']"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 分页 -->
|
||||
<Pagination
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNo"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 表单弹窗:添加/修改 -->
|
||||
<AttendRecordForm ref="formRef" @success="getList" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { getStrDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||
import { dateFormatter } from '@/utils/formatTime'
|
||||
import download from '@/utils/download'
|
||||
import { AttendRecordApi, AttendRecordVO } from '@/api/hrm/attendrecord'
|
||||
import AttendRecordForm from './AttendRecordForm.vue'
|
||||
|
||||
/** 考勤记录 列表 */
|
||||
defineOptions({ name: 'AttendRecord' })
|
||||
|
||||
const message = useMessage() // 消息弹窗
|
||||
const { t } = useI18n() // 国际化
|
||||
|
||||
const loading = ref(true) // 列表的加载中
|
||||
const list = ref<AttendRecordVO[]>([]) // 列表的数据
|
||||
const total = ref(0) // 列表的总页数
|
||||
const queryParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
userId: undefined,
|
||||
deptId: undefined,
|
||||
postId: undefined,
|
||||
clockStatus: undefined,
|
||||
clockType: undefined,
|
||||
clockInTime: [],
|
||||
clockOutTime: [],
|
||||
attendanceDuration: undefined,
|
||||
createTime: []
|
||||
})
|
||||
const queryFormRef = ref() // 搜索的表单
|
||||
const exportLoading = ref(false) // 导出的加载中
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const data = await AttendRecordApi.getAttendRecordPage(queryParams)
|
||||
list.value = data.list
|
||||
total.value = data.total
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNo = 1
|
||||
getList()
|
||||
}
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value.resetFields()
|
||||
handleQuery()
|
||||
}
|
||||
|
||||
/** 添加/修改操作 */
|
||||
const formRef = ref()
|
||||
const openForm = (type: string, id?: number) => {
|
||||
formRef.value.open(type, id)
|
||||
}
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (id: number) => {
|
||||
try {
|
||||
// 删除的二次确认
|
||||
await message.delConfirm()
|
||||
// 发起删除
|
||||
await AttendRecordApi.deleteAttendRecord(id)
|
||||
message.success(t('common.delSuccess'))
|
||||
// 刷新列表
|
||||
await getList()
|
||||
} catch {}
|
||||
}
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
// 导出的二次确认
|
||||
await message.exportConfirm()
|
||||
// 发起导出
|
||||
exportLoading.value = true
|
||||
const data = await AttendRecordApi.exportAttendRecord(queryParams)
|
||||
download.excel(data, '考勤记录.xls')
|
||||
} catch {
|
||||
} finally {
|
||||
exportLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 初始化 **/
|
||||
onMounted(() => {
|
||||
getList()
|
||||
})
|
||||
</script>
|
||||
|
|
@ -0,0 +1,168 @@
|
|||
<template>
|
||||
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
label-width="100px"
|
||||
v-loading="formLoading"
|
||||
>
|
||||
<el-form-item label="规则名称" prop="name">
|
||||
<el-input v-model="formData.name" placeholder="请输入规则名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="是否允许加班" prop="isOvertimeAllowed">
|
||||
<el-radio-group v-model="formData.isOvertimeAllowed">
|
||||
<el-radio
|
||||
v-for="dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
|
||||
:key="dict.value"
|
||||
:label="dict.value"
|
||||
>
|
||||
{{ dict.label }}
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="下班多少分钟后算加班" prop="overtimeStartAfter">
|
||||
<el-input v-model="formData.overtimeStartAfter" placeholder="请输入下班多少分钟后算加班" />
|
||||
</el-form-item>
|
||||
<el-form-item label="休息日打卡规则:1交替一次 2交替多次" prop="restDayMode">
|
||||
<el-select v-model="formData.restDayMode" placeholder="请选择休息日打卡规则:1交替一次 2交替多次">
|
||||
<el-option
|
||||
v-for="dict in getIntDictOptions(DICT_TYPE.HRM_REST_DAY_MODE)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="法定假日是否需要打卡" prop="holidayPunchRequired">
|
||||
<el-radio-group v-model="formData.holidayPunchRequired">
|
||||
<el-radio
|
||||
v-for="dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
|
||||
:key="dict.value"
|
||||
:label="dict.value"
|
||||
>
|
||||
{{ dict.label }}
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<!-- 子表的表单 -->
|
||||
<el-tabs v-model="subTabsName">
|
||||
<el-tab-pane label="考勤班次" name="attendShift">
|
||||
<AttendShiftForm ref="attendShiftFormRef" :rule-id="formData.id" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="考勤关系" name="userAttendRelation">
|
||||
<UserAttendRelationForm ref="userAttendRelationFormRef" :rule-id="formData.id" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<template #footer>
|
||||
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { getIntDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||
import { AttendRuleApi, AttendRuleVO } from '@/api/hrm/attendrule'
|
||||
import AttendShiftForm from './components/AttendShiftForm.vue'
|
||||
import UserAttendRelationForm from './components/UserAttendRelationForm.vue'
|
||||
|
||||
/** 考勤规则 表单 */
|
||||
defineOptions({ name: 'AttendRuleForm' })
|
||||
|
||||
const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
|
||||
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||
const dialogTitle = ref('') // 弹窗的标题
|
||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||
const formData = ref({
|
||||
id: undefined,
|
||||
name: undefined,
|
||||
isOvertimeAllowed: undefined,
|
||||
overtimeStartAfter: undefined,
|
||||
restDayMode: undefined,
|
||||
holidayPunchRequired: undefined
|
||||
})
|
||||
const formRules = reactive({
|
||||
name: [{ required: true, message: '规则名称不能为空', trigger: 'blur' }]
|
||||
})
|
||||
const formRef = ref() // 表单 Ref
|
||||
|
||||
/** 子表的表单 */
|
||||
const subTabsName = ref('attendShift')
|
||||
const attendShiftFormRef = ref()
|
||||
const userAttendRelationFormRef = ref()
|
||||
|
||||
/** 打开弹窗 */
|
||||
const open = async (type: string, id?: number) => {
|
||||
dialogVisible.value = true
|
||||
dialogTitle.value = t('action.' + type)
|
||||
formType.value = type
|
||||
resetForm()
|
||||
// 修改时,设置数据
|
||||
if (id) {
|
||||
formLoading.value = true
|
||||
try {
|
||||
formData.value = await AttendRuleApi.getAttendRule(id)
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||
|
||||
/** 提交表单 */
|
||||
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||
const submitForm = async () => {
|
||||
// 校验表单
|
||||
await formRef.value.validate()
|
||||
// 校验子表单
|
||||
try {
|
||||
await attendShiftFormRef.value.validate()
|
||||
} catch (e) {
|
||||
subTabsName.value = 'attendShift'
|
||||
return
|
||||
}
|
||||
try {
|
||||
await userAttendRelationFormRef.value.validate()
|
||||
} catch (e) {
|
||||
subTabsName.value = 'userAttendRelation'
|
||||
return
|
||||
}
|
||||
// 提交请求
|
||||
formLoading.value = true
|
||||
try {
|
||||
const data = formData.value as unknown as AttendRuleVO
|
||||
// 拼接子表的数据
|
||||
data.attendShifts = attendShiftFormRef.value.getData()
|
||||
data.userAttendRelations = userAttendRelationFormRef.value.getData()
|
||||
if (formType.value === 'create') {
|
||||
await AttendRuleApi.createAttendRule(data)
|
||||
message.success(t('common.createSuccess'))
|
||||
} else {
|
||||
await AttendRuleApi.updateAttendRule(data)
|
||||
message.success(t('common.updateSuccess'))
|
||||
}
|
||||
dialogVisible.value = false
|
||||
// 发送操作成功的事件
|
||||
emit('success')
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 重置表单 */
|
||||
const resetForm = () => {
|
||||
formData.value = {
|
||||
id: undefined,
|
||||
name: undefined,
|
||||
isOvertimeAllowed: undefined,
|
||||
overtimeStartAfter: undefined,
|
||||
restDayMode: undefined,
|
||||
holidayPunchRequired: undefined
|
||||
}
|
||||
formRef.value?.resetFields()
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
<template>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
v-loading="formLoading"
|
||||
label-width="0px"
|
||||
:inline-message="true"
|
||||
>
|
||||
<el-table :data="formData" class="-mt-10px">
|
||||
<el-table-column label="序号" type="index" width="100" />
|
||||
<el-table-column label="班次名称" min-width="150">
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.name`" :rules="formRules.name" class="mb-0px!">
|
||||
<el-input v-model="row.name" placeholder="请输入班次名称" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="班次类型:1固定班次 2轮班制(三班倒)" min-width="150">
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.shiftType`" :rules="formRules.shiftType" class="mb-0px!">
|
||||
<el-select v-model="row.shiftType" placeholder="请选择班次类型:1固定班次 2轮班制(三班倒)">
|
||||
<el-option
|
||||
v-for="dict in getIntDictOptions(DICT_TYPE.HRM_SHIFT_TYPE)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="是否包含休息时段" min-width="150">
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.restIncluded`" :rules="formRules.restIncluded" class="mb-0px!">
|
||||
<el-radio-group v-model="row.restIncluded">
|
||||
<el-radio
|
||||
v-for="dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
|
||||
:key="dict.value"
|
||||
:label="dict.value"
|
||||
>
|
||||
{{ dict.label }}
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" fixed="right" label="操作" width="60">
|
||||
<template #default="{ $index }">
|
||||
<el-button @click="handleDelete($index)" link>—</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-form>
|
||||
<el-row justify="center" class="mt-3">
|
||||
<el-button @click="handleAdd" round>+ 添加考勤班次</el-button>
|
||||
</el-row>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { getIntDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||
import { AttendRuleApi } from '@/api/hrm/attendrule'
|
||||
|
||||
const props = defineProps<{
|
||||
ruleId: undefined // 所属考勤规则(主表的关联字段)
|
||||
}>()
|
||||
const formLoading = ref(false) // 表单的加载中
|
||||
const formData = ref([])
|
||||
const formRules = reactive({
|
||||
ruleId: [{ required: true, message: '所属考勤规则不能为空', trigger: 'blur' }],
|
||||
name: [{ required: true, message: '班次名称不能为空', trigger: 'blur' }]
|
||||
})
|
||||
const formRef = ref() // 表单 Ref
|
||||
|
||||
/** 监听主表的关联字段的变化,加载对应的子表数据 */
|
||||
watch(
|
||||
() => props.ruleId,
|
||||
async (val) => {
|
||||
// 1. 重置表单
|
||||
formData.value = []
|
||||
// 2. val 非空,则加载数据
|
||||
if (!val) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
formLoading.value = true
|
||||
formData.value = await AttendRuleApi.getAttendShiftListByRuleId(val)
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = () => {
|
||||
const row = {
|
||||
id: undefined,
|
||||
ruleId: undefined,
|
||||
name: undefined,
|
||||
shiftType: undefined,
|
||||
restIncluded: undefined
|
||||
}
|
||||
row.ruleId = props.ruleId
|
||||
formData.value.push(row)
|
||||
}
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = (index) => {
|
||||
formData.value.splice(index, 1)
|
||||
}
|
||||
|
||||
/** 表单校验 */
|
||||
const validate = () => {
|
||||
return formRef.value.validate()
|
||||
}
|
||||
|
||||
/** 表单值 */
|
||||
const getData = () => {
|
||||
return formData.value
|
||||
}
|
||||
|
||||
defineExpose({ validate, getData })
|
||||
</script>
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
<template>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
v-loading="formLoading"
|
||||
label-width="0px"
|
||||
:inline-message="true"
|
||||
>
|
||||
<el-table :data="formData" class="-mt-10px">
|
||||
<el-table-column label="序号" type="index" width="100" />
|
||||
<el-table-column label="员工ID" min-width="150">
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.userId`" :rules="formRules.userId" class="mb-0px!">
|
||||
<el-input v-model="row.userId" placeholder="请输入员工ID" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="部门ID" min-width="150">
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.deptId`" :rules="formRules.deptId" class="mb-0px!">
|
||||
<el-input v-model="row.deptId" placeholder="请输入部门ID" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="岗位ID" min-width="150">
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.postId`" :rules="formRules.postId" class="mb-0px!">
|
||||
<el-input v-model="row.postId" placeholder="请输入岗位ID" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="绑定类型:1员工 2部门 3岗位" min-width="150">
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.bindType`" :rules="formRules.bindType" class="mb-0px!">
|
||||
<el-select v-model="row.bindType" placeholder="请选择绑定类型:1员工 2部门 3岗位">
|
||||
<el-option
|
||||
v-for="dict in getIntDictOptions(DICT_TYPE.HRM_BIND_TYPE)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" fixed="right" label="操作" width="60">
|
||||
<template #default="{ $index }">
|
||||
<el-button @click="handleDelete($index)" link>—</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-form>
|
||||
<el-row justify="center" class="mt-3">
|
||||
<el-button @click="handleAdd" round>+ 添加考勤关系</el-button>
|
||||
</el-row>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||
import { AttendRuleApi } from '@/api/hrm/attendrule'
|
||||
|
||||
const props = defineProps<{
|
||||
ruleId: undefined // 绑定的规则(主表的关联字段)
|
||||
}>()
|
||||
const formLoading = ref(false) // 表单的加载中
|
||||
const formData = ref([])
|
||||
const formRules = reactive({
|
||||
ruleId: [{ required: true, message: '绑定的规则不能为空', trigger: 'blur' }],
|
||||
bindType: [{ required: true, message: '绑定类型:1员工 2部门 3岗位不能为空', trigger: 'change' }]
|
||||
})
|
||||
const formRef = ref() // 表单 Ref
|
||||
|
||||
/** 监听主表的关联字段的变化,加载对应的子表数据 */
|
||||
watch(
|
||||
() => props.ruleId,
|
||||
async (val) => {
|
||||
// 1. 重置表单
|
||||
formData.value = []
|
||||
// 2. val 非空,则加载数据
|
||||
if (!val) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
formLoading.value = true
|
||||
formData.value = await AttendRuleApi.getUserAttendRelationListByRuleId(val)
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = () => {
|
||||
const row = {
|
||||
id: undefined,
|
||||
ruleId: undefined,
|
||||
userId: undefined,
|
||||
deptId: undefined,
|
||||
postId: undefined,
|
||||
bindType: undefined
|
||||
}
|
||||
row.ruleId = props.ruleId
|
||||
formData.value.push(row)
|
||||
}
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = (index) => {
|
||||
formData.value.splice(index, 1)
|
||||
}
|
||||
|
||||
/** 表单校验 */
|
||||
const validate = () => {
|
||||
return formRef.value.validate()
|
||||
}
|
||||
|
||||
/** 表单值 */
|
||||
const getData = () => {
|
||||
return formData.value
|
||||
}
|
||||
|
||||
defineExpose({ validate, getData })
|
||||
</script>
|
||||
|
|
@ -0,0 +1,262 @@
|
|||
<template>
|
||||
<ContentWrap>
|
||||
<!-- 搜索工作栏 -->
|
||||
<el-form
|
||||
class="-mb-15px"
|
||||
:model="queryParams"
|
||||
ref="queryFormRef"
|
||||
:inline="true"
|
||||
label-width="68px"
|
||||
>
|
||||
<el-form-item label="规则名称" prop="name">
|
||||
<el-input
|
||||
v-model="queryParams.name"
|
||||
placeholder="请输入规则名称"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否允许加班" prop="isOvertimeAllowed">
|
||||
<el-select
|
||||
v-model="queryParams.isOvertimeAllowed"
|
||||
placeholder="请选择是否允许加班"
|
||||
clearable
|
||||
class="!w-240px"
|
||||
>
|
||||
<el-option
|
||||
v-for="dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="下班多少分钟后算加班" prop="overtimeStartAfter">
|
||||
<el-input
|
||||
v-model="queryParams.overtimeStartAfter"
|
||||
placeholder="请输入下班多少分钟后算加班"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="休息日打卡规则:1交替一次 2交替多次" prop="restDayMode">
|
||||
<el-select
|
||||
v-model="queryParams.restDayMode"
|
||||
placeholder="请选择休息日打卡规则:1交替一次 2交替多次"
|
||||
clearable
|
||||
class="!w-240px"
|
||||
>
|
||||
<el-option
|
||||
v-for="dict in getIntDictOptions(DICT_TYPE.HRM_REST_DAY_MODE)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="法定假日是否需要打卡" prop="holidayPunchRequired">
|
||||
<el-select
|
||||
v-model="queryParams.holidayPunchRequired"
|
||||
placeholder="请选择法定假日是否需要打卡"
|
||||
clearable
|
||||
class="!w-240px"
|
||||
>
|
||||
<el-option
|
||||
v-for="dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间" prop="createTime">
|
||||
<el-date-picker
|
||||
v-model="queryParams.createTime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
type="daterange"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||
class="!w-220px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
@click="openForm('create')"
|
||||
v-hasPermi="['hrm:attend-rule:create']"
|
||||
>
|
||||
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||
</el-button>
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
@click="handleExport"
|
||||
:loading="exportLoading"
|
||||
v-hasPermi="['hrm:attend-rule:export']"
|
||||
>
|
||||
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 列表 -->
|
||||
<ContentWrap>
|
||||
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||
<el-table-column label="主键" align="center" prop="id" />
|
||||
<el-table-column label="规则名称" align="center" prop="name" />
|
||||
<el-table-column label="是否允许加班" align="center" prop="isOvertimeAllowed">
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.isOvertimeAllowed" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="下班多少分钟后算加班" align="center" prop="overtimeStartAfter" />
|
||||
<el-table-column label="休息日打卡规则:1交替一次 2交替多次" align="center" prop="restDayMode">
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.HRM_REST_DAY_MODE" :value="scope.row.restDayMode" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="法定假日是否需要打卡" align="center" prop="holidayPunchRequired">
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.holidayPunchRequired" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="创建时间"
|
||||
align="center"
|
||||
prop="createTime"
|
||||
:formatter="dateFormatter"
|
||||
width="180px"
|
||||
/>
|
||||
<el-table-column label="操作" align="center" min-width="120px">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
@click="openForm('update', scope.row.id)"
|
||||
v-hasPermi="['hrm:attend-rule:update']"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row.id)"
|
||||
v-hasPermi="['hrm:attend-rule:delete']"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 分页 -->
|
||||
<Pagination
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNo"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 表单弹窗:添加/修改 -->
|
||||
<AttendRuleForm ref="formRef" @success="getList" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { getIntDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||
import { dateFormatter } from '@/utils/formatTime'
|
||||
import download from '@/utils/download'
|
||||
import { AttendRuleApi, AttendRuleVO } from '@/api/hrm/attendrule'
|
||||
import AttendRuleForm from './AttendRuleForm.vue'
|
||||
|
||||
/** 考勤规则 列表 */
|
||||
defineOptions({ name: 'AttendRule' })
|
||||
|
||||
const message = useMessage() // 消息弹窗
|
||||
const { t } = useI18n() // 国际化
|
||||
|
||||
const loading = ref(true) // 列表的加载中
|
||||
const list = ref<AttendRuleVO[]>([]) // 列表的数据
|
||||
const total = ref(0) // 列表的总页数
|
||||
const queryParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
name: undefined,
|
||||
isOvertimeAllowed: undefined,
|
||||
overtimeStartAfter: undefined,
|
||||
restDayMode: undefined,
|
||||
holidayPunchRequired: undefined,
|
||||
createTime: []
|
||||
})
|
||||
const queryFormRef = ref() // 搜索的表单
|
||||
const exportLoading = ref(false) // 导出的加载中
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const data = await AttendRuleApi.getAttendRulePage(queryParams)
|
||||
list.value = data.list
|
||||
total.value = data.total
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNo = 1
|
||||
getList()
|
||||
}
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value.resetFields()
|
||||
handleQuery()
|
||||
}
|
||||
|
||||
/** 添加/修改操作 */
|
||||
const formRef = ref()
|
||||
const openForm = (type: string, id?: number) => {
|
||||
formRef.value.open(type, id)
|
||||
}
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (id: number) => {
|
||||
try {
|
||||
// 删除的二次确认
|
||||
await message.delConfirm()
|
||||
// 发起删除
|
||||
await AttendRuleApi.deleteAttendRule(id)
|
||||
message.success(t('common.delSuccess'))
|
||||
// 刷新列表
|
||||
await getList()
|
||||
} catch {}
|
||||
}
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
// 导出的二次确认
|
||||
await message.exportConfirm()
|
||||
// 发起导出
|
||||
exportLoading.value = true
|
||||
const data = await AttendRuleApi.exportAttendRule(queryParams)
|
||||
download.excel(data, '考勤规则.xls')
|
||||
} catch {
|
||||
} finally {
|
||||
exportLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 初始化 **/
|
||||
onMounted(() => {
|
||||
getList()
|
||||
})
|
||||
</script>
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
<template>
|
||||
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
label-width="100px"
|
||||
v-loading="formLoading"
|
||||
>
|
||||
<el-form-item label="所属考勤规则ID" prop="ruleId">
|
||||
<el-input v-model="formData.ruleId" placeholder="请输入所属考勤规则ID" />
|
||||
</el-form-item>
|
||||
<el-form-item label="调度类型:1=按天,2=按周,3=按月" prop="scheduleType">
|
||||
<el-select v-model="formData.scheduleType" placeholder="请选择调度类型:1=按天,2=按周,3=按月">
|
||||
<el-option label="请选择字典生成" value="" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="调度下标:日(从1开始),周(1~7),月(1~12)" prop="dayIndex">
|
||||
<el-input v-model="formData.dayIndex" placeholder="请输入调度下标:日(从1开始),周(1~7),月(1~12)" />
|
||||
</el-form-item>
|
||||
<el-form-item label="班次ID(为空表示休息)" prop="shiftId">
|
||||
<el-input v-model="formData.shiftId" placeholder="请输入班次ID(为空表示休息)" />
|
||||
</el-form-item>
|
||||
<el-form-item label="是否工作日(true 表示需打卡)" prop="isWorkingDay">
|
||||
<el-radio-group v-model="formData.isWorkingDay">
|
||||
<el-radio value="1">请选择字典生成</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注说明" prop="remarks">
|
||||
<el-input v-model="formData.remarks" placeholder="请输入备注说明" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { AttendScheduleConfigApi, AttendScheduleConfigVO } from '@/api/hrm/attendscheduleconfig'
|
||||
|
||||
/** 考勤排班调度配置 表单 */
|
||||
defineOptions({ name: 'AttendScheduleConfigForm' })
|
||||
|
||||
const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
|
||||
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||
const dialogTitle = ref('') // 弹窗的标题
|
||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||
const formData = ref({
|
||||
id: undefined,
|
||||
ruleId: undefined,
|
||||
scheduleType: undefined,
|
||||
dayIndex: undefined,
|
||||
shiftId: undefined,
|
||||
isWorkingDay: undefined,
|
||||
remarks: undefined
|
||||
})
|
||||
const formRules = reactive({
|
||||
ruleId: [{ required: true, message: '所属考勤规则ID不能为空', trigger: 'blur' }],
|
||||
scheduleType: [{ required: true, message: '调度类型:1=按天,2=按周,3=按月不能为空', trigger: 'change' }],
|
||||
dayIndex: [{ required: true, message: '调度下标:日(从1开始),周(1~7),月(1~12)不能为空', trigger: 'blur' }],
|
||||
isWorkingDay: [{ required: true, message: '是否工作日(true 表示需打卡)不能为空', trigger: 'blur' }]
|
||||
})
|
||||
const formRef = ref() // 表单 Ref
|
||||
|
||||
/** 打开弹窗 */
|
||||
const open = async (type: string, id?: number) => {
|
||||
dialogVisible.value = true
|
||||
dialogTitle.value = t('action.' + type)
|
||||
formType.value = type
|
||||
resetForm()
|
||||
// 修改时,设置数据
|
||||
if (id) {
|
||||
formLoading.value = true
|
||||
try {
|
||||
formData.value = await AttendScheduleConfigApi.getAttendScheduleConfig(id)
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||
|
||||
/** 提交表单 */
|
||||
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||
const submitForm = async () => {
|
||||
// 校验表单
|
||||
await formRef.value.validate()
|
||||
// 提交请求
|
||||
formLoading.value = true
|
||||
try {
|
||||
const data = formData.value as unknown as AttendScheduleConfigVO
|
||||
if (formType.value === 'create') {
|
||||
await AttendScheduleConfigApi.createAttendScheduleConfig(data)
|
||||
message.success(t('common.createSuccess'))
|
||||
} else {
|
||||
await AttendScheduleConfigApi.updateAttendScheduleConfig(data)
|
||||
message.success(t('common.updateSuccess'))
|
||||
}
|
||||
dialogVisible.value = false
|
||||
// 发送操作成功的事件
|
||||
emit('success')
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 重置表单 */
|
||||
const resetForm = () => {
|
||||
formData.value = {
|
||||
id: undefined,
|
||||
ruleId: undefined,
|
||||
scheduleType: undefined,
|
||||
dayIndex: undefined,
|
||||
shiftId: undefined,
|
||||
isWorkingDay: undefined,
|
||||
remarks: undefined
|
||||
}
|
||||
formRef.value?.resetFields()
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,244 @@
|
|||
<template>
|
||||
<ContentWrap>
|
||||
<!-- 搜索工作栏 -->
|
||||
<el-form
|
||||
class="-mb-15px"
|
||||
:model="queryParams"
|
||||
ref="queryFormRef"
|
||||
:inline="true"
|
||||
label-width="68px"
|
||||
>
|
||||
<el-form-item label="所属考勤规则ID" prop="ruleId">
|
||||
<el-input
|
||||
v-model="queryParams.ruleId"
|
||||
placeholder="请输入所属考勤规则ID"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="调度类型:1=按天,2=按周,3=按月" prop="scheduleType">
|
||||
<el-select
|
||||
v-model="queryParams.scheduleType"
|
||||
placeholder="请选择调度类型:1=按天,2=按周,3=按月"
|
||||
clearable
|
||||
class="!w-240px"
|
||||
>
|
||||
<el-option label="请选择字典生成" value="" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="调度下标:日(从1开始),周(1~7),月(1~12)" prop="dayIndex">
|
||||
<el-input
|
||||
v-model="queryParams.dayIndex"
|
||||
placeholder="请输入调度下标:日(从1开始),周(1~7),月(1~12)"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="班次ID(为空表示休息)" prop="shiftId">
|
||||
<el-input
|
||||
v-model="queryParams.shiftId"
|
||||
placeholder="请输入班次ID(为空表示休息)"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否工作日(true 表示需打卡)" prop="isWorkingDay">
|
||||
<el-select
|
||||
v-model="queryParams.isWorkingDay"
|
||||
placeholder="请选择是否工作日(true 表示需打卡)"
|
||||
clearable
|
||||
class="!w-240px"
|
||||
>
|
||||
<el-option label="请选择字典生成" value="" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注说明" prop="remarks">
|
||||
<el-input
|
||||
v-model="queryParams.remarks"
|
||||
placeholder="请输入备注说明"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间" prop="createTime">
|
||||
<el-date-picker
|
||||
v-model="queryParams.createTime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
type="daterange"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||
class="!w-220px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
@click="openForm('create')"
|
||||
v-hasPermi="['hrm:attend-schedule-config:create']"
|
||||
>
|
||||
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||
</el-button>
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
@click="handleExport"
|
||||
:loading="exportLoading"
|
||||
v-hasPermi="['hrm:attend-schedule-config:export']"
|
||||
>
|
||||
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 列表 -->
|
||||
<ContentWrap>
|
||||
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||
<el-table-column label="主键ID" align="center" prop="id" />
|
||||
<el-table-column label="所属考勤规则ID" align="center" prop="ruleId" />
|
||||
<el-table-column label="调度类型:1=按天,2=按周,3=按月" align="center" prop="scheduleType" />
|
||||
<el-table-column label="调度下标:日(从1开始),周(1~7),月(1~12)" align="center" prop="dayIndex" />
|
||||
<el-table-column label="班次ID(为空表示休息)" align="center" prop="shiftId" />
|
||||
<el-table-column label="是否工作日(true 表示需打卡)" align="center" prop="isWorkingDay" />
|
||||
<el-table-column label="备注说明" align="center" prop="remarks" />
|
||||
<el-table-column
|
||||
label="创建时间"
|
||||
align="center"
|
||||
prop="createTime"
|
||||
:formatter="dateFormatter"
|
||||
width="180px"
|
||||
/>
|
||||
<el-table-column label="操作" align="center" min-width="120px">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
@click="openForm('update', scope.row.id)"
|
||||
v-hasPermi="['hrm:attend-schedule-config:update']"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row.id)"
|
||||
v-hasPermi="['hrm:attend-schedule-config:delete']"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 分页 -->
|
||||
<Pagination
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNo"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 表单弹窗:添加/修改 -->
|
||||
<AttendScheduleConfigForm ref="formRef" @success="getList" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { dateFormatter } from '@/utils/formatTime'
|
||||
import download from '@/utils/download'
|
||||
import { AttendScheduleConfigApi, AttendScheduleConfigVO } from '@/api/hrm/attendscheduleconfig'
|
||||
import AttendScheduleConfigForm from './AttendScheduleConfigForm.vue'
|
||||
|
||||
/** 考勤排班调度配置 列表 */
|
||||
defineOptions({ name: 'AttendScheduleConfig' })
|
||||
|
||||
const message = useMessage() // 消息弹窗
|
||||
const { t } = useI18n() // 国际化
|
||||
|
||||
const loading = ref(true) // 列表的加载中
|
||||
const list = ref<AttendScheduleConfigVO[]>([]) // 列表的数据
|
||||
const total = ref(0) // 列表的总页数
|
||||
const queryParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
ruleId: undefined,
|
||||
scheduleType: undefined,
|
||||
dayIndex: undefined,
|
||||
shiftId: undefined,
|
||||
isWorkingDay: undefined,
|
||||
remarks: undefined,
|
||||
createTime: []
|
||||
})
|
||||
const queryFormRef = ref() // 搜索的表单
|
||||
const exportLoading = ref(false) // 导出的加载中
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const data = await AttendScheduleConfigApi.getAttendScheduleConfigPage(queryParams)
|
||||
list.value = data.list
|
||||
total.value = data.total
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNo = 1
|
||||
getList()
|
||||
}
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value.resetFields()
|
||||
handleQuery()
|
||||
}
|
||||
|
||||
/** 添加/修改操作 */
|
||||
const formRef = ref()
|
||||
const openForm = (type: string, id?: number) => {
|
||||
formRef.value.open(type, id)
|
||||
}
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (id: number) => {
|
||||
try {
|
||||
// 删除的二次确认
|
||||
await message.delConfirm()
|
||||
// 发起删除
|
||||
await AttendScheduleConfigApi.deleteAttendScheduleConfig(id)
|
||||
message.success(t('common.delSuccess'))
|
||||
// 刷新列表
|
||||
await getList()
|
||||
} catch {}
|
||||
}
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
// 导出的二次确认
|
||||
await message.exportConfirm()
|
||||
// 发起导出
|
||||
exportLoading.value = true
|
||||
const data = await AttendScheduleConfigApi.exportAttendScheduleConfig(queryParams)
|
||||
download.excel(data, '考勤排班调度配置.xls')
|
||||
} catch {
|
||||
} finally {
|
||||
exportLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 初始化 **/
|
||||
onMounted(() => {
|
||||
getList()
|
||||
})
|
||||
</script>
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
<template>
|
||||
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
label-width="100px"
|
||||
v-loading="formLoading"
|
||||
>
|
||||
<el-form-item label="所属考勤规则" prop="ruleId">
|
||||
<el-input v-model="formData.ruleId" placeholder="请输入所属考勤规则" />
|
||||
</el-form-item>
|
||||
<el-form-item label="班次名称" prop="name">
|
||||
<el-input v-model="formData.name" placeholder="请输入班次名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="班次类型:1固定班次 2轮班制(三班倒)" prop="shiftType">
|
||||
<el-select v-model="formData.shiftType" placeholder="请选择班次类型:1固定班次 2轮班制(三班倒)">
|
||||
<el-option
|
||||
v-for="dict in getIntDictOptions(DICT_TYPE.HRM_SHIFT_TYPE)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否包含休息时段" prop="restIncluded">
|
||||
<el-radio-group v-model="formData.restIncluded">
|
||||
<el-radio
|
||||
v-for="dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
|
||||
:key="dict.value"
|
||||
:label="dict.value"
|
||||
>
|
||||
{{ dict.label }}
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { getIntDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||
import { AttendShiftApi, AttendShiftVO } from '@/api/hrm/attendshift'
|
||||
|
||||
/** 考勤班次 表单 */
|
||||
defineOptions({ name: 'AttendShiftForm' })
|
||||
|
||||
const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
|
||||
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||
const dialogTitle = ref('') // 弹窗的标题
|
||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||
const formData = ref({
|
||||
id: undefined,
|
||||
ruleId: undefined,
|
||||
name: undefined,
|
||||
shiftType: undefined,
|
||||
restIncluded: undefined
|
||||
})
|
||||
const formRules = reactive({
|
||||
ruleId: [{ required: true, message: '所属考勤规则不能为空', trigger: 'blur' }],
|
||||
name: [{ required: true, message: '班次名称不能为空', trigger: 'blur' }]
|
||||
})
|
||||
const formRef = ref() // 表单 Ref
|
||||
|
||||
/** 打开弹窗 */
|
||||
const open = async (type: string, id?: number) => {
|
||||
dialogVisible.value = true
|
||||
dialogTitle.value = t('action.' + type)
|
||||
formType.value = type
|
||||
resetForm()
|
||||
// 修改时,设置数据
|
||||
if (id) {
|
||||
formLoading.value = true
|
||||
try {
|
||||
formData.value = await AttendShiftApi.getAttendShift(id)
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||
|
||||
/** 提交表单 */
|
||||
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||
const submitForm = async () => {
|
||||
// 校验表单
|
||||
await formRef.value.validate()
|
||||
// 提交请求
|
||||
formLoading.value = true
|
||||
try {
|
||||
const data = formData.value as unknown as AttendShiftVO
|
||||
if (formType.value === 'create') {
|
||||
await AttendShiftApi.createAttendShift(data)
|
||||
message.success(t('common.createSuccess'))
|
||||
} else {
|
||||
await AttendShiftApi.updateAttendShift(data)
|
||||
message.success(t('common.updateSuccess'))
|
||||
}
|
||||
dialogVisible.value = false
|
||||
// 发送操作成功的事件
|
||||
emit('success')
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 重置表单 */
|
||||
const resetForm = () => {
|
||||
formData.value = {
|
||||
id: undefined,
|
||||
ruleId: undefined,
|
||||
name: undefined,
|
||||
shiftType: undefined,
|
||||
restIncluded: undefined
|
||||
}
|
||||
formRef.value?.resetFields()
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,241 @@
|
|||
<template>
|
||||
<ContentWrap>
|
||||
<!-- 搜索工作栏 -->
|
||||
<el-form
|
||||
class="-mb-15px"
|
||||
:model="queryParams"
|
||||
ref="queryFormRef"
|
||||
:inline="true"
|
||||
label-width="68px"
|
||||
>
|
||||
<el-form-item label="所属考勤规则" prop="ruleId">
|
||||
<el-input
|
||||
v-model="queryParams.ruleId"
|
||||
placeholder="请输入所属考勤规则"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="班次名称" prop="name">
|
||||
<el-input
|
||||
v-model="queryParams.name"
|
||||
placeholder="请输入班次名称"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="班次类型:1固定班次 2轮班制(三班倒)" prop="shiftType">
|
||||
<el-select
|
||||
v-model="queryParams.shiftType"
|
||||
placeholder="请选择班次类型:1固定班次 2轮班制(三班倒)"
|
||||
clearable
|
||||
class="!w-240px"
|
||||
>
|
||||
<el-option
|
||||
v-for="dict in getIntDictOptions(DICT_TYPE.HRM_SHIFT_TYPE)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否包含休息时段" prop="restIncluded">
|
||||
<el-select
|
||||
v-model="queryParams.restIncluded"
|
||||
placeholder="请选择是否包含休息时段"
|
||||
clearable
|
||||
class="!w-240px"
|
||||
>
|
||||
<el-option
|
||||
v-for="dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间" prop="createTime">
|
||||
<el-date-picker
|
||||
v-model="queryParams.createTime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
type="daterange"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||
class="!w-220px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
@click="openForm('create')"
|
||||
v-hasPermi="['hrm:attend-shift:create']"
|
||||
>
|
||||
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||
</el-button>
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
@click="handleExport"
|
||||
:loading="exportLoading"
|
||||
v-hasPermi="['hrm:attend-shift:export']"
|
||||
>
|
||||
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 列表 -->
|
||||
<ContentWrap>
|
||||
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||
<el-table-column label="主键" align="center" prop="id" />
|
||||
<el-table-column label="所属考勤规则" align="center" prop="ruleId" />
|
||||
<el-table-column label="班次名称" align="center" prop="name" />
|
||||
<el-table-column label="班次类型:1固定班次 2轮班制(三班倒)" align="center" prop="shiftType">
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.HRM_SHIFT_TYPE" :value="scope.row.shiftType" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="是否包含休息时段" align="center" prop="restIncluded">
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.restIncluded" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="创建时间"
|
||||
align="center"
|
||||
prop="createTime"
|
||||
:formatter="dateFormatter"
|
||||
width="180px"
|
||||
/>
|
||||
<el-table-column label="操作" align="center" min-width="120px">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
@click="openForm('update', scope.row.id)"
|
||||
v-hasPermi="['hrm:attend-shift:update']"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row.id)"
|
||||
v-hasPermi="['hrm:attend-shift:delete']"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 分页 -->
|
||||
<Pagination
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNo"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 表单弹窗:添加/修改 -->
|
||||
<AttendShiftForm ref="formRef" @success="getList" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { getIntDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||
import { dateFormatter } from '@/utils/formatTime'
|
||||
import download from '@/utils/download'
|
||||
import { AttendShiftApi, AttendShiftVO } from '@/api/hrm/attendshift'
|
||||
import AttendShiftForm from './AttendShiftForm.vue'
|
||||
|
||||
/** 考勤班次 列表 */
|
||||
defineOptions({ name: 'AttendShift' })
|
||||
|
||||
const message = useMessage() // 消息弹窗
|
||||
const { t } = useI18n() // 国际化
|
||||
|
||||
const loading = ref(true) // 列表的加载中
|
||||
const list = ref<AttendShiftVO[]>([]) // 列表的数据
|
||||
const total = ref(0) // 列表的总页数
|
||||
const queryParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
ruleId: undefined,
|
||||
name: undefined,
|
||||
shiftType: undefined,
|
||||
restIncluded: undefined,
|
||||
createTime: []
|
||||
})
|
||||
const queryFormRef = ref() // 搜索的表单
|
||||
const exportLoading = ref(false) // 导出的加载中
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const data = await AttendShiftApi.getAttendShiftPage(queryParams)
|
||||
list.value = data.list
|
||||
total.value = data.total
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNo = 1
|
||||
getList()
|
||||
}
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value.resetFields()
|
||||
handleQuery()
|
||||
}
|
||||
|
||||
/** 添加/修改操作 */
|
||||
const formRef = ref()
|
||||
const openForm = (type: string, id?: number) => {
|
||||
formRef.value.open(type, id)
|
||||
}
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (id: number) => {
|
||||
try {
|
||||
// 删除的二次确认
|
||||
await message.delConfirm()
|
||||
// 发起删除
|
||||
await AttendShiftApi.deleteAttendShift(id)
|
||||
message.success(t('common.delSuccess'))
|
||||
// 刷新列表
|
||||
await getList()
|
||||
} catch {}
|
||||
}
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
// 导出的二次确认
|
||||
await message.exportConfirm()
|
||||
// 发起导出
|
||||
exportLoading.value = true
|
||||
const data = await AttendShiftApi.exportAttendShift(queryParams)
|
||||
download.excel(data, '考勤班次.xls')
|
||||
} catch {
|
||||
} finally {
|
||||
exportLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 初始化 **/
|
||||
onMounted(() => {
|
||||
getList()
|
||||
})
|
||||
</script>
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
<template>
|
||||
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
label-width="100px"
|
||||
v-loading="formLoading"
|
||||
>
|
||||
<el-form-item label="关联班次ID" prop="shiftId">
|
||||
<el-input v-model="formData.shiftId" placeholder="请输入关联班次ID" />
|
||||
</el-form-item>
|
||||
<el-form-item label="上班时间" prop="startTime">
|
||||
<el-date-picker
|
||||
v-model="formData.startTime"
|
||||
type="date"
|
||||
value-format="x"
|
||||
placeholder="选择上班时间"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="下班时间" prop="endTime">
|
||||
<el-date-picker
|
||||
v-model="formData.endTime"
|
||||
type="date"
|
||||
value-format="x"
|
||||
placeholder="选择下班时间"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="休息开始时间" prop="restStartTime">
|
||||
<el-date-picker
|
||||
v-model="formData.restStartTime"
|
||||
type="date"
|
||||
value-format="x"
|
||||
placeholder="选择休息开始时间"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="休息结束时间" prop="restEndTime">
|
||||
<el-date-picker
|
||||
v-model="formData.restEndTime"
|
||||
type="date"
|
||||
value-format="x"
|
||||
placeholder="选择休息结束时间"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="时段顺序(如早班、中班、晚班)" prop="seq">
|
||||
<el-input v-model="formData.seq" placeholder="请输入时段顺序(如早班、中班、晚班)" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { AttendShiftTimeApi, AttendShiftTimeVO } from '@/api/hrm/attendshifttime'
|
||||
|
||||
/** 考勤班次时间 表单 */
|
||||
defineOptions({ name: 'AttendShiftTimeForm' })
|
||||
|
||||
const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
|
||||
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||
const dialogTitle = ref('') // 弹窗的标题
|
||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||
const formData = ref({
|
||||
id: undefined,
|
||||
shiftId: undefined,
|
||||
startTime: undefined,
|
||||
endTime: undefined,
|
||||
restStartTime: undefined,
|
||||
restEndTime: undefined,
|
||||
seq: undefined
|
||||
})
|
||||
const formRules = reactive({
|
||||
shiftId: [{ required: true, message: '关联班次ID不能为空', trigger: 'blur' }],
|
||||
startTime: [{ required: true, message: '上班时间不能为空', trigger: 'blur' }],
|
||||
endTime: [{ required: true, message: '下班时间不能为空', trigger: 'blur' }]
|
||||
})
|
||||
const formRef = ref() // 表单 Ref
|
||||
|
||||
/** 打开弹窗 */
|
||||
const open = async (type: string, id?: number) => {
|
||||
dialogVisible.value = true
|
||||
dialogTitle.value = t('action.' + type)
|
||||
formType.value = type
|
||||
resetForm()
|
||||
// 修改时,设置数据
|
||||
if (id) {
|
||||
formLoading.value = true
|
||||
try {
|
||||
formData.value = await AttendShiftTimeApi.getAttendShiftTime(id)
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||
|
||||
/** 提交表单 */
|
||||
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||
const submitForm = async () => {
|
||||
// 校验表单
|
||||
await formRef.value.validate()
|
||||
// 提交请求
|
||||
formLoading.value = true
|
||||
try {
|
||||
const data = formData.value as unknown as AttendShiftTimeVO
|
||||
if (formType.value === 'create') {
|
||||
await AttendShiftTimeApi.createAttendShiftTime(data)
|
||||
message.success(t('common.createSuccess'))
|
||||
} else {
|
||||
await AttendShiftTimeApi.updateAttendShiftTime(data)
|
||||
message.success(t('common.updateSuccess'))
|
||||
}
|
||||
dialogVisible.value = false
|
||||
// 发送操作成功的事件
|
||||
emit('success')
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 重置表单 */
|
||||
const resetForm = () => {
|
||||
formData.value = {
|
||||
id: undefined,
|
||||
shiftId: undefined,
|
||||
startTime: undefined,
|
||||
endTime: undefined,
|
||||
restStartTime: undefined,
|
||||
restEndTime: undefined,
|
||||
seq: undefined
|
||||
}
|
||||
formRef.value?.resetFields()
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,250 @@
|
|||
<template>
|
||||
<ContentWrap>
|
||||
<!-- 搜索工作栏 -->
|
||||
<el-form
|
||||
class="-mb-15px"
|
||||
:model="queryParams"
|
||||
ref="queryFormRef"
|
||||
:inline="true"
|
||||
label-width="68px"
|
||||
>
|
||||
<el-form-item label="关联班次ID" prop="shiftId">
|
||||
<el-input
|
||||
v-model="queryParams.shiftId"
|
||||
placeholder="请输入关联班次ID"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="上班时间" prop="startTime">
|
||||
<el-date-picker
|
||||
v-model="queryParams.startTime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
type="daterange"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||
class="!w-220px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="下班时间" prop="endTime">
|
||||
<el-date-picker
|
||||
v-model="queryParams.endTime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
type="daterange"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||
class="!w-220px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="休息开始时间" prop="restStartTime">
|
||||
<el-date-picker
|
||||
v-model="queryParams.restStartTime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
type="daterange"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||
class="!w-220px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="休息结束时间" prop="restEndTime">
|
||||
<el-date-picker
|
||||
v-model="queryParams.restEndTime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
type="daterange"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||
class="!w-220px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="时段顺序(如早班、中班、晚班)" prop="seq">
|
||||
<el-input
|
||||
v-model="queryParams.seq"
|
||||
placeholder="请输入时段顺序(如早班、中班、晚班)"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间" prop="createTime">
|
||||
<el-date-picker
|
||||
v-model="queryParams.createTime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
type="daterange"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||
class="!w-220px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
@click="openForm('create')"
|
||||
v-hasPermi="['hrm:attend-shift-time:create']"
|
||||
>
|
||||
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||
</el-button>
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
@click="handleExport"
|
||||
:loading="exportLoading"
|
||||
v-hasPermi="['hrm:attend-shift-time:export']"
|
||||
>
|
||||
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 列表 -->
|
||||
<ContentWrap>
|
||||
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||
<el-table-column label="主键" align="center" prop="id" />
|
||||
<el-table-column label="关联班次ID" align="center" prop="shiftId" />
|
||||
<el-table-column label="上班时间" align="center" prop="startTime" />
|
||||
<el-table-column label="下班时间" align="center" prop="endTime" />
|
||||
<el-table-column label="休息开始时间" align="center" prop="restStartTime" />
|
||||
<el-table-column label="休息结束时间" align="center" prop="restEndTime" />
|
||||
<el-table-column label="时段顺序(如早班、中班、晚班)" align="center" prop="seq" />
|
||||
<el-table-column
|
||||
label="创建时间"
|
||||
align="center"
|
||||
prop="createTime"
|
||||
:formatter="dateFormatter"
|
||||
width="180px"
|
||||
/>
|
||||
<el-table-column label="操作" align="center" min-width="120px">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
@click="openForm('update', scope.row.id)"
|
||||
v-hasPermi="['hrm:attend-shift-time:update']"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row.id)"
|
||||
v-hasPermi="['hrm:attend-shift-time:delete']"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 分页 -->
|
||||
<Pagination
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNo"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 表单弹窗:添加/修改 -->
|
||||
<AttendShiftTimeForm ref="formRef" @success="getList" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { dateFormatter } from '@/utils/formatTime'
|
||||
import download from '@/utils/download'
|
||||
import { AttendShiftTimeApi, AttendShiftTimeVO } from '@/api/hrm/attendshifttime'
|
||||
import AttendShiftTimeForm from './AttendShiftTimeForm.vue'
|
||||
|
||||
/** 考勤班次时间 列表 */
|
||||
defineOptions({ name: 'AttendShiftTime' })
|
||||
|
||||
const message = useMessage() // 消息弹窗
|
||||
const { t } = useI18n() // 国际化
|
||||
|
||||
const loading = ref(true) // 列表的加载中
|
||||
const list = ref<AttendShiftTimeVO[]>([]) // 列表的数据
|
||||
const total = ref(0) // 列表的总页数
|
||||
const queryParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
shiftId: undefined,
|
||||
startTime: [],
|
||||
endTime: [],
|
||||
restStartTime: [],
|
||||
restEndTime: [],
|
||||
seq: undefined,
|
||||
createTime: []
|
||||
})
|
||||
const queryFormRef = ref() // 搜索的表单
|
||||
const exportLoading = ref(false) // 导出的加载中
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const data = await AttendShiftTimeApi.getAttendShiftTimePage(queryParams)
|
||||
list.value = data.list
|
||||
total.value = data.total
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNo = 1
|
||||
getList()
|
||||
}
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value.resetFields()
|
||||
handleQuery()
|
||||
}
|
||||
|
||||
/** 添加/修改操作 */
|
||||
const formRef = ref()
|
||||
const openForm = (type: string, id?: number) => {
|
||||
formRef.value.open(type, id)
|
||||
}
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (id: number) => {
|
||||
try {
|
||||
// 删除的二次确认
|
||||
await message.delConfirm()
|
||||
// 发起删除
|
||||
await AttendShiftTimeApi.deleteAttendShiftTime(id)
|
||||
message.success(t('common.delSuccess'))
|
||||
// 刷新列表
|
||||
await getList()
|
||||
} catch {}
|
||||
}
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
// 导出的二次确认
|
||||
await message.exportConfirm()
|
||||
// 发起导出
|
||||
exportLoading.value = true
|
||||
const data = await AttendShiftTimeApi.exportAttendShiftTime(queryParams)
|
||||
download.excel(data, '考勤班次时间.xls')
|
||||
} catch {
|
||||
} finally {
|
||||
exportLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 初始化 **/
|
||||
onMounted(() => {
|
||||
getList()
|
||||
})
|
||||
</script>
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
<template>
|
||||
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
label-width="100px"
|
||||
v-loading="formLoading"
|
||||
>
|
||||
<el-form-item label="员工档案ID(关联 hrm_user_infor)" prop="userId">
|
||||
<el-input v-model="formData.userId" placeholder="请输入员工档案ID(关联 hrm_user_infor)" />
|
||||
</el-form-item>
|
||||
<el-form-item label="考核月份(格式:YYYY-MM)" prop="assessmentMonth">
|
||||
<el-input v-model="formData.assessmentMonth" placeholder="请输入考核月份(格式:YYYY-MM)" />
|
||||
</el-form-item>
|
||||
<el-form-item label="绩效等级" prop="performanceLevel">
|
||||
<el-select v-model="formData.performanceLevel" placeholder="请选择绩效等级">
|
||||
<el-option
|
||||
v-for="dict in getIntDictOptions(DICT_TYPE.HRM_PERFORMANCE_LEVEL)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="考核得分合计" prop="assessmentScoreTotal">
|
||||
<el-input v-model="formData.assessmentScoreTotal" placeholder="请输入考核得分合计" />
|
||||
</el-form-item>
|
||||
<el-form-item label="考勤得分" prop="attendanceScore">
|
||||
<el-input v-model="formData.attendanceScore" placeholder="请输入考勤得分" />
|
||||
</el-form-item>
|
||||
<el-form-item label="业绩考核得分" prop="performanceAssessmentScore">
|
||||
<el-input v-model="formData.performanceAssessmentScore" placeholder="请输入业绩考核得分" />
|
||||
</el-form-item>
|
||||
<el-form-item label="行为考核得分" prop="behaviorAssessmentScore">
|
||||
<el-input v-model="formData.behaviorAssessmentScore" placeholder="请输入行为考核得分" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||
import { UserPerformanceApi, UserPerformanceVO } from '@/api/hrm/userperformance'
|
||||
|
||||
/** 员工绩效 表单 */
|
||||
defineOptions({ name: 'UserPerformanceForm' })
|
||||
|
||||
const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
|
||||
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||
const dialogTitle = ref('') // 弹窗的标题
|
||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||
const formData = ref({
|
||||
id: undefined,
|
||||
userId: undefined,
|
||||
assessmentMonth: undefined,
|
||||
performanceLevel: undefined,
|
||||
assessmentScoreTotal: undefined,
|
||||
attendanceScore: undefined,
|
||||
performanceAssessmentScore: undefined,
|
||||
behaviorAssessmentScore: undefined
|
||||
})
|
||||
const formRules = reactive({
|
||||
assessmentMonth: [{ required: true, message: '考核月份(格式:YYYY-MM)不能为空', trigger: 'blur' }],
|
||||
performanceLevel: [{ required: true, message: '绩效等级不能为空', trigger: 'change' }],
|
||||
assessmentScoreTotal: [{ required: true, message: '考核得分合计不能为空', trigger: 'blur' }],
|
||||
attendanceScore: [{ required: true, message: '考勤得分不能为空', trigger: 'blur' }],
|
||||
performanceAssessmentScore: [{ required: true, message: '业绩考核得分不能为空', trigger: 'blur' }],
|
||||
behaviorAssessmentScore: [{ required: true, message: '行为考核得分不能为空', trigger: 'blur' }]
|
||||
})
|
||||
const formRef = ref() // 表单 Ref
|
||||
|
||||
/** 打开弹窗 */
|
||||
const open = async (type: string, id?: number) => {
|
||||
dialogVisible.value = true
|
||||
dialogTitle.value = t('action.' + type)
|
||||
formType.value = type
|
||||
resetForm()
|
||||
// 修改时,设置数据
|
||||
if (id) {
|
||||
formLoading.value = true
|
||||
try {
|
||||
formData.value = await UserPerformanceApi.getUserPerformance(id)
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||
|
||||
/** 提交表单 */
|
||||
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||
const submitForm = async () => {
|
||||
// 校验表单
|
||||
await formRef.value.validate()
|
||||
// 提交请求
|
||||
formLoading.value = true
|
||||
try {
|
||||
const data = formData.value as unknown as UserPerformanceVO
|
||||
if (formType.value === 'create') {
|
||||
await UserPerformanceApi.createUserPerformance(data)
|
||||
message.success(t('common.createSuccess'))
|
||||
} else {
|
||||
await UserPerformanceApi.updateUserPerformance(data)
|
||||
message.success(t('common.updateSuccess'))
|
||||
}
|
||||
dialogVisible.value = false
|
||||
// 发送操作成功的事件
|
||||
emit('success')
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 重置表单 */
|
||||
const resetForm = () => {
|
||||
formData.value = {
|
||||
id: undefined,
|
||||
userId: undefined,
|
||||
assessmentMonth: undefined,
|
||||
performanceLevel: undefined,
|
||||
assessmentScoreTotal: undefined,
|
||||
attendanceScore: undefined,
|
||||
performanceAssessmentScore: undefined,
|
||||
behaviorAssessmentScore: undefined
|
||||
}
|
||||
formRef.value?.resetFields()
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,264 @@
|
|||
<template>
|
||||
<ContentWrap>
|
||||
<!-- 搜索工作栏 -->
|
||||
<el-form
|
||||
class="-mb-15px"
|
||||
:model="queryParams"
|
||||
ref="queryFormRef"
|
||||
:inline="true"
|
||||
label-width="68px"
|
||||
>
|
||||
<el-form-item label="员工档案ID(关联 hrm_user_infor)" prop="userId">
|
||||
<el-input
|
||||
v-model="queryParams.userId"
|
||||
placeholder="请输入员工档案ID(关联 hrm_user_infor)"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="考核月份(格式:YYYY-MM)" prop="assessmentMonth">
|
||||
<el-input
|
||||
v-model="queryParams.assessmentMonth"
|
||||
placeholder="请输入考核月份(格式:YYYY-MM)"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="绩效等级" prop="performanceLevel">
|
||||
<el-select
|
||||
v-model="queryParams.performanceLevel"
|
||||
placeholder="请选择绩效等级"
|
||||
clearable
|
||||
class="!w-240px"
|
||||
>
|
||||
<el-option
|
||||
v-for="dict in getIntDictOptions(DICT_TYPE.HRM_PERFORMANCE_LEVEL)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="考核得分合计" prop="assessmentScoreTotal">
|
||||
<el-input
|
||||
v-model="queryParams.assessmentScoreTotal"
|
||||
placeholder="请输入考核得分合计"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="考勤得分" prop="attendanceScore">
|
||||
<el-input
|
||||
v-model="queryParams.attendanceScore"
|
||||
placeholder="请输入考勤得分"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="业绩考核得分" prop="performanceAssessmentScore">
|
||||
<el-input
|
||||
v-model="queryParams.performanceAssessmentScore"
|
||||
placeholder="请输入业绩考核得分"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="行为考核得分" prop="behaviorAssessmentScore">
|
||||
<el-input
|
||||
v-model="queryParams.behaviorAssessmentScore"
|
||||
placeholder="请输入行为考核得分"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间" prop="createTime">
|
||||
<el-date-picker
|
||||
v-model="queryParams.createTime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
type="daterange"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||
class="!w-220px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
@click="openForm('create')"
|
||||
v-hasPermi="['hrm:user-performance:create']"
|
||||
>
|
||||
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||
</el-button>
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
@click="handleExport"
|
||||
:loading="exportLoading"
|
||||
v-hasPermi="['hrm:user-performance:export']"
|
||||
>
|
||||
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 列表 -->
|
||||
<ContentWrap>
|
||||
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||
<el-table-column label="唯一主键" align="center" prop="id" />
|
||||
<el-table-column label="员工档案ID(关联 hrm_user_infor)" align="center" prop="userId" />
|
||||
<el-table-column label="考核月份(格式:YYYY-MM)" align="center" prop="assessmentMonth" />
|
||||
<el-table-column label="绩效等级" align="center" prop="performanceLevel">
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.HRM_PERFORMANCE_LEVEL" :value="scope.row.performanceLevel" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="考核得分合计" align="center" prop="assessmentScoreTotal" />
|
||||
<el-table-column label="考勤得分" align="center" prop="attendanceScore" />
|
||||
<el-table-column label="业绩考核得分" align="center" prop="performanceAssessmentScore" />
|
||||
<el-table-column label="行为考核得分" align="center" prop="behaviorAssessmentScore" />
|
||||
<el-table-column
|
||||
label="创建时间"
|
||||
align="center"
|
||||
prop="createTime"
|
||||
:formatter="dateFormatter"
|
||||
width="180px"
|
||||
/>
|
||||
<el-table-column label="操作" align="center" min-width="120px">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
@click="openForm('update', scope.row.id)"
|
||||
v-hasPermi="['hrm:user-performance:update']"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row.id)"
|
||||
v-hasPermi="['hrm:user-performance:delete']"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 分页 -->
|
||||
<Pagination
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNo"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 表单弹窗:添加/修改 -->
|
||||
<UserPerformanceForm ref="formRef" @success="getList" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||
import { dateFormatter } from '@/utils/formatTime'
|
||||
import download from '@/utils/download'
|
||||
import { UserPerformanceApi, UserPerformanceVO } from '@/api/hrm/userperformance'
|
||||
import UserPerformanceForm from './UserPerformanceForm.vue'
|
||||
|
||||
/** 员工绩效 列表 */
|
||||
defineOptions({ name: 'UserPerformance' })
|
||||
|
||||
const message = useMessage() // 消息弹窗
|
||||
const { t } = useI18n() // 国际化
|
||||
|
||||
const loading = ref(true) // 列表的加载中
|
||||
const list = ref<UserPerformanceVO[]>([]) // 列表的数据
|
||||
const total = ref(0) // 列表的总页数
|
||||
const queryParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
userId: undefined,
|
||||
assessmentMonth: undefined,
|
||||
performanceLevel: undefined,
|
||||
assessmentScoreTotal: undefined,
|
||||
attendanceScore: undefined,
|
||||
performanceAssessmentScore: undefined,
|
||||
behaviorAssessmentScore: undefined,
|
||||
createTime: []
|
||||
})
|
||||
const queryFormRef = ref() // 搜索的表单
|
||||
const exportLoading = ref(false) // 导出的加载中
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const data = await UserPerformanceApi.getUserPerformancePage(queryParams)
|
||||
list.value = data.list
|
||||
total.value = data.total
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNo = 1
|
||||
getList()
|
||||
}
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value.resetFields()
|
||||
handleQuery()
|
||||
}
|
||||
|
||||
/** 添加/修改操作 */
|
||||
const formRef = ref()
|
||||
const openForm = (type: string, id?: number) => {
|
||||
formRef.value.open(type, id)
|
||||
}
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (id: number) => {
|
||||
try {
|
||||
// 删除的二次确认
|
||||
await message.delConfirm()
|
||||
// 发起删除
|
||||
await UserPerformanceApi.deleteUserPerformance(id)
|
||||
message.success(t('common.delSuccess'))
|
||||
// 刷新列表
|
||||
await getList()
|
||||
} catch {}
|
||||
}
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
// 导出的二次确认
|
||||
await message.exportConfirm()
|
||||
// 发起导出
|
||||
exportLoading.value = true
|
||||
const data = await UserPerformanceApi.exportUserPerformance(queryParams)
|
||||
download.excel(data, '员工绩效.xls')
|
||||
} catch {
|
||||
} finally {
|
||||
exportLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 初始化 **/
|
||||
onMounted(() => {
|
||||
getList()
|
||||
})
|
||||
</script>
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
<template>
|
||||
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
label-width="100px"
|
||||
v-loading="formLoading"
|
||||
>
|
||||
<el-form-item label="岗位关联ID" prop="postId">
|
||||
<el-input v-model="formData.postId" placeholder="请输入岗位关联ID" />
|
||||
</el-form-item>
|
||||
<el-form-item label="考核类型" prop="assessType">
|
||||
<el-select v-model="formData.assessType" placeholder="请选择考核类型">
|
||||
<el-option
|
||||
v-for="dict in getStrDictOptions(DICT_TYPE.HRM_ASSESS_TYPE)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="考核名称" prop="assessName">
|
||||
<el-input v-model="formData.assessName" placeholder="请输入考核名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="考核详情" prop="assessDetail">
|
||||
<el-input v-model="formData.assessDetail" placeholder="请输入考核详情" />
|
||||
</el-form-item>
|
||||
<el-form-item label="分数分值" prop="score">
|
||||
<el-input v-model="formData.score" placeholder="请输入分数分值" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { getStrDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||
import { PostAssessmentApi, PostAssessmentVO } from '@/api/system/postassessment'
|
||||
|
||||
/** 职位考核信息 表单 */
|
||||
defineOptions({ name: 'PostAssessmentForm' })
|
||||
|
||||
const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
|
||||
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||
const dialogTitle = ref('') // 弹窗的标题
|
||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||
const formData = ref({
|
||||
id: undefined,
|
||||
postId: undefined,
|
||||
assessType: undefined,
|
||||
assessName: undefined,
|
||||
assessDetail: undefined,
|
||||
score: undefined
|
||||
})
|
||||
const formRules = reactive({
|
||||
postId: [{ required: true, message: '岗位关联ID不能为空', trigger: 'blur' }],
|
||||
assessName: [{ required: true, message: '考核名称不能为空', trigger: 'blur' }]
|
||||
})
|
||||
const formRef = ref() // 表单 Ref
|
||||
|
||||
/** 打开弹窗 */
|
||||
const open = async (type: string, id?: number) => {
|
||||
dialogVisible.value = true
|
||||
dialogTitle.value = t('action.' + type)
|
||||
formType.value = type
|
||||
resetForm()
|
||||
// 修改时,设置数据
|
||||
if (id) {
|
||||
formLoading.value = true
|
||||
try {
|
||||
formData.value = await PostAssessmentApi.getPostAssessment(id)
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||
|
||||
/** 提交表单 */
|
||||
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||
const submitForm = async () => {
|
||||
// 校验表单
|
||||
await formRef.value.validate()
|
||||
// 提交请求
|
||||
formLoading.value = true
|
||||
try {
|
||||
const data = formData.value as unknown as PostAssessmentVO
|
||||
if (formType.value === 'create') {
|
||||
await PostAssessmentApi.createPostAssessment(data)
|
||||
message.success(t('common.createSuccess'))
|
||||
} else {
|
||||
await PostAssessmentApi.updatePostAssessment(data)
|
||||
message.success(t('common.updateSuccess'))
|
||||
}
|
||||
dialogVisible.value = false
|
||||
// 发送操作成功的事件
|
||||
emit('success')
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 重置表单 */
|
||||
const resetForm = () => {
|
||||
formData.value = {
|
||||
id: undefined,
|
||||
postId: undefined,
|
||||
assessType: undefined,
|
||||
assessName: undefined,
|
||||
assessDetail: undefined,
|
||||
score: undefined
|
||||
}
|
||||
formRef.value?.resetFields()
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,222 @@
|
|||
<template>
|
||||
<ContentWrap>
|
||||
<!-- 搜索工作栏 -->
|
||||
<el-form
|
||||
class="-mb-15px"
|
||||
:model="queryParams"
|
||||
ref="queryFormRef"
|
||||
:inline="true"
|
||||
label-width="68px"
|
||||
>
|
||||
<el-form-item label="岗位关联ID" prop="postId">
|
||||
<el-input
|
||||
v-model="queryParams.postId"
|
||||
placeholder="请输入岗位关联ID"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="考核类型" prop="assessType">
|
||||
<el-select
|
||||
v-model="queryParams.assessType"
|
||||
placeholder="请选择考核类型"
|
||||
clearable
|
||||
class="!w-240px"
|
||||
>
|
||||
<el-option
|
||||
v-for="dict in getStrDictOptions(DICT_TYPE.HRM_ASSESS_TYPE)"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="考核名称" prop="assessName">
|
||||
<el-input
|
||||
v-model="queryParams.assessName"
|
||||
placeholder="请输入考核名称"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="考核详情" prop="assessDetail">
|
||||
<el-input
|
||||
v-model="queryParams.assessDetail"
|
||||
placeholder="请输入考核详情"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="分数分值" prop="score">
|
||||
<el-input
|
||||
v-model="queryParams.score"
|
||||
placeholder="请输入分数分值"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
@click="openForm('create')"
|
||||
v-hasPermi="['system:post-assessment:create']"
|
||||
>
|
||||
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||
</el-button>
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
@click="handleExport"
|
||||
:loading="exportLoading"
|
||||
v-hasPermi="['system:post-assessment:export']"
|
||||
>
|
||||
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 列表 -->
|
||||
<ContentWrap>
|
||||
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||
<el-table-column label="主键" align="center" prop="id" />
|
||||
<el-table-column label="岗位关联ID" align="center" prop="postId" />
|
||||
<el-table-column label="考核类型" align="center" prop="assessType">
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.HRM_ASSESS_TYPE" :value="scope.row.assessType" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="考核名称" align="center" prop="assessName" />
|
||||
<el-table-column label="考核详情" align="center" prop="assessDetail" />
|
||||
<el-table-column label="分数分值" align="center" prop="score" />
|
||||
<el-table-column label="操作" align="center" min-width="120px">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
@click="openForm('update', scope.row.id)"
|
||||
v-hasPermi="['system:post-assessment:update']"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row.id)"
|
||||
v-hasPermi="['system:post-assessment:delete']"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 分页 -->
|
||||
<Pagination
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNo"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 表单弹窗:添加/修改 -->
|
||||
<PostAssessmentForm ref="formRef" @success="getList" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { getStrDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||
import download from '@/utils/download'
|
||||
import { PostAssessmentApi, PostAssessmentVO } from '@/api/system/postassessment'
|
||||
import PostAssessmentForm from './PostAssessmentForm.vue'
|
||||
|
||||
/** 职位考核信息 列表 */
|
||||
defineOptions({ name: 'PostAssessment' })
|
||||
|
||||
const message = useMessage() // 消息弹窗
|
||||
const { t } = useI18n() // 国际化
|
||||
|
||||
const loading = ref(true) // 列表的加载中
|
||||
const list = ref<PostAssessmentVO[]>([]) // 列表的数据
|
||||
const total = ref(0) // 列表的总页数
|
||||
const queryParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
postId: undefined,
|
||||
assessType: undefined,
|
||||
assessName: undefined,
|
||||
assessDetail: undefined,
|
||||
score: undefined
|
||||
})
|
||||
const queryFormRef = ref() // 搜索的表单
|
||||
const exportLoading = ref(false) // 导出的加载中
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const data = await PostAssessmentApi.getPostAssessmentPage(queryParams)
|
||||
list.value = data.list
|
||||
total.value = data.total
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNo = 1
|
||||
getList()
|
||||
}
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value.resetFields()
|
||||
handleQuery()
|
||||
}
|
||||
|
||||
/** 添加/修改操作 */
|
||||
const formRef = ref()
|
||||
const openForm = (type: string, id?: number) => {
|
||||
formRef.value.open(type, id)
|
||||
}
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (id: number) => {
|
||||
try {
|
||||
// 删除的二次确认
|
||||
await message.delConfirm()
|
||||
// 发起删除
|
||||
await PostAssessmentApi.deletePostAssessment(id)
|
||||
message.success(t('common.delSuccess'))
|
||||
// 刷新列表
|
||||
await getList()
|
||||
} catch {}
|
||||
}
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
// 导出的二次确认
|
||||
await message.exportConfirm()
|
||||
// 发起导出
|
||||
exportLoading.value = true
|
||||
const data = await PostAssessmentApi.exportPostAssessment(queryParams)
|
||||
download.excel(data, '职位考核信息.xls')
|
||||
} catch {
|
||||
} finally {
|
||||
exportLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 初始化 **/
|
||||
onMounted(() => {
|
||||
getList()
|
||||
})
|
||||
</script>
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
<template>
|
||||
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
label-width="100px"
|
||||
v-loading="formLoading"
|
||||
>
|
||||
<el-form-item label="岗位关联ID" prop="postId">
|
||||
<el-input v-model="formData.postId" placeholder="请输入岗位关联ID" />
|
||||
</el-form-item>
|
||||
<el-form-item label="名称" prop="requirementName">
|
||||
<el-input v-model="formData.requirementName" placeholder="请输入名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="资格说明" prop="qualificationDescription">
|
||||
<Editor v-model="formData.qualificationDescription" height="150px" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { PostRequirementApi, PostRequirementVO } from '@/api/system/postrequirement'
|
||||
|
||||
/** 任职条件 表单 */
|
||||
defineOptions({ name: 'PostRequirementForm' })
|
||||
|
||||
const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
|
||||
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||
const dialogTitle = ref('') // 弹窗的标题
|
||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||
const formData = ref({
|
||||
id: undefined,
|
||||
postId: undefined,
|
||||
requirementName: undefined,
|
||||
qualificationDescription: undefined
|
||||
})
|
||||
const formRules = reactive({
|
||||
postId: [{ required: true, message: '岗位关联ID不能为空', trigger: 'blur' }],
|
||||
requirementName: [{ required: true, message: '名称不能为空', trigger: 'blur' }]
|
||||
})
|
||||
const formRef = ref() // 表单 Ref
|
||||
|
||||
/** 打开弹窗 */
|
||||
const open = async (type: string, id?: number) => {
|
||||
dialogVisible.value = true
|
||||
dialogTitle.value = t('action.' + type)
|
||||
formType.value = type
|
||||
resetForm()
|
||||
// 修改时,设置数据
|
||||
if (id) {
|
||||
formLoading.value = true
|
||||
try {
|
||||
formData.value = await PostRequirementApi.getPostRequirement(id)
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||
|
||||
/** 提交表单 */
|
||||
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||
const submitForm = async () => {
|
||||
// 校验表单
|
||||
await formRef.value.validate()
|
||||
// 提交请求
|
||||
formLoading.value = true
|
||||
try {
|
||||
const data = formData.value as unknown as PostRequirementVO
|
||||
if (formType.value === 'create') {
|
||||
await PostRequirementApi.createPostRequirement(data)
|
||||
message.success(t('common.createSuccess'))
|
||||
} else {
|
||||
await PostRequirementApi.updatePostRequirement(data)
|
||||
message.success(t('common.updateSuccess'))
|
||||
}
|
||||
dialogVisible.value = false
|
||||
// 发送操作成功的事件
|
||||
emit('success')
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 重置表单 */
|
||||
const resetForm = () => {
|
||||
formData.value = {
|
||||
id: undefined,
|
||||
postId: undefined,
|
||||
requirementName: undefined,
|
||||
qualificationDescription: undefined
|
||||
}
|
||||
formRef.value?.resetFields()
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
<template>
|
||||
<ContentWrap>
|
||||
<!-- 搜索工作栏 -->
|
||||
<el-form
|
||||
class="-mb-15px"
|
||||
:model="queryParams"
|
||||
ref="queryFormRef"
|
||||
:inline="true"
|
||||
label-width="68px"
|
||||
>
|
||||
<el-form-item label="岗位关联ID" prop="postId">
|
||||
<el-input
|
||||
v-model="queryParams.postId"
|
||||
placeholder="请输入岗位关联ID"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="名称" prop="requirementName">
|
||||
<el-input
|
||||
v-model="queryParams.requirementName"
|
||||
placeholder="请输入名称"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
@click="openForm('create')"
|
||||
v-hasPermi="['system:post-requirement:create']"
|
||||
>
|
||||
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||
</el-button>
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
@click="handleExport"
|
||||
:loading="exportLoading"
|
||||
v-hasPermi="['system:post-requirement:export']"
|
||||
>
|
||||
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 列表 -->
|
||||
<ContentWrap>
|
||||
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||
<el-table-column label="唯一主键" align="center" prop="id" />
|
||||
<el-table-column label="岗位关联ID" align="center" prop="postId" />
|
||||
<el-table-column label="名称" align="center" prop="requirementName" />
|
||||
<el-table-column label="资格说明" align="center" prop="qualificationDescription" />
|
||||
<el-table-column label="操作" align="center" min-width="120px">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
@click="openForm('update', scope.row.id)"
|
||||
v-hasPermi="['system:post-requirement:update']"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row.id)"
|
||||
v-hasPermi="['system:post-requirement:delete']"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 分页 -->
|
||||
<Pagination
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNo"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 表单弹窗:添加/修改 -->
|
||||
<PostRequirementForm ref="formRef" @success="getList" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import download from '@/utils/download'
|
||||
import { PostRequirementApi, PostRequirementVO } from '@/api/system/postrequirement'
|
||||
import PostRequirementForm from './PostRequirementForm.vue'
|
||||
|
||||
/** 任职条件 列表 */
|
||||
defineOptions({ name: 'PostRequirement' })
|
||||
|
||||
const message = useMessage() // 消息弹窗
|
||||
const { t } = useI18n() // 国际化
|
||||
|
||||
const loading = ref(true) // 列表的加载中
|
||||
const list = ref<PostRequirementVO[]>([]) // 列表的数据
|
||||
const total = ref(0) // 列表的总页数
|
||||
const queryParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
postId: undefined,
|
||||
requirementName: undefined,
|
||||
qualificationDescription: undefined
|
||||
})
|
||||
const queryFormRef = ref() // 搜索的表单
|
||||
const exportLoading = ref(false) // 导出的加载中
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const data = await PostRequirementApi.getPostRequirementPage(queryParams)
|
||||
list.value = data.list
|
||||
total.value = data.total
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNo = 1
|
||||
getList()
|
||||
}
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value.resetFields()
|
||||
handleQuery()
|
||||
}
|
||||
|
||||
/** 添加/修改操作 */
|
||||
const formRef = ref()
|
||||
const openForm = (type: string, id?: number) => {
|
||||
formRef.value.open(type, id)
|
||||
}
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (id: number) => {
|
||||
try {
|
||||
// 删除的二次确认
|
||||
await message.delConfirm()
|
||||
// 发起删除
|
||||
await PostRequirementApi.deletePostRequirement(id)
|
||||
message.success(t('common.delSuccess'))
|
||||
// 刷新列表
|
||||
await getList()
|
||||
} catch {}
|
||||
}
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
// 导出的二次确认
|
||||
await message.exportConfirm()
|
||||
// 发起导出
|
||||
exportLoading.value = true
|
||||
const data = await PostRequirementApi.exportPostRequirement(queryParams)
|
||||
download.excel(data, '任职条件.xls')
|
||||
} catch {
|
||||
} finally {
|
||||
exportLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 初始化 **/
|
||||
onMounted(() => {
|
||||
getList()
|
||||
})
|
||||
</script>
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
<template>
|
||||
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
label-width="100px"
|
||||
v-loading="formLoading"
|
||||
>
|
||||
<el-form-item label="岗位关联ID" prop="postId">
|
||||
<el-input v-model="formData.postId" placeholder="请输入岗位关联ID" />
|
||||
</el-form-item>
|
||||
<el-form-item label="职责" prop="responsibility">
|
||||
<el-input v-model="formData.responsibility" placeholder="请输入职责" />
|
||||
</el-form-item>
|
||||
<el-form-item label="任务" prop="task">
|
||||
<el-input v-model="formData.task" placeholder="请输入任务" />
|
||||
</el-form-item>
|
||||
<el-form-item label="时间分配" prop="timeAllocation">
|
||||
<el-input v-model="formData.timeAllocation" placeholder="请输入时间分配" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { PostResponsibilityApi, PostResponsibilityVO } from '@/api/system/postresponsibility'
|
||||
|
||||
/** 岗位职责 表单 */
|
||||
defineOptions({ name: 'PostResponsibilityForm' })
|
||||
|
||||
const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
|
||||
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||
const dialogTitle = ref('') // 弹窗的标题
|
||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||
const formData = ref({
|
||||
id: undefined,
|
||||
postId: undefined,
|
||||
responsibility: undefined,
|
||||
task: undefined,
|
||||
timeAllocation: undefined
|
||||
})
|
||||
const formRules = reactive({
|
||||
postId: [{ required: true, message: '岗位关联ID不能为空', trigger: 'blur' }],
|
||||
responsibility: [{ required: true, message: '职责不能为空', trigger: 'blur' }],
|
||||
task: [{ required: true, message: '任务不能为空', trigger: 'blur' }]
|
||||
})
|
||||
const formRef = ref() // 表单 Ref
|
||||
|
||||
/** 打开弹窗 */
|
||||
const open = async (type: string, id?: number) => {
|
||||
dialogVisible.value = true
|
||||
dialogTitle.value = t('action.' + type)
|
||||
formType.value = type
|
||||
resetForm()
|
||||
// 修改时,设置数据
|
||||
if (id) {
|
||||
formLoading.value = true
|
||||
try {
|
||||
formData.value = await PostResponsibilityApi.getPostResponsibility(id)
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||
|
||||
/** 提交表单 */
|
||||
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||
const submitForm = async () => {
|
||||
// 校验表单
|
||||
await formRef.value.validate()
|
||||
// 提交请求
|
||||
formLoading.value = true
|
||||
try {
|
||||
const data = formData.value as unknown as PostResponsibilityVO
|
||||
if (formType.value === 'create') {
|
||||
await PostResponsibilityApi.createPostResponsibility(data)
|
||||
message.success(t('common.createSuccess'))
|
||||
} else {
|
||||
await PostResponsibilityApi.updatePostResponsibility(data)
|
||||
message.success(t('common.updateSuccess'))
|
||||
}
|
||||
dialogVisible.value = false
|
||||
// 发送操作成功的事件
|
||||
emit('success')
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 重置表单 */
|
||||
const resetForm = () => {
|
||||
formData.value = {
|
||||
id: undefined,
|
||||
postId: undefined,
|
||||
responsibility: undefined,
|
||||
task: undefined,
|
||||
timeAllocation: undefined
|
||||
}
|
||||
formRef.value?.resetFields()
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,200 @@
|
|||
<template>
|
||||
<ContentWrap>
|
||||
<!-- 搜索工作栏 -->
|
||||
<el-form
|
||||
class="-mb-15px"
|
||||
:model="queryParams"
|
||||
ref="queryFormRef"
|
||||
:inline="true"
|
||||
label-width="68px"
|
||||
>
|
||||
<el-form-item label="岗位关联ID" prop="postId">
|
||||
<el-input
|
||||
v-model="queryParams.postId"
|
||||
placeholder="请输入岗位关联ID"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="职责" prop="responsibility">
|
||||
<el-input
|
||||
v-model="queryParams.responsibility"
|
||||
placeholder="请输入职责"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="任务" prop="task">
|
||||
<el-input
|
||||
v-model="queryParams.task"
|
||||
placeholder="请输入任务"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="时间分配" prop="timeAllocation">
|
||||
<el-input
|
||||
v-model="queryParams.timeAllocation"
|
||||
placeholder="请输入时间分配"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
@click="openForm('create')"
|
||||
v-hasPermi="['system:post-responsibility:create']"
|
||||
>
|
||||
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||
</el-button>
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
@click="handleExport"
|
||||
:loading="exportLoading"
|
||||
v-hasPermi="['system:post-responsibility:export']"
|
||||
>
|
||||
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 列表 -->
|
||||
<ContentWrap>
|
||||
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||
<el-table-column label="唯一主键" align="center" prop="id" />
|
||||
<el-table-column label="岗位关联ID" align="center" prop="postId" />
|
||||
<el-table-column label="职责" align="center" prop="responsibility" />
|
||||
<el-table-column label="任务" align="center" prop="task" />
|
||||
<el-table-column label="时间分配" align="center" prop="timeAllocation" />
|
||||
<el-table-column label="操作" align="center" min-width="120px">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
@click="openForm('update', scope.row.id)"
|
||||
v-hasPermi="['system:post-responsibility:update']"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row.id)"
|
||||
v-hasPermi="['system:post-responsibility:delete']"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 分页 -->
|
||||
<Pagination
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNo"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 表单弹窗:添加/修改 -->
|
||||
<PostResponsibilityForm ref="formRef" @success="getList" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import download from '@/utils/download'
|
||||
import { PostResponsibilityApi, PostResponsibilityVO } from '@/api/system/postresponsibility'
|
||||
import PostResponsibilityForm from './PostResponsibilityForm.vue'
|
||||
|
||||
/** 岗位职责 列表 */
|
||||
defineOptions({ name: 'PostResponsibility' })
|
||||
|
||||
const message = useMessage() // 消息弹窗
|
||||
const { t } = useI18n() // 国际化
|
||||
|
||||
const loading = ref(true) // 列表的加载中
|
||||
const list = ref<PostResponsibilityVO[]>([]) // 列表的数据
|
||||
const total = ref(0) // 列表的总页数
|
||||
const queryParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
postId: undefined,
|
||||
responsibility: undefined,
|
||||
task: undefined,
|
||||
timeAllocation: undefined
|
||||
})
|
||||
const queryFormRef = ref() // 搜索的表单
|
||||
const exportLoading = ref(false) // 导出的加载中
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const data = await PostResponsibilityApi.getPostResponsibilityPage(queryParams)
|
||||
list.value = data.list
|
||||
total.value = data.total
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNo = 1
|
||||
getList()
|
||||
}
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value.resetFields()
|
||||
handleQuery()
|
||||
}
|
||||
|
||||
/** 添加/修改操作 */
|
||||
const formRef = ref()
|
||||
const openForm = (type: string, id?: number) => {
|
||||
formRef.value.open(type, id)
|
||||
}
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (id: number) => {
|
||||
try {
|
||||
// 删除的二次确认
|
||||
await message.delConfirm()
|
||||
// 发起删除
|
||||
await PostResponsibilityApi.deletePostResponsibility(id)
|
||||
message.success(t('common.delSuccess'))
|
||||
// 刷新列表
|
||||
await getList()
|
||||
} catch {}
|
||||
}
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
// 导出的二次确认
|
||||
await message.exportConfirm()
|
||||
// 发起导出
|
||||
exportLoading.value = true
|
||||
const data = await PostResponsibilityApi.exportPostResponsibility(queryParams)
|
||||
download.excel(data, '岗位职责.xls')
|
||||
} catch {
|
||||
} finally {
|
||||
exportLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 初始化 **/
|
||||
onMounted(() => {
|
||||
getList()
|
||||
})
|
||||
</script>
|
||||
Loading…
Reference in New Issue