Browse Source

'调试倒数第二天'

hfll
hflllll 3 weeks ago
parent
commit
6711946317
13 changed files with 266 additions and 134 deletions
  1. +7
    -0
      api/model/my.js
  2. +12
    -12
      components/coupon/CouponItem.vue
  3. +1
    -1
      pages/index/cart.vue
  4. +6
    -1
      pages/index/center.vue
  5. +25
    -18
      pages_order/location/pickupPoint.vue
  6. +21
    -15
      pages_order/mine/coupon.vue
  7. +11
    -8
      pages_order/mine/myTeam.vue
  8. +14
    -7
      pages_order/mine/team.vue
  9. +43
    -29
      pages_order/mine/unbindTeam.vue
  10. +54
    -16
      pages_order/order/groupMealDetail.vue
  11. +57
    -26
      pages_order/order/newOrderDetail.vue
  12. +2
    -0
      store/store.js
  13. +13
    -1
      utils/position.js

+ 7
- 0
api/model/my.js View File

@ -72,6 +72,13 @@ const api = {
limit: 500
},
// 我的-查询绑定团长信息(默认下单地址)
queryMyLeader: {
url: '/teambuy/leader/queryMyLeader',
method: 'GET',
limit: 500
},
// 钱包-充值回调
CashNotify: {
url: '/teambuy/amount/CashNotify',


+ 12
- 12
components/coupon/CouponItem.vue View File

@ -1,29 +1,29 @@
<template>
<view class="coupon-item" :class="{ 'used': coupon.status === 1, 'expired': coupon.status === 2 }">
<view class="coupon-item" :class="{ 'used': coupon.status === '1', 'expired': coupon.status === '2' }">
<!-- 左侧金额 -->
<view class="coupon-left">
<view class="coupon-amount">
<text class="currency">¥</text>
<text class="number">{{ coupon.amount }}</text>
<text class="number">{{ Number(coupon.discount) }}</text>
</view>
</view>
<!-- 中间信息 -->
<view class="coupon-middle">
<view class="coupon-type">{{ coupon.title }}</view>
<view class="coupon-validity">{{ coupon.validTime }} 前有效</view>
<view class="coupon-type">{{ coupon.couponId_dictText }}</view>
<view class="coupon-validity">{{ coupon.validDate }} 前有效</view>
</view>
<!-- 右侧使用按钮 -->
<view class="coupon-right">
<view class="use-btn" @click="useCoupon" v-if="coupon.status === 0">
<view class="use-btn" @click="useCoupon" v-if="coupon.status === '0'">
<text>立即</text>
<text>使用</text>
</view>
<view class="use-btn" v-if="coupon.status ===1">
<view class="use-btn" v-if="coupon.status === '1'">
<text>已使用</text>
</view>
<view class="use-btn" v-if="coupon.status === 2">
<view class="use-btn" v-if="coupon.status === '2'">
<text>已过期</text>
</view>
</view>
@ -44,11 +44,11 @@ export default {
coupon: {
type: Object,
default: () => ({
id: '',
amount: 0,
title: '新人专享优惠券',
validTime: '2025/4/12 23:59',
status: 0 // 0-使 1-使 2-
couponId: '',
discount: 0,
couponId_dictText: '新人专享优惠券',
validDate: '2025/4/12 23:59',
status: "0" // 0-使 1-使 2-
})
}
},


+ 1
- 1
pages/index/cart.vue View File

@ -154,7 +154,7 @@ export default {
}
const sendData = this.cartData.records.filter(item => this.checkboxValue.includes(item.id))
this.$store.commit('setCartData', sendData )
this.$store.commit('setCartData', { sendData, priceAll: this.totalPrice } )
//
this.$utils.navigateTo({


+ 6
- 1
pages/index/center.vue View File

@ -1,7 +1,7 @@
<template>
<view class="center-page">
<!-- 顶部背景和个人信息 -->
<view class="header" :style="{ 'background-image': 'url(/static/image/红烧肉.webp)' }">
<view class="header" :style="{ backgroundImage: `url(${imageUrl})` }">
<view class="user-info">
<image class="avatar" :src="userInfo.headImage" mode="aspectFill"></image>
@ -229,6 +229,11 @@ export default {
})
}
},
computed: {
imageUrl() {
return '/static/image/红烧肉.webp'
}
},
onLoad() {
this.$store.commit('getUserInfo')
}


+ 25
- 18
pages_order/location/pickupPoint.vue View File

@ -32,36 +32,26 @@
</view>
<!-- 无数据提示 -->
<uv-empty v-if="pickupPoints.length === 0" text="暂无取餐点" mode="list"></uv-empty>
<uv-empty v-if="pickupPoints.length === 0" text="暂无取餐点" mode="list" />
</view>
</view>
</template>
<script>
import navbar from '@/components/base/navbar.vue'
import position from '@/utils/position.js'
export default {
components: {
navbar
},
data() {
return {
pickupPoints: [
// {
// id: '1',
// spotName: '',
// area: '',
// phone: '15070023168',
// spotImage: '/static/image/.webp'
// },
// {
// id: '2',
// spotName: '便',
// area: '7102',
// phone: '15070023168',
// spotImage: '/static/image/.webp'
// }
]
pickupPoints: [],
location: {
latitude: 0,
longitude: 0
}
}
},
methods: {
@ -93,12 +83,29 @@
}, 800);
}
},
finalPickupPoints() {
//
const arr = this.pickupPoints.filter(item => position.calculateDistance(this.location.latitude, this.location.longitude, item.latitude, item.longitude) < 1000)
console.log('算出一定范围内的取餐点', arr);
//
this.pickupPoints = arr.sort((a, b) => position.calculateDistance(this.location.latitude, this.location.longitude, a.latitude, a.longitude) - position.calculateDistance(this.location.latitude, this.location.longitude, b.latitude, b.longitude))
console.log('根据近距离取餐点 进行排序', this.pickupPoints);
},
onLoad() {
this.$api('queryLeaderList', {}, res => {
if (res.code == 200) {
this.pickupPoints = res.result.records
}
})
position.getLocation( res => {
if (res.latitude && res.longitude) {
this.location.latitude = res.latitude
this.location.longitude = res.longitude
this.finalPickupPoints()
}
})
}
}
</script>


+ 21
- 15
pages_order/mine/coupon.vue View File

@ -15,20 +15,20 @@
<template v-if="currentTab === 0">
<coupon-item v-for="coupon in unusedCoupons" :key="coupon.id" :coupon="coupon" @use="useCoupon" />
<uv-empty v-if="unusedCoupons.length == 0" text="暂无优惠卷" textSize="30rpx" iconSize="200rpx"
style="padding-top: 100rpx;" icon="list" />
style="padding-top: 200rpx;" icon="list" />
</template>
<template v-if="currentTab === 1">
<coupon-item v-for="coupon in usedCoupons" :key="coupon.id" :coupon="coupon" />
<uv-empty v-if="usedCoupons.length == 0" text="暂无优惠卷" textSize="30rpx" iconSize="200rpx"
style="padding-top: 100rpx;" icon="list" />
style="padding-top: 200rpx;" icon="list" />
</template>
<template v-if="currentTab === 2">
<coupon-item v-for="coupon in expiredCoupons" :key="coupon.id" :coupon="coupon" />
<uv-empty v-if="expiredCoupons.length == 0" text="暂无优惠卷" textSize="30rpx" iconSize="200rpx"
style="padding-top: 100rpx;" icon="list" />
style="padding-top: 200rpx;" icon="list" />
</template>
</view>
</view>
@ -37,7 +37,6 @@
<script>
import navbar from '@/components/base/navbar.vue'
import CouponItem from '@/components/coupon/CouponItem.vue'
import { unusedCoupons, usedCoupons, expiredCoupons } from '@/static/js/mockCoupon.js'
export default {
components: {
@ -52,17 +51,21 @@ export default {
{ name: '已过期' }
],
currentTab: 0,
unusedCoupons: [],
usedCoupons: [],
expiredCoupons: []
allCoupons: []
}
},
onLoad() {
// mock
this.unusedCoupons = unusedCoupons
this.usedCoupons = usedCoupons
//
// this.expiredCoupons = expiredCoupons
computed: {
unusedCoupons() {
return (this.allCoupons || []).filter(coupon => coupon.status === "0")
},
usedCoupons() {
return (this.allCoupons || []).filter(coupon => coupon.status === "1")
},
expiredCoupons() {
return (this.allCoupons || []).filter(coupon => coupon.status === "2")
}
},
onLoad() {
this.getCoupon()
},
methods: {
@ -75,7 +78,7 @@ export default {
useCoupon(coupon) {
uni.showModal({
title: '提示',
content: `确定使用面值${coupon.amount}元的优惠券吗?`,
content: `确定使用面值${coupon.discount}元的优惠券吗?`,
success: (res) => {
// 使
uni.showLoading({
@ -93,6 +96,9 @@ export default {
}
}, 1000)
}, 1000)
},
fail: (err) => {
console.log('err', err)
}
})
},
@ -103,7 +109,7 @@ export default {
pageSize: 10000
}, res => {
if (res.code === 200){
console.log(res);
this.allCoupons = res.result.records
}
})
}


+ 11
- 8
pages_order/mine/myTeam.vue View File

@ -6,27 +6,27 @@
<!-- 团队信息展示 -->
<view class="team-info-section">
<!-- 店铺图片 -->
<image :src="teamData.teamInfo.shopImage" mode="aspectFill" class="shop-image" />
<image :src="teamData[0].teamLeader.spotImage" mode="aspectFill" class="shop-image" />
<!-- 团员数量 -->
<view class="member-count">
我的团员<text class="count">{{ teamData.teamInfo.memberCount }}</text>
我的团员<text class="count">{{ teamData.length }}</text>
</view>
</view>
<!-- 团员列表 -->
<view class="member-list">
<view class="member-item" v-for="member in teamData.memberList" :key="member.id">
<view class="member-item" v-for="member in teamData" :key="member.id">
<!-- 状态点 -->
<view class="status-dot"></view>
<!-- 头像 -->
<image :src="member.avatar" mode="aspectFill" class="member-avatar" />
<image :src="member.member.headImage" mode="aspectFill" class="member-avatar" />
<!-- 团员信息 -->
<view class="member-info">
<view class="member-name">{{ member.nickname }}</view>
<view class="join-time">注册时间: {{ member.joinTime }}</view>
<view class="member-name">{{ member.memberId_dictText }}</view>
<view class="join-time">注册时间: {{ member.createTime }}</view>
</view>
</view>
</view>
@ -50,9 +50,12 @@ export default {
},
onLoad() {
// this.teamData = teamData
this.$api('queryMemberList', {} , res => {
this.$api('queryMemberList', {
pageNo: 1,
pageSize: 10000
} , res => {
if (res.code === 200){
teamData = res.result
this.teamData = res.result.records
}
})


+ 14
- 7
pages_order/mine/team.vue View File

@ -43,12 +43,9 @@
placeholder-class="placeholder" />
</view>
<view class="form-item region-item">
<view class="form-item region-item" @click="regionSelect">
<text class="label">所在地区</text>
<picker mode="region" @change="regionSelect">
<text style="font-size: 30rpx;">{{ formData.area || '请选择' }}</text>
</picker>
<text>{{ formData.area }}</text>
<uv-icon name="arrow-right" color="#000" style="margin-left: 2rpx;"/>
</view>
<view class="address-item">
@ -74,6 +71,7 @@
<script>
import navbar from '@/components/base/navbar.vue'
import shareConfig from '@/mixins/configList.js'
import position from '@/utils/position.js'
export default {
components: {
@ -88,7 +86,9 @@ export default {
name: '', //
phone: '', //
area: '', //
address: '' //
address: '', //
latitude: '', //
longitude: '' //
},
identity: uni.getStorageSync('identity'),
beModify: false //
@ -111,7 +111,14 @@ export default {
//
regionSelect(e) {
this.formData.area = e.detail.value[1] + e.detail.value[2]
// this.formData.area = e.detail.value[1] + e.detail.value[2]
position.selectAddress(0, 0, res => {
delete res.errMsg
this.formData = {
...this.formData,
...res
}
})
},
//


+ 43
- 29
pages_order/mine/unbindTeam.vue View File

@ -23,8 +23,8 @@
<text>{{ currentPickupPoint.phone }}</text>
</view>
</view>
<view class="status-icon">
<uv-icon name="checkmark-circle-fill" color="#019245" size="40"></uv-icon>
<view class="select-btn" @click="deleteLeader">
<text>解绑</text>
</view>
</view>
@ -52,14 +52,14 @@
<view class="pickup-address-icon">
<uv-icon name="map-fill" color="#019245" size="24"></uv-icon>
</view>
<text>{{ item.area }}</text>
<text>{{ item.area }} {{ item.address }} </text>
</view>
<view class="pickup-phone">
<uv-icon name="phone-fill" color="#019245" size="24"></uv-icon>
<text>{{ item.phone }}</text>
</view>
</view>
<view class="select-btn" @click="selectPickupPoint(item)">
<view class="select-btn" @click="updateLeader(item)">
<text>选择</text>
</view>
</view>
@ -70,7 +70,7 @@
<script>
import navbar from '@/components/base/navbar.vue'
import { currentPickupPoint, nearbyPickupPoints } from '@/static/js/mockTeam.js'
// import { currentPickupPoint, nearbyPickupPoints } from '@/static/js/mockTeam.js'
export default {
components: {
@ -86,10 +86,10 @@ export default {
},
methods: {
//
selectPickupPoint(point) {
deleteLeader() {
uni.showModal({
title: '确认选择',
content: '您确定要选择该取餐点吗?需要平台审核通过后才能更换。',
title: '确认解绑',
content: '您确定要解绑团长吗?',
confirmColor: '#019245',
success: (res) => {
if (res.confirm) {
@ -98,45 +98,59 @@ export default {
})
this.$api('deleteLeader',{
leaderUpdateId: point.id
leaderId: this.currentPickupPoint.id
}, res => {
if (res.code === 200){
this.updateLeader(point)
uni.hideLoading()
uni.showToast({
title: `${res.message}`
})
}
})
}
}
})
},
updateLeader(point) {
this.$api('updateLeader', {
id: point.id
}, res => {
if (res.code == 200) {
uni.hideLoading()
uni.showToast({
title: '申请已提交,等待平台审核',
icon: 'success',
})
setTimeout(() => {
this.$utils.navigateBack()
}, 1000)
updateLeader(point) {
uni.showModal({
title: '确认选择',
content: '您确定要选择该取餐点吗?需要平台审核通过后才能更换。',
confirmColor: '#019245',
success: (res) => {
if (res.confirm) {
uni.showLoading({
title: '提交中...'
})
this.$api('updateLeader', {
leaderId: point.id
// leaderId: 1915305988566077441
}, res => {
if (res.code == 200) {
uni.hideLoading()
uni.showToast({
title: `${res.message}`,
icon: 'success',
})
}
})
}
}
})
}
},
onLoad() {
this.currentPickupPoint = currentPickupPoint
// this.currentPickupPoint = currentPickupPoint
this.$api('queryLeaderList', {}, res => {
if (res.code == 200){
this.nearbyPickupPoints = res.result.records
}
})
// this.$api('queryLeaderInfo', {}, res => {
// if (res.code == 200){
// this.currentPickupPoint = res.result
// </span><span class="err"> pan> }
// })
this.$api('queryMyLeader', {}, res => {
if (res.code == 200){
this.currentPickupPoint = res.result
}
})
}
}
</script>


+ 54
- 16
pages_order/order/groupMealDetail.vue View File

@ -5,26 +5,21 @@
bgColor="#019245" color="#fff" />
<view class="container">
<!-- test按钮 -->
<button @click="test1">通知所有人取餐</button>
<button @click="test1">通知所有人完成订单</button>
<!-- 修改后 -->
<view class="top-btn-group">
<button class="top-action-btn" @click="test1">通知所有人取餐</button>
<button class="top-action-btn" @click="test2">通知所有人完成订单</button>
</view>
<!-- 成员列表 -->
<view class="member-list">
<!-- 使用封装的成员项组件 -->
<member-food-item
v-for="(member, index) in members"
:key="index"
:member="member"
:status="status"
:default-expanded="index === defaultExpandedIndex"
@toggle="handleMemberToggle"
@sendNotice="handleSend(member)"
@completeOrder="handleComplete(member)"
/>
<member-food-item v-for="(member, index) in members" :key="index" :member="member" :status="status"
:default-expanded="index === defaultExpandedIndex" @toggle="handleMemberToggle"
@sendNotice="handleSend(member)" @completeOrder="handleComplete(member)" />
</view>
<!-- 空数据提示 -->
<uv-empty v-if="members.length === 0" text="暂无成员" mode="list" style="padding-top: 200rpx;" />
<uv-empty v-if="members.length === 0" text="暂无成员" mode="list" style="padding-top: 200rpx;" />
</view>
</view>
</template>
@ -76,7 +71,13 @@ export default {
test1 () {
this.$api('informOrderAll', { leaderOrderId: this.mealId }, res => {
if (res.code === 200) {
this.$utils.showToast('通知成功')
uni.showToast({
title: '通知成功',
icon: 'success'
})
setTimeout(() => {
this.$utils.navigateBack()
}, 500)
}
})
},
@ -84,7 +85,13 @@ export default {
test2 () {
this.$api('finishOrderAll', { leaderOrderId: this.mealId }, res => {
if (res.code === 200) {
this.$utils.showToast('通知成功')
uni.showToast({
title: '通知成功',
icon: 'success'
})
setTimeout(() => {
this.$utils.navigateBack()
}, 500)
}
})
},
@ -150,4 +157,35 @@ export default {
.member-list {
//
}
.top-btn-group {
display: flex;
flex-direction: row;
justify-content: space-between;
gap: 24rpx;
margin-bottom: 32rpx;
margin-top: 16rpx;
padding: 0 20rpx;
}
.top-action-btn {
flex: 1;
background: linear-gradient(90deg, #01c97b 0%, #019245 100%);
color: #fff;
font-size: 32rpx;
font-weight: bold;
border: none;
border-radius: 16rpx;
box-shadow: 0 4rpx 12rpx rgba(1, 146, 69, 0.08);
padding: 24rpx 0;
margin: 0;
transition: background 0.2s;
letter-spacing: 2rpx;
outline: none;
}
.top-action-btn:active {
background: linear-gradient(90deg, #019245 0%, #01c97b 100%);
opacity: 0.85;
}
</style>

+ 57
- 26
pages_order/order/newOrderDetail.vue View File

@ -1,7 +1,7 @@
<template>
<view class="page">
<!-- 导航栏 -->
<navbar :title="orderStatus === 'pending' ? '待支付订单' : '订单详情' " leftClick @leftClick="navigateBack" bgColor="#019245"
<navbar title="订单详情 " leftClick @leftClick="navigateBack" bgColor="#019245"
color="#fff" />
<!-- 店铺信息 -->
@ -56,11 +56,11 @@
<text class="info-label">合计:</text>
<text class="info-value price">{{ orderDetail.priceAll }}</text>
</view>
<view class="info-item">
<view class="info-item" v-if="this.orderDetail.status != '-1'" >
<text class="info-label">创建时间:</text>
<text class="info-value">{{ orderDetail.createTime }}</text>
</view>
<view class="info-item">
<view class="info-item" v-if="this.orderDetail.status != '-1'">
<text class="info-label">订单编号:</text>
<text class="info-value">{{orderDetail.id}}</text>
</view>
@ -68,7 +68,7 @@
</view>
<view class="discount-info-container">
<!-- 优惠信息 -->
<view class="discount-info">
<view class="discount-info" @click="gotoCoupon">
<view class="discount-header">
<text>优惠</text>
</view>
@ -77,7 +77,7 @@
<image src="@/static/image/券.webp" mode="aspectFill" class="coupon-icon" />
<view>新用户立减</view>
</view>
<text class="discount-amount">-{{ orderDetail.pricePreferential }}</text>
<text class="discount-amount">-{{ orderDetail.pricePreferential || 0 }}</text>
</view>
</view>
@ -114,7 +114,7 @@
<view class="bottom-bar">
<view class="total-section">
<text class="total-label">{{ orderDetail.goodsList.length || 0 }}<text style="color: black;">合计</text> </text>
<text class="total-price">{{ orderDetail.pricePay }}</text>
<text class="total-price">{{ orderDetail.pricePay || cartPay }}</text>
</view>
<view class="pay-button" @tap="handlePay" v-if="orderStatus === '待支付'">立即下单</view>
<view class="pay-button" @tap="handlePay" v-if="orderStatus === '已送达'">立即取餐</view>
@ -124,7 +124,8 @@
<script>
import navbar from '@/components/base/navbar.vue'
import { mapState } from 'vuex'
import Cart from '../../pages/index/cart.vue'
export default {
components: {
navbar
@ -135,41 +136,66 @@
payMethod: 'weixin',
showAllFoods: false,
orderStatus: '',
orderDetail: { }
orderDetail: { },
cartDiscount: 0
}
},
computed: {
statusText() {
const statusMap = {
'pending': '等待支付',
'processing': '正在出餐',
'shipping': '正在配送中',
'delivered': '已送达,等待取餐',
'completed': '订单已完成',
'canceled': '订单已取消'
}
return statusMap[this.orderDetail.status] || '等待支付'
},
...mapState(['cartData']),
// statusText() {
// const statusMap = {
// 'pending': '',
// 'processing': '',
// 'shipping': '',
// 'delivered': '',
// 'completed': '',
// 'canceled': ''
// }
// return statusMap[this.orderDetail.status] || ''
// },
showedFoods() {
return this.showAllFoods ? this.orderDetail.goodsList : this.orderDetail.goodsList.slice(0, 3)
},
teamLeader() {
return this.orderDetail.teamLeader
}
},
cartPay() {
return this.orderDetail.priceAll - this.cartDiscount
},
},
onLoad(options) {
if (options.id) {
//
if (options.status === 'cart') {
this.showCartData()
//
this.orderStatus = '-1'
}
else if (options.id) {
this.getOrderDetail(options.id)
this.orderStatus = options.status
}
this.orderStatus = options.status
},
methods: {
//
navigateBack() {
uni.navigateBack()
},
//
showCartData() {
this.$api('queryMyLeader', {}, res => {
if (res.code === 200) {
this.orderDetail.teamLeader =
{
...res.result
}
}
})
console.log('cartData', this.cartData);
this.orderDetail.goodsList = this.cartData.sendData
this.orderDetail.priceAll = this.cartData.priceAll
},
//
getOrderDetail(id) {
this.id = id
@ -178,8 +204,6 @@
}, res => {
if (res.code === 200) {
this.orderDetail = res.result.records[0]
// console.log('111', this.orderDetail);
console.log('222', this.showedFoods);
}
})
@ -215,6 +239,13 @@
}
}, 1000)
}, 2000)
},
//
gotoCoupon() {
this.$utils.navigateTo({
url: '/pages_order/mine/coupon?isUseinOrder=true'
})
}
}
}


+ 2
- 0
store/store.js View File

@ -17,6 +17,7 @@ const store = new Vuex.Store({
category: [], //分类信息
payOrderProduct: [], //支付订单中的商品
promotionUrl : '',//分享二维码
couponData: {} //选中的优惠券数据
},
getters: {},
mutations: {
@ -208,6 +209,7 @@ const store = new Vuex.Store({
},
// 设置购物车数据
setCartData(state, data){
console.log('data', data)
state.cartData = data
},
},


+ 13
- 1
utils/position.js View File

@ -44,6 +44,11 @@ function getLocation(fn) { //获取用户经纬度
let key = config.mapKey; //腾讯地图key
getUserAddressByIp(key).then(res => {
fn(res.position) //返回经纬度
}).catch(err => {
uni.showToast({
title: '获取位置失败',
icon: 'error'
})
})
}
})
@ -118,6 +123,11 @@ function getUserAddressByIp(key) { //根据IP获取当前用户位置
uni.request({
url,
success: (res) => {
console.log('根据IP获取当前用户位置',res);
if (!res.data.result) {
reject(new Error('根据IP获取当前用户位置失败'))
return
}
let {
lat,
lng
@ -162,7 +172,9 @@ function wxGetLocation(successCallback, failCallback) {
type: 'gcj02',
isHighAccuracy: true,
highAccuracyExpireTime: 2000,
success(res) {},
success(res) {
},
fail(err) {
if(err.errMsg == 'getLocation:gps closed'){
uni.showToast({


Loading…
Cancel
Save