修正项目

This commit is contained in:
2024-01-07 01:10:08 +08:00
parent 2f29241806
commit b22014e976
943 changed files with 27699 additions and 28227 deletions

View File

@@ -0,0 +1,132 @@
<template>
<view>
<!-- 如果商品没有加入购物车 -->
<block v-if="getCheckProductExists">
<u-button size="mini" type="warning" @click="addShopCart">加入购物车</u-button>
</block>
<block v-else>
<u-number-box
ref="uNumber"
v-model="skuNumValue"
:disabled-input="true"
:input-height="40"
:input-width="60"
:max="getMax"
:min="0"
:size="20"
@minus="changeSkuNumMinus"
@plus="changeSkuNumPlus"
></u-number-box>
</block>
<u-modal ref="confirmModal" v-model="showConfirmModal" :async-close="true" :show-cancel-button="true"
@cancel="modalCancel" @confirm="modalConfirm">
<view class="u-flex u-row-center u-m-20">确认删除该商品</view>
</u-modal>
</view>
</template>
<script>
import {mapGetters, mapActions} from 'vuex';
export default {
name: 'AddToCart',
data() {
return {
id: 0,
isCart: false,
showConfirmModal: false
};
},
props: {
shopDetail: {
type: Object,
default: () => {
return {};
}
},
// 在购物车页面的时候使用带活动的购物车将传递的不再是商品的id
// 商品详情信息中没有id而是skuId
skuId: {
type: Number,
default: null
}
},
computed: {
...mapGetters('cartModule', ['checkProductExists', 'getProductSkuNum']),
// 检查是否存在商品于购物车
getCheckProductExists() {
return !this.checkProductExists(this.id);
},
// 商品加入购物车的数量
skuNumValue: {
get() {
return this.getProductSkuNum(this.id);
},
set(value) {
}
},
// 最大可加入购物车的数量
getMax() {
let perLimit = this.shopDetail.perLimit;
// 秒杀商品与普通商品购买上限判断字段不同
if (this.shopDetail.skuType === 1) {
perLimit = this.shopDetail.seckillSkuVo && this.shopDetail.seckillSkuVo.seckillLimit
}
return perLimit;
}
},
methods: {
...mapActions('cartModule', ['addShopAction', 'changeSkuNumAction']),
// 添加到购物车
addShopCart() {
if (this.skuId) {
this.shopDetail.id = this.skuId;
}
this.addShopAction(this.shopDetail);
},
// 购物车数量递减
changeSkuNumMinus(e) {
// 如果是购物车中进行递减操作并且购物车数量为0那么需要弹出确认框
if (e.value < 1 && this.isCart) {
this.showConfirmModal = true;
} else {
this.changeSkuNumAction({skuId: this.id, value: -1, currentBuyNum: e.value, isCart: this.isCart});
}
},
// 购物车数量递增
changeSkuNumPlus(e) {
this.changeSkuNumAction({skuId: this.id, value: 1, currentBuyNum: e.value, isCart: this.isCart});
},
// 确认删除商品模态框
modalConfirm() {
this.showConfirmModal = false;
this.changeSkuNumAction({skuId: this.id, value: -1, currentBuyNum: 0, isCart: this.isCart});
},
// 取消删除商品模态框,只需要将商品购买数修改回初始值
modalCancel() {
this.showConfirmModal = false;
// 重新设置u-number-box的初始值
this.$refs.uNumber.$data.inputVal = 1;
},
},
watch: {
// skuId是在购物车频道使用如果是商品列表是id
skuId: {
handler(newVal, oldVal) {
if (newVal) {
this.id = newVal;
this.isCart = true;
} else {
this.id = this.shopDetail.id;
this.isCart = false;
}
},
immediate: true
}
}
};
</script>
<style lang="scss"></style>

View File

@@ -0,0 +1,130 @@
<template>
<u-popup v-model="showCouponInfoListModal" :closeable="true" border-radius="14" mode="bottom" @close="closeModal">
<view class="coupon">
<view v-for="couponInfoItem in couponInfoList" :key="couponInfoItem.id" class="content u-m-b-20">
<view class="left">
<view class="sum">
<text class="num">{{ couponInfoItem.amount }}</text>
</view>
<view class="type">{{ couponInfoItem.couponType === 'FULL_REDUCTION' ? '满减券' : '现金券' }}</view>
<view class="type">{{ getRangeType(couponInfoItem.rangeType) }}</view>
</view>
<view class="centre">
<view class="title">{{ couponInfoItem.couponName }}</view>
<view class="u-type-info">{{ couponInfoItem.rangeDesc }}</view>
<view class="valid-date">过期时间{{ dayjs(couponInfoItem.expireTime).format('YYYY-MM-DD') }}</view>
</view>
<view class="right">
<block v-if="couponInfoItem.couponStatus === 1">
<u-tag text="已领取" type="success"/>
</block>
<block v-else-if="couponInfoItem.couponStatus === 2">
<u-tag text="已使用" type="info"/>
</block>
<block v-else>
<view :round="true" class="immediate-use" size="mini" @click="receiveCoupon(couponInfoItem.id)">领取</view>
</block>
</view>
</view>
</view>
</u-popup>
</template>
<script>
import dayjs from 'dayjs';
export default {
props: ['showCouponInfoList', 'couponInfoList'],
name: 'CouponInfoList',
computed: {
getRangeType() {
return function (rangeType) {
switch (rangeType) {
case 'ALL':
return '全场通用';
case 'SKU':
return '指定商品';
case 'CATEGORY':
return '指定分类';
}
};
},
showCouponInfoListModal: {
get() {
return this.showCouponInfoList;
},
set(value) {
return false;
}
}
},
methods: {
dayjs,
closeModal() {
this.$emit('update:showCouponInfoList', false);
},
// 领取优惠券
receiveCoupon(id) {
this.$emit('getCouponInfo', id)
}
}
};
</script>
<style lang="scss">
.coupon {
margin: 80rpx auto;
margin-bottom: 30rpx;
background-color: #ffffff;
width: 700rpx;
color: $u-type-warning;
font-size: 28rpx;
.content {
display: flex;
justify-content: space-around;
align-items: center;
padding: 40rpx 20rpx;
border: 10rpx;
background-color: #fff5f4;
.left {
.sum {
font-size: 32rpx;
.num {
font-size: 60rpx;
font-weight: bold;
}
}
}
.centre {
margin-left: 40rpx;
.title {
font-size: 32rpx;
font-weight: bold;
color: $u-main-color;
}
}
.right {
margin-left: 30rpx;
.immediate-use {
padding: 0 20rpx;
height: 50rpx;
border-radius: 25rpx;
line-height: 50rpx;
background-color: $u-type-warning !important;
color: #ffffff !important;
font-size: 24rpx;
border: none;
word-break: keep-all;
}
}
}
}
</style>

View File

@@ -0,0 +1,99 @@
<template>
<view :style="[{ width: width, height: height }]" class="gg">
<view class="gg-left u-font-xs u-p-l-10 u-p-r-10">
<block v-if="showLeft">
<slot name="left">秒杀</slot>
</block>
</view>
<view class="gg-right u-font-xs u-p-l-10 u-p-r-10">
<block v-if="showRight">
<slot name="right">推荐</slot>
</block>
</view>
<u-image :border-radius="borderRadius" :height="height" :lazy-load="lazyLoad" :src="src" :width="width"/>
<view class="gg-bottom u-font-xs u-p-l-10 u-p-r-10">
<block v-if="showBottom">
<slot name="bottom">新人专享</slot>
</block>
</view>
</view>
</template>
<script>
export default {
name: 'ListImgItem',
props: {
lazyLoad: {
type: Boolean,
default: true
},
borderRadius: {
type: String,
default: '10rpx'
},
src: {
type: String,
default: '',
required: true
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '200rpx'
},
showLeft: {
type: Boolean,
default: true
},
showRight: {
type: Boolean,
default: true
},
showBottom: {
type: Boolean,
default: true
}
}
};
</script>
<style lang="scss" scoped>
.gg {
position: relative;
&-left {
position: absolute;
top: 0;
left: 0;
z-index: 1;
background-color: $u-type-primary;
color: $u-type-info-light;
border-top-left-radius: 10rpx;
}
&-right {
position: absolute;
right: 0;
top: 0;
z-index: 1;
background-color: $u-type-error;
color: $u-type-info-light;
border-top-right-radius: 10rpx;
}
&-bottom {
position: absolute;
bottom: 0;
left: 0;
z-index: 1;
width: 100%;
background-color: $u-type-success;
color: $u-type-info-light;
border-bottom-left-radius: 10rpx;
border-bottom-right-radius: 10rpx;
}
}
</style>

View File

@@ -0,0 +1,130 @@
<template>
<view class="gg-header">
<view class="gg-header-location u-p-r-50" @click="show = true">
<text class="u-p-r-10">{{ currentPickUpArea }}</text>
<u-icon color="gray" name="arrow-down-fill" size="20"></u-icon>
</view>
<!-- 如果利用v-model操作会造成searchKeyword对于父组件的二次重渲染问题所以将value与blur拆分
并且利用update:searchKeyword的方式将数据传递到父组件并进行本组件的数据搜索操作 -->
<u-search
:clearabled="false"
:show-action="true"
:value="searchKeyword"
class="gg-header-search"
height="70"
input-align="left"
@blur="onBlurSearch"
@custom="searchLocation"
@search="searchLocation"
></u-search>
<u-picker v-model="show" :default-selector="[0]" :range="findAllList" mode="selector" range-key="regionName"
@confirm="findAllListConfirm"></u-picker>
</view>
</template>
<script>
import {mapState, mapMutations, mapActions} from 'vuex';
import {BAIDU_MAP_AK} from '../../common/const.js';
// 百度地址资料https://lbsyun.baidu.com/index.php?title=wxjsapi/guide/geocoding
const bmap = require('../../common/bmap-wx.min.js');
const BMap = new bmap.BMapWX({
ak: BAIDU_MAP_AK
});
export default {
name: 'PickUpLocationHeader',
props: ['searchKeyword'],
data() {
return {
show: false,
latitude: '',
longitude: ''
};
},
computed: {
...mapState('pickUpLocationModule', ['findAllList', 'currentPickUpArea'])
},
methods: {
...mapMutations('pickUpLocationModule', ['setCurrentPickUpAreaMutation']),
...mapActions('pickUpLocationModule', ['getSysRegionFindAllListAction']),
findAllListConfirm(index) {
// 通过百度地图进行地址解析,返回经纬度,并通知父组件进行列表显示处理
// 发起geocoding检索请求
BMap.geocoding({
address: this.findAllList[index],
fail: e => {
console.log(e);
},
success: data => {
let wxMarkerData = data.wxMarkerData;
this.latitude = wxMarkerData[0].latitude;
this.longitude = wxMarkerData[0].longitude;
// 通过父组件查询数据
this.$emit('getSearchLeader', {
latitude: this.latitude,
longitude: this.longitude
});
this.setCurrentPickUpAreaMutation(this.findAllList[index])
}
});
},
searchLocation(value) {
if (value && value.trim().length > 0) {
BMap.geocoding({
address: value,
fail: e => {
console.log(e);
},
success: data => {
let wxMarkerData = data.wxMarkerData;
this.latitude = wxMarkerData[0].latitude;
this.longitude = wxMarkerData[0].longitude;
// 通过父组件查询数据
this.$emit('getSearchLeader', {
latitude: this.latitude,
longitude: this.longitude
});
}
});
}
},
onBlurSearch(value) {
this.$emit('update:searchKeyword', value);
}
},
watch: {
searchKeyword: {
handler(newVal, oldVal) {
console.log(newVal, oldVal)
this.searchLocation(newVal);
},
immediate: true
}
},
mounted() {
this.getSysRegionFindAllListAction();
}
};
</script>
<style lang="scss" scoped>
.gg {
&-header {
display: flex;
justify-content: center;
align-items: center;
&-location {
text {
color: gray;
}
}
&-search {
flex: 1;
}
}
}
</style>

View File

@@ -0,0 +1,99 @@
<template>
<block>
<u-tag v-if="isCurrent" class="gg-current-location-tag u-m-l-20" mode="dark" size="mini" text="当前提货点"
type="error"/>
<view :class="{ selected }" class="gg-current-location u-p-20" @click="changePickUpLocation(location.id)">
<u-image :src="location.storePath" border-radius="10rpx" class="gg-current-location-img" height="150rpx"
width="150rpx"></u-image>
<view class="gg-current-location-msg u-m-l-20 u-m-r-20">
<view class="gg-current-location-msg-title u-m-b-5">{{ location.takeName }}</view>
<view class="gg-current-location-msg-distance-address u-m-t-5">
<text v-if="location.distance" class="gg-current-location-msg-distance u-font-xs u-m-r-20">
距离最近*距离{{ location.distance }}km
</text>
<text class="gg-current-location-msg-address u-font-xs">{{ location.detailAddress }}</text>
</view>
</view>
<block v-if="showRadio">
<view v-if="isCurrent" class="gg-current-location-btn">
<u-icon color="#fa3534" name="checkmark-circle-fill" size="40"/>
</view>
<view v-else class="gg-current-location-btn">
<u-icon name="checkmark-circle-fill" size="40"/>
</view>
</block>
</view>
</block>
</template>
<script>
export default {
name: 'PickUpLocationItem',
props: {
selected: {
type: Boolean,
default: false
},
isCurrent: {
type: Boolean,
default: true
},
showRadio: {
type: Boolean,
default: true
},
location: {
type: Object,
default: () => {
return {};
}
}
},
methods: {
changePickUpLocation(id) {
this.$emit('selectPickUpLocation', id);
}
}
};
</script>
<style lang="scss" scoped>
.selected {
background-color: $u-type-info !important;
}
.gg-current-location {
display: flex;
background-color: $u-type-info-light;
border-radius: 20rpx;
&-tag {
position: absolute;
z-index: 9999;
}
&-msg {
flex: 1;
&-title {
font-weight: bold;
}
&-distance {
color: $u-type-error;
}
&-address {
color: $u-type-info;
}
}
&-btn {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
}
</style>