|
@@ -25,12 +25,10 @@
|
|
</el-form>
|
|
</el-form>
|
|
</div>
|
|
</div>
|
|
<!-- <el-calendar v-model="calendarValue" /> -->
|
|
<!-- <el-calendar v-model="calendarValue" /> -->
|
|
- <el-calendar v-model="calendarValue">
|
|
|
|
|
|
+ <el-calendar v-model="calendarValue" :key="calendarKey">
|
|
<template #date-cell="{ data }">
|
|
<template #date-cell="{ data }">
|
|
<div class="calendar-cell" @dblclick="handleDayDblClick(data.day)">
|
|
<div class="calendar-cell" @dblclick="handleDayDblClick(data.day)">
|
|
- <!-- 红点标记 -->
|
|
|
|
<div v-if="showRedDot(data.day)" class="red-dot"></div>
|
|
<div v-if="showRedDot(data.day)" class="red-dot"></div>
|
|
-
|
|
|
|
<div class="checkbox-status">
|
|
<div class="checkbox-status">
|
|
<el-checkbox
|
|
<el-checkbox
|
|
:label="formatMonthDay(data.day)"
|
|
:label="formatMonthDay(data.day)"
|
|
@@ -47,21 +45,20 @@
|
|
{{ getScheduleStatus(data.day) === 0 ? '待确认' : '已确认' }}
|
|
{{ getScheduleStatus(data.day) === 0 ? '待确认' : '已确认' }}
|
|
</el-tag>
|
|
</el-tag>
|
|
</div>
|
|
</div>
|
|
-
|
|
|
|
<div class="employee-names">
|
|
<div class="employee-names">
|
|
<div
|
|
<div
|
|
v-for="(name, index) in getScheduleNames(data.day)"
|
|
v-for="(name, index) in getScheduleNames(data.day)"
|
|
:key="index"
|
|
:key="index"
|
|
- class="employee-name"
|
|
|
|
- @dblclick.stop
|
|
|
|
|
|
+ class="employee-name"
|
|
>
|
|
>
|
|
|
|
+ <!-- @dblclick.stop -->
|
|
{{ name }}
|
|
{{ name }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
</el-calendar>
|
|
</el-calendar>
|
|
- <el-pagination :current-page="state.page" :page-sizes="[10, 20, 50, 100]" :page-size="state.limit" :total="state.total" layout="total, sizes, prev, pager, next, jumper" @size-change="state.pageSizeChangeHandle" @current-change="state.pageCurrentChangeHandle"> </el-pagination>
|
|
|
|
|
|
+ <el-pagination :current-page="state.page" :page-sizes="[200,300,450,600]" :page-size="state.limit" :total="state.total" layout="total, sizes, prev, pager, next, jumper" @size-change="state.pageSizeChangeHandle" @current-change="state.pageCurrentChangeHandle"> </el-pagination>
|
|
<!-- 弹窗, 新增 / 修改 -->
|
|
<!-- 弹窗, 新增 / 修改 -->
|
|
<add-or-update ref="addOrUpdateRef" @refreshDataList="refreshAfterAdd">确定</add-or-update>
|
|
<add-or-update ref="addOrUpdateRef" @refreshDataList="refreshAfterAdd">确定</add-or-update>
|
|
</div>
|
|
</div>
|
|
@@ -72,7 +69,6 @@ import useView from "@/hooks/useView";
|
|
import { reactive, ref, toRefs } from "vue";
|
|
import { reactive, ref, toRefs } from "vue";
|
|
import baseService from "@/service/baseService";
|
|
import baseService from "@/service/baseService";
|
|
import { ElMessage, ElMessageBox } from "element-plus";
|
|
import { ElMessage, ElMessageBox } from "element-plus";
|
|
-import { IObject } from "@/types/interface";
|
|
|
|
import AddOrUpdate from "./schedule-add-or-update.vue";
|
|
import AddOrUpdate from "./schedule-add-or-update.vue";
|
|
|
|
|
|
const view = reactive({
|
|
const view = reactive({
|
|
@@ -80,13 +76,12 @@ const view = reactive({
|
|
getDataListURL: "/emergency/schedule/page",
|
|
getDataListURL: "/emergency/schedule/page",
|
|
getDataListIsPage: true,
|
|
getDataListIsPage: true,
|
|
exportURL: "/emergency/schedule/export",
|
|
exportURL: "/emergency/schedule/export",
|
|
- deleteURL: "/emergency/schedule",
|
|
|
|
|
|
+ deleteURL: "/emergency/schedule/date",
|
|
|
|
|
|
});
|
|
});
|
|
|
|
|
|
const state = reactive({ ...useView(view), ...toRefs(view) });
|
|
const state = reactive({ ...useView(view), ...toRefs(view) });
|
|
-
|
|
|
|
-
|
|
|
|
|
|
+state.limit = 200;
|
|
//日历
|
|
//日历
|
|
const calendarValue = ref(new Date())
|
|
const calendarValue = ref(new Date())
|
|
const selectedDates = ref<string[]>([]);
|
|
const selectedDates = ref<string[]>([]);
|
|
@@ -109,7 +104,6 @@ const getScheduleNames = (date: string): string[] => {
|
|
return item?.employeeNames || [];
|
|
return item?.employeeNames || [];
|
|
};
|
|
};
|
|
|
|
|
|
-
|
|
|
|
const addHandle = () => {
|
|
const addHandle = () => {
|
|
if (!selectedDates.value || selectedDates.value.length === 0) {
|
|
if (!selectedDates.value || selectedDates.value.length === 0) {
|
|
ElMessage({
|
|
ElMessage({
|
|
@@ -149,6 +143,8 @@ const addHandle = () => {
|
|
const refreshAfterAdd = async () => {
|
|
const refreshAfterAdd = async () => {
|
|
selectedDates.value = [];
|
|
selectedDates.value = [];
|
|
state.getDataList();
|
|
state.getDataList();
|
|
|
|
+ //强制刷新日历
|
|
|
|
+ calendarKey.value += 1;
|
|
};
|
|
};
|
|
|
|
|
|
const addOrUpdateRef = ref();
|
|
const addOrUpdateRef = ref();
|
|
@@ -156,13 +152,11 @@ const addOrUpdateHandle = (id?: number, date?: string, dates?: string[]) => {
|
|
addOrUpdateRef.value.init(id, date, dates);
|
|
addOrUpdateRef.value.init(id, date, dates);
|
|
};
|
|
};
|
|
|
|
|
|
-
|
|
|
|
const handleDayDblClick = (day: string) => {
|
|
const handleDayDblClick = (day: string) => {
|
|
const schedule = state.dataList?.find(item => item.scheduleDate === day);
|
|
const schedule = state.dataList?.find(item => item.scheduleDate === day);
|
|
-
|
|
|
|
if (schedule && schedule.id) {
|
|
if (schedule && schedule.id) {
|
|
// 已有排班记录,修改
|
|
// 已有排班记录,修改
|
|
- addOrUpdateHandle(schedule.id);
|
|
|
|
|
|
+ addOrUpdateHandle(schedule.id, day);
|
|
} else {
|
|
} else {
|
|
// 不存在,调用“新增”
|
|
// 不存在,调用“新增”
|
|
addOrUpdateHandle(undefined, day);
|
|
addOrUpdateHandle(undefined, day);
|
|
@@ -170,10 +164,10 @@ const handleDayDblClick = (day: string) => {
|
|
};
|
|
};
|
|
//红点
|
|
//红点
|
|
const showRedDot = (date: string): boolean => {
|
|
const showRedDot = (date: string): boolean => {
|
|
|
|
+ //const today = new Date("2025-07-28");
|
|
const today = new Date();
|
|
const today = new Date();
|
|
const todayStr = today.toISOString().split("T")[0];
|
|
const todayStr = today.toISOString().split("T")[0];
|
|
|
|
|
|
- console.log("cell date:", date, "fake today:", todayStr);
|
|
|
|
if (date !== todayStr) return false;
|
|
if (date !== todayStr) return false;
|
|
|
|
|
|
const year = today.getFullYear();
|
|
const year = today.getFullYear();
|
|
@@ -181,15 +175,15 @@ const showRedDot = (date: string): boolean => {
|
|
|
|
|
|
// 本月最后一天
|
|
// 本月最后一天
|
|
const lastDateOfMonth = new Date(year, month + 1, 0);
|
|
const lastDateOfMonth = new Date(year, month + 1, 0);
|
|
- console.log(lastDateOfMonth);
|
|
|
|
-
|
|
|
|
|
|
+ lastDateOfMonth.setHours(23, 59, 59, 999);
|
|
const lastDayWeekDay = lastDateOfMonth.getDay();
|
|
const lastDayWeekDay = lastDateOfMonth.getDay();
|
|
|
|
|
|
// 最后一周的周一
|
|
// 最后一周的周一
|
|
const daysToMonday = lastDayWeekDay === 0 ? 6 : lastDayWeekDay - 1;
|
|
const daysToMonday = lastDayWeekDay === 0 ? 6 : lastDayWeekDay - 1;
|
|
const lastWeekMonday = new Date(lastDateOfMonth);
|
|
const lastWeekMonday = new Date(lastDateOfMonth);
|
|
lastWeekMonday.setDate(lastDateOfMonth.getDate() - daysToMonday);
|
|
lastWeekMonday.setDate(lastDateOfMonth.getDate() - daysToMonday);
|
|
-
|
|
|
|
|
|
+ lastWeekMonday.setHours(0, 0, 0, 0);
|
|
|
|
+
|
|
if (today >= lastWeekMonday && today <= lastDateOfMonth) {
|
|
if (today >= lastWeekMonday && today <= lastDateOfMonth) {
|
|
const nextYearMonth = new Date(year, month + 1).toISOString().slice(0, 7);
|
|
const nextYearMonth = new Date(year, month + 1).toISOString().slice(0, 7);
|
|
const hasNextMonthSchedule = state.dataList?.some(
|
|
const hasNextMonthSchedule = state.dataList?.some(
|
|
@@ -201,8 +195,6 @@ const showRedDot = (date: string): boolean => {
|
|
return false;
|
|
return false;
|
|
};
|
|
};
|
|
|
|
|
|
-
|
|
|
|
-
|
|
|
|
const handleDateToggle = (day: string, checked: boolean) => {
|
|
const handleDateToggle = (day: string, checked: boolean) => {
|
|
const index = selectedDates.value.indexOf(day);
|
|
const index = selectedDates.value.indexOf(day);
|
|
if (checked && index === -1) {
|
|
if (checked && index === -1) {
|
|
@@ -211,6 +203,7 @@ const handleDateToggle = (day: string, checked: boolean) => {
|
|
selectedDates.value.splice(index, 1);
|
|
selectedDates.value.splice(index, 1);
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
+const calendarKey = ref(0);
|
|
|
|
|
|
//删除
|
|
//删除
|
|
const customDeleteHandle = () => {
|
|
const customDeleteHandle = () => {
|
|
@@ -218,37 +211,36 @@ const customDeleteHandle = () => {
|
|
return ElMessage.warning("请先选择要删除的日期");
|
|
return ElMessage.warning("请先选择要删除的日期");
|
|
}
|
|
}
|
|
|
|
|
|
- const idsToDelete = selectedDates.value
|
|
|
|
- .map(date => {
|
|
|
|
- const match = state.dataList.find(item => item.scheduleDate === date);
|
|
|
|
- return match?.id;
|
|
|
|
- })
|
|
|
|
- .filter(Boolean) as string[];
|
|
|
|
|
|
+ const datesToDelete = selectedDates.value.filter(date =>
|
|
|
|
+ state.dataList.some(item => item.scheduleDate === date)
|
|
|
|
+ );
|
|
|
|
|
|
- if (idsToDelete.length === 0) {
|
|
|
|
|
|
+ if (datesToDelete.length === 0) {
|
|
return ElMessage.warning("选中日期中暂无排班数据");
|
|
return ElMessage.warning("选中日期中暂无排班数据");
|
|
}
|
|
}
|
|
|
|
|
|
- ElMessageBox.confirm(`确认要删除选中的 ${idsToDelete.length} 条排班记录吗?`, "提示", {
|
|
|
|
|
|
+ ElMessageBox.confirm(`确认要删除选中的 ${datesToDelete.length} 条排班记录吗?`, "提示", {
|
|
confirmButtonText: "删除",
|
|
confirmButtonText: "删除",
|
|
cancelButtonText: "取消",
|
|
cancelButtonText: "取消",
|
|
type: "warning"
|
|
type: "warning"
|
|
- }).then(() => {
|
|
|
|
- baseService.delete(state.deleteURL, idsToDelete);
|
|
|
|
|
|
+ }).then(async () => {
|
|
|
|
+ await baseService.delete(state.deleteURL, datesToDelete);
|
|
ElMessage.success({
|
|
ElMessage.success({
|
|
message: "删除成功",
|
|
message: "删除成功",
|
|
duration: 500,
|
|
duration: 500,
|
|
- onClose: () => {
|
|
|
|
- state.getDataList();
|
|
|
|
- selectedDates.value = [];
|
|
|
|
- }
|
|
|
|
|
|
+ onClose: async () => {
|
|
|
|
+ state.getDataList();
|
|
|
|
+ selectedDates.value = [];
|
|
|
|
+ calendarKey.value += 1; // 刷新日历
|
|
|
|
+ }
|
|
});
|
|
});
|
|
}).catch(() => {
|
|
}).catch(() => {
|
|
- // 取消删除
|
|
|
|
|
|
+ // 用户取消操作
|
|
});
|
|
});
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
+
|
|
// 审阅
|
|
// 审阅
|
|
const reviewHandle = (id?: string) => {
|
|
const reviewHandle = (id?: string) => {
|
|
if (selectedDates.value.length === 0) {
|
|
if (selectedDates.value.length === 0) {
|
|
@@ -280,8 +272,8 @@ const reviewHandle = (id?: string) => {
|
|
duration: 500,
|
|
duration: 500,
|
|
onClose: () => {
|
|
onClose: () => {
|
|
state.getDataList();
|
|
state.getDataList();
|
|
- state.dataListSelections = [];
|
|
|
|
-
|
|
|
|
|
|
+ selectedDates.value = [];
|
|
|
|
+ calendarKey.value += 1; // 刷新日历
|
|
}
|
|
}
|
|
});
|
|
});
|
|
});
|
|
});
|
|
@@ -305,11 +297,30 @@ const reviewHandle = (id?: string) => {
|
|
padding: 4px;
|
|
padding: 4px;
|
|
cursor: pointer;
|
|
cursor: pointer;
|
|
}
|
|
}
|
|
|
|
+.employee-names {
|
|
|
|
+ flex-grow: 1;
|
|
|
|
+ margin-top: 8px;
|
|
|
|
+ display: flex;
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
+ justify-content:center;
|
|
|
|
+ gap: 10px 12px;
|
|
|
|
+ max-height: 60px;
|
|
|
|
+ overflow-y: auto;
|
|
|
|
+ width: 100%;
|
|
|
|
+ padding-right: 4px;
|
|
|
|
+}
|
|
|
|
+
|
|
.employee-name {
|
|
.employee-name {
|
|
|
|
+ flex: 0 1 calc(50% - 12px);
|
|
|
|
+ text-align: center;
|
|
|
|
+ white-space: nowrap;
|
|
|
|
+ overflow: hidden;
|
|
|
|
+ text-overflow: ellipsis;
|
|
user-select: none;
|
|
user-select: none;
|
|
-webkit-user-select: none;
|
|
-webkit-user-select: none;
|
|
-moz-user-select: none;
|
|
-moz-user-select: none;
|
|
}
|
|
}
|
|
|
|
+
|
|
.checkbox-status {
|
|
.checkbox-status {
|
|
display: flex;
|
|
display: flex;
|
|
align-items: center;
|
|
align-items: center;
|
|
@@ -335,15 +346,21 @@ const reviewHandle = (id?: string) => {
|
|
right: 6px;
|
|
right: 6px;
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
-::v-deep(.el-calendar-day) {
|
|
|
|
- display: flex !important;
|
|
|
|
- flex-direction: column;
|
|
|
|
- align-items: flex-start;
|
|
|
|
- justify-content: flex-start;
|
|
|
|
- padding: 4px;
|
|
|
|
- box-sizing: border-box;
|
|
|
|
|
|
+.el-calendar-table .el-calendar-day {
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
+ height: 100px;
|
|
|
|
+ padding: 0;
|
|
}
|
|
}
|
|
-
|
|
|
|
-
|
|
|
|
-</style>
|
|
|
|
|
|
+/* .employee-names::after {
|
|
|
|
+ content: "";
|
|
|
|
+ position: absolute;
|
|
|
|
+ bottom: 0;
|
|
|
|
+ left: 0;
|
|
|
|
+ right: 0;
|
|
|
|
+ height: 18px;
|
|
|
|
+ background: linear-gradient(to bottom, rgba(246,248,250, 0), rgba(246,248,250, 1));
|
|
|
|
+ pointer-events: none;
|
|
|
|
+ z-index: 1;
|
|
|
|
+} */
|
|
|
|
+
|
|
|
|
+</style>
|