fix: 修复关注按钮相关问题
- 食谱详情页: 修复 applyDefaultData 中未定义变量 id 的问题 - 帖子详情页: 优化 toggleFollow 方法,提前校验 author.id,兼容多种后端字段 - 为帖子详情页已关注状态添加灰色样式
This commit is contained in:
@@ -340,9 +340,13 @@ export default {
|
||||
|
||||
try {
|
||||
const res = await getCommunityDetail(id)
|
||||
// 兼容 CommonResult:res = { code, data: 详情对象 },取 res.data 作为详情
|
||||
const data = (res && res.data !== undefined && res.data !== null) ? res.data : res
|
||||
|
||||
// 兼容 CommonResult:res = { code, data: 详情对象 } 或 { result: 详情对象 },取 data/result 作为详情
|
||||
const data = (res && res.data !== undefined && res.data !== null)
|
||||
? res.data
|
||||
: (res && res.result !== undefined && res.result !== null)
|
||||
? res.result
|
||||
: res
|
||||
|
||||
// 格式化帖子数据
|
||||
this.formatPostData(data)
|
||||
|
||||
@@ -412,7 +416,7 @@ export default {
|
||||
if (statsFromObj.length > 0 && !statsFromObj.every(s => s.value === '-')) return statsFromObj
|
||||
}
|
||||
|
||||
// 2) nutritionDataJson / nutrition_data_json(兼容后端驼峰与下划线;含 fill-nutrition 的 energyKcal/proteinG/potassiumMg/phosphorusMg、打卡字段 actualEnergy/actualProtein)
|
||||
// 2) nutritionDataJson / nutrition_data_json(兼容后端驼峰与下划线;含 fill-nutrition 的 energyKcal/proteinG、嵌套格式 calories: { value, unit })
|
||||
const jsonRaw = data.nutritionDataJson || data.nutrition_data_json
|
||||
if (jsonRaw) {
|
||||
try {
|
||||
@@ -429,7 +433,7 @@ export default {
|
||||
if (!Array.isArray(nutritionData) && Object.keys(nutritionData).length === 0) {
|
||||
return []
|
||||
}
|
||||
// 2c) 有键的对象:兼容后端 fill-nutrition 的 energyKcal/proteinG 等
|
||||
// 2c) 有键的对象:兼容后端嵌套 { calories: { value, unit }, protein: { value, unit }, ... } 与扁平 energyKcal/proteinG
|
||||
const statsFromJson = this.buildNutritionStatsFromNutritionObject(nutritionData)
|
||||
// 若解析后全部为占位符 "-",视为无效数据,返回 [] 以便走打卡/服务端填充
|
||||
if (statsFromJson.length > 0 && statsFromJson.every(s => s.value === '-')) {
|
||||
@@ -441,6 +445,20 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
// 2d) nutritionData / nutrition_data 为已解析对象(部分接口直接返回对象)
|
||||
const nutritionDataObj = data.nutritionData || data.nutrition_data
|
||||
if (nutritionDataObj && typeof nutritionDataObj === 'object' && !Array.isArray(nutritionDataObj) && Object.keys(nutritionDataObj).length > 0) {
|
||||
const statsFromObj = this.buildNutritionStatsFromNutritionObject(nutritionDataObj)
|
||||
if (statsFromObj.length > 0 && !statsFromObj.every(s => s.value === '-')) return statsFromObj
|
||||
}
|
||||
|
||||
// 2e) 详情中嵌套的打卡记录(若后端返回 checkInRecord/check_in_record,直接从中取营养)
|
||||
const checkInRecord = data.checkInRecord || data.check_in_record
|
||||
if (checkInRecord && typeof checkInRecord === 'object') {
|
||||
const statsFromCheckin = this.buildNutritionStatsFromCheckinDetail(checkInRecord)
|
||||
if (statsFromCheckin.length > 0 && statsFromCheckin.some(s => s.value !== '-' && s.value !== '')) return statsFromCheckin
|
||||
}
|
||||
|
||||
// 3) dietaryData / mealData / dietary_data / meal_data(饮食打卡对象)
|
||||
const dietary = data.dietaryData || data.dietary_data || data.mealData || data.meal_data
|
||||
if (dietary) {
|
||||
@@ -565,8 +583,12 @@ export default {
|
||||
async fillNutritionStatsFromCheckin(checkInRecordId) {
|
||||
try {
|
||||
const res = await getCheckinDetail(checkInRecordId)
|
||||
// 兼容:res 为 { code, data } 时取 res.data;部分封装直接返回 payload 则 res 即为 detail
|
||||
const detail = (res && res.data !== undefined && res.data !== null) ? res.data : res
|
||||
// 兼容:res 为 { code, data } 或 { result } 时取 data/result;部分封装直接返回 payload 则 res 即为 detail
|
||||
const detail = (res && res.data !== undefined && res.data !== null)
|
||||
? res.data
|
||||
: (res && res.result !== undefined && res.result !== null)
|
||||
? res.result
|
||||
: res
|
||||
if (!detail || typeof detail !== 'object') return
|
||||
const stats = this.buildNutritionStatsFromCheckinDetail(detail)
|
||||
// 仅当至少有一项有效值时才更新,避免展示全部为 "-" 的卡片
|
||||
@@ -706,7 +728,7 @@ export default {
|
||||
description: description,
|
||||
tags: tags,
|
||||
author: {
|
||||
id: data.userId,
|
||||
id: data.userId ?? data.authorId ?? data.user_id ?? data.author_id ?? null,
|
||||
avatar: data.userAvatar || '👤',
|
||||
name: data.userName || '匿名用户',
|
||||
time: this.formatTime(data.createdAt)
|
||||
@@ -717,7 +739,7 @@ export default {
|
||||
likeCount: data.likeCount || 0,
|
||||
favoriteCount: data.collectCount || 0,
|
||||
commentCount: data.commentCount || 0,
|
||||
checkInRecordId: data.checkInRecordId,
|
||||
checkInRecordId: data.checkInRecordId ?? data.check_in_record_id ?? null,
|
||||
videoUrl: data.videoUrl || null,
|
||||
videoStatus: data.videoStatus,
|
||||
hasVideo: data.hasVideo || false
|
||||
@@ -852,12 +874,16 @@ export default {
|
||||
setTimeout(() => toLogin(), 1000)
|
||||
return
|
||||
}
|
||||
|
||||
// 先检查 author.id 是否存在,再改状态、调 API,避免无效请求导致「操作失败」
|
||||
const authorId = this.postData && this.postData.author && (this.postData.author.id ?? this.postData.author.userId)
|
||||
if (authorId == null || authorId === '') {
|
||||
uni.showToast({ title: '无法获取作者信息', icon: 'none' })
|
||||
return
|
||||
}
|
||||
const newFollowState = !this.isFollowed
|
||||
this.isFollowed = newFollowState
|
||||
|
||||
try {
|
||||
await apiToggleFollow(this.postData.author.id, newFollowState)
|
||||
await apiToggleFollow(authorId, newFollowState)
|
||||
uni.showToast({
|
||||
title: newFollowState ? '已关注' : '取消关注',
|
||||
icon: 'none'
|
||||
@@ -1327,6 +1353,11 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
.follow-btn.followed {
|
||||
background: linear-gradient(135deg, #9fa5c0 0%, #8a90a8 100%);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
/* 营养统计卡片 */
|
||||
.nutrition-stats-card {
|
||||
margin: 10rpx 32rpx;
|
||||
|
||||
Reference in New Issue
Block a user