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; }