From 4b8b3916747e50528b8732b4650426093e67e07f Mon Sep 17 00:00:00 2001 From: msh-agent Date: Sun, 3 May 2026 03:34:28 +0800 Subject: [PATCH] =?UTF-8?q?feat(checkin):=20P2=20=E4=B8=80=E9=94=AE?= =?UTF-8?q?=E5=80=9F=E9=89=B4=E6=89=93=E5=8D=A1=E5=8A=9F=E8=83=BD=E8=90=BD?= =?UTF-8?q?=E5=9C=B0=EF=BC=88test-0415=20=E5=8F=8D=E9=A6=885-2=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 最小修改方案,零 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) --- .../impl/tool/ToolCheckinServiceImpl.java | 11 +++ .../pages/tool/checkin-publish.vue | 84 +++++++++++++++++-- 2 files changed, 88 insertions(+), 7 deletions(-) diff --git a/msh_crmeb_22/crmeb-service/src/main/java/com/zbkj/service/service/impl/tool/ToolCheckinServiceImpl.java b/msh_crmeb_22/crmeb-service/src/main/java/com/zbkj/service/service/impl/tool/ToolCheckinServiceImpl.java index e0196dc..3fec191 100644 --- a/msh_crmeb_22/crmeb-service/src/main/java/com/zbkj/service/service/impl/tool/ToolCheckinServiceImpl.java +++ b/msh_crmeb_22/crmeb-service/src/main/java/com/zbkj/service/service/impl/tool/ToolCheckinServiceImpl.java @@ -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")); } diff --git a/msh_single_uniapp/pages/tool/checkin-publish.vue b/msh_single_uniapp/pages/tool/checkin-publish.vue index 735fc5f..c2387d4 100644 --- a/msh_single_uniapp/pages/tool/checkin-publish.vue +++ b/msh_single_uniapp/pages/tool/checkin-publish.vue @@ -2,6 +2,11 @@ + + + 📖 + 借鉴自 {{ sourceAuthorName ? '@' + sourceAuthorName : '社区帖子' }} + @@ -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 {