Files
cashier_wx/groupBuying/index/index.vue
2025-12-18 09:42:46 +08:00

635 lines
13 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="min-page bg-f7 u-font-28">
<up-sticky :offsetTop="0" :customNavHeight="0">
<view class="top" :style="topStyle">
<up-navbar bg-color="transparent" :fixed="false" :placeholder="false" title="拼团特惠"
left-icon-color="#fff" title-color="#fff"></up-navbar>
<view class="u-flex info u-col-center">
<image :src="imgs.map" class="map"></image>
<view class="u-line-1 u-m-l-20">{{shopInfo.shopName||''}}</view>
</view>
</view>
<view class="translateY20">
<view class="steps">
<view class="step" v-for="(item,index) in steps" :key="index">
<text class="index">{{index+1}}</text>
<text class="text">{{item}}</text>
<template v-if="index<steps.length-1">
<text class="icon">
{{'>'}}
</text>
<text class="icon icon1">
{{'>'}}
</text>
</template>
</view>
</view>
<view class="filters ">
<view class="u-flex tabs">
<view class="tab" v-for="(item,index) in tabs.list" :class="{'active':tabs.sel==index}"
@click="tabs.sel=index">{{item}}</view>
</view>
<view class="u-flex u-col-center" v-if="tabs.sel==0">
<up-search v-model="query.wareName" @search="refresh" @clear="refresh"
@custom="refresh"></up-search>
<!-- <perpoleNumber v-model="query.groupPeopleNum"></perpoleNumber> -->
</view>
<view class="u-flex orderStatus" v-if="tabs.sel==1">
<view class="orderState" :class="{'active':orders.sel==index}"
v-for="(item,index) in orders.list" :key="index" @click="orders.sel=index">
{{item.name}}
</view>
</view>
</view>
</view>
</up-sticky>
<view class="lists" v-if="tabs.sel==0">
<view class="item" v-for="(item,index) in list" :key="index" @click="toDetail(item)">
<up-image width="218rpx" radius="16rpx" height="218rpx" :src="returnCoverImg(item)"></up-image>
<view class="u-flex-1 u-p-l-16">
<view class="u-flex u-col-center">
<text class="numbers">{{item.groupPeopleNum}}人团</text>
<text class="u-line-1 font-bold u-m-l-18 name">{{item.wareName}}</text>
</view>
<view class="members">已团9999</view>
<view class="info">
<view class="left">
<view class="">
<text class="u-font-24">拼团到手</text>
<text class="u-font-32 font-bold"> ¥{{item.groupPrice}}</text>
</view>
<view style="opacity: 0.84;">
<text class="u-font-24">原价</text>
<text class=""> ¥{{item.originalPrice}}</text>
</view>
</view>
<view class="right">
<image class="pin" :src="imgs.pin"></image>
</view>
</view>
</view>
</view>
</view>
<view class="orders" v-else-if="tabs.sel==1">
<view class="item" v-for="(item,index) in list" :key="index" @click="toOrderDetail(item)">
<view class="u-flex u-col-center u-row-between">
<text class="numbers">{{1}}人团</text>
<statusVue :status="item.status"></statusVue>
</view>
<view class="u-m-t-32 u-flex">
<up-image width="154rpx" height="154rpx" :src="item.goodsImg"></up-image>
<view class="u-flex-1 u-flex u-p-l-30 u-col-center u-row-between">
<view>
<view class="">{{item.wareJson.wareName}}</view>
<view class="u-m-t-34 price">¥{{item.payAmount}}</view>
</view>
<text class="u-font-40 font-bold">x{{item.num}}</text>
</view>
</view>
<view class="u-m-t-32 info">
<view class="u-flex u-col-center">
<text class="title">可核销门店</text>
<text class="stitle">{{item.shopName}}</text>
</view>
<view class="u-flex u-m-t-32 u-col-center">
<text class="title ">门店地址</text>
<text class="stitle">{{item.shopAddress}}</text>
</view>
<view class="u-flex u-m-t-32 u-col-center" v-if="showTime(item)">
<text class="title">剩余成团时间</text>
<text class="stitle price">{{returnTime(item)}}</text>
</view>
</view>
<view class="btns" v-if="showBtns(item)">
<view class="btn " @click.stop="refund(item)">申请退款</view>
<view class="btn " @click.stop="cancelRefund(item)" v-if="item.status=='退款中'">取消退款</view>
<button open-type="share" class="btn black" @click.stop="share(item)">邀请好友</button>
</view>
</view>
</view>
</view>
</template>
<script setup>
import {
wxShare
} from '@/utils/share.js'
import {
getRemainingHMS
} from '@/utils/countdown.js'
import {
onShow
} from '@dcloudio/uni-app'
import * as Api from '@/common/api/order/gbOrder.js'
import perpoleNumber from './components/perpole-number.vue'
import statusVue from '@/groupBuying/components/status.vue'
import {
computed,
reactive,
watch
} from 'vue'
const imgs = {
bg: 'https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/1/d21f2dfd7bec44618f2d5e4b88372b08.png',
bg1: 'https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/1/604c3f917daa41af9239145196c6d3f3.png',
map: 'https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/1/0a293f6e1a6a4e7b956379a5b6701104.png',
pin: 'https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/3/4bcce5bdfa074f2a838a0209fac24241.png'
}
const shopInfo = ref(uni.cache.get('shopInfo'))
const steps = ['发起拼团', '邀请好友', '成团优惠']
const topStyle = {
backgroundImage: 'url(' + imgs.bg + ')'
}
const tabs = reactive({
list: ['活动列表', '我的拼团'],
sel: 0
})
const orders = reactive({
list: [{
name: '全部',
value: ''
},
{
name: '待成团',
value: '待成团'
},
{
name: '待核销',
value: '待核销'
},
{
name: '已核销',
value: '已核销'
},
{
name: '退款',
value: '退款'
},
],
sel: 0
})
const query = reactive({
page: 1,
size: 10,
wareName: '',
groupPeopleNum: '',
shopId: uni.cache.get('shopId'),
})
const list = ref([])
const isEnd = ref(false)
const status = computed(() => {
return orders.list[orders.sel].value
})
watch(() => status.value, () => {
refresh()
})
function getData() {
if (tabs.sel == 0) {
Api.warePage(query).then(res => {
const newArr = res.records || []
if (query.page == 1) {
list.value = newArr
} else {
list.value.push(...newArr)
}
isEnd.value = query.page >= res.totalPage * 1 ? true : false
})
return
}
if (tabs.sel == 1) {
const {
page,
size,
shopId
} = query
Api.record({
page,
size,
shopId,
status: status.value,
}).then(res => {
const newArr = (res.records || []).map(v => {
const wareJson = JSON.parse(v.wareJson)
wareJson.wareImgs = wareJson.wareImgs.split(',').filter(v => v)
return {
...v,
goodsImg: wareJson.wareImgs[0],
wareJson,
}
})
if (query.page == 1) {
list.value = newArr
} else {
list.value.push(...newArr)
}
console.log(list.value)
isEnd.value = query.page >= res.totalPage * 1 ? true : false
})
return
}
}
function toDetail(item) {
uni.navigateTo({
url: '/groupBuying/goodsDetail/goodsDetail?wareId=' + item.id + '&shopId=' + item.shopId
})
}
function toOrderDetail(item) {
uni.navigateTo({
url: '/groupBuying/detail/index?detailId=' + item.id + '&shopId=' + item.shopId
})
}
function returnCoverImg(item) {
if (!item.wareImgs) {
return ''
}
const arr = item.wareImgs.split(',')
return arr[0]
}
function refresh() {
query.page = 1
isEnd.value = false
getData()
}
function refund(item) {
uni.showModal({
title: '提示',
content: '是否申请退款?',
showCancel: true,
success(res) {
if (res.confirm) {
Api.applyRefund({
recordId: item.id,
orderNo: item.orderNo,
}).then(res => {
if (res) {
uni.showToast({
title: '申请成功'
})
setTimeout(() => {
refresh()
}, 1000)
}
})
}
}
})
}
function camcelRefund(item) {
uni.showModal({
title: '提示',
content: '是否取消退款?',
showCancel: true,
success(res) {
if (res.confirm) {
Api.cancelRefund({
recordId: item.id,
orderNo: item.orderNo,
}).then(res => {
if (res) {
uni.showToast({
title: '取消成功'
})
setTimeout(() => {
refresh()
}, 1000)
}
})
}
}
})
}
watch(() => tabs.sel, (newval) => {
orders.sel = 0
refresh()
})
function showBtns(item) {
if (item.status == '已退款') {
return false
}
return true
}
function showTime(item) {
if (item.status == '已退款') {
return false
}
return true
}
let shareItem = null
function share(item) {
shareItem = item
}
onShareAppMessage(() => {
console.log('onShareAppMessage')
console.log(shareItem)
const query=`groupOrderNo=${shareItem.groupOrderNo}&shopId=${shareItem.shopId}`
return wxShare({
title: shareItem.wareJson.wareName,
imageUrl: shareItem.goodsImg,
path:'/groupBuying/detail/index' +'?'+query,
query,
})
})
onLoad(getData)
let timer = null
let nowTime = ref(Date.now())
timer = setInterval(() => {
nowTime.value = Date.now()
}, 1000)
function returnTime(item) {
nowTime.value
return getRemainingHMS(item)
}
</script>
<style lang="scss" scoped>
.top {
height: 422rpx;
background-size: cover;
.info {
padding: 32rpx 30rpx 0 30rpx;
color: #fff;
font-size: 32rpx;
font-weight: 700;
}
.map {
width: 48rpx;
height: 48rpx;
}
}
.steps {
display: flex;
padding: 20rpx 20rpx;
gap: 20rpx;
border-radius: 14rpx 14rpx 0 0;
background: linear-gradient(90deg, #FFF5E6 0%, #FFD2CA 100%);
align-items: center;
.step {
display: flex;
align-items: center;
}
.index {
border-radius: 60rpx;
color: #fff;
width: 44rpx;
height: 44rpx;
line-height: 44rpx;
text-align: center;
background: #E55626;
}
.text {
color: #5A352F;
margin-left: 10rpx;
margin-right: 22rpx;
white-space: nowrap;
}
.icon {
color: rgba(90, 53, 47, 0.42);
}
.icon1 {
color: #5A352F;
}
}
.lists {
padding: 18rpx 10rpx;
.item {
display: flex;
padding: 32rpx 16rpx;
border-radius: 32rpx;
background: #FFF;
margin-bottom: 14rpx;
.numbers {
background: #4C2828;
padding: 8rpx 18rpx;
border-radius: 10rpx;
font-weight: 700;
color: #FAEAC6;
white-space: nowrap;
}
.name {
max-width: 334rpx;
}
.members {
margin-top: 26rpx;
background: #FDF1CB;
padding: 4rpx 18rpx;
border-radius: 10rpx 10rpx 10rpx 0;
width: fit-content;
font-size: 24rpx;
font-weight: 700;
color: #ED5A2E;
}
.info {
background-image: url(https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/1/604c3f917daa41af9239145196c6d3f3.png);
width: 410rpx;
height: 102rpx;
background-size: cover;
transform: translateY(-10rpx);
display: flex;
.left {
width: 306rpx;
color: #fff;
padding: 16rpx 22rpx;
}
.right {
padding-left: 16rpx;
margin-top: 30rpx;
.pin {
width: 76rpx;
height: 54rpx;
}
}
}
}
}
.filters {
padding: 16rpx 28rpx;
border-radius: 6rpx 6rpx 16rpx 16rpx;
background: #FFF;
}
.tabs {
display: flex;
justify-content: space-between;
font-size: 24rpx;
color: #999;
padding: 32rpx 88rpx;
.tabs {
transition: all .3s linear;
}
.active {
color: #ED5A2E;
font-size: 32rpx;
font-weight: 700;
font-weight: 700;
}
}
.translateY20 {
transform: translateY(-20rpx);
}
.orderStatus {
padding: 26rpx 28rpx;
justify-content: space-between;
.orderState {
color: #999;
transition: all .3s linear;
&.active {
color: #000;
font-size: 32rpx;
font-weight: 700;
}
}
}
.orders {
padding: 0 26rpx 36rpx;
.item {
padding: 32rpx 24rpx;
border-radius: 16rpx;
background: #FFF;
margin-bottom: 32rpx;
.numbers {
background-color: #ED5A2E;
padding: 16rpx 30rpx;
border-radius: 12rpx;
font-size: 32rpx;
color: #fff;
font-weight: 700;
line-height: 36rpx;
}
.status {
padding: 8rpx 18rpx;
border-radius: 8rpx;
border: 2rpx solid transparent;
&.success {
border-color: rgba(123, 209, 54, 1);
color: rgba(123, 209, 54, 1);
background: rgba(123, 209, 54, 0.12);
}
&.error {
border-color: #FF1C1C;
color: #FF1C1C;
background: rgba(255, 28, 28, 0.18);
}
}
.price {
color: #ED5A2E;
font-weight: 700;
line-height: 36rpx;
font-size: 40rpx;
}
.info {
padding: 16rpx 34rpx;
flex-direction: column;
align-items: flex-start;
border-radius: 8rpx;
background: #F8F8F8;
.title {
min-width: 208rpx;
padding-right: 8rpx;
box-sizing: border-box;
}
.stitle {
color: #666;
&.price {
font-size: 32rpx;
color: #ed5a2e;
font-weight: 700;
}
}
}
.btns {
margin-top: 28rpx;
display: flex;
justify-content: flex-end;
gap: 34rpx;
.btn {
line-height: 1;
margin: 0;
padding: 12rpx 14rpx;
border-radius: 10rpx;
border: 2rpx solid #D9D9D9;
background: #FFF;
font-size: 28rpx;
&.black {
border-color: #343030;
background-color: #343030;
color: #fff;
}
}
}
}
}
</style>