修复稳定化:接入考勤人工调整闭环并增加住宿与门禁历史删除防护

This commit is contained in:
wangzhibiao committed 2026-09-20 14:09:45 +08:00
1 parent 5bcb6273ef
commit b1433dcaa1
7 files changed
+491 -9

No files matched your search

+106 -2
View File
@@ -33,7 +33,7 @@
</el-col>
<right-toolbar :show-search.sync="showSearch" @queryTable="getList" />
</el-row>
<el-alert title="考勤由课次签到、签退或留痕的人工修正流程生成,本页面仅供查询。" type="info" :closable="false" show-icon class="mb8" />
<el-alert title="考勤由课次签到、签退生成;具备管理权限时,可对异常或争议记录执行全留痕人工修正。" type="info" :closable="false" show-icon class="mb8" />
<el-table v-loading="loading" :data="rows">
<el-table-column label="培训计划" prop="planName" min-width="150" show-overflow-tooltip />
<el-table-column label="课程" prop="courseName" min-width="140" show-overflow-tooltip />
@@ -52,6 +52,20 @@
<el-table-column label="人工修正" align="center" width="90">
<template slot-scope="scope">{{ scope.row.manualFlag === 1 ? "是" : "否" }}</template>
</el-table-column>
<el-table-column label="备注/调整说明" prop="remark" min-width="150" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.remark || "-" }}</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="100">
<template slot-scope="scope">
<el-button
v-hasPermi="['train:attendance:edit']"
size="mini"
type="text"
icon="el-icon-edit"
@click="handleAdjust(scope.row)"
>调整</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
@@ -60,11 +74,49 @@
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 人工调整考勤对话框 (UC-19 / P0) -->
<el-dialog title="人工调整考勤 (Attendance Adjustment)" :visible.sync="adjustOpen" width="520px" append-to-body>
<el-form ref="adjustForm" :model="adjustForm" :rules="adjustRules" label-width="100px">
<el-form-item label="学员姓名">
<span>{{ currentRecord.studentName || '-' }}</span>
</el-form-item>
<el-form-item label="培训计划">
<span>{{ currentRecord.planName || '-' }}</span>
</el-form-item>
<el-form-item label="课程名称">
<span>{{ currentRecord.courseName || '-' }}</span>
</el-form-item>
<el-form-item label="当前状态">
<el-tag size="small">{{ labelOf(attendanceStatuses, currentRecord.attendanceStatus) }}</el-tag>
</el-form-item>
<el-form-item label="目标状态" prop="attendanceStatus">
<el-select v-model="adjustForm.attendanceStatus" placeholder="请选择调整后的考勤状态" style="width: 100%;">
<el-option v-for="item in attendanceStatuses" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="调整原因" prop="remark">
<el-input
v-model="adjustForm.remark"
type="textarea"
:rows="3"
placeholder="请输入人工调整原因或核验说明(如:班牌漏刷补录、事假证明核销,将全留痕记入审计流水)"
maxlength="200"
show-word-limit
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" :loading="adjustSubmitting" @click="submitAdjust">确 定</el-button>
<el-button @click="cancelAdjust">取 消</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listCheckin } from '@/api/train/checkin'
import { adjustAttendance } from '@/api/train/attendance'
export default {
name: 'Checkin',
@@ -82,7 +134,20 @@ export default {
{ value: 0, label: '缺勤' }, { value: 1, label: '正常' },
{ value: 2, label: '迟到' }, { value: 3, label: '早退' }, { value: 4, label: '请假' }
],
queryParams: { pageNum: 1, pageSize: 10, planName: null, studentName: null, courseName: null, attendanceStatus: null }
queryParams: { pageNum: 1, pageSize: 10, planName: null, studentName: null, courseName: null, attendanceStatus: null },
adjustOpen: false,
adjustSubmitting: false,
currentRecord: {},
adjustForm: {
checkinId: null,
attendanceStatus: null,
remark: ''
},
adjustRules: {
attendanceStatus: [
{ required: true, message: '请选择调整后的考勤状态', trigger: 'change' }
]
}
}
},
created() { this.getList() },
@@ -102,6 +167,45 @@ export default {
resetQuery() { this.resetForm('queryForm'); this.handleQuery() },
handleExport() {
this.download('train/checkin/export', { ...this.queryParams }, `checkin_${new Date().getTime()}.xlsx`)
},
handleAdjust(row) {
this.currentRecord = row
this.adjustForm = {
checkinId: row.checkinId,
attendanceStatus: row.attendanceStatus,
remark: row.remark || ''
}
this.adjustOpen = true
this.$nextTick(() => {
if (this.$refs.adjustForm) {
this.$refs.adjustForm.clearValidate()
}
})
},
cancelAdjust() {
this.adjustOpen = false
this.currentRecord = {}
this.adjustForm = {
checkinId: null,
attendanceStatus: null,
remark: ''
}
},
submitAdjust() {
this.$refs.adjustForm.validate(valid => {
if (!valid) return
this.adjustSubmitting = true
adjustAttendance(this.adjustForm.checkinId, {
attendanceStatus: this.adjustForm.attendanceStatus,
remark: this.adjustForm.remark
}).then(() => {
this.$modal.msgSuccess('考勤调整成功并已记录审计留痕')
this.adjustOpen = false
this.getList()
}).finally(() => {
this.adjustSubmitting = false
})
})
}
}
}