mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-ui.git
synced 2026-11-13 04:18:55 +08:00
feat(buyer): 增强搜索功能并提升用户体验
- 新增 `getStoreById` 接口方法,用于获取包含评分在内的店铺信息 - `Search.vue` 新增搜索建议面板,展示搜索历史和热词,优化搜索体验 - 新增 `SearchSuggest.vue` 组件,用于展示搜索建议和搜索历史 - `App.vue` 根据路由元信息按条件设置页面标题 - 优化多个组件的布局与样式,让整体风格更统一 - 重构多个组件的跳转逻辑,改用路由跳转(`router.push`)替代新开窗口(`window.open`),提升用户体验
This commit is contained in:
@@ -281,11 +281,10 @@ export default {
|
||||
},
|
||||
// 跳转店铺首页
|
||||
goShopPage(id) {
|
||||
let routeUrl = this.$router.resolve({
|
||||
this.$router.push({
|
||||
path: "/merchant",
|
||||
query: { id },
|
||||
});
|
||||
window.open(routeUrl.href, "_blank");
|
||||
},
|
||||
// 同步购物车商品收藏状态
|
||||
async syncCartCollectionStatus() {
|
||||
@@ -959,3 +958,6 @@ export default {
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,55 +2,43 @@
|
||||
<div class="coupon-center">
|
||||
<BaseHeader></BaseHeader>
|
||||
<div class="content">
|
||||
<div>
|
||||
<div class="coupon-title">
|
||||
<router-link to="/">
|
||||
<img src="../assets/images/logo.png" width="120" alt="" />
|
||||
</router-link>
|
||||
<p>领券中心</p>
|
||||
<el-input
|
||||
v-model="keyword"
|
||||
style="width: 400px"
|
||||
@keyup.enter="search"
|
||||
placeholder="搜索优惠券"
|
||||
/>
|
||||
</div>
|
||||
<h2 class="coupon-page-title">领券中心</h2>
|
||||
|
||||
<div class="fontsize_18 recommend">推荐好券</div>
|
||||
|
||||
<empty v-if="!loading && list.length === 0" />
|
||||
<ul class="coupon-list" v-else-if="list.length > 0">
|
||||
<li v-for="(item, index) in list" class="coupon-item" :key="index">
|
||||
<div class="c-left">
|
||||
<div>
|
||||
<span
|
||||
v-if="item.couponType === 'PRICE'"
|
||||
class="fontsize_12 global_color"
|
||||
>¥<span class="price">{{ $filters.unitPrice(item.price) }}</span></span>
|
||||
<span
|
||||
v-if="item.couponType === 'DISCOUNT'"
|
||||
class="fontsize_12 global_color"
|
||||
><span class="price">{{ item.couponDiscount || item.discount }}</span>折</span>
|
||||
<span class="describe"
|
||||
>满{{ item.consumeThreshold }}元可用</span>
|
||||
</div>
|
||||
<p>使用范围:{{ useScope(item.scopeType, item.storeName) }}</p>
|
||||
<p>有效期:{{ item.endTime }}</p>
|
||||
<empty v-if="!loading && list.length === 0" />
|
||||
<ul class="coupon-list" v-else-if="list.length > 0">
|
||||
<li v-for="item in list" class="coupon-item" :key="item.id">
|
||||
<div class="c-left">
|
||||
<div class="coupon-amount">
|
||||
<span v-if="item.couponType === 'PRICE'" class="global_color">
|
||||
¥<span class="price">{{ $filters.unitPrice(item.price) }}</span>
|
||||
</span>
|
||||
<span v-if="item.couponType === 'DISCOUNT'" class="global_color">
|
||||
<span class="price">{{ item.couponDiscount || item.discount }}</span>折
|
||||
</span>
|
||||
<span class="describe">{{ thresholdText(item) }}</span>
|
||||
</div>
|
||||
<b></b>
|
||||
<a class="c-right" @click="receive(item)">立即领取</a>
|
||||
<i class="circle-top"></i>
|
||||
<i class="circle-bottom"></i>
|
||||
</li>
|
||||
</ul>
|
||||
<el-pagination v-model:current-page="params.pageNumber"
|
||||
v-model:page-size="params.pageSize"
|
||||
:total="total"
|
||||
@current-change="changePageNum"
|
||||
class="pageration"
|
||||
@size-change="changePageSize"
|
||||
layout="total, sizes, prev, pager, next"></el-pagination>
|
||||
</div>
|
||||
<p class="coupon-name">
|
||||
<span class="scope-tag">{{ scopeTag(item.scopeType, item.storeName) }}</span>
|
||||
<span>{{ item.couponName }}</span>
|
||||
</p>
|
||||
<p class="coupon-time">有效期:{{ item.endTime }}</p>
|
||||
</div>
|
||||
<a
|
||||
class="c-right"
|
||||
:class="{ 'is-finished': isFinished(item) }"
|
||||
@click="receive(item)"
|
||||
>{{ isFinished(item) ? "已领完" : "立即领取" }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
<el-pagination
|
||||
v-model:current-page="params.pageNumber"
|
||||
v-model:page-size="params.pageSize"
|
||||
:total="total"
|
||||
@current-change="changePageNum"
|
||||
class="pageration"
|
||||
@size-change="changePageSize"
|
||||
layout="total, sizes, prev, pager, next"
|
||||
></el-pagination>
|
||||
</div>
|
||||
<BaseFooter></BaseFooter>
|
||||
</div>
|
||||
@@ -65,7 +53,6 @@ export default {
|
||||
list: [], // 优惠券列表
|
||||
total: 0, // 优惠券总数
|
||||
loading: false,
|
||||
keyword: "",
|
||||
params: {
|
||||
// 请求参数
|
||||
getType: "FREE",
|
||||
@@ -75,13 +62,6 @@ export default {
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 搜索优惠券
|
||||
search() {
|
||||
this.params.couponName = this.keyword.trim();
|
||||
this.params.pageNumber = 1;
|
||||
this.getList();
|
||||
},
|
||||
// 获取优惠券列表
|
||||
getList() {
|
||||
if (this.loading) return;
|
||||
this.loading = true;
|
||||
@@ -116,6 +96,7 @@ export default {
|
||||
},
|
||||
// 领取优惠券
|
||||
receive(item) {
|
||||
if (this.isFinished(item)) return;
|
||||
const userInfo = storage.getItem("userInfo");
|
||||
const isLogin = userInfo && JSON.parse(userInfo).username;
|
||||
if (!isLogin) {
|
||||
@@ -158,23 +139,22 @@ export default {
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
// 优惠券可用范围
|
||||
useScope(type, storeName) {
|
||||
let shop = "平台";
|
||||
let goods = "全部商品";
|
||||
if (storeName !== "platform") shop = storeName;
|
||||
switch (type) {
|
||||
case "ALL":
|
||||
goods = "全部商品";
|
||||
break;
|
||||
case "PORTION_GOODS":
|
||||
goods = "部分商品";
|
||||
break;
|
||||
case "PORTION_GOODS_CATEGORY":
|
||||
goods = "部分分类商品";
|
||||
break;
|
||||
}
|
||||
return `${shop}${goods}可用`;
|
||||
// 发行量已领完
|
||||
isFinished(item) {
|
||||
return Number(item.publishNum) > 0 && Number(item.receivedNum) >= Number(item.publishNum);
|
||||
},
|
||||
// 使用门槛文案
|
||||
thresholdText(item) {
|
||||
const threshold = Number(item.consumeThreshold);
|
||||
if (!threshold) return "无使用门槛";
|
||||
return `满${item.consumeThreshold}元可用`;
|
||||
},
|
||||
// 券范围。店铺名为 platform 时是平台通用券
|
||||
scopeTag(type, storeName) {
|
||||
if (type === "PORTION_GOODS") return "商品券";
|
||||
if (type === "PORTION_GOODS_CATEGORY") return "分类券";
|
||||
if (storeName && storeName !== "platform") return "店铺券";
|
||||
return "通用券";
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
@@ -184,84 +164,156 @@ export default {
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import "../assets/styles/coupon.scss";
|
||||
|
||||
.coupon-center {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.content {
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
|
||||
> div {
|
||||
margin: 10px auto;
|
||||
width: 1200px;
|
||||
}
|
||||
width: 1200px;
|
||||
margin: 0 auto 48px;
|
||||
background: transparent;
|
||||
}
|
||||
.coupon-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
p {
|
||||
font-size: 18px;
|
||||
margin-right: 500px;
|
||||
}
|
||||
border-bottom: 2px solid $theme_color;
|
||||
}
|
||||
.recommend {
|
||||
margin: 20px auto;
|
||||
font-weight: bold;
|
||||
width: 200px;
|
||||
.coupon-page-title {
|
||||
margin: 28px 0 20px;
|
||||
color: #171A26;
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
}
|
||||
.coupon-item {
|
||||
overflow: hidden;
|
||||
$claim-width: 55px;
|
||||
|
||||
.c-left {
|
||||
width: calc(100% - #{$claim-width});
|
||||
box-sizing: border-box;
|
||||
.coupon-list {
|
||||
gap: 16px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.coupon-item {
|
||||
width: calc((100% - 32px) / 3);
|
||||
height: auto;
|
||||
min-height: 132px;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
overflow: hidden;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
background: #fff;
|
||||
|
||||
b,
|
||||
i.circle-top,
|
||||
i.circle-bottom {
|
||||
display: none;
|
||||
}
|
||||
|
||||
b {
|
||||
right: $claim-width;
|
||||
width: 0;
|
||||
background: none;
|
||||
border-right: 1px dashed #e0e0e0;
|
||||
.c-left {
|
||||
flex: 1;
|
||||
width: auto;
|
||||
min-width: 0;
|
||||
padding: 16px 16px 14px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.coupon-amount {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.price {
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.describe {
|
||||
margin-left: 0;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.coupon-name {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
margin: 0 0 8px;
|
||||
color: #171A26;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.scope-tag {
|
||||
flex-shrink: 0;
|
||||
padding: 0 6px;
|
||||
border-radius: 2px;
|
||||
background: #fff5f4;
|
||||
color: $theme_color;
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.coupon-name span:last-child {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.coupon-time {
|
||||
margin: 0;
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
line-height: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
.c-right {
|
||||
width: $claim-width;
|
||||
position: relative;
|
||||
right: auto;
|
||||
top: auto;
|
||||
flex-shrink: 0;
|
||||
box-sizing: border-box;
|
||||
width: 48px;
|
||||
height: auto;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
writing-mode: vertical-rl;
|
||||
text-orientation: mixed;
|
||||
letter-spacing: 4px;
|
||||
font-size: 16px;
|
||||
white-space: nowrap;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
user-select: none;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.9;
|
||||
opacity: 0.92;
|
||||
}
|
||||
|
||||
&.is-finished {
|
||||
background: #c8c8c8;
|
||||
cursor: default;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
i.circle-top,
|
||||
i.circle-bottom {
|
||||
right: calc(#{$claim-width} - 9px);
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
i.circle-top {
|
||||
top: -9px;
|
||||
}
|
||||
|
||||
i.circle-bottom {
|
||||
bottom: -9px;
|
||||
}
|
||||
}
|
||||
|
||||
.pageration {
|
||||
text-align: right;
|
||||
padding-bottom: 10px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 20px;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -6,27 +6,10 @@
|
||||
<div class="shop-nav-container">
|
||||
<el-breadcrumb>
|
||||
<el-breadcrumb-item to="/">首页</el-breadcrumb-item>
|
||||
<el-breadcrumb-item v-for="(item, index) in categoryBar" :to="goGoodsList(index)" target="_blank" :key="index">
|
||||
<el-breadcrumb-item v-for="(item, index) in categoryBar" :to="goGoodsList(index)" :key="index">
|
||||
{{ item.name }}
|
||||
</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
<div class="store-collect" v-if="!takeDownSale && goodsMsg.data">
|
||||
<span class="mr_10" v-if="goodsMsg.data">
|
||||
<router-link
|
||||
class="store-name-link"
|
||||
:to="{ path: '/merchant', query: { id: goodsMsg.data.storeId } }"
|
||||
>{{ goodsMsg.data.storeName }}</router-link>
|
||||
</span>
|
||||
<span
|
||||
class="store-collect-btn"
|
||||
:class="{ 'is-collected': storeCollected }"
|
||||
@click="collect"
|
||||
>
|
||||
<el-icon class="store-collect-icon"><StarFilled /></el-icon>
|
||||
{{ storeCollected? "已收藏店铺": "收藏店铺" }}
|
||||
</span>
|
||||
<span class="ml_10 contact-service-btn" @click="IMService(goodsMsg.data.storeId,goodsMsg.data.goodsId,goodsMsg.data.id)">联系客服</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -48,21 +31,13 @@
|
||||
|
||||
<script>
|
||||
import { Message } from "@/utils/message";
|
||||
import { StarFilled } from '@element-plus/icons-vue';
|
||||
import Search from "@/components/Search";
|
||||
|
||||
import ShowGoods from "@/components/goodsDetail/ShowGoods";
|
||||
import empty from "@/components/empty/Main";
|
||||
import ShowGoodsDetail from "@/components/goodsDetail/ShowGoodsDetail";
|
||||
import { goodsSkuDetail } from "@/api/goods";
|
||||
import {
|
||||
cancelStoreCollect,
|
||||
collectStore,
|
||||
isStoreCollection,
|
||||
getGoodsDistribution,
|
||||
} from "@/api/member";
|
||||
import { getDetailById } from "@/api/shopentry";
|
||||
import imTalk from '@/components/mixes/talkIm'
|
||||
import { getGoodsDistribution } from "@/api/member";
|
||||
export default {
|
||||
name: "GoodsDetail",
|
||||
beforeRouteEnter (to, from, next) {
|
||||
@@ -72,14 +47,11 @@ export default {
|
||||
created () {
|
||||
this.getGoodsDetail();
|
||||
},
|
||||
mixins: [imTalk],
|
||||
data () {
|
||||
return {
|
||||
goodsMsg: {}, // 商品信息
|
||||
isLoading: false, // 加载状态
|
||||
categoryBar: [], // 分类
|
||||
storeCollected: false, // 商品收藏
|
||||
storeMsg: {}, // 店铺信息
|
||||
takeDownSale:false, // 是否下架
|
||||
|
||||
};
|
||||
@@ -140,24 +112,6 @@ export default {
|
||||
if (!this.goodsMsg.data.intro) {
|
||||
this.goodsMsg.data.intro = ''
|
||||
}
|
||||
// 判断是否收藏(须同时有 token,避免未登录/ token 失效时误跳登录页)
|
||||
if (this.Cookies.getItem("accessToken") && this.Cookies.getItem("userInfo")) {
|
||||
isStoreCollection("STORE", this.goodsMsg.data.storeId).then((res) => {
|
||||
if (res.success && res.result) {
|
||||
this.storeCollected = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!this.storeMsg) {
|
||||
// 获取店铺信息
|
||||
getDetailById(this.goodsMsg.data.storeId).then((res) => {
|
||||
if (res.success) {
|
||||
this.storeMsg = res.result;
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
Message.error(res.message);
|
||||
this.isLoading = false
|
||||
@@ -183,37 +137,12 @@ export default {
|
||||
query: { categoryId: arr.toString() },
|
||||
};
|
||||
},
|
||||
async collect () {
|
||||
// 收藏店铺
|
||||
const storeId = this.goodsMsg.data && this.goodsMsg.data.storeId;
|
||||
if (!storeId) {
|
||||
return;
|
||||
}
|
||||
if (!this.Cookies.getItem("userInfo")) {
|
||||
Message.warning("请先登录");
|
||||
this.$router.push("/login");
|
||||
return;
|
||||
}
|
||||
if (this.storeCollected) {
|
||||
let cancel = await cancelStoreCollect("STORE", storeId);
|
||||
if (cancel.success) {
|
||||
Message.success("已取消收藏");
|
||||
this.storeCollected = false;
|
||||
}
|
||||
} else {
|
||||
let collect = await collectStore("STORE", storeId);
|
||||
if (collect.code === 200) {
|
||||
this.storeCollected = true;
|
||||
Message.success("收藏店铺成功,可以前往个人中心我的收藏查看");
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {},
|
||||
components: { Search,
|
||||
ShowGoods,
|
||||
ShowGoodsDetail,
|
||||
empty, StarFilled },
|
||||
empty },
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@@ -248,52 +177,6 @@ export default {
|
||||
:deep(.el-breadcrumb__item:last-child .el-breadcrumb__inner) {
|
||||
color: #171A26;
|
||||
}
|
||||
|
||||
.store-collect {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
color: #171A26;
|
||||
font-size: 14px;
|
||||
|
||||
.store-collect-btn,
|
||||
.contact-service-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
cursor: pointer;
|
||||
color: #171A26;
|
||||
|
||||
&:hover {
|
||||
color: $theme_color;
|
||||
}
|
||||
}
|
||||
|
||||
.store-collect-btn {
|
||||
.store-collect-icon {
|
||||
color: #999;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
&.is-collected,
|
||||
&.is-collected .store-collect-icon {
|
||||
color: $theme_color;
|
||||
}
|
||||
}
|
||||
|
||||
.store-name-link {
|
||||
color: #438cde;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
color: $theme_color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.sale-btn{
|
||||
margin:10px 0
|
||||
|
||||
@@ -21,32 +21,34 @@
|
||||
>
|
||||
<span :class="{ 'goods-list-tool-active': index === sortIndex }">
|
||||
{{ item.title }}
|
||||
<el-icon><ArrowDown /></el-icon>
|
||||
<el-icon v-if="index === sortIndex" class="sort-arrow"><ArrowDown /></el-icon>
|
||||
</span>
|
||||
</li>
|
||||
<li @click="orderBy('price', 5, 'up')" class="price-sort">
|
||||
<span :class="{ 'goods-list-tool-active': 5 === sortIndex }">
|
||||
<li @click="orderBy('price', priceSortIndex)" class="price-sort">
|
||||
<span :class="{ 'goods-list-tool-active': priceSortIndex === sortIndex }">
|
||||
价格
|
||||
<span class="price-arrows">
|
||||
<el-icon :class="{ 'price-color': sortPriceIndex == 'desc' }"><ArrowUp /></el-icon>
|
||||
<el-icon :class="{ 'price-color': sortPriceIndex == 'asc' }"><ArrowDown /></el-icon>
|
||||
<el-icon :class="{ 'is-on': priceSortIndex === sortIndex && sortPriceIndex === 'asc' }"><ArrowUp /></el-icon>
|
||||
<el-icon :class="{ 'is-on': priceSortIndex === sortIndex && sortPriceIndex === 'desc' }"><ArrowDown /></el-icon>
|
||||
</span>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- 列表 -->
|
||||
<div class="goods-list">
|
||||
<empty v-if="goodsList.length === 0" />
|
||||
<div v-if="searched && !loading && goodsList.length === 0" class="list-empty">
|
||||
<empty :_Title="emptyTitle" />
|
||||
<div v-if="recommendList.length" class="recommend-title">为你推荐</div>
|
||||
</div>
|
||||
<div class="goods-list" v-if="displayGoods.length">
|
||||
<div
|
||||
v-else
|
||||
class="goods-show-info"
|
||||
v-for="(item, index) in goodsList"
|
||||
:key="index"
|
||||
v-for="(item, index) in displayGoods"
|
||||
:key="item.id || index"
|
||||
@click="goGoodsDetail(item.id, item.goodsId)"
|
||||
>
|
||||
<div class="goods-show-img">
|
||||
<img :src="item.thumbnail" />
|
||||
<GoodsThumb :src="item.thumbnail" :alt="item.goodsName" />
|
||||
</div>
|
||||
<div class="goods-show-price">
|
||||
<span>
|
||||
@@ -85,7 +87,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="goods-page">
|
||||
<div class="goods-page" v-if="total > 0">
|
||||
<el-pagination
|
||||
v-model:current-page="params.pageNumber"
|
||||
v-model:page-size="params.pageSize"
|
||||
@@ -105,6 +107,7 @@
|
||||
import { Message } from "@/utils/message";
|
||||
import { ArrowDown, ArrowUp } from '@element-plus/icons-vue';
|
||||
import GoodsClassNav from "@/components/nav/GoodsClassNav";
|
||||
import GoodsThumb from "@/components/goods/GoodsThumb.vue";
|
||||
import * as apiGoods from "@/api/goods";
|
||||
export default {
|
||||
name: "GoodsList",
|
||||
@@ -115,7 +118,10 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
sortIndex: 0, // 排序状态
|
||||
priceSortIndex: 4,
|
||||
sortPriceIndex: false, // 判断价格升序还是降序
|
||||
searched: false,
|
||||
recommendList: [],
|
||||
goodsTool: [
|
||||
// 排序类型
|
||||
{ title: "综合", en: "" },
|
||||
@@ -154,6 +160,16 @@ export default {
|
||||
this.getGoodsList();
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
displayGoods() {
|
||||
if (this.goodsList.length) return this.goodsList;
|
||||
return this.searched && !this.loading ? this.recommendList : [];
|
||||
},
|
||||
emptyTitle() {
|
||||
const keyword = this.params.keyword;
|
||||
return keyword ? `没有找到与“${keyword}”相关的商品` : "暂无商品";
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
// 搜索
|
||||
handleSearch(key) {
|
||||
@@ -204,11 +220,10 @@ export default {
|
||||
Message.warning("店铺信息不存在");
|
||||
return;
|
||||
}
|
||||
const routeUrl = this.$router.resolve({
|
||||
this.$router.push({
|
||||
path: "/merchant",
|
||||
query: { id },
|
||||
});
|
||||
window.open(routeUrl.href, "_blank");
|
||||
},
|
||||
// 分页 修改页码
|
||||
changePageNum(val) {
|
||||
@@ -230,14 +245,28 @@ export default {
|
||||
.then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.goodsList = res.result.records;
|
||||
this.goodsList = res.result.records || [];
|
||||
this.total = res.result.total;
|
||||
if (!this.goodsList.length) this.loadRecommend();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.goodsList = [];
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
this.searched = true;
|
||||
});
|
||||
},
|
||||
loadRecommend() {
|
||||
if (this.recommendList.length) return;
|
||||
apiGoods
|
||||
.goodsList({ pageNumber: 1, pageSize: 10, sort: "buyCount", order: "desc" })
|
||||
.then((res) => {
|
||||
if (res.success) this.recommendList = res.result.records || [];
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
getParams(val) {
|
||||
// 筛选条件回显
|
||||
Object.assign(this.params, val);
|
||||
@@ -256,6 +285,7 @@ export default {
|
||||
},
|
||||
components: {
|
||||
GoodsClassNav,
|
||||
GoodsThumb,
|
||||
ArrowDown,
|
||||
ArrowUp,
|
||||
},
|
||||
@@ -395,8 +425,12 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
.price-color {
|
||||
color: #b3b3b3;
|
||||
.el-icon {
|
||||
color: #c8c8c8;
|
||||
}
|
||||
|
||||
.el-icon.is-on {
|
||||
color: $theme_color;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -433,9 +467,30 @@ export default {
|
||||
background-color: transparent !important;
|
||||
font-weight: 600;
|
||||
|
||||
.price-color {
|
||||
color: $theme_color !important;
|
||||
.sort-arrow {
|
||||
color: $theme_color;
|
||||
}
|
||||
|
||||
.price-arrows .el-icon {
|
||||
color: #c8c8c8;
|
||||
}
|
||||
|
||||
.price-arrows .el-icon.is-on {
|
||||
color: $theme_color;
|
||||
}
|
||||
}
|
||||
|
||||
.list-empty {
|
||||
background: #fff;
|
||||
border: 1px solid #eee;
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.recommend-title {
|
||||
padding: 4px 16px 12px;
|
||||
color: #333;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.goods-list {
|
||||
|
||||
@@ -92,9 +92,9 @@
|
||||
</div>
|
||||
<div class="foot">
|
||||
<div type="flex" justify="space-around" class="help">
|
||||
<router-link to="/article" class="item" target="_blank">帮助</router-link>
|
||||
<router-link to="/article?id=1371779927900160000" class="item" target="_blank">隐私</router-link>
|
||||
<router-link to="/article?id=1371992704333905920" class="item" target="_blank">条款</router-link>
|
||||
<router-link to="/article" class="item">帮助</router-link>
|
||||
<router-link to="/article?id=1371779927900160000" class="item">隐私</router-link>
|
||||
<router-link to="/article?id=1371992704333905920" class="item">条款</router-link>
|
||||
</div>
|
||||
<div type="flex" justify="center" class="copyright">
|
||||
Copyright © {{year}} - Present
|
||||
@@ -601,3 +601,5 @@ export default {
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
44
buyer/src/pages/NotFound.vue
Normal file
44
buyer/src/pages/NotFound.vue
Normal file
@@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<div class="not-found-page">
|
||||
<BaseHeader></BaseHeader>
|
||||
<Search :show-tag="false"></Search>
|
||||
<div class="not-found">
|
||||
<h1>页面不存在</h1>
|
||||
<p>你访问的地址没有对应页面</p>
|
||||
<el-button type="primary" @click="$router.push('/')">返回首页</el-button>
|
||||
</div>
|
||||
<BaseFooter></BaseFooter>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "NotFound",
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.not-found {
|
||||
width: 1200px;
|
||||
min-height: 420px;
|
||||
margin: 24px auto 40px;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.not-found h1 {
|
||||
margin: 0;
|
||||
color: #333;
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.not-found p {
|
||||
margin: 12px 0 24px;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
@@ -66,7 +66,7 @@
|
||||
<el-form-item>
|
||||
<el-button class="signup-btn" @click="handleRegist">注册</el-button>
|
||||
</el-form-item>
|
||||
<p class="agreement">点击注册,表示您同意《<router-link to="/article?id=1371992704333905920" target="_blank">商城用户协议</router-link>》</p>
|
||||
<p class="agreement">点击注册,表示您同意《<router-link to="/article?id=1371992704333905920">商城用户协议</router-link>》</p>
|
||||
</el-form>
|
||||
<Verify
|
||||
ref="verify"
|
||||
@@ -78,9 +78,9 @@
|
||||
</div>
|
||||
<div class="foot">
|
||||
<div type="flex" justify="space-around" class="help">
|
||||
<router-link to="/article" class="item" target="_blank">帮助</router-link>
|
||||
<router-link to="/article?id=1371779927900160000" class="item" target="_blank">隐私</router-link>
|
||||
<router-link to="/article?id=1371992704333905920" class="item" target="_blank">条款</router-link>
|
||||
<router-link to="/article" class="item">帮助</router-link>
|
||||
<router-link to="/article?id=1371779927900160000" class="item">隐私</router-link>
|
||||
<router-link to="/article?id=1371992704333905920" class="item">条款</router-link>
|
||||
</div>
|
||||
<div type="flex" justify="center" class="copyright">
|
||||
Copyright © {{year}} - Present
|
||||
|
||||
@@ -1,35 +1,271 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="userBox">
|
||||
<div class="box">
|
||||
<!-- 我的订单组件 -->
|
||||
<myOrderPage :homePage="true" />
|
||||
</div>
|
||||
<div class="box">
|
||||
<!-- 近期收藏 -->
|
||||
<myFavorites :homePage="true" />
|
||||
</div>
|
||||
<div class="box">
|
||||
<div class="member-home">
|
||||
<div class="home-head">
|
||||
<div>
|
||||
<div class="home-hello">你好,{{ displayName }}</div>
|
||||
<div class="home-sub">查看订单进度、优惠券和账户余额</div>
|
||||
</div>
|
||||
<button type="button" class="msg-entry" @click="go('MsgList')">
|
||||
<el-icon :size="18"><Bell /></el-icon>
|
||||
<span>我的消息</span>
|
||||
<i v-if="unreadMsg > 0" class="msg-badge">{{ unreadLabel }}</i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="status-grid">
|
||||
<button
|
||||
v-for="item in orderStats"
|
||||
:key="item.key"
|
||||
type="button"
|
||||
class="stat-card"
|
||||
@click="item.action()"
|
||||
>
|
||||
<span class="stat-count">{{ item.count }}</span>
|
||||
<span class="stat-label">{{ item.label }}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="asset-grid">
|
||||
<button type="button" class="asset-card" @click="go('Coupons')">
|
||||
<div>
|
||||
<div class="asset-label">优惠券</div>
|
||||
<div class="asset-value">{{ couponCount }}<span>张可用</span></div>
|
||||
</div>
|
||||
<span class="asset-link">查看</span>
|
||||
</button>
|
||||
<button type="button" class="asset-card" @click="go('MoneyManagement')">
|
||||
<div>
|
||||
<div class="asset-label">账户余额</div>
|
||||
<div class="asset-value">¥{{ $filters.unitPrice(balance) }}</div>
|
||||
</div>
|
||||
<span class="asset-link">查看</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import myOrderPage from '@/pages/home/orderCenter/MyOrder'
|
||||
import myFavorites from '@/pages/home/memberCenter/Favorites'
|
||||
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 { refreshUnreadMessage } from "@/utils/unreadMessage";
|
||||
|
||||
function totalOf(res) {
|
||||
return res && res.success ? Number(res.result && res.result.total) || 0 : 0;
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'main',
|
||||
components: {
|
||||
myOrderPage,
|
||||
myFavorites
|
||||
}
|
||||
}
|
||||
name: "UserCenterHome",
|
||||
components: { Bell },
|
||||
data() {
|
||||
return {
|
||||
displayName: "会员",
|
||||
waitPay: 0,
|
||||
waitShip: 0,
|
||||
waitReceive: 0,
|
||||
afterSale: 0,
|
||||
couponCount: 0,
|
||||
balance: 0,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
unreadMsg() {
|
||||
return Number(this.$store.state.unreadMsg) || 0;
|
||||
},
|
||||
unreadLabel() {
|
||||
return this.unreadMsg > 99 ? "99+" : String(this.unreadMsg);
|
||||
},
|
||||
orderStats() {
|
||||
return [
|
||||
{ key: "pay", label: "待付款", count: this.waitPay, action: () => this.goOrder("WAIT_PAY") },
|
||||
{ key: "ship", label: "待发货", count: this.waitShip, action: () => this.goOrder("WAIT_SHIP") },
|
||||
{ key: "receive", label: "待收货", count: this.waitReceive, action: () => this.goOrder("WAIT_USE") },
|
||||
{ key: "after", label: "售后", count: this.afterSale, action: () => this.go("AfterSale") },
|
||||
];
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.readUser();
|
||||
this.loadSummary();
|
||||
},
|
||||
methods: {
|
||||
readUser() {
|
||||
try {
|
||||
const raw = storage.getItem("userInfo");
|
||||
const user = raw ? JSON.parse(raw) : {};
|
||||
this.displayName = user.nickName || user.username || "会员";
|
||||
} catch {
|
||||
this.displayName = "会员";
|
||||
}
|
||||
},
|
||||
loadSummary() {
|
||||
const page = { pageNumber: 1, pageSize: 1 };
|
||||
Promise.all([
|
||||
getOrderList({ ...page, tag: "WAIT_PAY" }).catch(() => null),
|
||||
getOrderList({ ...page, tag: "WAIT_SHIP" }).catch(() => null),
|
||||
getOrderList({ ...page, tag: "WAIT_USE" }).catch(() => null),
|
||||
afterSaleList({ ...page, sort: "createTime", order: "desc" }).catch(() => null),
|
||||
memberCouponList({ ...page, memberCouponStatus: "NEW" }).catch(() => null),
|
||||
getMembersWallet().catch(() => null),
|
||||
refreshUnreadMessage(),
|
||||
]).then(([pay, ship, receive, afterSale, coupon, wallet]) => {
|
||||
this.waitPay = totalOf(pay);
|
||||
this.waitShip = totalOf(ship);
|
||||
this.waitReceive = totalOf(receive);
|
||||
this.afterSale = totalOf(afterSale);
|
||||
this.couponCount = totalOf(coupon);
|
||||
this.balance = wallet && wallet.success ? wallet.result.memberWallet || 0 : 0;
|
||||
});
|
||||
},
|
||||
go(name) {
|
||||
this.$router.push({ name });
|
||||
},
|
||||
goOrder(tag) {
|
||||
this.$router.push({ name: "MyOrder", query: { tag } });
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.userBox {
|
||||
padding: 0 0 20px 0;
|
||||
.member-home {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.home-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding: 4px 4px 8px;
|
||||
}
|
||||
|
||||
.home-hello {
|
||||
color: #333;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
line-height: 26px;
|
||||
}
|
||||
|
||||
.home-sub {
|
||||
margin-top: 4px;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.msg-entry {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
height: 36px;
|
||||
padding: 0 14px;
|
||||
border: 1px solid #eee;
|
||||
border-radius: 18px;
|
||||
background: #fff;
|
||||
color: #333;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: $theme_color;
|
||||
border-color: $theme_color;
|
||||
}
|
||||
}
|
||||
|
||||
.msg-badge {
|
||||
min-width: 16px;
|
||||
height: 16px;
|
||||
padding: 0 4px;
|
||||
border-radius: 8px;
|
||||
background: $theme_color;
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
font-style: normal;
|
||||
line-height: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.status-grid,
|
||||
.asset-grid {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.status-grid {
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.asset-grid {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.stat-card,
|
||||
.asset-card {
|
||||
border: 1px solid #eee;
|
||||
border-radius: 8px;
|
||||
background: #fff;
|
||||
cursor: pointer;
|
||||
text-align: left;
|
||||
|
||||
&:hover {
|
||||
border-color: $theme_color;
|
||||
}
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
padding: 18px 16px;
|
||||
}
|
||||
|
||||
.stat-count {
|
||||
color: $theme_color;
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.asset-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 18px 20px;
|
||||
}
|
||||
|
||||
.asset-label {
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.asset-value {
|
||||
margin-top: 4px;
|
||||
color: #333;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
line-height: 28px;
|
||||
|
||||
span {
|
||||
margin-left: 4px;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
|
||||
.asset-link {
|
||||
color: $theme_color;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,44 +1,36 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<UserCenterLayout>
|
||||
<div class="safeList">
|
||||
<!-- 密码 -->
|
||||
<div class="safeItem">
|
||||
<div class="safeItem-icon">
|
||||
<el-icon :size="40"><Key /></el-icon>
|
||||
<div class="safe-list">
|
||||
<div class="safe-card">
|
||||
<div class="safe-icon">
|
||||
<el-icon :size="22"><Key /></el-icon>
|
||||
</div>
|
||||
<div class="safeItem-content">
|
||||
<div class="setDivItem">登录密码</div>
|
||||
<div class="setDivItem theme">互联网账号存在被盗风险,建议您定期更改密码以保护账户安全。</div>
|
||||
</div>
|
||||
<div class="safeItem-action">
|
||||
<el-button @click="modifyPwd">修改密码</el-button>
|
||||
<div class="safe-body">
|
||||
<p class="safe-title">登录密码</p>
|
||||
<p class="safe-desc">互联网账号存在被盗风险,建议您定期更改密码以保护账户安全。</p>
|
||||
</div>
|
||||
<el-button @click="modifyPwd">修改密码</el-button>
|
||||
</div>
|
||||
|
||||
<div class="safeItem safeItem-connect">
|
||||
<div class="safeItem-main">
|
||||
<div class="safeItem-icon">
|
||||
<el-icon :size="40"><Link /></el-icon>
|
||||
<div class="safe-card safe-card-connect">
|
||||
<div class="safe-card-main">
|
||||
<div class="safe-icon">
|
||||
<el-icon :size="22"><Link /></el-icon>
|
||||
</div>
|
||||
<div class="safeItem-content">
|
||||
<div class="setDivItem">第三方账户绑定</div>
|
||||
<div class="setDivItem theme">绑定后可使用第三方账号快捷登录。</div>
|
||||
</div>
|
||||
<div class="safeItem-action">
|
||||
<el-button v-if="!isBound(wechatConnect.type)" type="primary" @click="openBindModal(wechatConnect)">绑定</el-button>
|
||||
<el-button v-else @click="confirmUnbind(wechatConnect)">解绑</el-button>
|
||||
<div class="safe-body">
|
||||
<p class="safe-title">第三方账户绑定</p>
|
||||
<p class="safe-desc">绑定后可使用第三方账号快捷登录。</p>
|
||||
</div>
|
||||
<el-button v-if="!isBound(wechatConnect.type)" type="primary" @click="openBindModal(wechatConnect)">绑定</el-button>
|
||||
<el-button v-else @click="confirmUnbind(wechatConnect)">解绑</el-button>
|
||||
</div>
|
||||
<div class="connectList">
|
||||
<div class="connectRow">
|
||||
<div class="connectRowLeft">
|
||||
<span class="connectName">{{ wechatConnect.label }}</span>
|
||||
<el-tag v-if="isBound(wechatConnect.type)" color="success">已绑定</el-tag>
|
||||
<el-tag v-else>未绑定</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
<el-skeleton size="large" fix v-if="connectLoading"></el-skeleton>
|
||||
<div class="connect-row">
|
||||
<span class="connect-name">{{ wechatConnect.label }}</span>
|
||||
<span class="connect-status" :class="{ 'is-bound': isBound(wechatConnect.type) }">
|
||||
{{ isBound(wechatConnect.type) ? "已绑定" : "未绑定" }}
|
||||
</span>
|
||||
<el-skeleton v-if="connectLoading" animated class="connect-skeleton" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -273,73 +265,101 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.theme {
|
||||
color: $theme_color;
|
||||
.safe-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
.setDivItem {
|
||||
line-height: 1.75;
|
||||
}
|
||||
|
||||
.safeItem {
|
||||
.safe-card,
|
||||
.safe-card-main {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
border-bottom: 1px solid $border_color;
|
||||
padding: 16px 0;
|
||||
}
|
||||
|
||||
.safeItem-connect {
|
||||
.safe-card {
|
||||
padding: 20px;
|
||||
border: 1px solid #f0f0f0;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.safe-card-connect {
|
||||
display: block;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.safeItem-main {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
.safe-card-main {
|
||||
padding: 20px 20px 16px;
|
||||
}
|
||||
|
||||
.safeItem-icon {
|
||||
.safe-icon {
|
||||
flex-shrink: 0;
|
||||
width: 56px;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 8px;
|
||||
background: #fff5f4;
|
||||
color: $theme_color;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: $theme_color;
|
||||
}
|
||||
|
||||
.safeItem-content {
|
||||
.safe-body {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.safeItem-action {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.safe-title {
|
||||
margin: 0;
|
||||
color: #171A26;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.connectList {
|
||||
.safe-desc {
|
||||
margin: 6px 0 0;
|
||||
color: #999;
|
||||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.connect-row {
|
||||
position: relative;
|
||||
margin-top: 8px;
|
||||
margin-left: 72px;
|
||||
}
|
||||
|
||||
.connectRow {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 6px 0;
|
||||
}
|
||||
|
||||
.connectRowLeft {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin: 0 20px 16px 84px;
|
||||
padding-top: 12px;
|
||||
border-top: 1px solid #f5f5f5;
|
||||
}
|
||||
|
||||
.connectName {
|
||||
color: $title_color;
|
||||
.connect-name {
|
||||
color: #171A26;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.connect-status {
|
||||
height: 22px;
|
||||
padding: 0 8px;
|
||||
border-radius: 4px;
|
||||
background: #f5f5f5;
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.connect-status.is-bound {
|
||||
background: #f0faf3;
|
||||
color: #1f9d55;
|
||||
}
|
||||
|
||||
.connect-skeleton {
|
||||
width: 120px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
.wechatQrBox {
|
||||
|
||||
@@ -280,3 +280,9 @@ export default {
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -200,11 +200,10 @@ export default {
|
||||
|
||||
},
|
||||
goShop(id) { // 跳转店铺页面
|
||||
let url = this.$router.resolve({
|
||||
this.$router.push({
|
||||
path: '/merchant',
|
||||
query: { id }
|
||||
})
|
||||
window.open(url.href, '_blank')
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
<script>
|
||||
import { Message, Modal } from "@/utils/message";
|
||||
import { delMemberMsg, getMemberMessage, readMemberMsg } from '@/api/member.js';
|
||||
import { refreshUnreadMessage } from '@/utils/unreadMessage';
|
||||
|
||||
const CACHE_KEY = 'buyer-member-message';
|
||||
|
||||
@@ -71,7 +72,10 @@ export default {
|
||||
markRead () {
|
||||
if (!this.detail.id || this.detail.status !== 'UN_READY') return
|
||||
readMemberMsg(this.detail.id).then(res => {
|
||||
if (res && res.success) this.detail.status = 'ALREADY_READY'
|
||||
if (res && res.success) {
|
||||
this.detail.status = 'ALREADY_READY'
|
||||
refreshUnreadMessage()
|
||||
}
|
||||
}).catch(() => {})
|
||||
},
|
||||
goBack () {
|
||||
@@ -86,6 +90,7 @@ export default {
|
||||
delMemberMsg(this.detail.id).then((res) => {
|
||||
if (res.success) {
|
||||
Message.success('消息已成功放入回收站')
|
||||
refreshUnreadMessage()
|
||||
this.goBack()
|
||||
}
|
||||
})
|
||||
|
||||
@@ -94,6 +94,9 @@ export default {
|
||||
memberMsgList(this.params).then(res => {
|
||||
if (res.success) {
|
||||
this.messageData = res.result;
|
||||
if (this.params.status === 'UN_READY') {
|
||||
this.$store.commit('SET_UNREAD_MSG', Number(res.result.total) || 0);
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
@@ -212,11 +212,10 @@ export default {
|
||||
},
|
||||
// 跳转店铺首页
|
||||
shopPage(id) {
|
||||
let routeUrl = this.$router.resolve({
|
||||
this.$router.push({
|
||||
path: '/merchant',
|
||||
query: {id: id}
|
||||
});
|
||||
window.open(routeUrl.href, '_blank');
|
||||
},
|
||||
change(index) {
|
||||
this.activeTab = index
|
||||
|
||||
@@ -211,11 +211,10 @@ export default {
|
||||
},
|
||||
shopPage (id) {
|
||||
if (!id) return
|
||||
const routeUrl = this.$router.resolve({
|
||||
this.$router.push({
|
||||
path: '/merchant',
|
||||
query: { id }
|
||||
})
|
||||
window.open(routeUrl.href, '_blank')
|
||||
},
|
||||
filterOrderStatus (status) { // 获取订单状态中文
|
||||
const ob = this.afterSaleStatusList.filter(e => { return e.status === status });
|
||||
|
||||
@@ -223,7 +223,7 @@ export default {
|
||||
// 状态数组
|
||||
orderStatusList,
|
||||
afterSaleStatusList,
|
||||
changeWay: ['全部', '待支付', '待发货', '待收货/使用'],
|
||||
changeWay: ['全部', '待付款', '待发货', '待收货/使用'],
|
||||
activeOrderTab: 0,
|
||||
total: 0, // 数据总数
|
||||
spinShow: false, // 加载状态
|
||||
@@ -235,8 +235,18 @@ export default {
|
||||
},
|
||||
mounted () {
|
||||
if (this.homePage) this.params.pageSize = 5;
|
||||
if (!this.homePage) this.applyRouteTag();
|
||||
this.getList();
|
||||
},
|
||||
watch: {
|
||||
'$route.query.tag' () {
|
||||
if (this.homePage || this.$route.name !== 'MyOrder') return;
|
||||
const next = this.$route.query.tag || 'ALL';
|
||||
if (this.params.tag === next) return;
|
||||
this.applyRouteTag();
|
||||
this.getList();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 退款状态枚举
|
||||
refundPriceList(status) {
|
||||
@@ -261,22 +271,39 @@ export default {
|
||||
});
|
||||
window.open(routeUrl.href, '_blank');
|
||||
},
|
||||
orderTags () {
|
||||
return ['ALL', 'WAIT_PAY', 'WAIT_SHIP', 'WAIT_USE'];
|
||||
},
|
||||
applyRouteTag () {
|
||||
const tags = this.orderTags();
|
||||
const tag = this.$route.query.tag;
|
||||
const index = tags.indexOf(tag);
|
||||
this.activeOrderTab = index > -1 ? index : 0;
|
||||
this.params.tag = tags[this.activeOrderTab];
|
||||
this.params.pageNumber = 1;
|
||||
},
|
||||
// 切换订单状态
|
||||
change (index) {
|
||||
this.activeOrderTab = index;
|
||||
this.params.pageNumber = 1;
|
||||
delete this.params.commentStatus;
|
||||
const tags = ['ALL', 'WAIT_PAY', 'WAIT_SHIP', 'WAIT_USE'];
|
||||
const tags = this.orderTags();
|
||||
this.params.tag = tags[index] || 'ALL';
|
||||
const query = { ...this.$route.query };
|
||||
if (index === 0) delete query.tag;
|
||||
else query.tag = this.params.tag;
|
||||
const current = this.$route.query.tag || 'ALL';
|
||||
if (current !== this.params.tag) {
|
||||
this.$router.replace({ name: 'MyOrder', query });
|
||||
}
|
||||
this.getList()
|
||||
},
|
||||
// 跳转店铺首页
|
||||
shopPage (id) {
|
||||
let routeUrl = this.$router.resolve({
|
||||
this.$router.push({
|
||||
path: '/merchant',
|
||||
query: { id: id }
|
||||
});
|
||||
window.open(routeUrl.href, '_blank');
|
||||
},
|
||||
orderDetail (sn) {
|
||||
this.$router.push({ name: 'OrderDetail', query: {sn} });
|
||||
|
||||
@@ -589,11 +589,10 @@ export default {
|
||||
},
|
||||
// 跳转店铺首页
|
||||
shopPage(id) {
|
||||
let routeUrl = this.$router.resolve({
|
||||
this.$router.push({
|
||||
path: "/merchant",
|
||||
query: { id: id },
|
||||
});
|
||||
window.open(routeUrl.href, "_blank");
|
||||
},
|
||||
async getDetail() {
|
||||
// 获取订单详情
|
||||
|
||||
@@ -72,11 +72,10 @@ export default {
|
||||
},
|
||||
// 跳转店铺首页
|
||||
shopPage(id) {
|
||||
let routeUrl = this.$router.resolve({
|
||||
this.$router.push({
|
||||
path: "/merchant",
|
||||
query: { id: id },
|
||||
});
|
||||
window.open(routeUrl.href, "_blank");
|
||||
},
|
||||
clearAll() {
|
||||
// 清除全部足迹
|
||||
|
||||
@@ -836,11 +836,10 @@ export default {
|
||||
},
|
||||
// 跳转店铺首页
|
||||
goShopPage(id) {
|
||||
let routeUrl = this.$router.resolve({
|
||||
this.$router.push({
|
||||
path: "/merchant",
|
||||
query: { id: id },
|
||||
});
|
||||
window.open(routeUrl.href, "_blank");
|
||||
},
|
||||
useCoupon(id, used) {
|
||||
// 使用优惠券
|
||||
|
||||
@@ -29,46 +29,32 @@
|
||||
<div v-else class="goods-show-info1" v-for="(item, index) in goodsList" :key="index"
|
||||
@click="goGoodsDetail(item.skuId, item.goodsId)">
|
||||
<div class="goods-show-img">
|
||||
<img width="200" height="200" :src="item.goodsImage" />
|
||||
<img :src="item.goodsImage" :alt="item.goodsName" />
|
||||
</div>
|
||||
<div class="goods-show-price">
|
||||
<span>
|
||||
<span class="seckill-price text-danger">{{ $filters.unitPrice(item.price, "¥") }}</span>
|
||||
<span style="color: #999; text-decoration: line-through">{{ $filters.unitPrice(item.originalPrice, "¥") }}</span>
|
||||
</span>
|
||||
<span class="seckill-price text-danger">{{ $filters.unitPrice(item.price, "¥") }}</span>
|
||||
<span class="origin-price">{{ $filters.unitPrice(item.originalPrice, "¥") }}</span>
|
||||
</div>
|
||||
<div class="goods-show-detail" style="margin-bottom: 20px">
|
||||
<div class="goods-show-detail">
|
||||
<span>{{ item.goodsName }}</span>
|
||||
</div>
|
||||
<div class="goods-seckill-btn" :class="{
|
||||
'goods-seckill-btn-gray': nowHour < list[currIndex].timeLine,
|
||||
}">
|
||||
{{ nowHour >= list[currIndex].timeLine ? "立即抢购" : "即将开始" }}
|
||||
</div>
|
||||
<div v-if="nowHour >= list[currIndex].timeLine && item.quantity <= item.salesNum"
|
||||
class="goods-seckill-btn goods-seckill-btn-gray">
|
||||
已售罄
|
||||
</div>
|
||||
<div v-if="nowHour >= list[currIndex].timeLine" class="goods-show-num1">
|
||||
<span>已售{{
|
||||
(item.quantity && item.quantity > 0
|
||||
? Math.ceil(
|
||||
(item.salesNum / (item.quantity)) * 100
|
||||
)
|
||||
: 100) + "%"
|
||||
}}</span><el-progress
|
||||
<span>已售{{ salePercent(item) }}%</span>
|
||||
<el-progress
|
||||
:show-text="false"
|
||||
color="#df0021"
|
||||
style="width: 110px"
|
||||
class="ml_10"
|
||||
:percentage="item.quantity && item.quantity > 0
|
||||
? Math.ceil((item.salesNum / item.quantity) * 100)
|
||||
: 100"
|
||||
:color="'var(--theme-color, #ff3c2a)'"
|
||||
:percentage="salePercent(item)"
|
||||
/>
|
||||
</div>
|
||||
<div class="goods-show-seller">
|
||||
<span>{{ item.storeName }}</span>
|
||||
</div>
|
||||
<div
|
||||
class="goods-seckill-btn"
|
||||
:class="{ 'is-disabled': !canBuy(item) }"
|
||||
>
|
||||
{{ buyText(item) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -142,6 +128,25 @@ export default {
|
||||
});
|
||||
window.open(routeUrl.href, "_blank");
|
||||
},
|
||||
// 已售占比。没有库存时按售罄展示
|
||||
salePercent (item) {
|
||||
if (!item.quantity || item.quantity <= 0) return 100;
|
||||
return Math.min(100, Math.ceil((item.salesNum / item.quantity) * 100));
|
||||
},
|
||||
// 场次已开始,且销量达到库存
|
||||
isSoldOut (item) {
|
||||
return this.nowHour >= this.list[this.currIndex].timeLine && item.quantity <= item.salesNum;
|
||||
},
|
||||
// 场次已开始且未售罄才可抢
|
||||
canBuy (item) {
|
||||
return this.nowHour >= this.list[this.currIndex].timeLine && !this.isSoldOut(item);
|
||||
},
|
||||
// 按钮文案:未开始 / 已售罄 / 立即抢购
|
||||
buyText (item) {
|
||||
if (this.nowHour < this.list[this.currIndex].timeLine) return "即将开始";
|
||||
if (this.isSoldOut(item)) return "已售罄";
|
||||
return "立即抢购";
|
||||
},
|
||||
countDown (currIndex) {
|
||||
// 倒计时
|
||||
// 0点时间戳
|
||||
@@ -175,73 +180,96 @@ export default {
|
||||
<style lang="scss" scoped>
|
||||
@import "../../assets/styles/goodsList.scss";
|
||||
|
||||
.goods-seckill-btn {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
width: 80px;
|
||||
color: #fff;
|
||||
height: 35px;
|
||||
text-align: center;
|
||||
line-height: 35px;
|
||||
font-size: 14px;
|
||||
background-color: $theme_color;
|
||||
margin-bottom: 1px;
|
||||
margin-right: 1px;
|
||||
.seckill-list {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.goods-seckill-btn-gray {
|
||||
background-color: #666;
|
||||
}
|
||||
.promotion-decorate {
|
||||
width: auto;
|
||||
margin: 28px auto 16px;
|
||||
color: #171A26;
|
||||
font-size: 22px;
|
||||
font-weight: 600;
|
||||
|
||||
.promotion-decorate::before,
|
||||
.promotion-decorate::after {
|
||||
background-image: url("/src/assets/images/sprite@2x.png");
|
||||
&::before,
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.time-line {
|
||||
width: 1200px;
|
||||
max-width: 1200px;
|
||||
height: 60px;
|
||||
height: auto;
|
||||
margin: 0 auto;
|
||||
background-color: #fff;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
|
||||
li {
|
||||
padding: 0 30px;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
width: 240px;
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
width: auto;
|
||||
min-height: 78px;
|
||||
padding: 12px 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
gap: 4px;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #171A26;
|
||||
box-sizing: border-box;
|
||||
|
||||
& + li {
|
||||
box-shadow: inset 1px 0 0 #f2f2f2;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.not-curr {
|
||||
border: 1px solid #999;
|
||||
border-radius: 20px;
|
||||
padding: 3px 10px;
|
||||
margin-left: 10px;
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.currTimeline {
|
||||
background-color: $theme_color;
|
||||
background: $theme_color;
|
||||
color: #fff;
|
||||
|
||||
>div:nth-child(1) {
|
||||
font-size: 20px;
|
||||
&:hover {
|
||||
background: $theme_color;
|
||||
}
|
||||
|
||||
>div:nth-child(2) {
|
||||
font-size: 14px;
|
||||
margin-left: 10px;
|
||||
> div:nth-child(1) {
|
||||
font-size: 22px;
|
||||
line-height: 28px;
|
||||
}
|
||||
|
||||
> div:nth-child(2) {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.not-curr {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -249,55 +277,116 @@ export default {
|
||||
.seckill-goods-wrap {
|
||||
width: 1200px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
margin: 16px auto 40px;
|
||||
padding: 16px;
|
||||
box-sizing: border-box;
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
min-height: 320px;
|
||||
|
||||
.goods-list {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
column-gap: 10px;
|
||||
column-gap: 16px;
|
||||
}
|
||||
|
||||
:deep(.empty) {
|
||||
margin: 48px 0;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-show-info1 {
|
||||
width: calc(25% - 8px);
|
||||
width: calc(25% - 12px);
|
||||
min-width: 0;
|
||||
padding: 6px;
|
||||
margin: 10px 0;
|
||||
padding: 12px;
|
||||
margin: 0 0 16px;
|
||||
position: relative;
|
||||
border: 1px solid #fff;
|
||||
border: 1px solid #f0f0f0;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
background-color: #fff;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.goods-show-info1:hover {
|
||||
border: 1px solid #ccc;
|
||||
box-shadow: 0px 0px 15px #ccc;
|
||||
&:hover {
|
||||
border-color: #eee;
|
||||
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
}
|
||||
|
||||
.goods-show-img {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
background: #fafafa;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
max-width: 200px;
|
||||
height: auto;
|
||||
aspect-ratio: 1;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-show-price {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 8px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.origin-price {
|
||||
color: #999;
|
||||
font-size: 13px;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.goods-show-detail {
|
||||
height: 40px;
|
||||
margin: 8px 0;
|
||||
color: #333;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.goods-show-num1 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 12px;
|
||||
margin-bottom: 6px;
|
||||
margin-bottom: 8px;
|
||||
color: #666;
|
||||
|
||||
span {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
:deep(.el-progress) {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.el-progress-bar__inner {
|
||||
background-color: #df0021;
|
||||
.goods-show-seller {
|
||||
margin-bottom: 10px;
|
||||
color: #999;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.goods-seckill-btn {
|
||||
margin-top: auto;
|
||||
height: 34px;
|
||||
border-radius: 4px;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
line-height: 34px;
|
||||
font-size: 14px;
|
||||
background-color: $theme_color;
|
||||
|
||||
&.is-disabled {
|
||||
background: #c8c8c8;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -24,17 +24,25 @@
|
||||
<p>{{ userInfo.nickName }}</p>
|
||||
</div>
|
||||
|
||||
<el-menu-item index="UserCenter">
|
||||
<el-icon><House /></el-icon>
|
||||
<span>我的主页</span>
|
||||
</el-menu-item>
|
||||
<template v-for="(menu, index) in menuList" :key="index">
|
||||
<el-sub-menu v-if="menu.display" :index="menu.title">
|
||||
<template #title>
|
||||
<el-icon><Location /></el-icon>
|
||||
<el-icon><component :is="menuIcon(menu.icon)" /></el-icon>
|
||||
<span>{{ menu.title }}</span>
|
||||
</template>
|
||||
<el-menu-item
|
||||
v-for="(chlidren, i) in menu.menus"
|
||||
:key="i"
|
||||
:index="chlidren.path"
|
||||
>{{ chlidren.title }}</el-menu-item>
|
||||
>
|
||||
<el-icon><component :is="menuIcon(chlidren.icon)" /></el-icon>
|
||||
<span>{{ chlidren.title }}</span>
|
||||
<span v-if="chlidren.path === 'MsgList' && unreadMsg > 0" class="menu-badge">{{ unreadLabel }}</span>
|
||||
</el-menu-item>
|
||||
</el-sub-menu>
|
||||
</template>
|
||||
</el-menu>
|
||||
@@ -48,12 +56,51 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Location, User } from '@element-plus/icons-vue';
|
||||
import {
|
||||
Bell,
|
||||
ChatDotRound,
|
||||
Clock,
|
||||
Coin,
|
||||
Goods,
|
||||
House,
|
||||
List,
|
||||
Location,
|
||||
Lock,
|
||||
Present,
|
||||
RefreshLeft,
|
||||
Star,
|
||||
Ticket,
|
||||
Trophy,
|
||||
User,
|
||||
Wallet,
|
||||
Warning,
|
||||
} from '@element-plus/icons-vue';
|
||||
import menuList from "./menu";
|
||||
import Storage from "@/plugins/storage.js";
|
||||
import { refreshUnreadMessage } from "@/utils/unreadMessage";
|
||||
|
||||
const MENU_ICONS = {
|
||||
Bell,
|
||||
ChatDotRound,
|
||||
Clock,
|
||||
Coin,
|
||||
Goods,
|
||||
House,
|
||||
List,
|
||||
Location,
|
||||
Lock,
|
||||
Present,
|
||||
RefreshLeft,
|
||||
Star,
|
||||
Ticket,
|
||||
Trophy,
|
||||
User,
|
||||
Wallet,
|
||||
Warning,
|
||||
};
|
||||
|
||||
export default {
|
||||
components: { Location, User },
|
||||
components: { House, User },
|
||||
name: "Home",
|
||||
data() {
|
||||
return {
|
||||
@@ -67,14 +114,24 @@ export default {
|
||||
}
|
||||
return {};
|
||||
},
|
||||
unreadMsg() {
|
||||
return Number(this.$store.state.unreadMsg) || 0;
|
||||
},
|
||||
unreadLabel() {
|
||||
return this.unreadMsg > 99 ? "99+" : String(this.unreadMsg);
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
document.body.classList.add("buyer-user-center");
|
||||
refreshUnreadMessage();
|
||||
},
|
||||
beforeUnmount() {
|
||||
document.body.classList.remove("buyer-user-center");
|
||||
},
|
||||
methods: {
|
||||
menuIcon(name) {
|
||||
return MENU_ICONS[name] || Goods;
|
||||
},
|
||||
onSelect(name) {
|
||||
this.$router.push({ name });
|
||||
},
|
||||
@@ -134,6 +191,38 @@ export default {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.side-menu {
|
||||
:deep(.el-menu-item),
|
||||
:deep(.el-sub-menu__title) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
:deep(.el-menu-item .el-icon),
|
||||
:deep(.el-sub-menu__title .el-icon) {
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.menu-badge {
|
||||
margin-left: auto;
|
||||
min-width: 16px;
|
||||
height: 16px;
|
||||
padding: 0 4px;
|
||||
border-radius: 8px;
|
||||
background: $theme_color;
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
font-style: normal;
|
||||
line-height: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 选中项会把文字设成主题红。角标用 span,避免 i 继承成红底红字 */
|
||||
.side-menu :deep(.el-menu-item.is-active) .menu-badge {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.layout-footer-center {
|
||||
padding: 0px 15px;
|
||||
padding-bottom: 15px;
|
||||
|
||||
@@ -6,20 +6,20 @@
|
||||
|
||||
// 订单中心
|
||||
const order = [{
|
||||
icon: '',
|
||||
icon: 'List',
|
||||
title: '订单中心',
|
||||
menus: [{
|
||||
icon: '',
|
||||
icon: 'Goods',
|
||||
title: '我的订单',
|
||||
path: 'MyOrder'
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
icon: 'Location',
|
||||
title: '收货地址',
|
||||
path: 'MyAddress'
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
icon: 'RefreshLeft',
|
||||
title: '售后订单',
|
||||
path: 'AfterSale'
|
||||
}
|
||||
@@ -29,66 +29,66 @@ const order = [{
|
||||
|
||||
// 会员中心
|
||||
const member = [{
|
||||
icon: '',
|
||||
icon: 'User',
|
||||
title: '会员中心',
|
||||
menus: [{
|
||||
icon: '',
|
||||
icon: 'User',
|
||||
title: '用户信息',
|
||||
path: 'Profile'
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
icon: 'Lock',
|
||||
title: '账户安全',
|
||||
path: 'AccountSafe'
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
icon: 'Bell',
|
||||
title: '我的消息',
|
||||
path: 'MsgList'
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
icon: 'Clock',
|
||||
title: '我的足迹',
|
||||
path: 'MyTracks'
|
||||
},
|
||||
|
||||
{
|
||||
icon: '',
|
||||
icon: 'Star',
|
||||
title: '我的收藏',
|
||||
path: 'Favorites'
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
icon: 'ChatDotRound',
|
||||
title: '我的评论',
|
||||
path: 'CommentList'
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
icon: 'Warning',
|
||||
title: '我的投诉',
|
||||
path: 'ComplainList'
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
icon: 'Coin',
|
||||
title: '我的积分',
|
||||
path: 'Point'
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
icon: 'Trophy',
|
||||
title: '我的等级',
|
||||
path: 'MemberGrade'
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
icon: 'Ticket',
|
||||
title: '我的优惠券',
|
||||
path: 'Coupons'
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
icon: 'Wallet',
|
||||
title: '我的余额',
|
||||
path: 'MoneyManagement'
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
icon: 'Present',
|
||||
title: '我的礼品卡',
|
||||
path: 'MyGiftCards'
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user