|
|
@@ -1,8 +1,11 @@
|
|
|
<script setup lang="ts">
|
|
|
-import { ref, computed } from 'vue'
|
|
|
+import { ref, computed, onMounted } from 'vue'
|
|
|
import type { Dayjs } from 'dayjs'
|
|
|
import dayjs from 'dayjs'
|
|
|
import CalendarTagDetailDialog from './CalendarTagDetailDialog.vue'
|
|
|
+import { useUserStore } from '@/stores/modules/user'
|
|
|
+
|
|
|
+const userStore = useUserStore()
|
|
|
|
|
|
// 控制日历显示的月份(受控状态)
|
|
|
const displayMonth = ref<Dayjs>(dayjs())
|
|
|
@@ -10,12 +13,12 @@ const displayMonth = ref<Dayjs>(dayjs())
|
|
|
// 年份选项
|
|
|
const yearOptions = computed(() => {
|
|
|
const currentYear = new Date().getFullYear()
|
|
|
- const startYear = 1100 // 你可以改成任意起始年,比如 1990
|
|
|
+ const startYear = 1950 // 你可以改成任意起始年,比如 1990
|
|
|
const years = []
|
|
|
for (let y = currentYear; y >= startYear; y--) {
|
|
|
years.push(y)
|
|
|
}
|
|
|
- return years // [2026, 2025, ..., 2000]
|
|
|
+ return years //
|
|
|
})
|
|
|
|
|
|
const calendarData = ref({})
|
|
|
@@ -23,12 +26,25 @@ const calendarData = ref({})
|
|
|
const getDataByDate = (date: Dayjs, key: string) => {
|
|
|
return calendarData.value[date.format('YYYY-MM-DD')]?.[key] ?? 0
|
|
|
}
|
|
|
+
|
|
|
+const emit = defineEmits(['add'])
|
|
|
+const calendarLoading = ref(false)
|
|
|
+const handleAddClick = (date) => {
|
|
|
+ emit('add', dayjs(date).format('YYYY-MM-DD'))
|
|
|
+}
|
|
|
+
|
|
|
const getPageData = () => {
|
|
|
- $api.getDeliveryCalendarData({ month: dayjs().format('MM/YYYY') }).then((res) => {
|
|
|
- if (res.code === 200) {
|
|
|
- calendarData.value = res.data
|
|
|
- }
|
|
|
- })
|
|
|
+ calendarLoading.value = true
|
|
|
+ $api
|
|
|
+ .getDeliveryCalendarData({ month: dayjs().format('MM/YYYY') })
|
|
|
+ .then((res) => {
|
|
|
+ if (res.code === 200) {
|
|
|
+ calendarData.value = res.data
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .finally(() => {
|
|
|
+ calendarLoading.value = false
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
onMounted(() => {
|
|
|
@@ -41,13 +57,6 @@ const onPanelChange = (value: Dayjs) => {
|
|
|
displayMonth.value = value
|
|
|
}
|
|
|
|
|
|
-// 可选:处理日期点击(比如查看详情)
|
|
|
-const onSelect = (date: Dayjs) => {
|
|
|
- console.log('选中日期:', date.format('YYYY-MM-DD'))
|
|
|
- // 你可以在这里打开详情弹窗等
|
|
|
-}
|
|
|
-
|
|
|
-// 年份切换
|
|
|
const handleYearChange = (year: number, onChange: (date: Dayjs) => void) => {
|
|
|
const newDate = displayMonth.value.clone().year(year)
|
|
|
onChange(newDate)
|
|
|
@@ -62,6 +71,7 @@ const handleMonthChange = (month: number, onChange: (date: Dayjs) => void) => {
|
|
|
}
|
|
|
|
|
|
const calendarTagDialog = ref()
|
|
|
+
|
|
|
const handleTagClick = (type, date) => {
|
|
|
calendarTagDialog.value.openDialog(type, date, calendarData.value[date.format('YYYY-MM-DD')])
|
|
|
}
|
|
|
@@ -70,7 +80,12 @@ const handleTagClick = (type, date) => {
|
|
|
<template>
|
|
|
<div class="calendar-container">
|
|
|
<!-- 👇 绑定 :value + 监听 @panelChange -->
|
|
|
- <a-calendar :value="displayMonth" fullscreen @select="onSelect" @panelChange="onPanelChange">
|
|
|
+ <a-calendar
|
|
|
+ :value="displayMonth"
|
|
|
+ v-vloading="calendarLoading"
|
|
|
+ fullscreen
|
|
|
+ @panelChange="onPanelChange"
|
|
|
+ >
|
|
|
<!-- 自定义头部:value 来自 displayMonth(已同步) -->
|
|
|
<template #headerRender="{ value, onChange }">
|
|
|
<div class="custom-header">
|
|
|
@@ -93,7 +108,7 @@ const handleTagClick = (type, date) => {
|
|
|
@change="(year) => handleYearChange(year, onChange)"
|
|
|
>
|
|
|
<a-select-option v-for="y in yearOptions" :key="y" :value="y">
|
|
|
- {{ y }}年
|
|
|
+ {{ y }}
|
|
|
</a-select-option>
|
|
|
</a-select>
|
|
|
|
|
|
@@ -134,7 +149,11 @@ const handleTagClick = (type, date) => {
|
|
|
dayjs(current).isSame(dayjs(displayMonth), 'month')
|
|
|
"
|
|
|
>
|
|
|
- <div class="ending-tag tag-style" @click="handleTagClick('ending', current)">
|
|
|
+ <div
|
|
|
+ v-if="getDataByDate(current, 'endingNumber') || getDataByDate(current, 'endingCtns')"
|
|
|
+ class="ending-tag tag-style"
|
|
|
+ @click="handleTagClick('ending', current)"
|
|
|
+ >
|
|
|
<span
|
|
|
class="font_family icon-icon_delay_b1"
|
|
|
style="margin-right: 3px; font-size: 13px"
|
|
|
@@ -142,7 +161,13 @@ const handleTagClick = (type, date) => {
|
|
|
<span class="type">{{ getDataByDate(current, 'endingNumber') }} Ending</span>
|
|
|
<span class="ctns-tag">{{ getDataByDate(current, 'endingCtns') }} ctns</span>
|
|
|
</div>
|
|
|
- <div class="delivery-tag" @click="handleTagClick('delivery', current)">
|
|
|
+ <div
|
|
|
+ v-if="
|
|
|
+ getDataByDate(current, 'shipmentNumber') || getDataByDate(current, 'shipmentCtns')
|
|
|
+ "
|
|
|
+ class="delivery-tag"
|
|
|
+ @click="handleTagClick('delivery', current)"
|
|
|
+ >
|
|
|
<div class="label">Recommended Delivery</div>
|
|
|
<div class="tag-style">
|
|
|
<span class="font_family icon-icon_road__booking_b" style="font-size: 12px"></span>
|
|
|
@@ -150,7 +175,12 @@ const handleTagClick = (type, date) => {
|
|
|
<span class="ctns-tag">{{ getDataByDate(current, 'shipmentCtns') }} ctns</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div class="booking-tag">
|
|
|
+ <div
|
|
|
+ class="booking-tag"
|
|
|
+ v-if="
|
|
|
+ getDataByDate(current, 'bookingNumber') || getDataByDate(current, 'bookingCtns')
|
|
|
+ "
|
|
|
+ >
|
|
|
<div class="label">Destination Booking</div>
|
|
|
<div class="tag-style">
|
|
|
<span class="font_family icon-icon_booking_order_b" style="font-size: 12px"></span>
|
|
|
@@ -159,6 +189,14 @@ const handleTagClick = (type, date) => {
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
+ <!-- 新增图标 -->
|
|
|
+ <div
|
|
|
+ class="add-icon"
|
|
|
+ @click.stop="handleAddClick(current)"
|
|
|
+ v-if="userStore.userInfo.user_type.toLowerCase() !== 'employee'"
|
|
|
+ >
|
|
|
+ <span class="font_family icon-icon_add_b"></span>
|
|
|
+ </div>
|
|
|
</ul>
|
|
|
</template>
|
|
|
</a-calendar>
|
|
|
@@ -167,8 +205,9 @@ const handleTagClick = (type, date) => {
|
|
|
</template>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
-/* ... 你的深色样式保持不变 ... */
|
|
|
.calendar-container {
|
|
|
+ // position: relative;
|
|
|
+ // z-index: 99;
|
|
|
margin-top: -46px;
|
|
|
padding: 0 24px;
|
|
|
}
|
|
|
@@ -211,8 +250,8 @@ const handleTagClick = (type, date) => {
|
|
|
.free-storage-period-ends {
|
|
|
margin-right: 8px;
|
|
|
.sign {
|
|
|
- background-color: var(--color-delivery-calendar-ends-sign-bg);
|
|
|
- border: 1px dashed var(--color-delivery-calendar-ends-sign-border);
|
|
|
+ background-color: var(--color-calendar-ending-tag-bg);
|
|
|
+ border: 1px dashed var(--color-calendar-ending-tag-border);
|
|
|
}
|
|
|
.label {
|
|
|
color: var(--color-delivery-calendar-ends-label-text);
|
|
|
@@ -295,10 +334,14 @@ const handleTagClick = (type, date) => {
|
|
|
:deep(.ant-picker-calendar-date-selected),
|
|
|
:deep(.ant-picker-cell-selected .ant-picker-calendar-date) {
|
|
|
background: transparent !important;
|
|
|
- color: #e0e0e0 !important;
|
|
|
+ color: var(--color-neutral-1) !important;
|
|
|
box-shadow: none !important;
|
|
|
}
|
|
|
-
|
|
|
+:deep(td.ant-picker-cell-selected) {
|
|
|
+ &:hover {
|
|
|
+ background: var(--color-calendar-selected-cell-bg) !important;
|
|
|
+ }
|
|
|
+}
|
|
|
// 不是当月日期时的样式
|
|
|
:deep(
|
|
|
td.ant-picker-cell:not(.ant-picker-cell-in-view):not(.custom-delivery-calendar .ant-picker-cell)
|
|
|
@@ -329,14 +372,43 @@ const handleTagClick = (type, date) => {
|
|
|
}
|
|
|
|
|
|
.events {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: flex-end;
|
|
|
list-style: none;
|
|
|
margin: 0;
|
|
|
padding: 0;
|
|
|
+ padding-bottom: 6px;
|
|
|
height: 110px;
|
|
|
overflow-y: auto;
|
|
|
font-size: 12px;
|
|
|
}
|
|
|
|
|
|
+.add-icon {
|
|
|
+ position: absolute;
|
|
|
+ top: 8px;
|
|
|
+ right: 8px;
|
|
|
+ background-color: var(--color-theme);
|
|
|
+ border-radius: 50%;
|
|
|
+ width: 16px;
|
|
|
+ height: 16px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ opacity: 0;
|
|
|
+ transition: opacity 0.3s ease;
|
|
|
+
|
|
|
+ .font_family {
|
|
|
+ display: inline-block;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #fff !important;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.ant-picker-cell-in-view:hover .add-icon {
|
|
|
+ opacity: 1;
|
|
|
+}
|
|
|
+
|
|
|
.events .tags-details {
|
|
|
display: flex;
|
|
|
align-items: center;
|