Parcourir la source

1.考勤添加午休设置

master
wangqiang il y a 2 jours
Parent
révision
1911110ee2
1 fichiers modifiés avec 200 ajouts et 90 suppressions
  1. 200
    90
      src/views/oa/attendance/groups/index.vue

+ 200
- 90
src/views/oa/attendance/groups/index.vue Voir le fichier

@@ -10,39 +10,7 @@
@click="handleAdd"
>新增</el-button>
</el-col>
<!-- <el-col :span="1.5">
<el-button
v-hasPermi="['demo:leave:edit']"
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-hasPermi="['demo:leave:remove']"
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-hasPermi="['demo:leave:export']"
type="warning"
plain
icon="el-icon-download"
size="mini"
:loading="exportLoading"
@click="handleExport"
>导出</el-button>
</el-col> -->

<right-toolbar :show-search.sync="showSearch" @queryTable="getList" />
</el-row>

@@ -76,18 +44,18 @@
<el-form-item label="考勤组名称" prop="name">
<el-input v-model="attendanceGroup.name" placeholder="请输入考勤组名称"></el-input>
</el-form-item>
<el-form-item label="描述" prop="description">
<el-input v-model="attendanceGroup.description" placeholder="请输入描述信息"></el-input>
</el-form-item>
<!-- 考勤时间设置 -->
<el-form-item label="工作日设置">
<el-checkbox-group v-model="attendanceGroup.workDays">
<el-checkbox v-for="day in workDays" :key="day.value" :label="day.value">{{ day.label }}</el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="上班时间" prop="workStartTime">
<el-time-picker
v-model="attendanceGroup.workStartTime"
@@ -96,7 +64,7 @@
placeholder="选择上班时间"
></el-time-picker>
</el-form-item>
<el-form-item label="迟到浮动" prop="lateRange">
<el-col :span="12">
<el-switch
@@ -118,7 +86,7 @@
<div class="slider-value">{{ attendanceGroup.lateRange }}分钟</div>
</el-col>
</el-form-item>
<el-form-item label="下班时间" prop="workEndTime">
<el-time-picker
v-model="attendanceGroup.workEndTime"
@@ -127,7 +95,39 @@
placeholder="选择下班时间"
></el-time-picker>
</el-form-item>

<!-- 午休时间设置 -->
<el-form-item label="午休开始时间" prop="lunchStartTime">
<el-time-picker
v-model="attendanceGroup.lunchStartTime"
format="HH:mm"
value-format="HH:mm"
placeholder="选择午休开始时间"
@change="calculateLunchHours"
></el-time-picker>
</el-form-item>

<el-form-item label="午休结束时间" prop="lunchEndTime">
<el-time-picker
v-model="attendanceGroup.lunchEndTime"
format="HH:mm"
value-format="HH:mm"
placeholder="选择午休结束时间"
@change="calculateLunchHours"
></el-time-picker>
</el-form-item>

<el-form-item label="午休时间" prop="lunchHours">
<el-input
v-model="lunchHoursDisplay"
placeholder="午休时间(小时)"
readonly
style="width: 200px"
>
<template slot="append">小时</template>
</el-input>
</el-form-item>

<el-form-item label="早退浮动" prop="earlyRange">
<el-col :span="12">
<el-switch
@@ -149,7 +149,7 @@
<div class="slider-value">{{ attendanceGroup.earlyRange }}分钟</div>
</el-col>
</el-form-item>
<!-- 打卡配置 -->
<el-form-item label="打卡区域" prop="areaId">
<el-select
@@ -164,7 +164,7 @@
></el-option>
</el-select>
</el-form-item>
<!-- 关联员工 -->
<el-form-item label="关联员工">
<el-button
@@ -174,7 +174,7 @@
>
<i class="el-icon-plus"></i> 选择员工
</el-button>
<el-table
:data="attendanceGroup.members"
style="width: 100%; margin-top: 20px"
@@ -294,12 +294,6 @@ export default {
form: {},
// 结果
warnResult: '',
// 表单校验
rules: {
snapshotUrl: [
{ required: true, message: '图片快照不能为空', trigger: 'blur' }
]
},
daka_check_in_status: [{label: '正常', value: '0'},{label: '迟到', value: '1'},{label: '缺卡', value: '2'}],
// 地图相关
map: null,
@@ -307,7 +301,7 @@ export default {
circle: null,
mapHeight: '400px',
baiduMapKey: '你的百度地图API Key', // 替换为你的API Key
// 表单数据
formData: {
id: null,
@@ -317,10 +311,10 @@ export default {
radius: 500, // 默认半径500米
enabled: false
},
// 区域列表
areaList: [],
// 模态框状态
showDeleteModal: false,
currentDeletingArea: null,
@@ -336,6 +330,9 @@ export default {
workDays: ['mon', 'tue', 'wed', 'thu', 'fri'],
workStartTime: '09:00',
workEndTime: '18:00',
lunchStartTime: '12:00',
lunchEndTime: '13:00',
lunchHours: 1,
allowLate: false,
lateRange: 15,
allowEarly: false,
@@ -352,6 +349,9 @@ export default {
workDays: ['mon', 'tue', 'wed', 'thu', 'fri'],
workStartTime: '09:00',
workEndTime: '18:00',
lunchStartTime: '12:00',
lunchEndTime: '13:00',
lunchHours: 1,
allowLate: false,
lateRange: 15,
allowEarly: false,
@@ -402,6 +402,12 @@ export default {
workEndTime: [
{ required: true, message: '请选择下班时间', trigger: 'change' }
],
lunchStartTime: [
{ required: true, message: '请选择午休开始时间', trigger: 'change' }
],
lunchEndTime: [
{ required: true, message: '请选择午休结束时间', trigger: 'change' }
],
areaId: [
{ required: true, message: '请选择打卡区域', trigger: 'change' }
]
@@ -428,20 +434,41 @@ export default {
filteredUsers() {
// 获取不在当前考勤组中的用户
const groupMemberIds = this.attendanceGroup.members.map(member => member.id);
const availableUsers = this.users.filter(user =>
const availableUsers = this.users.filter(user =>
!groupMemberIds.includes(user.id)
);
// 应用搜索过滤
if (!this.userSearchKeyword) return availableUsers;
const keyword = this.userSearchKeyword.toLowerCase();
return availableUsers.filter(user =>
user.name.toLowerCase().includes(keyword) ||
return availableUsers.filter(user =>
user.name.toLowerCase().includes(keyword) ||
user.employeeId.toLowerCase().includes(keyword) ||
user.department.toLowerCase().includes(keyword) ||
user.position.toLowerCase().includes(keyword)
);
},
// 午休时间显示
lunchHoursDisplay() {
// 实时计算午休时间
if (!this.attendanceGroup.lunchStartTime || !this.attendanceGroup.lunchEndTime) {
return '0';
}

const startTime = this.parseTimeToMinutes(this.attendanceGroup.lunchStartTime);
const endTime = this.parseTimeToMinutes(this.attendanceGroup.lunchEndTime);

if (endTime <= startTime) {
return '0';
}

const diffMinutes = endTime - startTime;
const hours = diffMinutes / 60;

// 以0.5为基准进行向下取整计算
const result = Math.floor(hours * 2) / 2;
return result.toString();
}
},
mounted() {
@@ -453,7 +480,65 @@ export default {
// 加载打卡区域数据(实际项目中从API获取)
this.loadCheckInAreas();
},
watch: {
// 监听午休时间变化,自动计算午休小时数
'attendanceGroup.lunchStartTime': {
handler: function(newVal, oldVal) {
console.log('午休开始时间变化:', newVal);
if (newVal && this.attendanceGroup.lunchEndTime) {
this.$nextTick(() => {
this.calculateLunchHours();
});
}
},
immediate: true
},
'attendanceGroup.lunchEndTime': {
handler: function(newVal, oldVal) {
console.log('午休结束时间变化:', newVal);
if (newVal && this.attendanceGroup.lunchStartTime) {
this.$nextTick(() => {
this.calculateLunchHours();
});
}
},
immediate: true
}
},
methods: {
// 解析时间字符串为分钟数
parseTimeToMinutes(timeStr) {
if (!timeStr) return 0;
const [hours, minutes] = timeStr.split(':').map(Number);
return hours * 60 + minutes;
},

// 计算午休时间
calculateLunchHours() {
if (!this.attendanceGroup.lunchStartTime || !this.attendanceGroup.lunchEndTime) {
this.attendanceGroup.lunchHours = 0;
return;
}

const startTime = this.parseTimeToMinutes(this.attendanceGroup.lunchStartTime);
const endTime = this.parseTimeToMinutes(this.attendanceGroup.lunchEndTime);

if (endTime <= startTime) {
this.attendanceGroup.lunchHours = 0;
return;
}

const diffMinutes = endTime - startTime;
const hours = diffMinutes / 60;

// 以0.5为基准进行向下取整计算
// 例如:0.7按0.5算,1.7按1.5算
this.attendanceGroup.lunchHours = Math.floor(hours * 2) / 2;

// 调试输出
console.log(`午休时间计算: ${this.attendanceGroup.lunchStartTime} - ${this.attendanceGroup.lunchEndTime} = ${hours}小时,计算结果: ${this.attendanceGroup.lunchHours}小时`);
},

test(){
test({userId:1}).then((res) => {
console.log(res)
@@ -463,7 +548,9 @@ export default {
/** 新增按钮操作 */
handleAdd() {
// this.reset()
this.attendanceGroup = this.attendanceGroupModel
this.attendanceGroup = { ...this.attendanceGroupModel }
// 确保午休时间正确初始化
this.calculateLunchHours();
this.open = true
},

@@ -480,7 +567,21 @@ export default {
this.open = true
// 复制对象,避免直接修改原始数据
this.attendanceGroup = { ...area };

// 确保午休时间字段存在
if (!this.attendanceGroup.lunchStartTime) {
this.attendanceGroup.lunchStartTime = '12:00';
}
if (!this.attendanceGroup.lunchEndTime) {
this.attendanceGroup.lunchEndTime = '13:00';
}
if (this.attendanceGroup.lunchHours === undefined) {
this.attendanceGroup.lunchHours = 1;
}

// 重新计算午休时间
this.calculateLunchHours();

this.selectGroup(area.id)

},
@@ -532,6 +633,9 @@ export default {
console.log(this.attendanceGroup)
this.$refs.groupForm.validate(valid => {
if (valid) {
// 计算午休时间
this.calculateLunchHours();

// 实际项目中调用API创建
const newGroup = {
id: this.attendanceGroup.id,
@@ -540,6 +644,9 @@ export default {
workDays: this.attendanceGroup.workDays,
workStartTime: this.attendanceGroup.workStartTime,
workEndTime: this.attendanceGroup.workEndTime,
lunchStartTime: this.attendanceGroup.lunchStartTime,
lunchEndTime: this.attendanceGroup.lunchEndTime,
lunchHours: this.attendanceGroup.lunchHours,
allowLate: this.attendanceGroup.allowLate,
lateRange: this.attendanceGroup.lateRange,
allowEarly: this.attendanceGroup.allowEarly,
@@ -605,7 +712,7 @@ export default {
this.$message.warning('请选择员工');
return;
}
// 添加选中的员工到考勤组
// const map = new Map();
// [...this.attendanceGroup.members, ...this.selectedUsers].forEach(item => map.set(item.id, item));
@@ -661,7 +768,7 @@ export default {
// ]
// }
// ];
// 模拟员工数据
// this.users = [
// { id: 1, name: '张三', employeeId: 'EMP001', department: '研发部', position: '高级工程师' },
@@ -683,7 +790,7 @@ export default {
// console.log(this.attendanceGroups)
})
},
// 加载打卡区域数据(实际项目中从API获取)
loadCheckInAreas() {
// this.checkInAreas = [
@@ -696,7 +803,7 @@ export default {
this.checkInAreas = res
})
},
// 重置表单
resetForm() {
this.attendanceGroup = {
@@ -706,6 +813,9 @@ export default {
workDays: ['mon', 'tue', 'wed', 'thu', 'fri'],
workStartTime: '09:00',
workEndTime: '18:00',
lunchStartTime: '12:00',
lunchEndTime: '13:00',
lunchHours: 1,
allowLate: true,
lateRange: 15,
allowEarly: true,
@@ -715,20 +825,20 @@ export default {
members: [],
areaName: ''
};
this.isEditMode = false;
this.selectedGroupId = null;
},
// 打开新建考勤组对话框
openAddGroupDialog() {
this.resetForm();
this.showAddGroupModal = true;
},




// 保存考勤组
saveGroup() {
this.$refs.groupForm.validate(valid => {
@@ -738,7 +848,7 @@ export default {
if (area) {
this.attendanceGroup.areaName = area.name;
}
if (this.isEditMode) {
// 更新现有考勤组
const index = this.attendanceGroups.findIndex(g => g.id === this.attendanceGroup.id);
@@ -756,7 +866,7 @@ export default {
add(newGroup).then((res) => {
// console.log(res)
})
// 重置表单
// this.resetForm();
} else {
@@ -765,7 +875,7 @@ export default {
}
});
},
// 取消编辑
cancelEdit() {
if (this.isEditMode && this.selectedGroupId) {
@@ -777,26 +887,26 @@ export default {
this.resetForm();
}
},
// 搜索用户
searchUsers() {
// 搜索逻辑已在computed属性中实现
},
// 处理迟到开关变化
handleLateChange(value) {
if (!value) {
this.attendanceGroup.lateRange = 0;
}
},
// 处理早退开关变化
handleEarlyChange(value) {
if (!value) {
this.attendanceGroup.earlyRange = 0;
}
},
// 验证迟到浮动范围
validateLateRange(value) {
if (value > 30) {
@@ -804,12 +914,12 @@ export default {
this.$message.warning('迟到浮动范围最大为30分钟');
}
},
// 显示成功消息
showSuccessMessage(message) {
this.successMessage = message;
this.successMessageVisible = true;
// 3秒后自动关闭
setTimeout(() => {
this.successMessageVisible = false;
@@ -840,11 +950,11 @@ export default {
}
});
},
// 保存区域
saveArea() {
if (!this.isFormValid) return;
const newArea = {
id: this.formData.id || Date.now(), // 如果是新建,使用时间戳作为ID
name: this.formData.name.trim(),
@@ -853,7 +963,7 @@ export default {
radius: this.formData.radius,
enabled: this.formData.enabled
};
if (this.formData.id) {
// 更新现有区域
const index = this.areaList.findIndex(area => area.id === this.formData.id);
@@ -872,7 +982,7 @@ export default {
})
// 重置表单
this.clearMapSelection();
},

// 选择考勤组
@@ -885,7 +995,7 @@ export default {
this.isEditMode = true;
}
},
// 切换区域状态
toggleAreaStatus(area) {
if (area.enableStatus == '0') {
@@ -893,7 +1003,7 @@ export default {
alert('已启用的区域不允许禁用');
return;
}
// 启用区域
const index = this.areaList.findIndex(a => a.id === area.id);
if (index !== -1) {
@@ -905,20 +1015,20 @@ export default {
// console.log(res)
})
},
// 确认删除区域
confirmDeleteArea() {
if (!this.currentDeletingArea) return;
this.areaList = this.areaList.filter(
area => area.id !== this.currentDeletingArea.id
);
// console.log(this.currentDeletingArea)
deleteConfig(this.currentDeletingArea.id).then((res)=> {
// console.log(res)
})
this.currentDeletingArea = null;
this.showDeleteModal = false;
}
@@ -1073,7 +1183,7 @@ export default {
.main-content {
flex-direction: column;
}
.group-list-card, .group-form-card {
width: 100%;
}
@@ -1452,7 +1562,7 @@ export default {
.content-wrapper {
flex-direction: column;
}
.area-list,
.map-section {
min-width: auto;
@@ -1463,13 +1573,13 @@ export default {
.control-group {
min-width: 100%;
}
.area-table th,
.area-table td {
padding: 8px 5px;
font-size: 14px;
}
.btn-edit,
.btn-status,
.btn-delete {

Chargement…
Annuler
Enregistrer