feat: 分类页骨架屏优化
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
import type { DebugPublishMeta } from '../../utils/debugPublish';
|
||||
import { inferGradeFromAge } from '../../utils/debugPublish';
|
||||
import type { TemplateType } from '../../service/drawServiceFactory';
|
||||
|
||||
/** 本地 worksheet 元数据(与云库 `worksheets` 文档 `_id` 对齐) */
|
||||
interface WordColoringWorksheetDefinition {
|
||||
id: string;
|
||||
templateType: TemplateType;
|
||||
icon: string;
|
||||
title: string;
|
||||
subtitle: string;
|
||||
ageMin: number;
|
||||
ageMax: number;
|
||||
difficulty: 1 | 2 | 3 | 4;
|
||||
tags: string[];
|
||||
sortOrder: number;
|
||||
}
|
||||
|
||||
export const WORD_COLORING_WORKSHEET_DEFINITIONS = [
|
||||
{
|
||||
id: 'word-coloring-grid',
|
||||
templateType: 'grid' as TemplateType,
|
||||
icon: 'grid',
|
||||
title: '网格涂色',
|
||||
subtitle: '田字格涂色识字练习',
|
||||
ageMin: 3,
|
||||
ageMax: 6,
|
||||
difficulty: 1,
|
||||
tags: ['识字', '涂色', '田字格'],
|
||||
sortOrder: 30,
|
||||
},
|
||||
{
|
||||
id: 'word-coloring-find',
|
||||
templateType: 'find' as TemplateType,
|
||||
icon: 'search',
|
||||
title: '找字涂色',
|
||||
subtitle: '在字海中找到目标字并涂色',
|
||||
ageMin: 4,
|
||||
ageMax: 7,
|
||||
difficulty: 2,
|
||||
tags: ['识字', '涂色', '找字'],
|
||||
sortOrder: 31,
|
||||
},
|
||||
] as const satisfies ReadonlyArray<WordColoringWorksheetDefinition>;
|
||||
|
||||
type WordColoringWorksheetRow =
|
||||
(typeof WORD_COLORING_WORKSHEET_DEFINITIONS)[number];
|
||||
|
||||
const WORD_COLORING_WORKSHEET_BY_ID = Object.fromEntries(
|
||||
WORD_COLORING_WORKSHEET_DEFINITIONS.map((m) => [m.id, m]),
|
||||
) as Record<string, WordColoringWorksheetRow>;
|
||||
|
||||
/** 页面渲染用:模式选择器列表 */
|
||||
export const WORD_COLORING_MODE_OPTIONS = WORD_COLORING_WORKSHEET_DEFINITIONS;
|
||||
|
||||
/** 页面 pageInfoLookup 用 */
|
||||
export function getModeInfo(id: string) {
|
||||
const m = WORD_COLORING_WORKSHEET_BY_ID[id];
|
||||
return m ? { title: m.title, desc: m.subtitle } : undefined;
|
||||
}
|
||||
|
||||
/** 判断 id 是否有效 */
|
||||
export function isValidMode(id: string): boolean {
|
||||
return id in WORD_COLORING_WORKSHEET_BY_ID;
|
||||
}
|
||||
|
||||
/** 根据 id 获取 templateType */
|
||||
export function getTemplateType(id: string): TemplateType {
|
||||
const m = WORD_COLORING_WORKSHEET_BY_ID[id];
|
||||
return m?.templateType || 'grid';
|
||||
}
|
||||
|
||||
/** 发布用:从当前 mode 生成 DebugPublishMeta */
|
||||
export function getPublishMetaByMode(id: string): DebugPublishMeta | null {
|
||||
const m = WORD_COLORING_WORKSHEET_BY_ID[id];
|
||||
if (!m) return null;
|
||||
return {
|
||||
id: m.id,
|
||||
title: m.title,
|
||||
subtitle: m.subtitle,
|
||||
category: 'chinese',
|
||||
subcategory: 'word-coloring',
|
||||
path: `/chinesePages/wordColoring/wordColoring?id=${m.id}`,
|
||||
ageMin: m.ageMin,
|
||||
ageMax: m.ageMax,
|
||||
grade: inferGradeFromAge(m.ageMin, m.ageMax),
|
||||
difficulty: m.difficulty,
|
||||
previewImg: '',
|
||||
tags: [...m.tags],
|
||||
isNew: false,
|
||||
isHot: false,
|
||||
sortOrder: m.sortOrder,
|
||||
status: 'draft',
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "涂色识字",
|
||||
"navigationBarBackgroundColor": "#F8F0E0",
|
||||
"navigationBarTextStyle": "black",
|
||||
"backgroundColor": "#FEF6E7",
|
||||
"enablePullDownRefresh": false,
|
||||
"usingComponents": {
|
||||
"nav-bar": "../../components3.0/nav-bar/nav-bar",
|
||||
"preview-card": "../../components3.0/preview-card/preview-card",
|
||||
"preview-footer-actions": "../../components3.0/preview-footer-actions/preview-footer-actions",
|
||||
"debug-publish-tools": "../../components3.0/debug-publish-tools/debug-publish-tools",
|
||||
"share-guide-popup": "../../components/share-guide-popup/share-guide-popup",
|
||||
"draw-ad": "../../components/draw-ad/draw-ad",
|
||||
"toy-icon": "../../toy/icon/icon",
|
||||
"toy-button": "../../toy/button-v2/button",
|
||||
"word-input": "../../components/word-input/word-input",
|
||||
"word-card": "../../components/word-card/word-card",
|
||||
"color-picker": "../../components/color-picker/color-picker",
|
||||
"word-picker": "../../components/word-picker/word-picker",
|
||||
"empty-state": "../../components/empty-state/empty-state"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
@import '../../style/theme.less';
|
||||
|
||||
.wc-page {
|
||||
min-height: 100vh;
|
||||
background: @bg-page;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.wc-main {
|
||||
padding: @page-padding-x;
|
||||
padding-bottom: calc(120rpx + env(safe-area-inset-bottom));
|
||||
}
|
||||
|
||||
.wc-section {
|
||||
margin-top: @section-gap-sm;
|
||||
}
|
||||
|
||||
.wc-section-title {
|
||||
display: block;
|
||||
font-size: 26rpx;
|
||||
font-weight: 700;
|
||||
color: @text-secondary;
|
||||
letter-spacing: 0.04em;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
/* 输入行 */
|
||||
.wc-input-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
/* 文字卡片网格 */
|
||||
.wc-card-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 24rpx;
|
||||
}
|
||||
|
||||
/* 操作按钮行 */
|
||||
.wc-action-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
/* 空状态 */
|
||||
.wc-empty {
|
||||
padding: 48rpx 0;
|
||||
}
|
||||
|
||||
/* 模板选择网格(2列) */
|
||||
.wc-mode-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.wc-mode-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 12rpx;
|
||||
padding: 32rpx 16rpx;
|
||||
border-radius: @radius-lg;
|
||||
background: @bg-header;
|
||||
box-shadow: @shadow;
|
||||
transition: transform 0.12s, box-shadow 0.12s;
|
||||
}
|
||||
|
||||
.wc-mode-card--active {
|
||||
background: @brand;
|
||||
box-shadow: @shadow, 0 0 0 4rpx fade(@brand, 30%);
|
||||
}
|
||||
|
||||
.wc-mode-card--pressed {
|
||||
transform: scale(0.96);
|
||||
}
|
||||
|
||||
.wc-mode-card__icon {
|
||||
margin-bottom: 4rpx;
|
||||
}
|
||||
|
||||
.wc-mode-card__label {
|
||||
font-size: 26rpx;
|
||||
font-weight: 700;
|
||||
color: @text-title;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.wc-mode-card--active .wc-mode-card__label {
|
||||
color: @text-selected-btn;
|
||||
}
|
||||
|
||||
.wc-mode-card__sub {
|
||||
font-size: 20rpx;
|
||||
color: @text-secondary;
|
||||
text-align: center;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.wc-mode-card--active .wc-mode-card__sub {
|
||||
color: fade(@text-selected-btn, 75%);
|
||||
}
|
||||
@@ -0,0 +1,312 @@
|
||||
import { WATER_COLORS } from '../../constants/colors';
|
||||
import { WORDS } from '../../constants/words';
|
||||
import { DrawServiceFactory, type IDrawService } from '../../service/drawServiceFactory';
|
||||
import { createPage, type CanvasDataState } from '../../base/pageMixin';
|
||||
import { defaultShareConfig } from '../../config/config';
|
||||
import {
|
||||
getModeInfo,
|
||||
getPublishMetaByMode,
|
||||
getTemplateType,
|
||||
isValidMode,
|
||||
WORD_COLORING_MODE_OPTIONS,
|
||||
WORD_COLORING_WORKSHEET_DEFINITIONS,
|
||||
} from './wordColoring.config';
|
||||
import type { DebugPublishMeta } from '../../utils/debugPublish';
|
||||
import { addFavorite, removeFavorite, batchCheckFavorited } from '../../utils/favorites';
|
||||
|
||||
type CardItem = { color: string; word: string };
|
||||
|
||||
const COLOR_MAP: Record<string, string> = {
|
||||
红: '#FF0000', 蓝: '#0000FF', 绿: '#00FF00', 黄: '#FFFF00',
|
||||
黑: '#000000', 白: '#FFFFFF', 紫: '#800080', 橙: '#FF7F00',
|
||||
粉: '#FF69B4', 棕: '#A52A2A', 灰: '#808080',
|
||||
};
|
||||
|
||||
const pageInfoLookup = getModeInfo;
|
||||
|
||||
// PLACEHOLDER_TS_PART2
|
||||
|
||||
type PageData = CanvasDataState & {
|
||||
worksheetId: string;
|
||||
cardList: CardItem[];
|
||||
selectedWords: string[];
|
||||
showColorPopup: boolean;
|
||||
currentKey: number;
|
||||
currentColor: string;
|
||||
showSelectWordPopup: boolean;
|
||||
modeOptions: typeof WORD_COLORING_MODE_OPTIONS;
|
||||
isPreviewFavorite: boolean;
|
||||
isDevEnv: boolean;
|
||||
debugPublishVisible: boolean;
|
||||
debugPublishLoading: boolean;
|
||||
debugPublishMeta: DebugPublishMeta | null;
|
||||
};
|
||||
|
||||
createPage(
|
||||
{
|
||||
canvas: null as Canvas | null,
|
||||
ctx: null as RenderingContext | null,
|
||||
boxHeight: 0,
|
||||
boxWidth: 0,
|
||||
drawService: null as IDrawService | null,
|
||||
_favoritedMap: {} as Record<string, boolean>,
|
||||
|
||||
data: {
|
||||
pageTitle: '涂色识字',
|
||||
functionId: '',
|
||||
hasContent: false,
|
||||
showShareDialog: false,
|
||||
worksheetId: 'word-coloring-grid',
|
||||
cardList: [] as CardItem[],
|
||||
selectedWords: [] as string[],
|
||||
showColorPopup: false,
|
||||
currentKey: 0,
|
||||
currentColor: '',
|
||||
showSelectWordPopup: false,
|
||||
modeOptions: WORD_COLORING_MODE_OPTIONS,
|
||||
isPreviewFavorite: false,
|
||||
isDevEnv: false,
|
||||
debugPublishVisible: false,
|
||||
debugPublishLoading: false,
|
||||
debugPublishMeta: null,
|
||||
} as unknown as PageData,
|
||||
|
||||
onLoad(options: { id?: string }) {
|
||||
const worksheetId =
|
||||
options.id && isValidMode(options.id)
|
||||
? options.id
|
||||
: 'word-coloring-grid';
|
||||
|
||||
this.syncDebugPublishEnv();
|
||||
this.setData({
|
||||
worksheetId,
|
||||
functionId: worksheetId,
|
||||
});
|
||||
this.initPageInfo(worksheetId, '涂色识字');
|
||||
this.loadFavoritedMap();
|
||||
},
|
||||
|
||||
onCanvasReady(e: WechatMiniprogram.CustomEvent) {
|
||||
const worksheetId = this.data.worksheetId;
|
||||
const templateType = getTemplateType(worksheetId);
|
||||
|
||||
this.initCanvasFromComponent(e.detail, {
|
||||
createDrawService: (
|
||||
canvas: Canvas,
|
||||
ctx: RenderingContext,
|
||||
options?: Record<string, any>,
|
||||
) => DrawServiceFactory.create(templateType, canvas, ctx, options),
|
||||
drawServiceOptions: {
|
||||
title: this.data.pageTitle,
|
||||
},
|
||||
onCanvasReady: () => {
|
||||
if (this.data.cardList.length > 0) {
|
||||
this.drawCanvas();
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
// PLACEHOLDER_TS_PART3
|
||||
|
||||
/** 执行 Canvas 绘制 */
|
||||
async drawCanvas() {
|
||||
if (!this.drawService) return;
|
||||
const cardList = this.data.cardList;
|
||||
if (cardList.length === 0) {
|
||||
this.setData({ hasContent: false });
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await this.drawService.draw(cardList);
|
||||
this.setData({ hasContent: true });
|
||||
} catch (e) {
|
||||
console.error('绘制失败:', e);
|
||||
this.setData({ hasContent: false });
|
||||
}
|
||||
},
|
||||
|
||||
/** 切换模板类型 */
|
||||
onSelectMode(e: WechatMiniprogram.TouchEvent) {
|
||||
const id = e.currentTarget.dataset.id as string;
|
||||
if (!id || id === this.data.worksheetId || !isValidMode(id)) return;
|
||||
|
||||
const templateType = getTemplateType(id);
|
||||
this.setData({
|
||||
worksheetId: id,
|
||||
functionId: id,
|
||||
isPreviewFavorite: !!this._favoritedMap[id],
|
||||
});
|
||||
this.initPageInfo(id, '涂色识字');
|
||||
|
||||
if (this.canvas && this.ctx) {
|
||||
this.drawService = DrawServiceFactory.create(
|
||||
templateType,
|
||||
this.canvas,
|
||||
this.ctx,
|
||||
{ title: this.data.pageTitle },
|
||||
);
|
||||
if (this.data.cardList.length > 0) {
|
||||
this.drawCanvas();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/** preview-card 换一批 */
|
||||
onPreviewRefresh() {
|
||||
this.refreshCardList();
|
||||
},
|
||||
|
||||
/** 随机生成文字卡片 */
|
||||
refreshCardList() {
|
||||
const allWords = WORDS.slice(0, 2).reduce(
|
||||
(acc, cat) => acc.concat(cat.words),
|
||||
[] as string[],
|
||||
);
|
||||
const selected: string[] = [];
|
||||
while (selected.length < 6 && allWords.length > 0) {
|
||||
const idx = Math.floor(Math.random() * allWords.length);
|
||||
const w = allWords[idx];
|
||||
if (!selected.includes(w)) selected.push(w);
|
||||
}
|
||||
const colors = [...WATER_COLORS.basic12].sort(() => Math.random() - 0.5);
|
||||
const cardList = selected.map((word, i) => ({
|
||||
word,
|
||||
color: COLOR_MAP[word] || colors[i % colors.length].hex,
|
||||
}));
|
||||
this.setData({ cardList, selectedWords: selected }, () => {
|
||||
this.drawCanvas();
|
||||
});
|
||||
},
|
||||
|
||||
/** 清空文字卡片 */
|
||||
clearCardList() {
|
||||
this.setData({ cardList: [], selectedWords: [], hasContent: false });
|
||||
},
|
||||
|
||||
// PLACEHOLDER_TS_PART4
|
||||
|
||||
/** 输入确认:添加文字卡片 */
|
||||
onConfirmInput(e: WechatMiniprogram.Input) {
|
||||
const { cardList } = this.data;
|
||||
const { value } = e.detail;
|
||||
const characters = value.split('');
|
||||
const remainingSlots = 6 - cardList.length;
|
||||
if (remainingSlots <= 0) {
|
||||
wx.showToast({ title: '最多只能添加6个字哦', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
|
||||
const usedColors = cardList.map((item) => item.color);
|
||||
const usedWords = cardList.map((item) => item.word);
|
||||
const allColors = WATER_COLORS.basic12.map((c) => c.hex);
|
||||
const available = allColors.filter((c) => !usedColors.includes(c));
|
||||
const shuffled = [...available].sort(() => Math.random() - 0.5);
|
||||
|
||||
const newChars: string[] = [];
|
||||
for (const char of characters) {
|
||||
if (newChars.length >= remainingSlots) break;
|
||||
if (!usedWords.includes(char) && !newChars.includes(char)) {
|
||||
newChars.push(char);
|
||||
}
|
||||
}
|
||||
|
||||
const newCards = newChars.map((char, i) => {
|
||||
const mapped = COLOR_MAP[char];
|
||||
const color =
|
||||
mapped && !usedColors.includes(mapped)
|
||||
? mapped
|
||||
: shuffled[i % shuffled.length];
|
||||
return { word: char, color };
|
||||
});
|
||||
|
||||
const updated = [...cardList, ...newCards];
|
||||
this.setData(
|
||||
{ cardList: updated, selectedWords: updated.map((c) => c.word) },
|
||||
() => this.drawCanvas(),
|
||||
);
|
||||
},
|
||||
|
||||
/** 删除单个文字卡片 */
|
||||
deleteWordCard(e: WechatMiniprogram.CustomEvent) {
|
||||
const { key } = e.detail;
|
||||
const updated = this.data.cardList.filter((_, i) => i !== key);
|
||||
this.setData(
|
||||
{ cardList: updated, selectedWords: updated.map((c) => c.word) },
|
||||
() => this.drawCanvas(),
|
||||
);
|
||||
},
|
||||
|
||||
/** 颜色选择相关 */
|
||||
onColorTap(e: WechatMiniprogram.CustomEvent) {
|
||||
const { key, color } = e.detail;
|
||||
this.setData({ showColorPopup: true, currentKey: key, currentColor: color });
|
||||
},
|
||||
|
||||
onCloseColorPopup() {
|
||||
this.setData({ showColorPopup: false, currentKey: 0, currentColor: '' });
|
||||
},
|
||||
|
||||
onChangeColor(e: WechatMiniprogram.CustomEvent) {
|
||||
const { color } = e.detail;
|
||||
const { currentKey, cardList } = this.data;
|
||||
const updated = [...cardList];
|
||||
updated[currentKey] = { ...updated[currentKey], color };
|
||||
this.setData({ showColorPopup: false, cardList: updated }, () => {
|
||||
this.drawCanvas();
|
||||
});
|
||||
},
|
||||
|
||||
/** 文字选择弹窗 */
|
||||
openSelectWordPopup() {
|
||||
this.setData({ showSelectWordPopup: true });
|
||||
},
|
||||
|
||||
closeSelectWordPopup() {
|
||||
this.setData({ showSelectWordPopup: false });
|
||||
},
|
||||
|
||||
onChangeWord(e: WechatMiniprogram.CustomEvent) {
|
||||
const selectedWords = e.detail.selectedWords as string[];
|
||||
const colors = [...WATER_COLORS.basic12];
|
||||
const cardList = selectedWords.map((word, i) => ({
|
||||
word,
|
||||
color: COLOR_MAP[word] || colors[i % colors.length].hex,
|
||||
}));
|
||||
this.setData({ showSelectWordPopup: false, cardList, selectedWords }, () => {
|
||||
this.drawCanvas();
|
||||
});
|
||||
},
|
||||
|
||||
/** 收藏 */
|
||||
async onPreviewFavorite() {
|
||||
const next = !this.data.isPreviewFavorite;
|
||||
this.setData({ isPreviewFavorite: next });
|
||||
const id = this.data.worksheetId;
|
||||
if (id) {
|
||||
this._favoritedMap[id] = next;
|
||||
if (next) addFavorite(id);
|
||||
else removeFavorite(id);
|
||||
}
|
||||
wx.showToast({ title: next ? '收藏成功' : '已取消收藏', icon: 'none' });
|
||||
},
|
||||
|
||||
async loadFavoritedMap() {
|
||||
const ids = WORD_COLORING_WORKSHEET_DEFINITIONS.map((d) => d.id);
|
||||
this._favoritedMap = await batchCheckFavorited(ids);
|
||||
if (this._favoritedMap[this.data.worksheetId]) {
|
||||
this.setData({ isPreviewFavorite: true });
|
||||
}
|
||||
},
|
||||
|
||||
getPublishMeta(): DebugPublishMeta {
|
||||
const meta = getPublishMetaByMode(this.data.worksheetId);
|
||||
if (!meta) throw new Error('当前题型配置不存在');
|
||||
return meta;
|
||||
},
|
||||
},
|
||||
{
|
||||
shareConfig: defaultShareConfig,
|
||||
pageInfoLookup,
|
||||
},
|
||||
);
|
||||
@@ -0,0 +1,130 @@
|
||||
<nav-bar title="涂色识字" />
|
||||
|
||||
<view class="wc-page">
|
||||
<view class="wc-main">
|
||||
<preview-card
|
||||
id="previewCard"
|
||||
showRefresh="{{true}}"
|
||||
showFavorite="{{true}}"
|
||||
favorited="{{isPreviewFavorite}}"
|
||||
bind:canvas-ready="onCanvasReady"
|
||||
bind:refresh="onPreviewRefresh"
|
||||
bind:favorite="onPreviewFavorite" />
|
||||
|
||||
<!-- 文字输入区域 -->
|
||||
<view class="wc-section">
|
||||
<text class="wc-section-title">添加文字</text>
|
||||
<view class="wc-input-row">
|
||||
<word-input bind:onConfirm="onConfirmInput" width="380rpx" />
|
||||
<toy-button
|
||||
type="green"
|
||||
size="small"
|
||||
bind:click="openSelectWordPopup"
|
||||
width="180rpx">
|
||||
选择文字
|
||||
</toy-button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 文字卡片 -->
|
||||
<view wx:if="{{cardList.length > 0}}" class="wc-section">
|
||||
<view class="wc-card-grid">
|
||||
<word-card
|
||||
wx:for="{{cardList}}"
|
||||
wx:key="index"
|
||||
key="{{index}}"
|
||||
word="{{item.word}}"
|
||||
color="{{item.color}}"
|
||||
bind:onDelete="deleteWordCard"
|
||||
bind:onColorTap="onColorTap" />
|
||||
</view>
|
||||
</view>
|
||||
<view wx:elif="{{!hasContent}}" class="wc-empty">
|
||||
<empty-state
|
||||
title="还没有添加文字"
|
||||
desc="输入文字或点击选择文字,开始创建涂鸦卡"
|
||||
hint="提示:最多可以同时添加 6 个文字" />
|
||||
</view>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<view class="wc-section">
|
||||
<view class="wc-action-row">
|
||||
<toy-button
|
||||
type="primary"
|
||||
bind:click="refreshCardList"
|
||||
width="380rpx"
|
||||
icon="refresh"
|
||||
icon-class-prefix="toy-icon">
|
||||
随机生成
|
||||
</toy-button>
|
||||
<toy-button
|
||||
disabled="{{cardList.length <= 0}}"
|
||||
type="white"
|
||||
bind:click="clearCardList"
|
||||
width="180rpx"
|
||||
icon="clear"
|
||||
icon-class-prefix="toy-icon">
|
||||
清空
|
||||
</toy-button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 模板选择(2列卡片网格) -->
|
||||
<view class="wc-section">
|
||||
<text class="wc-section-title">选择模板</text>
|
||||
<view class="wc-mode-grid">
|
||||
<view
|
||||
wx:for="{{modeOptions}}"
|
||||
wx:key="id"
|
||||
class="wc-mode-card {{worksheetId === item.id ? 'wc-mode-card--active' : ''}}"
|
||||
data-id="{{item.id}}"
|
||||
hover-class="wc-mode-card--pressed"
|
||||
hover-start-time="0"
|
||||
hover-stay-time="70"
|
||||
bindtap="onSelectMode">
|
||||
<toy-icon
|
||||
name="{{item.icon}}"
|
||||
size="42rpx"
|
||||
color="{{worksheetId === item.id ? '#453900' : '#605b50'}}"
|
||||
custom-class="wc-mode-card__icon" />
|
||||
<text class="wc-mode-card__label">{{item.title}}</text>
|
||||
<text class="wc-mode-card__sub">{{item.subtitle}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<draw-ad type="mathDraw"></draw-ad>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<preview-footer-actions
|
||||
disabled="{{!hasContent}}"
|
||||
bind:primary="exportToPrint"
|
||||
bind:secondary="onShare" />
|
||||
|
||||
<debug-publish-tools
|
||||
wx:if="{{isDevEnv && hasContent}}"
|
||||
id="debugPublishTools"
|
||||
visible="{{debugPublishVisible}}"
|
||||
loading="{{debugPublishLoading}}"
|
||||
meta="{{debugPublishMeta}}"
|
||||
bind:open="onOpenDebugPublish"
|
||||
bind:close="onCloseDebugPublish"
|
||||
bind:confirm="onConfirmDebugPublish" />
|
||||
|
||||
<share-guide-popup
|
||||
show="{{showShareDialog}}"
|
||||
bind:onClose="onCloseShareDialog"
|
||||
bind:onShareSuccess="onShareSuccess" />
|
||||
|
||||
<color-picker
|
||||
show="{{showColorPopup}}"
|
||||
currentColor="{{currentColor}}"
|
||||
bind:onClose="onCloseColorPopup"
|
||||
bind:onChange="onChangeColor" />
|
||||
|
||||
<word-picker
|
||||
show="{{showSelectWordPopup}}"
|
||||
cardList="{{cardList}}"
|
||||
bind:onClose="closeSelectWordPopup"
|
||||
bind:onChange="onChangeWord" />
|
||||
Reference in New Issue
Block a user