From c4c140bd07042fce602ce358fbab2ff9d84e5820 Mon Sep 17 00:00:00 2001 From: davy Date: Sun, 6 Apr 2025 12:46:05 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E6=88=91=E7=9A=84?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E5=8A=9F=E8=83=BD=201.=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=9C=AA=E7=99=BB=E5=BD=95=E7=8A=B6=E6=80=81=E6=96=87=E6=9C=AC?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=202.=20=E4=BC=98=E5=8C=96=E5=A4=B4=E5=83=8F?= =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E5=8A=9F=E8=83=BD=203.=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E9=97=A8=E5=BA=97ID=E5=A4=8D=E5=88=B6=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages.json | 3 +- pages/activityList/activityList.vue | 253 +++++----- pages/index/my.vue | 145 +++++- pages/index/myJoin.vue | 8 +- pages/index/review.vue | 23 +- pagesActivity/activityDetail.vue | 698 +++++++++++++++++++++------- pagesActivity/myActivityDetail.vue | 2 +- pagesActivity/scanResult.vue | 10 +- pagesMy/setting.vue | 48 +- 9 files changed, 881 insertions(+), 309 deletions(-) diff --git a/pages.json b/pages.json index f6d3de5..7e05f0f 100644 --- a/pages.json +++ b/pages.json @@ -190,7 +190,8 @@ "style" : { "navigationBarTitleText" : "活动详情", - "navigationStyle": "custom" + "navigationBarBackgroundColor": "#FFFFFF", + "navigationBarTextStyle": "black" } }, { diff --git a/pages/activityList/activityList.vue b/pages/activityList/activityList.vue index 20d9f48..dad6cdc 100644 --- a/pages/activityList/activityList.vue +++ b/pages/activityList/activityList.vue @@ -1,50 +1,51 @@ @@ -118,11 +119,19 @@ console.log('最终显示的数据:', arr); + // 过滤掉招募剩余天数为负数的活动 + const filteredRows = arr.filter(item => { + if (item.activityStatus === 1) { // 招募中状态 + return item.remainingDays >= 0 + } + return true + }); + // 更新显示列表 if (this.queryForm.pageNum === 1) { - this.activeList = arr; + this.activeList = filteredRows; } else { - this.activeList = [...this.activeList, ...arr]; + this.activeList = [...this.activeList, ...filteredRows]; } } else { if (this.queryForm.pageNum === 1) { @@ -226,89 +235,113 @@ \ No newline at end of file diff --git a/pages/index/my.vue b/pages/index/my.vue index 72cc409..b701129 100644 --- a/pages/index/my.vue +++ b/pages/index/my.vue @@ -8,8 +8,13 @@ {{ barInfo.nickName || barInfo.barContactPhone }} - 店铺名称:{{ barInfo.barName || '-'}} - 店铺ID:{{ barInfo.barNumber || '-' }} + 门店名称:{{ barInfo.barName || '-'}} + + 门店ID:{{ barInfo.barNumber || '-' }} + + + + @@ -83,7 +88,7 @@ - 添加枝点小助手 + 添加啤啤猩球小助手 @@ -143,6 +148,10 @@ if (!this.barInfo || this.barInfo.authState === 0) return 'unverified' // 未认证 if (this.barInfo.authState === 1) return 'verifying' // 认证中 return 'verified' // 认证通过 + }, + maskedPhone() { + if (!this.barInfo.barContactPhone) return ''; + return this.barInfo.barContactPhone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2'); } }, onLoad() { @@ -412,6 +421,120 @@ uni.navigateTo({ url: '/pages/index/registration' }) + }, + // 显示修改头像提示 + showChangeAvatar() { + uni.showActionSheet({ + itemList: ['修改头像'], + success: () => { + this.toSetting(); + } + }); + }, + + // 跳转到设置页面 + toSetting() { + uni.navigateTo({ + url: '/pagesMy/setting' + }); + }, + + // 获取用户信息 + getUserInfo() { + const barInfo = uni.getStorageSync('barInfo'); + const token = uni.getStorageSync('token'); + this.isLoggedIn = !!token; + if (barInfo) { + this.barInfo = barInfo; + // 如果没有昵称,设置默认昵称 + if (!this.barInfo.nickName) { + this.barInfo.nickName = this.barInfo.barName + '01'; + } + } + }, + // 复制门店ID + copyBarNumber() { + if (!this.barInfo || !this.barInfo.barNumber) { + uni.showToast({ + title: '暂无门店ID', + icon: 'none' + }); + return; + } + + uni.setClipboardData({ + data: this.barInfo.barNumber, + success: () => { + uni.showToast({ + title: '复制成功', + icon: 'success' + }); + } + }); + }, + // 选择头像 + async onChooseAvatar() { + try { + // 调用微信选择头像接口 + const res = await uni.chooseImage({ + count: 1, + sizeType: ['compressed'], + sourceType: ['album', 'camera'] + }) + + if (res.tempFilePaths && res.tempFilePaths.length > 0) { + uni.showLoading({ + title: '上传中...' + }) + + // 上传头像 + const uploadRes = await uni.uploadFile({ + url: '/bar/barinfo', // 使用编辑酒吧信息接口 + filePath: res.tempFilePaths[0], + name: 'barLogo', // 修改为正确的参数名 + header: { + 'Authorization': uni.getStorageSync('token') + }, + formData: { + // 添加其他必要的参数 + barNumber: this.barInfo.barNumber + } + }) + + // 解析响应数据 + let result + try { + result = JSON.parse(uploadRes.data) + } catch (e) { + result = uploadRes.data + } + + if (result.code === 200 && result.data) { + // 更新本地存储的门店信息 + const barInfo = uni.getStorageSync('barInfo') + barInfo.barLogo = result.data + uni.setStorageSync('barInfo', barInfo) + + // 更新页面显示 + this.barInfo = barInfo + + uni.showToast({ + title: '更新成功', + icon: 'success' + }) + } else { + throw new Error(result.msg || '上传失败') + } + } + } catch (error) { + console.error('选择头像失败:', error) + uni.showToast({ + title: error.message || '选择头像失败', + icon: 'none' + }) + } finally { + uni.hideLoading() + } } } } @@ -514,4 +637,20 @@ border-radius: 30rpx; margin: 0 auto; } + + .copy-btn { + margin-left: 16rpx; + padding: 4rpx 12rpx; + background: #F5F5F5; + border-radius: 8rpx; + + .cuIcon-copy { + font-size: 24rpx; + color: #666666; + } + + &:active { + opacity: 0.7; + } + } \ No newline at end of file diff --git a/pages/index/myJoin.vue b/pages/index/myJoin.vue index 1567d6e..a28aeaa 100644 --- a/pages/index/myJoin.vue +++ b/pages/index/myJoin.vue @@ -549,16 +549,16 @@ // 设置查询状态 switch(key) { case 0: // 累计中 - this.queryForm.status = 'ACCUMULATING' + this.queryForm.status = 1 // 使用整数类型 break case 1: // 待兑付 - this.queryForm.status = 'PENDING_PAYMENT' + this.queryForm.status = 2 // 使用整数类型 break case 2: // 已兑付 - this.queryForm.status = 'PAID' + this.queryForm.status = 3 // 使用整数类型 break case 3: // 已完成 - this.queryForm.status = 'COMPLETED' + this.queryForm.status = 4 // 使用整数类型 break default: delete this.queryForm.status diff --git a/pages/index/review.vue b/pages/index/review.vue index ca47f13..a3b46a5 100644 --- a/pages/index/review.vue +++ b/pages/index/review.vue @@ -488,17 +488,38 @@ } favorBeer(data).then(res => { if (status == 1) { + this.isFavor = true uni.showToast({ title: '收藏成功', icon: 'success' }) } else { + this.isFavor = false uni.showToast({ title: '取消收藏', icon: 'none' }) } - this.getBeerFavorStatusFun() + }).catch(err => { + if (err.code === 500 && err.msg.includes('门店未认证')) { + uni.showModal({ + title: '提示', + content: '请先认证门店', + showCancel: true, + success: (res) => { + if (res.confirm) { + uni.navigateTo({ + url: '/pages/index/registration' + }) + } + } + }) + } else { + uni.showToast({ + title: err.msg || '操作失败', + icon: 'none' + }) + } }) }, // 点赞 diff --git a/pagesActivity/activityDetail.vue b/pagesActivity/activityDetail.vue index 3be7ba0..5386315 100644 --- a/pagesActivity/activityDetail.vue +++ b/pagesActivity/activityDetail.vue @@ -1,51 +1,58 @@ @@ -126,42 +119,136 @@ getActivityInfo } from '@/api/bar.js' import process from './components/progress.vue'; + import loginPopup from '@/components/loginPopup.vue'; export default { components: { - process + process, + loginPopup }, data() { return { - statusBaeHeight: 40, id: '', activityInfo: {}, currentTab: 1, + countdownTime: { + hours: '00', + minutes: '00', + seconds: '00' + }, + timer: null, + isLoggedIn: false, + isVerified: false }; }, onLoad({ id }) { - this.statusBaeHeight = uni.getWindowInfo.statusBarHeight - this.id = id - this.init() + this.id = id; + this.init(); + this.checkLoginStatus(); }, computed: { processNum() { - if(this.activityInfo.duration) { - return (this.activityInfo.duration - this.activityInfo.remainingDays) / this.activityInfo.duration * 100 - }else { - return 0 + if(this.activityInfo.endDate) { + const endDate = new Date(this.activityInfo.endDate); + const startDate = new Date(this.activityInfo.startDate || new Date()); + const currentDate = new Date(); + + // 计算总天数 + const totalDays = Math.ceil((endDate - startDate) / (1000 * 3600 * 24)); + // 计算已经过去的天数 + const passedDays = Math.ceil((currentDate - startDate) / (1000 * 3600 * 24)); + + // 确保进度在0-100之间 + return Math.min(Math.max(Math.floor((passedDays / totalDays) * 100), 0), 100); } - + return 0; + }, + targetText() { + const { beer_scope, activityTarget, beers } = this.activityInfo; + if (!activityTarget) return '-'; + return beer_scope === 0 ? '全系列酒款' : '以下酒款'; } }, methods: { init() { getActivityInfo(this.id).then(res => { - this.activityInfo = res.data - this.activityInfo.remainingDays = this.getRemainingDays(res.data.endDate) + console.log('活动详情数据:', res.data); + this.activityInfo = res.data; + + // 检查关键数据是否存在 + if (!this.activityInfo.activityDuration) { + console.warn('缺少活动累计天数:activityDuration'); + } + if (!this.activityInfo.activityTarget) { + console.warn('缺少活动目标数量:activityTarget'); + } + if (typeof this.activityInfo.beer_scope === 'undefined') { + console.warn('缺少活动产品范围:beer_scope'); + } + + // 计算剩余天数 + this.activityInfo.remainingDays = this.getRemainingDays(res.data.endDate); + + // 计算活动总持续时间(用于进度条显示) + if(res.data.endDate && res.data.startDate) { + const endDate = new Date(res.data.endDate); + const startDate = new Date(res.data.startDate); + this.activityInfo.duration = Math.ceil((endDate - startDate) / (1000 * 3600 * 24)); + } + + // 启动倒计时 + this.startCountdown(); + }).catch(err => { + console.error('获取活动详情失败:', err); + uni.showToast({ + title: '获取活动信息失败', + icon: 'none' + }); }) }, + startCountdown() { + if(this.timer) { + clearInterval(this.timer); + } + + const updateCountdown = () => { + if(!this.activityInfo.endDate) return; + + const now = new Date().getTime(); + const end = new Date(this.activityInfo.endDate).getTime(); + const diff = end - now; + + if(diff <= 0) { + clearInterval(this.timer); + this.countdownTime = { + hours: '00', + minutes: '00', + seconds: '00' + }; + return; + } + + // 更新剩余天数 + this.activityInfo.remainingDays = this.getRemainingDays(this.activityInfo.endDate); + + // 计算时分秒 + const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); + const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)); + const seconds = Math.floor((diff % (1000 * 60)) / 1000); + + this.countdownTime = { + hours: hours.toString().padStart(2, '0'), + minutes: minutes.toString().padStart(2, '0'), + seconds: seconds.toString().padStart(2, '0') + }; + }; + + // 立即执行一次 + updateCountdown(); + // 每秒更新一次 + this.timer = setInterval(updateCountdown, 1000); + }, changeTab(index) { this.currentTab = index }, @@ -173,12 +260,13 @@ }, // 计算剩余天数 - getRemainingDays(date) { - const targetDate = new Date(date); + getRemainingDays(endDate) { + if(!endDate) return 0; + const targetDate = new Date(endDate); const currentDate = new Date(); const timeDiff = targetDate.getTime() - currentDate.getTime(); const remainingDays = Math.ceil(timeDiff / (1000 * 3600 * 24)); - return remainingDays; + return Math.max(remainingDays, 0); // 确保不会显示负数天数 }, handleScan() { uni.getSetting({ @@ -247,7 +335,109 @@ }, goBack() { uni.navigateBack() + }, + checkLoginStatus() { + const token = uni.getStorageSync('token'); + const barInfo = uni.getStorageSync('barInfo'); + + this.isLoggedIn = !!token; + this.isVerified = barInfo && barInfo.authState === 2; + }, + handleButtonClick() { + const token = uni.getStorageSync('token'); + if (!token) { + this.$refs.loginPopup.open(); + return; + } + + // 检查认证状态 + const barInfo = uni.getStorageSync('barInfo'); + if (!barInfo) { + uni.showModal({ + title: '提示', + content: '请先认证门店', + showCancel: true, + success: (res) => { + if (res.confirm) { + uni.navigateTo({ + url: '/pages/index/registration' + }); + } + } + }); + return; + } + + // 处理不同的认证状态 + if (barInfo.authState === 0) { + uni.showModal({ + title: '提示', + content: '请先认证门店', + showCancel: true, + success: (res) => { + if (res.confirm) { + uni.navigateTo({ + url: '/pages/index/registration' + }); + } + } + }); + return; + } else if (barInfo.authState === 1) { + uni.showToast({ + title: '您的门店正在认证中,请耐心等待', + icon: 'none' + }); + return; + } + + // 都通过后执行扫码 + this.handleScan(); + }, + onLoginSuccess() { + // 登录成功后重新检查状态 + this.checkLoginStatus(); + + // 检查认证状态 + const barInfo = uni.getStorageSync('barInfo'); + if (!barInfo || barInfo.authState === 0) { + uni.showModal({ + title: '提示', + content: '请先认证门店', + showCancel: true, + success: (res) => { + if (res.confirm) { + uni.navigateTo({ + url: '/pages/index/registration' + }); + } + } + }); + return; + } else if (barInfo.authState === 1) { + uni.showToast({ + title: '您的门店正在认证中,请耐心等待', + icon: 'none' + }); + return; + } + + // 如果已认证,直接执行扫码 + if (this.isVerified) { + this.handleScan(); + } } + }, + onUnload() { + // 页面卸载时清除定时器 + if(this.timer) { + clearInterval(this.timer); + this.timer = null; + } + }, + onShow() { + // 每次页面显示时检查登录状态 + this.checkLoginStatus(); } } @@ -255,137 +445,157 @@ \ No newline at end of file diff --git a/pagesActivity/myActivityDetail.vue b/pagesActivity/myActivityDetail.vue index f8f4b86..9eadb4e 100644 --- a/pagesActivity/myActivityDetail.vue +++ b/pagesActivity/myActivityDetail.vue @@ -32,7 +32,7 @@ diff --git a/pagesActivity/scanResult.vue b/pagesActivity/scanResult.vue index 4f3542f..63445f6 100644 --- a/pagesActivity/scanResult.vue +++ b/pagesActivity/scanResult.vue @@ -102,9 +102,8 @@ {{ it.activityName }} - 时间:首次扫码开始累计 {{it.duration}}天内 - - 目标:全系列酒款累积扫码 ≥ {{ it.activityTarget}}桶 + 时间:首次扫码开始累计 {{it.duration}}天内 + 目标:{{ it.beer_scope === 0 ? '全系列酒款' : '以下酒款' }}累积扫码 ≥ {{ it.activityTarget}}桶 @@ -140,9 +139,8 @@ {{ it.activityName }} - 时间:首次扫码开始累计 {{it.duration}}天内 - - 目标:全系列酒款累积扫码 ≥ {{ it.activityTarget}}桶 + 时间:首次扫码开始累计 {{it.duration}}天内 + 目标:{{ it.beer_scope === 0 ? '全系列酒款' : '以下酒款' }}累积扫码 ≥ {{ it.activityTarget}}桶 diff --git a/pagesMy/setting.vue b/pagesMy/setting.vue index cab664d..cf16c90 100644 --- a/pagesMy/setting.vue +++ b/pagesMy/setting.vue @@ -48,7 +48,7 @@ 所在地区 - {{form.region}} + {{form.city || '--'}} @@ -67,7 +67,7 @@ 门店ID - N080202 + {{ barInfo.barNumber || '--' }} @@ -350,11 +350,12 @@ storefrontPhoto: '', // 门头照 position: '', // 职务 openId: '', - region: '' + city: '' }, userInfo: {}, currentTab: 1, QQMap: null, + barInfo: {}, }; }, computed: { @@ -370,13 +371,20 @@ // }); this.getBarInfoFun() }, + onShow() { + // 获取最新的门店信息 + const barInfo = uni.getStorageSync('barInfo'); + if (barInfo) { + this.barInfo = barInfo; + } + }, methods: { goBack() { uni.navigateBack(); }, copyId() { uni.setClipboardData({ - data: 'N080202', + data: this.barInfo.barNumber || '', success: () => { uni.showToast({ title: '复制成功', @@ -533,6 +541,9 @@ // 只保留微信头像选择方法 onChooseAvatar(e) { const avatarUrl = e.detail.avatarUrl; + uni.showLoading({ + title: '上传中' + }); // 上传头像到服务器 uni.uploadFile({ url: base_url + '/bar/common/upload', @@ -542,9 +553,36 @@ type: 'image' }, success: (uploadFileRes) => { - this.form.barLogo = JSON.parse(uploadFileRes.data).url; + try { + let result; + if (typeof uploadFileRes.data === 'string') { + result = JSON.parse(uploadFileRes.data); + } else { + result = uploadFileRes.data; + } + + if (result && result.code === 200) { + this.form.barLogo = result.data; // 使用data字段获取URL + uni.hideLoading(); + uni.showToast({ + title: '上传成功', + icon: 'success' + }); + } else { + throw new Error(result?.msg || '上传失败'); + } + } catch (error) { + console.error('Upload response parsing error:', error); + uni.hideLoading(); + uni.showToast({ + title: error.message || '上传失败', + icon: 'none' + }); + } }, fail: (err) => { + console.error('Upload failed:', err); + uni.hideLoading(); uni.showToast({ title: '头像上传失败', icon: 'none'