feat: 更新前端多个页面和后端服务

- 前端: 更新AI营养师、计算器、打卡、食物详情等页面
- 前端: 更新食物百科、知识详情、营养知识页面
- 前端: 更新社区首页
- 后端: 更新ToolKieAIServiceImpl服务
- API: 更新models-api.js和user.js
This commit is contained in:
2026-03-07 22:26:37 +08:00
parent 1632801880
commit f692c75f7b
11 changed files with 221 additions and 85 deletions

View File

@@ -128,7 +128,7 @@ export default {
data() {
return {
currentTab: 'nutrients',
scrollViewHeight: 'calc(100vh - 120rpx)', // 为 tab 预留高度,微信小程序 scroll-view 明确高度
scrollViewHeight: '100vh', // 默认值onReady 中按机型计算为 px保证微信小程序 scroll-view 明确高度
guideList: [],
articleList: [],
nutrientList: [
@@ -188,8 +188,25 @@ export default {
// 有 id 时切换到科普文章 tabswitchTab 内会调用 loadKnowledgeList 加载列表
this.switchTab('articles');
} else {
// 无 id 时默认当前 tab 为「营养素」,不请求接口;用户点击「饮食指南」或「科普文章」时由 switchTab 触发 loadKnowledgeList
// 无 id 时默认当前 tab 为「营养素」;切换到「饮食指南」或「科普文章」时由 switchTab 触发 loadKnowledgeList
this.currentTab = 'nutrients';
// 确保列表初始为数组,避免未加载时为 undefined切换 Tab 后再加载对应列表
this.guideList = Array.isArray(this.guideList) ? this.guideList : [];
this.articleList = Array.isArray(this.articleList) ? this.articleList : [];
}
},
onReady() {
// 微信小程序 scroll-view 必须使用明确高度,且 calc(vh - rpx) 兼容性差,改为用 px 计算
try {
const systemInfo = uni.getSystemInfoSync();
const statusBarHeight = systemInfo.statusBarHeight || 0;
const navHeight = 44;
const tabBarRpx = 120;
const windowWidth = systemInfo.windowWidth || 375;
const tabBarPx = Math.ceil((windowWidth / 750) * tabBarRpx);
this.scrollViewHeight = `calc(100vh - ${statusBarHeight + navHeight + tabBarPx}px)`;
} catch (e) {
this.scrollViewHeight = 'calc(100vh - 140px)';
}
},
methods: {
@@ -216,16 +233,21 @@ export default {
page: 1,
limit: 50
});
// 兼容 CommonPageresult.data.list,或 result.data/result.data.records 为数组
// 兼容多种返回结构result.data.list / result.data.records / result.data 为数组 / result.list
let rawList = [];
if (result && result.data) {
if (Array.isArray(result.data.list)) {
rawList = result.data.list;
} else if (Array.isArray(result.data.records)) {
rawList = result.data.records;
} else if (Array.isArray(result.data)) {
rawList = result.data;
const d = result.data;
if (Array.isArray(d.list)) {
rawList = d.list;
} else if (Array.isArray(d.records)) {
rawList = d.records;
} else if (Array.isArray(d)) {
rawList = d;
} else if (d && Array.isArray(d.data)) {
rawList = d.data;
}
} else if (result && Array.isArray(result.list)) {
rawList = result.list;
}
// Normalize id: backend may return knowledgeId, id, or knowledge_id (BeanUtil/JSON)
const list = (rawList || []).map(item => {
@@ -233,6 +255,7 @@ export default {
return {
...item,
id,
knowledgeId: item.knowledgeId ?? id,
desc: item.desc || item.summary || '',
time: item.time || (item.publishedAt || item.createdAt ? this.formatKnowledgeTime(item.publishedAt || item.createdAt) : ''),
views: item.views != null ? item.views : (item.viewCount != null ? item.viewCount : 0),
@@ -240,19 +263,20 @@ export default {
coverImage: item.coverImage || item.cover_image || ''
};
});
// 始终赋值为数组,绝不设为 undefined
if (this.currentTab === 'guide') {
this.guideList = list;
this.guideList = Array.isArray(list) ? list : [];
} else if (this.currentTab === 'articles') {
this.articleList = list;
this.articleList = Array.isArray(list) ? list : [];
}
} catch (error) {
console.error('加载知识列表失败:', error);
const msg = (error && (typeof error === 'string' ? error : (error.message || error.msg))) || '加载列表失败';
uni.showToast({
title: String(msg),
title: String(msg).substring(0, 20),
icon: 'none'
});
// 失败时清空当前 tab 列表确保始终为数组,不设为 undefined
// 失败时清空当前 tab 列表确保始终为数组,不设为 undefined
if (this.currentTab === 'guide') {
this.guideList = [];
} else if (this.currentTab === 'articles') {
@@ -275,13 +299,19 @@ export default {
goToDetail(event) {
const id = event.currentTarget.dataset.itemId;
const knowledgeId = event.currentTarget.dataset.itemKid;
const finalId = knowledgeId || id;
if (!finalId) {
uni.showToast({ title: "暂无详情", icon: "none" });
const finalId = knowledgeId ?? id;
// 仅当 knowledgeId 或 id 存在且有效时才跳转,否则提示暂无详情
if (finalId == null || finalId === '' || String(finalId).trim() === '' || String(finalId) === 'undefined') {
uni.showToast({ title: '暂无详情', icon: 'none' });
return;
}
const idStr = String(finalId).trim();
if (idStr === 'undefined') {
uni.showToast({ title: '暂无详情', icon: 'none' });
return;
}
uni.navigateTo({
url: `/pages/tool/knowledge-detail?id=${finalId}`
url: `/pages/tool/knowledge-detail?id=${encodeURIComponent(idStr)}`
});
}
}