diff --git a/App.vue b/App.vue index 8c2b732..d22b78e 100644 --- a/App.vue +++ b/App.vue @@ -2,6 +2,7 @@ export default { onLaunch: function() { console.log('App Launch') + try { uni.setStorageSync('app_session_id', String(Date.now())) } catch (_) {} }, onShow: function() { console.log('App Show') diff --git a/api/appUser.js b/api/appUser.js index bf2c5d4..93ebb4c 100644 --- a/api/appUser.js +++ b/api/appUser.js @@ -57,4 +57,12 @@ export function getActivityIssues(activity_id) { export function getActivityIssueRewards(activity_id, issue_id) { return authRequest({ url: `/api/app/activities/${activity_id}/issues/${issue_id}/rewards`, method: 'GET' }) -} \ No newline at end of file +} + +export function drawActivityIssue(activity_id, issue_id) { + return authRequest({ url: `/api/app/activities/${activity_id}/issues/${issue_id}/draw`, method: 'POST' }) +} + +export function getActivityWinRecords(activity_id, page = 1, page_size = 20) { + return authRequest({ url: `/api/app/activities/${activity_id}/wins`, method: 'GET', data: { page, page_size } }) +} diff --git a/components/ElCard.vue b/components/ElCard.vue new file mode 100644 index 0000000..3ff944f --- /dev/null +++ b/components/ElCard.vue @@ -0,0 +1,30 @@ + + + + + diff --git a/components/FlipGrid.vue b/components/FlipGrid.vue new file mode 100644 index 0000000..816bd8e --- /dev/null +++ b/components/FlipGrid.vue @@ -0,0 +1,83 @@ + + + + + diff --git a/pages/activity/duiduipeng/index.vue b/pages/activity/duiduipeng/index.vue index 8ef9e2c..e44d131 100644 --- a/pages/activity/duiduipeng/index.vue +++ b/pages/activity/duiduipeng/index.vue @@ -5,46 +5,83 @@ {{ detail.name || detail.title || '-' }} - 分类:{{ detail.category_name || '对对碰' }} 参与价:¥{{ detail.price_draw }} - 状态:{{ statusText }} - - - - - + + 期数 - - {{ it.title || ('第' + (it.no || it.index || it.issue_no || '-') + '期') }} - {{ it.status_text }} - - - - - {{ rw.title }} - {{ [rw.rarity, rw.odds].filter(Boolean).join(' · ') }} + + + {{ it.title || ('第' + (it.no || it.index || it.issue_no || '-') + '期') }} + + + + + 本机奖池 + 中奖记录 + + + + + + + + + 概率 {{ rw.percent }}% - + 暂无奖励配置 + + + + + + + + 占比 {{ it.percent }}% + + + + 暂无中奖记录 + 暂无期数 + + + \ No newline at end of file + diff --git a/pages/activity/wuxianshang/index.vue b/pages/activity/wuxianshang/index.vue index 94b27e1..954b074 100644 --- a/pages/activity/wuxianshang/index.vue +++ b/pages/activity/wuxianshang/index.vue @@ -5,46 +5,57 @@ {{ detail.name || detail.title || '-' }} - 分类:{{ detail.category_name || '无限赏' }} 单次抽选:¥{{ detail.price_draw }} - 状态:{{ statusText }} - - - + + + + - - 期数 - - - {{ it.title || ('第' + (it.no || it.index || it.issue_no || '-') + '期') }} - {{ it.status_text }} - - - - - {{ rw.title }} - {{ [rw.rarity, rw.odds].filter(Boolean).join(' · ') }} - - - - 暂无奖励配置 - + + + + {{ currentIssueTitle }} + - 暂无期数 + + + + + + + + diff --git a/pages/activity/yifanshang/index.vue b/pages/activity/yifanshang/index.vue index 4ae43ca..8da00cd 100644 --- a/pages/activity/yifanshang/index.vue +++ b/pages/activity/yifanshang/index.vue @@ -5,45 +5,58 @@ {{ detail.name || detail.title || '-' }} - 分类:{{ detail.category_name || '一番赏' }} 抽选价:¥{{ detail.price_draw }} - 状态:{{ statusText }} - - - + + + + - - 期数 - - - {{ it.title || ('第' + (it.no || it.index || it.issue_no || '-') + '期') }} - {{ it.status_text }} - - - - - {{ rw.title }} - {{ [rw.rarity, rw.odds].filter(Boolean).join(' · ') }} - - - - 暂无奖励配置 - + + + + {{ currentIssueTitle }} + - 暂无期数 + + + + + + + + \ No newline at end of file + diff --git a/pages/agreement/purchase.vue b/pages/agreement/purchase.vue index 3cbf33a..d563371 100644 --- a/pages/agreement/purchase.vue +++ b/pages/agreement/purchase.vue @@ -2,8 +2,8 @@ 购买协议 生效日期:2025年11月18日 - 运营方:【公司全称】 - 本《购买协议》适用于您在【您的小程序名称】(以下简称“本平台”)购买盲盒商品的行为。当您点击“立即购买”并完成支付时,即视为您已阅读、理解并同意本协议全部内容。 + 运营方:柯大鸭潮玩 + 本《购买协议》适用于您在【柯大鸭潮玩】(以下简称“本平台”)购买盲盒商品的行为。当您点击“立即购买”并完成支付时,即视为您已阅读、理解并同意本协议全部内容。 一、商品说明 盲盒特性:本平台所售盲盒为系列化商品,包装外观一致,内部款式随机,具体款式无法提前指定或预知。 @@ -22,7 +22,7 @@ 四、售后服务 - 质量问题(如商品破损、漏发、错发、非盲盒系列商品):请在签收后2到4小时内联系客服并提供凭证(如开箱视频、照片);经核实后,平台将为您补发、换货或退款。 + 质量问题(如商品破损、漏发、错发、非盲盒系列商品):请在签收后2小时内联系客服并提供凭证(如开箱视频、照片);经核实后,平台将为您补发、换货或退款。 非质量问题(如抽中重复款式、不喜欢款式、未抽中隐藏款等):不支持无理由退换货。 拆封后商品:出于卫生与二次销售考虑,已拆封盲盒恕不退换(质量问题除外)。 @@ -45,10 +45,9 @@ 八、协议效力 本购买协议为《用户协议》的补充,两者冲突时,以本协议中关于交易的条款为准。未尽事宜,依照《消费者权益保护法》《电子商务法》等法律法规执行。 九、联系我们 - 售后专线:service@yourdomain.com - 工作时间:工作日 9:00–18:00 - 运营主体:【公司全称】 - 统一社会信用代码:【XXXXXXXXXXXXXX】 + 售后专线:请联系企业客服,客服将在工作时间内为您服务。 + 工作时间:工作日 13:00–04:00 + 运营主体:【柯大鸭潮玩】 理性消费提醒:盲盒是一种娱乐消费形式,请根据自身经济能力合理购买,切勿沉迷或过度投入。 diff --git a/pages/agreement/user.vue b/pages/agreement/user.vue index 849b27c..442090b 100644 --- a/pages/agreement/user.vue +++ b/pages/agreement/user.vue @@ -2,8 +2,8 @@ 用户协议 生效日期:2025年11月18日 - 运营方:【公司全称】 - 欢迎您使用【您的小程序名称】(以下简称“本平台”)提供的服务。请您在注册、登录或使用本平台前,认真阅读并充分理解本《用户协议》(以下简称“本协议”)。一旦您完成注册、登录或以任何方式使用本平台服务,即视为您已完全接受本协议全部条款。如您不同意,请勿使用本平台。 + 运营方:【柯大鸭潮玩】 + 欢迎您使用【柯大鸭潮玩】(以下简称“本平台”)提供的服务。请您在注册、登录或使用本平台前,认真阅读并充分理解本《用户协议》(以下简称“本协议”)。一旦您完成注册、登录或以任何方式使用本平台服务,即视为您已完全接受本协议全部条款。如您不同意,请勿使用本平台。 一、协议范围 本协议规范您作为用户在本平台注册、浏览、互动、参与活动等行为,是您与本平台之间的基本权利义务约定。 二、用户资格 @@ -44,10 +44,9 @@ 九、法律适用与争议解决 本协议适用中华人民共和国法律。因本协议引起的争议,双方应协商解决;协商不成的,提交本平台运营方所在地有管辖权的人民法院诉讼解决。 十、联系我们 - 客服邮箱:service@yourdomain.com - 客服电话:400-XXX-XXXX(工作日 9:00–18:00) - 运营主体:【公司全称】 - 地址:【公司注册地址】 + 客服邮箱:请通过企业客服联系我们,客服将在工作时间内为您服务。 + 工作时间:(工作日 13:00–04:00) + 运营主体:【柯大鸭潮玩】 温馨提示:盲盒具有随机性和娱乐性,请理性参与,避免沉迷。未成年人禁止参与购买。 diff --git a/pages/index/index.vue b/pages/index/index.vue index 0f825a6..bca5b27 100644 --- a/pages/index/index.vue +++ b/pages/index/index.vue @@ -21,15 +21,21 @@ 活动 - - - - @@ -43,7 +49,8 @@ export default { return { notices: [], banners: [], - activities: [] + activities: [], + selectedGroupName: '' } }, computed: { @@ -61,6 +68,22 @@ export default { { id: 'ph-2', title: '敬请期待', image: '' }, { id: 'ph-3', title: '更多活动请关注', image: '' } ] + }, + activityGroups() { + const list = Array.isArray(this.activities) ? this.activities : [] + const map = new Map() + list.forEach(a => { + const key = (a.category_name || '').trim() || '其他' + if (!map.has(key)) map.set(key, []) + map.get(key).push(a) + }) + return Array.from(map.entries()).map(([name, items]) => ({ name, items })) + }, + activeGroupItems() { + const groups = this.activityGroups + const name = this.selectedGroupName || (groups[0] && groups[0].name) || '' + const g = groups.find(x => x.name === name) + return g ? g.items : [] } }, onShow() { @@ -82,6 +105,16 @@ export default { this.loadHomeData() }, methods: { + onSelectGroup(name) { + this.selectedGroupName = String(name || '') + }, + updateSelectedGroup() { + const groups = this.activityGroups + if (!groups.length) { this.selectedGroupName = ''; return } + if (!groups.find(g => g.name === this.selectedGroupName)) { + this.selectedGroupName = groups[0].name + } + }, toArray(x) { return Array.isArray(x) ? x : [] }, unwrap(list) { if (Array.isArray(list)) return list @@ -126,7 +159,7 @@ export default { console.log('normalizeActivities input', list, 'unwrapped', arr) const mapped = arr.map((i, idx) => ({ id: i.id ?? String(idx), - image: this.cleanUrl(i.banner ?? i.coverUrl ?? i.cover_url ?? i.image ?? i.img ?? i.pic ?? ''), + image: this.cleanUrl(i.image ?? i.banner ?? i.coverUrl ?? i.cover_url ?? i.img ?? i.pic ?? ''), title: i.title ?? i.name ?? '', subtitle: this.buildActivitySubtitle(i), link: this.cleanUrl(i.linkUrl ?? i.link_url ?? i.link ?? i.url ?? ''), @@ -168,9 +201,11 @@ export default { if (acRes.status === 'fulfilled') { console.log('activities ok', acRes.value) this.activities = this.normalizeActivities(acRes.value) + this.updateSelectedGroup() } else { console.error('activities error', acRes.reason) this.activities = [] + this.updateSelectedGroup() } console.log('home normalized', { notices: this.notices, banners: this.banners, activities: this.activities }) }, @@ -216,6 +251,9 @@ export default { .banner-fallback-text { color: #666; font-size: 28rpx } .activity-section { background: #ffffff; border-radius: 12rpx; padding: 24rpx } .section-title { font-size: 30rpx; font-weight: 600; margin-bottom: 16rpx } +.tabs { white-space: nowrap; display: flex; gap: 12rpx; margin-bottom: 16rpx } +.tab { display: inline-flex; align-items: center; height: 56rpx; padding: 0 20rpx; border-radius: 999rpx; background: #f5f7fa; color: #555; font-size: 26rpx } +.tab.active { background: #007AFF; color: #fff } .activity-grid { display: flex; flex-wrap: wrap; margin: -12rpx } .activity-item { width: 50%; padding: 12rpx } .activity-thumb { width: 100%; height: 200rpx; border-radius: 8rpx } diff --git a/pages/shop/index.vue b/pages/shop/index.vue index 1d5477b..2e26794 100644 --- a/pages/shop/index.vue +++ b/pages/shop/index.vue @@ -1,5 +1,18 @@