feat: 打卡详情页一键分享到社区功能
- 新增后端接口 POST /api/front/tool/checkin/{checkinId}/share-to-community
- 实现 shareCheckinToCommunity 方法,复制打卡数据到社区帖子表
- 前端修改 handleCopyCheckin 方法,直接调用后端接口创建帖子
- 支持将打卡图片、描述、营养分析数据复制到社区
- 添加重复分享检查,防止重复创建帖子
- 创建成功后显示提示并可跳转到社区详情页
This commit is contained in:
@@ -7,6 +7,7 @@ import com.zbkj.common.request.PageParamRequest;
|
||||
import com.zbkj.common.response.NutritionAdoptResponse;
|
||||
import com.zbkj.common.response.NutritionCalculateResponse;
|
||||
import com.zbkj.common.result.CommonResult;
|
||||
import com.zbkj.common.token.FrontTokenComponent;
|
||||
import com.zbkj.service.service.tool.*;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
@@ -65,6 +66,9 @@ public class ToolController {
|
||||
@Autowired
|
||||
private ToolUploadService toolUploadService;
|
||||
|
||||
@Autowired
|
||||
private FrontTokenComponent frontTokenComponent;
|
||||
|
||||
// ==================== 食谱计算器相关 ====================
|
||||
|
||||
/**
|
||||
@@ -230,6 +234,17 @@ public class ToolController {
|
||||
return CommonResult.success(toolCheckinService.learn((Long) data.get("sourcePostId"), data));
|
||||
}
|
||||
|
||||
/**
|
||||
* 分享打卡记录到社区
|
||||
*/
|
||||
@ApiOperation(value = "分享打卡记录到社区")
|
||||
@PostMapping("/checkin/{checkinId}/share-to-community")
|
||||
public CommonResult<Map<String, Object>> shareCheckinToCommunity(
|
||||
@ApiParam(value = "打卡记录ID", required = true) @PathVariable Integer checkinId) {
|
||||
Integer userId = frontTokenComponent.getUserId();
|
||||
return CommonResult.success(toolCheckinService.shareCheckinToCommunity(checkinId, userId));
|
||||
}
|
||||
|
||||
// ==================== 食物百科相关 ====================
|
||||
|
||||
/**
|
||||
|
||||
@@ -663,4 +663,108 @@ public class ToolCheckinServiceImpl implements ToolCheckinService {
|
||||
return "饮食";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 分享打卡记录到社区
|
||||
*
|
||||
* @param checkinId 打卡记录ID
|
||||
* @param userId 当前用户ID
|
||||
* @return 创建的帖子信息
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Map<String, Object> shareCheckinToCommunity(Integer checkinId, Integer userId) {
|
||||
if (ObjectUtil.isNull(checkinId)) {
|
||||
throw new CrmebException("打卡记录ID不能为空");
|
||||
}
|
||||
if (ObjectUtil.isNull(userId)) {
|
||||
throw new CrmebException("用户ID不能为空");
|
||||
}
|
||||
|
||||
// 1. 获取打卡记录详情
|
||||
UserSign sign = userSignDao.selectById(checkinId);
|
||||
if (sign == null) {
|
||||
throw new CrmebException("打卡记录不存在");
|
||||
}
|
||||
|
||||
// 2. 检查打卡记录是否属于当前用户
|
||||
if (!sign.getUid().equals(userId)) {
|
||||
throw new CrmebException("无权分享他人的打卡记录");
|
||||
}
|
||||
|
||||
// 3. 检查是否已分享过(可选:根据需求可以更新或报错)
|
||||
LambdaQueryWrapper<V2CommunityPost> existingQuery = new LambdaQueryWrapper<V2CommunityPost>()
|
||||
.eq(V2CommunityPost::getCheckInRecordId, checkinId)
|
||||
.eq(V2CommunityPost::getUserId, userId.longValue())
|
||||
.orderByDesc(V2CommunityPost::getCreatedAt)
|
||||
.last("LIMIT 1");
|
||||
V2CommunityPost existingPost = v2CommunityPostDao.selectOne(existingQuery);
|
||||
|
||||
if (existingPost != null) {
|
||||
// 已分享过,返回已有的帖子ID
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("postId", existingPost.getPostId());
|
||||
result.put("message", "该打卡记录已分享到社区");
|
||||
return result;
|
||||
}
|
||||
|
||||
// 4. 生成标题
|
||||
String mealTypeLabel = getMealTypeLabel(sign.getMealType());
|
||||
String title = mealTypeLabel + "打卡";
|
||||
|
||||
// 5. 准备营养数据JSON(如果有AI分析结果)
|
||||
String nutritionDataJson = null;
|
||||
if (StrUtil.isNotBlank(sign.getAiRecognizedFoodsJson())) {
|
||||
try {
|
||||
Map<String, Object> nutritionData = new HashMap<>();
|
||||
nutritionData.put("aiRecognizedFoods", sign.getAiRecognizedFoodsJson());
|
||||
nutritionData.put("aiStatus", sign.getAiRecognitionStatus());
|
||||
nutritionData.put("actualProtein", sign.getActualProtein());
|
||||
nutritionData.put("actualEnergy", sign.getActualEnergy());
|
||||
nutritionData.put("nutritionScore", sign.getNutritionScore());
|
||||
nutritionDataJson = com.alibaba.fastjson.JSON.toJSONString(nutritionData);
|
||||
} catch (Exception e) {
|
||||
log.warn("生成营养数据JSON失败: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 6. 解析封面图
|
||||
String coverImage = parseFirstImage(sign.getPhotosJson());
|
||||
|
||||
// 7. 创建社区帖子
|
||||
V2CommunityPost communityPost = new V2CommunityPost();
|
||||
communityPost.setUserId(userId.longValue());
|
||||
communityPost.setCheckInRecordId(checkinId);
|
||||
communityPost.setTitle(title);
|
||||
communityPost.setContent(sign.getNotes());
|
||||
communityPost.setCoverImage(coverImage);
|
||||
communityPost.setImagesJson(sign.getPhotosJson());
|
||||
communityPost.setNutritionDataJson(nutritionDataJson);
|
||||
communityPost.setStatus("published");
|
||||
communityPost.setPrivacy("public");
|
||||
communityPost.setAuditStatus("approved"); // 自动审核通过
|
||||
communityPost.setCreatedAt(new Date());
|
||||
communityPost.setUpdatedAt(new Date());
|
||||
communityPost.setLikeCount(0);
|
||||
communityPost.setCommentCount(0);
|
||||
communityPost.setCollectCount(0);
|
||||
communityPost.setShareCount(0);
|
||||
communityPost.setViewCount(0);
|
||||
communityPost.setQuickCheckinCount(0);
|
||||
communityPost.setAiVideoCount(0);
|
||||
communityPost.setRecommendScore(new BigDecimal("0.00"));
|
||||
communityPost.setHotScore(new BigDecimal("0.00"));
|
||||
|
||||
v2CommunityPostDao.insert(communityPost);
|
||||
|
||||
log.info("分享打卡记录到社区成功,postId: {}, checkinId: {}, userId: {}",
|
||||
communityPost.getPostId(), checkinId, userId);
|
||||
|
||||
// 8. 返回结果
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("postId", communityPost.getPostId());
|
||||
result.put("title", title);
|
||||
result.put("message", "分享成功");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,5 +70,13 @@ public interface ToolCheckinService {
|
||||
* @return 新打卡记录信息
|
||||
*/
|
||||
Map<String, Object> learn(Long sourcePostId, Map<String, Object> data);
|
||||
|
||||
/**
|
||||
* 分享打卡记录到社区
|
||||
* @param checkinId 打卡记录ID
|
||||
* @param userId 当前用户ID
|
||||
* @return 创建的帖子信息
|
||||
*/
|
||||
Map<String, Object> shareCheckinToCommunity(Integer checkinId, Integer userId);
|
||||
}
|
||||
|
||||
|
||||
@@ -177,6 +177,14 @@ export function learnCheckin(sourcePostId, data) {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 分享打卡记录到社区
|
||||
* @param {Number} checkinId - 打卡记录ID
|
||||
*/
|
||||
export function shareCheckinToCommunity(checkinId) {
|
||||
return request.post('tool/checkin/' + checkinId + '/share-to-community');
|
||||
}
|
||||
|
||||
// ==================== 食物百科相关 ====================
|
||||
|
||||
/**
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getCheckinDetail } from '@/api/tool.js';
|
||||
import { getCheckinDetail, shareCheckinToCommunity } from '@/api/tool.js';
|
||||
import { mapGetters } from 'vuex';
|
||||
|
||||
export default {
|
||||
@@ -220,20 +220,52 @@ export default {
|
||||
};
|
||||
return map[type] || '🍽️';
|
||||
},
|
||||
handleCopyCheckin() {
|
||||
// 将数据存储到本地缓存,避免URL参数过长
|
||||
uni.setStorageSync('checkin_copy_data', {
|
||||
images: this.checkinData.images,
|
||||
mealType: this.checkinData.mealType,
|
||||
notes: this.checkinData.notes
|
||||
async handleCopyCheckin() {
|
||||
if (!this.checkinData.id) {
|
||||
uni.showToast({
|
||||
title: '打卡记录ID不存在',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
uni.showLoading({
|
||||
title: '分享中...',
|
||||
mask: true
|
||||
});
|
||||
|
||||
// 跳转到发布页
|
||||
try {
|
||||
const res = await shareCheckinToCommunity(this.checkinData.id);
|
||||
uni.hideLoading();
|
||||
|
||||
if (res && res.code === 200) {
|
||||
const postId = res.data && res.data.postId;
|
||||
uni.showModal({
|
||||
title: '分享成功',
|
||||
content: '您的打卡记录已成功分享到社区',
|
||||
confirmText: '去查看',
|
||||
cancelText: '知道了',
|
||||
success: (modalRes) => {
|
||||
if (modalRes.confirm && postId) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/tool/checkin-publish?mode=copy'
|
||||
url: '/pages/tool/community-detail?id=' + postId
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
throw new Error(res.message || '分享失败');
|
||||
}
|
||||
} catch (e) {
|
||||
uni.hideLoading();
|
||||
console.error('分享到社区失败:', e);
|
||||
uni.showToast({
|
||||
title: e.message || '分享失败,请重试',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user