| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399 |
- <script lang="ts" setup>
- import { computed, ref, watch } from 'vue';
- import { Page, useVbenDrawer } from '@vben/common-ui';
- import dayjs from 'dayjs';
- import { ElCheckbox, ElRadioButton, ElRadioGroup } from 'element-plus';
- import {
- Tickets,
- Plus,
- User,
- CaretLeft,
- CaretRight,
- } from '@element-plus/icons-vue';
- import CreateTasK from './components/create/index.vue';
- import Day from './components/day/index.vue';
- import Month from './components/month/index.vue';
- import Week from './components/week/index.vue';
- // 根据timeType计算默认日期
- const getDefaultDate = (type: string) => {
- switch (type) {
- case 'month': {
- return dayjs().format('YYYY-MM-DD');
- }
- case 'week': {
- return dayjs().format('YYYY-MM-DD');
- }
- default: {
- return dayjs().format('YYYY-MM-DD');
- }
- }
- };
- const searchParams = ref({
- timeType: 'day',
- station: '',
- date: getDefaultDate('day'),
- });
- // 当前显示的日期
- const currentDate = ref(dayjs());
- const currentDate2 = ref(dayjs()); //单独给月份的时间
- // 任务授权状态
- const taskStatuses = ref({
- canAuthorize: true,
- authorized: true,
- beAuthorized: true,
- });
- // 监听timeType变化,更新默认日期和当前显示日期
- watch(
- () => searchParams.value.timeType,
- (newType) => {
- searchParams.value.date = getDefaultDate(newType);
- currentDate.value = dayjs(searchParams.value.date);
- currentDate2.value = dayjs(searchParams.value.date); //单独给月份的时间
- },
- );
- // 确保currentDate和currentDate2始终保持同步
- watch(
- () => currentDate.value,
- (newDate) => {
- currentDate2.value = newDate;
- },
- );
- //单独给月份的监听器
- watch(
- () => currentDate2.value,
- (newDate) => {
- currentDate.value = newDate;
- },
- );
- // 计算年份和周数
- const year = computed(() => {
- return dayjs(searchParams.value.date).year();
- });
- const weekNumber = computed(() => {
- return dayjs(searchParams.value.date).week();
- });
- // 计算当前选中日期所在周的开始和结束日期
- const currentWeekRange = computed(() => {
- const date = dayjs(searchParams.value.date);
- // 计算周开始(周一)
- const startOfWeek = date.startOf('week');
- // 调整为周一(dayjs默认周日为一周开始)
- const monday =
- startOfWeek.day() === 0 ? startOfWeek.subtract(1, 'day') : startOfWeek;
- // 计算周日
- const sunday = monday.add(6, 'day');
- return {
- start: monday,
- end: sunday,
- };
- });
- // 生成日历天数
- const calendarDays = computed(() => {
- const days = [];
- const year = currentDate.value.year();
- const month = currentDate.value.month();
- // 获取当月第一天
- const firstDay = dayjs(new Date(year, month, 1));
- // 获取当月第一天是星期几(0-6,0是周日)
- const firstDayOfWeek = firstDay.day();
- // 计算需要显示的上个月天数
- const prevMonthDays = firstDayOfWeek === 0 ? 6 : firstDayOfWeek - 1;
- // 获取当月最后一天
- const lastDay = dayjs(new Date(year, month + 1, 0));
- const lastDate = lastDay.date();
- // 添加上个月的日期
- for (let i = prevMonthDays; i > 0; i--) {
- const date = firstDay.subtract(i, 'day');
- const isInCurrentWeek =
- searchParams.value.timeType === 'week' &&
- date.isAfter(currentWeekRange.value.start.subtract(1, 'day')) &&
- date.isBefore(currentWeekRange.value.end.add(1, 'day'));
- days.push({
- date: date.format('YYYY-MM-DD'),
- day: date.date(),
- isToday: date.isSame(dayjs(), 'day'),
- isOtherMonth: true,
- isInCurrentWeek,
- });
- }
- // 添加当月的日期
- for (let i = 1; i <= lastDate; i++) {
- const date = dayjs(new Date(year, month, i));
- const isInCurrentWeek =
- searchParams.value.timeType === 'week' &&
- date.isAfter(currentWeekRange.value.start.subtract(1, 'day')) &&
- date.isBefore(currentWeekRange.value.end.add(1, 'day'));
- days.push({
- date: date.format('YYYY-MM-DD'),
- day: i,
- isToday: date.isSame(dayjs(), 'day'),
- isOtherMonth: false,
- isInCurrentWeek,
- });
- }
- // 计算需要显示的下个月天数
- const totalDays = days.length;
- const nextMonthDays = 42 - totalDays; // 6行7列=42个格子
- // 添加下个月的日期
- for (let i = 1; i <= nextMonthDays; i++) {
- const date = lastDay.add(i, 'day');
- const isInCurrentWeek =
- searchParams.value.timeType === 'week' &&
- date.isAfter(currentWeekRange.value.start.subtract(1, 'day')) &&
- date.isBefore(currentWeekRange.value.end.add(1, 'day'));
- days.push({
- date: date.format('YYYY-MM-DD'),
- day: date.date(),
- isToday: date.isSame(dayjs(), 'day'),
- isOtherMonth: true,
- isInCurrentWeek,
- });
- }
- return days;
- });
- // 切换到上个月
- const prevMonth = () => {
- currentDate.value = currentDate.value.subtract(1, 'month');
- currentDate2.value = currentDate2.value.subtract(1, 'month');
- };
- // 切换到下个月
- const nextMonth = () => {
- currentDate.value = currentDate.value.add(1, 'month');
- currentDate2.value = currentDate2.value.add(1, 'month');
- };
- // 选择日期
- const selectDate = (date: string) => {
- searchParams.value.date = date;
- };
- const [CreateTaskDrawer, createTaskDrawerApi] = useVbenDrawer({
- // 连接抽离的组件
- connectedComponent: CreateTasK,
- // placement: 'left',
- });
- const createTaskDrawerEvent = () => {
- createTaskDrawerApi.setData({ isUpdate: false }).open();
- };
- console.log(currentDate.value);
- </script>
- <template>
- <Page
- style="height: 100%"
- title=""
- :auto-content-height="true"
- class="h-screen"
- >
- <div class="flex h-full min-h-0 flex-row space-x-4">
- <!--左侧筛选区域-->
- <div
- class="relative h-full w-80 flex-shrink-0 overflow-y-auto rounded-lg bg-white p-4 pb-20 shadow"
- >
- <!--油站选择-->
- <div class="mb-4">
- <ElSelect
- v-model="searchParams.station"
- placeholder="请选择油站"
- class="w-full"
- >
- <ElOption label="张三站-龙飞加油站" value="1" />
- </ElSelect>
- </div>
- <!--日期导航和视图切换-->
- <div class="mb-4">
- <div class="flex items-center justify-between">
- <!--时间筛选靠左-->
- <div class="flex items-center space-x-2">
- <el-icon><CaretLeft @click="prevMonth" /></el-icon>
- <span class="font-medium">{{
- currentDate.format('YYYY年 M月')
- }}</span>
- <el-icon><CaretRight @click="nextMonth" /></el-icon>
- </div>
- <!--视图切换靠右-->
- <ElRadioGroup
- v-model="searchParams.timeType"
- size="small"
- class="custom-radio-group"
- >
- <ElRadioButton label="day" class="custom-radio-btn"
- >日</ElRadioButton
- >
- <ElRadioButton label="week" class="custom-radio-btn"
- >周</ElRadioButton
- >
- <ElRadioButton label="month" class="custom-radio-btn"
- >月</ElRadioButton
- >
- </ElRadioGroup>
- </div>
- <!--日历显示-->
- <div class="calendar-container mt-1">
- <!--星期标题-->
- <div class="mb-1 flex justify-between text-xs text-gray-500">
- <div class="w-7 text-center">一</div>
- <div class="w-7 text-center">二</div>
- <div class="w-7 text-center">三</div>
- <div class="w-7 text-center">四</div>
- <div class="w-7 text-center">五</div>
- <div class="w-7 text-center">六</div>
- <div class="w-7 text-center">日</div>
- </div>
- <!--日期网格-->
- <div class="grid grid-cols-7 gap-1">
- <div
- v-for="day in calendarDays"
- :key="day.date"
- :style="
- day.date === '2025-12-22' || day.date === '2025-12-23'
- ? 'background-color: #FFE6E0'
- : day.isInCurrentWeek && !day.isToday
- ? 'background-color: #E6E8EB'
- : ''
- "
- class="flex h-7 w-7 cursor-pointer items-center justify-center rounded text-xs"
- :class="{
- 'bg-blue-600 text-white': day.isToday,
- 'bg-gray-100 text-gray-400': day.isOtherMonth,
- 'hover:bg-gray-100': !day.isOtherMonth,
- }"
- @click="selectDate(day.date)"
- >
- {{ day.day }}
- </div>
- </div>
- </div>
- </div>
- <!--任务授权状态-->
- <div class="mb-4">
- <div class="mb-2 font-medium">任务授权状态:</div>
- <div class="space-y-1" style="display: flex; flex-direction: column">
- <ElCheckbox v-model="taskStatuses.canAuthorize">
- 任务可授权
- </ElCheckbox>
- <ElCheckbox v-model="taskStatuses.authorized">
- 任务已授权
- </ElCheckbox>
- <ElCheckbox v-model="taskStatuses.beAuthorized">
- 任务被授权
- </ElCheckbox>
- </div>
- </div>
- <!--新增任务按钮固定在底部-->
- <div class="absolute bottom-0 left-0 w-full bg-white p-4">
- <div class="space-y-2">
- <ElButton
- type="primary"
- class="w-full"
- @click="createTaskDrawerEvent"
- >
- <template #icon>
- <el-icon><Plus /></el-icon> </template
- >油站新增任务
- </ElButton>
- </div>
- <div class="mt-1 space-y-2">
- <ElButton type="default" class="w-full"
- ><template #icon>
- <el-icon><User /></el-icon> </template
- >访客新增任务
- </ElButton>
- </div>
- <div class="mt-1 space-y-2">
- <ElButton type="default" class="w-full">
- <template #icon>
- <el-icon><Tickets /></el-icon>
- </template>
- 工单提报
- </ElButton>
- </div>
- </div>
- </div>
- <!--右侧内容区域-->
- <div class="flex h-full min-h-0 flex-1 flex-col">
- <ElCard class="flex h-full w-full flex-col">
- <div
- class="min-h-0 flex-1 overflow-y-auto"
- style="max-height: calc(100vh - 120px)"
- >
- <Day v-if="searchParams.timeType === 'day'" />
- <Week
- v-if="searchParams.timeType === 'week'"
- :year="year"
- :week-number="weekNumber"
- />
- <Month
- v-if="searchParams.timeType === 'month'"
- :month="currentDate"
- />
- </div>
- </ElCard>
- </div>
- </div>
- <CreateTaskDrawer />
- </Page>
- </template>
- <style scoped lang="scss">
- // :deep(.el-card) {
- // border: none !important;
- // box-shadow: none !important;
- // background: transparent !important;
- // }
- :deep(.custom-radio-group .el-radio-button) {
- padding: 4px;
- // background: transparent !important;
- background-color: #fafafa !important;
- border: none !important;
- }
- :deep(.custom-radio-group .el-radio-button__inner) {
- padding: 0 8px;
- background: transparent !important;
- border: none !important;
- box-shadow: none !important;
- }
- :deep(.custom-radio-group .el-radio-button__inner:hover) {
- color: #1890ff !important;
- background: transparent !important;
- }
- :deep(.custom-radio-group .el-radio-button.is-active .el-radio-button__inner) {
- color: #1890ff !important;
- background: transparent !important;
- border: none !important;
- box-shadow: none !important;
- }
- </style>
|