mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-ui.git
synced 2025-12-19 17:35:53 +08:00
- 将iView组件统一替换为TDesign组件 - 优化表单、表格、弹窗等交互样式 - 修复路由重复添加问题 - 更新依赖版本 - 调整布局间距与响应式 - 修复表单重置方法兼容性 - 统一消息提示组件
478 lines
14 KiB
Vue
478 lines
14 KiB
Vue
<template>
|
||
<div>
|
||
<t-card class="card" title="基本信息">
|
||
<div class="count-list flex">
|
||
<div class="count-item" @click="navigateTo('managerGoods')">
|
||
<div>
|
||
<Icon class="icon" size="31" type="md-photos" />
|
||
</div>
|
||
<div>
|
||
<div class="counts">{{ homeData.goodsNum || 0 }}</div>
|
||
<div>商品数量</div>
|
||
</div>
|
||
</div>
|
||
<div class="count-item" @click="navigateTo('memberList')">
|
||
<div>
|
||
<Icon class="icon" size="31" type="md-person" />
|
||
</div>
|
||
<div>
|
||
<div class="counts">{{ homeData.memberNum || 0 }}</div>
|
||
<div>会员数量</div>
|
||
</div>
|
||
</div>
|
||
<div class="count-item" @click="navigateTo('orderList')">
|
||
<div>
|
||
<Icon class="icon" size="31" type="md-list" />
|
||
</div>
|
||
<div>
|
||
<div class="counts">{{ homeData.orderNum || 0 }}</div>
|
||
<div>订单数量</div>
|
||
</div>
|
||
</div>
|
||
<div class="count-item" @click="navigateTo('shopList')">
|
||
<div>
|
||
<Icon class="icon" size="31" type="ios-stats" />
|
||
</div>
|
||
<div>
|
||
<div class="counts">{{ homeData.storeNum || 0 }}</div>
|
||
<div>店铺数量</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</t-card>
|
||
|
||
<t-card class="card" title="今日待办">
|
||
<div class="todo-list flex">
|
||
<div class="todo-item" @click="navigateTo('applyGoods')">
|
||
<div class="counts">{{ $store.state.notices.goods || 0 }}</div>
|
||
<div>待审核商品</div>
|
||
</div>
|
||
<div class="todo-item" @click="navigateTo('shopAuth')">
|
||
<div class="counts">{{ $store.state.notices.store || 0 }}</div>
|
||
<div>待审核店铺</div>
|
||
</div>
|
||
<div class="todo-item" @click="navigateTo('orderComplaint')">
|
||
<div class="counts">{{ $store.state.notices.complain || 0 }}</div>
|
||
<div>待审核投诉</div>
|
||
</div>
|
||
<div class="todo-item" @click="navigateTo('afterSaleOrder')">
|
||
<div class="counts">{{ $store.state.notices.refund || 0 }}</div>
|
||
<div>待审核售后</div>
|
||
</div>
|
||
<div class="todo-item">
|
||
<div class="counts">{{ $store.state.notices.distributionCash || 0 }}</div>
|
||
<div>待审核分销提现</div>
|
||
</div>
|
||
<div class="todo-item" @click="navigateTo('accountStatementBill')">
|
||
<div class="counts">{{ $store.state.notices.waitPayBill || 0 }}</div>
|
||
<div>待审核分账</div>
|
||
</div>
|
||
</div>
|
||
</t-card>
|
||
|
||
<t-card class="card flow" title="流量与概括">
|
||
<div class="flow-list flex">
|
||
<div class="flow-item">
|
||
<div class="flow-member">
|
||
<div>当前在线人数</div>
|
||
<span>
|
||
{{ homeData.currentNumberPeopleOnline || 0 }}
|
||
</span>
|
||
</div>
|
||
<div class="flow-wrapper">
|
||
<h4>流量概括</h4>
|
||
<div class="card flow-box flex">
|
||
<div class="flow-box-item">
|
||
<div>今日访客数</div>
|
||
<div class="counts">
|
||
{{ homeData.todayUV || 0 }}
|
||
</div>
|
||
</div>
|
||
<div class="flow-box-item">
|
||
<div>昨日访客数</div>
|
||
<div class="counts">
|
||
{{ homeData.yesterdayUV || 0 }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="flow-splice flex">
|
||
<div class="flow-box-splice">
|
||
<div>前七日访客数</div>
|
||
<div class="counts">
|
||
{{ homeData.lastSevenUV || 0 }}
|
||
</div>
|
||
</div>
|
||
<div class="flow-box-splice">
|
||
<div>前三十日访客数</div>
|
||
<div class="counts">
|
||
{{ homeData.lastThirtyUV || 0 }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="today-box">
|
||
<h4>今日概括</h4>
|
||
<div class="today-list flex">
|
||
<div class="today-item">
|
||
<div>今日订单数</div>
|
||
<span>{{ homeData.todayOrderNum || 0 }}</span>
|
||
</div>
|
||
<div class="today-item">
|
||
<div>今日交易额</div>
|
||
<span v-if="homeData.todayOrderPrice">¥{{ homeData.todayOrderPrice | unitPrice }}</span>
|
||
<span v-else>¥0.00</span>
|
||
</div>
|
||
<div class="today-item">
|
||
<div>今日新增店铺</div>
|
||
<span>{{ homeData.todayStoreNum || 0 }}</span>
|
||
</div>
|
||
<div class="today-item">
|
||
<div>今日新增会员数</div>
|
||
<span>{{ homeData.todayMemberNum || 0 }}</span>
|
||
</div>
|
||
<div class="today-item">
|
||
<div>今日上架商品数量</div>
|
||
<span>{{ homeData.todayGoodsNum || 0 }}</span>
|
||
</div>
|
||
<div class="today-item">
|
||
<div>今日新增评论</div>
|
||
<span>{{ homeData.todayMemberEvaluation || 0 }}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</t-card>
|
||
|
||
<t-card class="card transform" title="最近48小时在线人数(整点为准)">
|
||
<div id="historyMemberChart"></div>
|
||
</t-card>
|
||
<div class="charts flex">
|
||
<t-card class="chart-item" title="流量走势">
|
||
<div id="pvChart"></div>
|
||
</t-card>
|
||
<t-card class="chart-item" title="交易趋势">
|
||
<div id="orderChart"></div>
|
||
</t-card>
|
||
</div>
|
||
|
||
<t-card class="card transform" title="热卖商品TOP10">
|
||
<t-table stripe :columns="tophotGoodsColumns" :data="topHotGoodsData" rowKey="goodsName" />
|
||
</t-card>
|
||
|
||
<t-card class="card transform" title="热卖店铺TOP10">
|
||
<t-table stripe :columns="tophotShopsColumns" :data="topHotShopsData" rowKey="storeName" />
|
||
</t-card>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { homeStatistics, hotGoods, hotShops, getNoticePage } from "@/api/index";
|
||
import * as API_Goods from "@/api/goods";
|
||
import { Chart } from "@antv/g2";
|
||
import * as API_Member from "@/api/member";
|
||
|
||
export default {
|
||
name: "home",
|
||
|
||
data() {
|
||
return {
|
||
// 测试数据
|
||
test: {
|
||
a: "test",
|
||
languages: [],
|
||
},
|
||
// 测试数据结束
|
||
tophotShopsColumns: [
|
||
{ title: "排名", colKey: "index", width: 90, align: "center", cell: (h, { rowIndex }) => rowIndex + 1 },
|
||
{ title: "店铺名称", colKey: "storeName", minWidth: 140, tooltip: true },
|
||
{ title: "价格", colKey: "price", width: 120, cell: (h, { row }) => h("priceColorScheme", { props: { value: row.price, color: this.$mainColor } }) },
|
||
{ title: "销量", colKey: "num", width: 100 },
|
||
],
|
||
|
||
tophotGoodsColumns: [
|
||
{ title: "排名", colKey: "index", width: 90, align: "center", cell: (h, { rowIndex }) => rowIndex + 1 },
|
||
{ title: "商品名称", colKey: "goodsName", minWidth: 140, tooltip: true },
|
||
{ title: "价格", colKey: "price", width: 120, cell: (h, { row }) => h("priceColorScheme", { props: { value: row.price, color: this.$mainColor } }) },
|
||
{ title: "销量", colKey: "num", width: 100 },
|
||
],
|
||
topHotGoodsData: [], //热卖商品集合
|
||
topHotShopsData: [], //热卖店铺集合
|
||
awaitTodoData: "", //今日待办集合
|
||
homeData: "", // 首页数据
|
||
pvChart: "", // 流量统计
|
||
orderChart: "", // 订单统计
|
||
historyMemberChart: "", // 最近会员流量统计
|
||
params: {
|
||
// 请求参数
|
||
searchType: "LAST_SEVEN",
|
||
},
|
||
// 订单传参
|
||
orderParams: {
|
||
searchType: "LAST_SEVEN", // TODAY , YESTERDAY , LAST_SEVEN , LAST_THIRTY
|
||
year: "",
|
||
shopId: "",
|
||
memberId: "",
|
||
},
|
||
};
|
||
},
|
||
methods: {
|
||
// 路由跳转
|
||
navigateTo(name) {
|
||
this.$router.push({
|
||
name,
|
||
});
|
||
},
|
||
// top10热卖商品
|
||
async toHotGoods() {
|
||
let res = await hotGoods(this.params);
|
||
res.success ? (this.topHotGoodsData = res.result) : "";
|
||
},
|
||
|
||
// top10热卖店铺
|
||
async topHotShops() {
|
||
let res = await hotShops(this.params);
|
||
res.success ? (this.topHotShopsData = res.result) : "";
|
||
},
|
||
// 今日待办
|
||
async awaitTodo() {
|
||
let res = await getNoticePage();
|
||
res.success ? (this.awaitTodoData = res.result) : "";
|
||
},
|
||
|
||
//首页统计数据
|
||
async getHomeData() {
|
||
let res = await homeStatistics();
|
||
if (res.success) {
|
||
if (
|
||
res.result.todayOrderPrice &&
|
||
res.result.todayOrderPrice != "null"
|
||
) {
|
||
res.result.todayOrderPrice = parseInt(res.result.todayOrderPrice);
|
||
} else {
|
||
res.result.todayOrderPrice = 0;
|
||
}
|
||
|
||
this.homeData = res.result;
|
||
}
|
||
},
|
||
|
||
// 实例化订单图表
|
||
async initOrderChartList(name) {
|
||
this.orderChart ? this.orderChart.clear() : ''
|
||
const res = await API_Goods.getOrderChart(this.orderParams);
|
||
if (res.success) {
|
||
this.chartList = res.result;
|
||
|
||
if (!this.orderChart) {
|
||
this.orderChart = new Chart({
|
||
container: "orderChart",
|
||
autoFit: true,
|
||
height: 500,
|
||
padding: [70, 70, 70, 70],
|
||
});
|
||
}
|
||
|
||
this.initOrderChart(); //订单表
|
||
}
|
||
},
|
||
|
||
// 订单表
|
||
initOrderChart() {
|
||
// 默认已经加载 legend-filter 交互
|
||
let data = this.chartList;
|
||
|
||
data.forEach((item) => {
|
||
item.createTime = item.createTime.split(" ")[0];
|
||
item.title = "交易额";
|
||
});
|
||
this.orderChart.data(data);
|
||
|
||
this.orderChart.tooltip({
|
||
showCrosshairs: true,
|
||
shared: true,
|
||
});
|
||
|
||
this.orderChart
|
||
.line()
|
||
.position("createTime*price")
|
||
.label("price")
|
||
.color("title")
|
||
.shape("smooth");
|
||
|
||
this.orderChart
|
||
.point()
|
||
.position("createTime*price")
|
||
.label("price")
|
||
.color("title")
|
||
.shape("circle")
|
||
.style({
|
||
stroke: "#fff",
|
||
lineWidth: 1,
|
||
});
|
||
this.orderChart.area().position("createTime*price").color("title").shape("smooth");
|
||
|
||
this.orderChart.render();
|
||
},
|
||
|
||
// 浏览量统计图
|
||
initPvChart() {
|
||
let uv = [];
|
||
let pv = [];
|
||
this.data.forEach((item) => {
|
||
uv.push({
|
||
date: item.date,
|
||
uvNum: item.uvNum,
|
||
title: "访客数UV",
|
||
pv: item.uvNum,
|
||
});
|
||
|
||
pv.push({
|
||
date: item.date,
|
||
pvNum: item.pvNum,
|
||
pv: item.pvNum,
|
||
title: "浏览量PV",
|
||
});
|
||
});
|
||
|
||
let data = [...uv, ...pv];
|
||
|
||
console.log("pv", data);
|
||
this.pvChart.data(data);
|
||
|
||
this.pvChart.tooltip({
|
||
showCrosshairs: true,
|
||
shared: true,
|
||
});
|
||
|
||
this.pvChart
|
||
.line()
|
||
.position("date*pv")
|
||
.color("title")
|
||
.label("pv")
|
||
.shape("smooth");
|
||
|
||
this.pvChart
|
||
.point()
|
||
.position("date*pv")
|
||
.color("title")
|
||
.label("pv")
|
||
.shape("circle")
|
||
.style({
|
||
stroke: "#fff",
|
||
lineWidth: 1,
|
||
});
|
||
this.pvChart.area().position("date*pv").color("title").shape("smooth");
|
||
|
||
this.pvChart.render();
|
||
},
|
||
|
||
// 浏览量
|
||
async getPvChart() {
|
||
this.pvChart ? this.pvChart.clear() : ''
|
||
API_Member.getStatisticsList(this.params).then((res) => {
|
||
if (res.result) {
|
||
this.data = res.result;
|
||
|
||
if (!this.pvChart) {
|
||
this.pvChart = new Chart({
|
||
container: "pvChart",
|
||
autoFit: true,
|
||
height: 500,
|
||
padding: [70, 70, 70, 70],
|
||
});
|
||
}
|
||
this.initPvChart();
|
||
}
|
||
});
|
||
},
|
||
// 实例化会员流量图表
|
||
async initHistoryMemberChartList() {
|
||
this.historyMemberChart ? this.historyMemberChart.clear() : ''
|
||
const res = await API_Member.historyMemberChartList();
|
||
if (res.success) {
|
||
this.chartList = res.result;
|
||
|
||
if (!this.historyMemberChart) {
|
||
this.historyMemberChart = new Chart({
|
||
container: "historyMemberChart",
|
||
autoFit: true,
|
||
height: 500,
|
||
padding: [70, 70, 70, 70],
|
||
});
|
||
}
|
||
|
||
this.initHistoryMemberChart();
|
||
}
|
||
},
|
||
// 历史在线人数
|
||
initHistoryMemberChart() {
|
||
// 默认已经加载 legend-filter 交互
|
||
let data = this.chartList;
|
||
let num = [];
|
||
let lastNum = [];
|
||
data.forEach((item) => {
|
||
num.push({
|
||
date: item.date.substring(5),
|
||
title: "最近48小时",
|
||
num: item.num,
|
||
res: item.num,
|
||
});
|
||
|
||
lastNum.push({
|
||
date: item.date.substring(5),
|
||
title: "上一周期",
|
||
lastNum: item.lastNum || 0,
|
||
res: item.lastNum || 0,
|
||
});
|
||
});
|
||
let params = [...num, ...lastNum];
|
||
this.historyMemberChart.data(params);
|
||
|
||
this.historyMemberChart.tooltip({
|
||
showCrosshairs: true,
|
||
shared: true,
|
||
});
|
||
|
||
this.historyMemberChart
|
||
.line()
|
||
.position("date*res")
|
||
.color("title")
|
||
.label("res")
|
||
.shape("smooth");
|
||
this.historyMemberChart
|
||
.point()
|
||
.position("date*res")
|
||
.color("title")
|
||
.label("res")
|
||
.shape("circle");
|
||
|
||
this.historyMemberChart
|
||
.area()
|
||
.position("date*res")
|
||
.color("title")
|
||
.shape("smooth");
|
||
|
||
this.historyMemberChart.render();
|
||
},
|
||
// 初始化信息
|
||
init() {
|
||
this.toHotGoods();
|
||
this.topHotShops();
|
||
this.awaitTodo();
|
||
this.getHomeData();
|
||
this.getPvChart();
|
||
this.initOrderChartList();
|
||
this.initHistoryMemberChartList();
|
||
},
|
||
},
|
||
mounted() {
|
||
this.init();
|
||
},
|
||
};
|
||
</script>
|
||
<style lang="scss" scoped>
|
||
@import "./home.scss";
|
||
</style>
|