From 5365e1396379ff61989a0c0a557c780672f3daee Mon Sep 17 00:00:00 2001 From: Blizzard Date: Sun, 11 Oct 2026 09:16:38 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8C=89=E6=A1=8C=E9=9D=A2past-go=E5=8E=9F?= =?UTF-8?q?=E6=A0=B7=E5=90=8C=E6=AD=A5=E9=A6=96=E9=A1=B5=E6=A0=B7=E5=BC=8F?= =?UTF-8?q?=E4=B8=8E=E5=90=8E=E7=AB=AF=E9=80=9A=E7=9F=A5=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- past-go/internal/handler/couple.go | 16 ++++++++++++++++ past-go/internal/handler/diary.go | 20 +++++++++++++++++++- past-go/internal/handler/smoking.go | 22 ++++++++++++++++++++++ past-go/internal/notify/notify.go | 7 +++++-- past-go/internal/wechat/wechat.go | 7 ++++--- weapp/pages/index/index.wxss | 6 +++--- 6 files changed, 69 insertions(+), 9 deletions(-) diff --git a/past-go/internal/handler/couple.go b/past-go/internal/handler/couple.go index aa14587..5825370 100644 --- a/past-go/internal/handler/couple.go +++ b/past-go/internal/handler/couple.go @@ -271,6 +271,14 @@ func respondInvitation(c *httpapi.Ctx) error { return err } createDefaultAlbums(c.DB, coupleID, uid) + // 通知邀请人:对方已同意 + actID := logActivity(c.DB, coupleID, uid, "couple_bind", "你们已成功绑定为情侣", "") + c.App.Wechat.SendSubscribeMessage(fromID, "notify", map[string]string{ + "thing1": "我们在一起啦 💕", + "thing2": "TA 已同意你的邀请", + "date3": today(), + "thing4": "点击开始记录", + }, "pages/index/index", actID, uid) return c.OK(M{"success": true, "couple_id": fmt.Sprint(coupleID)}) } c.DB.Exec("UPDATE invitations SET status = 'rejected', responded_at = CURRENT_TIMESTAMP WHERE id = ?", invID) @@ -319,6 +327,14 @@ func acceptShareInvite(c *httpapi.Ctx) error { return err } createDefaultAlbums(c.DB, coupleID, uid) + // 通知邀请人:对方已接受分享邀请 + actID := logActivity(c.DB, coupleID, uid, "couple_bind", "你们已成功绑定为情侣", "") + c.App.Wechat.SendSubscribeMessage(inviterID, "notify", map[string]string{ + "thing1": "我们在一起啦 💕", + "thing2": "TA 已接受你的分享邀请", + "date3": today(), + "thing4": "点击开始记录", + }, "pages/index/index", actID, uid) return c.OK(M{"success": true, "couple_id": fmt.Sprint(coupleID), "partner_nickname": inviter["nickname"]}) } diff --git a/past-go/internal/handler/diary.go b/past-go/internal/handler/diary.go index 58615f1..692a9c1 100644 --- a/past-go/internal/handler/diary.go +++ b/past-go/internal/handler/diary.go @@ -284,7 +284,8 @@ func diaryCommentAdd(c *httpapi.Ctx) error { if err := checkTextOr400(c, content); err != nil { return err } - if d, _ := c.DB.QueryOne("SELECT id FROM diaries WHERE id = ? AND couple_id = ?", diaryID, cid); d == nil { + diary, _ := c.DB.QueryOne("SELECT id, created_by FROM diaries WHERE id = ? AND couple_id = ?", diaryID, cid) + if diary == nil { return c.Err(404, "日记不存在") } parentID := c.InInt("parent_id") @@ -303,6 +304,23 @@ func diaryCommentAdd(c *httpapi.Ctx) error { comment["avatar_url"] = avatarURL(comment.Str("avatar")) out = comment } + // 通知对象:优先被回复的人,否则日记作者;自己评论自己不通知 + var notifyTo int64 + if replyToUserID != nil { + notifyTo = store.ToInt(replyToUserID) + } + if notifyTo == 0 { + notifyTo = diary.Int("created_by") + } + if notifyTo != 0 && notifyTo != uid { + actID := logActivity(c.DB, cid, uid, "diary_comment_add", "评论了你的日记", "") + c.App.Wechat.SendSubscribeMessage(notifyTo, "notify", map[string]string{ + "thing1": "日记有新评论 💬", + "thing2": mbTruncate("TA评论了你:"+content, 20), + "date3": today(), + "thing4": "点击查看详情", + }, "pages/diary/diary", actID, uid) + } return c.OK(M{"success": true, "comment": out}) } diff --git a/past-go/internal/handler/smoking.go b/past-go/internal/handler/smoking.go index 2303e5d..0e0decf 100644 --- a/past-go/internal/handler/smoking.go +++ b/past-go/internal/handler/smoking.go @@ -10,6 +10,7 @@ import ( "unicode/utf8" "past/internal/httpapi" + "past/internal/store" ) func guardSmokingCheckin(c *httpapi.Ctx, id int64) error { @@ -222,6 +223,27 @@ func smokingAction(c *httpapi.Ctx) error { if err != nil { return err } + // 仅记录抽烟/消耗类动作时通知伴侣(撤销、补库存不打扰) + var smokeDesc string + switch kind { + case "consume": + smokeDesc = "TA 记录抽了一支烟" + case "give": + smokeDesc = "TA 递出了一支烟" + case "receive_smoke": + smokeDesc = "TA 记录收到一支烟" + } + if smokeDesc != "" { + if partnerID := partnerUserId(c.DB, uid); partnerID != 0 { + actID := logActivity(c.DB, c.CoupleID(), uid, "smoking_consume", smokeDesc, "") + c.App.Wechat.SendSubscribeMessage(partnerID, "notify", map[string]string{ + "thing1": "戒烟打卡", + "thing2": fmt.Sprintf("%s,今日已 %d 支", smokeDesc, store.ToInt(info["today_count"])), + "date3": today(), + "thing4": "点击查看详情", + }, "pages/punch/punch", actID, uid) + } + } return c.OK(M{"success": true, "info": info}) } func nullableID(id int64) any { diff --git a/past-go/internal/notify/notify.go b/past-go/internal/notify/notify.go index 2e5e6e5..eedb9c6 100644 --- a/past-go/internal/notify/notify.go +++ b/past-go/internal/notify/notify.go @@ -20,6 +20,7 @@ const ( var actionTypes = []string{ "login", "timeline_create", "album_create", "photo_upload", "diary_create", "diary_comment_add", "song_add", "checkin_do", "period_add", "period_sex_add", "pet_adopt", "pet_daily", "pet_rename", "pet_all_done", + "couple_bind", "smoking_consume", } var actionLabels = map[string]string{ @@ -27,6 +28,7 @@ var actionLabels = map[string]string{ "diary_create": "写了新的日记", "diary_comment_add": "评论了日记", "song_add": "添加了新歌曲", "checkin_do": "完成了打卡", "period_add": "记录了姨妈期", "period_sex_add": "记录了亲密时光", "pet_adopt": "领养了新宠物", "pet_daily": "照顾了宠物", "pet_rename": "给宠物改了名", "pet_all_done": "完成了所有宠物任务", + "couple_bind": "同意了你的邀请", "smoking_consume": "记录了抽烟", } var pageMap = map[string]string{ @@ -35,6 +37,7 @@ var pageMap = map[string]string{ "song_add": "pages/lovewords/lovewords", "checkin_do": "pages/punch/punch", "period_add": "pages/period/period", "period_sex_add": "pages/period/period", "pet_adopt": "pages/pet/pet", "pet_daily": "pages/pet/pet", "pet_rename": "pages/pet/pet", "pet_all_done": "pages/pet/pet", + "couple_bind": "pages/index/index", "smoking_consume": "pages/punch/punch", } func mbSub(s string, n int) string { @@ -70,9 +73,9 @@ func Once(db *store.DB, wx *wechat.Client, force bool) { } var sql string if force { - sql = "SELECT a.*, u.nickname, u.couple_id as user_couple_id FROM activity_log a JOIN users u ON a.user_id = u.id WHERE a.action_type IN (" + ph + ") AND a.id NOT IN (SELECT nl.activity_id FROM notify_log nl WHERE nl.status = 'success') AND a.couple_id IS NOT NULL ORDER BY a.created_at DESC LIMIT 20" + sql = "SELECT a.*, u.nickname, u.couple_id as user_couple_id FROM activity_log a JOIN users u ON a.user_id = u.id WHERE a.action_type IN (" + ph + ") AND a.id NOT IN (SELECT nl.activity_id FROM notify_log nl) AND a.couple_id IS NOT NULL ORDER BY a.created_at DESC LIMIT 20" } else { - sql = "SELECT a.*, u.nickname, u.couple_id as user_couple_id FROM activity_log a JOIN users u ON a.user_id = u.id WHERE a.action_type IN (" + ph + ") AND a.created_at >= ? AND a.id NOT IN (SELECT nl.activity_id FROM notify_log nl WHERE nl.status = 'success') AND a.couple_id IS NOT NULL ORDER BY a.created_at DESC LIMIT 20" + sql = "SELECT a.*, u.nickname, u.couple_id as user_couple_id FROM activity_log a JOIN users u ON a.user_id = u.id WHERE a.action_type IN (" + ph + ") AND a.created_at >= ? AND a.id NOT IN (SELECT nl.activity_id FROM notify_log nl) AND a.couple_id IS NOT NULL ORDER BY a.created_at DESC LIMIT 20" args = append(args, time.Now().Add(-scanMinutes*time.Minute).Format("2006-01-02 15:04:05")) } activities, err := db.Query(sql, args...) diff --git a/past-go/internal/wechat/wechat.go b/past-go/internal/wechat/wechat.go index 2442c79..cbb537b 100644 --- a/past-go/internal/wechat/wechat.go +++ b/past-go/internal/wechat/wechat.go @@ -260,9 +260,10 @@ func (c *Client) SendSubscribeMessage(toUserID int64, templateType string, data c.clearTokenCache() continue } - // 43101 可能是「一次性订阅额度已用尽」,并非用户主动关闭订阅; - // 此时删除记录会导致前端设置页显示为未勾选,误导用户。仅在 openid 无效(40003)时清理。 - if ec == 40003 { + // 43101 表示用户拒收或一次性订阅额度已用尽,40003 表示 openid 无效; + // 这两种情况下订阅记录已失效,删除记录让前端设置页显示「未订阅」, + // 引导用户重新授权,避免出现「显示已订阅却收不到」的假象。 + if ec == 40003 || ec == 43101 { db.Exec("DELETE FROM subscribe_templates WHERE user_id = ? AND template_type = ?", toUserID, templateType) } break diff --git a/weapp/pages/index/index.wxss b/weapp/pages/index/index.wxss index 254bc03..2afc3d0 100644 --- a/weapp/pages/index/index.wxss +++ b/weapp/pages/index/index.wxss @@ -25,11 +25,11 @@ .home-couple-avatars .j-avatar { width:64rpx; height:64rpx; } .home-couple-avatars .j-avatar-partner { margin-left:-16rpx; } .home-couple-names { flex:1; min-width:0; font-size:26rpx; line-height:1.5; color:#64424D; overflow-wrap:break-word; } -.home-couple-locations { display:flex; align-items:center; gap:18rpx; margin-top:22rpx; } -.home-location-row { display:flex; flex:1; min-width:0; align-items:center; gap:10rpx; } +.home-couple-locations { margin-top:22rpx; } +.home-location-row { display:flex; align-items:flex-start; gap:14rpx; margin-top:12rpx; } .home-location-label { flex-shrink:0; width:42rpx; padding:3rpx 0; border-radius:10rpx; text-align:center; font-size:19rpx; line-height:1.5; color:#B74768; background:#F8E6ED; } .home-location-partner { color:#526B57; background:#E4EBE3; } -.home-location-text { flex:1; min-width:0; padding-top:2rpx; font-size:23rpx; line-height:1.6; color:#85776D; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; } +.home-location-text { flex:1; min-width:0; padding-top:2rpx; font-size:23rpx; line-height:1.6; color:#85776D; overflow-wrap:break-word; word-break:break-all; } .home-distance-pill { display:inline-block; flex-shrink:0; white-space:nowrap; padding:8rpx 14rpx; border-radius:24rpx; background:#FBE4ED; color:#B74768; font-size:22rpx; line-height:1.5; } .home-birthday-row { display:flex; flex-wrap:wrap; align-items:center; gap:8rpx 28rpx; margin-top:18rpx; color:#A65A73; font-size:22rpx; line-height:1.6; }