增加广播栏

This commit is contained in:
tianmo committed 2026-09-30 16:47:27 +08:00
1 parent 85b0e70907
commit d8786eb28a
21 files changed
+516 -59

No files matched your search

+48 -5
View File
@@ -8,6 +8,22 @@ const updateManager = wx.getUpdateManager();
const PAGE_SIZE = 10;
/** 广播文字默认色(红),配置里没填或填得不像颜色时用它 */
const DEFAULT_BROADCAST_COLOR = '#e60012';
/**
* 只认安全的颜色写法,其余一律回退默认色。
* 后台是文本框,填错一个字符不该把首页样式搞坏,也不该让这个值变成注入点。
*/
function safeColor(value) {
const v = String(value || '').trim();
if (/^#[0-9a-fA-F]{3}$|^#[0-9a-fA-F]{6}$|^#[0-9a-fA-F]{8}$/.test(v)) return v;
if (/^rgba?\([\d\s.,%]+\)$/.test(v)) return v;
if (/^hsla?\([\d\s.,%]+\)$/.test(v)) return v;
if (/^[a-zA-Z]{3,20}$/.test(v)) return v; // red / orange / tomato ...
return DEFAULT_BROADCAST_COLOR;
}
Page({
data: {
staticBase: config.STATIC_BASE_URL,
@@ -23,6 +39,12 @@ Page({
title2: '',
title3: '',
footerText: '',
/** 首页信息广播文案,空则不显示整条 */
broadcast: '',
/** 文案超出宽度时才横向滚动 */
broadcastScroll: false,
/** 广播文字颜色,取自 home.broadcast_color */
broadcastColor: DEFAULT_BROADCAST_COLOR,
},
onLoad() {
@@ -32,11 +54,32 @@ Page({
},
applyConfig() {
this.setData({
title1: store.cfg('home.title.paid'),
title2: store.cfg('home.title.trial'),
title3: store.cfg('home.title.public'),
footerText: store.cfg('home.footer_text'),
this.setData(
{
title1: store.cfg('home.title.paid'),
title2: store.cfg('home.title.trial'),
title3: store.cfg('home.title.public'),
footerText: store.cfg('home.footer_text'),
broadcast: store.cfg('home.broadcast') || '',
broadcastColor: safeColor(store.cfg('home.broadcast_color')),
broadcastScroll: false,
},
// 等渲染完再量宽度:只有真放不下才让它滚动,短文案就静静居中
() => this.measureBroadcast(),
);
},
/** 量一下广播文字有没有超出容器,超了才加滚动动画。量不到就当不超。 */
measureBroadcast() {
if (!this.data.broadcast) return;
const query = wx.createSelectorQuery().in(this);
query.select('.broadcast-body').boundingClientRect();
query.select('.broadcast-text').boundingClientRect();
query.exec((res) => {
const box = res && res[0];
const text = res && res[1];
if (!box || !text) return;
if (text.width > box.width) this.setData({ broadcastScroll: true });
});
},
+12 -1
View File
@@ -1,6 +1,18 @@
<!--index.wxml-->
<scroll-view class="container" scroll-y enable-flex type="custom">
<!-- 信息广播:文案取自站点配置 home.broadcast,空则整条不显示。
文字放得下就静态居中,放不下就横向滚动(避免长通知被截断看不到)。 -->
<view class="broadcast" wx:if="{{broadcast}}">
<text class="broadcast-icon">📢</text>
<view class="broadcast-body">
<view class="broadcast-track {{broadcastScroll ? 'broadcast-scroll' : ''}}" style="color: {{broadcastColor}}">
<text class="broadcast-text">{{broadcast}}</text>
<text class="broadcast-text broadcast-clone" wx:if="{{broadcastScroll}}">{{broadcast}}</text>
</view>
</view>
</view>
<view class="banner">
<swiper class="bannerswiper" autoplay interval="20000" circular indicator-dots indicator-color="rgba(255, 255, 255, .3)" indicator-active-color="rgba(255, 255, 255, 1.0)" indicator-type="normal" duration="1000" easing-function="easeOutCubic">
<swiper-item wx:for="{{banners}}" wx:for-item="item" wx:key="id" class="bannerswiperitem">
@@ -57,4 +69,3 @@
</view>
</scroll-view>
+61
View File
@@ -147,3 +147,64 @@ page {
top: 0;
width: 370rpx;
}
/* ── 信息广播(首页最上方,文案为空则整条不渲染)─────────────────
文案放得下就静态居中;放不下加 .broadcast-scroll 横向滚动,
并把同一段文字渲染两遍首尾相接,滚动到 -50% 时正好接上,看不出循环接缝。 */
.broadcast {
display: flex;
align-items: center;
width: 710rpx;
margin: 12rpx auto 0;
padding: 14rpx 20rpx;
box-sizing: border-box;
background: #fff7e6;
border: 1rpx solid #ffe3a3;
border-radius: 12rpx;
}
.broadcast-icon {
flex: none;
margin-right: 12rpx;
font-size: 28rpx;
line-height: 1;
}
.broadcast-body {
flex: 1;
min-width: 0;
overflow: hidden;
}
/* 静态:居中显示,实在超了也留个省略号兜底 */
.broadcast-track {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
text-align: center;
font-size: 26rpx;
color: #e60012; /* 兜底色:真实颜色由 home.broadcast_color 以内联样式覆盖 */
}
/* 滚动:两段文字并排,整体左移 50% 后无缝重来 */
.broadcast-scroll {
display: inline-flex;
overflow: visible;
text-overflow: clip;
animation: broadcast-marquee 18s linear infinite;
}
/* 两段文字各带一个等宽右边距,整条宽度 = 2 ×(文字+间距),
所以左移 50% 正好是一段,循环无缝 */
.broadcast-text {
margin-right: 80rpx;
}
@keyframes broadcast-marquee {
from {
transform: translateX(0);
}
to {
transform: translateX(-50%);
}
}