新增营销系统、分销系统、会员功能、门店、提现功能

This commit is contained in:
Shaw
2024-02-08 21:01:37 +08:00
parent 68b3f2dcc3
commit 17c043348a
1398 changed files with 81279 additions and 56269 deletions

View File

@ -0,0 +1,171 @@
<template>
<div class="spike">
<div class="spike-card" v-if="productList?.length>0">
<div class="spike-card-top">
<h2 class="spike-card-top-title">
限时秒杀
</h2>
<div class="spike-card-top-time" v-if="activityData?.state===2">
<div class="session">活动已结束</div>
</div>
<div class="spike-card-top-time" v-else-if="count?.length > 0">
<div class="session">距活动{{count[0]}}还有</div>
<div class="time">{{count[1]}}:{{count[2]}}:{{count[3]}}</div>
</div>
<a v-show="componentContent.showMore" class="btn-more" @click="jumpSeckills(componentContent.id)">查看更多</a>
</div>
<div class="spike-card-list">
<div class="spike-card-item" v-for='item in productList.slice(0,4)' :key='item.productId' @click="jumpProductDetail(item)">
<div class="spike-card-item-img">
<image :src="item.image" alt="" />
</div>
<div class="spike-card-item-info">
<h3 class="name">
{{item.storeName}}
</h3>
<div class="price-warp">
<div class="price">¥{{item.price}}</div>
<!-- <div class="original-price">
¥ {{item.originalPrice}}
</div> -->
<div class="stock">
限量{{item.stock}}件
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import commonMixin from '../mixin'
import { toRefs } from 'vue';
const props = defineProps({
typeId: {
type: Number,
default: 1,
},
shopId: {
type: Number,
default: 0,
},
componentContent: {
type: Object,
default () {
return {};
}
}
})
const { typeId, shopId, componentContent } = toRefs(props)
const { activityData, productList, count, jumpProductDetail, jumpSeckills } = commonMixin(componentContent, typeId, shopId)
</script>
<style lang="scss" scoped>
.spike{
&-card{
border-radius: 20rpx;
margin: 0 34rpx;
&-top{
position: relative;
display: flex;
margin-bottom: 17rpx;
&-title{
font-size: 32rpx;
color: #333333;
margin-right: 25rpx;
font-weight: normal;
}
&-time{
height: 40rpx;
border-radius: 21rpx;
border: 1rpx solid #EE6D46;
display: flex;
overflow: hidden;
align-items: center;
.session{
height: 100%;
line-height: 40rpx;
background: #EE6D46;
font-size: 20rpx;
color: #FFFFFF;
padding: 0 15rpx;
border-radius: 21rpx;
}
.time{
font-size: 20rpx;
color: #EE6D46;
padding: 0 14rpx 0 10rpx;
}
}
.btn-more{
position: absolute;
right: 8rpx;
top: 0rpx;
line-height: 40rpx;
padding-right: 30rpx;
font-size: 24rpx;
color: #999;
background: url("https://b2c-pro-static-dev.zkthink.com/static/images/icon-arrow.png") no-repeat right center / 20rpx 20rpx;
}
}
&-list{
background-color: #ffffff;
display: flex;
overflow: auto;
padding: 20rpx;
border-radius: 15rpx;
}
&-item{
align-items: center;
box-sizing: border-box;
flex: 0 0 203rpx;
margin-right: 18rpx;
&-img{
width: 203rpx;
height: 203rpx;
image{
width: 100%;
height: 100%;
object-fit: contain;
}
}
&-info{
width: 203rpx;
.name{
font-size: 30rpx;
font-weight: normal;
line-height: 40rpx;
color: #333333;
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
padding: 15rpx 0 6rpx;
}
.price-warp{
display: flex;
align-items: center;
}
.price{
font-size: 32rpx;
color: #EE6D46;
padding-right: 10rpx;
display: inline-block;
}
.original-price{
font-size: 20rpx;
line-height: 28rpx;
color: #CCCCCC;
display: inline-block;
}
.stock{
line-height: 1em;
display: inline-block;
font-size: 20rpx;
color: #999999;
}
}
}
}
}
</style>

View File

@ -0,0 +1,102 @@
import api from '../../config/api'
import { funMixin } from '../../config/mixin'
import { ref, onMounted, onBeforeUnmount } from 'vue';
export default function (componentContent, typeId, shopId) {
const { sendReq, beforeGetData, afterGetData, jumpProductDetail, jumpSeckills } = funMixin()
const activityData = ref({})
const productList = ref([])
const count = ref([])
const timer = ref(null)
onMounted(() => {
if (componentContent.value.id) {
getProList()
getActivit()
} else {
productList.value = []
}
})
onBeforeUnmount(() => {
clearInterval(timer.value)
})
function getProList () {
beforeGetData()
const params = {
method: 'POST',
url: api.getActivityProduct,
data: {
isPage: 2,
ids: [componentContent.value.id]
}
}
sendReq(
params,
(res) => {
afterGetData()
productList.value = res.data.list
},
() => {
afterGetData()
}
)
}
function getActivit () {
beforeGetData()
const params = {
method: 'GET',
url: `${api.getActivity}?id=${componentContent.value.id}`,
}
sendReq(
params,
(res) => {
afterGetData()
activityData.value = res.data
getTime()
},
() => {
afterGetData()
}
)
}
function getTime () {
const date = new Date().getTime()
let startTime = activityData.value.startTime
let endTime = activityData.value.endTime
let time = 0
if (activityData.value.state === 0) {
time = startTime - date // 未开始
} else if(activityData.value.state === 1) {
time = endTime - date // 进行中
}
let countDownInterval = setInterval(()=>{
countDown(time)
time -= 1000
if(time <= 0){
clearInterval(countDownInterval)
activityData.value.state ++
}
},1000)
}
function countDown (time) {
const fn = (v) => (v < 10 ? `0${v}` : v)
const t = parseInt(time / 1000)
const text = activityData.value.state === 0 ? '开始' : '结束'
const hour = parseInt(t / 3600)
const min = parseInt((t % 3600) / 60)
const s = t % 60
count.value = [text, fn(hour), fn(min), fn(s)]
}
return {
activityData,
productList,
count,
jumpProductDetail,
jumpSeckills
}
}