Compare commits

..

No commits in common. "4466afd8a1b6079309ecb2b5ccc0d6afae7f8ec5" and "f635a06acbbda93c0107df7df7da570da502716e" have entirely different histories.

7 changed files with 120 additions and 480 deletions

View File

@ -8,33 +8,16 @@ let showModal = false
const publicApis = [
'/beer/list', // 啤酒列表
'/beer/detail', // 啤酒详情
'/beer/favor/status', // 收藏状态
'/beer/review/score', // 评分
'/beer/review/list', // 评价列表
'/activity/list', // 活动列表
'/activity/detail', // 活动详情
'/bar/detail', // 酒吧详情
'/bar/list', // 酒吧列表
'/common/', // 公共接口
'/bar/brewery/getBeerInfo', // 获取酒款信息
'/bar/brewery/getReviewList', // 获取酒评列表
'/bar/brewery/getReviewScoreList', // 获取酒评评分列表
'/bar/brewery/getActivities', // 获取活动列表
'/bar/brewery/getActivityInfo', // 获取活动详情
'/bar/brewery/getBreweryInfo', // 获取品牌详情
]
// 检查是否是公开API
const isPublicApi = (url) => {
// 使用更精确的匹配方式
return publicApis.some(api => {
// 如果是完整路径匹配
if (api.includes('/')) {
return url.includes(api);
}
// 如果是通配符匹配
return url.split('/').includes(api);
});
return publicApis.some(api => url.includes(api))
}
export default (params) => {
@ -73,7 +56,7 @@ export default (params) => {
showModal = true
uni.showModal({
title: "提示",
content: res.data.msg || "身份已过期,请重新登录",
content: "身份已过期,请重新登录",
showCancel: false,
success() {
showModal = false
@ -83,14 +66,11 @@ export default (params) => {
},
});
} else {
// 对于公开接口的401错误不显示错误提示
if (!isPublicApi(url)) {
uni.showToast({
title: res.data.msg || '请求失败',
icon: 'none',
duration: 3000,
})
}
uni.showToast({
title: res.data.msg || '请求失败',
icon: 'none',
duration: 3000,
})
reject(res.data)
}

View File

@ -1,244 +0,0 @@
<template>
<view class="brand-filter-popup" v-if="show">
<view class="mask" @click="close"></view>
<view class="content">
<view class="page-content">
<!-- 标题区域 -->
<view class="section">
<view class="section-title">
筛选品牌
<view class="close-btn" @click="close">
<text class="cuIcon-close"></text>
</view>
</view>
</view>
<!-- 品牌列表区域 -->
<view class="section brand-list-section">
<scroll-view scroll-y="true" class="brand-list">
<!-- 全部选项 -->
<view class="brand-item" @tap="selectAll">
<view class="item-content" :class="{'selected': isAllSelected}">
<text>全部</text>
</view>
</view>
<!-- 品牌列表 -->
<view class="brand-item"
v-for="(item, index) in brandList"
:key="index"
@tap="selectBrand(item)">
<view class="item-content" :class="{'selected': selectedBrand === item.id}">
<text class="brand-name">{{item.name}}</text>
</view>
</view>
</scroll-view>
</view>
<!-- 底部按钮 -->
<view class="button-group">
<view class="reset-btn" @click="reset">重置</view>
<view class="save-btn" @click="confirm">确定</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'brand-filter',
data() {
return {
show: false,
brandList: [],
selectedBrand: null,
isAllSelected: true
}
},
methods: {
open() {
this.show = true;
},
close() {
this.show = false;
},
selectAll() {
this.isAllSelected = true;
this.selectedBrand = null;
this.$emit('confirm', {
id: null,
name: '全部'
});
this.close();
},
selectBrand(brand) {
this.selectedBrand = brand.id;
this.isAllSelected = false;
this.$emit('confirm', {
id: brand.id,
name: brand.name
});
this.close();
},
reset() {
this.selectAll();
},
confirm() {
this.$emit('confirm', {
id: this.selectedBrand,
name: this.selectedBrand ? this.brandList.find(b => b.id === this.selectedBrand)?.name : '全部'
});
this.close();
},
//
extractBrandsFromList(listData) {
if (!Array.isArray(listData) || listData.length === 0) {
return;
}
// 使Set
const brandSet = new Set();
const brands = [];
listData.forEach(item => {
if (item.breweryId && !brandSet.has(item.breweryId)) {
brandSet.add(item.breweryId);
brands.push({
id: item.breweryId,
name: item.breweryName || '未知品牌'
});
}
});
//
this.brandList = brands.sort((a, b) => a.name.localeCompare(b.name));
}
}
}
</script>
<style lang="scss" scoped>
.brand-filter-popup {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 999;
.mask {
position: absolute;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.4);
}
.content {
position: absolute;
bottom: 0;
width: 100%;
background: #F7F7F7;
border-radius: 32rpx 32rpx 0 0;
.page-content {
padding: 24rpx 32rpx;
.section {
background: #FFFFFF;
border-radius: 16rpx;
margin-bottom: 24rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
.section-title {
font-size: 32rpx;
font-weight: 600;
padding: 32rpx;
color: #333333;
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
&::after {
content: '';
position: absolute;
left: 32rpx;
bottom: 0;
width: 48rpx;
height: 4rpx;
background: #19367A;
border-radius: 2rpx;
}
.close-btn {
font-size: 36rpx;
color: #999999;
padding: 10rpx;
}
}
}
.brand-list-section {
.brand-list {
max-height: 60vh;
padding: 24rpx;
.brand-item {
margin-bottom: 24rpx;
.item-content {
padding: 24rpx;
background: #F7F7F7;
border-radius: 12rpx;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s;
&.selected {
background: rgba(25, 54, 122, 0.05);
border: 2rpx solid #19367A;
}
.brand-name {
font-size: 28rpx;
color: #333333;
text-align: center;
}
}
}
}
}
.button-group {
display: flex;
justify-content: space-between;
gap: 24rpx;
.reset-btn, .save-btn {
flex: 1;
height: 88rpx;
border-radius: 44rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 32rpx;
font-weight: 500;
}
.reset-btn {
background: #F7F7F7;
color: #666666;
border: 2rpx solid #E5E5E5;
}
.save-btn {
background: #19367A;
color: #FFFFFF;
}
}
}
}
}
</style>

View File

@ -406,12 +406,6 @@
"network": "all",
"packages": ["pagesActivity","pagesCoin","pagesMy"]
}
},
"easycom": {
"autoscan": true,
"custom": {
"^u-(.*)": "uview-ui/components/u-$1/u-$1.vue",
"^brand-filter": "@/components/brandFilter.vue"
}
}
}
}

View File

@ -6,15 +6,15 @@
<view class="tabs-content">
<view
class="tab-item"
:class="{'active-tag': queryForm.orderType == 'latest'}"
@click="changeOrder('latest')"
:class="{'active-tag': queryForm.orderBy == 'create_time'}"
@click="changeOrder('create_time')"
>最新发布</view>
<view
class="tab-item"
:class="{'active-tag': queryForm.orderType == 'popularity'}"
:class="{'active-tag': queryForm.orderBy == 'popularity'}"
@click="changeOrder('popularity')"
>人气排名</view>
<view class="brand-filter" :class="{ active: selectedBrand !== null }" @click="showBrandFilter">
<view class="brand-filter" :class="{ active: isFilterActive }" @click="showBrandFilter">
<text>筛选品牌</text>
<image :src="'/static/icons/filter.svg'" mode="aspectFit" class="filter-icon"></image>
</view>
@ -64,8 +64,6 @@
</scroll-view>
</view>
<loginPopup ref="loginRef"></loginPopup>
<!-- 品牌筛选组件 -->
<brand-filter ref="brandFilterRef" @confirm="onBrandFilterConfirm"></brand-filter>
</view>
</view>
</template>
@ -74,96 +72,36 @@
import {
getActivities
} from '@/api/bar.js'
import loginPopup from '@/components/loginPopup.vue'
import brandFilter from '@/components/brandFilter.vue'
import loginPopup from '@/components/loginPopup.vue';
export default {
components: {
loginPopup,
brandFilter
loginPopup
},
data() {
return {
activeList: [], //
loading: false,
isRefreshing: false,
isRefreshing: false, //
queryForm: {
pageNum: 1,
pageSize: 5,
orderType: 'latest',
orderBy: 'create_time' //
},
total: 0,
isFilterActive: false,
userLocation: null,
isLocationReady: false, //
originalList: [], //
selectedBrand: null, // ID
isFilterActive: false //
};
},
onLoad() {
//
this.getActivitiesFun();
//
this.getUserLocation();
//
this.getActivitiesFun()
},
methods: {
//
getUserLocation() {
uni.getLocation({
type: 'gcj02',
success: (res) => {
this.userLocation = {
latitude: res.latitude,
longitude: res.longitude
};
this.isLocationReady = true;
//
this.filterListByLocation();
},
fail: (err) => {
console.error('获取位置失败:', err);
this.isLocationReady = true;
uni.showToast({
title: '未获取到位置信息,将显示所有活动',
icon: 'none',
duration: 2000
});
}
});
},
//
filterListByLocation() {
if (this.originalList.length > 0) {
this.activeList = this.originalList.filter(item => this.isActivityInUserCity(item.city));
}
},
//
isActivityInUserCity(activityCity) {
if (!this.userLocation) return false;
try {
const cityList = JSON.parse(activityCity);
//
return true; // true
} catch (e) {
return false;
}
},
//
changeOrder(type) {
//
if (this.queryForm.orderType === type) return;
//
this.queryForm.orderType = type;
//
changeOrder(key) {
if (this.queryForm.orderBy === key) return;
this.queryForm.orderBy = key;
this.queryForm.pageNum = 1;
this.activeList = [];
//
this.getActivitiesFun();
},
@ -177,75 +115,35 @@
//
toDetail(item) {
if (!uni.getStorageSync('token')) {
this.$refs.loginRef.open()
return
}
uni.navigateTo({
url: "/pagesActivity/activityDetail?id=" + item.id
});
},
//
toReview(it) {
uni.navigateTo({
url: "/pages/index/review?beerId=" + it.id
});
})
},
//
getActivitiesFun() {
this.loading = true;
const params = {
pageNum: this.queryForm.pageNum,
pageSize: this.queryForm.pageSize
};
//
if (this.selectedBrand) {
params.breweryId = this.selectedBrand;
} else {
//
params.orderBy = this.queryForm.orderType === 'latest' ? 'start_date' : 'popularity';
params.order = 'desc';
}
getActivities(params).then(res => {
getActivities(this.queryForm).then(res => {
this.total = res.total;
if(res.rows && res.rows.length > 0) {
let arr = res.rows.map(it => {
it.remainingDays = this.getRemainingDays(it.endDate);
return it;
});
// (2,3)(4)(0)
arr = arr.filter(item => item.stage === 1);
//
if (this.selectedBrand) {
arr = arr.filter(item => item.breweryId === this.selectedBrand);
}
//
this.originalList = arr;
//
if (this.isLocationReady && this.userLocation) {
arr = arr.filter(item => this.isActivityInUserCity(item.city));
}
//
//
if (this.queryForm.pageNum === 1) {
this.activeList = arr;
} else {
//
this.activeList = [...this.activeList, ...arr];
}
} else {
if (this.queryForm.pageNum === 1) {
this.activeList = [];
this.originalList = [];
}
}
this.loading = false;
}).catch(err => {
console.error('获取活动列表失败:', err);
this.loading = false;
});
},
@ -261,25 +159,8 @@
//
showBrandFilter() {
//
if (!this.originalList || this.originalList.length === 0) {
this.queryForm.pageNum = 1;
this.getActivitiesFun().then(() => {
this.$refs.brandFilterRef.extractBrandsFromList(this.originalList);
this.$refs.brandFilterRef.open();
});
} else {
this.$refs.brandFilterRef.extractBrandsFromList(this.originalList);
this.$refs.brandFilterRef.open();
}
},
//
onBrandFilterConfirm(result) {
this.selectedBrand = result.id;
this.queryForm.pageNum = 1;
this.activeList = [];
this.getActivitiesFun();
this.isFilterActive = !this.isFilterActive;
//
},
//
@ -290,7 +171,19 @@
this.activeList = [];
//
this.getActivitiesFun();
getActivities(this.queryForm).then(res => {
this.total = res.total;
if(res.rows && res.rows.length > 0) {
let arr = res.rows.map(it => {
it.remainingDays = this.getRemainingDays(it.endDate);
return it;
});
this.activeList = arr;
}
this.isRefreshing = false;
}).catch(err => {
this.isRefreshing = false;
});
}
}
}

View File

@ -110,7 +110,7 @@
</view>
</view>
<view class="cu-load" style="height: 88rpx;"></view>
<view class="more-btn-box" @click="moreHotActivity">
<view class="more-btn-box" @click="moreClick">
<view class="more-btn">更多热门活动招募</view>
</view>
</scroll-view>
@ -296,6 +296,10 @@
})
},
toGo(key) {
//
const token = uni.getStorageSync('token')
const userInfo = uni.getStorageSync('userInfo')
switch (key) {
case 1: //
uni.navigateTo({
@ -303,29 +307,80 @@
})
break;
case 2: //
if (!token || !userInfo) {
this.$refs.loginRef.open()
return
}
if (!userInfo.barId) {
uni.showModal({
title: '提示',
content: '您还未认证门店,请先完成认证',
showCancel: true,
success: (res) => {
if (res.confirm) {
uni.navigateTo({
url: '/pages/index/registration'
})
}
}
})
return
}
uni.navigateTo({
url: "/pagesActivity/winelist"
})
break;
case 3: //
if (!token || !userInfo) {
this.$refs.loginRef.open()
return
}
if (!userInfo.barId) {
uni.showModal({
title: '提示',
content: '您还未认证门店,请先完成认证',
showCancel: true,
success: (res) => {
if (res.confirm) {
uni.navigateTo({
url: '/pages/index/registration'
})
}
}
})
return
}
uni.navigateTo({
url: "/pagesCoin/beerCoin"
})
break;
case 4: //
const token = uni.getStorageSync('token')
if (!token) {
if (!token || !userInfo) {
this.$refs.loginRef.open()
return
}
if (!userInfo.barId) {
uni.showModal({
title: '提示',
content: '您还未认证门店,请先完成认证',
showCancel: true,
success: (res) => {
if (res.confirm) {
uni.navigateTo({
url: '/pages/index/registration'
})
}
}
})
return
}
uni.navigateTo({
url: '/pagesMy/myAttention'
})
break;
}
},
//
moreHotActivity() {
moreClick() {
uni.navigateTo({
url: "/pages/activityList/activityList"
})

View File

@ -267,15 +267,13 @@
isFavor: false, //
};
},
onLoad({beerId}) {
onLoad({
beerId
}) {
this.beerId = beerId
this.queryForm.beerId = beerId
this.getBeerInfoFun()
//
const token = uni.getStorageSync('token')
if (token) {
this.getBeerFavorStatusFun()
}
this.getBeerFavorStatusFun() //
},
onShow() {
console.log('show')
@ -283,9 +281,7 @@
this.queryForm.pageNum = 1
this.getReviewListFun()
this.getReviewScoreListFun()
//
const token = uni.getStorageSync('token')
if (token) {
if (uni.getStorageSync('token')) {
this.getMyReviewInfoFun()
}
//
@ -302,11 +298,6 @@
},
//
getBeerFavorStatusFun() {
const token = uni.getStorageSync('token')
if (!token) {
this.$refs.loginRef.open()
return
}
getBeerFavorStatus(this.beerId).then(res => {
if(res.data) {
this.isFavor = true
@ -358,19 +349,13 @@
},
//
getMyReviewInfoFun() {
const token = uni.getStorageSync('token')
if (!token) {
this.$refs.loginRef.open()
return
}
getMyReviewInfo(this.beerId).then(res => {
this.myReviewInfo = res.data
})
},
//
toWrite() {
const token = uni.getStorageSync('token')
if (!token) {
if (!uni.getStorageSync('token')) {
this.$refs.loginRef.open()
return
}
@ -393,8 +378,7 @@
},
//
favorBeerFun(status) {
const token = uni.getStorageSync('token')
if (!token) {
if (!uni.getStorageSync('token')) {
this.$refs.loginRef.open()
return
}
@ -419,8 +403,7 @@
},
//
handleLike(item) {
const token = uni.getStorageSync('token')
if (!token) {
if (!uni.getStorageSync('token')) {
this.$refs.loginRef.open()
return
}
@ -442,12 +425,16 @@
})
item.reviewLike = false
}
// this.reviewList = []
// this.queryForm.pageNum = 1
// this.getReviewListFun()
})
},
//
toWinelist() {
const token = uni.getStorageSync('token')
if (!token) {
if (!uni.getStorageSync('token')) {
this.$refs.loginRef.open()
return
}

View File

@ -216,31 +216,6 @@
return
}
//
const token = uni.getStorageSync('token')
const isAuth = uni.getStorageSync('isAuth')
if (!token) {
this.$refs.loginRef.open()
return
}
if (!isAuth) {
uni.showModal({
title: '提示',
content: '您还未认证门店,请先完成认证',
confirmText: '去认证',
success: (res) => {
if (res.confirm) {
uni.navigateTo({
url: '/pagesActivity/barAuth'
})
}
}
})
return
}
if (this.currentStep < 3) {
this.currentStep++
}