| | |
| | | </el-button> |
| | | </div> |
| | | </div> |
| | | <!-- 查询条件 --> |
| | | <!-- <el-form :model="searchForm" |
| | | <el-form :model="searchForm" |
| | | :inline="true" |
| | | class="search-form mb16"> |
| | | <el-form-item label="部门:" |
| | | prop="countId"> |
| | | <el-tree-select v-model="searchForm.countId" |
| | | prop="sysDeptId"> |
| | | <el-tree-select v-model="searchForm.sysDeptId" |
| | | :data="deptOptions" |
| | | :props="{ value: 'id', label: 'label', children: 'children' }" |
| | | value-key="id" |
| | | placeholder="请选择部门" |
| | | check-strictly |
| | | clearable |
| | | 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 label="班次:" |
| | | prop="shift"> |
| | | <el-select v-model="searchForm.shift" |
| | | placeholder="请选择班次" |
| | | clearable |
| | | style="width: 200px"> |
| | | <el-option |
| | | v-for="item in shifts_list" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" |
| | | @click="fetchData"> |
| | | @click="handleSearch"> |
| | | <el-icon> |
| | | <Search /> |
| | | </el-icon> |
| | |
| | | 重置 |
| | | </el-button> |
| | | </el-form-item> |
| | | </el-form> --> |
| | | </el-form> |
| | | <!-- 班次列表 --> |
| | | <el-card shadow="never" |
| | | class="mb16"> |
| | | <el-table :data="tableData" |
| | | border |
| | | v-loading="tableLoading" |
| | | height="calc(100vh - 18.5em)" |
| | | style="width: 100%" |
| | | row-key="id"> |
| | | <el-table-column type="index" |
| | |
| | | {{ getDeptNameById(scope.row.sysDeptId) }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="班次"> |
| | | <template #default="scope"> |
| | | {{ getShiftNameByValue(scope.row.shift) }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="locationName" |
| | | label="地点名称" /> |
| | | label="地点名称"> |
| | | <template #default="scope"> |
| | | {{ scope.row.locationName || "-" }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="longitude" |
| | | label="经度" /> |
| | | label="经度"> |
| | | <template #default="scope"> |
| | | {{ scope.row.longitude ?? "-" }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="latitude" |
| | | label="纬度" /> |
| | | label="纬度"> |
| | | <template #default="scope"> |
| | | {{ scope.row.latitude ?? "-" }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="radius" |
| | | label="打卡范围(m)" /> |
| | | label="打卡范围(m)"> |
| | | <template #default="scope"> |
| | | {{ scope.row.radius ?? "-" }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="startAt" |
| | | label="上班时间"> |
| | | <template #default="scope"> |
| | | {{ scope.row.startAt }} |
| | | {{ scope.row.startAt || "-" }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="endAt" |
| | | label="下班时间"> |
| | | <template #default="scope"> |
| | | {{ scope.row.endAt }} |
| | | {{ scope.row.endAt || "-" }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" |
| | |
| | | align="center"> |
| | | <template #default="scope"> |
| | | <el-button type="primary" |
| | | size="small" |
| | | link |
| | | :disabled="isRuleLocked(scope.row)" |
| | | @click="openForm('edit', scope.row)">编辑</el-button> |
| | | <el-button type="danger" |
| | | size="small" |
| | | link |
| | | :disabled="isRuleLocked(scope.row)" |
| | | @click="handleDelete(scope.row.id)">删除</el-button> |
| | | </template> |
| | | </el-table-column> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, onMounted } from "vue"; |
| | | import { ref, reactive, onMounted, getCurrentInstance } from "vue"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | import { Plus, Edit, Delete, Search, Refresh } from "@element-plus/icons-vue"; |
| | | import { |
| | | Plus, |
| | | Edit, |
| | | Delete, |
| | | Search, |
| | | Refresh, |
| | | ArrowLeft, |
| | | } 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"; |
| | |
| | | getAttendanceRules, |
| | | deleteAttendanceRule, |
| | | } from "@/api/personnelManagement/attendanceRules.js"; |
| | | import { useDict } from "@/utils/dict"; |
| | | |
| | | const { proxy } = getCurrentInstance(); |
| | | |
| | |
| | | |
| | | // 查询表单 |
| | | const searchForm = reactive({ |
| | | countId: "", |
| | | locationName: "", |
| | | sysDeptId: "", |
| | | shift: "", |
| | | }); |
| | | |
| | | // 部门选项 |
| | | const deptOptions = ref([]); |
| | | // 获取班次字典值 |
| | | const { shifts_list } = useDict("shifts_list"); |
| | | |
| | | // 弹窗控制 |
| | | const dialogVisible = ref(false); |
| | |
| | | return `${String(date.getHours()).padStart(2, "0")}:${String( |
| | | date.getMinutes() |
| | | ).padStart(2, "0")}`; |
| | | }; |
| | | |
| | | // 根据班次值获取班次名称 |
| | | const getShiftNameByValue = value => { |
| | | if (!value) return ""; |
| | | const shift = shifts_list.value.find(item => item.value === value); |
| | | return shift ? shift.label : value; |
| | | }; |
| | | |
| | | const isRuleLocked = row => { |
| | | return Boolean(row?.usageLocked || row?.canEdit === false || row?.canDelete === false); |
| | | }; |
| | | |
| | | // 获取部门列表 |
| | |
| | | tableLoading.value = true; |
| | | getAttendanceRules({ ...page, ...searchForm }) |
| | | .then(res => { |
| | | tableData.value = res.data.records; |
| | | const records = Array.isArray(res?.data?.records) ? res.data.records : []; |
| | | tableData.value = records.filter(r => String(r?.id) !== "999"); |
| | | page.total = res.data.total; |
| | | }) |
| | | .finally(() => { |
| | | tableLoading.value = false; |
| | | }); |
| | | }; |
| | | |
| | | const handleSearch = () => { |
| | | page.current = 1; |
| | | fetchData(); |
| | | }; |
| | | |
| | | // 分页变更 |
| | |
| | | |
| | | // 重置搜索 |
| | | const resetSearch = () => { |
| | | searchForm.countId = ""; |
| | | searchForm.locationName = ""; |
| | | searchForm.sysDeptId = ""; |
| | | searchForm.shift = ""; |
| | | page.current = 1; |
| | | fetchData(); |
| | | }; |
| | | |
| | | // 打开表单 |
| | | const openForm = (type, row = {}) => { |
| | | if (type === "edit" && isRuleLocked(row)) { |
| | | ElMessage.warning("该班次配置已被排班并产生打卡记录,不能编辑"); |
| | | return; |
| | | } |
| | | operationType.value = type; |
| | | currentRow.value = row; |
| | | dialogVisible.value = true; |
| | |
| | | |
| | | // 删除班次 |
| | | const handleDelete = id => { |
| | | const row = tableData.value.find(item => String(item.id) === String(id)); |
| | | if (isRuleLocked(row)) { |
| | | ElMessage.warning("存在已排班且已有打卡记录的班次配置,不能删除"); |
| | | return; |
| | | } |
| | | ElMessageBox.confirm("确定要删除这条班次吗?", "删除确认", { |
| | | confirmButtonText: "确定", |
| | | cancelButtonText: "取消", |
| | |
| | | .mt10 { |
| | | margin-top: 10px; |
| | | } |
| | | </style> |
| | | </style> |