feat(checkin): P2 一键借鉴打卡功能落地(test-0415 反馈5-2)
最小修改方案,零 DB 表结构变动: 前端 checkin-publish.vue: - onLoad 识别 sourcePostId + sourceType=learn → 调 getCommunityDetail 拉原帖 - 预填 selectedImages / selectedMealType / remark(带「[借鉴自 @xxx]」前缀) - 顶部新增黄色徽章「借鉴自 @xxx」 - handlePublish 提交时透传 sourcePostId 到后端 后端 ToolCheckinServiceImpl.submit: - 检测 data.sourcePostId,若 notes 没有「借鉴自」字样则追加 [借鉴自 post#id] 标记 - 不新增 UserSign 列,引用关系记录在 notes,便于后续查询展示 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -141,6 +141,17 @@ public class ToolCheckinServiceImpl implements ToolCheckinService {
|
||||
if (data.containsKey("notes") && StrUtil.isNotBlank((String) data.get("notes"))) {
|
||||
userSign.setNotes((String) data.get("notes"));
|
||||
}
|
||||
// test-0415 P2 反馈5-2:一键借鉴打卡——若客户端附带 sourcePostId,则在 notes 末尾追加引用标记,
|
||||
// 避免新增 DB 列;同时保证查询/检索时可以通过 notes 正则定位「借鉴自 @xxx」徽章
|
||||
if (data.containsKey("sourcePostId") && ObjectUtil.isNotNull(data.get("sourcePostId"))) {
|
||||
String sourcePostId = data.get("sourcePostId").toString();
|
||||
String existingNotes = userSign.getNotes() == null ? "" : userSign.getNotes();
|
||||
// 如果备注里已经包含「借鉴自」字样(前端已写),不再重复追加;否则补一条标记
|
||||
if (!existingNotes.contains("借鉴自")) {
|
||||
String marker = "[借鉴自 post#" + sourcePostId + "]";
|
||||
userSign.setNotes(StrUtil.isBlank(existingNotes) ? marker : (existingNotes + " " + marker));
|
||||
}
|
||||
}
|
||||
if (data.containsKey("voiceUrl") && StrUtil.isNotBlank((String) data.get("voiceUrl"))) {
|
||||
userSign.setVoiceUrl((String) data.get("voiceUrl"));
|
||||
}
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
<view class="checkin-publish-page">
|
||||
<!-- 内容区域 -->
|
||||
<scroll-view class="content-scroll" scroll-y>
|
||||
<!-- 借鉴打卡徽章(test-0415 P2 反馈5-2) -->
|
||||
<view class="learn-badge" v-if="sourcePostId">
|
||||
<text class="learn-icon">📖</text>
|
||||
<text class="learn-text">借鉴自 {{ sourceAuthorName ? '@' + sourceAuthorName : '社区帖子' }}</text>
|
||||
</view>
|
||||
<!-- 上传照片卡片 -->
|
||||
<view class="card">
|
||||
<view class="card-header">
|
||||
@@ -132,6 +137,9 @@ export default {
|
||||
return {
|
||||
selectedImages: [],
|
||||
selectedMealType: 'breakfast',
|
||||
// test-0415 P2 反馈5-2 借鉴打卡相关
|
||||
sourcePostId: null,
|
||||
sourceAuthorName: '',
|
||||
mealTypes: [
|
||||
{ label: '早餐', value: 'breakfast' },
|
||||
{ label: '午餐', value: 'lunch' },
|
||||
@@ -151,12 +159,12 @@ export default {
|
||||
onLoad(options) {
|
||||
// 初始化录音管理器
|
||||
this.initRecorder();
|
||||
|
||||
|
||||
// 根据参数处理
|
||||
if (options.type === 'video') {
|
||||
this.enableAIVideo = true;
|
||||
}
|
||||
|
||||
|
||||
// 处理一键复制/借鉴打卡
|
||||
if (options.mode === 'copy') {
|
||||
try {
|
||||
@@ -165,10 +173,10 @@ export default {
|
||||
this.selectedImages = copyData.images || [];
|
||||
this.selectedMealType = copyData.mealType || 'breakfast';
|
||||
this.remark = copyData.notes || '';
|
||||
|
||||
|
||||
// 清除缓存
|
||||
uni.removeStorageSync('checkin_copy_data');
|
||||
|
||||
|
||||
uni.showToast({
|
||||
title: '已加载打卡内容',
|
||||
icon: 'success'
|
||||
@@ -178,6 +186,12 @@ export default {
|
||||
console.error('读取复制数据失败:', e);
|
||||
}
|
||||
}
|
||||
|
||||
// test-0415 P2 反馈5-2:一键借鉴打卡——预填来源帖子的图片/餐次/文字
|
||||
if (options.sourcePostId && options.sourceType === 'learn') {
|
||||
this.sourcePostId = options.sourcePostId
|
||||
this.loadSourcePost(options.sourcePostId)
|
||||
}
|
||||
},
|
||||
onUnload() {
|
||||
// 清理录音计时器
|
||||
@@ -556,6 +570,43 @@ export default {
|
||||
}
|
||||
})
|
||||
},
|
||||
// test-0415 P2 反馈5-2:从来源帖子拉取图片/餐次/文字预填表单
|
||||
async loadSourcePost(postId) {
|
||||
try {
|
||||
const { getCommunityDetail } = await import('@/api/tool.js');
|
||||
const res = await getCommunityDetail(postId);
|
||||
const data = (res && res.data) || res || {};
|
||||
// 图片:优先 photosJson;否则 images / image 单图
|
||||
let imgs = [];
|
||||
if (data.photosJson || data.photos_json) {
|
||||
try {
|
||||
const arr = JSON.parse(data.photosJson || data.photos_json);
|
||||
if (Array.isArray(arr)) imgs = arr;
|
||||
} catch (e) { /* ignore */ }
|
||||
}
|
||||
if (imgs.length === 0 && Array.isArray(data.images)) imgs = data.images.slice();
|
||||
if (imgs.length === 0 && data.image) imgs = [data.image];
|
||||
if (imgs.length > 0) this.selectedImages = imgs;
|
||||
|
||||
if (data.mealType) this.selectedMealType = data.mealType;
|
||||
|
||||
const author = data.userName || data.authorName || '';
|
||||
this.sourceAuthorName = author;
|
||||
|
||||
// 备注预填来源帖子的标题/描述/内容
|
||||
const seed = (data.title || data.description || data.content || '').toString().trim();
|
||||
const prefix = author ? `[借鉴自 @${author}] ` : '[借鉴打卡] ';
|
||||
if (seed) {
|
||||
this.remark = prefix + seed;
|
||||
} else {
|
||||
this.remark = prefix.trim();
|
||||
}
|
||||
uni.showToast({ title: '已载入借鉴内容', icon: 'success' });
|
||||
} catch (e) {
|
||||
console.error('加载来源帖子失败', e);
|
||||
uni.showToast({ title: '原帖加载失败,可手动填写', icon: 'none' });
|
||||
}
|
||||
},
|
||||
async handlePublish() {
|
||||
if (this.selectedImages.length === 0) {
|
||||
uni.showToast({
|
||||
@@ -567,20 +618,25 @@ export default {
|
||||
// 防止重复提交
|
||||
if (this._publishing) return
|
||||
this._publishing = true
|
||||
|
||||
|
||||
uni.showLoading({ title: '发布中...' });
|
||||
|
||||
try {
|
||||
const imageUrls = this.selectedImages;
|
||||
const today = new Date().toISOString().split('T')[0];
|
||||
const result = await submitCheckin({
|
||||
const submitData = {
|
||||
mealType: this.selectedMealType,
|
||||
date: today,
|
||||
photosJson: JSON.stringify(imageUrls),
|
||||
notes: this.remark,
|
||||
enableAIVideo: this.enableAIVideo,
|
||||
enableAIAnalysis: false
|
||||
});
|
||||
};
|
||||
// 借鉴打卡:透传 sourcePostId 给后端做引用关系记录
|
||||
if (this.sourcePostId) {
|
||||
submitData.sourcePostId = this.sourcePostId;
|
||||
}
|
||||
const result = await submitCheckin(submitData);
|
||||
|
||||
uni.hideLoading();
|
||||
|
||||
@@ -619,6 +675,20 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 借鉴打卡徽章(test-0415 P2 反馈5-2) */
|
||||
.learn-badge {
|
||||
margin: 16rpx 32rpx 0;
|
||||
padding: 16rpx 24rpx;
|
||||
background: linear-gradient(135deg, #fff8e1 0%, #ffecb3 100%);
|
||||
border-radius: 16rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12rpx;
|
||||
border: 1rpx solid #ffd54f;
|
||||
}
|
||||
.learn-badge .learn-icon { font-size: 28rpx; }
|
||||
.learn-badge .learn-text { font-size: 26rpx; color: #6b5300; flex: 1; }
|
||||
|
||||
.checkin-publish-page {
|
||||
min-height: 100vh;
|
||||
background: #f4f5f7;
|
||||
|
||||
Reference in New Issue
Block a user