Merge branch 'feature/task1.0.0' of http://internel-git.mashibing.cn/yanxuan-frontend/shop-pc into feature/task1.0.0

merge-requests/57/head
ch 2 years ago
commit c09cbb9900

Binary file not shown.

After

Width:  |  Height:  |  Size: 700 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 569 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 842 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 841 B

@ -34,4 +34,20 @@ table {border-collapse: collapse; border-spacing: 0;
a { text-decoration:none;
color: #333;
&:hover { text-decoration:none; color: #FF512B;}
}
}
/* 自定义滚动条样式 */
.scrollbar-self {
&::-webkit-scrollbar {
width: 4px;
background-color: none;
}
&::-webkit-scrollbar-track {
background-color: none;
}
&::-webkit-scrollbar-thumb {
background: #dddddd;
border-radius: 10px;
}
}

@ -112,4 +112,17 @@ $baseFontSize: 100 !default;
/*可点击文字hover*/
.hover-text:hover {
color: #FF875B;
}
/*扩大元素可点击热区*/
.expend-click {
position: relative;
&::after {
content: '';
position: absolute;
left: -10px;
top: -10px;
right: -10px;
bottom: -10px;
}
}

@ -1,7 +1,7 @@
<template>
<div class="bs-login">
<el-dialog
:visible.sync="dialogTableVisible"
:visible.sync="dialogVisible"
:show-close="false"
:close-on-click-modal="false"
:close-on-press-escape="false"
@ -35,11 +35,11 @@
>登录</el-button
>
</el-form>
<div class="login-wrap-content__agreement flex felx-start">
<div
class="wrap-content-agreement-icons"
@click="onAgreementSelect"
>
<div
@click="onAgreementSelect"
class="login-wrap-content__agreement flex felx-start"
>
<div class="wrap-content-agreement-icons">
<img
v-if="isAcceptAgreement"
class="icon-choose"
@ -48,7 +48,7 @@
<span v-else class="icon-unchoose"></span>
</div>
<span class="wrap-content-agreement__text flex-1">
同意用户协议隐私协议首次 登陆将自动注册
同意用户协议隐私协议首次登录将自动注册
</span>
</div>
</div>
@ -101,11 +101,16 @@ export default {
},
computed: {
...mapState(["token"]),
dialogTableVisible: {
dialogVisible: {
get() {
return this.visible;
},
set(val) {
if (!val) {
this.$refs.ruleForm.resetFields();
this.isAcceptAgreement = false;
this.countDown = 0;
}
this.$emit("update:visible", val);
},
},
@ -150,7 +155,7 @@ export default {
const { result, error } = await ApiPostLogin({
...this.form,
clientId: 1,
systemId: 3,
systemId: 1,
});
if (error !== null) {
Message.error(
@ -159,7 +164,7 @@ export default {
return;
}
if (result) {
this.dialogTableVisible = false;
this.dialogVisible = false;
this.$store.commit("setToken", result.token);
this.$store.dispatch("getUserInfo");
}
@ -167,7 +172,7 @@ export default {
});
},
onClose() {
this.dialogTableVisible = false;
this.dialogVisible = false;
},
},
};
@ -227,6 +232,7 @@ export default {
color: #999999;
font-size: 12px;
margin-top: 25px;
cursor: pointer;
.wrap-content-agreement-icons {
cursor: pointer;
.icon-unchoose {

@ -46,9 +46,9 @@ metadata:
namespace: yanxuan
spec:
ports:
- port: 3000
- port: $JAR_PORD
protocol: TCP
targetPort: 3000
targetPort: $JAR_PORD
selector:
app: $IMAGES
type: ClusterIP

@ -8,13 +8,7 @@
<template>
<div class="layout">
<BsLogin :visible.sync="loginVisible" />
<Header
:is-categroy-open="isHomePage"
:hide-bar-line="isHideBarLinePage"
:hide-sticky-shadow="isHideSeckillPage"
:show-categroy-tab="showCategroyTab"
:is-sticky="isSticky"
/>
<Header :is-sticky="isSticky" />
<Nuxt />
<Footer />
</div>
@ -23,7 +17,6 @@
import BsLogin from "@/components/BsLogin.vue";
import Header from "./module/header/index.vue";
import Footer from "./module/footer/index.vue";
const CATEGROY_HIDE_PAGES = [/\/account/]; // tab
export default {
name: "Layout",
@ -31,7 +24,6 @@ export default {
data() {
return {
isSticky: false,
ticking: false,
};
},
computed: {
@ -43,20 +35,6 @@ export default {
this.$store.commit("setLoginVisible", val);
},
},
isHomePage() {
return this.$route.path === "/";
},
isHideBarLinePage() {
return ["/", "/seckill"].includes(this.$route.path);
},
isHideSeckillPage() {
return this.$route.path === "/seckill";
},
showCategroyTab() {
return !CATEGROY_HIDE_PAGES.some((reg) => {
return reg.test(this.$route.path);
});
},
},
mounted() {
//
@ -66,16 +44,8 @@ export default {
window.removeEventListener("scroll", this.scrollEventMethod);
},
methods: {
scrollEventMethod(e) {
const that = this;
//
if (!that.ticking) {
window.requestAnimationFrame(function () {
that.ticking = false;
that.isSticky = window.scrollY > 300;
});
that.ticking = true;
}
scrollEventMethod() {
this.isSticky = window.scrollY > 300;
},
},
};

@ -30,15 +30,15 @@ export default {
icon: require("~/assets/img/layout/footer-1.png"),
},
{
label: "马士兵严选",
label: "100%正品",
icon: require("~/assets/img/layout/footer-2.png"),
},
{
label: "马士兵严选",
label: "365天质保",
icon: require("~/assets/img/layout/footer-3.png"),
},
{
label: "马士兵严选",
label: "售后无忧",
icon: require("~/assets/img/layout/footer-4.png"),
},
],

@ -0,0 +1,274 @@
<template>
<!-- 购物车 -->
<el-popover
popper-class="header-cart-popover"
trigger="hover"
placement="bottom"
width="330"
:disabled="cartCount === 0"
>
<div
slot="reference"
class="header-cart-popover__refrence flex flex-middle"
@click="onJumpCart"
>
<img src="~/assets/img/layout/icon-shop.png" />
<span>购物车</span>
<div v-if="cartCount > 0" class="wrap-right-cart__tip">
{{ cartCount }}
</div>
</div>
<div class="header-cart-products scrollbar-self">
<div
v-for="item in products"
:key="item.id"
@click="onJumpGoodsDetail(item.product.id)"
class="header-cart-products__wrap flex flex-middle flex-between"
>
<div class="cart-products-wrap__left flex felx-middle">
<div class="products-wrap-left__cover">
<img :src="item.productMainPicture" />
</div>
<div class="products-wrap-left__info">
<p class="wrap-left-info__title">{{ item.productName }}</p>
<div class="wrap-left-info__detail flex">
<span class="left-info-detail__skuname">{{
item.productSku.name
}}</span>
<span class="left-info-detail__count">{{ item.number }}</span>
</div>
</div>
</div>
<UiMoney
class="cart-products-wrap__right"
:float="true"
:money="item.product.startingPrice"
/>
</div>
<!-- 失效商品 -->
<template v-if="failureProducts.length > 0">
<div class="header-cart-products__bar">以下商品已失效</div>
<div
v-for="item in failureProducts"
:key="item.id"
@click="onJumpGoodsDetail(item.product.id)"
class="header-cart-products__wrap flex flex-middle flex-between"
>
<div class="cart-products-wrap__left flex felx-middle">
<div class="products-wrap-left__cover">
<img :src="item.productMainPicture" />
</div>
<div class="products-wrap-left__info">
<p
class="wrap-left-info__title header-cart-products--failure-color"
>
{{ item.productName }}
</p>
<div class="wrap-left-info__detail flex">
<span class="left-info-detail__skuname">{{
item.productSku && item.productSku.name
}}</span>
<span class="left-info-detail__count">{{ item.number }}</span>
</div>
</div>
</div>
<UiMoney
class="header-cart-products--failure-color"
:float="true"
:money="item.product.startingPrice"
/>
</div>
</template>
</div>
<div class="header-cart-bottom flex flex-middle flex-between">
<p>{{ cartCount }}件商品</p>
<UiButton type="red_panel" :radius="true" @click="onJumCartPage"
>去购物车</UiButton
>
</div>
</el-popover>
</template>
<script>
import { mapState } from "vuex";
import UiButton from "@/components/UiButton.vue";
export default {
name: "HeaderCart",
components: { UiButton },
data() {
return {
products: [],
failureProducts: [], //
};
},
computed: {
...mapState(["cartProducts", "token"]),
cartCount() {
return this.cartProducts.length;
},
},
watch: {
token: {
immediate: true,
handler(val) {
if (val) {
this.$store.dispatch("getCartProducts");
return;
}
this.$store.commit("setCartProducts", []);
},
},
cartProducts: {
immediate: true,
deep: true,
handler(val) {
this.products = [];
this.failureProducts = [];
val.forEach((item) => {
if (item.product.isEnable) {
if (item.productSku && item.productSku.stock > 0) {
//
this.products.push(item);
return;
}
this.failureProducts.push(item);
return;
}
this.failureProducts.push(item);
});
},
},
},
methods: {
onJumpCart() {
if (!this.$isLoginValidate()) {
return;
}
this.$router.push("/cart");
},
onJumpGoodsDetail(id) {
this.$router.push(`/goods/detail/${id}`);
},
onJumCartPage() {
this.$router.push("/cart");
},
},
};
</script>
<style lang="scss">
.header-cart-popover {
padding: 16px 20px;
}
</style>
<style lang="scss" scoped>
.header-cart-popover__refrence {
padding: 0 18px;
height: 42px;
line-height: 42px;
color: #999999;
border-radius: 8px 8px 8px 8px;
border: 1px solid #eeeeee;
cursor: pointer;
.wrap-right-cart__tip {
min-width: 14px;
height: 14px;
padding: 0 3px;
font-size: 10px;
line-height: 14px;
text-align: center;
background: #ff512b;
border-radius: 50%;
color: #ffffff;
}
img {
width: 16px;
height: 16px;
margin: 0 4px 0 10px;
}
}
.header-cart-popover {
padding: 20px 16px;
.header-cart-products {
padding: 0 10px 50px 0;
max-height: 360px;
overflow: auto;
&--failure-color {
color: #999999 !important;
}
.header-cart-products__wrap {
margin-bottom: 20px;
cursor: pointer;
.cart-products-wrap__left {
.products-wrap-left__cover {
width: 54px;
height: 54px;
padding: 3px;
border: 1px solid #eeeeee;
border-radius: 4px;
margin-right: 11px;
img {
width: 100%;
height: 100%;
}
}
.products-wrap-left__info {
font-size: 12px;
color: #999999;
.wrap-left-info__title {
display: block;
width: 120px;
@include ellipsis;
font-size: 14px;
color: #333333;
margin-bottom: 10px;
}
.wrap-left-info__detail {
.left-info-detail__skuname {
display: block;
width: 70px;
@include ellipsis;
}
.left-info-detail__count {
&::before {
content: "X";
font-size: 8px;
}
}
}
}
}
.cart-products-wrap__right {
color: #ff512b;
}
}
.header-cart-products__bar {
font-size: 14px;
width: 298px;
height: 40px;
line-height: 40px;
padding: 0 11px;
background: #f8f8f8;
color: #999999;
margin-bottom: 20px;
}
}
.header-cart-bottom {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 50px;
background: #eeeeee;
padding: 0 16px;
font-size: 14px;
color: #666666;
/deep/.ui-button {
width: 84px;
height: 30px;
font-size: 14px;
font-weight: normal;
padding: 0;
}
}
}
</style>

@ -0,0 +1,221 @@
<template>
<div class="header-category">
<!-- 热门分类 -->
<div
v-show="showCategroyTab"
class="header-box-tab__category"
@mouseenter="handleCategoryChange(true)"
@mouseleave="handleCategoryChange(false)"
>
<div class="tab-category__label flex flex-center flex-middle">
<img src="~/assets/img/layout/icon-category.png" />
<span>热门分类</span>
</div>
<div
v-show="isCategroyOpen || categroyVisible"
class="tab-category__menu flex"
@mouseenter="handleCategoryTwoChange(true)"
@mouseleave="handleCategoryTwoChange(false)"
>
<!-- 左侧一级分类 -->
<div class="tab-category-menu__left">
<div
v-for="item in categroyData"
:key="item.id"
@mouseenter="handleCategoryHover(item.id)"
@click="onCategoryClick(item.id, CATEGROY_LEVEL.ONE)"
class="menu-left__item flex flex-middle"
:class="{
'menu-left__item--light': item.id === currentCategroyId,
}"
>
<img />
<span>{{ item.name }}</span>
</div>
</div>
<!-- 右侧二级分类 -->
<div
v-show="categroyTwoVisible"
class="tab-category-menu__right flex-1"
>
<div
v-for="item in categroyData"
:key="item.id"
@mouseenter="handleCategoryHover(item.id)"
class="category-menu-right__wrap"
:class="{
'category-menu-right__wrap--light': item.id === currentCategroyId,
}"
>
<span
v-for="itemList in item.list"
:key="itemList.id"
class="menu-right-wrap__item"
@click="onCategoryClick(itemList.id, CATEGROY_LEVEL.TWO)"
>{{ itemList.name }}</span
>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import {
ApiGetCategoryOneList,
ApiGetCategoryTwoAndGoods,
} from "@/plugins/api/goods";
import { CATEGROY_LEVEL } from "@/constants";
const CATEGROY_HIDE_PAGES = [/\/account/]; // tab
export default {
name: "HeaderCategory",
data() {
return {
CATEGROY_LEVEL,
categroyTwoVisible: false, //
categroyVisible: false, //
currentCategroyId: 0, // id
categroyData: [],
};
},
computed: {
showCategroyTab() {
return !CATEGROY_HIDE_PAGES.some((reg) => {
return reg.test(this.$route.path);
});
},
//
isCategroyOpen() {
return this.$route.path === "/";
},
},
created() {
this.getCategroyData();
},
methods: {
//
async getCategroyData() {
const { result } = await ApiGetCategoryOneList();
if (result && result.length > 0) {
this.categroyData = await Promise.all(
result.map(async (item) => {
const { result: resultGoods } = await ApiGetCategoryTwoAndGoods({
categoryId: item.id,
});
if (resultGoods && resultGoods.length > 0) {
return {
...item,
list: resultGoods,
};
}
})
);
}
},
//
handleCategoryHover(id) {
this.currentCategroyId = id;
},
//
onCategoryClick(id, levelType) {
this.categroyVisible = false;
this.categroyTwoVisible = false;
this.$router.push({
path: "/goods/list",
query: {
id,
levelType,
},
});
},
//
handleCategoryChange(val) {
this.categroyVisible = val;
if (!val) {
this.currentCategroyId = 0;
}
},
//
handleCategoryTwoChange(val) {
this.categroyTwoVisible = val;
},
},
};
</script>
<style lang="scss" scoped>
.header-category {
height: 100%;
.header-box-tab__category {
position: relative;
height: 100%;
.tab-category__label {
width: 190px;
height: 100%;
background: linear-gradient(270deg, #ffa25a 0%, #ff7f39 100%);
border-radius: 4px 4px 0px 0px;
font-weight: bold;
color: #ffffff;
cursor: pointer;
img {
width: 20px;
height: 20px;
margin-right: 16px;
}
}
.tab-category__menu {
position: absolute;
top: 38px;
left: 0;
font-size: 14px;
color: #333333;
.tab-category-menu__left {
width: 190px;
padding: 15px 0;
background: #ffffff;
.menu-left__item {
height: 50px;
cursor: pointer;
padding: 0 24px 0 41px;
&:hover,
&--light {
color: #ff875b;
}
img {
width: 20px;
height: 20px;
margin-right: 16px;
}
}
}
.tab-category-menu__right {
padding: 15px 26px;
box-shadow: 7px 0px 10px 1px rgba(0, 0, 0, 0.1);
border: 1px solid #eeeeee;
background: #ffffff;
.category-menu-right__wrap {
height: 50px;
line-height: 50px;
padding: 0 16px;
font-size: 12px;
color: #999999;
white-space: nowrap;
&:hover,
&--light {
background: #f8f8f8;
}
.menu-right-wrap__item {
color: #999999;
margin-right: 20px;
cursor: pointer;
&:hover {
color: #ff875b;
}
}
}
}
}
}
}
</style>

@ -155,13 +155,18 @@ export default {
};
</script>
<style lang="scss">
.header-info-bar__dropdown,
.header-info-bar__popover {
.popper__arrow {
display: none;
}
}
</style>
<style lang="scss" scoped>
.header-info-bar__dropdown {
width: 200px;
margin-top: 0 !important;
padding-bottom: 0;
.popper__arrow {
display: none;
}
.el-dropdown-menu__item:hover {
background: #f8f9fb;
color: #666666;
@ -203,12 +208,7 @@ export default {
margin-bottom: 15px;
}
}
.popper__arrow {
display: none !important;
}
}
</style>
<style lang="scss" scoped>
.info-bar-header {
height: 30px;
color: #999999;

@ -4,7 +4,7 @@
<div v-show="isSticky">
<div
class="sticky-bar-header"
:class="{ 'sticky-bar-header--hide-shadow': hideStickyShadow }"
:class="{ 'sticky-bar-header--hide-shadow': hideBarShadow }"
>
<div class="sticky-bar-header__wrap flex flex-middle flex-between">
<div class="flex flex-middle">
@ -77,78 +77,12 @@
<img src="~/assets/img/layout/icon-search.png" />
</div>
</div>
<div
class="box-wrap-right__cart flex flex-middle"
@click="onJumpCart"
>
<img src="~/assets/img/layout/icon-shop.png" />
<span>购物车</span>
<div v-if="cartCount > 0" class="wrap-right-cart__tip">
{{ cartCount }}
</div>
</div>
<!-- 购物车 -->
<HeaderCart />
</div>
</div>
<!-- 热门分类 -->
<div class="bar-header-box__tab flex flex-middle">
<div
v-show="showCategroyTab"
class="header-box-tab__category"
@mouseenter="handleCategoryChange(true)"
@mouseleave="handleCategoryChange(false)"
>
<div class="tab-category__label flex flex-center flex-middle">
<img src="~/assets/img/layout/icon-category.png" />
<span>热门分类</span>
</div>
<div
v-show="isCategroyOpen || categroyVisible"
class="tab-category__menu flex"
@mouseenter="handleCategoryTwoChange(true)"
@mouseleave="handleCategoryTwoChange(false)"
>
<!-- 左侧一级分类 -->
<div class="tab-category-menu__left">
<div
v-for="item in categroyData"
:key="item.id"
@mouseenter="handleCategoryHover(item.id)"
@click="onCategoryClick(item.id, CATEGROY_LEVEL.ONE)"
class="menu-left__item flex flex-middle"
:class="{
'menu-left__item--light': item.id === currentCategroyId,
}"
>
<img />
<span>{{ item.name }}</span>
</div>
</div>
<!-- 右侧二级分类 -->
<div
v-show="categroyTwoVisible"
class="tab-category-menu__right flex-1"
>
<div
v-for="item in categroyData"
:key="item.id"
@mouseenter="handleCategoryHover(item.id)"
class="category-menu-right__wrap"
:class="{
'category-menu-right__wrap--light':
item.id === currentCategroyId,
}"
>
<span
v-for="itemList in item.list"
:key="itemList.id"
class="menu-right-wrap__item"
@click="onCategoryClick(itemList.id, CATEGROY_LEVEL.TWO)"
>{{ itemList.name }}</span
>
</div>
</div>
</div>
</div>
<HeaderCategory />
<div
v-for="item in tabList"
:key="item.value"
@ -170,58 +104,27 @@
</template>
<script>
import { mapState } from "vuex";
import {
ApiGetCategoryOneList,
ApiGetCategoryTwoAndGoods,
} from "@/plugins/api/goods";
import { ApiGetCartList } from "@/plugins/api/cart";
import { CATEGROY_LEVEL } from "@/constants";
import HeaderInfoBar from "./HeaderInfoBar.vue";
import HeaderCategory from "./HeaderCategory.vue";
import HeaderCart from "./HeaderCart.vue";
export default {
name: "DefaultHeader",
components: { HeaderInfoBar },
components: { HeaderInfoBar, HeaderCategory, HeaderCart },
props: {
//
isSticky: {
type: Boolean,
default: false,
},
//
isCategroyOpen: {
type: Boolean,
default: false,
},
// tab
showCategroyTab: {
type: Boolean,
default: true,
},
//
hideBarLine: {
type: Boolean,
default: false,
},
// tab
hideStickyShadow: {
type: Boolean,
default: true,
},
},
data() {
return {
CATEGROY_LEVEL,
searchContent: "",
tabPath: "/",
categroyTwoVisible: false, //
categroyVisible: false, //
currentCategroyId: 0, // id
categroyData: [],
cartCount: 0, //
cartProductList: [], //
};
},
computed: {
@ -239,6 +142,16 @@ export default {
}
return defaultList;
},
// tab
hideBarShadow() {
return ["/seckill"].includes(this.$route.path);
},
//
hideBarLine() {
return ["/", "/seckill"].includes(this.$route.path);
},
},
watch: {
"$route.path"(val) {
@ -247,79 +160,15 @@ export default {
}
},
},
created() {
this.getCategroyData();
this.getCartInfo();
},
methods: {
onLoginClick() {
this.$isLoginValidate();
},
//
handleCategoryHover(id) {
this.currentCategroyId = id;
},
//
onCategoryClick(id, levelType) {
this.categroyVisible = false;
this.categroyTwoVisible = false;
this.$router.push({
path: "/goods/list",
query: {
id,
levelType,
},
});
},
//
handleCategoryChange(val) {
this.categroyVisible = val;
if (!val) {
this.currentCategroyId = 0;
}
},
//
handleCategoryTwoChange(val) {
this.categroyTwoVisible = val;
},
onTabSelect(value) {
this.tabPath = value;
this.searchContent = "";
this.$router.push({ path: value });
},
onJumpCart() {
if (!this.$isLoginValidate()) {
return;
}
this.$router.push("/cart");
},
//
async getCartInfo() {
const { result } = await ApiGetCartList();
if (result) {
this.cartCount = result.number;
}
},
//
async getCategroyData() {
const { result } = await ApiGetCategoryOneList();
if (result && result.length > 0) {
this.categroyData = await Promise.all(
result.map(async (item) => {
const { result: resultGoods } = await ApiGetCategoryTwoAndGoods({
categoryId: item.id,
});
if (resultGoods && resultGoods.length > 0) {
return {
...item,
list: resultGoods,
};
}
})
);
}
},
onSearch() {
this.$router.push({
path: "/goods/list",
@ -455,105 +304,10 @@ export default {
}
}
}
.box-wrap-right__cart {
padding: 0 18px;
height: 42px;
line-height: 42px;
color: #999999;
border-radius: 8px 8px 8px 8px;
border: 1px solid #eeeeee;
cursor: pointer;
.wrap-right-cart__tip {
min-width: 14px;
height: 14px;
padding: 0 3px;
font-size: 10px;
line-height: 14px;
text-align: center;
background: #ff512b;
border-radius: 50%;
color: #ffffff;
}
img {
width: 16px;
height: 16px;
margin: 0 4px 0 10px;
}
}
}
}
.bar-header-box__tab {
height: 38px;
.header-box-tab__category {
position: relative;
height: 100%;
.tab-category__label {
width: 190px;
height: 100%;
background: linear-gradient(270deg, #ffa25a 0%, #ff7f39 100%);
border-radius: 4px 4px 0px 0px;
font-weight: bold;
color: #ffffff;
cursor: pointer;
img {
width: 20px;
height: 20px;
margin-right: 16px;
}
}
.tab-category__menu {
position: absolute;
top: 38px;
left: 0;
font-size: 14px;
color: #333333;
.tab-category-menu__left {
width: 190px;
padding: 15px 0;
background: #ffffff;
.menu-left__item {
height: 50px;
cursor: pointer;
padding: 0 24px 0 41px;
&:hover,
&--light {
color: #ff875b;
}
img {
width: 20px;
height: 20px;
margin-right: 16px;
}
}
}
.tab-category-menu__right {
padding: 15px 26px;
box-shadow: 7px 0px 10px 1px rgba(0, 0, 0, 0.1);
border: 1px solid #eeeeee;
background: #ffffff;
.category-menu-right__wrap {
height: 50px;
line-height: 50px;
padding: 0 16px;
font-size: 12px;
color: #999999;
white-space: nowrap;
&:hover,
&--light {
background: #f8f8f8;
}
.menu-right-wrap__item {
color: #999999;
margin-right: 20px;
cursor: pointer;
&:hover {
color: #ff875b;
}
}
}
}
}
}
.header-box-tab__common--light {
color: #ff7f39 !important;
}

@ -18,7 +18,10 @@
</div>
<!-- 有物流信息 -->
<div v-else v-loading="loading">
<div v-infinite-scroll="handleListload" class="home-logisitcs-content">
<div
v-infinite-scroll="handleListload"
class="home-logisitcs-content scrollbar-self"
>
<div
v-for="item in list"
:key="item.orderId"
@ -165,17 +168,6 @@ export default {
max-height: 620px;
overflow: auto;
padding: 30px;
&::-webkit-scrollbar {
width: 4px;
background-color: none;
}
&::-webkit-scrollbar-track {
background-color: none;
}
&::-webkit-scrollbar-thumb {
background: #dddddd;
border-radius: 10px;
}
.home-logisitcs-content__item {
margin-bottom: 30px;
cursor: pointer;

@ -76,7 +76,8 @@ export default {
},
rules: {
nickname: [
{ min: 1, max: 5, message: "请输入1-10个字符", trigger: "blur" },
{ required: true, message: "请输入昵称", trigger: "blur" },
{ min: 1, max: 10, message: "请输入1-10个字符", trigger: "blur" },
],
},
ossUploadUrl: "",

@ -223,6 +223,7 @@ export default {
}else{
this.checkedIds = [];
}
this.$store.dispatch('getCartProducts');
})
},

@ -176,7 +176,7 @@ import UiMoney from "@/components/UiMoney.vue";
import UiButton from "@/components/UiButton.vue";
import UiGoodsItem from "@/components/UiGoodsItem.vue";
import BsChosen from "@/components/BsChosen.vue";
import {ApiPutAddCart} from "@/plugins/api/cart";
import { ApiPutAddCart } from "@/plugins/api/cart";
import {
ApiGetGoodsDetail,
ApiGetGoodsSkus,
@ -264,6 +264,16 @@ export default {
},
},
methods: {
addCart() {
let ids = [this.detailData.id];
this.$router.push({
path: `/orderSubmit`,
query: {
mode: "cart",
ids,
},
});
},
isStock() {
return this.skuData.some((item) => item.stock > 0);
},
@ -426,26 +436,27 @@ export default {
});
},
/**
* 加入购物车
*/
async addCart(){
if(!this.curSku.skuId){
/**
* 加入购物车
*/
async addCart() {
if (!this.curSku.skuId) {
this.$message.error("请选择规格~");
return false;
}
const {error, result} = await ApiPutAddCart({
productSkuId : this.curSku.skuId,
productId : this.detailData.id,
number : this.curBuyNum
});
if(error){
this.$message.error(error.message);
return false;
}
this.$message.success('加入购物车成功~');
// this.$Router.push('/cart');
},
return false;
}
const { error, result } = await ApiPutAddCart({
productSkuId: this.curSku.skuId,
productId: this.detailData.id,
number: this.curBuyNum,
});
if (error) {
this.$message.error(error.message);
return false;
}
this.$message.success("加入购物车成功~");
this.$store.dispatch('getCartProducts');
// this.$Router.push('/cart');
},
},
};
</script>

@ -21,10 +21,7 @@
<div class="home-wrap-select__header flex flex-center flex-middle">
<img src="~/assets/img/common/icon-select.png" />
<strong>为你精选</strong>
<img
class="wrap-select-header__img--rotate"
src="~/assets/img/common/icon-select.png"
/>
<img src="~/assets/img/common/icon-select-turn.png" />
</div>
<div v-loading="loading">
<div class="home-wrap-select__content flex flex-wrap">
@ -43,6 +40,7 @@
</div>
</div>
</div>
<TabbarFixed :scroll-top="scrollTop" />
</div>
</template>
@ -61,11 +59,12 @@ import {
import Banner from "./module/Banner.vue";
import Seckil from "./module/Seckill.vue";
import Pick from "./module/Pick.vue";
import TabbarFixed from "./module/TabbarFixed.vue";
const SECKILL_COUNT = 20; //
const NEW_COUNT = 5; //
export default {
components: { Banner, Seckil, Pick, UiGoodsItem, UiPagination },
components: { Banner, Seckil, Pick, UiGoodsItem, UiPagination, TabbarFixed },
async asyncData({ store }) {
//
let seckillData = { activityTimeVO: null };
@ -122,12 +121,24 @@ export default {
total: 0,
loading: false,
currentPage: 0,
scrollTop: 0,
};
},
created() {
this.getSelectProducts();
},
mounted() {
//
window.addEventListener("scroll", this.scrollEventMethod);
},
destroyed() {
window.removeEventListener("scroll", this.scrollEventMethod);
},
methods: {
scrollEventMethod() {
this.scrollTop = window.scrollY;
},
//
async handleSeckillRefresh() {
const { result: seckillData } = await ApiGetHomeSeckill();
@ -166,9 +177,6 @@ export default {
font-size: 24px;
color: #333333;
margin-bottom: 30px;
.wrap-select-header__img--rotate {
transform: rotate(180deg);
}
img {
width: 24px;
height: 22px;

@ -26,11 +26,11 @@ export default {
return {
bannerList: [
{
url: "https://msb-edu-dev.oss-cn-beijing.aliyuncs.com/uc/account-avatar/banner4.jpg",
url: "https://msb-edu-dev.oss-cn-beijing.aliyuncs.com/uc/account-avatar/goods13.jpg",
id: 13,
},
{
url: "https://msb-edu-dev.oss-cn-beijing.aliyuncs.com/uc/account-avatar/1.png",
url: "https://msb-edu-dev.oss-cn-beijing.aliyuncs.com/uc/account-avatar/goods30.jpg",
id: 30,
},
{
@ -38,7 +38,7 @@ export default {
id: 15,
},
{
url: "https://msb-edu-dev.oss-cn-beijing.aliyuncs.com/uc/account-avatar/3banner.png",
url: "https://msb-edu-dev.oss-cn-beijing.aliyuncs.com/uc/account-avatar/goods40.jpg",
id: 40,
},
],

@ -0,0 +1,131 @@
<template>
<div class="home-tabbar-fixed flex">
<div v-show="appHover" class="home-tabbar-fixed__qrcode">
<img src="~/assets/img/common/app-qrcode.png" />
<p>扫一扫上方二维码 下载APP</p>
</div>
<div
class="home-tabbar-fixed__box flex flex-column flex-middle"
:class="{ 'home-tabbar-fixed__box--height-short': !showToTop }"
>
<div
@mouseenter="appHover = true"
@mouseleave="appHover = false"
class="tabbar-fixed-box__common flex flex-middle"
>
<span v-show="appHover">app</span>
<img v-show="!appHover" src="~/assets/img/home/icon-app.png" />
</div>
<div class="tabbar-fixed-box__line"></div>
<div
@mouseenter="customerHover = true"
@mouseleave="customerHover = false"
@click="onConcatCustomer"
class="tabbar-fixed-box__common flex flex-middle"
>
<span v-show="customerHover"></span>
<img
v-show="!customerHover"
src="~/assets/img/home/icon-customer.png"
/>
</div>
<div v-show="showToTop">
<div class="tabbar-fixed-box__line"></div>
<div
@mouseenter="totopHover = true"
@mouseleave="totopHover = false"
@click="toPageTop"
class="tabbar-fixed-box__common flex flex-middle"
>
<img
v-show="totopHover"
src="~/assets/img/home/icon-totop-light.png"
/>
<img v-show="!totopHover" src="~/assets/img/home/icon-totop.png" />
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "HomeTabbarFixed",
props: {
scrollTop: {
type: Number,
default: 0,
},
},
data() {
return {
appHover: false,
customerHover: false,
totopHover: false,
};
},
computed: {
showToTop() {
return this.scrollTop > 400;
},
},
methods: {
onConcatCustomer() {
if (!this.$isLoginValidate()) {
return;
}
},
toPageTop() {
document.querySelector("body").scrollIntoView({ behavior: "smooth" });
},
},
};
</script>
<style lang="scss" scoped>
.home-tabbar-fixed {
position: fixed;
right: 270px;
top: 568px;
z-index: 10;
.home-tabbar-fixed__qrcode {
width: 230px;
height: 260px;
background: #ffffff;
box-shadow: 0px 4px 30px 1px rgba(0, 0, 0, 0.1);
font-size: 14px;
color: #666666;
padding: 22px;
margin-right: 10px;
img {
width: 186px;
height: 186px;
margin-bottom: 14px;
}
}
.home-tabbar-fixed__box {
width: 60px;
height: 180px;
background: #ffffff;
border-radius: 2px;
&--height-short {
height: 120px;
}
.tabbar-fixed-box__common {
height: 60px;
padding: 0 15px;
cursor: pointer;
font-size: 14px;
color: #ff875b;
img {
width: 22px;
height: 22px;
}
}
.tabbar-fixed-box__line {
width: 30px;
height: 1px;
background: #eeeeee;
margin: 0 auto;
}
}
}
</style>

@ -23,7 +23,7 @@ export default function ({$axios, store, route}, inject) {
return result.data;
}
if(result.code === 'TOKEN_FAIL'){
await store.dispatch('logout');
await store.commit('setLoginOut');
store.commit('setLoginVisible');
return result;
}

@ -7,6 +7,7 @@
*/
import { TOKEN_KEY } from "@/constants";
import { ApiGetCurrentUser, ApiPostLogout } from "@/plugins/api/account";
import { ApiGetCartList } from "@/plugins/api/cart";
const ONE_DAY = 86400000; // 一天的毫秒数 24 * 60 * 60 * 1000;
const state = () => ({
@ -14,6 +15,7 @@ const state = () => ({
userInfo: {},
loginVisible: false, // 是否展示登录弹窗
seckillTabVisible: false, // 公共头是否展示秒杀tab
cartProducts: [], // 购物车列表
});
const mutations = {
setUserInfo(state, info) {
@ -37,13 +39,16 @@ const mutations = {
setSeckillTabVisible(state, visible) {
state.seckillTabVisible = visible;
},
setCartProducts(state, val) {
state.cartProducts = val;
},
};
const actions = {
async nuxtServerInit({ state, commit, dispatch }) {
nuxtServerInit({ state, commit, dispatch }) {
const token = this.$cookies.get(TOKEN_KEY);
if (!state.token && token) {
commit("setToken", token);
await dispatch("getUserInfo");
dispatch("getUserInfo");
}
},
async getUserInfo({ commit }) {
@ -58,6 +63,14 @@ const actions = {
await ApiPostLogout();
commit("setLoginOut");
},
// 获取购物车数据
async getCartProducts({ commit }) {
const { result } = await ApiGetCartList();
if (result) {
commit("setCartProducts", result);
}
},
};
export { state, mutations, actions };

Loading…
Cancel
Save