优化代码

This commit is contained in:
hero920103 committed 2026-11-05 18:28:46 +08:00
1 parent 8ba15d87b3
commit 7b1c94b5ff
5 files changed
+261 -2

No files matched your search

+5
View File
@@ -34,6 +34,11 @@ export function getScheduleBoard(params) {
return request({ url: '/backend/oa/scheduling/board', method: 'get', params })
}
// 当前登录用户的排班(按账号匹配员工档案),供日程日历显示上班/休息背景
export function getMyScheduleBoard(params) {
return request({ url: '/backend/oa/scheduling/my', method: 'get', params })
}
// 批量按格子编辑排班:cells 为排班板多选的「员工 × 日期」任意组合
// shift_id>0 设为该班次(有排班=调班,无排班=新增);shift_id=0 清除(休息/请假)
export function saveScheduleEntryCells(data) {
+143 -2
View File
@@ -78,6 +78,12 @@
>
<el-button :icon="ArrowRight" circle @click="changeMonth(1)" />
<el-button @click="goToday">今天</el-button>
<span
v-if="mySchedLoaded && mySchedCount === 0"
class="my-sched-tip"
title="当前登录账号未匹配到排班(账号需要有对应员工档案且已排班),因此不渲染上班/休息背景"
>当前账号暂无排班</span
>
</div>
</div>
<div class="calendar-week-header">
@@ -94,7 +100,9 @@
selected: cell.date === selectedDate,
'has-items': cell.items.length > 0,
'is-off': cell.tag === 'off',
'is-work': cell.tag === 'work'
'is-work': cell.tag === 'work',
'is-my-work': cell.myTag === 'work',
'is-my-rest': cell.myTag === 'rest'
}"
@click="selectedDate = cell.date"
@dblclick="openCreate(cell.date)"
@@ -109,6 +117,13 @@
<span v-else-if="cell.day === 1" class="month-tag"
>{{ cell.month }}月</span
>
<span
v-if="cell.myEntry"
class="my-shift-chip"
:style="{ background: cell.myEntry.color }"
:title="`${cell.myEntry.shift_name} ${cell.myEntry.work_start}-${cell.myEntry.work_end}`"
>{{ cell.myEntry.short_name || cell.myEntry.shift_name }}</span
>
</div>
<div v-if="cell.holidayName" class="cell-holiday" :title="cell.holidayName">
{{ cell.holidayName }}
@@ -164,6 +179,28 @@
<span v-else-if="selectedIsRestDay" class="day-title-holiday"
>周末</span
>
<span
v-if="selectedMyEntry"
class="day-title-holiday my-shift-title"
>
<span
class="holiday-tag"
:style="{
background: selectedMyEntry.color,
color: '#fff',
borderColor: selectedMyEntry.color
}"
>{{ selectedMyEntry.short_name || selectedMyEntry.shift_name }}</span
>
{{ selectedMyEntry.work_start }}-{{
selectedMyEntry.work_end
}}
</span>
<span
v-else-if="mySchedCount > 0"
class="day-title-holiday my-rest-title"
>休息</span
>
</div>
<div class="day-sub">
{{ selectedItems.length }} 项日程<template v-if="pendingCount > 0"
@@ -445,6 +482,7 @@ import {
getScheduleList,
getScheduleStats
} from "@/api/oaSchedule";
import { getMyScheduleBoard } from "@/api/oaScheduling";
const viewMode = ref("calendar");
const stats = ref({});
@@ -516,6 +554,39 @@ const calendarMonth = ref(now.getMonth() + 1);
const calendarItems = ref([]);
const selectedDate = ref(todayStr());
// ---------- 我的排班(上班 / 休息背景) ----------
// mySchedMap: { 'YYYY-MM-DD': 排班记录 };mySchedCount 为区间内排班天数。
// 只有区间内存在排班时才渲染背景,未排班的月份不显示,避免误导。
const mySchedMap = ref({});
const mySchedCount = ref(0);
// 是否已完成加载:用于区分“还没查完”与“查了但没有”,后者在日历标题旁提示
const mySchedLoaded = ref(false);
async function loadMySchedule(startStr, endStr) {
try {
const res = await getMyScheduleBoard({
start_date: startStr,
end_date: endStr
});
const list = res?.data?.list || [];
const map = {};
for (const item of list) {
map[normDate(item.date)] = item;
}
mySchedMap.value = map;
mySchedCount.value = list.length;
mySchedLoaded.value = true;
} catch {
// 排班背景属于辅助信息,失败时静默降级为无背景
mySchedMap.value = {};
mySchedCount.value = 0;
mySchedLoaded.value = true;
}
}
// 选中日期的排班,供侧栏标题展示班次
const selectedMyEntry = computed(() => mySchedMap.value[selectedDate.value] || null);
// ---------- 中国法定节假日 / 调休 ----------
// 后端返回 { 'YYYY-MM-DD': {name, type, wage} },type: 0 调休上班 / 1 法定放假。
// 普通周末不在此表内,由 isWeekend 按星期判定,避免与节假日数据重复。
@@ -643,6 +714,7 @@ const calendarCells = computed(() => {
start.getDate() + i
);
const date = fmtDate(d);
const my = mySchedMap.value[date];
cells.push({
date,
day: d.getDate(),
@@ -652,7 +724,10 @@ const calendarCells = computed(() => {
items: map[date] || [],
// 节假日相关:tag 用于格内角标与整格底色,holidayName 用于节日名文案
tag: dayTag(date),
holidayName: holidayName(date)
holidayName: holidayName(date),
// 我的排班:work=上班(有排班记录)/ rest=休息(区间内有排班但当天无记录)
myEntry: my || null,
myTag: mySchedCount.value === 0 ? "" : my ? "work" : "rest"
});
}
return cells;
@@ -732,6 +807,8 @@ async function loadCalendarData() {
);
const startStr = fmtDate(start);
const endStr = fmtDate(end);
// 我的排班与节假日一样按可视区间加载,用于日历格子的上班/休息背景
loadMySchedule(startStr, endStr);
// 节假日不在这里加载:由上方 watch([calendarYear, calendarMonth]) 统一驱动,
// 保证"翻月即加载对应月份所需年份",且首次挂载、二次进入都能自动补齐。
const res = await getScheduleList({
@@ -1265,6 +1342,16 @@ onMounted(() => {
text-align: center;
}
/* “当前账号暂无排班”提示:说明为什么没有上班/休息背景 */
.my-sched-tip {
font-size: 12px;
color: var(--el-text-color-secondary);
background: var(--el-fill-color-light);
border-radius: 10px;
padding: 2px 10px;
cursor: help;
}
.calendar-week-header {
display: grid;
grid-template-columns: repeat(7, 1fr);
@@ -1381,6 +1468,40 @@ onMounted(() => {
background: #fff;
}
/* 我的排班背景:上班浅绿 / 休息浅橙。排班是实际作息,覆盖节假日底色,
但保留休/班角标与节日名;today / selected 在后面定义,优先级仍最高 */
.calendar-cell.is-my-work {
background: #f0f9eb;
}
.calendar-cell.is-my-work:hover {
background: #e6f5db;
}
.calendar-cell.is-my-rest {
background: #fdf6ec;
}
.calendar-cell.is-my-rest:hover {
background: #faecd8;
}
/* 格内班次角标:用班次定义色做实底小色块 */
.my-shift-chip {
display: inline-flex;
align-items: center;
height: 16px;
padding: 0 4px;
border-radius: 3px;
font-size: 10px;
line-height: 1;
color: #fff;
flex-shrink: 0;
max-width: 56px;
overflow: hidden;
white-space: nowrap;
}
/* 今天:整格实蓝底,最醒目。放在 is-off / is-work 之后,
保证今天即使逢节假日也保留蓝色标识。
实底较深,格内文字统一转白(或白底反白)以保证对比度。 */
@@ -1753,6 +1874,20 @@ html.dark & {
.calendar-cell.is-work {
background: var(--el-bg-color);
}
.calendar-cell.is-my-work {
background: rgba(103, 194, 58, 0.1);
&:hover {
background: rgba(103, 194, 58, 0.16);
}
}
.calendar-cell.is-my-rest {
background: rgba(230, 162, 60, 0.1);
&:hover {
background: rgba(230, 162, 60, 0.16);
}
}
/* 今天:整格主色实底,与浅色主题保持一致 */
.calendar-cell.today {
background: var(--el-color-primary);
@@ -1795,6 +1930,12 @@ html.dark & {
.day-title-holiday .holiday-tag.is-work {
color: var(--el-text-color-secondary);
}
.day-title-holiday.my-shift-title {
color: var(--el-text-color-secondary);
}
.day-title-holiday.my-rest-title {
color: var(--el-color-warning);
}
.cell-item {
background: var(--el-fill-color-light);