|
@@ -4,6 +4,8 @@ import type { Dayjs } from 'dayjs'
|
|
|
import dayjs from 'dayjs'
|
|
import dayjs from 'dayjs'
|
|
|
import CalendarTagDetailDialog from './CalendarTagDetailDialog.vue'
|
|
import CalendarTagDetailDialog from './CalendarTagDetailDialog.vue'
|
|
|
import { useUserStore } from '@/stores/modules/user'
|
|
import { useUserStore } from '@/stores/modules/user'
|
|
|
|
|
+import { cloneDeep, debounce } from 'lodash'
|
|
|
|
|
+import axios from 'axios'
|
|
|
|
|
|
|
|
const userStore = useUserStore()
|
|
const userStore = useUserStore()
|
|
|
|
|
|
|
@@ -22,11 +24,55 @@ const yearOptions = computed(() => {
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
const calendarData = ref({})
|
|
const calendarData = ref({})
|
|
|
|
|
+const consigneeValue = ref('')
|
|
|
|
|
+const consigneeLoading = ref(false)
|
|
|
|
|
+const consignessList = ref([])
|
|
|
|
|
|
|
|
const getDataByDate = (date: Dayjs, key: string) => {
|
|
const getDataByDate = (date: Dayjs, key: string) => {
|
|
|
- return calendarData.value[date.format('YYYY-MM-DD')]?.[key] ?? 0
|
|
|
|
|
|
|
+ return calendarData.value?.[date.format('YYYY-MM-DD')]?.[key] ?? 0
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+const remoteMethod = (query: string) => {
|
|
|
|
|
+ currentController.value?.abort()
|
|
|
|
|
+
|
|
|
|
|
+ const newController = new AbortController()
|
|
|
|
|
+ currentController.value = newController
|
|
|
|
|
+ consigneeLoading.value = true
|
|
|
|
|
+
|
|
|
|
|
+ $api
|
|
|
|
|
+ .getDeliveryCalendarConsignee(
|
|
|
|
|
+ {
|
|
|
|
|
+ month: dayjs(displayMonth.value).format('MM/YYYY'),
|
|
|
|
|
+ consignee: query
|
|
|
|
|
+ },
|
|
|
|
|
+ { signal: newController.signal }
|
|
|
|
|
+ )
|
|
|
|
|
+ .then((res) => {
|
|
|
|
|
+ if (!newController.signal.aborted && res.code === 200) {
|
|
|
|
|
+ consignessList.value = res.data || []
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ .catch((err) => {
|
|
|
|
|
+ consignessList.value = []
|
|
|
|
|
+ if (!axios.isCancel(err) && !newController.signal.aborted) {
|
|
|
|
|
+ ElMessage.error('Failed to load options')
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ .finally(() => {
|
|
|
|
|
+ // 仅当这是最新请求时,才关闭 loading
|
|
|
|
|
+ if (currentController.value === newController) {
|
|
|
|
|
+ consigneeLoading.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const debouncedRemoteMethod = debounce(remoteMethod, 200)
|
|
|
|
|
+const handleVisibleChange = (visible) => {
|
|
|
|
|
+ !visible && (consignessList.value = [])
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const currentController = ref<AbortController | null>(null)
|
|
|
|
|
+
|
|
|
const emit = defineEmits(['add', 'jumpListPage'])
|
|
const emit = defineEmits(['add', 'jumpListPage'])
|
|
|
const calendarLoading = ref(false)
|
|
const calendarLoading = ref(false)
|
|
|
const handleAddClick = (date) => {
|
|
const handleAddClick = (date) => {
|
|
@@ -80,6 +126,16 @@ const handleTagClick = (type, date) => {
|
|
|
const jumpListPage = (date) => {
|
|
const jumpListPage = (date) => {
|
|
|
emit('jumpListPage', date.format('YYYY-MM-DD'))
|
|
emit('jumpListPage', date.format('YYYY-MM-DD'))
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+const test = () => {
|
|
|
|
|
+ ElMessageBox.alert(
|
|
|
|
|
+ "This account's password has expired and is currently unavailable. Please select a different customer account to continue.",
|
|
|
|
|
+ {
|
|
|
|
|
+ confirmButtonText: 'OK',
|
|
|
|
|
+ confirmButtonClass: 'el-button--dark'
|
|
|
|
|
+ }
|
|
|
|
|
+ )
|
|
|
|
|
+}
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<template>
|
|
<template>
|
|
@@ -94,7 +150,7 @@ const jumpListPage = (date) => {
|
|
|
<!-- 自定义头部:value 来自 displayMonth(已同步) -->
|
|
<!-- 自定义头部:value 来自 displayMonth(已同步) -->
|
|
|
<template #headerRender="{ value, onChange }">
|
|
<template #headerRender="{ value, onChange }">
|
|
|
<div class="custom-header">
|
|
<div class="custom-header">
|
|
|
- <div class="label-type destination-booking">
|
|
|
|
|
|
|
+ <!-- <div class="label-type destination-booking">
|
|
|
<div class="sign"></div>
|
|
<div class="sign"></div>
|
|
|
<div class="label">Destination Booking</div>
|
|
<div class="label">Destination Booking</div>
|
|
|
</div>
|
|
</div>
|
|
@@ -106,20 +162,26 @@ const jumpListPage = (date) => {
|
|
|
<div class="sign"></div>
|
|
<div class="sign"></div>
|
|
|
<div class="label">Free Storage Period Ends</div>
|
|
<div class="label">Free Storage Period Ends</div>
|
|
|
</div>
|
|
</div>
|
|
|
- <div class="grid-lines"></div>
|
|
|
|
|
|
|
+ <div class="grid-lines"></div> -->
|
|
|
<a-select
|
|
<a-select
|
|
|
|
|
+ :bordered="false"
|
|
|
:value="value.year()"
|
|
:value="value.year()"
|
|
|
- style="width: 180px; margin-right: 8px"
|
|
|
|
|
|
|
+ style="width: 140px"
|
|
|
@change="(year) => handleYearChange(year, onChange)"
|
|
@change="(year) => handleYearChange(year, onChange)"
|
|
|
>
|
|
>
|
|
|
<a-select-option v-for="y in yearOptions" :key="y" :value="y">
|
|
<a-select-option v-for="y in yearOptions" :key="y" :value="y">
|
|
|
{{ y }}
|
|
{{ y }}
|
|
|
</a-select-option>
|
|
</a-select-option>
|
|
|
|
|
+ <template #suffixIcon>
|
|
|
|
|
+ <!-- 这里可以使用任何图标组件,包括 Element Plus 的 -->
|
|
|
|
|
+ <span class="font_family icon-icon_dropdown_b"></span>
|
|
|
|
|
+ </template>
|
|
|
</a-select>
|
|
</a-select>
|
|
|
|
|
|
|
|
<a-select
|
|
<a-select
|
|
|
|
|
+ :bordered="false"
|
|
|
:value="value.month() + 1"
|
|
:value="value.month() + 1"
|
|
|
- style="width: 80px"
|
|
|
|
|
|
|
+ style="width: 92px"
|
|
|
@change="(month) => handleMonthChange(month, onChange)"
|
|
@change="(month) => handleMonthChange(month, onChange)"
|
|
|
>
|
|
>
|
|
|
<a-select-option v-for="m in 12" :key="m" :value="m">
|
|
<a-select-option v-for="m in 12" :key="m" :value="m">
|
|
@@ -140,21 +202,45 @@ const jumpListPage = (date) => {
|
|
|
][m - 1]
|
|
][m - 1]
|
|
|
}}
|
|
}}
|
|
|
</a-select-option>
|
|
</a-select-option>
|
|
|
|
|
+ <template #suffixIcon>
|
|
|
|
|
+ <!-- 这里可以使用任何图标组件,包括 Element Plus 的 -->
|
|
|
|
|
+ <span class="font_family icon-icon_dropdown_b"></span>
|
|
|
|
|
+ </template>
|
|
|
</a-select>
|
|
</a-select>
|
|
|
|
|
+ <div class="grid-lines"></div>
|
|
|
|
|
+
|
|
|
|
|
+ <el-select
|
|
|
|
|
+ :model-value="consigneeValue"
|
|
|
|
|
+ multiple
|
|
|
|
|
+ filterable
|
|
|
|
|
+ reserve-keyword
|
|
|
|
|
+ placeholder="Consignee"
|
|
|
|
|
+ :loading="consigneeLoading"
|
|
|
|
|
+ style="width: 240px"
|
|
|
|
|
+ popper-class="part-id-select-popper"
|
|
|
|
|
+ :filter-method="debouncedRemoteMethod"
|
|
|
|
|
+ @visible-change="handleVisibleChange"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-option
|
|
|
|
|
+ v-for="item in consignessList"
|
|
|
|
|
+ :key="item.value"
|
|
|
|
|
+ :label="item.value"
|
|
|
|
|
+ :value="item.value"
|
|
|
|
|
+ >
|
|
|
|
|
+ </el-option>
|
|
|
|
|
+ </el-select>
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<template #dateCellRender="{ current }">
|
|
<template #dateCellRender="{ current }">
|
|
|
<ul class="events">
|
|
<ul class="events">
|
|
|
<!-- 如果不为当前月份的日期,则不显示标签 -->
|
|
<!-- 如果不为当前月份的日期,则不显示标签 -->
|
|
|
- <div
|
|
|
|
|
- class="tags-details"
|
|
|
|
|
- v-if="
|
|
|
|
|
|
|
+ <!-- v-if="
|
|
|
calendarData?.[dayjs(current).format('YYYY-MM-DD')] &&
|
|
calendarData?.[dayjs(current).format('YYYY-MM-DD')] &&
|
|
|
dayjs(current).isSame(dayjs(displayMonth), 'month')
|
|
dayjs(current).isSame(dayjs(displayMonth), 'month')
|
|
|
- "
|
|
|
|
|
- >
|
|
|
|
|
- <div
|
|
|
|
|
|
|
+ " -->
|
|
|
|
|
+ <div class="tags-details">
|
|
|
|
|
+ <!-- <div
|
|
|
v-if="getDataByDate(current, 'endingNumber') || getDataByDate(current, 'endingCtns')"
|
|
v-if="getDataByDate(current, 'endingNumber') || getDataByDate(current, 'endingCtns')"
|
|
|
class="ending-tag tag-style"
|
|
class="ending-tag tag-style"
|
|
|
@click="handleTagClick('ending', current)"
|
|
@click="handleTagClick('ending', current)"
|
|
@@ -179,20 +265,27 @@ const jumpListPage = (date) => {
|
|
|
<span class="type">{{ getDataByDate(current, 'shipmentNumber') }} Shipments</span>
|
|
<span class="type">{{ getDataByDate(current, 'shipmentNumber') }} Shipments</span>
|
|
|
<span class="ctns-tag">{{ getDataByDate(current, 'shipmentCtns') }} ctns</span>
|
|
<span class="ctns-tag">{{ getDataByDate(current, 'shipmentCtns') }} ctns</span>
|
|
|
</div>
|
|
</div>
|
|
|
- </div>
|
|
|
|
|
|
|
+ </div> -->
|
|
|
|
|
+
|
|
|
<div
|
|
<div
|
|
|
- class="booking-tag"
|
|
|
|
|
v-if="
|
|
v-if="
|
|
|
getDataByDate(current, 'bookingNumber') || getDataByDate(current, 'bookingCtns')
|
|
getDataByDate(current, 'bookingNumber') || getDataByDate(current, 'bookingCtns')
|
|
|
"
|
|
"
|
|
|
|
|
+ class="booking-tag"
|
|
|
@click="jumpListPage(current)"
|
|
@click="jumpListPage(current)"
|
|
|
>
|
|
>
|
|
|
- <div class="label">Destination Booking</div>
|
|
|
|
|
|
|
+ <!-- <div class="label">Destination Booking</div> -->
|
|
|
<div class="tag-style">
|
|
<div class="tag-style">
|
|
|
<span class="font_family icon-icon_booking_order_b" style="font-size: 12px"></span>
|
|
<span class="font_family icon-icon_booking_order_b" style="font-size: 12px"></span>
|
|
|
<span class="type">{{ getDataByDate(current, 'bookingNumber') }} Bookings</span>
|
|
<span class="type">{{ getDataByDate(current, 'bookingNumber') }} Bookings</span>
|
|
|
|
|
+ <div class="grid-lines"></div>
|
|
|
<span class="ctns-tag">{{ getDataByDate(current, 'bookingCtns') }} ctns</span>
|
|
<span class="ctns-tag">{{ getDataByDate(current, 'bookingCtns') }} ctns</span>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
+ <div class="list">
|
|
|
|
|
+ <div class="item" v-for="size in getDataByDate(current, 'ctnrSize')">
|
|
|
|
|
+ {{ size }}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
<!-- 新增图标 -->
|
|
<!-- 新增图标 -->
|
|
@@ -212,8 +305,6 @@ const jumpListPage = (date) => {
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
<style scoped lang="scss">
|
|
|
.calendar-container {
|
|
.calendar-container {
|
|
|
- // position: relative;
|
|
|
|
|
- // z-index: 99;
|
|
|
|
|
margin-top: -46px;
|
|
margin-top: -46px;
|
|
|
padding: 0 24px;
|
|
padding: 0 24px;
|
|
|
}
|
|
}
|
|
@@ -223,6 +314,20 @@ const jumpListPage = (date) => {
|
|
|
justify-content: flex-end;
|
|
justify-content: flex-end;
|
|
|
align-items: center;
|
|
align-items: center;
|
|
|
padding: 2px 0;
|
|
padding: 2px 0;
|
|
|
|
|
+ :deep(.ant-select-selection-item) {
|
|
|
|
|
+ margin-right: 4px;
|
|
|
|
|
+ font-size: 24px;
|
|
|
|
|
+ font-weight: 700;
|
|
|
|
|
+ text-align: right;
|
|
|
|
|
+ }
|
|
|
|
|
+ :deep(
|
|
|
|
|
+ .ant-select-focused.ant-select:not(.ant-select-disabled):not(.ant-select-customize-input):not(
|
|
|
|
|
+ .ant-pagination-size-changer
|
|
|
|
|
+ )
|
|
|
|
|
+ div.ant-select-selector
|
|
|
|
|
+ ) {
|
|
|
|
|
+ border: 1px solid transparent !important;
|
|
|
|
|
+ }
|
|
|
.label-type {
|
|
.label-type {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
align-items: center;
|
|
align-items: center;
|
|
@@ -456,7 +561,7 @@ const jumpListPage = (date) => {
|
|
|
}
|
|
}
|
|
|
.delivery-tag,
|
|
.delivery-tag,
|
|
|
.booking-tag {
|
|
.booking-tag {
|
|
|
- height: 36px;
|
|
|
|
|
|
|
+ // height: 36px;
|
|
|
width: 100%;
|
|
width: 100%;
|
|
|
padding-top: 4px;
|
|
padding-top: 4px;
|
|
|
border-radius: 3px;
|
|
border-radius: 3px;
|
|
@@ -498,6 +603,32 @@ const jumpListPage = (date) => {
|
|
|
.ctns-tag {
|
|
.ctns-tag {
|
|
|
background-color: var(--color-calendar-booking-tag-bg);
|
|
background-color: var(--color-calendar-booking-tag-bg);
|
|
|
}
|
|
}
|
|
|
|
|
+ .grid-lines {
|
|
|
|
|
+ height: 12px;
|
|
|
|
|
+ width: 1px;
|
|
|
|
|
+ margin-left: 6px;
|
|
|
|
|
+ background-color: var(--color-calendar-booking-tag-label-text);
|
|
|
|
|
+ }
|
|
|
|
|
+ .list {
|
|
|
|
|
+ padding: 6px 8px 8px;
|
|
|
|
|
+ .item {
|
|
|
|
|
+ height: 12px;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ padding: 2px 4px;
|
|
|
|
|
+ margin-top: 1px;
|
|
|
|
|
+ font-size: 8px;
|
|
|
|
|
+ line-height: 10px;
|
|
|
|
|
+ background-color: var(--color-calendar-booking-tag-item-bg);
|
|
|
|
|
+ // background-color: red;
|
|
|
|
|
+ &:first-child {
|
|
|
|
|
+ margin-top: 0;
|
|
|
|
|
+ border-radius: 3px 3px 0 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ &:last-child {
|
|
|
|
|
+ border-radius: 0 0 3px 3px;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
.ending-tag {
|
|
.ending-tag {
|
|
|
height: 24px;
|
|
height: 24px;
|