feat:生产初版页面
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* Canvas 平台适配器
|
||||
* 封装微信小程序 Canvas API,为未来 Web 平台迁移做准备
|
||||
*/
|
||||
|
||||
export interface CanvasInitResult {
|
||||
canvas: WechatMiniprogram.Canvas;
|
||||
ctx: CanvasRenderingContext2D;
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化 Canvas 节点
|
||||
* @param selector Canvas 选择器 (如 '#canvasContent')
|
||||
* @param wrapperSelector 容器选择器 (如 '#canvasWrapper')
|
||||
* @param aspectRatio 宽高比 (width / height)
|
||||
*/
|
||||
export function initCanvas(
|
||||
selector: string,
|
||||
wrapperSelector: string,
|
||||
aspectRatio: number,
|
||||
): Promise<CanvasInitResult> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const query = wx.createSelectorQuery();
|
||||
query
|
||||
.select(wrapperSelector)
|
||||
.boundingClientRect((rect) => {
|
||||
if (!rect) {
|
||||
reject(new Error('Canvas wrapper not found'));
|
||||
return;
|
||||
}
|
||||
|
||||
const boxWidth = rect.width;
|
||||
const boxHeight = boxWidth / aspectRatio;
|
||||
|
||||
wx.createSelectorQuery()
|
||||
.select(selector)
|
||||
.fields({ node: true, size: true })
|
||||
.exec((res) => {
|
||||
if (!res[0]) {
|
||||
reject(new Error('Canvas node not found'));
|
||||
return;
|
||||
}
|
||||
|
||||
const canvas = res[0].node;
|
||||
const ctx = canvas.getContext('2d');
|
||||
const dpr = wx.getSystemInfoSync().pixelRatio;
|
||||
|
||||
canvas.width = boxWidth * dpr;
|
||||
canvas.height = boxHeight * dpr;
|
||||
ctx.scale(dpr, dpr);
|
||||
|
||||
resolve({ canvas, ctx, width: boxWidth, height: boxHeight });
|
||||
});
|
||||
})
|
||||
.exec();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Canvas 导出为临时文件路径
|
||||
*/
|
||||
export function canvasToTempFilePath(
|
||||
canvas: WechatMiniprogram.Canvas,
|
||||
options?: { quality?: number; fileType?: 'png' | 'jpg' },
|
||||
): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
wx.canvasToTempFilePath({
|
||||
canvas,
|
||||
fileType: options?.fileType || 'png',
|
||||
quality: options?.quality || 1,
|
||||
success: (res) => resolve(res.tempFilePath),
|
||||
fail: reject,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载图片到 Canvas
|
||||
*/
|
||||
export function loadImage(
|
||||
canvas: WechatMiniprogram.Canvas,
|
||||
src: string,
|
||||
): Promise<WechatMiniprogram.Image> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const img = canvas.createImage();
|
||||
img.onload = () => resolve(img);
|
||||
img.onerror = reject;
|
||||
img.src = src;
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* 云服务平台适配器
|
||||
* 封装微信云开发 API
|
||||
*/
|
||||
|
||||
export interface CloudResult {
|
||||
code?: string | number;
|
||||
message?: string;
|
||||
info?: string;
|
||||
data?: any;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用云函数
|
||||
*/
|
||||
export async function callCloud(
|
||||
action: string,
|
||||
options?: Record<string, any>,
|
||||
): Promise<CloudResult> {
|
||||
try {
|
||||
const name = 'doodle';
|
||||
|
||||
const { errMsg, result } = await wx.cloud.callFunction({
|
||||
name,
|
||||
data: {
|
||||
action,
|
||||
...options,
|
||||
},
|
||||
});
|
||||
if (!/ok/.test(errMsg)) {
|
||||
wx.showToast({
|
||||
title: '服务器错误',
|
||||
icon: 'none',
|
||||
duration: 2000,
|
||||
});
|
||||
return {
|
||||
code: '500',
|
||||
info: '服务器繁忙',
|
||||
message: errMsg,
|
||||
};
|
||||
}
|
||||
return result as CloudResult;
|
||||
} catch (e: any) {
|
||||
return { code: '500', info: e.message || '服务器繁忙' };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询云数据库集合
|
||||
*/
|
||||
export async function queryCollection(
|
||||
collection: string,
|
||||
where?: Record<string, any>,
|
||||
limit: number = 20,
|
||||
orderBy?: { field: string; order: 'asc' | 'desc' },
|
||||
): Promise<any[]> {
|
||||
try {
|
||||
const db = wx.cloud.database();
|
||||
let query = db.collection(collection).where(where || {}).limit(limit);
|
||||
if (orderBy) {
|
||||
query = query.orderBy(orderBy.field, orderBy.order);
|
||||
}
|
||||
const { data } = await query.get();
|
||||
return data;
|
||||
} catch (e) {
|
||||
console.error('queryCollection failed:', collection, e);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* 图片平台适配器
|
||||
* 封装微信小程序图片加载和保存 API
|
||||
*/
|
||||
|
||||
/**
|
||||
* 保存图片到相册
|
||||
*/
|
||||
export function saveImageToAlbum(filePath: string): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
wx.saveImageToPhotosAlbum({
|
||||
filePath,
|
||||
success: () => resolve(),
|
||||
fail: (err) => {
|
||||
if (
|
||||
err.errMsg.includes('auth deny') ||
|
||||
err.errMsg.includes('authorize')
|
||||
) {
|
||||
wx.showModal({
|
||||
title: '提示',
|
||||
content: '需要授权保存图片到相册',
|
||||
confirmText: '去设置',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
wx.openSetting();
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
reject(err);
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取图片信息
|
||||
*/
|
||||
export function getImageInfo(
|
||||
src: string,
|
||||
): Promise<WechatMiniprogram.GetImageInfoSuccessCallbackResult> {
|
||||
return new Promise((resolve, reject) => {
|
||||
wx.getImageInfo({
|
||||
src,
|
||||
success: resolve,
|
||||
fail: reject,
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* 存储平台适配器
|
||||
* 封装微信小程序 Storage API
|
||||
*/
|
||||
|
||||
export function getStorage<T>(key: string, defaultValue?: T): T | undefined {
|
||||
try {
|
||||
const value = wx.getStorageSync(key);
|
||||
return value !== '' ? value : defaultValue;
|
||||
} catch {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
export function setStorage(key: string, value: any): void {
|
||||
try {
|
||||
wx.setStorageSync(key, value);
|
||||
} catch (e) {
|
||||
console.error('setStorage failed:', key, e);
|
||||
}
|
||||
}
|
||||
|
||||
export function removeStorage(key: string): void {
|
||||
try {
|
||||
wx.removeStorageSync(key);
|
||||
} catch (e) {
|
||||
console.error('removeStorage failed:', key, e);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user