diff --git a/internal/handler/api/login/topinfo.go b/internal/handler/api/login/topinfo.go index b859655..95dc717 100644 --- a/internal/handler/api/login/topinfo.go +++ b/internal/handler/api/login/topinfo.go @@ -30,13 +30,23 @@ func loginTopInfo(ctx *gin.Context) (res any, err error) { 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) friendsApprovalWaitCnt := int(friendsApprovalWaitCnt64) + friendGreetCnt := int(friendGreetCnt64) res = loginapischema.TopInfoResp{ Result: loginapischema.TopInfoData{ - FriendActionCnt: 0, - FriendGreetCnt: 0, + FriendActionCnt: friendGreetCnt, + FriendGreetCnt: friendGreetCnt, FriendVarietyCnt: 0, FriendNewCnt: friendsRequestCnt + friendsApprovalWaitCnt, PresentCnt: 0, @@ -44,7 +54,7 @@ func loginTopInfo(ctx *gin.Context) (res any, err error) { ServerDatetime: now.Format("2006-01-02 15:04:05"), ServerTimestamp: now.Unix(), 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, FriendsRequestCnt: friendsRequestCnt, IsTodayBirthday: false, diff --git a/internal/handler/greet/common.go b/internal/handler/greet/common.go new file mode 100644 index 0000000..bb6d8af --- /dev/null +++ b/internal/handler/greet/common.go @@ -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 +} diff --git a/internal/handler/greet/delete.go b/internal/handler/greet/delete.go new file mode 100644 index 0000000..63f1628 --- /dev/null +++ b/internal/handler/greet/delete.go @@ -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(¬ice) + 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) +} diff --git a/internal/handler/greet/user.go b/internal/handler/greet/user.go new file mode 100644 index 0000000..bbc29f2 --- /dev/null +++ b/internal/handler/greet/user.go @@ -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) +} diff --git a/internal/handler/handler.go b/internal/handler/handler.go index e77ab71..022c299 100644 --- a/internal/handler/handler.go +++ b/internal/handler/handler.go @@ -11,6 +11,7 @@ import ( _ "honoka-chan/internal/handler/friend" _ "honoka-chan/internal/handler/gdpr" _ "honoka-chan/internal/handler/ghome" + _ "honoka-chan/internal/handler/greet" _ "honoka-chan/internal/handler/lbonus" _ "honoka-chan/internal/handler/live" _ "honoka-chan/internal/handler/login" diff --git a/internal/handler/notice/common.go b/internal/handler/notice/common.go new file mode 100644 index 0000000..3f50b8e --- /dev/null +++ b/internal/handler/notice/common.go @@ -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 ¬iceschema.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) + "天前" +} diff --git a/internal/handler/notice/friendgreeting.go b/internal/handler/notice/friendgreeting.go index 48d3be3..cc64b2e 100644 --- a/internal/handler/notice/friendgreeting.go +++ b/internal/handler/notice/friendgreeting.go @@ -2,9 +2,11 @@ package notice import ( "honoka-chan/internal/middleware" + usermodel "honoka-chan/internal/model/user" "honoka-chan/internal/router" noticeschema "honoka-chan/internal/schema/notice" "honoka-chan/internal/session" + honokautils "honoka-chan/internal/utils" "time" "github.com/gin-gonic/gin" @@ -14,10 +16,67 @@ func friendGreeting(ctx *gin.Context) { ss := session.Get(ctx) 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{ ResponseData: noticeschema.FriendGreetingData{ - NextId: 0, - NoticeList: []any{}, + NextId: nextID, + NoticeList: noticeList, ServerTimestamp: time.Now().Unix(), }, ReleaseInfo: []any{}, diff --git a/internal/handler/notice/usergreetinghistory.go b/internal/handler/notice/usergreetinghistory.go index cfea2c9..00e1709 100644 --- a/internal/handler/notice/usergreetinghistory.go +++ b/internal/handler/notice/usergreetinghistory.go @@ -2,9 +2,11 @@ package notice import ( "honoka-chan/internal/middleware" + usermodel "honoka-chan/internal/model/user" "honoka-chan/internal/router" noticeschema "honoka-chan/internal/schema/notice" "honoka-chan/internal/session" + honokautils "honoka-chan/internal/utils" "time" "github.com/gin-gonic/gin" @@ -14,11 +16,55 @@ func userGreetingHistory(ctx *gin.Context) { ss := session.Get(ctx) 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{ ResponseData: noticeschema.UserGreetingData{ - ItemCount: 0, - HasNext: false, - NoticeList: []any{}, + ItemCount: int(totalCount), + HasNext: totalCount > int64(len(rows)), + NoticeList: noticeList, ServerTimestamp: time.Now().Unix(), }, ReleaseInfo: []any{}, diff --git a/internal/model/user/usergreet.go b/internal/model/user/usergreet.go new file mode 100644 index 0000000..f95630a --- /dev/null +++ b/internal/model/user/usergreet.go @@ -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" +} diff --git a/internal/schema/greet/common.go b/internal/schema/greet/common.go new file mode 100644 index 0000000..6a98fc6 --- /dev/null +++ b/internal/schema/greet/common.go @@ -0,0 +1,7 @@ +package greetschema + +type EmptyResp struct { + ResponseData []any `json:"response_data"` + ReleaseInfo []any `json:"release_info"` + StatusCode int `json:"status_code"` +} diff --git a/internal/schema/greet/delete.go b/internal/schema/greet/delete.go new file mode 100644 index 0000000..c2b012f --- /dev/null +++ b/internal/schema/greet/delete.go @@ -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"` +} diff --git a/internal/schema/greet/user.go b/internal/schema/greet/user.go new file mode 100644 index 0000000..4910f87 --- /dev/null +++ b/internal/schema/greet/user.go @@ -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"` +} diff --git a/internal/schema/notice/common.go b/internal/schema/notice/common.go new file mode 100644 index 0000000..cf9bdde --- /dev/null +++ b/internal/schema/notice/common.go @@ -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"` +} diff --git a/internal/schema/notice/friendgreeting.go b/internal/schema/notice/friendgreeting.go index 8ce117f..9348182 100644 --- a/internal/schema/notice/friendgreeting.go +++ b/internal/schema/notice/friendgreeting.go @@ -1,9 +1,21 @@ package noticeschema type FriendGreetingData struct { - NextId int `json:"next_id"` - NoticeList []any `json:"notice_list"` - ServerTimestamp int64 `json:"server_timestamp"` + NextId int `json:"next_id"` + NoticeList []FriendGreetingNotice `json:"notice_list"` + 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 { diff --git a/internal/schema/notice/usergreetinghistory.go b/internal/schema/notice/usergreetinghistory.go index c84d9ab..dbc6c9f 100644 --- a/internal/schema/notice/usergreetinghistory.go +++ b/internal/schema/notice/usergreetinghistory.go @@ -1,10 +1,21 @@ package noticeschema type UserGreetingData struct { - ItemCount int `json:"item_count"` - HasNext bool `json:"has_next"` - NoticeList []any `json:"notice_list"` - ServerTimestamp int64 `json:"server_timestamp"` + ItemCount int `json:"item_count"` + HasNext bool `json:"has_next"` + NoticeList []UserGreetingNotice `json:"notice_list"` + 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 { diff --git a/internal/startup/database.go b/internal/startup/database.go index 3a22078..72b3127 100644 --- a/internal/startup/database.go +++ b/internal/startup/database.go @@ -28,6 +28,7 @@ func CreateTables() { db.UserEng.Sync2(new(usermodel.UserLiveInProgress)) db.UserEng.Sync2(new(usermodel.UserLiveRecord)) db.UserEng.Sync2(new(usermodel.UserFriend)) + db.UserEng.Sync2(new(usermodel.UserGreet)) db.UserEng.Sync2(new(usermodel.UserPref)) db.UserEng.Sync2(new(usermodel.Users)) db.UserEng.Sync2(new(usermodel.UserUnit))