电商交易-交易分析页面优化空数据时的默认展示;表格组件增加formatter处理逻辑

This commit is contained in:
郭永超 2025-07-02 14:42:23 +08:00
parent 466cef50a6
commit ef7140e446
2 changed files with 179 additions and 52 deletions

View File

@ -78,6 +78,10 @@
<template v-if="column.slotName" #default="scope">
<slot :name="column.slotName" :row="scope.row"></slot>
</template>
<!-- 动态处理 formatter -->
<template v-else-if="column.formatter" #default="{ row, colum, $index }">
{{ column.formatter(row, colum, row[column.prop], $index) }}
</template>
</el-table-column>
</template>
</el-table>

View File

@ -1,9 +1,15 @@
<template>
<div class="app-container customer-control">
<div style="overflow-y: auto;overflow-x: hidden; height: 100%;">
<div style="overflow-y: auto; overflow-x: hidden; height: 100%">
<div class="app-container-data" ref="chartContainer">
<div class="app-container-title">运营看板
<el-radio-group v-model="dateRadio" @change="changeDateRadio" size="small" style="float: right;">
<div class="app-container-title">
运营看板
<el-radio-group
v-model="dateRadio"
@change="changeDateRadio"
size="small"
style="float: right"
>
<el-radio-button label="周" :value="1" />
<el-radio-button label="月" :value="2" />
<el-radio-button label="年" :value="3" />
@ -14,14 +20,22 @@
<div class="app-container-data-left-top">
<div>
<div class="title">
<img class="title-image" src="../../assets/images/money.png" alt="" />
<img
class="title-image"
src="../../assets/images/money.png"
alt=""
/>
<div>销售总额()</div>
</div>
<div class="number">{{ topLeftData.salesTotalAmount }}</div>
</div>
<div>
<div class="title">
<img class="title-image" src="../../assets/images/order.png" alt="" />
<img
class="title-image"
src="../../assets/images/order.png"
alt=""
/>
<div>订单总数()</div>
</div>
<div class="number">{{ topLeftData.orderTotalNum }}</div>
@ -30,14 +44,22 @@
<div class="app-container-data-left-bottom">
<div>
<div class="title">
<img class="title-image" src="../../assets/images/views.png" alt="" />
<img
class="title-image"
src="../../assets/images/views.png"
alt=""
/>
<div>浏览量()</div>
</div>
<div class="number">{{ topLeftData.viewCount }}</div>
</div>
<div>
<div class="title">
<img class="title-image" src="../../assets/images/money1.png" alt="" />
<img
class="title-image"
src="../../assets/images/money1.png"
alt=""
/>
<div>成功退款金额()</div>
</div>
<div class="number">{{ topLeftData.refundSuccessAmout }}</div>
@ -51,32 +73,42 @@
</div>
<!-- 中间模块 -->
<div class="app-container-list" ref="middleRef">
<div class="app-container-block" v-for="(item, index) in middleData" :key="index">
<div class="app-container-block-title">{{ item.title }}
<div
class="app-container-block"
v-for="(item, index) in middleData"
:key="index"
>
<div class="app-container-block-title">
{{ item.title }}
<el-popover title="" :content="item.toolTip" placement="left-start">
<template #reference>
<el-icon color="#c5c5c5" style="float: right;">
<el-icon color="#c5c5c5" style="float: right">
<QuestionFilled />
</el-icon>
</template>
</el-popover>
</div>
<div class="app-container-block-price">
{{ item.valueStr ?? '--' }}
{{ item.valueStr ?? "--" }}
<text style="font-size: 12px; color: #999999; margin-left: 5px">
{{ item.unit ?? '' }}
{{ item.unit ?? "" }}
</text>
</div>
<div class="app-container-block-proportion">
{{ item.ratioMethod }}
<text :style="{ 'font-size': '12px', color: item.ratioStatus == '下降' ? 'red' : 'green' }">
<text
:style="{
'font-size': '12px',
color: item.ratioStatus == '下降' ? 'red' : 'green',
}"
>
<el-icon v-if="item.ratioStatus == '下降'">
<CaretBottom />
</el-icon>
<el-icon v-else>
<CaretTop />
</el-icon>
{{ item.ratioValue ?? '' }}%
{{ item.ratioValue ?? "" }}%
</text>
</div>
</div>
@ -85,20 +117,38 @@
<div class="bottom-flex-box">
<div class="bottom-box-item">
<div class="bottom-box-item-title">商品销量</div>
<div class="bottom-box-item-content" :style="{ height: tableViewportHeight + 'px' }">
<tableComponent :table-data="tableData" :columns="columns" :show-border="false" :show-pagination="false"
:loading="tableLoading">
<div
class="bottom-box-item-content"
:style="{ height: tableViewportHeight + 'px' }"
>
<tableComponent
:table-data="tableData"
:columns="columns"
:show-border="false"
:show-pagination="false"
:loading="tableLoading"
>
<!-- 自定义-排名图片 -->
<template #ranking="slotProps">
<div class="table-cell-img-box" style="width: 40px;height: 40px;" v-if="slotProps.row.ranking == 1">
<div
class="table-cell-img-box"
style="width: 40px; height: 40px"
v-if="slotProps.row.ranking == 1"
>
<img :src="img1" class="table-cell-img" alt="" />
</div>
<div class="table-cell-img-box" style="width: 40px;height: 40px;"
v-else-if="slotProps.row.ranking == 2">
<div
class="table-cell-img-box"
style="width: 40px; height: 40px"
v-else-if="slotProps.row.ranking == 2"
>
<img :src="img2" class="table-cell-img" alt="" />
</div>
<div class="table-cell-img-box" style="width: 40px;height: 40px;"
v-else-if="slotProps.row.ranking == 3">
<div
class="table-cell-img-box"
style="width: 40px; height: 40px"
v-else-if="slotProps.row.ranking == 3"
>
<img :src="img3" class="table-cell-img" alt="" />
</div>
<div v-else>{{ slotProps.row.ranking }}</div>
@ -106,8 +156,15 @@
<!-- 自定义-商品图片 -->
<template #goodUrl="slotProps">
<div class="table-cell-img-box" style="width: 40px;height: 40px;">
<img :src="slotProps.row.goodUrl" class="table-cell-img" alt="" />
<div
class="table-cell-img-box"
style="width: 40px; height: 40px"
>
<img
:src="slotProps.row.goodUrl"
class="table-cell-img"
alt=""
/>
</div>
</template>
</tableComponent>
@ -117,55 +174,114 @@
<div class="bottom-box-item-title">售后概况</div>
<div class="bottom-box-item-content">
<!-- -->
<div class="bottom-box-summary" style="margin: 20px 0;">
<div class="bottom-box-summary" style="margin: 20px 0">
<div class="bottom-box-summary-item">
<div class="bottom-box-summary-title">售后订单数量()</div>
<div class="bottom-box-summary-value">{{ afterSalesData.totalAfterSalesOrders }}</div>
<div class="bottom-box-summary-value">
{{ afterSalesData.totalAfterSalesOrders }}
</div>
</div>
<div class="bottom-box-summary-item">
<div class="bottom-box-summary-title">退货退款金额()</div>
<div class="bottom-box-summary-value">{{ afterSalesData.totalRefundAmount }}</div>
<div class="bottom-box-summary-value">
{{ afterSalesData.totalRefundAmount }}
</div>
</div>
<div class="bottom-box-summary-item">
<div class="bottom-box-summary-title">退货退款订单数量()</div>
<div class="bottom-box-summary-value">{{ afterSalesData.totalRefundOrders }}</div>
<div class="bottom-box-summary-value">
{{ afterSalesData.totalRefundOrders }}
</div>
</div>
</div>
<!-- -->
<div class="bottom-box-summary" style="line-height: 30px;margin: 0;">
<div
class="bottom-box-summary"
style="line-height: 30px; margin: 0"
>
<div class="bottom-box-summary-item">
<img :src="alert" style="width: 30px;height: 30px;" alt="" />
<div class="bottom-box-summary-title"
style="display: inline-block;vertical-align: middle;margin-left: 8px;">
预警商品</div>
<img :src="alert" style="width: 30px; height: 30px" alt="" />
<div
class="bottom-box-summary-title"
style="
display: inline-block;
vertical-align: middle;
margin-left: 8px;
"
>
预警商品
</div>
</div>
<div class="bottom-box-summary-item" style="width: 120px;flex: none;">
<div
class="bottom-box-summary-item"
style="width: 120px; flex: none"
>
<div class="bottom-box-summary-title">退款订单量</div>
</div>
<div class="bottom-box-summary-item" style="width: 130px;flex: none;">
<div
class="bottom-box-summary-item"
style="width: 130px; flex: none"
>
<div class="bottom-box-summary-title">退款金额</div>
</div>
</div>
<div ref="warningGoodsRef" style="overflow-y: auto; height: 150px;"
:style="{ height: tableViewportHeight - 150 + 'px' }">
<div v-if="afterSalesData.warningProductInfos.length == 0" style="color: #909399; font-size: 14px; text-align: center; padding-top: 20px">
<div
ref="warningGoodsRef"
style="overflow-y: auto; height: 150px"
:style="{ height: tableViewportHeight - 150 + 'px' }"
>
<div
v-if="afterSalesData.warningProductInfos.length == 0"
style="
color: #909399;
font-size: 14px;
text-align: center;
padding-top: 20px;
"
>
暂无数据
</div>
<template v-else>
<div class="bottom-box-summary" style="line-height: 40px;margin: 0;"
v-for="(item, index) in afterSalesData.warningProductInfos" :key="index">
<div class="bottom-box-summary-item" style="display: flex;">
<img :src="item.goodUrl" style="width: 40px;height: 40px;" alt="" />
<div class="bottom-box-summary-title text-ellipsis"
style="flex: 1; vertical-align: top;color: #000;margin-left: 8px;" :title="item.goodName">
<div
class="bottom-box-summary"
style="line-height: 40px; margin: 0"
v-for="(item, index) in afterSalesData.warningProductInfos"
:key="index"
>
<div class="bottom-box-summary-item" style="display: flex">
<img
:src="item.goodUrl"
style="width: 40px; height: 40px"
alt=""
/>
<div
class="bottom-box-summary-title text-ellipsis"
style="
flex: 1;
vertical-align: top;
color: #000;
margin-left: 8px;
"
:title="item.goodName"
>
{{ item.goodName }}
</div>
</div>
<div class="bottom-box-summary-item" style="width: 120px;flex: none;">
<div class="bottom-box-summary-title" style="color: #000;">{{ item.refundedOrders }}</div>
<div
class="bottom-box-summary-item"
style="width: 120px; flex: none"
>
<div class="bottom-box-summary-title" style="color: #000">
{{ item.refundedOrders }}
</div>
</div>
<div class="bottom-box-summary-item" style="width: 120px;flex: none;">
<div class="bottom-box-summary-title" style="color: #000;">{{ item.refundAmount }}</div>
<div
class="bottom-box-summary-item"
style="width: 120px; flex: none"
>
<div class="bottom-box-summary-title" style="color: #000">
{{ item.refundAmount }}
</div>
</div>
</div>
</template>
@ -679,7 +795,10 @@ const loadTopLeftData = async () => {
queryType: dateRadio.value,
});
if (response.code == 200) {
topLeftData.value = response.data;
topLeftData.value.salesTotalAmount = response.data.salesTotalAmount ?? 0;
topLeftData.value.orderTotalNum = response.data.orderTotalNum ?? 0;
topLeftData.value.viewCount = response.data.viewCount ?? 0;
topLeftData.value.refundSuccessAmout = response.data.refundSuccessAmout ?? 0;
} else {
initTopLeftData();
}
@ -739,8 +858,8 @@ const columns = ref([
{ prop: "ranking", label: "排名", slotName: "ranking", width: 66 },
{ prop: "goodUrl", label: "商品图片", slotName: "goodUrl", width: 80, align: "left" },
{ prop: "goodName", label: "商品名称", width: "auto", align: "left" },
{ prop: "stockToUseRatio", label: "存销比", width: 70, align: "left" },
{ prop: "salesAmount", label: "销售金额", width: 100, align: "left" },
{ prop: "stockToUseRatio", label: "存销比", width: 70, align: "left", formatter: (row) => `${row.stockToUseRatio ?? 0}%` },
{ prop: "salesAmount", label: "销售金额", width: 100, align: "left", formatter: (row) => `${row.salesAmount ?? 0}` },
]);
// -
const loadbottomLeftData = async () => {
@ -801,7 +920,11 @@ const loadbottomRightData = async () => {
queryType: dateRadio.value,
});
if (response.code == 200) {
afterSalesData.value = response.data;
afterSalesData.value.totalAfterSalesOrders = response.data.totalAfterSalesOrders ?? 0;
afterSalesData.value.totalRefundAmount = response.data.totalRefundAmount ?? 0;
afterSalesData.value.totalAfterSalesOrders = response.data.totalAfterSalesOrders ?? 0;
afterSalesData.value.warningProductInfos = response.data.warningProductInfos ?? [];
console.log(afterSalesData.value);
}
} catch (error) { }
};