This commit is contained in:
oneao committed 2025-12-05 17:28:46 +08:00
1 parent 33ab76f73e
commit 3af982d669
31 files changed
+632 -316

No files matched your search

@@ -39,20 +39,75 @@ func QueryMoneyRecord(ctx context.Context, c *app.RequestContext) {
}
endTime := startTime.AddDate(0, 1, 0).Add(-time.Nanosecond)
// 获取 userID
// 获取 userID 和 spaceID
userID := middleware.GetUserID(ctx)
spaceID, ok := middleware.GetSpaceID(ctx)
// 查询记录
params := repo.FindUserMoneyRecordsParams{
UserID: userID,
RecordTime: pgtype.Timestamp{Time: startTime, Valid: true},
RecordTime_2: pgtype.Timestamp{Time: endTime, Valid: true},
}
// 定义统一的 records 切片
var dbRecordsUser []repo.FindUserMoneyRecordsRow
var dbRecordsSpace []repo.FindMoneyRecordsBySpaceRow
var errQuery error
records, err := db.Queries.FindUserMoneyRecords(ctx, params)
if err != nil {
errorx.AddError(c, err)
return
// 最终返回统一类型
var records []*money.MoneyRecordItem
if ok { // 有空间ID,查询空间内所有用户
params := repo.FindMoneyRecordsBySpaceParams{
SpaceID: spaceID,
RecordTime: pgtype.Timestamp{Time: startTime, Valid: true},
RecordTime_2: pgtype.Timestamp{Time: endTime, Valid: true},
}
dbRecordsSpace, errQuery = db.Queries.FindMoneyRecordsBySpace(ctx, params)
if errQuery != nil {
errorx.AddError(c, errQuery)
return
}
for _, r := range dbRecordsSpace {
records = append(records, &money.MoneyRecordItem{
Id: r.ID,
CategoryId: r.CategoryID,
CategoryType: r.CategoryType.Int32,
CategoryIcon: r.CategoryIcon.String,
CategoryName: r.CategoryName.String,
UserId: r.UserID,
Username: r.Username.String,
Amount: pgtypex.NumericToString(r.Amount),
Remark: r.Remark.String,
RecordTime: pgtypex.TimestampToDateString(r.RecordTime),
CreateTime: pgtypex.TimestampToDateTimeString(r.CreateTime),
UpdateTime: pgtypex.TimestampToDateTimeString(r.UpdateTime),
})
}
} else { // 没有空间ID,只查询单用户
params := repo.FindUserMoneyRecordsParams{
UserID: userID,
RecordTime: pgtype.Timestamp{Time: startTime, Valid: true},
RecordTime_2: pgtype.Timestamp{Time: endTime, Valid: true},
}
dbRecordsUser, errQuery = db.Queries.FindUserMoneyRecords(ctx, params)
if errQuery != nil {
errorx.AddError(c, errQuery)
return
}
for _, r := range dbRecordsUser {
records = append(records, &money.MoneyRecordItem{
Id: r.ID,
CategoryId: r.CategoryID,
CategoryType: r.CategoryType.Int32,
CategoryIcon: r.CategoryIcon.String,
CategoryName: r.CategoryName.String,
UserId: r.UserID,
Username: "", // 单用户查询没有 username
Amount: pgtypex.NumericToString(r.Amount),
Remark: r.Remark.String,
RecordTime: pgtypex.TimestampToDateString(r.RecordTime),
CreateTime: pgtypex.TimestampToDateTimeString(r.CreateTime),
UpdateTime: pgtypex.TimestampToDateTimeString(r.UpdateTime),
})
}
}
// 分组统计
@@ -61,7 +116,7 @@ func QueryMoneyRecord(ctx context.Context, c *app.RequestContext) {
totalExpense := decimal.NewFromInt(0)
for _, r := range records {
day := r.RecordTime.Time.Format("2006-01-02")
day := r.RecordTime[:10] // "YYYY-MM-DD"
group, ok := groupMap[day]
if !ok {
@@ -74,28 +129,16 @@ func QueryMoneyRecord(ctx context.Context, c *app.RequestContext) {
groupMap[day] = group
}
// 构造单条记录
item := &money.MoneyRecordItem{
Id: r.ID,
CategoryId: r.CategoryID,
UserId: r.UserID,
Amount: pgtypex.NumericToString(r.Amount),
Remark: r.Remark.String,
RecordTime: pgtypex.TimestampToDateString(r.RecordTime),
CreateTime: pgtypex.TimestampToDateTimeString(r.CreateTime),
UpdateTime: pgtypex.TimestampToDateTimeString(r.UpdateTime),
}
group.Records = append(group.Records, item)
group.Records = append(group.Records, r)
// 收支累加
amount := pgtypex.NumericToDecimal(r.Amount)
if r.CategoryType.Int32 == 1 {
amount := decimal.RequireFromString(r.Amount)
if r.CategoryType == 1 {
incomeDec, _ := decimal.NewFromString(group.Income)
incomeDec = incomeDec.Add(amount)
group.Income = incomeDec.Round(2).StringFixed(2)
totalIncome = totalIncome.Add(amount)
} else if r.CategoryType.Int32 == 0 {
} else if r.CategoryType == 0 {
expenseDec, _ := decimal.NewFromString(group.Expense)
expenseDec = expenseDec.Add(amount)
group.Expense = expenseDec.Round(2).StringFixed(2)
@@ -103,14 +146,13 @@ func QueryMoneyRecord(ctx context.Context, c *app.RequestContext) {
}
}
// 对日期排序,最新在前
// 对日期排序
dates := make([]string, 0, len(groupMap))
for k := range groupMap {
dates = append(dates, k)
}
sort.Slice(dates, func(i, j int) bool { return dates[i] > dates[j] })
// 构建最终返回数组
resultGroups := make([]*money.MoneyRecordGroup, 0, len(dates))
for _, day := range dates {
resultGroups = append(resultGroups, groupMap[day])
@@ -89,7 +89,7 @@ func ListSpaceUsers(ctx context.Context, c *app.RequestContext) {
response.Success(c).Data(resp).Send()
}
// RemoveSpaceUser .
// RemoveSpaceUser 移除空间用户
// @router /space/user/remove [POST]
func RemoveSpaceUser(ctx context.Context, c *app.RequestContext) {
var req space.RemoveSpaceUserParams
@@ -98,17 +98,17 @@ func RemoveSpaceUser(ctx context.Context, c *app.RequestContext) {
return
}
spaceId := req.SpaceId
delUserId := req.UserId
userID := middleware.GetUserID(ctx)
delUserID := req.UserId
currentUserID := middleware.GetUserID(ctx)
if userID == delUserId {
// 不能删除自己
if currentUserID == delUserID {
response.Fail(c).Message("请退出空间或解散空间").Send()
return
}
// 当前操作者信息
spaceUser, err := db.Queries.GetSpaceUserByUserId(ctx, userID)
// 获取当前操作者所在空间及角色
spaceUser, err := db.Queries.GetSpaceUserByUserId(ctx, currentUserID)
if err != nil {
if errorx.IsNotFound(err) {
response.Fail(c).Message("权限不足").Send()
@@ -118,36 +118,31 @@ func RemoveSpaceUser(ctx context.Context, c *app.RequestContext) {
return
}
if spaceUser.SpaceID != spaceId {
response.Fail(c).Message("权限不足").Send()
return
}
// 检查权限
if spaceUser.Role != 0 && spaceUser.Role != 1 {
response.Fail(c).Message("权限不足").Send()
return
}
// 被踢用户是否在该空间
targetUser, err := db.Queries.GetSpaceUserByUserId(ctx, delUserId)
// 获取待删除用户的空间信息
delUserSpace, err := db.Queries.GetSpaceByUserId(ctx, delUserID)
if err != nil {
if errorx.IsNotFound(err) {
response.Success(c).Message("用户不在空间").Send()
response.Fail(c).Message("待删除用户不存在或权限不足").Send()
return
}
errorx.AddError(c, err)
return
}
if targetUser.SpaceID != spaceId {
response.Fail(c).Message("用户不在该空间").Send()
// 校验是否在同一个空间
if spaceUser.SpaceID != delUserSpace.ID {
response.Fail(c).Message("权限不足").Send()
return
}
// 删除
err = db.Queries.DeleteSpaceUser(ctx, delUserId)
if err != nil {
// 删除用户
if err := db.Queries.DeleteSpaceUser(ctx, delUserID); err != nil {
errorx.AddError(c, err)
return
}
@@ -3,7 +3,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.0
// protoc v6.33.1
// protoc v4.25.3
// source: api.proto
package api
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.0
// protoc v6.33.1
// protoc v4.25.3
// source: money.proto
package money
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.0
// protoc v6.33.1
// protoc v4.25.3
// source: money/money_category_types.proto
package money
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.0
// protoc v6.33.1
// protoc v4.25.3
// source: money/money_record_types.proto
package money
@@ -27,14 +27,18 @@ type MoneyRecordItem struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id int64 `protobuf:"varint,1,opt,name=Id,proto3" form:"id" json:"id"`
CategoryId int64 `protobuf:"varint,2,opt,name=CategoryId,proto3" form:"category_id" json:"category_id"`
UserId int64 `protobuf:"varint,3,opt,name=UserId,proto3" form:"user_id" json:"user_id"`
Amount string `protobuf:"bytes,4,opt,name=Amount,proto3" form:"amount" json:"amount"`
Remark string `protobuf:"bytes,5,opt,name=Remark,proto3" form:"remark" json:"remark"`
RecordTime string `protobuf:"bytes,6,opt,name=RecordTime,proto3" form:"record_time" json:"record_time"`
CreateTime string `protobuf:"bytes,7,opt,name=CreateTime,proto3" form:"create_time" json:"create_time"`
UpdateTime string `protobuf:"bytes,8,opt,name=UpdateTime,proto3" form:"update_time" json:"update_time"`
Id int64 `protobuf:"varint,1,opt,name=Id,proto3" form:"id" json:"id"`
CategoryId int64 `protobuf:"varint,2,opt,name=CategoryId,proto3" form:"category_id" json:"category_id"`
UserId int64 `protobuf:"varint,3,opt,name=UserId,proto3" form:"user_id" json:"user_id"`
Amount string `protobuf:"bytes,4,opt,name=Amount,proto3" form:"amount" json:"amount"`
Remark string `protobuf:"bytes,5,opt,name=Remark,proto3" form:"remark" json:"remark"`
RecordTime string `protobuf:"bytes,6,opt,name=RecordTime,proto3" form:"record_time" json:"record_time"`
CreateTime string `protobuf:"bytes,7,opt,name=CreateTime,proto3" form:"create_time" json:"create_time"`
UpdateTime string `protobuf:"bytes,8,opt,name=UpdateTime,proto3" form:"update_time" json:"update_time"`
Username string `protobuf:"bytes,9,opt,name=Username,proto3" form:"username" json:"username"`
CategoryType int32 `protobuf:"varint,10,opt,name=CategoryType,proto3" form:"category_type" json:"category_type"`
CategoryIcon string `protobuf:"bytes,11,opt,name=CategoryIcon,proto3" form:"category_icon" json:"category_icon"`
CategoryName string `protobuf:"bytes,12,opt,name=CategoryName,proto3" form:"category_name" json:"category_name"`
}
func (x *MoneyRecordItem) Reset() {
@@ -125,6 +129,34 @@ func (x *MoneyRecordItem) GetUpdateTime() string {
return ""
}
func (x *MoneyRecordItem) GetUsername() string {
if x != nil {
return x.Username
}
return ""
}
func (x *MoneyRecordItem) GetCategoryType() int32 {
if x != nil {
return x.CategoryType
}
return 0
}
func (x *MoneyRecordItem) GetCategoryIcon() string {
if x != nil {
return x.CategoryIcon
}
return ""
}
func (x *MoneyRecordItem) GetCategoryName() string {
if x != nil {
return x.CategoryName
}
return ""
}
// 同一天的记账记录分组
type MoneyRecordGroup struct {
state protoimpl.MessageState
@@ -695,7 +727,7 @@ var file_money_money_record_types_proto_rawDesc = []byte{
0x0a, 0x1e, 0x6d, 0x6f, 0x6e, 0x65, 0x79, 0x2f, 0x6d, 0x6f, 0x6e, 0x65, 0x79, 0x5f, 0x72, 0x65,
0x63, 0x6f, 0x72, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x12, 0x05, 0x6d, 0x6f, 0x6e, 0x65, 0x79, 0x1a, 0x09, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x22, 0xda, 0x02, 0x0a, 0x0f, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x65, 0x63, 0x6f,
0x74, 0x6f, 0x22, 0xa9, 0x04, 0x0a, 0x0f, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x65, 0x63, 0x6f,
0x72, 0x64, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x16, 0x0a, 0x02, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01,
0x28, 0x03, 0x42, 0x06, 0xca, 0xbb, 0x18, 0x02, 0x69, 0x64, 0x52, 0x02, 0x49, 0x64, 0x12, 0x2f,
0x0a, 0x0a, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01,
@@ -716,103 +748,115 @@ var file_money_money_record_types_proto_rawDesc = []byte{
0x6d, 0x65, 0x52, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x2f,
0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01,
0x28, 0x09, 0x42, 0x0f, 0xca, 0xbb, 0x18, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74,
0x69, 0x6d, 0x65, 0x52, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x22,
0xcd, 0x01, 0x0a, 0x10, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x47,
0x72, 0x6f, 0x75, 0x70, 0x12, 0x2f, 0x0a, 0x0a, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x69,
0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0f, 0xca, 0xbb, 0x18, 0x0b, 0x72, 0x65,
0x63, 0x6f, 0x72, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x0a, 0x52, 0x65, 0x63, 0x6f, 0x72,
0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x07, 0x45, 0x78, 0x70, 0x65, 0x6e, 0x73, 0x65,
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0b, 0xca, 0xbb, 0x18, 0x07, 0x65, 0x78, 0x70, 0x65,
0x6e, 0x73, 0x65, 0x52, 0x07, 0x45, 0x78, 0x70, 0x65, 0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x06,
0x49, 0x6e, 0x63, 0x6f, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xca, 0xbb,
0x18, 0x06, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x65, 0x52, 0x06, 0x49, 0x6e, 0x63, 0x6f, 0x6d, 0x65,
0x12, 0x3d, 0x0a, 0x07, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x6f, 0x6e, 0x65, 0x79, 0x2e, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52,
0x65, 0x63, 0x6f, 0x72, 0x64, 0x49, 0x74, 0x65, 0x6d, 0x42, 0x0b, 0xca, 0xbb, 0x18, 0x07, 0x72,
0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x52, 0x07, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x22,
0x4a, 0x0a, 0x17, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x65, 0x63,
0x6f, 0x72, 0x64, 0x73, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x2f, 0x0a, 0x0a, 0x52, 0x65,
0x63, 0x6f, 0x72, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0f,
0xca, 0xbb, 0x18, 0x0b, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x52,
0x0a, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x22, 0xc4, 0x01, 0x0a, 0x17,
0x51, 0x75, 0x65, 0x72, 0x79, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64,
0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x3e, 0x0a, 0x07, 0x52, 0x65, 0x63, 0x6f, 0x72,
0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6d, 0x6f, 0x6e, 0x65, 0x79,
0x2e, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x47, 0x72, 0x6f, 0x75,
0x70, 0x42, 0x0b, 0xca, 0xbb, 0x18, 0x07, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x52, 0x07,
0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x12, 0x32, 0x0a, 0x0b, 0x54, 0x6f, 0x74, 0x61, 0x6c,
0x49, 0x6e, 0x63, 0x6f, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x10, 0xca, 0xbb,
0x18, 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x65, 0x52, 0x0b,
0x54, 0x6f, 0x74, 0x61, 0x6c, 0x49, 0x6e, 0x63, 0x6f, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x0c, 0x54,
0x6f, 0x74, 0x61, 0x6c, 0x45, 0x78, 0x70, 0x65, 0x6e, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
0x09, 0x42, 0x11, 0xca, 0xbb, 0x18, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x65, 0x78, 0x70,
0x65, 0x6e, 0x73, 0x65, 0x52, 0x0c, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x45, 0x78, 0x70, 0x65, 0x6e,
0x73, 0x65, 0x22, 0xa4, 0x02, 0x0a, 0x17, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x4d, 0x6f, 0x6e,
0x65, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x38,
0x0a, 0x0a, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01,
0x28, 0x03, 0x42, 0x18, 0xca, 0xbb, 0x18, 0x0b, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79,
0x5f, 0x69, 0x64, 0xda, 0xbb, 0x18, 0x05, 0x24, 0x21, 0x3d, 0x27, 0x27, 0x52, 0x0a, 0x43, 0x61,
0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x49, 0x64, 0x12, 0x4d, 0x0a, 0x06, 0x41, 0x6d, 0x6f, 0x75,
0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x35, 0xca, 0xbb, 0x18, 0x06, 0x61, 0x6d,
0x6f, 0x75, 0x6e, 0x74, 0xda, 0xbb, 0x18, 0x27, 0x24, 0x21, 0x3d, 0x27, 0x27, 0x20, 0x26, 0x26,
0x20, 0x72, 0x65, 0x67, 0x65, 0x78, 0x70, 0x28, 0x27, 0x5e, 0x5c, 0x64, 0x2b, 0x28, 0x5c, 0x2e,
0x5c, 0x64, 0x7b, 0x31, 0x2c, 0x32, 0x7d, 0x29, 0x3f, 0x24, 0x27, 0x2c, 0x20, 0x24, 0x29, 0x52,
0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x22, 0x0a, 0x06, 0x52, 0x65, 0x6d, 0x61, 0x72,
0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xca, 0xbb, 0x18, 0x06, 0x72, 0x65, 0x6d,
0x61, 0x72, 0x6b, 0x52, 0x06, 0x52, 0x65, 0x6d, 0x61, 0x72, 0x6b, 0x12, 0x5c, 0x0a, 0x0a, 0x52,
0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42,
0x3c, 0xca, 0xbb, 0x18, 0x0b, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65,
0xda, 0xbb, 0x18, 0x29, 0x24, 0x21, 0x3d, 0x27, 0x27, 0x20, 0x26, 0x26, 0x20, 0x72, 0x65, 0x67,
0x65, 0x78, 0x70, 0x28, 0x27, 0x5e, 0x5c, 0x64, 0x7b, 0x34, 0x7d, 0x2d, 0x5c, 0x64, 0x7b, 0x32,
0x7d, 0x2d, 0x5c, 0x64, 0x7b, 0x32, 0x7d, 0x24, 0x27, 0x2c, 0x20, 0x24, 0x29, 0x52, 0x0a, 0x52,
0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x22, 0xe2, 0x02, 0x0a, 0x17, 0x49, 0x6e,
0x73, 0x65, 0x72, 0x74, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52,
0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x16, 0x0a, 0x02, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
0x03, 0x42, 0x06, 0xca, 0xbb, 0x18, 0x02, 0x69, 0x64, 0x52, 0x02, 0x49, 0x64, 0x12, 0x2f, 0x0a,
0x0a, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
0x03, 0x42, 0x0f, 0xca, 0xbb, 0x18, 0x0b, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x5f,
0x69, 0x64, 0x52, 0x0a, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x49, 0x64, 0x12, 0x23,
0x0a, 0x06, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x42, 0x0b,
0xca, 0xbb, 0x18, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x52, 0x06, 0x55, 0x73, 0x65,
0x72, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20,
0x01, 0x28, 0x09, 0x42, 0x0a, 0xca, 0xbb, 0x18, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x52,
0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x22, 0x0a, 0x06, 0x52, 0x65, 0x6d, 0x61, 0x72,
0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xca, 0xbb, 0x18, 0x06, 0x72, 0x65, 0x6d,
0x61, 0x72, 0x6b, 0x52, 0x06, 0x52, 0x65, 0x6d, 0x61, 0x72, 0x6b, 0x12, 0x2f, 0x0a, 0x0a, 0x52,
0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x42,
0x0f, 0xca, 0xbb, 0x18, 0x0b, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65,
0x52, 0x0a, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x0a,
0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09,
0x42, 0x0f, 0xca, 0xbb, 0x18, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d,
0x65, 0x52, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x2f, 0x0a,
0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28,
0x09, 0x42, 0x0f, 0xca, 0xbb, 0x18, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69,
0x6d, 0x65, 0x52, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x22, 0xe3,
0x01, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x65,
0x63, 0x6f, 0x72, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x1e, 0x0a, 0x02, 0x49, 0x64,
0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x42, 0x0e, 0xca, 0xbb, 0x18, 0x02, 0x69, 0x64, 0xda, 0xbb,
0x18, 0x04, 0x24, 0x21, 0x3d, 0x30, 0x52, 0x02, 0x49, 0x64, 0x12, 0x2f, 0x0a, 0x0a, 0x43, 0x61,
0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x42, 0x0f,
0xca, 0xbb, 0x18, 0x0b, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x52,
0x0a, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x06, 0x41,
0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xca, 0xbb, 0x18,
0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12,
0x22, 0x0a, 0x06, 0x52, 0x65, 0x6d, 0x61, 0x72, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42,
0x0a, 0xca, 0xbb, 0x18, 0x06, 0x72, 0x65, 0x6d, 0x61, 0x72, 0x6b, 0x52, 0x06, 0x52, 0x65, 0x6d,
0x61, 0x72, 0x6b, 0x12, 0x2f, 0x0a, 0x0a, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x69, 0x6d,
0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0f, 0xca, 0xbb, 0x18, 0x0b, 0x72, 0x65, 0x63,
0x69, 0x6d, 0x65, 0x52, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12,
0x28, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28,
0x09, 0x42, 0x0c, 0xca, 0xbb, 0x18, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x52,
0x08, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x0c, 0x43, 0x61, 0x74,
0x65, 0x67, 0x6f, 0x72, 0x79, 0x54, 0x79, 0x70, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x42,
0x11, 0xca, 0xbb, 0x18, 0x0d, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x5f, 0x74, 0x79,
0x70, 0x65, 0x52, 0x0c, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x54, 0x79, 0x70, 0x65,
0x12, 0x35, 0x0a, 0x0c, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x49, 0x63, 0x6f, 0x6e,
0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x42, 0x11, 0xca, 0xbb, 0x18, 0x0d, 0x63, 0x61, 0x74, 0x65,
0x67, 0x6f, 0x72, 0x79, 0x5f, 0x69, 0x63, 0x6f, 0x6e, 0x52, 0x0c, 0x43, 0x61, 0x74, 0x65, 0x67,
0x6f, 0x72, 0x79, 0x49, 0x63, 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x0c, 0x43, 0x61, 0x74, 0x65, 0x67,
0x6f, 0x72, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x42, 0x11, 0xca,
0xbb, 0x18, 0x0d, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65,
0x52, 0x0c, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xcd,
0x01, 0x0a, 0x10, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x47, 0x72,
0x6f, 0x75, 0x70, 0x12, 0x2f, 0x0a, 0x0a, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x69, 0x6d,
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0f, 0xca, 0xbb, 0x18, 0x0b, 0x72, 0x65, 0x63,
0x6f, 0x72, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x0a, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64,
0x54, 0x69, 0x6d, 0x65, 0x22, 0x19, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x6f,
0x6e, 0x65, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22,
0x39, 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x65,
0x63, 0x6f, 0x72, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x1e, 0x0a, 0x02, 0x49, 0x64,
0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x42, 0x0e, 0xca, 0xbb, 0x18, 0x02, 0x69, 0x64, 0xda, 0xbb,
0x18, 0x04, 0x24, 0x21, 0x3d, 0x30, 0x52, 0x02, 0x49, 0x64, 0x22, 0x19, 0x0a, 0x17, 0x44, 0x65,
0x6c, 0x65, 0x74, 0x65, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52,
0x65, 0x73, 0x75, 0x6c, 0x74, 0x42, 0x22, 0x5a, 0x20, 0x63, 0x6e, 0x2f, 0x6f, 0x6e, 0x65, 0x61,
0x6f, 0x2f, 0x62, 0x61, 0x73, 0x65, 0x2d, 0x67, 0x6f, 0x2f, 0x62, 0x69, 0x7a, 0x2f, 0x6d, 0x6f,
0x64, 0x65, 0x6c, 0x2f, 0x6d, 0x6f, 0x6e, 0x65, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x33,
0x54, 0x69, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x07, 0x45, 0x78, 0x70, 0x65, 0x6e, 0x73, 0x65, 0x18,
0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0b, 0xca, 0xbb, 0x18, 0x07, 0x65, 0x78, 0x70, 0x65, 0x6e,
0x73, 0x65, 0x52, 0x07, 0x45, 0x78, 0x70, 0x65, 0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x06, 0x49,
0x6e, 0x63, 0x6f, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xca, 0xbb, 0x18,
0x06, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x65, 0x52, 0x06, 0x49, 0x6e, 0x63, 0x6f, 0x6d, 0x65, 0x12,
0x3d, 0x0a, 0x07, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b,
0x32, 0x16, 0x2e, 0x6d, 0x6f, 0x6e, 0x65, 0x79, 0x2e, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x65,
0x63, 0x6f, 0x72, 0x64, 0x49, 0x74, 0x65, 0x6d, 0x42, 0x0b, 0xca, 0xbb, 0x18, 0x07, 0x72, 0x65,
0x63, 0x6f, 0x72, 0x64, 0x73, 0x52, 0x07, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x22, 0x4a,
0x0a, 0x17, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x65, 0x63, 0x6f,
0x72, 0x64, 0x73, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x2f, 0x0a, 0x0a, 0x52, 0x65, 0x63,
0x6f, 0x72, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0f, 0xca,
0xbb, 0x18, 0x0b, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x0a,
0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x22, 0xc4, 0x01, 0x0a, 0x17, 0x51,
0x75, 0x65, 0x72, 0x79, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73,
0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x3e, 0x0a, 0x07, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64,
0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6d, 0x6f, 0x6e, 0x65, 0x79, 0x2e,
0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x47, 0x72, 0x6f, 0x75, 0x70,
0x42, 0x0b, 0xca, 0xbb, 0x18, 0x07, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x52, 0x07, 0x52,
0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x12, 0x32, 0x0a, 0x0b, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x49,
0x6e, 0x63, 0x6f, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x10, 0xca, 0xbb, 0x18,
0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x65, 0x52, 0x0b, 0x54,
0x6f, 0x74, 0x61, 0x6c, 0x49, 0x6e, 0x63, 0x6f, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x0c, 0x54, 0x6f,
0x74, 0x61, 0x6c, 0x45, 0x78, 0x70, 0x65, 0x6e, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
0x42, 0x11, 0xca, 0xbb, 0x18, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x65, 0x78, 0x70, 0x65,
0x6e, 0x73, 0x65, 0x52, 0x0c, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x45, 0x78, 0x70, 0x65, 0x6e, 0x73,
0x65, 0x22, 0xa4, 0x02, 0x0a, 0x17, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x4d, 0x6f, 0x6e, 0x65,
0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x38, 0x0a,
0x0a, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
0x03, 0x42, 0x18, 0xca, 0xbb, 0x18, 0x0b, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x5f,
0x69, 0x64, 0xda, 0xbb, 0x18, 0x05, 0x24, 0x21, 0x3d, 0x27, 0x27, 0x52, 0x0a, 0x43, 0x61, 0x74,
0x65, 0x67, 0x6f, 0x72, 0x79, 0x49, 0x64, 0x12, 0x4d, 0x0a, 0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e,
0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x35, 0xca, 0xbb, 0x18, 0x06, 0x61, 0x6d, 0x6f,
0x75, 0x6e, 0x74, 0xda, 0xbb, 0x18, 0x27, 0x24, 0x21, 0x3d, 0x27, 0x27, 0x20, 0x26, 0x26, 0x20,
0x72, 0x65, 0x67, 0x65, 0x78, 0x70, 0x28, 0x27, 0x5e, 0x5c, 0x64, 0x2b, 0x28, 0x5c, 0x2e, 0x5c,
0x64, 0x7b, 0x31, 0x2c, 0x32, 0x7d, 0x29, 0x3f, 0x24, 0x27, 0x2c, 0x20, 0x24, 0x29, 0x52, 0x06,
0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x22, 0x0a, 0x06, 0x52, 0x65, 0x6d, 0x61, 0x72, 0x6b,
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xca, 0xbb, 0x18, 0x06, 0x72, 0x65, 0x6d, 0x61,
0x72, 0x6b, 0x52, 0x06, 0x52, 0x65, 0x6d, 0x61, 0x72, 0x6b, 0x12, 0x5c, 0x0a, 0x0a, 0x52, 0x65,
0x63, 0x6f, 0x72, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x3c,
0xca, 0xbb, 0x18, 0x0b, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0xda,
0xbb, 0x18, 0x29, 0x24, 0x21, 0x3d, 0x27, 0x27, 0x20, 0x26, 0x26, 0x20, 0x72, 0x65, 0x67, 0x65,
0x78, 0x70, 0x28, 0x27, 0x5e, 0x5c, 0x64, 0x7b, 0x34, 0x7d, 0x2d, 0x5c, 0x64, 0x7b, 0x32, 0x7d,
0x2d, 0x5c, 0x64, 0x7b, 0x32, 0x7d, 0x24, 0x27, 0x2c, 0x20, 0x24, 0x29, 0x52, 0x0a, 0x52, 0x65,
0x63, 0x6f, 0x72, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x22, 0xe2, 0x02, 0x0a, 0x17, 0x49, 0x6e, 0x73,
0x65, 0x72, 0x74, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x65,
0x73, 0x75, 0x6c, 0x74, 0x12, 0x16, 0x0a, 0x02, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03,
0x42, 0x06, 0xca, 0xbb, 0x18, 0x02, 0x69, 0x64, 0x52, 0x02, 0x49, 0x64, 0x12, 0x2f, 0x0a, 0x0a,
0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03,
0x42, 0x0f, 0xca, 0xbb, 0x18, 0x0b, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x5f, 0x69,
0x64, 0x52, 0x0a, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x49, 0x64, 0x12, 0x23, 0x0a,
0x06, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x42, 0x0b, 0xca,
0xbb, 0x18, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x52, 0x06, 0x55, 0x73, 0x65, 0x72,
0x49, 0x64, 0x12, 0x22, 0x0a, 0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01,
0x28, 0x09, 0x42, 0x0a, 0xca, 0xbb, 0x18, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x06,
0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x22, 0x0a, 0x06, 0x52, 0x65, 0x6d, 0x61, 0x72, 0x6b,
0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xca, 0xbb, 0x18, 0x06, 0x72, 0x65, 0x6d, 0x61,
0x72, 0x6b, 0x52, 0x06, 0x52, 0x65, 0x6d, 0x61, 0x72, 0x6b, 0x12, 0x2f, 0x0a, 0x0a, 0x52, 0x65,
0x63, 0x6f, 0x72, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0f,
0xca, 0xbb, 0x18, 0x0b, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x52,
0x0a, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x0a, 0x43,
0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x42,
0x0f, 0xca, 0xbb, 0x18, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65,
0x52, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x0a,
0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09,
0x42, 0x0f, 0xca, 0xbb, 0x18, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d,
0x65, 0x52, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x22, 0xe3, 0x01,
0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x65, 0x63,
0x6f, 0x72, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x1e, 0x0a, 0x02, 0x49, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x03, 0x42, 0x0e, 0xca, 0xbb, 0x18, 0x02, 0x69, 0x64, 0xda, 0xbb, 0x18,
0x04, 0x24, 0x21, 0x3d, 0x30, 0x52, 0x02, 0x49, 0x64, 0x12, 0x2f, 0x0a, 0x0a, 0x43, 0x61, 0x74,
0x65, 0x67, 0x6f, 0x72, 0x79, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x42, 0x0f, 0xca,
0xbb, 0x18, 0x0b, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x52, 0x0a,
0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x06, 0x41, 0x6d,
0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xca, 0xbb, 0x18, 0x06,
0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x22,
0x0a, 0x06, 0x52, 0x65, 0x6d, 0x61, 0x72, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a,
0xca, 0xbb, 0x18, 0x06, 0x72, 0x65, 0x6d, 0x61, 0x72, 0x6b, 0x52, 0x06, 0x52, 0x65, 0x6d, 0x61,
0x72, 0x6b, 0x12, 0x2f, 0x0a, 0x0a, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x69, 0x6d, 0x65,
0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0f, 0xca, 0xbb, 0x18, 0x0b, 0x72, 0x65, 0x63, 0x6f,
0x72, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x0a, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54,
0x69, 0x6d, 0x65, 0x22, 0x19, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x6f, 0x6e,
0x65, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x39,
0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x65, 0x63,
0x6f, 0x72, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x1e, 0x0a, 0x02, 0x49, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x03, 0x42, 0x0e, 0xca, 0xbb, 0x18, 0x02, 0x69, 0x64, 0xda, 0xbb, 0x18,
0x04, 0x24, 0x21, 0x3d, 0x30, 0x52, 0x02, 0x49, 0x64, 0x22, 0x19, 0x0a, 0x17, 0x44, 0x65, 0x6c,
0x65, 0x74, 0x65, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x65,
0x73, 0x75, 0x6c, 0x74, 0x42, 0x22, 0x5a, 0x20, 0x63, 0x6e, 0x2f, 0x6f, 0x6e, 0x65, 0x61, 0x6f,
0x2f, 0x62, 0x61, 0x73, 0x65, 0x2d, 0x67, 0x6f, 0x2f, 0x62, 0x69, 0x7a, 0x2f, 0x6d, 0x6f, 0x64,
0x65, 0x6c, 0x2f, 0x6d, 0x6f, 0x6e, 0x65, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.0
// protoc v6.33.1
// protoc v4.25.3
// source: space.proto
package space
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.0
// protoc v6.33.1
// protoc v4.25.3
// source: space/space_types.proto
package space
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.0
// protoc v6.33.1
// protoc v4.25.3
// source: space/space_user_types.proto
package space
@@ -347,8 +347,7 @@ type RemoveSpaceUserParams struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
SpaceId int64 `protobuf:"varint,1,opt,name=SpaceId,proto3" form:"space_id" json:"space_id" vd:"$ != 0"`
UserId int64 `protobuf:"varint,2,opt,name=UserId,proto3" form:"user_id" json:"user_id" vd:"$ != 0"`
UserId int64 `protobuf:"varint,1,opt,name=UserId,proto3" form:"user_id" json:"user_id" vd:"$ != 0"`
}
func (x *RemoveSpaceUserParams) Reset() {
@@ -383,13 +382,6 @@ func (*RemoveSpaceUserParams) Descriptor() ([]byte, []int) {
return file_space_space_user_types_proto_rawDescGZIP(), []int{7}
}
func (x *RemoveSpaceUserParams) GetSpaceId() int64 {
if x != nil {
return x.SpaceId
}
return 0
}
func (x *RemoveSpaceUserParams) GetUserId() int64 {
if x != nil {
return x.UserId
@@ -576,32 +568,29 @@ var file_space_space_user_types_proto_rawDesc = []byte{
0x6f, 0x64, 0x65, 0x22, 0x11, 0x0a, 0x0f, 0x4a, 0x6f, 0x69, 0x6e, 0x53, 0x70, 0x61, 0x63, 0x65,
0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x11, 0x0a, 0x0f, 0x45, 0x78, 0x69, 0x74, 0x53, 0x70,
0x61, 0x63, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x11, 0x0a, 0x0f, 0x45, 0x78, 0x69,
0x74, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x78, 0x0a, 0x15,
0x74, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x46, 0x0a, 0x15,
0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x70, 0x61, 0x63, 0x65, 0x55, 0x73, 0x65, 0x72, 0x50,
0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x30, 0x0a, 0x07, 0x53, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64,
0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x42, 0x16, 0xca, 0xbb, 0x18, 0x08, 0x73, 0x70, 0x61, 0x63,
0x65, 0x5f, 0x69, 0x64, 0xda, 0xbb, 0x18, 0x06, 0x24, 0x20, 0x21, 0x3d, 0x20, 0x30, 0x52, 0x07,
0x53, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x2d, 0x0a, 0x06, 0x55, 0x73, 0x65, 0x72, 0x49,
0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x42, 0x15, 0xca, 0xbb, 0x18, 0x07, 0x75, 0x73, 0x65,
0x72, 0x5f, 0x69, 0x64, 0xda, 0xbb, 0x18, 0x06, 0x24, 0x20, 0x21, 0x3d, 0x20, 0x30, 0x52, 0x06,
0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0x17, 0x0a, 0x15, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65,
0x53, 0x70, 0x61, 0x63, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22,
0x14, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50,
0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0xb9, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65,
0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x26, 0x0a, 0x07,
0x53, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x42, 0x0c, 0xca,
0xbb, 0x18, 0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x52, 0x07, 0x53, 0x70, 0x61,
0x63, 0x65, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x09, 0x53, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d,
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0e, 0xca, 0xbb, 0x18, 0x0a, 0x73, 0x70, 0x61,
0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x09, 0x53, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61,
0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x0a, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x43, 0x6f, 0x64, 0x65,
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0f, 0xca, 0xbb, 0x18, 0x0b, 0x69, 0x6e, 0x76, 0x69,
0x74, 0x65, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x0a, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x43,
0x6f, 0x64, 0x65, 0x12, 0x1c, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28,
0x05, 0x42, 0x08, 0xca, 0xbb, 0x18, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x52, 0x6f, 0x6c,
0x65, 0x42, 0x22, 0x5a, 0x20, 0x63, 0x6e, 0x2f, 0x6f, 0x6e, 0x65, 0x61, 0x6f, 0x2f, 0x62, 0x61,
0x73, 0x65, 0x2d, 0x67, 0x6f, 0x2f, 0x62, 0x69, 0x7a, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2f,
0x73, 0x70, 0x61, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x2d, 0x0a, 0x06, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x03, 0x42, 0x15, 0xca, 0xbb, 0x18, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f,
0x69, 0x64, 0xda, 0xbb, 0x18, 0x06, 0x24, 0x20, 0x21, 0x3d, 0x20, 0x30, 0x52, 0x06, 0x55, 0x73,
0x65, 0x72, 0x49, 0x64, 0x22, 0x17, 0x0a, 0x15, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x70,
0x61, 0x63, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x14, 0x0a,
0x12, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x72,
0x61, 0x6d, 0x73, 0x22, 0xb9, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x53,
0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x26, 0x0a, 0x07, 0x53, 0x70,
0x61, 0x63, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x42, 0x0c, 0xca, 0xbb, 0x18,
0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x52, 0x07, 0x53, 0x70, 0x61, 0x63, 0x65,
0x49, 0x64, 0x12, 0x2c, 0x0a, 0x09, 0x53, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18,
0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0e, 0xca, 0xbb, 0x18, 0x0a, 0x73, 0x70, 0x61, 0x63, 0x65,
0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x09, 0x53, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65,
0x12, 0x2f, 0x0a, 0x0a, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x03,
0x20, 0x01, 0x28, 0x09, 0x42, 0x0f, 0xca, 0xbb, 0x18, 0x0b, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65,
0x5f, 0x63, 0x6f, 0x64, 0x65, 0x52, 0x0a, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x43, 0x6f, 0x64,
0x65, 0x12, 0x1c, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x42,
0x08, 0xca, 0xbb, 0x18, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x42,
0x22, 0x5a, 0x20, 0x63, 0x6e, 0x2f, 0x6f, 0x6e, 0x65, 0x61, 0x6f, 0x2f, 0x62, 0x61, 0x73, 0x65,
0x2d, 0x67, 0x6f, 0x2f, 0x62, 0x69, 0x7a, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2f, 0x73, 0x70,
0x61, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -6,14 +6,20 @@ import (
"cn/oneao/base-go/utils/response"
"context"
"github.com/cloudwego/hertz/pkg/app"
"strconv"
)
// 私有 key,防止冲突
type ctxKeyUserID struct{}
type ctxKeyUser struct{}
// ContextUser 保存用户信息,包括 UserID 和 SpaceID
type ContextUser struct {
UserID int64
SpaceID int64
}
// Auth 中间件,直接在中间件里过滤白名单路径
func Auth() app.HandlerFunc {
// 白名单路径,直接写死
whitelistPaths := []string{
"/auth/login",
"/auth/register",
@@ -23,14 +29,13 @@ func Auth() app.HandlerFunc {
return func(ctx context.Context, c *app.RequestContext) {
path := string(c.Request.URI().Path())
// 使用工具函数判断是否在白名单
if pathx.MatchPath(path, whitelistPaths) {
c.Next(ctx)
return
}
// 获取 token
token := string(c.GetHeader("token"))
spaceId := string(c.GetHeader("x-space-id"))
if token == "" {
response.Fail(c).Code(response.HttpCode.Unauthorized).Send()
@@ -41,28 +46,52 @@ func Auth() app.HandlerFunc {
verifyToken := jwtx.VerifyToken(token)
if verifyToken.IsValid {
// 设置 userID 到 context
ctx = setUserID(ctx, verifyToken.Claims.UserID)
user := &ContextUser{
UserID: verifyToken.Claims.UserID,
SpaceID: 0,
}
if spaceId != "" {
i, err := strconv.ParseInt(spaceId, 10, 64)
if err != nil {
response.Fail(c).Message("Invalid x-space-id").Send()
c.Abort()
return
}
user.SpaceID = i
}
ctx = setContextUser(ctx, user)
c.Next(ctx)
return
}
// token 无效
response.Fail(c).Code(response.HttpCode.RefreshToken).Send()
c.Abort()
}
}
// GetUserID 从 context 中获取 user_id
func GetUserID(ctx context.Context) int64 {
userID, ok := ctx.Value(ctxKeyUserID{}).(int64)
if !ok {
return 0 // 或者返回 error,根据业务需求
// GetContextUser 从 context 获取用户信息
func GetContextUser(ctx context.Context) *ContextUser {
user, ok := ctx.Value(ctxKeyUser{}).(*ContextUser)
if !ok || user == nil {
return &ContextUser{}
}
return userID
return user
}
// 内部中间件设置 user_id
func setUserID(ctx context.Context, userID int64) context.Context {
return context.WithValue(ctx, ctxKeyUserID{}, userID)
// GetUserID 从 context 获取 user_id
func GetUserID(ctx context.Context) int64 {
return GetContextUser(ctx).UserID
}
// GetSpaceID 从 context 获取 space_id,并返回是否有效
func GetSpaceID(ctx context.Context) (int64, bool) {
spaceID := GetContextUser(ctx).SpaceID
return spaceID, spaceID != 0
}
// 内部中间件设置 ContextUser
func setContextUser(ctx context.Context, user *ContextUser) context.Context {
return context.WithValue(ctx, ctxKeyUser{}, user)
}
@@ -10,6 +10,20 @@ WHERE mr.user_id = $1
AND mr.record_time BETWEEN $2 AND $3
ORDER BY mr.record_time DESC, mr.create_time DESC;
-- name: FindMoneyRecordsBySpace :many
SELECT
mr.*,
u.username AS username,
muc.name AS category_name,
muc.icon AS category_icon,
muc.type AS category_type
FROM money_record mr
LEFT JOIN money_user_category muc ON mr.category_id = muc.id
INNER JOIN space_user su ON mr.user_id = su.user_id AND su.space_id = $1
LEFT JOIN user_info u ON mr.user_id = u.id
WHERE mr.record_time BETWEEN $2 AND $3
ORDER BY mr.record_time DESC, mr.create_time DESC;
-- name: InsertMoneyRecord :one
INSERT INTO money_record (
id,
@@ -20,6 +20,75 @@ func (q *Queries) DeleteMoneyRecord(ctx context.Context, id int64) error {
return err
}
const findMoneyRecordsBySpace = `-- name: FindMoneyRecordsBySpace :many
SELECT
mr.id, mr.category_id, mr.user_id, mr.amount, mr.remark, mr.record_time, mr.create_time, mr.update_time,
u.username AS username,
muc.name AS category_name,
muc.icon AS category_icon,
muc.type AS category_type
FROM money_record mr
LEFT JOIN money_user_category muc ON mr.category_id = muc.id
INNER JOIN space_user su ON mr.user_id = su.user_id AND su.space_id = $1
LEFT JOIN user_info u ON mr.user_id = u.id
WHERE mr.record_time BETWEEN $2 AND $3
ORDER BY mr.record_time DESC, mr.create_time DESC
`
type FindMoneyRecordsBySpaceParams struct {
SpaceID int64
RecordTime pgtype.Timestamp
RecordTime_2 pgtype.Timestamp
}
type FindMoneyRecordsBySpaceRow struct {
ID int64
CategoryID int64
UserID int64
Amount pgtype.Numeric
Remark pgtype.Text
RecordTime pgtype.Timestamp
CreateTime pgtype.Timestamp
UpdateTime pgtype.Timestamp
Username pgtype.Text
CategoryName pgtype.Text
CategoryIcon pgtype.Text
CategoryType pgtype.Int4
}
func (q *Queries) FindMoneyRecordsBySpace(ctx context.Context, arg FindMoneyRecordsBySpaceParams) ([]FindMoneyRecordsBySpaceRow, error) {
rows, err := q.db.Query(ctx, findMoneyRecordsBySpace, arg.SpaceID, arg.RecordTime, arg.RecordTime_2)
if err != nil {
return nil, err
}
defer rows.Close()
var items []FindMoneyRecordsBySpaceRow
for rows.Next() {
var i FindMoneyRecordsBySpaceRow
if err := rows.Scan(
&i.ID,
&i.CategoryID,
&i.UserID,
&i.Amount,
&i.Remark,
&i.RecordTime,
&i.CreateTime,
&i.UpdateTime,
&i.Username,
&i.CategoryName,
&i.CategoryIcon,
&i.CategoryType,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const findUserMoneyRecords = `-- name: FindUserMoneyRecords :many
SELECT
mr.id, mr.category_id, mr.user_id, mr.amount, mr.remark, mr.record_time, mr.create_time, mr.update_time,
@@ -16,6 +16,10 @@ message MoneyRecordItem {
string RecordTime = 6 [(api.body)="record_time"];
string CreateTime = 7 [(api.body)="create_time"];
string UpdateTime = 8 [(api.body)="update_time"];
string Username = 9 [(api.body)="username"];
int32 CategoryType = 10 [(api.body)="category_type"];
string CategoryIcon = 11 [(api.body)="category_icon"];
string CategoryName = 12 [(api.body)="category_name"];
}
// 同一天的记账记录分组
@@ -40,8 +40,7 @@ message ExitSpaceResult {
// 踢出成员
message RemoveSpaceUserParams {
int64 SpaceId = 1 [(api.body) = "space_id",(api.vd)="$ != 0"];
int64 UserId = 2 [(api.body) = "user_id",(api.vd)="$ != 0"];
int64 UserId = 1 [(api.body) = "user_id",(api.vd)="$ != 0"];
}
message RemoveSpaceUserResult {
@@ -88,8 +88,8 @@ func StringToTimestamp(s string) pgtype.Timestamp {
var err error
layouts := []string{
"2006-01-02 15:04:05",
"2006-01-02",
"2006-01-02 15:04:05", // 完整时间
"2006-01-02", // 仅日期也可解析
}
for _, layout := range layouts {
@@ -104,3 +104,22 @@ func StringToTimestamp(s string) pgtype.Timestamp {
return pgtype.Timestamp{Valid: false}
}
// StringToDate 将字符串解析为 pgtype.Date
// 支持格式:YYYY-MM-DD
// 解析失败或空字符串返回零值 Date
func StringToDate(s string) pgtype.Date {
if s == "" {
return pgtype.Date{Valid: false}
}
t, err := time.Parse("2006-01-02", s)
if err != nil {
return pgtype.Date{Valid: false}
}
return pgtype.Date{
Time: t,
Valid: true,
}
}