按桌面past-go原样同步首页样式与后端通知逻辑

This commit is contained in:
2026-10-11 09:16:38 +08:00
parent 4e751410b3
commit 5365e13963
6 changed files with 69 additions and 9 deletions
+16
View File
@@ -271,6 +271,14 @@ func respondInvitation(c *httpapi.Ctx) error {
return err return err
} }
createDefaultAlbums(c.DB, coupleID, uid) 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)}) 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) 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 return err
} }
createDefaultAlbums(c.DB, coupleID, uid) 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"]}) return c.OK(M{"success": true, "couple_id": fmt.Sprint(coupleID), "partner_nickname": inviter["nickname"]})
} }
+19 -1
View File
@@ -284,7 +284,8 @@ func diaryCommentAdd(c *httpapi.Ctx) error {
if err := checkTextOr400(c, content); err != nil { if err := checkTextOr400(c, content); err != nil {
return err 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, "日记不存在") return c.Err(404, "日记不存在")
} }
parentID := c.InInt("parent_id") parentID := c.InInt("parent_id")
@@ -303,6 +304,23 @@ func diaryCommentAdd(c *httpapi.Ctx) error {
comment["avatar_url"] = avatarURL(comment.Str("avatar")) comment["avatar_url"] = avatarURL(comment.Str("avatar"))
out = comment 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}) return c.OK(M{"success": true, "comment": out})
} }
+22
View File
@@ -10,6 +10,7 @@ import (
"unicode/utf8" "unicode/utf8"
"past/internal/httpapi" "past/internal/httpapi"
"past/internal/store"
) )
func guardSmokingCheckin(c *httpapi.Ctx, id int64) error { func guardSmokingCheckin(c *httpapi.Ctx, id int64) error {
@@ -222,6 +223,27 @@ func smokingAction(c *httpapi.Ctx) error {
if err != nil { if err != nil {
return err 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}) return c.OK(M{"success": true, "info": info})
} }
func nullableID(id int64) any { func nullableID(id int64) any {
+5 -2
View File
@@ -20,6 +20,7 @@ const (
var actionTypes = []string{ var actionTypes = []string{
"login", "timeline_create", "album_create", "photo_upload", "diary_create", "diary_comment_add", "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", "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{ var actionLabels = map[string]string{
@@ -27,6 +28,7 @@ var actionLabels = map[string]string{
"diary_create": "写了新的日记", "diary_comment_add": "评论了日记", "song_add": "添加了新歌曲", "checkin_do": "完成了打卡", "diary_create": "写了新的日记", "diary_comment_add": "评论了日记", "song_add": "添加了新歌曲", "checkin_do": "完成了打卡",
"period_add": "记录了姨妈期", "period_sex_add": "记录了亲密时光", "pet_adopt": "领养了新宠物", "pet_daily": "照顾了宠物", "period_add": "记录了姨妈期", "period_sex_add": "记录了亲密时光", "pet_adopt": "领养了新宠物", "pet_daily": "照顾了宠物",
"pet_rename": "给宠物改了名", "pet_all_done": "完成了所有宠物任务", "pet_rename": "给宠物改了名", "pet_all_done": "完成了所有宠物任务",
"couple_bind": "同意了你的邀请", "smoking_consume": "记录了抽烟",
} }
var pageMap = map[string]string{ 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", "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", "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", "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 { func mbSub(s string, n int) string {
@@ -70,9 +73,9 @@ func Once(db *store.DB, wx *wechat.Client, force bool) {
} }
var sql string var sql string
if force { 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 { } 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")) args = append(args, time.Now().Add(-scanMinutes*time.Minute).Format("2006-01-02 15:04:05"))
} }
activities, err := db.Query(sql, args...) activities, err := db.Query(sql, args...)
+4 -3
View File
@@ -260,9 +260,10 @@ func (c *Client) SendSubscribeMessage(toUserID int64, templateType string, data
c.clearTokenCache() c.clearTokenCache()
continue continue
} }
// 43101 可能是「一次性订阅额度已用尽」,并非用户主动关闭订阅; // 43101 表示用户拒收或一次性订阅额度已用尽,40003 表示 openid 无效;
// 此时删除记录会导致前端设置页显示为未勾选,误导用户。仅在 openid 无效(40003)时清理。 // 这两种情况下订阅记录已失效,删除记录让前端设置页显示「未订阅」,
if ec == 40003 { // 引导用户重新授权,避免出现「显示已订阅却收不到」的假象。
if ec == 40003 || ec == 43101 {
db.Exec("DELETE FROM subscribe_templates WHERE user_id = ? AND template_type = ?", toUserID, templateType) db.Exec("DELETE FROM subscribe_templates WHERE user_id = ? AND template_type = ?", toUserID, templateType)
} }
break break
+3 -3
View File
@@ -25,11 +25,11 @@
.home-couple-avatars .j-avatar { width:64rpx; height:64rpx; } .home-couple-avatars .j-avatar { width:64rpx; height:64rpx; }
.home-couple-avatars .j-avatar-partner { margin-left:-16rpx; } .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-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-couple-locations { margin-top:22rpx; }
.home-location-row { display:flex; flex:1; min-width:0; align-items:center; gap:10rpx; } .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-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-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-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; } .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; }