feat: 修改活动小按钮改为动态
This commit is contained in:
parent
e81ef0a375
commit
8b03809c7a
@ -559,6 +559,7 @@ func convertActivityListResponse(resp *pbActivity.GetActivityListResponse) map[s
|
||||
"banner_image": activity.BannerImage,
|
||||
"current_stage_background": activity.CurrentStageBackground,
|
||||
"current_stage_title": activity.CurrentStageTitle,
|
||||
"icon": activity.Icon,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -20,6 +20,7 @@ type Activity struct {
|
||||
CurrentProgress int64 `json:"current_progress" gorm:"default:0"`
|
||||
Status string `json:"status" gorm:"size:20;default:pending"` // pending/active/completed/expired
|
||||
StageConfigs json.RawMessage `json:"stage_configs" gorm:"type:jsonb"` // 阶段配置
|
||||
Icon string `json:"icon" gorm:"size:500"` // 活动图标
|
||||
CreatedAt int64 `json:"created_at" gorm:"not null"`
|
||||
UpdatedAt int64 `json:"updated_at" gorm:"not null"`
|
||||
|
||||
|
||||
@ -44,6 +44,7 @@ type Activity struct {
|
||||
CurrentStageBackground string `protobuf:"bytes,15,opt,name=current_stage_background,json=currentStageBackground,proto3" json:"current_stage_background,omitempty"` // 当前阶段背景图
|
||||
CurrentStageTitle string `protobuf:"bytes,16,opt,name=current_stage_title,json=currentStageTitle,proto3" json:"current_stage_title,omitempty"` // 当前阶段标题
|
||||
OverallEndTime int64 `protobuf:"varint,18,opt,name=overall_end_time,json=overallEndTime,proto3" json:"overall_end_time,omitempty"` // 整体活动结束时间
|
||||
Icon string `protobuf:"bytes,19,opt,name=icon,proto3" json:"icon,omitempty"` // 活动图标
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
@ -204,6 +205,13 @@ func (x *Activity) GetOverallEndTime() int64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Activity) GetIcon() string {
|
||||
if x != nil {
|
||||
return x.Icon
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// 活动道具
|
||||
type ActivityItem struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
@ -1355,7 +1363,7 @@ var File_activity_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_activity_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x0eactivity.proto\x12\x10topfans.activity\x1a\x12proto/common.proto\x1a\x1cgoogle/api/annotations.proto\"\xff\x04\n" +
|
||||
"\x0eactivity.proto\x12\x10topfans.activity\x1a\x12proto/common.proto\x1a\x1cgoogle/api/annotations.proto\"\x93\x05\n" +
|
||||
"\bActivity\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\x03R\x02id\x12#\n" +
|
||||
"\ractivity_type\x18\x02 \x01(\tR\factivityType\x12\x14\n" +
|
||||
@ -1377,7 +1385,8 @@ const file_activity_proto_rawDesc = "" +
|
||||
"\fbanner_image\x18\x0e \x01(\tR\vbannerImage\x128\n" +
|
||||
"\x18current_stage_background\x18\x0f \x01(\tR\x16currentStageBackground\x12.\n" +
|
||||
"\x13current_stage_title\x18\x10 \x01(\tR\x11currentStageTitle\x12(\n" +
|
||||
"\x10overall_end_time\x18\x12 \x01(\x03R\x0eoverallEndTime\"\xc7\x01\n" +
|
||||
"\x10overall_end_time\x18\x12 \x01(\x03R\x0eoverallEndTime\x12\x12\n" +
|
||||
"\x04icon\x18\x13 \x01(\tR\x04icon\"\xc7\x01\n" +
|
||||
"\fActivityItem\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\x03R\x02id\x12\x1b\n" +
|
||||
"\titem_type\x18\x02 \x01(\tR\bitemType\x12\x1b\n" +
|
||||
|
||||
@ -29,6 +29,7 @@ message Activity {
|
||||
string current_stage_background = 15; // 当前阶段背景图
|
||||
string current_stage_title = 16; // 当前阶段标题
|
||||
int64 overall_end_time = 18; // 整体活动结束时间
|
||||
string icon = 19; // 活动图标
|
||||
}
|
||||
|
||||
// 活动道具
|
||||
|
||||
2
backend/scripts/migrate_add_icon_to_activities.sql
Normal file
2
backend/scripts/migrate_add_icon_to_activities.sql
Normal file
@ -0,0 +1,2 @@
|
||||
-- 添加 icon 字段到 activities 表
|
||||
ALTER TABLE activities ADD COLUMN icon VARCHAR(500) DEFAULT '' COMMENT '活动图标';
|
||||
@ -35,17 +35,24 @@
|
||||
</view>
|
||||
</view> -->
|
||||
|
||||
<!-- 星援活动 -->
|
||||
<view v-if="showStarActivityIcon" class="daily-task-group" @click="handleStarActivityClick">
|
||||
<!-- 1. 上层:星援活动(悬浮在上面) -->
|
||||
<view class="task-icon-box">
|
||||
<image class="task-icon-img" src="/static/icon/bus-icon.png" mode="aspectFit"></image>
|
||||
<image class="task-red-dot" src="/static/square/tishi.png" mode="aspectFit"></image>
|
||||
</view>
|
||||
<!-- 星援活动列表 -->
|
||||
<view v-if="showStarActivityIcon" class="star-activity-list">
|
||||
<view
|
||||
v-for="activity in starActivities"
|
||||
:key="activity.id"
|
||||
class="daily-task-group"
|
||||
@click="handleActivityClick(activity)"
|
||||
>
|
||||
<!-- 上层:活动图标 -->
|
||||
<view class="task-icon-box">
|
||||
<image class="task-icon-img" :src="activity.icon || '/static/icon/bus-icon.png'" mode="aspectFit"></image>
|
||||
<image class="task-red-dot" src="/static/square/tishi.png" mode="aspectFit"></image>
|
||||
</view>
|
||||
|
||||
<!-- 2. 下层:文字背景块 -->
|
||||
<view class="task-text-box">
|
||||
<text class="task-text-label">星援活动</text>
|
||||
<!-- 下层:文字背景块 -->
|
||||
<view class="task-text-box">
|
||||
<text class="task-text-label">{{ activity.theme || '星援活动' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@ -94,9 +101,12 @@ import { useStore } from 'vuex';
|
||||
import Avatar from './Avatar.vue';
|
||||
import DailyTasks from '@/pages/tasks/daily-tasks.vue';
|
||||
import GuideModal from '@/pages/tasks/GuideModal.vue';
|
||||
import { getActivityListApi } from '@/utils/api.js';
|
||||
import { useBanner } from '@/pages/square/composables/useBanner.js';
|
||||
import { reportEvent } from '@/utils/task-api.js';
|
||||
|
||||
// 获取星援活动数据(复用 square 的 useBanner)
|
||||
const { bannerActivities, loadBannerActivities } = useBanner();
|
||||
|
||||
// 定义 props
|
||||
const props = defineProps({
|
||||
showBack: {
|
||||
@ -226,9 +236,16 @@ function checkAndReportDailyLogin() {
|
||||
}
|
||||
}
|
||||
|
||||
// 组件挂载时加载用户信息并监听事件
|
||||
// 星援活动列表 - 从 bannerActivities 中获取非 expired 的活动
|
||||
const starActivities = computed(() => {
|
||||
// return bannerActivities.value
|
||||
return bannerActivities.value.filter(activity => activity.status !== 'expired');
|
||||
});
|
||||
|
||||
// 组件挂载时加载用户信息和星援活动数据
|
||||
onMounted(() => {
|
||||
loadUserInfo();
|
||||
loadBannerActivities();
|
||||
uni.$on('avatarUpdated', handleAvatarUpdate);
|
||||
uni.$on('userInfoUpdated', handleUserInfoUpdate);
|
||||
uni.$on('balanceUpdated', handleBalanceUpdate);
|
||||
@ -270,58 +287,10 @@ const handleTaskClick = () => {
|
||||
};
|
||||
|
||||
// 处理星援活动图标点击
|
||||
const handleStarActivityClick = async () => {
|
||||
try {
|
||||
// 从本地存储获取star_id
|
||||
const starId = uni.getStorageSync('star_id');
|
||||
if (!starId) {
|
||||
uni.showToast({
|
||||
title: '无法获取用户信息',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 显示加载提示
|
||||
uni.showLoading({
|
||||
title: '加载中...'
|
||||
});
|
||||
|
||||
// 调用API获取活动列表
|
||||
const response = await getActivityListApi(starId, 1, 10);
|
||||
|
||||
uni.hideLoading();
|
||||
|
||||
// 检查响应数据
|
||||
if (response && response.data && response.data.activities) {
|
||||
const activities = response.data.activities;
|
||||
|
||||
// 查找activity_type为bus的活动
|
||||
const busActivity = activities.find(activity => activity.activity_type === 'bus');
|
||||
|
||||
if (busActivity) {
|
||||
// 跳转到应援活动页面
|
||||
uni.navigateTo({
|
||||
url: `/pages/support-activity/index?id=${busActivity.id}`
|
||||
});
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '暂无巴士应援活动',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '获取活动列表失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
uni.hideLoading();
|
||||
console.error('获取活动列表失败:', error);
|
||||
uni.showToast({
|
||||
title: error.message || '获取活动列表失败',
|
||||
icon: 'none'
|
||||
const handleActivityClick = (activity) => {
|
||||
if (activity) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/support-activity/index?id=${activity.id}`
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -443,6 +412,12 @@ defineExpose({
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.star-activity-list {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
.daily-task-group {
|
||||
position: relative;
|
||||
/* 必须是相对定位,作为子元素的定位基准 */
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
>
|
||||
<view
|
||||
ref="waterfallInnerRef"
|
||||
class="waterfall-inner ios-css-animate"
|
||||
:class="{'waterfall-inner': true, 'ios-css-animate': !iosScrollPaused}"
|
||||
:style="innerStyle"
|
||||
>
|
||||
<view
|
||||
@ -742,11 +742,12 @@ const handleCardClick = (card) => {
|
||||
});
|
||||
} else {
|
||||
// 第一次点击,单击跳转
|
||||
|
||||
cardTapTimers[card.id] = setTimeout(() => {
|
||||
delete cardTapTimers[card.id];
|
||||
uni.navigateTo({ url: `/pages/asset-detail/asset-detail?asset_id=${card.id}` });
|
||||
}, 300);
|
||||
if(card.id){
|
||||
cardTapTimers[card.id] = setTimeout(() => {
|
||||
delete cardTapTimers[card.id];
|
||||
uni.navigateTo({ url: `/pages/asset-detail/asset-detail?asset_id=${card.id}` });
|
||||
}, 300);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -966,7 +967,7 @@ const loadUsersAndStartScroll = () => {
|
||||
}
|
||||
|
||||
@keyframes iosAutoScroll {
|
||||
from { transform: translateX(0); }
|
||||
/* from { transform: translateX(0); } */
|
||||
to { transform: translateX(var(--scroll-dist)); }
|
||||
}
|
||||
|
||||
|
||||
@ -11,8 +11,9 @@ export function useBanner() {
|
||||
|
||||
if (res.code === 200 && res.data?.activities) {
|
||||
const activities = res.data.activities
|
||||
// 直接使用后端返回的图片URL
|
||||
bannerActivities.value = activities
|
||||
// 过滤掉已过期的活动
|
||||
// bannerActivities.value = activities
|
||||
bannerActivities.value = activities.filter(item => item.status !== 'expired')
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('[useBanner] 加载 banner 活动失败', e?.message ?? e)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user