Implement greet inbox and outbox

- Add user_greet model and startup table sync
- Implement /greet/user and /greet/delete handlers
- Implement noticeFriendGreeting inbox and noticeUserGreetingHistory outbox
- Return peer profile and center unit info for greeting notices
- Update login topInfo friend greet counters from unread inbox messages

Signed-off-by: Sean Du <do4suki@gmail.com>
This commit is contained in:
2026-06-05 01:54:59 +08:00
parent d48293be44
commit 101f7e8a3f
16 changed files with 641 additions and 15 deletions
+13 -3
View File
@@ -30,13 +30,23 @@ func loginTopInfo(ctx *gin.Context) (res any, err error) {
return nil, err return nil, err
} }
friendGreetCnt64, err := ss.UserEng.Table(new(usermodel.UserGreet)).
Where("receiver_id = ?", ss.UserID).
Where("deleted_from_receiver = ?", false).
Where("readed = ?", false).
Count()
if err != nil {
return nil, err
}
friendsRequestCnt := int(friendsRequestCnt64) friendsRequestCnt := int(friendsRequestCnt64)
friendsApprovalWaitCnt := int(friendsApprovalWaitCnt64) friendsApprovalWaitCnt := int(friendsApprovalWaitCnt64)
friendGreetCnt := int(friendGreetCnt64)
res = loginapischema.TopInfoResp{ res = loginapischema.TopInfoResp{
Result: loginapischema.TopInfoData{ Result: loginapischema.TopInfoData{
FriendActionCnt: 0, FriendActionCnt: friendGreetCnt,
FriendGreetCnt: 0, FriendGreetCnt: friendGreetCnt,
FriendVarietyCnt: 0, FriendVarietyCnt: 0,
FriendNewCnt: friendsRequestCnt + friendsApprovalWaitCnt, FriendNewCnt: friendsRequestCnt + friendsApprovalWaitCnt,
PresentCnt: 0, PresentCnt: 0,
@@ -44,7 +54,7 @@ func loginTopInfo(ctx *gin.Context) (res any, err error) {
ServerDatetime: now.Format("2006-01-02 15:04:05"), ServerDatetime: now.Format("2006-01-02 15:04:05"),
ServerTimestamp: now.Unix(), ServerTimestamp: now.Unix(),
NoticeFriendDatetime: now.Format("2006-01-02 15:04:05"), NoticeFriendDatetime: now.Format("2006-01-02 15:04:05"),
NoticeMailDatetime: "2000-01-01 12:00:00", NoticeMailDatetime: now.Format("2006-01-02 15:04:05"),
FriendsApprovalWaitCnt: friendsApprovalWaitCnt, FriendsApprovalWaitCnt: friendsApprovalWaitCnt,
FriendsRequestCnt: friendsRequestCnt, FriendsRequestCnt: friendsRequestCnt,
IsTodayBirthday: false, IsTodayBirthday: false,
+40
View File
@@ -0,0 +1,40 @@
package greet
import (
"errors"
usermodel "honoka-chan/internal/model/user"
"honoka-chan/internal/session"
"strconv"
)
func resolveGreetingUserID(ss *session.Session, requestedUserID int) (int, error) {
if requestedUserID <= 0 {
return 0, errors.New("invalid user_id")
}
pref := usermodel.UserPref{}
has, err := ss.UserEng.Table(new(usermodel.UserPref)).
Where("invite_code = ?", strconv.Itoa(requestedUserID)).
Cols("user_id").
Get(&pref)
if err != nil {
return 0, err
}
if has && pref.UserID > 0 {
return pref.UserID, nil
}
user := usermodel.Users{}
has, err = ss.UserEng.Table(new(usermodel.Users)).
Where("user_id = ?", requestedUserID).
Cols("user_id").
Get(&user)
if err != nil {
return 0, err
}
if !has || user.UserID <= 0 {
return 0, errors.New("user not found")
}
return user.UserID, nil
}
+66
View File
@@ -0,0 +1,66 @@
package greet
import (
"errors"
"honoka-chan/internal/middleware"
usermodel "honoka-chan/internal/model/user"
"honoka-chan/internal/router"
greetschema "honoka-chan/internal/schema/greet"
"honoka-chan/internal/session"
honokautils "honoka-chan/internal/utils"
"github.com/gin-gonic/gin"
)
func deleteMail(ctx *gin.Context) {
ss := session.Get(ctx)
defer ss.Finalize()
req := greetschema.DeleteReq{}
err := honokautils.ParseRequestData(ctx, &req)
if ss.CheckErr(err) {
return
}
notice := usermodel.UserGreet{}
has, err := ss.UserEng.Table(new(usermodel.UserGreet)).
Where("notice_id = ?", req.MailNoticeID).
Get(&notice)
if ss.CheckErr(err) {
return
}
if !has {
ss.CheckErr(errors.New("notice not found"))
return
}
switch {
case req.IsSendMail && notice.AffectorID == ss.UserID:
_, err = ss.UserEng.Table(new(usermodel.UserGreet)).
Where("notice_id = ?", req.MailNoticeID).
Cols("deleted_from_affector").
Update(&usermodel.UserGreet{DeletedFromAffector: true})
case !req.IsSendMail && notice.ReceiverID == ss.UserID:
_, err = ss.UserEng.Table(new(usermodel.UserGreet)).
Where("notice_id = ?", req.MailNoticeID).
Cols("deleted_from_receiver").
Update(&usermodel.UserGreet{DeletedFromReceiver: true})
default:
ss.CheckErr(errors.New("cannot delete this notice"))
return
}
if ss.CheckErr(err) {
return
}
ss.Respond(greetschema.EmptyResp{
ResponseData: []any{},
ReleaseInfo: []any{},
StatusCode: 200,
})
}
func init() {
router.AddHandler("main.php", "POST", "/greet/delete", middleware.Common, deleteMail)
}
+85
View File
@@ -0,0 +1,85 @@
package greet
import (
"errors"
"strings"
"time"
"honoka-chan/internal/middleware"
usermodel "honoka-chan/internal/model/user"
"honoka-chan/internal/router"
greetschema "honoka-chan/internal/schema/greet"
"honoka-chan/internal/session"
honokautils "honoka-chan/internal/utils"
"github.com/gin-gonic/gin"
)
func user(ctx *gin.Context) {
ss := session.Get(ctx)
defer ss.Finalize()
req := greetschema.UserReq{}
err := honokautils.ParseRequestData(ctx, &req)
if ss.CheckErr(err) {
return
}
message := strings.TrimSpace(req.Message)
if message == "" {
ss.CheckErr(errors.New("message is required"))
return
}
if len([]rune(message)) > 200 {
ss.CheckErr(errors.New("message too long"))
return
}
targetUserID, err := resolveGreetingUserID(ss, req.ToUserID)
if ss.CheckErr(err) {
return
}
if targetUserID == ss.UserID {
ss.CheckErr(errors.New("cannot greet self"))
return
}
replyFlag := false
if req.RepliedNoticeID > 0 {
exists, err := ss.UserEng.Table(new(usermodel.UserGreet)).
Where("notice_id = ?", req.RepliedNoticeID).
Exist()
if ss.CheckErr(err) {
return
}
if !exists {
ss.CheckErr(errors.New("replied notice not found"))
return
}
replyFlag = true
}
_, err = ss.UserEng.Table(new(usermodel.UserGreet)).Insert(&usermodel.UserGreet{
AffectorID: ss.UserID,
ReceiverID: targetUserID,
Message: message,
Reply: replyFlag,
Readed: false,
DeletedFromAffector: false,
DeletedFromReceiver: false,
InsertDate: time.Now().Unix(),
})
if ss.CheckErr(err) {
return
}
ss.Respond(greetschema.EmptyResp{
ResponseData: []any{},
ReleaseInfo: []any{},
StatusCode: 200,
})
}
func init() {
router.AddHandler("main.php", "POST", "/greet/user", middleware.Common, user)
}
+1
View File
@@ -11,6 +11,7 @@ import (
_ "honoka-chan/internal/handler/friend" _ "honoka-chan/internal/handler/friend"
_ "honoka-chan/internal/handler/gdpr" _ "honoka-chan/internal/handler/gdpr"
_ "honoka-chan/internal/handler/ghome" _ "honoka-chan/internal/handler/ghome"
_ "honoka-chan/internal/handler/greet"
_ "honoka-chan/internal/handler/lbonus" _ "honoka-chan/internal/handler/lbonus"
_ "honoka-chan/internal/handler/live" _ "honoka-chan/internal/handler/live"
_ "honoka-chan/internal/handler/login" _ "honoka-chan/internal/handler/login"
+180
View File
@@ -0,0 +1,180 @@
package notice
import (
unitmodel "honoka-chan/internal/model/unit"
usermodel "honoka-chan/internal/model/user"
noticeschema "honoka-chan/internal/schema/notice"
"honoka-chan/internal/session"
"strconv"
"time"
)
type greetingPeerRow struct {
UserID int `xorm:"user_id"`
UserName string `xorm:"user_name"`
UserLevel int `xorm:"user_level"`
AwardID int `xorm:"award_id"`
CenterUnitOwningUserID int `xorm:"center_unit_owning_user_id"`
}
func getGreetingPeer(ss *session.Session, userID int) (noticeschema.GreetingPeer, error) {
row := greetingPeerRow{}
has, err := ss.UserEng.Table(new(usermodel.UserPref)).Alias("up").
Join("LEFT", "user_deck ud", "ud.user_id = up.user_id AND ud.main_flag = 1").
Join("LEFT", "user_deck_unit udu", "udu.user_deck_id = ud.id AND udu.position = 5").
Select(`
up.user_id,
up.user_name,
up.user_level,
up.award_id,
COALESCE(udu.unit_owning_user_id, up.unit_owning_user_id) AS center_unit_owning_user_id
`).
Where("up.user_id = ?", userID).
Get(&row)
if err != nil {
return noticeschema.GreetingPeer{}, err
}
if !has {
return noticeschema.GreetingPeer{}, nil
}
centerUnitInfo, err := buildGreetingCenterUnitInfo(ss, userID, row.CenterUnitOwningUserID, row.AwardID)
if err != nil {
return noticeschema.GreetingPeer{}, err
}
return noticeschema.GreetingPeer{
UserData: noticeschema.GreetingUserData{
UserID: row.UserID,
Name: row.UserName,
Level: row.UserLevel,
},
CenterUnitInfo: centerUnitInfo,
SettingAwardID: row.AwardID,
}, nil
}
func buildGreetingCenterUnitInfo(ss *session.Session, userID, unitOwningUserID, awardID int) (noticeschema.GreetingCenterUnitInfo, error) {
info := noticeschema.GreetingCenterUnitInfo{
SettingAwardID: awardID,
RemovableSkillIds: []int{},
}
if unitOwningUserID <= 0 {
return info, nil
}
unitData := unitmodel.UnitDataMap{}
has, err := ss.GetBasicUnitInfo().
Where("a.user_id = ?", userID).
Where("a.unit_owning_user_id = ?", unitOwningUserID).
Get(&unitData)
if err != nil {
return info, err
}
if !has {
return info, nil
}
accessoryInfo, err := getGreetingAccessoryInfo(ss, userID, unitOwningUserID)
if err != nil {
return info, err
}
removableSkillIDs := []int{}
err = ss.UserEng.Table(new(usermodel.UserUnitSkillEquip)).
Where("user_id = ? AND unit_owning_user_id = ?", userID, unitOwningUserID).
Cols("unit_removable_skill_id").
Find(&removableSkillIDs)
if err != nil {
return info, err
}
return noticeschema.GreetingCenterUnitInfo{
UnitOwningUserID: int64(unitData.UnitOwningUserID),
UnitID: unitData.UnitID,
Exp: unitData.Exp,
NextExp: 0,
Level: unitData.Level,
LevelLimitID: unitData.LevelLimitID,
MaxLevel: unitData.MaxLevel,
Rank: unitData.Rank,
MaxRank: unitData.MaxRank,
Love: unitData.Love,
MaxLove: unitData.MaxLove,
UnitSkillLevel: unitData.UnitSkillLevel,
MaxHp: unitData.MaxHp,
FavoriteFlag: unitData.FavoriteFlag,
DisplayRank: unitData.DisplayRank,
UnitSkillExp: unitData.UnitSkillExp,
UnitRemovableSkillCapacity: unitData.UnitRemovableSkillCapacity,
Attribute: unitData.Attribute,
Smile: unitData.Smile,
Cute: unitData.Cute,
Cool: unitData.Cool,
IsLoveMax: unitData.IsLoveMax,
IsLevelMax: unitData.IsLevelMax,
IsRankMax: unitData.IsRankMax,
IsSigned: unitData.IsSigned,
IsSkillLevelMax: unitData.IsSkillLevelMax,
SettingAwardID: awardID,
RemovableSkillIds: removableSkillIDs,
AccessoryInfo: accessoryInfo,
}, nil
}
func getGreetingAccessoryInfo(ss *session.Session, userID, unitOwningUserID int) (*noticeschema.GreetingAccessoryInfo, error) {
accessoryWear := usermodel.UserAccessoryWear{}
has, err := ss.UserEng.Table(new(usermodel.UserAccessoryWear)).
Where("user_id = ? AND unit_owning_user_id = ?", userID, unitOwningUserID).
Get(&accessoryWear)
if err != nil {
return nil, err
}
if !has || accessoryWear.AccessoryOwningUserID <= 0 {
return nil, nil
}
accessoryData := struct {
AccessoryID int `xorm:"accessory_id"`
Exp int `xorm:"exp"`
}{}
has, err = ss.MainEng.Table("common_accessory_m").
Where("accessory_owning_user_id = ?", accessoryWear.AccessoryOwningUserID).
Cols("accessory_id,exp").
Get(&accessoryData)
if err != nil {
return nil, err
}
if !has {
return nil, nil
}
return &noticeschema.GreetingAccessoryInfo{
AccessoryOwningUserID: accessoryWear.AccessoryOwningUserID,
AccessoryID: accessoryData.AccessoryID,
Exp: accessoryData.Exp,
NextExp: 0,
Level: 8,
MaxLevel: 8,
RankUpCount: 4,
FavoriteFlag: true,
}, nil
}
func formatGreetingElapsedTime(ts int64) string {
if ts <= 0 {
return "刚刚"
}
delta := time.Since(time.Unix(ts, 0))
if delta < time.Minute {
return "刚刚"
}
if delta < time.Hour {
return strconv.Itoa(int(delta.Minutes())) + "分钟前"
}
if delta < 24*time.Hour {
return strconv.Itoa(int(delta.Hours())) + "小时前"
}
return strconv.Itoa(int(delta.Hours())/24) + "天前"
}
+61 -2
View File
@@ -2,9 +2,11 @@ package notice
import ( import (
"honoka-chan/internal/middleware" "honoka-chan/internal/middleware"
usermodel "honoka-chan/internal/model/user"
"honoka-chan/internal/router" "honoka-chan/internal/router"
noticeschema "honoka-chan/internal/schema/notice" noticeschema "honoka-chan/internal/schema/notice"
"honoka-chan/internal/session" "honoka-chan/internal/session"
honokautils "honoka-chan/internal/utils"
"time" "time"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@@ -14,10 +16,67 @@ func friendGreeting(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.Finalize()
req := noticeschema.GreetingNoticeReq{}
err := honokautils.ParseRequestData(ctx, &req)
if ss.CheckErr(err) {
return
}
query := ss.UserEng.Table(new(usermodel.UserGreet)).
Where("receiver_id = ?", ss.UserID).
Where("deleted_from_receiver = ?", false)
if req.NextID > 0 {
query = query.Where("notice_id < ?", req.NextID)
}
rows := []usermodel.UserGreet{}
err = query.
OrderBy("notice_id DESC").
Limit(usermodel.GreetingPageSize).
Find(&rows)
if ss.CheckErr(err) {
return
}
noticeList := make([]noticeschema.FriendGreetingNotice, 0, len(rows))
nextID := 0
for _, row := range rows {
affector, err := getGreetingPeer(ss, row.AffectorID)
if ss.CheckErr(err) {
return
}
noticeList = append(noticeList, noticeschema.FriendGreetingNotice{
NoticeID: row.NoticeID,
NewFlag: true,
ReferenceTable: 6,
Message: row.Message,
ListMessage: row.Message,
Readed: true,
InsertDate: formatGreetingElapsedTime(row.InsertDate),
Affector: affector,
ReplyFlag: row.Reply,
})
nextID = row.NoticeID
}
if len(rows) < usermodel.GreetingPageSize {
nextID = 0
}
_, err = ss.UserEng.Table(new(usermodel.UserGreet)).
Where("receiver_id = ?", ss.UserID).
Where("readed = ?", false).
Cols("readed").
Update(&usermodel.UserGreet{Readed: true})
if ss.CheckErr(err) {
return
}
ss.Respond(noticeschema.FriendGreetingResp{ ss.Respond(noticeschema.FriendGreetingResp{
ResponseData: noticeschema.FriendGreetingData{ ResponseData: noticeschema.FriendGreetingData{
NextId: 0, NextId: nextID,
NoticeList: []any{}, NoticeList: noticeList,
ServerTimestamp: time.Now().Unix(), ServerTimestamp: time.Now().Unix(),
}, },
ReleaseInfo: []any{}, ReleaseInfo: []any{},
+49 -3
View File
@@ -2,9 +2,11 @@ package notice
import ( import (
"honoka-chan/internal/middleware" "honoka-chan/internal/middleware"
usermodel "honoka-chan/internal/model/user"
"honoka-chan/internal/router" "honoka-chan/internal/router"
noticeschema "honoka-chan/internal/schema/notice" noticeschema "honoka-chan/internal/schema/notice"
"honoka-chan/internal/session" "honoka-chan/internal/session"
honokautils "honoka-chan/internal/utils"
"time" "time"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@@ -14,11 +16,55 @@ func userGreetingHistory(ctx *gin.Context) {
ss := session.Get(ctx) ss := session.Get(ctx)
defer ss.Finalize() defer ss.Finalize()
req := noticeschema.GreetingNoticeReq{}
err := honokautils.ParseRequestData(ctx, &req)
if ss.CheckErr(err) {
return
}
totalCount, err := ss.UserEng.Table(new(usermodel.UserGreet)).
Where("affector_id = ?", ss.UserID).
Where("deleted_from_affector = ?", false).
Count()
if ss.CheckErr(err) {
return
}
rows := []usermodel.UserGreet{}
err = ss.UserEng.Table(new(usermodel.UserGreet)).
Where("affector_id = ?", ss.UserID).
Where("deleted_from_affector = ?", false).
OrderBy("notice_id DESC").
Limit(usermodel.GreetingPageSize).
Find(&rows)
if ss.CheckErr(err) {
return
}
noticeList := make([]noticeschema.UserGreetingNotice, 0, len(rows))
for _, row := range rows {
receiver, err := getGreetingPeer(ss, row.ReceiverID)
if ss.CheckErr(err) {
return
}
noticeList = append(noticeList, noticeschema.UserGreetingNotice{
NoticeID: row.NoticeID,
ReferenceTable: 6,
Message: row.Message,
ListMessage: row.Message,
InsertDate: formatGreetingElapsedTime(row.InsertDate),
Receiver: receiver,
ReplyFlag: row.Reply,
Readed: row.Readed,
})
}
ss.Respond(noticeschema.UserGreetingResp{ ss.Respond(noticeschema.UserGreetingResp{
ResponseData: noticeschema.UserGreetingData{ ResponseData: noticeschema.UserGreetingData{
ItemCount: 0, ItemCount: int(totalCount),
HasNext: false, HasNext: totalCount > int64(len(rows)),
NoticeList: []any{}, NoticeList: noticeList,
ServerTimestamp: time.Now().Unix(), ServerTimestamp: time.Now().Unix(),
}, },
ReleaseInfo: []any{}, ReleaseInfo: []any{},
+19
View File
@@ -0,0 +1,19 @@
package usermodel
const GreetingPageSize = 40
type UserGreet struct {
NoticeID int `xorm:"notice_id pk autoincr"`
AffectorID int `xorm:"affector_id index"`
ReceiverID int `xorm:"receiver_id index"`
Message string `xorm:"message text"`
Reply bool `xorm:"reply"`
Readed bool `xorm:"readed"`
DeletedFromAffector bool `xorm:"deleted_from_affector"`
DeletedFromReceiver bool `xorm:"deleted_from_receiver"`
InsertDate int64 `xorm:"insert_date index"`
}
func (UserGreet) TableName() string {
return "user_greet"
}
+7
View File
@@ -0,0 +1,7 @@
package greetschema
type EmptyResp struct {
ResponseData []any `json:"response_data"`
ReleaseInfo []any `json:"release_info"`
StatusCode int `json:"status_code"`
}
+11
View File
@@ -0,0 +1,11 @@
package greetschema
type DeleteReq struct {
Module string `json:"module"`
Action string `json:"action"`
TimeStamp int64 `json:"timeStamp"`
Mgd int `json:"mgd"`
IsSendMail bool `json:"is_send_mail"`
MailNoticeID int `json:"mail_notice_id"`
CommandNum string `json:"commandNum"`
}
+12
View File
@@ -0,0 +1,12 @@
package greetschema
type UserReq struct {
Module string `json:"module"`
Mgd int `json:"mgd"`
Action string `json:"action"`
TimeStamp int64 `json:"timeStamp"`
ToUserID int `json:"to_user_id"`
Message string `json:"message"`
RepliedNoticeID int `json:"replied_notice_id"`
CommandNum string `json:"commandNum"`
}
+66
View File
@@ -0,0 +1,66 @@
package noticeschema
type GreetingNoticeReq struct {
Module string `json:"module"`
Action string `json:"action"`
TimeStamp int64 `json:"timeStamp"`
Mgd int `json:"mgd"`
NextID int `json:"next_id"`
IsPrevious bool `json:"is_previous"`
CommandNum string `json:"commandNum"`
}
type GreetingUserData struct {
UserID int `json:"user_id"`
Name string `json:"name"`
Level int `json:"level"`
}
type GreetingAccessoryInfo struct {
AccessoryOwningUserID int `json:"accessory_owning_user_id"`
AccessoryID int `json:"accessory_id"`
Exp int `json:"exp"`
NextExp int `json:"next_exp"`
Level int `json:"level"`
MaxLevel int `json:"max_level"`
RankUpCount int `json:"rank_up_count"`
FavoriteFlag bool `json:"favorite_flag"`
}
type GreetingCenterUnitInfo struct {
UnitOwningUserID int64 `json:"unit_owning_user_id"`
UnitID int `json:"unit_id"`
Exp int `json:"exp"`
NextExp int `json:"next_exp"`
Level int `json:"level"`
LevelLimitID int `json:"level_limit_id"`
MaxLevel int `json:"max_level"`
Rank int `json:"rank"`
MaxRank int `json:"max_rank"`
Love int `json:"love"`
MaxLove int `json:"max_love"`
UnitSkillLevel int `json:"unit_skill_level"`
MaxHp int `json:"max_hp"`
FavoriteFlag bool `json:"favorite_flag"`
DisplayRank int `json:"display_rank"`
UnitSkillExp int `json:"unit_skill_exp"`
UnitRemovableSkillCapacity int `json:"unit_removable_skill_capacity"`
Attribute int `json:"attribute"`
Smile int `json:"smile"`
Cute int `json:"cute"`
Cool int `json:"cool"`
IsLoveMax bool `json:"is_love_max"`
IsLevelMax bool `json:"is_level_max"`
IsRankMax bool `json:"is_rank_max"`
IsSigned bool `json:"is_signed"`
IsSkillLevelMax bool `json:"is_skill_level_max"`
SettingAwardID int `json:"setting_award_id"`
RemovableSkillIds []int `json:"removable_skill_ids"`
AccessoryInfo *GreetingAccessoryInfo `json:"accessory_info,omitempty"`
}
type GreetingPeer struct {
UserData GreetingUserData `json:"user_data"`
CenterUnitInfo GreetingCenterUnitInfo `json:"center_unit_info"`
SettingAwardID int `json:"setting_award_id"`
}
+13 -1
View File
@@ -2,10 +2,22 @@ package noticeschema
type FriendGreetingData struct { type FriendGreetingData struct {
NextId int `json:"next_id"` NextId int `json:"next_id"`
NoticeList []any `json:"notice_list"` NoticeList []FriendGreetingNotice `json:"notice_list"`
ServerTimestamp int64 `json:"server_timestamp"` ServerTimestamp int64 `json:"server_timestamp"`
} }
type FriendGreetingNotice struct {
NoticeID int `json:"notice_id"`
NewFlag bool `json:"new_flag"`
ReferenceTable int `json:"reference_table"`
Message string `json:"message"`
ListMessage string `json:"list_message"`
Readed bool `json:"readed"`
InsertDate string `json:"insert_date"`
Affector GreetingPeer `json:"affector"`
ReplyFlag bool `json:"reply_flag"`
}
type FriendGreetingResp struct { type FriendGreetingResp struct {
ResponseData FriendGreetingData `json:"response_data"` ResponseData FriendGreetingData `json:"response_data"`
ReleaseInfo []any `json:"release_info"` ReleaseInfo []any `json:"release_info"`
+12 -1
View File
@@ -3,10 +3,21 @@ package noticeschema
type UserGreetingData struct { type UserGreetingData struct {
ItemCount int `json:"item_count"` ItemCount int `json:"item_count"`
HasNext bool `json:"has_next"` HasNext bool `json:"has_next"`
NoticeList []any `json:"notice_list"` NoticeList []UserGreetingNotice `json:"notice_list"`
ServerTimestamp int64 `json:"server_timestamp"` ServerTimestamp int64 `json:"server_timestamp"`
} }
type UserGreetingNotice struct {
NoticeID int `json:"notice_id"`
ReferenceTable int `json:"reference_table"`
Message string `json:"message"`
ListMessage string `json:"list_message"`
InsertDate string `json:"insert_date"`
Receiver GreetingPeer `json:"receiver"`
ReplyFlag bool `json:"reply_flag"`
Readed bool `json:"readed"`
}
type UserGreetingResp struct { type UserGreetingResp struct {
ResponseData UserGreetingData `json:"response_data"` ResponseData UserGreetingData `json:"response_data"`
ReleaseInfo []any `json:"release_info"` ReleaseInfo []any `json:"release_info"`
+1
View File
@@ -28,6 +28,7 @@ func CreateTables() {
db.UserEng.Sync2(new(usermodel.UserLiveInProgress)) db.UserEng.Sync2(new(usermodel.UserLiveInProgress))
db.UserEng.Sync2(new(usermodel.UserLiveRecord)) db.UserEng.Sync2(new(usermodel.UserLiveRecord))
db.UserEng.Sync2(new(usermodel.UserFriend)) db.UserEng.Sync2(new(usermodel.UserFriend))
db.UserEng.Sync2(new(usermodel.UserGreet))
db.UserEng.Sync2(new(usermodel.UserPref)) db.UserEng.Sync2(new(usermodel.UserPref))
db.UserEng.Sync2(new(usermodel.Users)) db.UserEng.Sync2(new(usermodel.Users))
db.UserEng.Sync2(new(usermodel.UserUnit)) db.UserEng.Sync2(new(usermodel.UserUnit))