feat(mes): 完善排班日历功能,新增假期过滤及班组排班记录查询逻辑
parent
93a76b19db
commit
f4239e8a0e
|
|
@ -16,13 +16,18 @@
|
||||||
>
|
>
|
||||||
{{ lunarDisplay }}
|
{{ lunarDisplay }}
|
||||||
</div>
|
</div>
|
||||||
<!-- 班次信息:节假日不显示排班 -->
|
<!-- 班次列表:节假日不显示排班 -->
|
||||||
<template v-if="!isHoliday">
|
<template v-if="!isHoliday">
|
||||||
<!-- TODO @AI:最好有个地方,说明下这个逻辑; -->
|
<!--
|
||||||
|
配色规则(sort 对应轮班方式中的班次顺序):
|
||||||
|
sort=1 白班 → success(绿色)
|
||||||
|
sort=2 中班 → 三班倒用 warning(橙色),两班倒用 info(灰色)
|
||||||
|
sort=3 夜班 → info(灰色)
|
||||||
|
-->
|
||||||
<div v-for="item in teamShifts" :key="item.sort" class="mt-2px">
|
<div v-for="item in teamShifts" :key="item.sort" class="mt-2px">
|
||||||
<!-- sort=1 白班:绿色 -->
|
<!-- sort=1 白班:绿色 -->
|
||||||
<el-button v-if="item.sort === 1" type="success" size="small" class="!w-full !text-12px">
|
<el-button v-if="item.sort === 1" type="success" size="small" class="!w-full !text-12px">
|
||||||
{{ item.teamName }}
|
{{ item.shiftName }} · {{ item.teamName }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<!-- sort=2 中班:三班倒时用橙色,两班倒时用灰色 -->
|
<!-- sort=2 中班:三班倒时用橙色,两班倒时用灰色 -->
|
||||||
<el-button
|
<el-button
|
||||||
|
|
@ -31,11 +36,11 @@
|
||||||
size="small"
|
size="small"
|
||||||
class="!w-full !text-12px"
|
class="!w-full !text-12px"
|
||||||
>
|
>
|
||||||
{{ item.teamName }}
|
{{ item.shiftName }} · {{ item.teamName }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<!-- sort=3 夜班:灰色 -->
|
<!-- sort=3 夜班:灰色 -->
|
||||||
<el-button v-else-if="item.sort === 3" type="info" size="small" class="!w-full !text-12px">
|
<el-button v-else-if="item.sort === 3" type="info" size="small" class="!w-full !text-12px">
|
||||||
{{ item.teamName }}
|
{{ item.shiftName }} · {{ item.teamName }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
<!-- 排班日历 - 配色图例说明 -->
|
||||||
|
<template>
|
||||||
|
<div class="flex items-center flex-wrap gap-x-16px gap-y-4px text-12px text-#606266 px-2px py-6px">
|
||||||
|
<span class="text-#909399 shrink-0">配色说明:</span>
|
||||||
|
<span class="flex items-center gap-4px">
|
||||||
|
<span class="legend-dot bg-#95d475" ></span>
|
||||||
|
白班
|
||||||
|
</span>
|
||||||
|
<span class="flex items-center gap-4px">
|
||||||
|
<span class="legend-dot bg-#f0a020" ></span>
|
||||||
|
中班(三班倒)
|
||||||
|
</span>
|
||||||
|
<span class="flex items-center gap-4px">
|
||||||
|
<span class="legend-dot bg-#909399" ></span>
|
||||||
|
中班(两班倒)/ 夜班
|
||||||
|
</span>
|
||||||
|
<span class="flex items-center gap-4px">
|
||||||
|
<span class="legend-dot bg-#f56c6c opacity-60" ></span>
|
||||||
|
<span class="text-#f56c6c">红色日期</span>
|
||||||
|
= 周末
|
||||||
|
</span>
|
||||||
|
<span class="flex items-center gap-4px">
|
||||||
|
<el-tag size="small" effect="dark" type="success" class="!text-11px !h-18px !px-4px">休</el-tag>
|
||||||
|
= 节假日(不显示排班)
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.legend-dot {
|
||||||
|
display: inline-block;
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
border-radius: 2px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -2,17 +2,15 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<!-- 左侧:班组列表选择 -->
|
<!-- 左侧:班组列表选择 -->
|
||||||
<!-- TODO @AI:默认选中首个 -->
|
|
||||||
<div
|
<div
|
||||||
class="w-150px shrink-0 mr-12px border border-solid border-#dcdfe6 rounded-4px overflow-hidden"
|
class="w-150px shrink-0 mr-12px border border-solid border-#dcdfe6 rounded-4px overflow-hidden"
|
||||||
>
|
>
|
||||||
<!-- TODO @AI:可以把 @click 在封装下么?更统一一些; -->
|
|
||||||
<div
|
<div
|
||||||
v-for="team in teamList"
|
v-for="team in teamList"
|
||||||
:key="team.id"
|
:key="team.id"
|
||||||
class="px-16px py-10px cursor-pointer text-14px text-#606266 border-b border-b-solid border-b-#ebeef5 last:border-b-0 hover:bg-#f5f7fa transition-colors"
|
class="px-16px py-10px cursor-pointer text-14px text-#606266 border-b border-b-solid border-b-#ebeef5 last:border-b-0 hover:bg-#f5f7fa transition-colors"
|
||||||
:class="selectedTeamId === team.id ? 'bg-#ecf5ff text-#409eff font-500' : ''"
|
:class="selectedTeamId === team.id ? 'bg-#ecf5ff text-#409eff font-500' : ''"
|
||||||
@click="selectedTeamId = team.id; onTeamSelected()"
|
@click="onSelectTeam(team.id)"
|
||||||
>
|
>
|
||||||
{{ team.name }}
|
{{ team.name }}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -20,6 +18,7 @@
|
||||||
|
|
||||||
<!-- 右侧:日历 -->
|
<!-- 右侧:日历 -->
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
|
<CalendarLegend />
|
||||||
<el-calendar v-model="currentDate" v-loading="loading">
|
<el-calendar v-model="currentDate" v-loading="loading">
|
||||||
<template #date-cell="{ data }">
|
<template #date-cell="{ data }">
|
||||||
<CalendarDateCell
|
<CalendarDateCell
|
||||||
|
|
@ -40,6 +39,7 @@ import { CalHolidayApi, CalHolidayVO } from '@/api/mes/cal/holiday'
|
||||||
import { formatDate } from '@/utils/formatTime'
|
import { formatDate } from '@/utils/formatTime'
|
||||||
import { HolidayType } from '@/views/mes/utils/constants'
|
import { HolidayType } from '@/views/mes/utils/constants'
|
||||||
import CalendarDateCell from './CalendarDateCell.vue'
|
import CalendarDateCell from './CalendarDateCell.vue'
|
||||||
|
import CalendarLegend from './CalendarLegend.vue'
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const currentDate = ref(new Date()) // 日历当前显示月份
|
const currentDate = ref(new Date()) // 日历当前显示月份
|
||||||
|
|
@ -48,9 +48,12 @@ const teamList = ref<CalTeamVO[]>([]) // 所有班组列表
|
||||||
const calendarDayMap = ref<Map<string, CalCalendarDayVO>>(new Map()) // key: yyyy-MM-dd
|
const calendarDayMap = ref<Map<string, CalCalendarDayVO>>(new Map()) // key: yyyy-MM-dd
|
||||||
const holidaySet = ref(new Set<string>()) // 节假日日期集合,key: yyyy-MM-dd
|
const holidaySet = ref(new Set<string>()) // 节假日日期集合,key: yyyy-MM-dd
|
||||||
|
|
||||||
/** 获取班组列表 */
|
/** 获取班组列表,并默认选中第一个 */
|
||||||
const getTeamList = async () => {
|
const getTeamList = async () => {
|
||||||
teamList.value = await CalTeamApi.getTeamList()
|
teamList.value = await CalTeamApi.getTeamList()
|
||||||
|
if (teamList.value.length > 0) {
|
||||||
|
onSelectTeam(teamList.value[0].id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 获取节假日列表,构建节假日日期集合 */
|
/** 获取节假日列表,构建节假日日期集合 */
|
||||||
|
|
@ -98,8 +101,9 @@ const fetchCalendar = async () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 选择班组后刷新日历 */
|
/** 点击左侧班组后切换并刷新日历 */
|
||||||
const onTeamSelected = () => {
|
const onSelectTeam = (id: number) => {
|
||||||
|
selectedTeamId.value = id
|
||||||
fetchCalendar()
|
fetchCalendar()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,20 +2,15 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<!-- 左侧:班组类型选择 -->
|
<!-- 左侧:班组类型选择 -->
|
||||||
<!-- TODO @AI:默认选中首个 -->
|
|
||||||
<div
|
<div
|
||||||
class="w-150px shrink-0 mr-12px border border-solid border-#dcdfe6 rounded-4px overflow-hidden"
|
class="w-150px shrink-0 mr-12px border border-solid border-#dcdfe6 rounded-4px overflow-hidden"
|
||||||
>
|
>
|
||||||
<!-- TODO @AI:可以把 @click 在封装下么?更统一一些; -->
|
|
||||||
<div
|
<div
|
||||||
v-for="dict in getIntDictOptions(DICT_TYPE.MES_CAL_CALENDAR_TYPE)"
|
v-for="dict in getIntDictOptions(DICT_TYPE.MES_CAL_CALENDAR_TYPE)"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
class="px-16px py-10px cursor-pointer text-14px text-#606266 border-b border-b-solid border-b-#ebeef5 last:border-b-0 hover:bg-#f5f7fa transition-colors"
|
class="px-16px py-10px cursor-pointer text-14px text-#606266 border-b border-b-solid border-b-#ebeef5 last:border-b-0 hover:bg-#f5f7fa transition-colors"
|
||||||
:class="selectedType === dict.value ? 'bg-#ecf5ff text-#409eff font-500' : ''"
|
:class="selectedType === dict.value ? 'bg-#ecf5ff text-#409eff font-500' : ''"
|
||||||
@click="
|
@click="onSelectType(dict.value)"
|
||||||
selectedType = dict.value
|
|
||||||
onTypeSelected()
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
{{ dict.label }}
|
{{ dict.label }}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -23,6 +18,7 @@
|
||||||
|
|
||||||
<!-- 右侧:日历 -->
|
<!-- 右侧:日历 -->
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
|
<CalendarLegend />
|
||||||
<el-calendar v-model="currentDate" v-loading="loading">
|
<el-calendar v-model="currentDate" v-loading="loading">
|
||||||
<template #date-cell="{ data }">
|
<template #date-cell="{ data }">
|
||||||
<CalendarDateCell
|
<CalendarDateCell
|
||||||
|
|
@ -43,6 +39,7 @@ import { formatDate } from '@/utils/formatTime'
|
||||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
import { HolidayType } from '@/views/mes/utils/constants'
|
import { HolidayType } from '@/views/mes/utils/constants'
|
||||||
import CalendarDateCell from './CalendarDateCell.vue'
|
import CalendarDateCell from './CalendarDateCell.vue'
|
||||||
|
import CalendarLegend from './CalendarLegend.vue'
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const currentDate = ref(new Date()) // 日历当前显示月份
|
const currentDate = ref(new Date()) // 日历当前显示月份
|
||||||
|
|
@ -95,8 +92,9 @@ const fetchCalendar = async () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 选择分类后刷新日历 */
|
/** 点击左侧分类后切换并刷新日历 */
|
||||||
const onTypeSelected = () => {
|
const onSelectType = (value: number) => {
|
||||||
|
selectedType.value = value
|
||||||
fetchCalendar()
|
fetchCalendar()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -107,8 +105,12 @@ watch(currentDate, () => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
/** 初始化 */
|
/** 初始化:加载节假日,并默认选中第一个分类 */
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getHolidayList()
|
getHolidayList()
|
||||||
|
const opts = getIntDictOptions(DICT_TYPE.MES_CAL_CALENDAR_TYPE)
|
||||||
|
if (opts.length > 0) {
|
||||||
|
onSelectType(opts[0].value as number)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<!-- 日历 -->
|
<!-- 日历 -->
|
||||||
|
<CalendarLegend />
|
||||||
<el-calendar v-model="currentDate" v-loading="loading">
|
<el-calendar v-model="currentDate" v-loading="loading">
|
||||||
<template #date-cell="{ data }">
|
<template #date-cell="{ data }">
|
||||||
<CalendarDateCell
|
<CalendarDateCell
|
||||||
|
|
@ -46,6 +47,7 @@ import { getSimpleUserList, UserVO } from '@/api/system/user'
|
||||||
import { formatDate } from '@/utils/formatTime'
|
import { formatDate } from '@/utils/formatTime'
|
||||||
import { HolidayType } from '@/views/mes/utils/constants'
|
import { HolidayType } from '@/views/mes/utils/constants'
|
||||||
import CalendarDateCell from './CalendarDateCell.vue'
|
import CalendarDateCell from './CalendarDateCell.vue'
|
||||||
|
import CalendarLegend from './CalendarLegend.vue'
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const currentDate = ref(new Date()) // 日历当前显示月份
|
const currentDate = ref(new Date()) // 日历当前显示月份
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue