diff --git a/miniprogram/pages/copyBook/copyBook.json b/miniprogram/pages/copyBook/copyBook.json
index 5e1c6b8..9eba36f 100644
--- a/miniprogram/pages/copyBook/copyBook.json
+++ b/miniprogram/pages/copyBook/copyBook.json
@@ -7,6 +7,7 @@
"usingComponents": {
"toy-button": "/ui/button/button",
"van-icon": "@vant/weapp/icon/index",
+ "van-dialog": "@vant/weapp/dialog/index",
"word-input": "/components/word-input/word-input",
"word-card": "/components/word-card/word-card",
"word-picker": "/components/word-picker/word-picker",
diff --git a/miniprogram/pages/copyBook/copyBook.ts b/miniprogram/pages/copyBook/copyBook.ts
index 2f5a432..9f7315b 100644
--- a/miniprogram/pages/copyBook/copyBook.ts
+++ b/miniprogram/pages/copyBook/copyBook.ts
@@ -1,5 +1,9 @@
import WordDrawService from '../../service/wordDrawService';
import { checkAndSaveImage } from '../../utils/saveImage';
+import {
+ shouldShowShareGuide,
+ recordShareSuccess,
+} from '../../utils/shareGuide';
import { PAPER_SIZE } from '../../constants/colors';
import { getWordsSvgData } from '../../utils/getWordsSvgJson';
import { WORDS } from '../../constants/words';
@@ -22,6 +26,7 @@ Page({
currentColor: '',
boxWidth: 0,
boxHeight: 0,
+ showShareDialog: false, // 显示分享引导弹窗
},
async onLoad() {
@@ -29,14 +34,17 @@ Page({
const hasShowPracticeDemo =
wx.getStorageSync('hasShowPracticeDemo') || false;
if (!hasShowPracticeDemo) {
- this.setData({
- words: ['好', '好', '学', '习', '天', '天', '向', '上']
- }, () => {
- wx.setStorageSync('hasShowPracticeDemo', true);
- })
+ this.setData(
+ {
+ words: ['好', '好', '学', '习', '天', '天', '向', '上'],
+ },
+ () => {
+ wx.setStorageSync('hasShowPracticeDemo', true);
+ },
+ );
}
await this.setCanvasBoxSize();
- await this.initCanvas()
+ await this.initCanvas();
},
async loadSvgWords() {
@@ -48,7 +56,11 @@ Page({
this.svgWords = svgWordsData;
wx.hideToast();
- console.log('SVG汉字数据加载成功,共', Object.keys(this.svgWords).length, '个汉字');
+ console.log(
+ 'SVG汉字数据加载成功,共',
+ Object.keys(this.svgWords).length,
+ '个汉字',
+ );
const { words } = this.data as any;
if (words && words.length > 0) {
@@ -70,7 +82,7 @@ Page({
// 用户点击重试,重新加载
this.loadSvgWords();
}
- }
+ },
});
}
},
@@ -143,18 +155,25 @@ Page({
const { key } = e.detail;
const { words } = this.data as any;
const next = words.filter((_: string, index: number) => index !== key);
- this.setData({ words: next }, () => this.renderPracticeContent().catch(console.error));
+ this.setData({ words: next }, () =>
+ this.renderPracticeContent().catch(console.error),
+ );
},
// 清空
clearWords() {
- this.setData({ words: [] }, () => this.renderPracticeContent().catch(console.error));
+ this.setData({ words: [] }, () =>
+ this.renderPracticeContent().catch(console.error),
+ );
},
// 随机生成(取基础分类,过滤为可用SVG字,最多11个)
refreshWords() {
// 选取较简单的几个分类(如 0:基础独体字,1:生活高频字,2:自然与动作)
- const candidate = WORDS.slice(0, 3).reduce((acc: string[], c: any) => acc.concat(c.words), [] as string[]);
+ const candidate = WORDS.slice(0, 3).reduce(
+ (acc: string[], c: any) => acc.concat(c.words),
+ [] as string[],
+ );
// 去重
const unique = Array.from(new Set(candidate));
// 打乱
@@ -164,10 +183,15 @@ Page({
// 过滤为支持的SVG字
const supported = this.getSupportedWords(picked);
if (supported.length === 0) {
- wx.showToast({ title: '随机到的字暂不支持,重试一下', icon: 'none' });
+ wx.showToast({
+ title: '随机到的字暂不支持,重试一下',
+ icon: 'none',
+ });
return;
}
- this.setData({ words: supported }, () => this.renderPracticeContent().catch(console.error));
+ this.setData({ words: supported }, () =>
+ this.renderPracticeContent().catch(console.error),
+ );
},
// 校验 & 分割
@@ -181,7 +205,6 @@ Page({
return matches || [];
},
-
setCanvasBoxSize() {
const query = wx.createSelectorQuery();
query
@@ -212,13 +235,17 @@ Page({
if (ctx) {
this.canvas = canvas;
this.ctx = ctx;
- this.wordDrawService = new WordDrawService(canvas, ctx);
+ this.wordDrawService = new WordDrawService(
+ canvas,
+ ctx,
+ );
// 初始化时只绘制页眉和布局
await this.wordDrawService.drawLayout();
// 绘制完成后计算并缓存最大行列数(与实际绘制一致)
- const { maxRow, maxCol } = this.wordDrawService.getMaxGridLayout();
+ const { maxRow, maxCol } =
+ this.wordDrawService.getMaxGridLayout();
this.maxRow = maxRow;
this.maxCol = maxCol;
@@ -269,18 +296,25 @@ Page({
}
// 处理布局和生成练字数据(基于实际最大行列数)
- const characterData = this.processCharacterLayout(supportedWords, maxRow, maxCol);
+ const characterData = this.processCharacterLayout(
+ supportedWords,
+ maxRow,
+ maxCol,
+ );
this.wordDrawService.drawPracticeContent(characterData);
},
-
/** 检查汉字是否支持,返回支持的汉字列表 */
getSupportedWords(words: string[]): string[] {
- return words.filter(word => this.svgWords[word]);
+ return words.filter((word) => this.svgWords[word]);
},
/** 处理汉字布局,生成练字数据 */
- processCharacterLayout(words: string[], maxRow: number, maxCol: number): CharacterItem[] {
+ processCharacterLayout(
+ words: string[],
+ maxRow: number,
+ maxCol: number,
+ ): CharacterItem[] {
let rowIndex = 0;
const characterData: CharacterItem[] = [];
const boundaryWords: string[] = [];
@@ -319,11 +353,58 @@ Page({
wx.showToast({ title: '请先生成练字贴', icon: 'none' });
return;
}
+
+ // 检查是否需要显示分享引导
+ if (shouldShowShareGuide()) {
+ this.setData({ showShareDialog: true });
+ return;
+ }
+
+ // 直接下载
checkAndSaveImage(this.canvas);
},
+ /** 关闭分享引导弹窗 */
+ onCloseShareDialog() {
+ this.setData({ showShareDialog: false });
+ },
+
+ /** 点击转发按钮 */
+ onShareToFriend() {
+ // 记录分享成功(用户点击了分享按钮,视为已分享)
+ recordShareSuccess();
+ this.setData({ showShareDialog: false });
+ // 允许继续下载
+ if (this.canvas) {
+ checkAndSaveImage(this.canvas);
+ }
+ wx.showToast({
+ title: '分享后即可继续下载',
+ icon: 'success',
+ duration: 2000,
+ });
+ },
+
+ /** 点击分享到朋友圈按钮 */
+ onShareToTimeline() {
+ // 记录分享成功(用户点击了分享按钮,视为已分享)
+ recordShareSuccess();
+ this.setData({ showShareDialog: false });
+ // 允许继续下载
+ if (this.canvas) {
+ checkAndSaveImage(this.canvas);
+ }
+ wx.showToast({
+ title: '分享后即可继续下载',
+ icon: 'success',
+ duration: 2000,
+ });
+ },
+
// 分享功能
onShareAppMessage() {
+ // 记录分享成功(用户真正分享了)
+ recordShareSuccess();
return {
title: '涂鸦丫-练字|识字|打印',
path: '/pages/copyBook/index',
@@ -331,11 +412,11 @@ Page({
},
onShareTimeline() {
+ // 记录分享成功(用户真正分享了)
+ recordShareSuccess();
return {
title: '涂鸦丫-练字|识字|打印',
query: '/pages/copyBook/index',
};
},
});
-
-
diff --git a/miniprogram/pages/copyBook/copyBook.wxml b/miniprogram/pages/copyBook/copyBook.wxml
index 1e60a90..ca744d3 100644
--- a/miniprogram/pages/copyBook/copyBook.wxml
+++ b/miniprogram/pages/copyBook/copyBook.wxml
@@ -91,6 +91,16 @@
max="11"
bind:onClose="closeSelectWordPopup"
bind:onChange="onChangeWord" />
+
diff --git a/miniprogram/pages/index/index.json b/miniprogram/pages/index/index.json
index 08eaf8d..180f50e 100644
--- a/miniprogram/pages/index/index.json
+++ b/miniprogram/pages/index/index.json
@@ -8,6 +8,7 @@
"van-cell": "@vant/weapp/cell/index",
"van-icon": "@vant/weapp/icon/index",
"van-popup": "@vant/weapp/popup/index",
+ "van-dialog": "@vant/weapp/dialog/index",
"word-input": "../../components/word-input/word-input",
"word-card": "../../components/word-card/word-card",
"color-picker": "../../components/color-picker/color-picker",
diff --git a/miniprogram/pages/index/index.ts b/miniprogram/pages/index/index.ts
index 80be3fc..cf2054f 100644
--- a/miniprogram/pages/index/index.ts
+++ b/miniprogram/pages/index/index.ts
@@ -6,6 +6,10 @@ import {
TemplateType,
} from '../../service/drawServiceFactory';
import { checkAndSaveImage } from '../../utils/saveImage';
+import {
+ shouldShowShareGuide,
+ recordShareSuccess,
+} from '../../utils/shareGuide';
Page({
canvas: null as Canvas | null,
@@ -25,6 +29,7 @@ Page({
selectedTemplate: 'find', // 选中的模板类型
env: 'release',
isPCDevtool: false,
+ showShareDialog: false, // 显示分享引导弹窗
},
onLoad() {
@@ -280,10 +285,55 @@ Page({
/** 下载打印 */
exportToPrint() {
- if (this.canvas && this.data.cardList.length > 0) {
- checkAndSaveImage(this.canvas);
+ if (!this.canvas || this.data.cardList.length <= 0) {
return;
}
+
+ // 检查是否需要显示分享引导
+ if (shouldShowShareGuide()) {
+ this.setData({ showShareDialog: true });
+ return;
+ }
+
+ // 直接下载
+ checkAndSaveImage(this.canvas);
+ },
+
+ /** 关闭分享引导弹窗 */
+ onCloseShareDialog() {
+ this.setData({ showShareDialog: false });
+ },
+
+ /** 点击转发按钮 */
+ onShareToFriend() {
+ // 记录分享成功(用户点击了分享按钮,视为已分享)
+ recordShareSuccess();
+ this.setData({ showShareDialog: false });
+ // 允许继续下载
+ if (this.canvas && this.data.cardList.length > 0) {
+ checkAndSaveImage(this.canvas);
+ }
+ wx.showToast({
+ title: '分享后即可继续下载',
+ icon: 'success',
+ duration: 2000,
+ });
+ },
+
+ /** 点击分享到朋友圈按钮 */
+ onShareToTimeline() {
+ // 记录分享成功(用户点击了分享按钮,视为已分享)
+ recordShareSuccess();
+ this.setData({ showShareDialog: false });
+ // 允许继续下载
+ if (this.canvas && this.data.cardList.length > 0) {
+ checkAndSaveImage(this.canvas);
+ }
+ wx.showToast({
+ title: '分享后即可继续下载',
+ icon: 'success',
+ duration: 2000,
+ });
},
onColorTap(e: WechatMiniprogram.CustomEvent) {
@@ -324,12 +374,16 @@ Page({
},
onShareAppMessage() {
+ // 记录分享成功(用户真正分享了)
+ recordShareSuccess();
return {
title: '涂鸦丫-涂色|识字|画画|打印',
path: '/pages/index/index',
};
},
onShareTimeline() {
+ // 记录分享成功(用户真正分享了)
+ recordShareSuccess();
return {
title: '涂鸦丫-涂色|识字|画画|打印',
query: '/pages/index/index',
diff --git a/miniprogram/pages/index/index.wxml b/miniprogram/pages/index/index.wxml
index f9685f3..b244c7b 100644
--- a/miniprogram/pages/index/index.wxml
+++ b/miniprogram/pages/index/index.wxml
@@ -135,6 +135,16 @@
下载打印
-
+
+
diff --git a/miniprogram/pages/shape/index.json b/miniprogram/pages/shape/index.json
index 9e3ac91..2cd7409 100644
--- a/miniprogram/pages/shape/index.json
+++ b/miniprogram/pages/shape/index.json
@@ -8,6 +8,7 @@
"van-divider": "@vant/weapp/divider/index",
"van-icon": "@vant/weapp/icon/index",
"van-popup": "@vant/weapp/popup/index",
+ "van-dialog": "@vant/weapp/dialog/index",
"toy-button": "../../ui/button/button",
"shape-card": "../../components/shape-card/shape-card",
"shape-picker": "../../components/shape-picker/shape-picker",
diff --git a/miniprogram/pages/shape/index.ts b/miniprogram/pages/shape/index.ts
index 68d806c..e9d6232 100644
--- a/miniprogram/pages/shape/index.ts
+++ b/miniprogram/pages/shape/index.ts
@@ -2,6 +2,10 @@ import { SHAPES, ShapeCard } from '../../constants/shapes';
import { WATER_COLORS, PAPER_SIZE } from '../../constants/colors';
import ShapeDrawService from '../../service/shapeDrawService';
import { checkAndSaveImage } from '../../utils/saveImage';
+import {
+ shouldShowShareGuide,
+ recordShareSuccess,
+} from '../../utils/shareGuide';
Page({
@@ -20,6 +24,7 @@ Page({
currentIndex: 0,
currentColor: '',
isPCDevtool: false,
+ showShareDialog: false, // 显示分享引导弹窗
},
onLoad() {
@@ -263,12 +268,16 @@ Page({
},
onShareAppMessage() {
+ // 记录分享成功(用户真正分享了)
+ recordShareSuccess();
return {
title: '涂鸦丫-涂色|识字|画画|打印',
path: '/pages/index/index',
};
},
onShareTimeline() {
+ // 记录分享成功(用户真正分享了)
+ recordShareSuccess();
return {
title: '涂鸦丫-涂色|识字|画画|打印',
query: '/pages/index/index',
@@ -277,10 +286,55 @@ Page({
/** 下载打印 */
exportToPrint() {
- if (this.canvas && this.data.shapeList.length > 0) {
- checkAndSaveImage(this.canvas);
+ if (!this.canvas || this.data.shapeList.length <= 0) {
return;
}
+
+ // 检查是否需要显示分享引导
+ if (shouldShowShareGuide()) {
+ this.setData({ showShareDialog: true });
+ return;
+ }
+
+ // 直接下载
+ checkAndSaveImage(this.canvas);
+ },
+
+ /** 关闭分享引导弹窗 */
+ onCloseShareDialog() {
+ this.setData({ showShareDialog: false });
+ },
+
+ /** 点击转发按钮 */
+ onShareToFriend() {
+ // 记录分享成功(用户点击了分享按钮,视为已分享)
+ recordShareSuccess();
+ this.setData({ showShareDialog: false });
+ // 允许继续下载
+ if (this.canvas && this.data.shapeList.length > 0) {
+ checkAndSaveImage(this.canvas);
+ }
+ wx.showToast({
+ title: '分享后即可继续下载',
+ icon: 'success',
+ duration: 2000,
+ });
+ },
+
+ /** 点击分享到朋友圈按钮 */
+ onShareToTimeline() {
+ // 记录分享成功(用户点击了分享按钮,视为已分享)
+ recordShareSuccess();
+ this.setData({ showShareDialog: false });
+ // 允许继续下载
+ if (this.canvas && this.data.shapeList.length > 0) {
+ checkAndSaveImage(this.canvas);
+ }
+ wx.showToast({
+ title: '分享后即可继续下载',
+ icon: 'success',
+ duration: 2000,
+ });
},
onUnload() {
diff --git a/miniprogram/pages/shape/index.wxml b/miniprogram/pages/shape/index.wxml
index b5a1c63..162ab85 100644
--- a/miniprogram/pages/shape/index.wxml
+++ b/miniprogram/pages/shape/index.wxml
@@ -67,6 +67,16 @@
+
{
wx.canvasToTempFilePath({
canvas: canvas,
@@ -6,11 +8,15 @@ const doSaveImage = (canvas: Canvas) => {
success: (res) => {
wx.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
- success: () => wx.showToast({
- title: '保存成功,请在相册中查看',
- icon: 'success',
- duration: 2000,
- }),
+ success: () => {
+ // 记录下载成功
+ recordDownloadSuccess();
+ wx.showToast({
+ title: '保存成功,请在相册中查看',
+ icon: 'success',
+ duration: 2000,
+ });
+ },
// fail: () => wx.showToast({
// title: '保存涂色卡失败,请重试!',
// icon: 'none',
@@ -18,38 +24,37 @@ const doSaveImage = (canvas: Canvas) => {
// })
});
},
- fail: (err: any) => {
+ fail: () => {
wx.showToast({
title: '生成涂色卡失败,请重试!',
icon: 'none',
duration: 2000,
- })
- }
+ });
+ },
});
-}
+};
const requestPhotoPermission = (canvas: Canvas) => {
wx.authorize({
scope: 'scope.writePhotosAlbum',
success: () => doSaveImage(canvas),
- fail: () => wx.showToast({
- title: '请在“设置-添加到相册”中开启相册权限以保存涂色卡',
- icon: 'none',
- duration: 3000,
- })
- })
-}
-
+ fail: () =>
+ wx.showToast({
+ title: '请在“设置-添加到相册”中开启相册权限以保存涂色卡',
+ icon: 'none',
+ duration: 3000,
+ }),
+ });
+};
export const checkAndSaveImage = (canvas: Canvas) => {
wx.getSetting({
- success: res => {
+ success: (res) => {
if (!res.authSetting['scope.writePhotosAlbum']) {
- requestPhotoPermission(canvas)
+ requestPhotoPermission(canvas);
} else {
- doSaveImage(canvas)
+ doSaveImage(canvas);
}
- }
- })
+ },
+ });
};
-
diff --git a/miniprogram/utils/shareGuide.ts b/miniprogram/utils/shareGuide.ts
new file mode 100644
index 0000000..514c303
--- /dev/null
+++ b/miniprogram/utils/shareGuide.ts
@@ -0,0 +1,71 @@
+/**
+ * 分享引导工具
+ * 用于控制每日免费下载次数和分享引导
+ */
+
+const STORAGE_KEY_DOWNLOAD_DATE = 'downloadDate';
+const STORAGE_KEY_DOWNLOAD_COUNT = 'downloadCount';
+const STORAGE_KEY_SHARED_DATE = 'sharedDate';
+
+/**
+ * 获取今天的日期字符串(YYYY-MM-DD格式)
+ */
+function getTodayDateString(): string {
+ const today = new Date();
+ const year = today.getFullYear();
+ const month = String(today.getMonth() + 1).padStart(2, '0');
+ const day = String(today.getDate()).padStart(2, '0');
+ return `${year}-${month}-${day}`;
+}
+
+/**
+ * 检查今天是否已经下载过
+ * @returns true表示今天已下载过,false表示今天未下载
+ */
+export function hasDownloadedToday(): boolean {
+ const today = getTodayDateString();
+ const downloadDate = wx.getStorageSync(STORAGE_KEY_DOWNLOAD_DATE);
+ return downloadDate === today;
+}
+
+/**
+ * 记录今天的下载成功
+ */
+export function recordDownloadSuccess(): void {
+ const today = getTodayDateString();
+ wx.setStorageSync(STORAGE_KEY_DOWNLOAD_DATE, today);
+ const count = wx.getStorageSync(STORAGE_KEY_DOWNLOAD_COUNT) || 0;
+ wx.setStorageSync(STORAGE_KEY_DOWNLOAD_COUNT, count + 1);
+}
+
+/**
+ * 检查今天是否已经分享过
+ * @returns true表示今天已分享过,false表示今天未分享
+ */
+export function hasSharedToday(): boolean {
+ const today = getTodayDateString();
+ const sharedDate = wx.getStorageSync(STORAGE_KEY_SHARED_DATE);
+ return sharedDate === today;
+}
+
+/**
+ * 记录今天的分享成功
+ */
+export function recordShareSuccess(): void {
+ const today = getTodayDateString();
+ wx.setStorageSync(STORAGE_KEY_SHARED_DATE, today);
+}
+
+/**
+ * 检查是否需要显示分享引导
+ * @returns true表示需要显示分享引导,false表示不需要
+ */
+export function shouldShowShareGuide(): boolean {
+ // 如果今天已经分享过,不需要显示引导
+ if (hasSharedToday()) {
+ return false;
+ }
+ // 如果今天已经下载过,需要显示引导
+ return hasDownloadedToday();
+}
+