Files
Blizzard 2f5dd6eefc feat: 养护模板/社区运营/体重趋势/计划日历 + 雪花ID重构 + 文件表与图片上传
后端
- 主键改雪花字符串 ID(pkg/idgen + Base.BeforeCreate),全表外键/JWT/中间件随之调整
- 新增 files 表:/api/upload 按 MD5 去重,返回 {id,url,md5},服务端只收图片
- 头像/记录附图/帖子图改 file_id 关联,读取解析为 URL
- 养护模板(物种×阶段)后台可配 + AI 生成草稿;建档按模板生成任务/计划/提醒
- 社区 AI 运营:虚拟账号池 + 每日定时/手动生成,帖子带 AI 标
- 计划路线图节点带真实日期;首页周历与计划日历同源;新增 day-plan 当日安排
- 体重趋势接口带备注;记录列表分页

小程序
- 公共图片上传 utils/upload.js(仅图片);记录拍照/我的头像/社区发图三处接入
- 首页日历点选查当日任务;记录页体重趋势可点看备注 + 时间轴分页折叠
- 计划页日历点选查当日计划;自定义 tabBar 高度调整

后台(React)
- 新增「养护模板」「社区运营」页;用户管理加机器人筛选

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 08:48:15 +08:00

56 lines
1.8 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 公共图片上传:选图(仅图片)→ 上传后端(/api/uploadMD5 去重)→ 返回 {id,url,md5}
const { uploadFile } = require('./request.js');
const IMG_EXT = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp', 'heic', 'heif'];
// 仅允许图片:按扩展名二次校验(chooseMedia mediaType 已限制,这里双保险)
function isImagePath(p) {
const m = /\.([a-zA-Z0-9]+)(\?.*)?$/.exec(p || '');
return !!m && IMG_EXT.indexOf(m[1].toLowerCase()) >= 0;
}
// 选择并上传图片,返回 Promise<[{id,url,md5}]>。用户取消时 reject({canceled:true})。
function chooseAndUploadImages(count) {
count = count || 1;
return new Promise((resolve, reject) => {
wx.chooseMedia({
count,
mediaType: ['image'], // 仅图片,不允许视频/文件
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success(res) {
const files = (res.tempFiles || []).filter((f) => isImagePath(f.tempFilePath));
if (!files.length) {
reject(new Error('只能上传图片文件'));
return;
}
wx.showLoading({ title: '上传中...', mask: true });
Promise.all(files.map((f) => uploadFile(f.tempFilePath)))
.then((list) => {
wx.hideLoading();
resolve(list);
})
.catch((e) => {
wx.hideLoading();
reject(e);
});
},
fail(err) {
const msg = (err && err.errMsg) || '';
if (/cancel/i.test(msg)) {
reject({ canceled: true });
return;
}
reject(new Error(msg || '选择图片失败'));
},
});
});
}
// 单张图片,返回 Promise<{id,url,md5}>
function chooseAndUploadImage() {
return chooseAndUploadImages(1).then((list) => list[0]);
}
module.exports = { chooseAndUploadImages, chooseAndUploadImage, isImagePath };