diff --git a/buyer/src/pages/home/Main.vue b/buyer/src/pages/home/Main.vue
index 2756a5c6e..1a5260a1a 100644
--- a/buyer/src/pages/home/Main.vue
+++ b/buyer/src/pages/home/Main.vue
@@ -40,6 +40,105 @@
查看
+
+
+
+
+
+
+ 最近订单
+
+
+
+
+
+
暂无订单
+
+
+
+
+ 我的足迹
+
+
+
+
+
+
暂无足迹
+
+
+
+
+ 我的收藏
+
+
+
+
+
+
暂无收藏
@@ -50,9 +149,18 @@ import { useRouter } from "vue-router";
import { Bell } from "@element-plus/icons-vue";
import storage from "@/plugins/storage";
import { getOrderList } from "@/api/order";
-import { afterSaleList, getMembersWallet, memberCouponList } from "@/api/member";
+import {
+ afterSaleList,
+ collectList,
+ getMembersWallet,
+ memberCouponList,
+ memberGradeCurrent,
+ memberPoint,
+ tracksList,
+} from "@/api/member";
import { refreshUnreadMessage } from "@/utils/unreadMessage";
import { useAppStore } from "@/stores/app";
+import { orderStatusList } from "./enumeration.js";
defineOptions({ name: "UserCenterHome" });
@@ -63,6 +171,12 @@ function totalOf(res) {
return res && res.success ? Number(res.result && res.result.total) || 0 : 0;
}
+function recordsOf(res) {
+ return res && res.success && res.result && Array.isArray(res.result.records)
+ ? res.result.records.filter((item) => item != null)
+ : [];
+}
+
const displayName = ref("会员");
const waitPay = ref(0);
const waitShip = ref(0);
@@ -70,6 +184,14 @@ const waitReceive = ref(0);
const afterSale = ref(0);
const couponCount = ref(0);
const balance = ref(0);
+const point = ref(0);
+const gradeName = ref("-");
+const recentOrders = ref([]);
+const tracks = ref([]);
+const favorites = ref([]);
+const ordersLoaded = ref(false);
+const tracksLoaded = ref(false);
+const favoritesLoaded = ref(false);
const unreadMsg = computed(() => appStore.unreadMsg);
const unreadLabel = computed(() => (unreadMsg.value > 99 ? "99+" : String(unreadMsg.value)));
@@ -90,6 +212,15 @@ function readUser() {
}
}
+function firstItem(order) {
+ return (order.orderItems && order.orderItems[0]) || {};
+}
+
+function orderStatusText(status) {
+ const hit = orderStatusList.find((e) => e.status === status);
+ return hit ? hit.name : status;
+}
+
function loadSummary() {
const page = { pageNumber: 1, pageSize: 1 };
Promise.all([
@@ -100,14 +231,45 @@ function loadSummary() {
memberCouponList({ ...page, memberCouponStatus: "NEW" }).catch(() => null),
getMembersWallet().catch(() => null),
refreshUnreadMessage(),
- ]).then(([pay, ship, receive, afterSaleRes, coupon, wallet]) => {
- waitPay.value = totalOf(pay);
- waitShip.value = totalOf(ship);
- waitReceive.value = totalOf(receive);
- afterSale.value = totalOf(afterSaleRes);
- couponCount.value = totalOf(coupon);
- balance.value = wallet && wallet.success ? wallet.result.memberWallet || 0 : 0;
- });
+ getOrderList({ pageNumber: 1, pageSize: 3 }).catch(() => null),
+ tracksList({ pageNumber: 1, pageSize: 10, order: "desc", sort: "updateTime" }).catch(() => null),
+ collectList({ pageNumber: 1, pageSize: 10, type: "GOODS" }).catch(() => null),
+ memberPoint().catch(() => null),
+ memberGradeCurrent({ pageNumber: 1, pageSize: 10 }).catch(() => null),
+ ]).then(
+ ([
+ pay,
+ ship,
+ receive,
+ afterSaleRes,
+ coupon,
+ wallet,
+ ,
+ recent,
+ tracksRes,
+ favoritesRes,
+ pointRes,
+ gradeRes,
+ ]) => {
+ waitPay.value = totalOf(pay);
+ waitShip.value = totalOf(ship);
+ waitReceive.value = totalOf(receive);
+ afterSale.value = totalOf(afterSaleRes);
+ couponCount.value = totalOf(coupon);
+ balance.value = wallet && wallet.success ? wallet.result.memberWallet || 0 : 0;
+
+ recentOrders.value = recordsOf(recent).filter((order) => order && order.sn);
+ ordersLoaded.value = true;
+ tracks.value = recordsOf(tracksRes);
+ tracksLoaded.value = true;
+ favorites.value = recordsOf(favoritesRes);
+ favoritesLoaded.value = true;
+
+ point.value = pointRes && pointRes.success && pointRes.result ? pointRes.result.point || 0 : 0;
+ const grade = gradeRes && gradeRes.success && gradeRes.result ? gradeRes.result.grade : null;
+ gradeName.value = grade && grade.gradeName ? grade.gradeName : "暂无等级";
+ }
+ );
}
function go(name) {
@@ -118,6 +280,15 @@ function goOrder(tag) {
router.push({ name: "MyOrder", query: { tag } });
}
+function goOrderDetail(sn) {
+ router.push({ name: "OrderDetail", query: { sn } });
+}
+
+function openGoods(skuId, goodsId) {
+ const routeUrl = router.resolve({ path: "/goodsDetail", query: { skuId, goodsId } });
+ window.open(routeUrl.href, "_blank");
+}
+
onMounted(() => {
readUser();
loadSummary();
@@ -196,7 +367,7 @@ onMounted(() => {
}
.asset-grid {
- grid-template-columns: repeat(2, minmax(0, 1fr));
+ grid-template-columns: repeat(4, minmax(0, 1fr));
}
.stat-card,
@@ -236,7 +407,12 @@ onMounted(() => {
display: flex;
align-items: center;
justify-content: space-between;
+ gap: 8px;
padding: 18px 20px;
+
+ > div {
+ min-width: 0;
+ }
}
.asset-label {
@@ -251,6 +427,9 @@ onMounted(() => {
font-size: 20px;
font-weight: 600;
line-height: 28px;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
span {
margin-left: 4px;
@@ -260,8 +439,201 @@ onMounted(() => {
}
}
+.grade-value {
+ font-size: 16px;
+}
+
.asset-link {
+ flex: 0 0 auto;
color: $theme_color;
font-size: 14px;
+ white-space: nowrap;
+}
+
+.panel {
+ border: 1px solid #eee;
+ border-radius: 8px;
+ background: #fff;
+ padding: 16px 20px 20px;
+}
+
+.panel-head {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-bottom: 12px;
+}
+
+.panel-title {
+ color: #333;
+ font-size: 16px;
+ font-weight: 600;
+ line-height: 24px;
+}
+
+.panel-more {
+ border: none;
+ background: none;
+ color: #999;
+ font-size: 14px;
+ cursor: pointer;
+ padding: 0;
+
+ &:hover {
+ color: $theme_color;
+ }
+}
+
+.panel-empty {
+ padding: 32px 0;
+ color: #999;
+ font-size: 14px;
+ text-align: center;
+}
+
+.order-list {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+}
+
+.order-row {
+ display: flex;
+ align-items: center;
+ gap: 14px;
+ width: 100%;
+ padding: 10px 12px;
+ border: 1px solid #f0f0f0;
+ border-radius: 8px;
+ background: #fff;
+ cursor: pointer;
+ text-align: left;
+
+ &:hover {
+ border-color: $theme_color;
+ }
+}
+
+.order-thumb {
+ flex: 0 0 56px;
+ width: 56px;
+ height: 56px;
+ border-radius: 6px;
+ background: #f5f5f5;
+ overflow: hidden;
+
+ img {
+ display: block;
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ }
+}
+
+.order-info {
+ flex: 1;
+ min-width: 0;
+}
+
+.order-name {
+ color: #333;
+ font-size: 14px;
+ line-height: 22px;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.order-more {
+ color: #999;
+ font-size: 13px;
+}
+
+.order-meta {
+ margin-top: 4px;
+ color: #999;
+ font-size: 13px;
+ line-height: 20px;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.order-side {
+ flex: 0 0 auto;
+ text-align: right;
+}
+
+.order-amount {
+ color: #333;
+ font-size: 15px;
+ font-weight: 600;
+ line-height: 22px;
+}
+
+.order-status {
+ margin-top: 4px;
+ color: $theme_color;
+ font-size: 13px;
+ line-height: 20px;
+}
+
+.goods-strip {
+ display: flex;
+ gap: 12px;
+ overflow-x: auto;
+ padding-bottom: 4px;
+}
+
+.goods-card {
+ flex: 0 0 140px;
+ display: flex;
+ flex-direction: column;
+ border: 1px solid #f0f0f0;
+ border-radius: 8px;
+ background: #fff;
+ overflow: hidden;
+ cursor: pointer;
+ text-align: left;
+ padding: 0;
+
+ &:hover {
+ border-color: $theme_color;
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
+ }
+}
+
+.goods-thumb {
+ width: 100%;
+ aspect-ratio: 1;
+ background: #f5f5f5;
+ overflow: hidden;
+
+ img {
+ display: block;
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ }
+}
+
+.goods-name {
+ margin: 8px 10px 0;
+ color: #333;
+ font-size: 13px;
+ line-height: 1.4;
+ height: 36px;
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ -webkit-line-clamp: 2;
+ overflow: hidden;
+}
+
+.goods-price {
+ margin: 6px 10px 10px;
+ color: $theme_color;
+ font-size: 14px;
+ font-weight: 600;
+ line-height: 1.2;
}