feat:生产初版页面

This commit is contained in:
R524809
2026-03-26 17:33:04 +08:00
parent 3aaf340781
commit dc5e057cb3
63 changed files with 2940 additions and 543 deletions
+11
View File
@@ -0,0 +1,11 @@
{
"navigationBarTitleText": "涂鸦丫",
"navigationBarTextStyle": "black",
"navigationBarBackgroundColor": "#FEF6E7",
"backgroundColor": "#FEF6E7",
"enablePullDownRefresh": false,
"usingComponents": {
"worksheet-card": "/components/shared/worksheet-card/worksheet-card",
"category-tabs": "/components/shared/category-tabs/category-tabs"
}
}
+172
View File
@@ -0,0 +1,172 @@
/* 首页体验配色:主题 #FFD709 / 正文 #605B50 / 底 #FEF6E7 / 按钮字 #322E25 / 标签 #91F78E */
.home-page {
min-height: 100vh;
background: #fef6e7;
padding-bottom: 48rpx;
box-sizing: border-box;
color: #605b50;
}
.home-header {
background: #fef6e7;
padding: 24rpx 24rpx 20rpx;
}
.home-brand {
display: flex;
flex-direction: row;
align-items: center;
gap: 16rpx;
margin-bottom: 24rpx;
}
.home-brand__duck {
font-size: 48rpx;
line-height: 1;
}
.home-brand__name {
font-size: 36rpx;
font-weight: 700;
color: #322e25;
}
.home-search {
background: rgba(255, 255, 255, 0.72);
border-radius: 40rpx;
padding: 22rpx 32rpx;
border: 1rpx solid rgba(255, 215, 9, 0.35);
}
.home-search__placeholder {
font-size: 28rpx;
color: rgba(96, 91, 80, 0.55);
}
.home-body {
padding: 24rpx 24rpx 0;
}
.home-section {
margin-bottom: 40rpx;
}
.home-section--hot {
margin-bottom: 32rpx;
}
.home-section__title-row {
margin-bottom: 20rpx;
}
.home-section__title {
font-size: 32rpx;
font-weight: 700;
color: #605b50;
}
.home-section__head {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
margin-bottom: 20rpx;
}
.home-section__head-left {
display: flex;
flex-direction: row;
align-items: center;
gap: 12rpx;
}
.home-section__icon {
font-size: 36rpx;
line-height: 1;
}
.home-section__name {
font-size: 32rpx;
font-weight: 700;
color: #605b50;
}
.home-section__more {
font-size: 26rpx;
color: #322e25;
font-weight: 500;
}
.home-hot__scroll {
width: 100%;
white-space: nowrap;
}
.home-hot__row {
display: inline-flex;
flex-direction: row;
gap: 24rpx;
padding-bottom: 8rpx;
}
.home-hot__item {
display: inline-block;
width: 240rpx;
vertical-align: top;
}
.home-hot__card-wrap {
width: 240rpx;
padding: 4rpx;
border-radius: 28rpx;
box-sizing: border-box;
background: linear-gradient(145deg, rgba(255, 215, 9, 0.85), rgba(254, 246, 231, 0.95));
}
/* category-tabs:仅首页通过 apply-shared + .home-page 生效 */
.home-page .category-tabs {
background: #fef6e7;
}
.home-page .category-tabs__pill {
background: rgba(96, 91, 80, 0.08);
color: #605b50;
}
.home-page .category-tabs__pill--active {
background: #ffd709;
color: #322e25;
font-weight: 600;
}
/* worksheet-card:仅首页 */
.home-page .worksheet-card {
box-shadow: 0 8rpx 28rpx rgba(50, 46, 37, 0.08);
}
.home-page .worksheet-card__title {
color: #605b50;
}
.home-page .worksheet-card__preview-text {
color: #605b50;
}
.home-page .worksheet-card__tag--age,
.home-page .worksheet-card__tag--diff {
background: #91f78e;
color: #322e25;
}
.home-grid {
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 20rpx;
}
.home-grid__cell {
width: calc((100% - 40rpx) / 3);
box-sizing: border-box;
}
+88
View File
@@ -0,0 +1,88 @@
import { ALL_WORKSHEETS, getWorksheetsByCategory, getWorksheetPath } from '../../core/data/worksheets';
import { CATEGORIES } from '../../core/data/categories';
import { WorksheetType } from '../../core/models/worksheet';
const CATEGORY_TABS = [
{ id: 'all', name: '全部' },
...CATEGORIES.map((c) => ({ id: c.id, name: c.name })),
];
Page({
data: {
tabs: CATEGORY_TABS,
activeTab: 'all',
sections: [] as Array<{ title: string; icon: string; category: string; items: WorksheetType[] }>,
hotItems: [] as WorksheetType[],
filteredItems: null as WorksheetType[] | null,
},
onLoad() {
const sections = CATEGORIES.filter((cat) => {
const items = getWorksheetsByCategory(cat.id);
return items.length > 0;
}).map((cat) => ({
title: cat.name,
icon: cat.icon,
category: cat.id,
items: getWorksheetsByCategory(cat.id).slice(0, 3),
}));
const hotItems = ALL_WORKSHEETS.filter((w) => w.page).slice(0, 4);
this.setData({ sections, hotItems });
},
onTabChange(e: WechatMiniprogram.CustomEvent) {
const activeTab = e.detail.id;
if (activeTab === 'all') {
this.setData({ activeTab, filteredItems: null });
} else {
const filteredItems = getWorksheetsByCategory(activeTab);
this.setData({ activeTab, filteredItems });
}
},
onCardTap(e: WechatMiniprogram.TouchEvent) {
const id = e.currentTarget.dataset.id as string | undefined;
if (!id) return;
const item = ALL_WORKSHEETS.find((w) => w.id === id);
if (!item) return;
const path = getWorksheetPath(item);
if (path) {
wx.navigateTo({ url: path });
}
},
onHotCardTap(e: WechatMiniprogram.TouchEvent) {
const id = e.currentTarget.dataset.id as string | undefined;
if (!id) return;
const item = ALL_WORKSHEETS.find((w) => w.id === id);
if (!item) return;
const path = getWorksheetPath(item);
if (path) {
wx.navigateTo({ url: path });
}
},
onSeeMore(e: WechatMiniprogram.TouchEvent) {
const { category } = e.currentTarget.dataset;
wx.navigateTo({
url: `/pages/category/category?category=${category}`,
});
},
onShareAppMessage() {
return {
title: '涂鸦丫 - 快来生成宝宝的专属学习卡',
path: '/pages/home/home',
imageUrl: 'https://cdn.joeyone.cn/doodle/share-img/index-share-v2.png',
};
},
onShareTimeline() {
return {
title: '涂鸦丫 - 快来生成宝宝的专属学习卡',
query: '',
};
},
});
+105
View File
@@ -0,0 +1,105 @@
<wxs module="fmt">
function ageLabel(arr) {
if (!arr || arr.length < 2) {
return '';
}
return arr[0] + '-' + arr[1] + '岁';
}
module.exports.ageLabel = ageLabel;
</wxs>
<view class="home-page">
<view class="home-header">
<view class="home-brand">
<text class="home-brand__duck">🦆</text>
<text class="home-brand__name">涂鸦丫</text>
</view>
<view class="home-search">
<text class="home-search__placeholder">搜索练习单(即将上线)</text>
</view>
</view>
<category-tabs tabs="{{tabs}}" active-tab="{{activeTab}}" bind:change="onTabChange" />
<view class="home-body">
<block wx:if="{{activeTab != 'all'}}">
<view class="home-grid">
<view
wx:for="{{filteredItems}}"
wx:key="id"
class="home-grid__cell"
bindtap="onCardTap"
data-id="{{item.id}}"
>
<worksheet-card
title="{{item.title}}"
preview-bg="{{item.previewBg}}"
preview-text="{{item.previewText}}"
img="{{item.img}}"
age-range="{{fmt.ageLabel(item.ageRange)}}"
difficulty="{{item.difficulty}}"
/>
</view>
</view>
</block>
<block wx:else>
<view class="home-section home-section--hot">
<view class="home-section__title-row">
<text class="home-section__title">🔥 热门下载</text>
</view>
<scroll-view class="home-hot__scroll" scroll-x enable-flex>
<view class="home-hot__row">
<view
wx:for="{{hotItems}}"
wx:key="id"
class="home-hot__item"
bindtap="onHotCardTap"
data-id="{{item.id}}"
>
<view class="home-hot__card-wrap">
<worksheet-card
title="{{item.title}}"
preview-bg="{{item.previewBg}}"
preview-text="{{item.previewText}}"
img="{{item.img}}"
age-range="{{fmt.ageLabel(item.ageRange)}}"
difficulty="{{item.difficulty}}"
/>
</view>
</view>
</view>
</scroll-view>
</view>
<view wx:for="{{sections}}" wx:key="category" class="home-section">
<view class="home-section__head">
<view class="home-section__head-left">
<text class="home-section__icon">{{item.icon}}</text>
<text class="home-section__name">{{item.title}}</text>
</view>
<text class="home-section__more" bindtap="onSeeMore" data-category="{{item.category}}">更多</text>
</view>
<view class="home-grid">
<view
wx:for="{{item.items}}"
wx:for-item="w"
wx:key="id"
class="home-grid__cell"
bindtap="onCardTap"
data-id="{{w.id}}"
>
<worksheet-card
title="{{w.title}}"
preview-bg="{{w.previewBg}}"
preview-text="{{w.previewText}}"
img="{{w.img}}"
age-range="{{fmt.ageLabel(w.ageRange)}}"
difficulty="{{w.difficulty}}"
/>
</view>
</view>
</view>
</block>
</view>
</view>