chore: update pom.xml Lombok config and deploy settings
- Update Maven compiler plugin to support Lombok annotation processing - Add deploy.conf for automated deployment - Update backend models and controllers - Update frontend pages and API
This commit is contained in:
@@ -110,8 +110,8 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 营养统计卡片:仅根据是否有数据展示 -->
|
||||
<view class="nutrition-stats-card" v-if="nutritionStatsLength > 0">
|
||||
<!-- 营养统计卡片:仅当 nutritionStats.length > 0 时展示,不依赖后端字段存在性 -->
|
||||
<view class="nutrition-stats-card" v-if="nutritionStats.length > 0">
|
||||
<view class="stats-header">
|
||||
<view class="stats-title">
|
||||
<text class="title-icon">📊</text>
|
||||
@@ -122,7 +122,7 @@
|
||||
</view>
|
||||
</view>
|
||||
<view class="stats-grid">
|
||||
<view class="stat-item" v-for="(stat, index) in postData.nutritionStats" :key="index">
|
||||
<view class="stat-item" v-for="(stat, index) in nutritionStats" :key="index">
|
||||
<view class="stat-value">{{ stat.value }}</view>
|
||||
<view class="stat-label">{{ stat.label }}</view>
|
||||
</view>
|
||||
@@ -286,16 +286,17 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 营养统计条数,用于卡片显示条件(避免 postData.nutritionStats 未定义时报错)
|
||||
nutritionStatsLength() {
|
||||
// 营养统计数组,用于卡片显示与列表渲染(单一数据源,避免未定义)
|
||||
nutritionStats() {
|
||||
const stats = this.postData && this.postData.nutritionStats
|
||||
return Array.isArray(stats) ? stats.length : 0
|
||||
return Array.isArray(stats) ? stats : []
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
if (options.id) {
|
||||
this.postId = options.id
|
||||
this.loadPostData(options.id)
|
||||
// Ensure postId is number for API calls (URL params are strings)
|
||||
this.postId = parseInt(options.id, 10) || options.id
|
||||
this.loadPostData(this.postId)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -343,6 +344,14 @@ export default {
|
||||
*/
|
||||
buildNutritionStatsFromDetailData(data) {
|
||||
if (!data) return []
|
||||
console.log('[post-detail] buildNutritionStatsFromDetailData API response data:', JSON.stringify({
|
||||
nutritionStats: data.nutritionStats,
|
||||
nutrition_stats: data.nutrition_stats,
|
||||
nutritionDataJson: data.nutritionDataJson,
|
||||
nutrition_data_json: data.nutrition_data_json,
|
||||
dietaryData: data.dietaryData,
|
||||
mealData: data.mealData
|
||||
}))
|
||||
|
||||
// 1) 后端直接返回的 stat 数组(兼容不同命名)
|
||||
const rawStats = data.nutritionStats || data.nutrition_stats
|
||||
@@ -353,17 +362,21 @@ export default {
|
||||
})).filter(s => s.label)
|
||||
}
|
||||
|
||||
// 2) nutritionDataJson / nutrition_data_json
|
||||
// 2) nutritionDataJson / nutrition_data_json(兼容后端驼峰与下划线;含打卡字段 actualEnergy/actualProtein)
|
||||
const jsonRaw = data.nutritionDataJson || data.nutrition_data_json
|
||||
if (jsonRaw) {
|
||||
try {
|
||||
const nutritionData = typeof jsonRaw === 'string' ? JSON.parse(jsonRaw) : jsonRaw
|
||||
if (nutritionData && typeof nutritionData === 'object') {
|
||||
const cal = nutritionData.calories ?? nutritionData.energy ?? nutritionData.calorie ?? nutritionData.actualEnergy
|
||||
const pro = nutritionData.protein ?? nutritionData.proteins ?? nutritionData.actualProtein
|
||||
const pot = nutritionData.potassium ?? nutritionData.k
|
||||
const pho = nutritionData.phosphorus ?? nutritionData.p
|
||||
return [
|
||||
{ label: '热量(kcal)', value: nutritionData.calories != null ? String(nutritionData.calories) : '-' },
|
||||
{ label: '蛋白质', value: nutritionData.protein != null ? nutritionData.protein + 'g' : '-' },
|
||||
{ label: '钾', value: nutritionData.potassium != null ? nutritionData.potassium + 'mg' : '-' },
|
||||
{ label: '磷', value: nutritionData.phosphorus != null ? nutritionData.phosphorus + 'mg' : '-' }
|
||||
{ label: '热量(kcal)', value: cal != null ? String(cal) : '-' },
|
||||
{ label: '蛋白质', value: this.formatNutritionValue(pro, 'g') },
|
||||
{ label: '钾', value: pot != null ? (typeof pot === 'number' ? pot + 'mg' : String(pot)) : '-' },
|
||||
{ label: '磷', value: pho != null ? (typeof pho === 'number' ? pho + 'mg' : String(pho)) : '-' }
|
||||
]
|
||||
}
|
||||
} catch (e) {
|
||||
@@ -376,13 +389,13 @@ export default {
|
||||
if (dietary) {
|
||||
const obj = typeof dietary === 'string' ? (() => { try { return JSON.parse(dietary) } catch (_) { return null } })() : dietary
|
||||
if (obj && typeof obj === 'object') {
|
||||
const cal = obj.calories ?? obj.energy ?? obj.calorie
|
||||
const pro = obj.protein ?? obj.proteins
|
||||
const cal = obj.calories ?? obj.energy ?? obj.calorie ?? obj.actualEnergy
|
||||
const pro = obj.protein ?? obj.proteins ?? obj.actualProtein
|
||||
const pot = obj.potassium ?? obj.k
|
||||
const pho = obj.phosphorus ?? obj.p
|
||||
return [
|
||||
{ label: '热量(kcal)', value: cal != null ? String(cal) : '-' },
|
||||
{ label: '蛋白质', value: pro != null ? (typeof pro === 'number' ? pro + 'g' : String(pro)) : '-' },
|
||||
{ label: '蛋白质', value: this.formatNutritionValue(pro, 'g') },
|
||||
{ label: '钾', value: pot != null ? (typeof pot === 'number' ? pot + 'mg' : String(pot)) : '-' },
|
||||
{ label: '磷', value: pho != null ? (typeof pho === 'number' ? pho + 'mg' : String(pho)) : '-' }
|
||||
]
|
||||
@@ -392,22 +405,26 @@ export default {
|
||||
return []
|
||||
},
|
||||
|
||||
/** 格式化营养素显示值(兼容 number/string/BigDecimal 等) */
|
||||
formatNutritionValue(val, unit) {
|
||||
if (val == null || val === '') return '-'
|
||||
const str = typeof val === 'number' ? String(val) : String(val)
|
||||
return str === '' || str === 'undefined' || str === 'null' ? '-' : (unit ? str + unit : str)
|
||||
},
|
||||
|
||||
/**
|
||||
* 根据打卡详情接口返回的数据构建 nutritionStats(蛋白质、热量、钾、磷)
|
||||
*/
|
||||
buildNutritionStatsFromCheckinDetail(detail) {
|
||||
if (!detail || typeof detail !== 'object') return []
|
||||
const items = []
|
||||
// 热量
|
||||
const energy = detail.actualEnergy ?? detail.energy
|
||||
items.push({ label: '热量(kcal)', value: energy != null ? String(energy) : '-' })
|
||||
// 蛋白质
|
||||
const protein = detail.actualProtein ?? detail.protein
|
||||
items.push({ label: '蛋白质', value: protein != null ? (typeof protein === 'number' ? protein + 'g' : String(protein)) : '-' })
|
||||
// 钾、磷:打卡详情可能没有,用 -
|
||||
items.push({ label: '钾', value: '-' })
|
||||
items.push({ label: '磷', value: '-' })
|
||||
return items
|
||||
return [
|
||||
{ label: '热量(kcal)', value: energy != null ? String(energy) : '-' },
|
||||
{ label: '蛋白质', value: this.formatNutritionValue(protein, 'g') },
|
||||
{ label: '钾', value: '-' },
|
||||
{ label: '磷', value: '-' }
|
||||
]
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -715,6 +732,13 @@ export default {
|
||||
return
|
||||
}
|
||||
|
||||
const postIdNum = typeof this.postId === 'number' ? this.postId : parseInt(this.postId, 10)
|
||||
if (!postIdNum || isNaN(postIdNum)) {
|
||||
console.error('[post-detail] toggleLike: invalid postId', this.postId)
|
||||
uni.showToast({ title: '操作失败,请重试', icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
const newLikeState = !this.isLiked
|
||||
const newLikeCount = newLikeState
|
||||
? this.postData.likeCount + 1
|
||||
@@ -725,8 +749,9 @@ export default {
|
||||
this.postData.likeCount = newLikeCount
|
||||
|
||||
try {
|
||||
await apiToggleLike(this.postId, newLikeState)
|
||||
await apiToggleLike(postIdNum, newLikeState)
|
||||
} catch (error) {
|
||||
console.error('[post-detail] toggleLike failed:', error)
|
||||
// 回滚
|
||||
this.isLiked = !newLikeState
|
||||
this.postData.likeCount = newLikeState
|
||||
@@ -747,6 +772,13 @@ export default {
|
||||
return
|
||||
}
|
||||
|
||||
const postIdNum = typeof this.postId === 'number' ? this.postId : parseInt(this.postId, 10)
|
||||
if (!postIdNum || isNaN(postIdNum)) {
|
||||
console.error('[post-detail] toggleFavorite: invalid postId', this.postId)
|
||||
uni.showToast({ title: '操作失败,请重试', icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
const newCollectState = !this.isCollected
|
||||
const newCollectCount = newCollectState
|
||||
? this.postData.favoriteCount + 1
|
||||
@@ -757,12 +789,13 @@ export default {
|
||||
this.postData.favoriteCount = newCollectCount
|
||||
|
||||
try {
|
||||
await toggleCollect(this.postId, newCollectState)
|
||||
await toggleCollect(postIdNum, newCollectState)
|
||||
uni.showToast({
|
||||
title: newCollectState ? '已收藏' : '取消收藏',
|
||||
icon: 'none'
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('[post-detail] toggleFavorite failed:', error)
|
||||
// 回滚
|
||||
this.isCollected = !newCollectState
|
||||
this.postData.favoriteCount = newCollectState
|
||||
|
||||
Reference in New Issue
Block a user