<template>
|
<div class="app-container">
|
<!-- 页面标题和操作按钮 -->
|
<div class="page-header">
|
<div class="title">打卡规则配置</div>
|
<div class="actions">
|
<el-button type="primary"
|
@click="openForm('add')">
|
<el-icon>
|
<Plus />
|
</el-icon>
|
新增规则
|
</el-button>
|
</div>
|
</div>
|
<!-- 查询条件 -->
|
<!-- <el-form :model="searchForm"
|
:inline="true"
|
class="search-form mb16">
|
<el-form-item label="部门:"
|
prop="countId">
|
<el-tree-select v-model="searchForm.countId"
|
:data="deptOptions"
|
:props="{ value: 'id', label: 'label', children: 'children' }"
|
value-key="id"
|
placeholder="请选择部门"
|
check-strictly
|
style="width: 200px" />
|
</el-form-item>
|
<el-form-item label="地点:"
|
prop="locationName">
|
<el-input v-model="searchForm.locationName"
|
placeholder="请输入地点名称"
|
clearable
|
style="width: 200px" />
|
</el-form-item>
|
<el-form-item>
|
<el-button type="primary"
|
@click="fetchData">
|
<el-icon>
|
<Search />
|
</el-icon>
|
搜索
|
</el-button>
|
<el-button @click="resetSearch">
|
<el-icon>
|
<Refresh />
|
</el-icon>
|
重置
|
</el-button>
|
</el-form-item>
|
</el-form> -->
|
<!-- 规则列表 -->
|
<el-card shadow="never"
|
class="mb16">
|
<el-table :data="tableData"
|
border
|
v-loading="tableLoading"
|
style="width: 100%"
|
row-key="id">
|
<el-table-column type="index"
|
label="序号"
|
width="60"
|
align="center" />
|
<el-table-column label="部门">
|
<template #default="scope">
|
{{ getDeptNameById(scope.row.sysDeptId) }}
|
</template>
|
</el-table-column>
|
<el-table-column prop="locationName"
|
label="地点名称" />
|
<el-table-column prop="longitude"
|
label="经度" />
|
<el-table-column prop="latitude"
|
label="纬度" />
|
<el-table-column prop="radius"
|
label="打卡范围(m)" />
|
<el-table-column prop="startAt"
|
label="上班时间">
|
<template #default="scope">
|
{{ scope.row.startAt }}
|
</template>
|
</el-table-column>
|
<el-table-column prop="endAt"
|
label="下班时间">
|
<template #default="scope">
|
{{ scope.row.endAt }}
|
</template>
|
</el-table-column>
|
<el-table-column label="操作"
|
width="180"
|
fixed="right"
|
align="center">
|
<template #default="scope">
|
<el-button type="primary"
|
size="small"
|
link
|
@click="openForm('edit', scope.row)">编辑</el-button>
|
<el-button type="danger"
|
size="small"
|
link
|
@click="handleDelete(scope.row.id)">删除</el-button>
|
</template>
|
</el-table-column>
|
</el-table>
|
<pagination :total="page.total"
|
layout="total, sizes, prev, pager, next, jumper"
|
:page="page.current"
|
:limit="page.size"
|
@pagination="paginationChange"
|
class="mt10" />
|
</el-card>
|
<!-- 新增/编辑规则弹窗 -->
|
<rule-form ref="ruleFormRef"
|
v-model="dialogVisible"
|
:operation-type="operationType"
|
:row="currentRow"
|
@close="dialogVisible = false; fetchData()" />
|
</div>
|
</template>
|
|
<script setup>
|
import { ref, reactive, onMounted } from "vue";
|
import { ElMessage, ElMessageBox } from "element-plus";
|
import { Plus, Edit, Delete, Search, Refresh } from "@element-plus/icons-vue";
|
import Pagination from "@/components/Pagination/index.vue";
|
import RuleForm from "./components/form.vue";
|
import { deptTreeSelect } from "@/api/system/user.js";
|
import {
|
getAttendanceRules,
|
deleteAttendanceRule,
|
} from "@/api/personnelManagement/attendanceRules.js";
|
|
const { proxy } = getCurrentInstance();
|
|
// 表格数据
|
const tableData = ref([]);
|
const tableLoading = ref(false);
|
|
// 分页参数
|
const page = reactive({
|
current: 1,
|
size: 10,
|
total: 0,
|
});
|
|
// 查询表单
|
const searchForm = reactive({
|
countId: "",
|
locationName: "",
|
});
|
|
// 部门选项
|
const deptOptions = ref([]);
|
|
// 弹窗控制
|
const dialogVisible = ref(false);
|
const operationType = ref("add");
|
const currentRow = ref({});
|
const ruleFormRef = ref();
|
|
// 格式化时间
|
const formatTime = timestamp => {
|
if (!timestamp) return "";
|
const date = new Date(timestamp);
|
return `${String(date.getHours()).padStart(2, "0")}:${String(
|
date.getMinutes()
|
).padStart(2, "0")}`;
|
};
|
|
// 获取部门列表
|
const fetchDeptOptions = () => {
|
deptTreeSelect().then(response => {
|
deptOptions.value = filterDisabledDept(
|
JSON.parse(JSON.stringify(response.data))
|
);
|
});
|
};
|
|
// 过滤禁用的部门
|
const filterDisabledDept = deptList => {
|
return deptList.filter(dept => {
|
if (dept.disabled) {
|
return false;
|
}
|
if (dept.children && dept.children.length) {
|
dept.children = filterDisabledDept(dept.children);
|
}
|
return true;
|
});
|
};
|
|
// 根据部门ID查找部门名称
|
const getDeptNameById = (deptId, deptList = deptOptions.value) => {
|
for (const dept of deptList) {
|
if (dept.id === deptId) {
|
return dept.label;
|
}
|
if (dept.children && dept.children.length) {
|
const name = getDeptNameById(deptId, dept.children);
|
if (name) {
|
return name;
|
}
|
}
|
}
|
return "";
|
};
|
|
// 查询规则列表
|
const fetchData = () => {
|
tableLoading.value = true;
|
getAttendanceRules({ ...page, ...searchForm })
|
.then(res => {
|
tableData.value = res.data.records;
|
page.total = res.data.total;
|
})
|
.finally(() => {
|
tableLoading.value = false;
|
});
|
};
|
|
// 分页变更
|
const paginationChange = pagination => {
|
page.current = pagination.page;
|
page.size = pagination.limit;
|
fetchData();
|
};
|
|
// 重置搜索
|
const resetSearch = () => {
|
searchForm.countId = "";
|
searchForm.locationName = "";
|
fetchData();
|
};
|
|
// 打开表单
|
const openForm = (type, row = {}) => {
|
operationType.value = type;
|
currentRow.value = row;
|
dialogVisible.value = true;
|
};
|
|
// 删除规则
|
const handleDelete = id => {
|
ElMessageBox.confirm("确定要删除这条规则吗?", "删除确认", {
|
confirmButtonText: "确定",
|
cancelButtonText: "取消",
|
type: "warning",
|
})
|
.then(() => {
|
deleteAttendanceRule([id]).then(() => {
|
ElMessage.success("删除成功");
|
fetchData();
|
});
|
})
|
.catch(() => {
|
// 取消删除
|
});
|
};
|
|
// 初始化
|
onMounted(() => {
|
fetchDeptOptions();
|
fetchData();
|
});
|
</script>
|
|
<style scoped lang="scss">
|
.page-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
margin-bottom: 20px;
|
|
.title {
|
font-size: 18px;
|
font-weight: 600;
|
}
|
|
.actions {
|
display: flex;
|
gap: 10px;
|
}
|
}
|
|
.mb16 {
|
margin-bottom: 16px;
|
}
|
|
.mt10 {
|
margin-top: 10px;
|
}
|
</style>
|