Commit 336d59a8 by wusiyi

feat: POD订单(CN)新增收件国家筛选 #1002558

parent 70742842
...@@ -27,11 +27,17 @@ export interface statisticData { ...@@ -27,11 +27,17 @@ export interface statisticData {
outOfStockSkuNum: number outOfStockSkuNum: number
outOfStockProductNum: number outOfStockProductNum: number
yesterdayOverTimeShipmentOrderNum: number yesterdayOverTimeShipmentOrderNum: number
notShipmentProductNum: number
overTimeNotShipmentProductNum: number
yesterdayShipmentProductNum: number
} }
export interface trendType { export interface trendType {
confirmNum: number // 接单数 confirmNum: number // 接单数
produceNum: number // 生产数 produceNum: number // 生产数
shipmentNum: number // 发货数 shipmentNum: number // 发货数
confirmProductNum?: number // 新接数(件)
producedProductNum?: number // 生产数(件)
shipmentProductNum?: number // 发货数(件)
shipmentRateOf24Hour: number // 24小时发货率 shipmentRateOf24Hour: number // 24小时发货率
shipmentRateOf48Hour: number // 48小时发货率 shipmentRateOf48Hour: number // 48小时发货率
overtimeShipmentRate: number // 超48小时发货率 overtimeShipmentRate: number // 超48小时发货率
......
...@@ -50,11 +50,11 @@ ...@@ -50,11 +50,11 @@
</div> </div>
<div class="card-item"> <div class="card-item">
<div class="card-item-header"> <div class="card-item-header">
<div class="card-title">未发货订单(订单)</div> <div class="card-title">未发货订单(件/订单)</div>
<el-tooltip <el-tooltip
class="item" class="item"
effect="light" effect="light"
content="目前确认生产后还未转为已发货状态的总订单数" content="目前确认生产后还未转为已发货状态的总件数/总订单数"
placement="bottom" placement="bottom"
> >
<div class="card-icon"></div> <div class="card-icon"></div>
...@@ -62,17 +62,21 @@ ...@@ -62,17 +62,21 @@
</div> </div>
<div class="card-item-content-box"> <div class="card-item-content-box">
<div v-auto-fit-text class="card-item-content text-blue"> <div v-auto-fit-text class="card-item-content text-blue">
{{ statisticData?.notShipmentOrderNum ?? '-' }} {{
(statisticData?.notShipmentProductNum ?? '-') +
'/' +
(statisticData?.notShipmentOrderNum ?? '-')
}}
</div> </div>
</div> </div>
</div> </div>
<div class="card-item"> <div class="card-item">
<div class="card-item-header"> <div class="card-item-header">
<div class="card-title">超时未发订单(订单)</div> <div class="card-title">超时未发订单(件/订单)</div>
<el-tooltip <el-tooltip
class="item" class="item"
effect="light" effect="light"
content="目前确认生产后超过48H还未转为已发货状态的总订单数" content="目前确认生产后超过48H还未转为已发货状态的总件数/总订单数"
placement="bottom" placement="bottom"
> >
<div class="card-icon"></div> <div class="card-icon"></div>
...@@ -80,7 +84,11 @@ ...@@ -80,7 +84,11 @@
</div> </div>
<div class="card-item-content-box"> <div class="card-item-content-box">
<div v-auto-fit-text class="card-item-content text-red"> <div v-auto-fit-text class="card-item-content text-red">
{{ statisticData?.overTimeNotShipmentOrderNum ?? '-' }} {{
(statisticData?.overTimeNotShipmentProductNum ?? '-') +
'/' +
(statisticData?.overTimeNotShipmentOrderNum ?? '-')
}}
</div> </div>
</div> </div>
</div> </div>
...@@ -97,11 +105,11 @@ ...@@ -97,11 +105,11 @@
</template> </template>
<div class="card-item"> <div class="card-item">
<div class="card-item-header"> <div class="card-item-header">
<div class="card-title">昨日发货数(订单)</div> <div class="card-title">昨日发货数(件/订单)</div>
<el-tooltip <el-tooltip
class="item" class="item"
effect="light" effect="light"
:content="`昨日转为已发货状态的总订单数(${yesterday}北京时间 0-24点数据)`" :content="`昨日转为已发货状态的总件数/总订单数(${yesterday}北京时间 0-24点数据)`"
placement="bottom" placement="bottom"
> >
<div class="card-icon"></div> <div class="card-icon"></div>
...@@ -109,7 +117,11 @@ ...@@ -109,7 +117,11 @@
</div> </div>
<div class="card-item-content-box"> <div class="card-item-content-box">
<div v-auto-fit-text class="card-item-content text-blue"> <div v-auto-fit-text class="card-item-content text-blue">
{{ statisticData?.yesterdayShipmentOrderNum ?? '-' }} {{
(statisticData?.yesterdayShipmentProductNum ?? '-') +
'/' +
(statisticData?.yesterdayShipmentOrderNum ?? '-')
}}
</div> </div>
<div class="card-item-content-text"> <div class="card-item-content-text">
较前天 较前天
...@@ -121,7 +133,11 @@ ...@@ -121,7 +133,11 @@
style="display: flex; margin-left: 10px" style="display: flex; margin-left: 10px"
> >
<div class="text-green"> <div class="text-green">
{{ statisticData?.compareYesterdayShipmentOrderNum }} {{
(statisticData?.compareYesterdayShipmentOrderNum).toFixed(
0,
) + '单'
}}
</div> </div>
<div class="up-icon-green"></div> <div class="up-icon-green"></div>
</div> </div>
...@@ -130,7 +146,7 @@ ...@@ -130,7 +146,7 @@
{{ {{
Math.abs( Math.abs(
statisticData?.compareYesterdayShipmentOrderNum || 0, statisticData?.compareYesterdayShipmentOrderNum || 0,
) ).toFixed(0) + '单'
}} }}
</div> </div>
<div class="down-icon-red"></div> <div class="down-icon-red"></div>
...@@ -541,27 +557,51 @@ ...@@ -541,27 +557,51 @@
</div> </div>
</div> </div>
</div> </div>
<div class="chart-wrapper" style="width: 100%"> <div class="charts-row" style="width: 100%">
<el-radio-group <div class="chart-wrapper chart-half">
v-model="chartTimes1" <el-radio-group
size="small" v-model="chartTimes4"
class="chart-controls" size="small"
@change="getchartTimes($event, 'ORDER_TREND')" class="chart-controls"
> @change="getchartTimes($event, 'PRODUCT_TREND')"
<el-radio-button >
v-for="time in timeOptions" <el-radio-button
:key="time.type" v-for="time in timeOptions"
:value="time.type" :key="time.type"
:label="time.name" :value="time.type"
:label="time.name"
>
</el-radio-button>
</el-radio-group>
<div
ref="orderChart4"
v-loading="orderChart4Loading"
class="chart-container"
style="width: 100%"
/>
</div>
<div class="chart-wrapper chart-half">
<el-radio-group
v-model="chartTimes1"
size="small"
class="chart-controls"
@change="getchartTimes($event, 'ORDER_TREND')"
> >
</el-radio-button> <el-radio-button
</el-radio-group> v-for="time in timeOptions"
<div :key="time.type"
ref="orderChart1" :value="time.type"
v-loading="orderChart1Loading" :label="time.name"
class="chart-container" >
style="width: 100%" </el-radio-button>
/> </el-radio-group>
<div
ref="orderChart1"
v-loading="orderChart1Loading"
class="chart-container"
style="width: 100%"
/>
</div>
</div> </div>
<div class="charts-row"> <div class="charts-row">
<div class="chart-wrapper chart-half"> <div class="chart-wrapper chart-half">
...@@ -662,6 +702,7 @@ const statisticData = ref<StatisticData | null>(null) ...@@ -662,6 +702,7 @@ const statisticData = ref<StatisticData | null>(null)
const orderChart1Loading = ref<boolean>(true) const orderChart1Loading = ref<boolean>(true)
const orderChart2Loading = ref<boolean>(true) const orderChart2Loading = ref<boolean>(true)
const orderChart3Loading = ref<boolean>(true) const orderChart3Loading = ref<boolean>(true)
const orderChart4Loading = ref<boolean>(true)
const timeOptions = ref<{ type: string; name: string }[]>([ const timeOptions = ref<{ type: string; name: string }[]>([
{ type: '0', name: '日数据' }, { type: '0', name: '日数据' },
...@@ -672,14 +713,16 @@ const timeOptions = ref<{ type: string; name: string }[]>([ ...@@ -672,14 +713,16 @@ const timeOptions = ref<{ type: string; name: string }[]>([
const chartTimes1 = ref<string>('0') const chartTimes1 = ref<string>('0')
const chartTimes2 = ref<string>('0') const chartTimes2 = ref<string>('0')
const chartTimes3 = ref<string>('0') const chartTimes3 = ref<string>('0')
const chartTimes4 = ref<string>('0')
// 图表容器引用 // 图表容器引用
const orderChart1 = ref<HTMLDivElement | null>(null) const orderChart1 = ref<HTMLDivElement | null>(null)
const orderChart2 = ref<HTMLDivElement | null>(null) const orderChart2 = ref<HTMLDivElement | null>(null)
const orderChart3 = ref<HTMLDivElement | null>(null) const orderChart3 = ref<HTMLDivElement | null>(null)
const orderChart4 = ref<HTMLDivElement | null>(null)
// 图表实例数组 // 图表实例数组
const chartInstances: (echarts.ECharts | null)[] = [null, null, null] const chartInstances: (echarts.ECharts | null)[] = [null, null, null, null]
type ChartSeriesItem = { type ChartSeriesItem = {
name: string name: string
...@@ -750,6 +793,29 @@ const chartConfig3 = ref<ChartConfig>({ ...@@ -750,6 +793,29 @@ const chartConfig3 = ref<ChartConfig>({
], ],
}) })
const chartConfig4 = ref<ChartConfig>({
title: '订单趋势统计(件)',
legend: ['新接数', '生产数', '发货数'],
xAxisData: [''],
series: [
{
name: '新接数',
data: [0],
color: '#30d2cb',
},
{
name: '生产数',
data: [0],
color: '#9e95ff',
},
{
name: '发货数',
data: [0],
color: '#6bb3fd',
},
],
})
const overtimeTooltipFormatter = (params: TooltipParam[]) => const overtimeTooltipFormatter = (params: TooltipParam[]) =>
params params
.map((item) => { .map((item) => {
...@@ -1045,11 +1111,35 @@ const getStatisticDataApi = async () => { ...@@ -1045,11 +1111,35 @@ const getStatisticDataApi = async () => {
.catch((error) => { .catch((error) => {
console.error('获取超时发货趋势数据失败:', error) console.error('获取超时发货趋势数据失败:', error)
}) })
// 订单趋势统计(件)
trendApi({
timeUnit: 0,
trendType: 'PRODUCT_TREND',
})
.then((res) => {
if (res.code === 200) {
const isEmpty = checkProductNumTrendDataEmpty(res.data)
// 无论数据是否为空,都要更新 x 轴数据
updateProductNumTrendChart(res.data, 0)
updateChart(
chartInstances[3],
chartConfig4,
isEmpty,
false,
chartTimes4.value,
)
orderChart4Loading.value = !(res.data && res.data.length > 0)
}
})
.catch((error) => {
console.error('获取订单趋势(件)数据失败:', error)
})
} }
onMounted(async () => { onMounted(async () => {
await nextTick() await nextTick()
// 订单趋势统计 // 订单趋势统计(单)
if (orderChart1.value) { if (orderChart1.value) {
chartInstances[0] = echarts.init(orderChart1.value) chartInstances[0] = echarts.init(orderChart1.value)
chartInstances[0]?.setOption(createChartOption(chartConfig1)) chartInstances[0]?.setOption(createChartOption(chartConfig1))
...@@ -1066,6 +1156,11 @@ onMounted(async () => { ...@@ -1066,6 +1156,11 @@ onMounted(async () => {
createChartOption(chartConfig3, true, overtimeTooltipFormatter), createChartOption(chartConfig3, true, overtimeTooltipFormatter),
) )
} }
// 订单趋势统计(件)
if (orderChart4.value) {
chartInstances[3] = echarts.init(orderChart4.value)
chartInstances[3]?.setOption(createChartOption(chartConfig4))
}
// 请求成功后立即更新对应的图表 // 请求成功后立即更新对应的图表
getStatisticDataApi() getStatisticDataApi()
// 监听窗口大小变化,自动调整图表大小 // 监听窗口大小变化,自动调整图表大小
...@@ -1081,6 +1176,8 @@ const getchartTimes = async (v: string, type: string) => { ...@@ -1081,6 +1176,8 @@ const getchartTimes = async (v: string, type: string) => {
orderChart2Loading.value = true orderChart2Loading.value = true
} else if (type === 'OVERTIME_SHIPMENT_TREND') { } else if (type === 'OVERTIME_SHIPMENT_TREND') {
orderChart3Loading.value = true orderChart3Loading.value = true
} else if (type === 'PRODUCT_TREND') {
orderChart4Loading.value = true
} }
const { data } = await trendApi({ const { data } = await trendApi({
...@@ -1111,6 +1208,18 @@ const getchartTimes = async (v: string, type: string) => { ...@@ -1111,6 +1208,18 @@ const getchartTimes = async (v: string, type: string) => {
chartTimes2.value, chartTimes2.value,
) )
orderChart2Loading.value = !(data && data.length > 0) orderChart2Loading.value = !(data && data.length > 0)
} else if (type == 'PRODUCT_TREND') {
const isEmpty = checkProductNumTrendDataEmpty(data)
// 无论数据是否为空,都要更新 x 轴数据
updateProductNumTrendChart(data, v)
updateChart(
chartInstances[3],
chartConfig4,
isEmpty,
false,
chartTimes4.value,
)
orderChart4Loading.value = !(data && data.length > 0)
} else { } else {
const isEmpty = checkOvertimeTrendDataEmpty(data) const isEmpty = checkOvertimeTrendDataEmpty(data)
// 无论数据是否为空,都要更新 x 轴数据 // 无论数据是否为空,都要更新 x 轴数据
...@@ -1416,6 +1525,40 @@ const updateOvertimeTrendChart = (data: trendType[], type: number | string) => { ...@@ -1416,6 +1525,40 @@ const updateOvertimeTrendChart = (data: trendType[], type: number | string) => {
) )
} }
// 检查订单趋势(件)数据是否为空
const checkProductNumTrendDataEmpty = (data: trendType[]): boolean => {
const confirmProductNums = data.map((el) => el.confirmProductNum ?? 0)
const producedProductNums = data.map((el) => el.producedProductNum ?? 0)
const shipmentProductNums = data.map((el) => el.shipmentProductNum ?? 0)
const hasData =
confirmProductNums.some((item) => item !== 0) ||
producedProductNums.some((item) => item !== 0) ||
shipmentProductNums.some((item) => item !== 0)
return !hasData
}
// 更新订单趋势(件)图表数据
const updateProductNumTrendChart = (
data: trendType[],
type: number | string,
) => {
const confirmProductNums = data.map((el) => el.confirmProductNum ?? 0)
const producedProductNums = data.map((el) => el.producedProductNum ?? 0)
const shipmentProductNums = data.map((el) => el.shipmentProductNum ?? 0)
const startTimes = data.map((el) => el.startTime)
const timerange = data.map((el) => `${el.startTime}——${el.endTime}`)
if (type == 0) {
chartConfig4.value.xAxisData = startTimes
} else {
chartConfig4.value.xAxisData = timerange
}
chartConfig4.value.series[0].data = confirmProductNums
chartConfig4.value.series[1].data = producedProductNums
chartConfig4.value.series[2].data = shipmentProductNums
}
const handleResize = () => { const handleResize = () => {
chartInstances.forEach((instance) => { chartInstances.forEach((instance) => {
instance?.resize() instance?.resize()
......
...@@ -757,19 +757,6 @@ const handleSelectionChange = (val: PodUsOrderListData[]) => { ...@@ -757,19 +757,6 @@ const handleSelectionChange = (val: PodUsOrderListData[]) => {
selection.value = val selection.value = val
} }
// 修改行样式方法
const getRowStyle = ({ row }: { row: PodUsOrderListData }) => {
// 如果行被选中,设置背景色为 #fdf6ec
if (selection.value.some((item) => item.id === row.id)) {
return {
backgroundColor: '#fdf6ec',
}
}
return {
backgroundColor: '',
}
}
// 获取行类名方法 // 获取行类名方法
const getRowClassName = ({ row }: { row: PodUsOrderListData }) => { const getRowClassName = ({ row }: { row: PodUsOrderListData }) => {
return selection.value.some((item) => item.id === row.id) return selection.value.some((item) => item.id === row.id)
...@@ -1156,7 +1143,6 @@ onMounted(() => { ...@@ -1156,7 +1143,6 @@ onMounted(() => {
:serial-numberable="true" :serial-numberable="true"
:selectionable="true" :selectionable="true"
:paginated-data="tableData" :paginated-data="tableData"
:row-style="getRowStyle"
:row-class-name="getRowClassName" :row-class-name="getRowClassName"
@row-click="rowClick" @row-click="rowClick"
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
...@@ -1385,11 +1371,22 @@ onMounted(() => { ...@@ -1385,11 +1371,22 @@ onMounted(() => {
} }
} }
// 确保选中行的背景色在 hover 时也保持 // 设置选中行的背景色
:deep(.el-table__body) { :deep(.el-table__body) {
.el-table__row:hover {
td {
background-color: #e1ebf5 !important;
}
}
.el-table__row.row-selected {
td {
background-color: #faecd8 !important;
}
}
// 确保选中行的背景色在 hover 时也保持
.el-table__row.row-selected:hover { .el-table__row.row-selected:hover {
td { td {
background-color: #fdf6ec !important; background-color: #faecd8 !important;
} }
} }
} }
......
...@@ -772,20 +772,6 @@ const handleSelectionChange = (val: PodCnOrderListData[]) => { ...@@ -772,20 +772,6 @@ const handleSelectionChange = (val: PodCnOrderListData[]) => {
selection.value = val selection.value = val
} }
// 修改行样式方法
const getRowStyle = ({ row }: { row: PodCnOrderListData }) => {
// 如果行被选中,设置背景色为 #fdf6ec
if (selection.value.some((item) => item.id === row.id)) {
return {
backgroundColor: '#fdf6ec',
}
}
return {
backgroundColor: '',
}
}
// 获取行类名方法 // 获取行类名方法
const getRowClassName = ({ row }: { row: PodCnOrderListData }) => { const getRowClassName = ({ row }: { row: PodCnOrderListData }) => {
return selection.value.some((item) => item.id === row.id) return selection.value.some((item) => item.id === row.id)
...@@ -1246,7 +1232,6 @@ onMounted(() => { ...@@ -1246,7 +1232,6 @@ onMounted(() => {
:serial-numberable="true" :serial-numberable="true"
:selectionable="true" :selectionable="true"
:paginated-data="tableData" :paginated-data="tableData"
:row-style="getRowStyle"
:row-class-name="getRowClassName" :row-class-name="getRowClassName"
@row-click="rowClick" @row-click="rowClick"
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
...@@ -1482,11 +1467,22 @@ onMounted(() => { ...@@ -1482,11 +1467,22 @@ onMounted(() => {
} }
} }
// 确保选中行的背景色在 hover 时也保持 // 设置选中行的背景色
:deep(.el-table__body) { :deep(.el-table__body) {
.el-table__row:hover {
td {
background-color: #e1ebf5 !important;
}
}
.el-table__row.row-selected {
td {
background-color: #faecd8 !important;
}
}
// 确保选中行的背景色在 hover 时也保持
.el-table__row.row-selected:hover { .el-table__row.row-selected:hover {
td { td {
background-color: #fdf6ec !important; background-color: #faecd8 !important;
} }
} }
} }
......
...@@ -5524,15 +5524,8 @@ const getRowStyle = ({ row }: { row: PodCnOrderListData }) => { ...@@ -5524,15 +5524,8 @@ const getRowStyle = ({ row }: { row: PodCnOrderListData }) => {
color: '#67c23a', color: '#67c23a',
} }
} }
// 如果行被选中,设置背景色为 #fdf6ec // 选中状态通过 CSS 类名控制,这里不再处理
if (selection.value.some((item) => item.id === row.id)) { return {}
return {
backgroundColor: '#fdf6ec',
}
}
return {
backgroundColor: '',
}
} }
// 获取行类名方法 // 获取行类名方法
...@@ -6541,11 +6534,22 @@ const onUpdateCustomsDeclarationInfo = () => { ...@@ -6541,11 +6534,22 @@ const onUpdateCustomsDeclarationInfo = () => {
} }
} }
// 确保选中行的背景色在 hover 时也保持 // 设置选中行的背景色
:deep(.el-table__body) { :deep(.el-table__body) {
.el-table__row:hover {
td {
background-color: #e1ebf5 !important;
}
}
.el-table__row.row-selected {
td {
background-color: #faecd8 !important;
}
}
// 确保选中行的背景色在 hover 时也保持
.el-table__row.row-selected:hover { .el-table__row.row-selected:hover {
td { td {
background-color: #fdf6ec !important; background-color: #faecd8 !important;
} }
} }
} }
......
...@@ -6176,15 +6176,8 @@ const getRowStyle = ({ row }: { row: PodUsOrderListData }) => { ...@@ -6176,15 +6176,8 @@ const getRowStyle = ({ row }: { row: PodUsOrderListData }) => {
color: '#67c23a', color: '#67c23a',
} }
} }
// 如果行被选中,设置背景色为 #fdf6ec // 选中状态通过 CSS 类名控制,这里不再处理
if (selection.value.some((item) => item.id === row.id)) { return {}
return {
backgroundColor: '#fdf6ec',
}
}
return {
backgroundColor: '',
}
} }
// 获取行类名方法 // 获取行类名方法
...@@ -7327,11 +7320,22 @@ useRouter().beforeEach((to, from, next) => { ...@@ -7327,11 +7320,22 @@ useRouter().beforeEach((to, from, next) => {
} }
} }
// 确保选中行的背景色在 hover 时也保持 // 设置选中行的背景色
:deep(.el-table__body) { :deep(.el-table__body) {
.el-table__row:hover {
td {
background-color: #e1ebf5 !important;
}
}
.el-table__row.row-selected {
td {
background-color: #faecd8 !important;
}
}
// 确保选中行的背景色在 hover 时也保持
.el-table__row.row-selected:hover { .el-table__row.row-selected:hover {
td { td {
background-color: #fdf6ec !important; background-color: #faecd8 !important;
} }
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment