feat(mini): 节气详情排版优化 + 本地开发连线上数据
Publish Mini Program Dev Version / publish (push) Successful in 1m2s

- wiki 页节气详情排版:配图圆角阴影、涵义引言(米黄渐变+红竖条)、
  简介两端对齐、结构化字段列表(红点标签)分块展示
- wiki.js 提取 meaning 单独展示,extraList 排除避免重复
- request.js develop 环境指向线上(本地 8080 被占用且 localhost 受域名校验限制)
- project.config.json 关闭 urlCheck 便于本地开发连线上调试
This commit is contained in:
gouki
2026-08-13 23:37:12 +00:00
parent fec383f257
commit 5a5388234a
5 changed files with 75 additions and 16 deletions
+12 -1
View File
@@ -56,19 +56,29 @@ const EXTRA_LABELS = [
{ key: 'flower', name: '花信' } { key: 'flower', name: '花信' }
]; ];
// buildExtraList 把服务端 extra JSON 字符串解析为 [{name, value}] 展示列表(仅保留非空项,按定义顺序) // buildExtraList 把服务端 extra JSON 字符串解析为 [{name, value}] 展示列表(仅保留非空项,按定义顺序meaning 单独展示故排除
function buildExtraList(extraStr) { function buildExtraList(extraStr) {
if (!extraStr) return []; if (!extraStr) return [];
let obj = {}; let obj = {};
try { obj = JSON.parse(extraStr); } catch (e) { return []; } try { obj = JSON.parse(extraStr); } catch (e) { return []; }
const list = []; const list = [];
EXTRA_LABELS.forEach(f => { EXTRA_LABELS.forEach(f => {
if (f.key === 'meaning') return; // 涵义在引言区单独突出显示
const v = (obj[f.key] || '').trim(); const v = (obj[f.key] || '').trim();
if (v) list.push({ name: f.name, value: v }); if (v) list.push({ name: f.name, value: v });
}); });
return list; return list;
} }
// extractMeaning 从 extra JSON 中提取涵义(用于引言区突出显示)
function extractMeaning(extraStr) {
if (!extraStr) return '';
try {
const obj = JSON.parse(extraStr);
return (obj.meaning || '').trim();
} catch (e) { return ''; }
}
function buildEntries() { function buildEntries() {
const entries = []; const entries = [];
@@ -168,6 +178,7 @@ Page({
brief: s.brief, brief: s.brief,
content: s.content, content: s.content,
image: s.image || '', image: s.image || '',
meaning: extractMeaning(s.extra),
extraList: buildExtraList(s.extra), extraList: buildExtraList(s.extra),
open: false open: false
}; };
+12 -2
View File
@@ -25,15 +25,25 @@
<text class="badge badge-outline">{{item.catName}}</text> <text class="badge badge-outline">{{item.catName}}</text>
</view> </view>
<view class="text-sm text-muted mt-1" wx:if="{{!item.open}}">{{item.brief}}</view> <view class="text-sm text-muted mt-1" wx:if="{{!item.open}}">{{item.brief}}</view>
<view class="entry-detail mt-2" wx:if="{{item.open}}"> <view class="entry-detail" wx:if="{{item.open}}">
<!-- 配图(仅服务端条目有图时显示) --> <!-- 配图(仅服务端条目有图时显示) -->
<image wx:if="{{item.image}}" class="entry-image" src="{{item.image}}" mode="widthFix" lazy-load/> <image wx:if="{{item.image}}" class="entry-image" src="{{item.image}}" mode="widthFix" lazy-load/>
<!-- 涵义引言(节气有 meaning 时突出显示) -->
<view class="entry-meaning" wx:if="{{item.meaning}}">
<text class="meaning-text">{{item.meaning}}</text>
</view>
<!-- 详细简介 --> <!-- 详细简介 -->
<text class="text-base entry-content">{{item.content}}</text> <text class="text-base entry-content">{{item.content}}</text>
<!-- 结构化扩展字段(节气:物候/习俗/养生等) --> <!-- 结构化扩展字段(节气:物候/习俗/养生等) -->
<view class="extra-list" wx:if="{{item.extraList && item.extraList.length > 0}}"> <view class="extra-list" wx:if="{{item.extraList && item.extraList.length > 0}}">
<view class="extra-item" wx:for="{{item.extraList}}" wx:key="name" wx:for-item="field"> <view class="extra-item" wx:for="{{item.extraList}}" wx:key="name" wx:for-item="field">
<text class="extra-name">{{field.name}}</text> <view class="extra-name">
<text class="extra-dot"></text>
<text>{{field.name}}</text>
</view>
<text class="extra-value">{{field.value}}</text> <text class="extra-value">{{field.value}}</text>
</view> </view>
</view> </view>
+48 -10
View File
@@ -47,35 +47,59 @@
.entry-detail { .entry-detail {
border-top: 1rpx solid #F0E6DA; border-top: 1rpx solid #F0E6DA;
padding-top: 16rpx; margin-top: 16rpx;
line-height: 1.7; padding-top: 20rpx;
} }
/* 节气配图 */ /* 节气配图 */
.entry-image { .entry-image {
width: 100%; width: 100%;
border-radius: 12rpx; border-radius: 16rpx;
margin-bottom: 16rpx; margin-bottom: 20rpx;
background: #F5F0EA; background: #F5F0EA;
box-shadow: 0 4rpx 16rpx rgba(74, 64, 54, 0.08);
}
/* 涵义引言(突出显示) */
.entry-meaning {
position: relative;
background: linear-gradient(135deg, #FBF3EC 0%, #F7ECE2 100%);
border-left: 6rpx solid #C41E3A;
border-radius: 8rpx;
padding: 20rpx 24rpx;
margin-bottom: 20rpx;
}
.meaning-text {
font-size: 28rpx;
color: #8C6D4F;
line-height: 1.6;
font-weight: 500;
letter-spacing: 1rpx;
} }
/* 详细简介 */ /* 详细简介 */
.entry-content { .entry-content {
display: block; display: block;
color: #4A4036; color: #4A4036;
font-size: 28rpx;
line-height: 1.9;
text-align: justify;
letter-spacing: 0.5rpx;
} }
/* 结构化扩展字段列表 */ /* 结构化扩展字段列表 */
.extra-list { .extra-list {
margin-top: 16rpx; margin-top: 24rpx;
background: #FBF7F1; background: #FBF7F1;
border-radius: 12rpx; border-radius: 16rpx;
padding: 8rpx 20rpx; padding: 8rpx 24rpx;
} }
.extra-item { .extra-item {
display: flex; display: flex;
padding: 12rpx 0; align-items: flex-start;
padding: 16rpx 0;
border-bottom: 1rpx solid #F0E6DA; border-bottom: 1rpx solid #F0E6DA;
} }
@@ -85,17 +109,31 @@
.extra-name { .extra-name {
flex-shrink: 0; flex-shrink: 0;
width: 140rpx; width: 150rpx;
display: flex;
align-items: center;
font-size: 26rpx; font-size: 26rpx;
color: #A08B76; color: #A08B76;
font-weight: 500; font-weight: 500;
padding-top: 2rpx;
}
/* 标签前的小圆点装饰 */
.extra-dot {
display: inline-block;
width: 8rpx;
height: 8rpx;
border-radius: 50%;
background: #C41E3A;
margin-right: 12rpx;
flex-shrink: 0;
} }
.extra-value { .extra-value {
flex: 1; flex: 1;
font-size: 26rpx; font-size: 26rpx;
color: #4A4036; color: #4A4036;
line-height: 1.6; line-height: 1.7;
} }
.empty-tip { .empty-tip {
+1 -1
View File
@@ -7,7 +7,7 @@
"setting": { "setting": {
"bundle": false, "bundle": false,
"userConfirmedBundleSwitch": false, "userConfirmedBundleSwitch": false,
"urlCheck": true, "urlCheck": false,
"scopeDataCheck": false, "scopeDataCheck": false,
"coverView": true, "coverView": true,
"es6": true, "es6": true,
+2 -2
View File
@@ -1,9 +1,9 @@
// 网络请求封装 // 网络请求封装
// 按小程序运行环境自动切换后端地址: // 按小程序运行环境自动切换后端地址:
// - develop(开发者工具):本地开发服务 // - develop(开发者工具):连线上数据(本地 8080 被其他服务占用,且 localhost 受域名校验限制)
// - trial/release(体验版/正式版):生产域名(需在微信公众平台配置为 request 合法域名) // - trial/release(体验版/正式版):生产域名(需在微信公众平台配置为 request 合法域名)
const API_HOSTS = { const API_HOSTS = {
develop: 'http://localhost:8080', develop: 'https://lunar.neatcn.com',
trial: 'https://lunar.neatcn.com', trial: 'https://lunar.neatcn.com',
release: 'https://lunar.neatcn.com', release: 'https://lunar.neatcn.com',
}; };