756 lines
27 KiB
TypeScript
Executable File
756 lines
27 KiB
TypeScript
Executable File
// upload.ts - 主功能页面(拍照/相册选择)
|
||
import { IAppOption, IUserInfo } from 'miniprogram/types/app'
|
||
import apiManager from '../../utils/api'
|
||
import imageManager from '../../utils/image'
|
||
import ActionSheet, { ActionSheetTheme } from 'tdesign-miniprogram/action-sheet/index';
|
||
import { FILE_BASE_URL } from '../../utils/config'
|
||
|
||
const app = getApp<IAppOption>()
|
||
|
||
type IDayType = 'morning' | 'afternoon' | 'night'
|
||
const DayTypeMap: Record<IDayType, string> = {
|
||
morning: '早上好',
|
||
afternoon: '下午好',
|
||
night: '晚上好'
|
||
}
|
||
|
||
Page({
|
||
data: {
|
||
DayTypeMap,
|
||
current_date: '',
|
||
currentYear: new Date().getFullYear(), // 添加当前年份
|
||
day_type: 'morning' as IDayType,
|
||
isLoggedIn: false,
|
||
showLoginView: false,
|
||
userInfo: null as IUserInfo | null,
|
||
isProcessing: false, // 是否正在处理图片
|
||
// 移除模拟数据,改为从API获取
|
||
groupedHistory: [] as any[],
|
||
todaySummary: [] as any[], // 添加今日摘要数据
|
||
// 添加分页相关数据
|
||
dailyPage: 1,
|
||
dailySize: 10,
|
||
dailyTotal: 0,
|
||
dailyHasMore: true,
|
||
todayPage: 1,
|
||
todaySize: 10,
|
||
// 添加加载状态
|
||
isLoading: true,
|
||
// 添加文件基础URL
|
||
fileBaseUrl: FILE_BASE_URL,
|
||
// 添加表情位置状态
|
||
facePosition: 'normal' as 'up' | 'down' | 'normal',
|
||
// SVG data for avatar
|
||
avatarSvgData: '',
|
||
paperSvgData: '',
|
||
photoSvgData: '',
|
||
scrollTop: 0
|
||
},
|
||
|
||
onLoad() {
|
||
console.log('主功能页面加载')
|
||
this.checkLoginStatus().then(() => {
|
||
// 只有登录成功后才加载历史数据
|
||
if (this.data.isLoggedIn) {
|
||
this.loadTodaySummary() // 加载今日摘要数据
|
||
this.loadDailySummary()
|
||
this.checkDayType()
|
||
}
|
||
}).catch((error) => {
|
||
console.error('登录检查失败:', error)
|
||
})
|
||
this.generateAvatarSvg()
|
||
this.generatePhotoSvg()
|
||
},
|
||
|
||
// Generate SVG data URL for avatar
|
||
generateAvatarSvg() {
|
||
const svgString = `
|
||
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="470 50 20 40">
|
||
<path d="M 486 70 C 486 71.7614 483.761 74 481 74 C 478.239 74 476 71.7614 476 70 C 476 69 477 69 477 70 C 477 71 479 73 481 73 C 483 73 485 71 485 70 C 485 69 486 69 486 70 M 490 64 C 488.7 64 488.7 66 490 66 C 491.3 66 491.3 64 490 64 M 472 64 C 470.7 64 470.7 66 472 66 C 473.3 66 473.3 64 472 64" stroke="#001858" stroke-width="1.5" stroke-linecap="round"></path>
|
||
</svg>
|
||
`.trim();
|
||
|
||
const encodedSvg = encodeURIComponent(svgString);
|
||
const dataUrl = `data:image/svg+xml;utf8,${encodedSvg}`;
|
||
|
||
this.setData({
|
||
avatarSvgData: dataUrl
|
||
});
|
||
},
|
||
|
||
generatePhotoSvg() {
|
||
const svgString = `
|
||
<svg viewBox="0 0 2000 960" width="500" height="240" xmlns="http://www.w3.org/2000/svg">
|
||
<path transform="translate(59,243)" d="m0 0h16l8 5 7 9 4 8 3 15 8 87 6 62 12 109 7 59 2 15 8-24 11-21 11-17 9-11 10-9 16-11 12-6 20-6 19-2 19 1 16 4 11 5 16 9 11 9 10 9 10 13 11 18 8 16 5 17 7 29 2 19 1 16v12l-2 28-4 24-6 22-7 19-12 28-13 21-16 21-12 13-14 11-21 12-19 8-17 5-18 3h-25l-15-3-18-7-13-7-13-10-9-12-8-17-6-20-5-23-8-51-24-122-9-60-8-60-5-43-8-92-6-74v-29l4-10 6-7 8-5z" fill="#4D4848"/>
|
||
<path transform="translate(1026,96)" d="m0 0h7l10 3 8 7 6 11 3 14 2 33 2 115 3 62 5 57 5 37 4 23v4h2l1-11 4-15 5-12 8-15 11-15 10-11 13-10 14-8 16-6 16-3 17-1 17 2 13 4 12 5 13 7 12 9 13 13 10 15 8 14 8 20 6 25 3 18 1 11v35l-2 29-4 24-6 20-8 20-12 25-8 14-11 15-8 10-11 12-11 11-14 9-25 12-20 6-10 2h-29l-18-4-15-6-13-7-12-11-8-10-8-14-7-20-6-26-6-37-6-35-8-39-6-32-8-54-4-29-6-56-3-37-2-40-1-35-1-65v-29l1-21 3-18 5-10 9-8 5-2z" fill="#4D4848"/>
|
||
<path transform="translate(1740,245)" d="m0 0h10l16 3 13 5 17 9 14 11 12 12 8 14 5 18 2 17 3 56 3 29 5 26 6 23 8 21 9 17 10 13 8 7 7 4 8 1 11-4 11-8 12-10 10-4 12 1 10 5 7 8 3 10v8l-3 12-6 11-9 10-10 8-15 8-12 3-7 1h-27l-16-4-16-8-13-8-13-12-10-14-9-20-2-1-3 12-6 16-12 22-8 12-8 10-9 10-12 10-13 8-12 6-16 4h-26l-16-4-14-6-13-9-12-11-9-10-10-17-8-19-7-28-3-20-1-11v-22l3-29 6-31 8-28 8-22 11-24 11-22 10-16 10-13 12-14 10-9 14-10 19-9 12-3z" fill="#4D4848"/>
|
||
<path transform="translate(794,392)" d="m0 0h9l16 3 19 7 14 8 11 9 9 10 8 14 5 14 2 13 3 69 4 40 5 25 7 21 12 23 10 14 8 8 12 6h10l10-5 12-12 9-6 3-1h14l8 4 9 8 4 8 1 3v17l-3 10-6 10-7 7-14 8-18 6-12 2h-25l-17-4-16-7-14-9-10-9-14-24-7-14-2-1-3 10-9 24-8 16-7 11-9 10-12 12-13 10-13 8-16 6-17 3h-19l-15-3-10-4-10-6-13-10-9-9-12-17-9-17-6-17-4-19-2-15-1-15v-21l2-28 4-26 6-25 12-36 10-23 9-17 14-20 9-11 15-15 10-9 14-9 12-6 17-5z" fill="#4D4848"/>
|
||
<path transform="translate(1408,40)" d="m0 0h13l8 3 5 5 4 5 4 8 2 9v30l-6 98-2 42-1 38v103l2 43 4 46 5 39 5 29 8 32 8 24 9 16 9 10 6 4 3 1h8l11-4 9-8 6-8 8-11 8-10 7-5 4-1h17l10 5 6 7 4 10v14l-4 13-7 13-8 11-9 10-9 8-15 9-16 6-15 3h-24l-15-4-17-8-10-8-9-9-12-17-9-16-9-21-7-23-9-41-8-45-6-41-3-36-2-32-1-30v-98l2-54 6-89 3-32 4-18 7-14 8-7z" fill="#4D4848"/>
|
||
<path transform="translate(460,186)" d="m0 0 9 1 8 5 6 7 5 10 3 11 1 9v44l-4 71-2 65v67l2 48 4 53 5 45 6 38 8 37 8 27 10 25 6 10 8 9 6 4 6 2h8l10-5 5-4 10-13 9-13 6-7 9-5 4-1h12l10 4 8 9 4 8 1 4v14l-3 12-6 10-9 13-7 8-14 11-12 7-18 7-15 3h-21l-15-3-13-5-12-8-10-9-9-12-14-24-8-17-12-36-6-23-10-50-12-91-3-28-1-16-1-37v-78l1-46 4-91 3-35 4-18 5-10 7-7 7-4z" fill="#4D4848"/>
|
||
<path transform="translate(249,568)" d="m0 0 14 1 10 4 10 9 6 7 8 15 6 18 4 17 2 17v34l-3 26-6 25-8 21-8 17-13 19-12 13-9 8-11 7-19 9-15 4h-21l-8-3-4-6-3-12-1-7-1-25v-28l2-28 5-35 5-26 7-27 7-20 10-19 8-11 9-10 8-7 11-5z" fill="#FEFDE2"/>
|
||
<path transform="translate(1194,416)" d="m0 0h7l10 3 11 7 7 7 8 13 7 16 5 22 2 20v29l-3 22-5 24-8 24-8 16-8 14-9 11-9 10-7 7-13 10-10 6-16 7-8 2h-14l-8-5-7-8-4-11-2-11-1-13v-31l2-25 4-29 8-43 7-24 8-19 8-15 10-14 9-10 11-7 11-4z" fill="#FEFDE2"/>
|
||
<path transform="translate(1737,307)" d="m0 0h13l10 5 7 8 5 10 2 9 1 16v60l-3 28-5 25-7 27-10 25-10 19-9 13-12 12-8 5-7 2h-10l-9-3-10-9-6-10-6-20-2-12-1-14v-25l2-23 5-26 7-25 9-24 11-24 10-18 9-12 8-9 9-7z" fill="#FEFDE2"/>
|
||
<path transform="translate(789,454)" d="m0 0h13l10 3 5 5 4 10 3 18 1 12v45l-3 33-4 25-8 34-7 20-11 23-8 12-11 12-9 6-6 2h-13l-10-4-6-5-7-11-6-15-4-19-2-18v-25l4-29 6-26 9-27 9-21 10-19 10-15 12-14 10-8 5-3z" fill="#FEFDE2"/>
|
||
</svg>
|
||
`.trim();
|
||
|
||
const encodedSvg = encodeURIComponent(svgString);
|
||
const dataUrl = `data:image/svg+xml;utf8,${encodedSvg}`;
|
||
|
||
this.setData({
|
||
photoSvgData: dataUrl
|
||
});
|
||
},
|
||
|
||
onShow() {
|
||
// 每次显示页面时检查登录状态和清理处理状态
|
||
this.updateLoginStatus()
|
||
this.setData({ isProcessing: false }) // 清理处理状态
|
||
},
|
||
|
||
// 处理页面滚动
|
||
onPageScroll(e: WechatMiniprogram.Page.IPageScrollOption): void {
|
||
const scrollTop = e.scrollTop
|
||
const lastScrollTop = this.data.scrollTop
|
||
const threshold = 30 // 滚动阈值
|
||
|
||
// 更新滚动位置
|
||
this.setData({ scrollTop })
|
||
|
||
// 向上滚动
|
||
if (scrollTop < lastScrollTop && scrollTop > threshold) {
|
||
if (this.data.facePosition !== 'up') {
|
||
this.setData({ facePosition: 'up' })
|
||
}
|
||
}
|
||
// 向下滚动
|
||
else if (scrollTop > lastScrollTop && scrollTop > threshold) {
|
||
if (this.data.facePosition !== 'down') {
|
||
this.setData({ facePosition: 'down' })
|
||
}
|
||
}
|
||
// 回到顶部附近
|
||
else if (scrollTop <= threshold) {
|
||
if (this.data.facePosition !== 'normal') {
|
||
this.setData({ facePosition: 'normal' })
|
||
}
|
||
}
|
||
},
|
||
|
||
checkDayType() {
|
||
const currentHour = new Date().getHours();
|
||
const currentDate = new Date().toLocaleDateString('zh-CN');
|
||
const dayType = currentHour >= 6 && currentHour < 12 ? 'morning' :
|
||
currentHour >= 12 && currentHour < 18 ? 'afternoon' : 'night';
|
||
// const dayType = 'morning';
|
||
this.setData({
|
||
current_date: currentDate,
|
||
day_type: dayType as IDayType
|
||
});
|
||
|
||
// 根据日间/夜间模式设置导航栏颜色
|
||
wx.setNavigationBarColor({
|
||
frontColor: '#ffffff',
|
||
backgroundColor: dayType === 'night' ? '#232946' : '#fffffe',
|
||
animation: {
|
||
duration: 300,
|
||
timingFunc: 'easeIn'
|
||
}
|
||
});
|
||
},
|
||
|
||
// 加载每日摘要数据(历史记录,支持分页)
|
||
async loadDailySummary(page: number = 1) {
|
||
try {
|
||
// 只有在第一页时才显示加载状态(下拉刷新)
|
||
if (page === 1) {
|
||
this.setData({ isLoading: true });
|
||
}
|
||
|
||
const result = await apiManager.getDailySummary(page, this.data.dailySize);
|
||
|
||
// 处理数据,按年份分组
|
||
const processedItems = result.items.map(item => ({
|
||
...item,
|
||
images: item.image_ids && item.thumbnail_ids ?
|
||
item.image_ids.map((imageId: string, index: number) => ({
|
||
image_id: imageId,
|
||
thumbnail_id: item.thumbnail_ids![index],
|
||
// 不再直接构造URL,而是存储文件ID,稍后通过安全方式获取
|
||
thumbnail_file_id: item.thumbnail_ids![index],
|
||
image_file_id: imageId,
|
||
thumbnail_url: '', // 将在页面渲染前通过安全方式获取
|
||
image_url: '', // 将在需要时通过安全方式获取
|
||
thumbnail_loading: true // 添加加载状态
|
||
})) : []
|
||
}));
|
||
|
||
let groupedArray;
|
||
|
||
if (page === 1) {
|
||
// 第一页:替换所有数据
|
||
const currentYear = new Date().getFullYear();
|
||
const grouped: any = {};
|
||
|
||
processedItems.forEach(item => {
|
||
const date = new Date(item.summary_time);
|
||
const year = date.getFullYear();
|
||
const month = date.getMonth() + 1;
|
||
const day = date.getDate();
|
||
|
||
if (!grouped[year]) {
|
||
grouped[year] = [];
|
||
}
|
||
|
||
grouped[year].push({
|
||
...item,
|
||
monthDay: `${month}-${day}`
|
||
});
|
||
});
|
||
|
||
// 转换为数组形式并按年份排序
|
||
groupedArray = Object.keys(grouped)
|
||
.map(year => ({
|
||
year: parseInt(year),
|
||
isCurrentYear: parseInt(year) === currentYear,
|
||
items: grouped[year]
|
||
}))
|
||
.sort((a, b) => b.year - a.year);
|
||
} else {
|
||
// 后续页面:只处理新数据并追加到现有数据
|
||
const currentYear = new Date().getFullYear();
|
||
const existingData = [...this.data.groupedHistory];
|
||
|
||
// 处理新数据的分组
|
||
const newGrouped: any = {};
|
||
processedItems.forEach(item => {
|
||
const date = new Date(item.summary_time);
|
||
const year = date.getFullYear();
|
||
const month = date.getMonth() + 1;
|
||
const day = date.getDate();
|
||
|
||
if (!newGrouped[year]) {
|
||
newGrouped[year] = [];
|
||
}
|
||
|
||
newGrouped[year].push({
|
||
...item,
|
||
monthDay: `${month}-${day}`
|
||
});
|
||
});
|
||
|
||
// 将新数据合并到现有数据中
|
||
Object.keys(newGrouped).forEach(year => {
|
||
const yearInt = parseInt(year);
|
||
const existingYearGroup = existingData.find(group => group.year === yearInt);
|
||
|
||
if (existingYearGroup) {
|
||
// 如果年份已存在,追加到该年份的数据中
|
||
existingYearGroup.items = [...existingYearGroup.items, ...newGrouped[year]];
|
||
} else {
|
||
// 如果年份不存在,添加新的年份组
|
||
existingData.push({
|
||
year: yearInt,
|
||
isCurrentYear: yearInt === currentYear,
|
||
items: newGrouped[year]
|
||
});
|
||
}
|
||
});
|
||
|
||
// 重新排序年份
|
||
groupedArray = existingData.sort((a, b) => b.year - a.year);
|
||
}
|
||
|
||
this.setData({
|
||
groupedHistory: groupedArray,
|
||
dailyPage: page,
|
||
dailyTotal: result.total,
|
||
dailyHasMore: page * this.data.dailySize < result.total,
|
||
isLoading: false,
|
||
}, () => {
|
||
// 在数据设置完成后获取安全的图片URL
|
||
this.fetchSecureImageUrls();
|
||
});
|
||
} catch (error) {
|
||
console.error('加载每日摘要失败:', error);
|
||
this.setData({ isLoading: false });
|
||
wx.showToast({
|
||
title: '加载失败',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
},
|
||
|
||
// 加载今日摘要数据(当天记录,只加载第一页)
|
||
async loadTodaySummary(page: number = 1) {
|
||
try {
|
||
const result = await apiManager.getTodaySummary(page, this.data.todaySize);
|
||
|
||
// 处理数据,按时间分组
|
||
const processedItems = result.items.map(item => {
|
||
// 为今天的数据添加 monthDay 字段
|
||
const date = new Date(item.summary_time);
|
||
const month = date.getMonth() + 1;
|
||
const day = date.getDate();
|
||
const monthDay = `${month}-${day}`;
|
||
|
||
return {
|
||
...item,
|
||
monthDay: monthDay, // 添加 monthDay 字段
|
||
images: item.image_ids && item.thumbnail_ids ?
|
||
item.image_ids.map((imageId: string, index: number) => ({
|
||
image_id: imageId,
|
||
thumbnail_id: item.thumbnail_ids![index],
|
||
// 不再直接构造URL,而是存储文件ID,稍后通过安全方式获取
|
||
thumbnail_file_id: item.thumbnail_ids![index],
|
||
image_file_id: imageId,
|
||
thumbnail_url: '', // 将在页面渲染前通过安全方式获取
|
||
image_url: '', // 将在需要时通过安全方式获取
|
||
thumbnail_loading: true // 添加加载状态
|
||
})) : []
|
||
};
|
||
});
|
||
|
||
// 设置今日摘要数据
|
||
this.setData({
|
||
todaySummary: processedItems
|
||
}, () => {
|
||
// 在数据设置完成后获取安全的图片URL
|
||
this.fetchSecureTodayImageUrls();
|
||
});
|
||
|
||
console.log('今日摘要数据加载完成:', processedItems);
|
||
return processedItems;
|
||
} catch (error) {
|
||
console.error('加载今日摘要失败:', error);
|
||
wx.showToast({
|
||
title: '加载今日数据失败',
|
||
icon: 'none'
|
||
});
|
||
throw error;
|
||
}
|
||
},
|
||
|
||
// 触底加载更多数据(只加载每日摘要的下一页)
|
||
onReachBottom() {
|
||
if (this.data.dailyHasMore && !this.data.isLoading) {
|
||
const nextPage = this.data.dailyPage + 1;
|
||
this.loadDailySummary(nextPage);
|
||
}
|
||
},
|
||
|
||
// 下拉刷新
|
||
onPullDownRefresh() {
|
||
this.setData({
|
||
dailyPage: 1,
|
||
todayPage: 1
|
||
});
|
||
this.loadDailySummary(1).then(() => {
|
||
wx.stopPullDownRefresh();
|
||
}).catch(() => {
|
||
wx.stopPullDownRefresh();
|
||
});
|
||
},
|
||
|
||
// 获取安全的图片URL
|
||
async fetchSecureImageUrls() {
|
||
try {
|
||
console.log('开始获取安全的图片URL');
|
||
|
||
// 遍历所有分组的历史记录
|
||
const updatedHistory = [...this.data.groupedHistory];
|
||
let hasChanges = false;
|
||
|
||
for (const yearGroup of updatedHistory) {
|
||
for (const item of yearGroup.items) {
|
||
for (const image of item.images) {
|
||
// 如果还没有获取过安全URL且有thumbnail_file_id
|
||
if ((!image.thumbnail_url || image.thumbnail_url === '') && image.thumbnail_file_id) {
|
||
try {
|
||
// 首先检查本地缓存中是否已有该缩略图
|
||
const cachedThumbnail = this.getCachedThumbnail(image.thumbnail_file_id);
|
||
if (cachedThumbnail) {
|
||
image.thumbnail_url = cachedThumbnail;
|
||
image.thumbnail_loading = false;
|
||
hasChanges = true;
|
||
// console.log('使用缓存的缩略图:', image.thumbnail_file_id);
|
||
continue;
|
||
}
|
||
|
||
// 获取安全的缩略图URL
|
||
image.thumbnail_url = await apiManager.getFileDisplayUrl(image.thumbnail_file_id);
|
||
|
||
// 缓存缩略图到本地存储
|
||
this.cacheThumbnail(image.thumbnail_file_id, image.thumbnail_url);
|
||
|
||
image.thumbnail_loading = false; // 设置加载完成状态
|
||
hasChanges = true;
|
||
} catch (error) {
|
||
console.error('获取缩略图URL失败:', error);
|
||
// 如果获取失败,使用默认的占位图
|
||
image.thumbnail_url = '/static/sun-2.png';
|
||
image.thumbnail_loading = false; // 设置加载完成状态
|
||
}
|
||
}
|
||
|
||
// 如果还没有获取过安全URL且有image_file_id
|
||
// if (!image.image_url && image.image_file_id) {
|
||
// try {
|
||
// // 获取安全的原图URL
|
||
// image.image_url = await apiManager.getFileDisplayUrl(image.image_file_id);
|
||
// hasChanges = true;
|
||
// } catch (error) {
|
||
// console.error('获取原图URL失败:', error);
|
||
// // 如果获取失败,使用默认的占位图
|
||
// image.image_url = '/static/placeholder.png';
|
||
// }
|
||
// }
|
||
}
|
||
}
|
||
}
|
||
|
||
// 如果有变化,更新数据
|
||
if (hasChanges) {
|
||
this.setData({
|
||
groupedHistory: updatedHistory
|
||
});
|
||
// console.log('安全图片URL获取完成');
|
||
}
|
||
} catch (error) {
|
||
console.error('获取安全图片URL失败:', error);
|
||
}
|
||
},
|
||
|
||
// 获取安全的今日摘要图片URL
|
||
async fetchSecureTodayImageUrls() {
|
||
try {
|
||
console.log('开始获取今日摘要安全的图片URL');
|
||
|
||
// 获取今日摘要数据
|
||
const todaySummary = [...this.data.todaySummary];
|
||
let hasChanges = false;
|
||
|
||
for (const item of todaySummary) {
|
||
for (const image of item.images) {
|
||
// 如果还没有获取过安全URL且有thumbnail_file_id
|
||
if ((!image.thumbnail_url || image.thumbnail_url === '') && image.thumbnail_file_id) {
|
||
try {
|
||
// 首先检查本地缓存中是否已有该缩略图
|
||
const cachedThumbnail = this.getCachedThumbnail(image.thumbnail_file_id);
|
||
if (cachedThumbnail) {
|
||
image.thumbnail_url = cachedThumbnail;
|
||
image.thumbnail_loading = false;
|
||
hasChanges = true;
|
||
// console.log('使用缓存的缩略图:', image.thumbnail_file_id);
|
||
continue;
|
||
}
|
||
|
||
// 获取安全的缩略图URL
|
||
image.thumbnail_url = await apiManager.getFileDisplayUrl(image.thumbnail_file_id);
|
||
|
||
// 缓存缩略图到本地存储
|
||
this.cacheThumbnail(image.thumbnail_file_id, image.thumbnail_url);
|
||
|
||
image.thumbnail_loading = false; // 设置加载完成状态
|
||
hasChanges = true;
|
||
} catch (error) {
|
||
console.error('获取缩略图URL失败:', error);
|
||
// 如果获取失败,使用默认的占位图
|
||
image.thumbnail_url = '/static/sun-2.png';
|
||
image.thumbnail_loading = false; // 设置加载完成状态
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 如果有变化,更新数据
|
||
if (hasChanges) {
|
||
this.setData({
|
||
todaySummary: todaySummary
|
||
});
|
||
// console.log('安全图片URL获取完成');
|
||
}
|
||
} catch (error) {
|
||
console.error('获取安全图片URL失败:', error);
|
||
}
|
||
},
|
||
|
||
// 缓存缩略图到本地存储
|
||
cacheThumbnail(fileId: string, filePath: string) {
|
||
try {
|
||
// 获取文件信息以计算大小
|
||
const fs = wx.getFileSystemManager();
|
||
fs.getFileInfo({
|
||
filePath: filePath,
|
||
success: (res) => {
|
||
const fileSize = res.size;
|
||
// 创建缓存条目
|
||
const cacheEntry = {
|
||
filePath: filePath,
|
||
timestamp: Date.now(),
|
||
size: fileSize
|
||
};
|
||
|
||
// 保存到本地存储
|
||
wx.setStorageSync(`thumbnail_cache_${fileId}`, cacheEntry);
|
||
// console.log('缩略图已缓存:', fileId, '大小:', fileSize, 'bytes');
|
||
},
|
||
fail: (err) => {
|
||
console.error('获取缩略图文件信息失败:', err);
|
||
}
|
||
});
|
||
} catch (error) {
|
||
console.error('缓存缩略图失败:', error);
|
||
}
|
||
},
|
||
|
||
// 从本地存储获取缓存的缩略图
|
||
getCachedThumbnail(fileId: string): string | null {
|
||
try {
|
||
const cacheKey = `thumbnail_cache_${fileId}`;
|
||
const cacheEntry = wx.getStorageSync(cacheKey);
|
||
|
||
if (cacheEntry) {
|
||
// 检查文件是否存在
|
||
const fs = wx.getFileSystemManager();
|
||
try {
|
||
fs.accessSync(cacheEntry.filePath);
|
||
// 检查缓存是否过期(例如7天)
|
||
const cacheAge = Date.now() - cacheEntry.timestamp;
|
||
const maxCacheAge = 7 * 24 * 60 * 60 * 1000; // 7天
|
||
|
||
if (cacheAge < maxCacheAge) {
|
||
return cacheEntry.filePath;
|
||
} else {
|
||
// 缓存过期,删除缓存条目
|
||
wx.removeStorageSync(cacheKey);
|
||
console.log('缩略图缓存已过期并已删除:', fileId);
|
||
}
|
||
} catch (err) {
|
||
// 文件不存在,删除缓存条目
|
||
wx.removeStorageSync(cacheKey);
|
||
console.log('缩略图文件不存在,已删除缓存条目:', fileId);
|
||
}
|
||
}
|
||
|
||
return null;
|
||
} catch (error) {
|
||
console.error('获取缓存缩略图失败:', error);
|
||
return null;
|
||
}
|
||
},
|
||
|
||
// 图片点击事件
|
||
onImageTap(e: any) {
|
||
const { imageId } = e.currentTarget.dataset;
|
||
if (imageId) {
|
||
wx.navigateTo({
|
||
url: `/pages/assessment/assessment?imageId=${imageId}`
|
||
})
|
||
}
|
||
},
|
||
|
||
onImageCardTap(e: any) {
|
||
const { imageItems } = e.currentTarget.dataset;
|
||
if (!imageItems?.images?.length) return;
|
||
|
||
const items = imageItems.images.map((item: any) => ({
|
||
image_id: item.image_id,
|
||
image: item.thumbnail_loading ? '' : (item.thumbnail_url || '/static/sun-2.png'), // 使用安全URL或占位图
|
||
}));
|
||
ActionSheet.show({
|
||
theme: ActionSheetTheme.Grid,
|
||
selector: '#t-images-sheet',
|
||
context: this,
|
||
align: 'center',
|
||
description: '请选择图片',
|
||
items,
|
||
cancelText: '取消'
|
||
});
|
||
},
|
||
|
||
// 检查登录状态
|
||
async checkLoginStatus() {
|
||
try {
|
||
// 使用智能登录检查和更新登录状态
|
||
const loginResult = await apiManager.smartLogin()
|
||
|
||
if (loginResult) {
|
||
// 登录成功,更新全局状态
|
||
app.globalData.isLoggedIn = true
|
||
app.globalData.token = loginResult.access_token
|
||
this.updateLoginStatus()
|
||
console.log('登录状态验证成功')
|
||
return true
|
||
} else {
|
||
// 登录失败,跳转到登录页
|
||
console.log('登录状态验证失败,跳转到登录页')
|
||
wx.reLaunch({
|
||
url: '/pages/index/index'
|
||
})
|
||
return false
|
||
}
|
||
} catch (error) {
|
||
console.error('检查登录状态失败:', error)
|
||
// 发生错误时跳转到登录页
|
||
wx.reLaunch({
|
||
url: '/pages/index/index'
|
||
})
|
||
return false
|
||
}
|
||
},
|
||
|
||
// 更新登录状态
|
||
updateLoginStatus() {
|
||
const isLoggedIn = !!app.globalData.token
|
||
this.setData({ isLoggedIn, showLoginView: !isLoggedIn })
|
||
},
|
||
|
||
// 处理图片选择(合并拍照和相册选择功能)
|
||
handleImageSelect() {
|
||
if (this.data.isProcessing) return;
|
||
|
||
ActionSheet.show({
|
||
theme: ActionSheetTheme.List,
|
||
selector: '#t-action-sheet',
|
||
context: this,
|
||
align: 'center',
|
||
description: '请选择操作',
|
||
items: [
|
||
{
|
||
label: '拍照识别',
|
||
icon: 'camera'
|
||
},
|
||
{
|
||
label: '相册选择',
|
||
icon: 'image'
|
||
}
|
||
],
|
||
cancelText: '取消'
|
||
});
|
||
},
|
||
|
||
handleSelected(e: any) {
|
||
const { index } = e.detail;
|
||
console.log('用户选择:', index)
|
||
if (index === 0) {
|
||
this.handleTakePhoto();
|
||
} else if (index === 1) {
|
||
this.handleChooseFromAlbum();
|
||
}
|
||
},
|
||
|
||
handleImageSelected(e: any) {
|
||
console.log('用户选择:', e)
|
||
if (e.detail.selected === 'cancel') return;
|
||
|
||
const { image_id } = e.detail.selected
|
||
if (image_id) {
|
||
wx.navigateTo({
|
||
url: `/pages/assessment/assessment?imageId=${image_id}`
|
||
})
|
||
}
|
||
},
|
||
|
||
// 拍照
|
||
async handleTakePhoto() {
|
||
try {
|
||
this.setData({ isProcessing: true })
|
||
wx.showLoading({ title: '准备拍照...' })
|
||
|
||
const imagePath = await imageManager.takePhoto({
|
||
quality: 80,
|
||
maxWidth: 1920,
|
||
maxHeight: 1920
|
||
})
|
||
|
||
wx.hideLoading()
|
||
console.log('拍照成功:', imagePath)
|
||
|
||
// 直接跳转到结果页面
|
||
this.navigateToResult(imagePath)
|
||
|
||
} catch (error: any) {
|
||
wx.hideLoading()
|
||
this.setData({ isProcessing: false })
|
||
console.error('拍照失败:', error)
|
||
|
||
if (error?.message !== '用户取消选择') {
|
||
wx.showToast({
|
||
title: '拍照失败',
|
||
icon: 'none'
|
||
})
|
||
}
|
||
}
|
||
},
|
||
|
||
// 从相册选择
|
||
async handleChooseFromAlbum() {
|
||
try {
|
||
this.setData({ isProcessing: true })
|
||
wx.showLoading({ title: '准备选择图片...' })
|
||
|
||
// const imagePath = await imageManager.chooseFromAlbum({
|
||
// quality: 80,
|
||
// maxWidth: 1920,
|
||
// maxHeight: 1920
|
||
// })
|
||
const imagePath = await imageManager.chooseFromAlbum()
|
||
|
||
wx.hideLoading()
|
||
console.log('选择图片成功:', imagePath)
|
||
|
||
// 直接跳转到结果页面
|
||
this.navigateToResult(imagePath)
|
||
|
||
} catch (error: any) {
|
||
wx.hideLoading()
|
||
this.setData({ isProcessing: false })
|
||
console.error('选择图片失败:', error)
|
||
|
||
if (error?.message !== '用户取消选择') {
|
||
wx.showToast({
|
||
title: '选择图片失败',
|
||
icon: 'none'
|
||
})
|
||
}
|
||
}
|
||
},
|
||
|
||
// 跳转到结果页面
|
||
navigateToResult(imagePath: string) {
|
||
try {
|
||
console.log('跳转到结果页面:', imagePath)
|
||
|
||
// 跳转到结果页面并传递图片路径
|
||
wx.navigateTo({
|
||
url: `/pages/result/result?imagePath=${encodeURIComponent(imagePath)}`
|
||
})
|
||
|
||
} catch (error) {
|
||
console.error('跳转结果页面失败:', error)
|
||
this.setData({ isProcessing: false })
|
||
wx.showToast({
|
||
title: '操作失败',
|
||
icon: 'none'
|
||
})
|
||
}
|
||
},
|
||
|
||
// 跳转到个人主页
|
||
goProfile() {
|
||
wx.navigateTo({
|
||
url: '/pages/profile/profile'
|
||
})
|
||
}
|
||
|
||
})
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|