first commit

This commit is contained in:
Blizzard
2026-03-05 09:08:21 +08:00
commit 0a61c4ddec
2189 changed files with 38610 additions and 0 deletions
+64
View File
@@ -0,0 +1,64 @@
/**
* 首次引导页 — 选择2个免费频道
*/
const app = getApp()
const mock = require('../../utils/mock')
Page({
data: {
domains: mock.DOMAINS,
selectedIds: [],
isValid: false,
statusBarHeight: 0
},
onLoad() {
this.setData({
statusBarHeight: app.globalData.statusBarHeight
})
},
/**
* 切换频道选中状态
*/
onToggle(e) {
const id = e.currentTarget.dataset.id
let selected = this.data.selectedIds.slice()
const idx = selected.indexOf(id)
if (idx > -1) {
// 取消选中
selected.splice(idx, 1)
} else {
// 选中(最多2个)
if (selected.length >= 2) {
wx.showToast({ title: '最多选择2个免费频道', icon: 'none' })
return
}
selected.push(id)
}
this.setData({
selectedIds: selected,
isValid: selected.length > 0 && selected.length <= 2
})
},
/**
* 确认选择
*/
onConfirm() {
if (!this.data.isValid) return
const self = this
this.data.selectedIds.forEach(function (id) {
app.subscribeToDomain(id)
})
wx.showToast({ title: '订阅成功!', icon: 'success' })
setTimeout(function () {
wx.switchTab({ url: '/pages/index/index' })
}, 800)
}
})
+6
View File
@@ -0,0 +1,6 @@
{
"usingComponents": {
"t-message": "tdesign-miniprogram/message/message"
},
"navigationStyle": "custom"
}
+50
View File
@@ -0,0 +1,50 @@
<!-- 首次引导页 —— 选择2个免费频道 -->
<view class="onboarding-page">
<!-- 顶部区域 -->
<view class="header" style="padding-top: {{statusBarHeight + 10}}px;">
<text class="header-title">选择感兴趣的频道</text>
<view class="header-sub">
<text class="sub-text">可免费选择 2 个</text>
<text class="sub-warn">选择后不可更换</text>
</view>
</view>
<!-- 频道网格 -->
<scroll-view scroll-y enhanced show-scrollbar="{{false}}" class="grid-scroll">
<view class="grid">
<view
wx:for="{{domains}}"
wx:key="id"
class="grid-item {{selectedIds.indexOf(item.id) > -1 ? 'selected' : ''}}"
bindtap="onToggle"
data-id="{{item.id}}"
>
<!-- 图标 -->
<view class="item-icon" style="background: {{item.bgColor}};">
<text class="icon-emoji">{{item.icon}}</text>
</view>
<!-- 名称 -->
<text class="item-name">{{item.name}}</text>
<text class="item-tag">{{item.tag}}</text>
<!-- 选中对勾 -->
<view class="check-mark" wx:if="{{selectedIds.indexOf(item.id) > -1}}">
<text class="check-icon">✓</text>
</view>
</view>
</view>
</scroll-view>
<!-- 底部确认按钮 -->
<view class="footer">
<button
class="confirm-btn {{isValid ? 'active' : 'disabled'}}"
bindtap="onConfirm"
disabled="{{!isValid}}"
>
确认选择 {{selectedIds.length > 0 ? '(' + selectedIds.length + '/2)' : ''}}
</button>
</view>
<t-message id="t-message" />
</view>
+170
View File
@@ -0,0 +1,170 @@
/* 首次引导页样式 */
.onboarding-page {
height: 100vh;
display: flex;
flex-direction: column;
background: #FFFFFF;
}
/* 顶部 */
.header {
padding: 24rpx 40rpx 24rpx;
position: sticky;
top: 0;
z-index: 10;
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(20px);
border-bottom: 1rpx solid #F5F5F5;
}
.header-title {
font-size: 44rpx;
font-weight: 700;
color: #333;
display: block;
}
.header-sub {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 16rpx;
}
.sub-text {
font-size: 26rpx;
color: #999;
}
.sub-warn {
font-size: 22rpx;
color: var(--color-primary);
}
/* 网格滚动 */
.grid-scroll {
flex: 1;
overflow-y: auto;
scrollbar-width: none;
-ms-overflow-style: none;
}
.grid-scroll::-webkit-scrollbar {
display: none;
width: 0 !important;
height: 0 !important;
}
.grid {
display: flex;
flex-wrap: wrap;
padding: 24rpx 20rpx 200rpx;
gap: 16rpx;
}
/* 网格项 */
.grid-item {
width: calc(33.33% - 12rpx);
box-sizing: border-box;
background: #F8F8F8;
border-radius: 32rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 28rpx 16rpx;
position: relative;
border: 4rpx solid transparent;
transition: all 0.3s ease;
}
.grid-item.selected {
border-color: var(--color-primary);
background: var(--color-primary-light);
box-shadow: 0 8rpx 24rpx rgba(255, 157, 66, 0.15);
transform: scale(1.02);
}
/* 图标 */
.item-icon {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 16rpx;
}
.icon-emoji {
font-size: 40rpx;
}
/* 文字 */
.item-name {
font-size: 24rpx;
font-weight: 700;
color: #333;
text-align: center;
line-height: 1.3;
margin-bottom: 6rpx;
}
.item-tag {
font-size: 18rpx;
color: #999;
text-align: center;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 100%;
}
/* 选中对勾 */
.check-mark {
position: absolute;
top: 12rpx;
right: 12rpx;
width: 40rpx;
height: 40rpx;
border-radius: 50%;
background: var(--color-primary);
display: flex;
align-items: center;
justify-content: center;
}
.check-icon {
font-size: 22rpx;
color: #FFF;
font-weight: 700;
}
/* 底部 */
.footer {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 24rpx 40rpx;
padding-bottom: calc(24rpx + env(safe-area-inset-bottom));
background: linear-gradient(to top, #FFFFFF, #FFFFFF, rgba(255,255,255,0));
}
.confirm-btn {
width: 100%;
height: 100rpx;
border-radius: 999rpx;
font-size: 32rpx;
font-weight: 600;
border: none;
display: flex;
align-items: center;
justify-content: center;
line-height: 1;
}
.confirm-btn.active {
background: var(--color-primary);
color: #FFF;
box-shadow: 0 12rpx 32rpx rgba(255, 157, 66, 0.3);
}
.confirm-btn.active:active {
transform: scale(0.97);
}
.confirm-btn.disabled {
background: #E5E5E5;
color: #BBB;
}
.confirm-btn::after {
border: none;
}