feat: 优化UI
This commit is contained in:
+44
-70
@@ -12,9 +12,36 @@ const app = getApp()
|
||||
const api = require('../../utils/api')
|
||||
const util = require('../../utils/util')
|
||||
|
||||
/**
|
||||
* 模块级函数:根据时间段随机返回文案
|
||||
* 必须在 Page() 外定义,才能在 data 初始化时同步调用,避免闪烁
|
||||
*/
|
||||
function _computeGreeting() {
|
||||
const hour = new Date().getHours()
|
||||
var pool
|
||||
if (hour >= 5 && hour < 9) {
|
||||
pool = ['新的一天,从声音开始', '早起的人,先听一段', '清晨的第一居声,属于你', '晚起不如早起,早起不如听起']
|
||||
} else if (hour >= 9 && hour < 12) {
|
||||
pool = ['上午充能量,声音加持', '专注工作,也别忘了呼吸', '高效早上,入耳知识', '好状态,从一段内容开始']
|
||||
} else if (hour >= 12 && hour < 14) {
|
||||
pool = ['午后小憩,听点轻松的', '借耳机隔绝喖鼺,中午也有自己的时间', '饭后十分钟,充电一下', '慢下来,下午还长']
|
||||
} else if (hour >= 14 && hour < 17) {
|
||||
pool = ['下午了,来点声音撤个困', '下午三点,刚好开始听一段', '下午的阳光和一段好内容', '止止广告,呜口内容']
|
||||
} else if (hour >= 17 && hour < 19) {
|
||||
pool = ['日落时分,放慢脚步', '下班了,耳机里换一个频道', '偶尔不刷短视频,试试听点实的', '归途中最适合听一段']
|
||||
} else if (hour >= 19 && hour < 22) {
|
||||
pool = ['夜晚温柔,适合倾听', '夜晚的声音,不用起时间', '放下手机,喂口内容', '夹着夜色,听一段值得的']
|
||||
} else {
|
||||
pool = ['夜深了,听点帮助入眠的', '出发前最后一段,晚安', '夜深的小时光,留给自己', '好梦将至,晚安']
|
||||
}
|
||||
return pool[Math.floor(Math.random() * pool.length)]
|
||||
}
|
||||
|
||||
Page({
|
||||
data: {
|
||||
greetingSub: '',
|
||||
// 同步计算,第一帧就正确,避免闪烁
|
||||
greetingSub: _computeGreeting(),
|
||||
statusBarHeight: app.globalData.statusBarHeight || 0,
|
||||
locationName: '',
|
||||
weather: null,
|
||||
dateDisplay: '',
|
||||
@@ -23,7 +50,6 @@ Page({
|
||||
freeChannels: [],
|
||||
isPlaying: false,
|
||||
isVip: false,
|
||||
statusBarHeight: 0,
|
||||
loadingSub: true,
|
||||
loadingFree: true
|
||||
},
|
||||
@@ -33,13 +59,13 @@ Page({
|
||||
onShow() {
|
||||
const gd = app.globalData
|
||||
this.setData({
|
||||
greetingSub: this._getGreeting(),
|
||||
greetingSub: _computeGreeting(), // 每次进页随机刷新文案
|
||||
dateDisplay: util.getDateDisplay(),
|
||||
weekDay: util.getWeekDay(),
|
||||
locationName: gd.locationName || '',
|
||||
weather: gd.weather || null,
|
||||
isVip: gd.isVip || false,
|
||||
statusBarHeight: gd.statusBarHeight || 0
|
||||
isVip: gd.isVip || false
|
||||
// statusBarHeight 小程序运行期间不会变化,无需重设
|
||||
})
|
||||
this._loadAll()
|
||||
this._bindEvents()
|
||||
@@ -96,18 +122,24 @@ Page({
|
||||
},
|
||||
|
||||
/**
|
||||
* 拉取免费频道列表
|
||||
* 首次无数据时显示骨架屏,后续静默刷新
|
||||
* 拉取频道列表(Section 2)
|
||||
* VIP 用户:全部频道;普通用户:仅免费频道
|
||||
*/
|
||||
_loadFreeChannels() {
|
||||
const self = this
|
||||
const gd = app.globalData
|
||||
const isFirstLoad = self.data.freeChannels.length === 0
|
||||
|
||||
if (isFirstLoad) {
|
||||
self.setData({ loadingFree: true })
|
||||
}
|
||||
|
||||
api.getFreeChannelList({ current: 1, pageSize: 20 })
|
||||
// VIP 用户加载全量频道,普通用户仅免费频道
|
||||
var apiCall = gd.isVip
|
||||
? api.getChannelList({ current: 1, pageSize: 50 })
|
||||
: api.getFreeChannelList({ current: 1, pageSize: 20 })
|
||||
|
||||
apiCall
|
||||
.then(function (res) {
|
||||
if (res.code !== 200 || !res.data) {
|
||||
self.setData({ freeChannels: [], loadingFree: false })
|
||||
@@ -115,23 +147,21 @@ Page({
|
||||
}
|
||||
|
||||
const list = res.data.list || []
|
||||
|
||||
const freeChannels = list.map(function (ch) {
|
||||
return {
|
||||
id: ch.id,
|
||||
name: ch.name || '未命名',
|
||||
// cover 直接是 emoji 字符串
|
||||
cover: ch.cover || '📻',
|
||||
bgColor: self._genColor(ch.id),
|
||||
programCount: (ch.Programs || ch.programs || []).length,
|
||||
isFree: ch.isFree
|
||||
isFree: ch.isFree,
|
||||
isVipOnly: ch.isVipOnly
|
||||
}
|
||||
})
|
||||
|
||||
self.setData({ freeChannels: freeChannels, loadingFree: false })
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.error('[首页] 免费频道失败', err)
|
||||
console.error('[首页] 频道加载失败', err)
|
||||
self.setData({ loadingFree: false })
|
||||
})
|
||||
},
|
||||
@@ -261,61 +291,5 @@ Page({
|
||||
},
|
||||
|
||||
// ===================== 工具方法 =====================
|
||||
|
||||
/** 根据时间段返回问候语 */
|
||||
_getGreeting() {
|
||||
const hour = new Date().getHours()
|
||||
var pool
|
||||
if (hour >= 5 && hour < 9) {
|
||||
pool = [
|
||||
'新的一天,从声音开始',
|
||||
'早起的人,先听一段',
|
||||
'清晨的第一居声,属于你',
|
||||
'晚起不如早起,早起不如听起'
|
||||
]
|
||||
} else if (hour >= 9 && hour < 12) {
|
||||
pool = [
|
||||
'上午充能量,声音加持',
|
||||
'专注工作,也别忘了呼吸',
|
||||
'高效早上,入耳知识',
|
||||
'好状态,从一段内容开始'
|
||||
]
|
||||
} else if (hour >= 12 && hour < 14) {
|
||||
pool = [
|
||||
'午后小憩,听点轻松的',
|
||||
'借耳机隔绝喧嚣,中午也有自己的时间',
|
||||
'饭后十分钟,充电一下',
|
||||
'慢下来,下午还长'
|
||||
]
|
||||
} else if (hour >= 14 && hour < 17) {
|
||||
pool = [
|
||||
'下午了,来点声音撤个困',
|
||||
'下午三点,刚好开始听一段',
|
||||
'下午的阳光和一段好内容',
|
||||
'止止广告,喝口内容'
|
||||
]
|
||||
} else if (hour >= 17 && hour < 19) {
|
||||
pool = [
|
||||
'日落时分,放慢脚步',
|
||||
'下班了,耳机里换一个频道',
|
||||
'偶尔不刷短视频,试试听点实的',
|
||||
'归途中最适合听一段'
|
||||
]
|
||||
} else if (hour >= 19 && hour < 22) {
|
||||
pool = [
|
||||
'夜晚温柔,适合倾听',
|
||||
'夜晚的声音,不用赶时间',
|
||||
'放下手机,喂口内容',
|
||||
'夹着夜色,听一段值得的'
|
||||
]
|
||||
} else {
|
||||
pool = [
|
||||
'夜深了,听点帮助入眠的',
|
||||
'出发前最后一段,晚安',
|
||||
'夜奥的小时光,留给自己',
|
||||
'好梦将至,晚安'
|
||||
]
|
||||
}
|
||||
return pool[Math.floor(Math.random() * pool.length)]
|
||||
}
|
||||
// _computeGreeting 已提至模块级,可在 data 初始化时直接调用
|
||||
})
|
||||
|
||||
+16
-3
@@ -41,6 +41,16 @@
|
||||
>
|
||||
<view class="content-area">
|
||||
|
||||
<!-- VIP 状态卡片(仅 VIP 用户显示) -->
|
||||
<view wx:if="{{isVip}}" class="vip-home-card tap-active" bindtap="goVip">
|
||||
<text class="vip-home-icon">👑</text>
|
||||
<view class="vip-home-body">
|
||||
<text class="vip-home-title">全部频道会员</text>
|
||||
<text class="vip-home-desc">所有频道面向你全量开放 · 畅听无限制</text>
|
||||
</view>
|
||||
<text class="vip-home-tag">享看权益 ›</text>
|
||||
</view>
|
||||
|
||||
<!-- ─── Section 1: 我的订阅 ─── -->
|
||||
<view class="section-header">
|
||||
<view class="section-title-wrap">
|
||||
@@ -152,8 +162,8 @@
|
||||
<view class="section-header section-header-free">
|
||||
<view class="section-title-wrap">
|
||||
<text class="section-dot dot-free"></text>
|
||||
<text class="section-title">免费频道</text>
|
||||
<text class="section-subtitle">无需订阅,随时收听</text>
|
||||
<text class="section-title">{{isVip ? '全部频道' : '免费频道'}}</text>
|
||||
<text class="section-subtitle">{{isVip ? '会员全开放,点即收听' : '无需订阅,随时收听'}}</text>
|
||||
</view>
|
||||
<view class="section-action tap-active" bindtap="goDiscover">
|
||||
<text class="section-action-text">全部</text>
|
||||
@@ -191,7 +201,10 @@
|
||||
<text class="free-emoji">{{item.cover || '📻'}}</text>
|
||||
</view>
|
||||
<text class="free-name">{{item.name}}</text>
|
||||
<t-tag size="small" variant="light-outline" theme="success">免费</t-tag>
|
||||
<!-- VIP 用户显示频道类型,普通用户只显免费帘记 -->
|
||||
<t-tag wx:if="{{item.isVipOnly}}" size="small" variant="light" theme="warning">👑</t-tag>
|
||||
<t-tag wx:elif="{{item.isFree !== 1}}" size="small" variant="light" theme="default">付费</t-tag>
|
||||
<t-tag wx:else size="small" variant="light-outline" theme="success">免费</t-tag>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
@@ -118,6 +118,39 @@
|
||||
.content-area {
|
||||
padding: 24rpx 32rpx 0;
|
||||
}
|
||||
/* ========== VIP 首页状态卡 ========== */
|
||||
.vip-home-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20rpx;
|
||||
background: linear-gradient(135deg, #FFF8EE, #FFF3DC);
|
||||
border: 1rpx solid #FFDFA0;
|
||||
border-radius: 24rpx;
|
||||
padding: 24rpx 28rpx;
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
.vip-home-icon { font-size: 44rpx; }
|
||||
.vip-home-body {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4rpx;
|
||||
}
|
||||
.vip-home-title {
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
color: #B07000;
|
||||
font-family: 'PingFang SC', sans-serif;
|
||||
}
|
||||
.vip-home-desc {
|
||||
font-size: 22rpx;
|
||||
color: #C09040;
|
||||
}
|
||||
.vip-home-tag {
|
||||
font-size: 22rpx;
|
||||
font-weight: 600;
|
||||
color: #FF9D42;
|
||||
}
|
||||
|
||||
|
||||
/* ========== Section Header ========== */
|
||||
|
||||
Reference in New Issue
Block a user