u
This commit is contained in:
1 parent
6277fb2f9e
commit
8ecac0d7dd
270 files changed
+40438
-529
No files matched your search
@@ -0,0 +1,67 @@
|
||||
// Code generated by hertz generator.
|
||||
|
||||
package auth
|
||||
|
||||
import (
|
||||
"allapp/db"
|
||||
"allapp/db/repo"
|
||||
"allapp/logx"
|
||||
"allapp/utils/jwtx"
|
||||
"allapp/utils/response"
|
||||
"context"
|
||||
|
||||
"allapp/biz/model/auth"
|
||||
|
||||
"github.com/cloudwego/hertz/pkg/app"
|
||||
"github.com/cloudwego/hertz/pkg/protocol/consts"
|
||||
)
|
||||
|
||||
// LoginDefault .
|
||||
// @router /auth/login/default [POST]
|
||||
func LoginDefault(ctx context.Context, c *app.RequestContext) {
|
||||
var err error
|
||||
var req auth.LoginDefaultReq
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 登录
|
||||
account := req.Account
|
||||
password := req.Password
|
||||
|
||||
params := repo.GetUserForLoginParams{
|
||||
Account: account,
|
||||
Password: password,
|
||||
}
|
||||
loginUser, err := db.Queries.GetUserForLogin(ctx, params)
|
||||
|
||||
if err != nil {
|
||||
response.Fail(c).Message("账号或密码错误!").Send()
|
||||
return
|
||||
}
|
||||
|
||||
// 异步更新登录事件
|
||||
go func(userID int64) {
|
||||
err = db.Queries.UpdateUserLoginLastTime(ctx, userID)
|
||||
if err != nil {
|
||||
logx.CtxError(ctx, "更新用户登录时间失败,UserID=%d, err=%v", loginUser.ID, err)
|
||||
}
|
||||
}(loginUser.ID)
|
||||
|
||||
// 包装数据
|
||||
token, err := jwtx.CreateAccessToken(loginUser.ID)
|
||||
refreshToken, err := jwtx.CreateRefreshToken(loginUser.ID)
|
||||
|
||||
resp := new(auth.LoginDefaultResp)
|
||||
|
||||
resp.Token = token
|
||||
resp.RefreshToken = refreshToken
|
||||
resp.UserId = loginUser.ID
|
||||
resp.Gender = loginUser.Gender.Int32
|
||||
resp.SeqNo = loginUser.SeqNo.Int32
|
||||
resp.Username = loginUser.Username.String
|
||||
|
||||
response.Success(c).Data(resp).Send()
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
// Code generated by hertz generator.
|
||||
|
||||
package auth
|
||||
|
||||
import (
|
||||
auth "allapp/biz/model/auth"
|
||||
"allapp/db"
|
||||
"allapp/db/repo"
|
||||
"allapp/utils"
|
||||
"allapp/utils/errorx"
|
||||
"allapp/utils/idgen"
|
||||
"allapp/utils/pgtypex"
|
||||
"allapp/utils/response"
|
||||
"context"
|
||||
|
||||
"github.com/cloudwego/hertz/pkg/app"
|
||||
"github.com/cloudwego/hertz/pkg/protocol/consts"
|
||||
"github.com/jackc/pgx/v5"
|
||||
)
|
||||
|
||||
// RegisterDefault .
|
||||
// @router /auth/register/default [POST]
|
||||
func RegisterDefault(ctx context.Context, c *app.RequestContext) {
|
||||
var err error
|
||||
var req auth.RegisterDefaultReq
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
account := req.Account
|
||||
password := req.Password
|
||||
|
||||
_, err = db.Queries.GetUserByAccount(ctx, account)
|
||||
if err != nil {
|
||||
if errorx.IsNotFound(err) {
|
||||
// 忽略
|
||||
} else {
|
||||
errorx.AddError(c, err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
response.Fail(c).Message("该账号已被注册").Send()
|
||||
return
|
||||
}
|
||||
|
||||
// 开启事务
|
||||
tx, err := db.DB.BeginTx(ctx, pgx.TxOptions{})
|
||||
if err != nil {
|
||||
errorx.AddError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
err := tx.Rollback(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
err := tx.Commit(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
generateCode, err := utils.GenerateCode(8)
|
||||
if err != nil {
|
||||
errorx.AddError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
// 插入用户
|
||||
params := repo.InsertUserParams{
|
||||
ID: idgen.NextId(),
|
||||
Account: account,
|
||||
Password: password,
|
||||
Username: pgtypex.StringToText("a_" + generateCode),
|
||||
}
|
||||
|
||||
insert, err := db.Queries.WithTx(tx).InsertUser(ctx, params)
|
||||
if err != nil || insert == 0 {
|
||||
errorx.AddError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
// 初始化用户分类
|
||||
err = initMoneyCategoryTx(ctx, tx, params.ID)
|
||||
if err != nil {
|
||||
errorx.AddError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
// 注册成功
|
||||
response.Success(c).Message("注册成功").Send()
|
||||
}
|
||||
|
||||
func initMoneyCategoryTx(ctx context.Context, tx pgx.Tx, userId int64) error {
|
||||
sysCategories, err := db.Queries.ListMoneySysCategory(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(sysCategories) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
userCategories := make([]repo.BatchInsertMoneyUserCategoriesParams, 0, len(sysCategories))
|
||||
for _, sysCat := range sysCategories {
|
||||
userCategories = append(userCategories, repo.BatchInsertMoneyUserCategoriesParams{
|
||||
ID: idgen.NextId(),
|
||||
UserID: userId,
|
||||
Name: sysCat.Name,
|
||||
Icon: sysCat.Icon,
|
||||
Type: sysCat.Type,
|
||||
SortNumber: sysCat.SortNumber,
|
||||
})
|
||||
}
|
||||
|
||||
_, err = db.Queries.WithTx(tx).BatchInsertMoneyUserCategories(ctx, userCategories)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
// Code generated by hertz generator.
|
||||
|
||||
package auth
|
||||
|
||||
import (
|
||||
"allapp/utils/errorx"
|
||||
"allapp/utils/jwtx"
|
||||
"allapp/utils/response"
|
||||
"context"
|
||||
|
||||
auth "allapp/biz/model/auth"
|
||||
|
||||
"github.com/cloudwego/hertz/pkg/app"
|
||||
"github.com/cloudwego/hertz/pkg/protocol/consts"
|
||||
)
|
||||
|
||||
// RefreshAccessToken .
|
||||
// @router /auth/refresh/token [GET]
|
||||
func RefreshAccessToken(ctx context.Context, c *app.RequestContext) {
|
||||
var err error
|
||||
var req auth.RefreshAccessTokenReq
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
refreshToken := string(c.GetHeader("refreshToken"))
|
||||
if refreshToken == "" {
|
||||
response.Fail(c).
|
||||
Code(response.HttpCode.Unauthorized).
|
||||
Send()
|
||||
return
|
||||
}
|
||||
|
||||
tokenResult := jwtx.VerifyToken(refreshToken)
|
||||
|
||||
if !tokenResult.IsValid || tokenResult.IsExpired {
|
||||
// Refresh Token 无效或过期,需要重新登录
|
||||
response.Fail(c).
|
||||
Code(response.HttpCode.Unauthorized).
|
||||
Send()
|
||||
return
|
||||
}
|
||||
|
||||
userID := tokenResult.Claims.UserID
|
||||
// 生成新的 Access Token
|
||||
newAccessToken, err := jwtx.CreateAccessToken(userID)
|
||||
if err != nil {
|
||||
errorx.AddError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
resp := new(auth.RefreshAccessTokenResp)
|
||||
resp.AccessToken = newAccessToken
|
||||
|
||||
response.Success(c).
|
||||
Data(resp).
|
||||
Send()
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
// Code generated by hertz generator.
|
||||
|
||||
package money
|
||||
|
||||
import (
|
||||
"allapp/biz/router/middleware"
|
||||
"allapp/db"
|
||||
"allapp/db/repo"
|
||||
"allapp/utils/errorx"
|
||||
"allapp/utils/response"
|
||||
"context"
|
||||
|
||||
money "allapp/biz/model/money"
|
||||
|
||||
"github.com/cloudwego/hertz/pkg/app"
|
||||
"github.com/cloudwego/hertz/pkg/protocol/consts"
|
||||
)
|
||||
|
||||
// QueryUserMoneyCategory .
|
||||
// @router /money/category [GET]
|
||||
func QueryUserMoneyCategory(ctx context.Context, c *app.RequestContext) {
|
||||
var err error
|
||||
var req money.QueryMoneyCategoryReq
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
userID := middleware.GetUserID(ctx)
|
||||
|
||||
// 查询用户分类
|
||||
moneyUserCategories, err := db.Queries.FindUserMoneyCategoriesByUserID(ctx, userID)
|
||||
if err != nil {
|
||||
errorx.AddError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
// 构造返回数据,切片类型是 []*UserMoneyCategory
|
||||
resp := &money.QueryMoneyCategoryResp{
|
||||
Categories: make([]*money.MoneyCategory, 0, len(moneyUserCategories)),
|
||||
}
|
||||
|
||||
for _, c := range moneyUserCategories {
|
||||
category := &money.MoneyCategory{
|
||||
Id: c.ID,
|
||||
Name: c.Name,
|
||||
Icon: c.Icon,
|
||||
|
||||
Type: c.Type,
|
||||
SortNumber: c.SortNumber,
|
||||
}
|
||||
resp.Categories = append(resp.Categories, category)
|
||||
}
|
||||
|
||||
response.Success(c).Data(resp).Send()
|
||||
}
|
||||
|
||||
// DeleteUserMoneyCategory .
|
||||
// @router /money/category/delete [POST]
|
||||
func DeleteUserMoneyCategory(ctx context.Context, c *app.RequestContext) {
|
||||
var err error
|
||||
var req money.DeleteMoneyCategoryReq
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
err = db.Queries.DeleteUserMoneyCategoryById(ctx, req.Id)
|
||||
|
||||
if err != nil {
|
||||
errorx.AddError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
resp := new(money.DeleteMoneyCategoryResp)
|
||||
|
||||
response.Success(c).Data(resp).Send()
|
||||
}
|
||||
|
||||
// UpdateMoneyCategorySort .
|
||||
// @router /money/category/updateSort [POST]
|
||||
func UpdateMoneyCategorySort(ctx context.Context, c *app.RequestContext) {
|
||||
var req money.UpdateMoneyCategorySortReq
|
||||
if err := c.BindAndValidate(&req); err != nil {
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 组装批量更新参数
|
||||
params := make([]repo.BatchUpdateMoneyCategorySortParams, 0, len(req.Data))
|
||||
for _, datum := range req.Data {
|
||||
params = append(params, repo.BatchUpdateMoneyCategorySortParams{
|
||||
ID: datum.Id,
|
||||
SortNumber: datum.SortNumber,
|
||||
})
|
||||
}
|
||||
|
||||
// 使用统一事务封装
|
||||
err := db.WithTx(ctx, func(q *repo.Queries) error {
|
||||
batch := q.BatchUpdateMoneyCategorySort(ctx, params)
|
||||
|
||||
if err := db.RunBatch(ctx, batch); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
errorx.AddError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
// 返回成功
|
||||
response.Success(c).Send()
|
||||
}
|
||||
@@ -0,0 +1,267 @@
|
||||
// Code generated by hertz generator.
|
||||
|
||||
package money
|
||||
|
||||
import (
|
||||
"allapp/biz/router/middleware"
|
||||
"allapp/db"
|
||||
"allapp/db/repo"
|
||||
"allapp/utils/errorx"
|
||||
"allapp/utils/idgen"
|
||||
"allapp/utils/pgtypex"
|
||||
"allapp/utils/response"
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
"github.com/shopspring/decimal"
|
||||
|
||||
money "allapp/biz/model/money"
|
||||
|
||||
"github.com/cloudwego/hertz/pkg/app"
|
||||
"github.com/cloudwego/hertz/pkg/protocol/consts"
|
||||
)
|
||||
|
||||
// QueryMoneyRecord .
|
||||
// @router /money/record/query [POST]
|
||||
func QueryMoneyRecord(ctx context.Context, c *app.RequestContext) {
|
||||
var req money.QueryMoneyRecordsParams
|
||||
if err := c.BindAndValidate(&req); err != nil {
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 解析年月
|
||||
startTime, err := time.Parse("2006-01", req.RecordTime)
|
||||
if err != nil {
|
||||
errorx.AddError(c, fmt.Errorf("invalid record_time format: %v", err))
|
||||
return
|
||||
}
|
||||
endTime := startTime.AddDate(0, 1, 0).Add(-time.Nanosecond)
|
||||
|
||||
// 获取 userID 和 spaceID
|
||||
userID := middleware.GetUserID(ctx)
|
||||
spaceID, ok := middleware.GetSpaceID(ctx)
|
||||
|
||||
// 定义统一的 records 切片
|
||||
var dbRecordsUser []repo.FindUserMoneyRecordsRow
|
||||
var dbRecordsSpace []repo.FindMoneyRecordsBySpaceRow
|
||||
var errQuery error
|
||||
|
||||
// 最终返回统一类型
|
||||
var records []*money.MoneyRecordItem
|
||||
|
||||
// 有空间ID,查询空间内所有用户
|
||||
if ok {
|
||||
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: "",
|
||||
Amount: pgtypex.NumericToString(r.Amount),
|
||||
Remark: r.Remark.String,
|
||||
RecordTime: pgtypex.TimestampToDateString(r.RecordTime),
|
||||
CreateTime: pgtypex.TimestampToDateTimeString(r.CreateTime),
|
||||
UpdateTime: pgtypex.TimestampToDateTimeString(r.UpdateTime),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 分组统计
|
||||
groupMap := make(map[string]*money.MoneyRecordGroup)
|
||||
totalIncome := decimal.NewFromInt(0)
|
||||
totalExpense := decimal.NewFromInt(0)
|
||||
|
||||
for _, r := range records {
|
||||
day := r.RecordTime[:10] // "YYYY-MM-DD"
|
||||
|
||||
group, ok := groupMap[day]
|
||||
if !ok {
|
||||
group = &money.MoneyRecordGroup{
|
||||
RecordTime: day,
|
||||
Income: "0.00",
|
||||
Expense: "0.00",
|
||||
Records: make([]*money.MoneyRecordItem, 0),
|
||||
}
|
||||
groupMap[day] = group
|
||||
}
|
||||
|
||||
group.Records = append(group.Records, r)
|
||||
|
||||
// 收支累加
|
||||
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 == 0 {
|
||||
expenseDec, _ := decimal.NewFromString(group.Expense)
|
||||
expenseDec = expenseDec.Add(amount)
|
||||
group.Expense = expenseDec.Round(2).StringFixed(2)
|
||||
totalExpense = totalExpense.Add(amount)
|
||||
}
|
||||
}
|
||||
|
||||
// 对日期排序
|
||||
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])
|
||||
}
|
||||
|
||||
result := &money.QueryMoneyRecordsResult{
|
||||
Records: resultGroups,
|
||||
TotalIncome: totalIncome.Round(2).StringFixed(2),
|
||||
TotalExpense: totalExpense.Round(2).StringFixed(2),
|
||||
TotalBalance: totalIncome.Sub(totalExpense).Round(2).StringFixed(2),
|
||||
}
|
||||
|
||||
response.Success(c).Data(result).Send()
|
||||
}
|
||||
|
||||
// InsertMoneyRecord .
|
||||
// @router /money/record/insert [POST]
|
||||
func InsertMoneyRecord(ctx context.Context, c *app.RequestContext) {
|
||||
var err error
|
||||
var req money.InsertMoneyRecordParams
|
||||
err = c.BindAndValidate(&req)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
resp := new(money.InsertMoneyRecordResult)
|
||||
|
||||
params := repo.InsertMoneyRecordParams{
|
||||
ID: idgen.NextId(),
|
||||
CategoryID: req.CategoryId,
|
||||
UserID: middleware.GetUserID(ctx),
|
||||
Amount: pgtypex.StringToNumeric(req.Amount),
|
||||
Remark: pgtypex.StringToText(req.Remark),
|
||||
RecordTime: pgtypex.StringToTimestamp(req.RecordTime),
|
||||
}
|
||||
|
||||
record, err := db.Queries.InsertMoneyRecord(ctx, params)
|
||||
|
||||
resp.Id = record.ID
|
||||
resp.CategoryId = record.CategoryID
|
||||
resp.UserId = record.UserID
|
||||
resp.Amount = pgtypex.NumericToString(record.Amount)
|
||||
resp.Remark = record.Remark.String
|
||||
resp.RecordTime = pgtypex.TimestampToDateString(record.RecordTime)
|
||||
resp.CreateTime = pgtypex.TimestampToDateTimeString(record.CreateTime)
|
||||
resp.UpdateTime = pgtypex.TimestampToDateTimeString(record.UpdateTime)
|
||||
|
||||
response.Success(c).Data(resp).Message("新增成功").Send()
|
||||
}
|
||||
|
||||
// UpdateMoneyRecord .
|
||||
// @router /money/record/update [POST]
|
||||
func UpdateMoneyRecord(ctx context.Context, c *app.RequestContext) {
|
||||
var req money.UpdateMoneyRecordParams
|
||||
if err := c.BindAndValidate(&req); err != nil {
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
id := req.Id
|
||||
_, err := db.Queries.GetMoneyRecordById(ctx, id)
|
||||
if err != nil {
|
||||
if errorx.IsNotFound(err) {
|
||||
response.Success(c).Send()
|
||||
return
|
||||
}
|
||||
errorx.AddError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
params := repo.UpdateMoneyRecordParams{
|
||||
ID: id,
|
||||
CategoryID: req.CategoryId,
|
||||
Amount: pgtypex.StringToNumeric(req.Amount),
|
||||
Remark: pgtypex.StringToText(req.Remark),
|
||||
RecordTime: pgtypex.StringToTimestamp(req.RecordTime),
|
||||
}
|
||||
|
||||
if err := db.Queries.UpdateMoneyRecord(ctx, params); err != nil {
|
||||
errorx.AddError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(c).Send()
|
||||
}
|
||||
|
||||
// DeleteMoneyRecord .
|
||||
// @router /money/record/delete [POST]
|
||||
func DeleteMoneyRecord(ctx context.Context, c *app.RequestContext) {
|
||||
var err error
|
||||
var req money.DeleteMoneyRecordParams
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
err = db.Queries.DeleteMoneyRecord(ctx, req.Id)
|
||||
|
||||
if err != nil {
|
||||
errorx.AddError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(c).Send()
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
// Code generated by hertz generator.
|
||||
|
||||
package space
|
||||
|
||||
import (
|
||||
"allapp/biz/router/middleware"
|
||||
"allapp/db"
|
||||
"allapp/db/repo"
|
||||
"allapp/utils"
|
||||
"allapp/utils/errorx"
|
||||
"allapp/utils/idgen"
|
||||
"allapp/utils/response"
|
||||
"context"
|
||||
|
||||
space "allapp/biz/model/space"
|
||||
|
||||
"github.com/cloudwego/hertz/pkg/app"
|
||||
"github.com/cloudwego/hertz/pkg/protocol/consts"
|
||||
)
|
||||
|
||||
// CreateSpace .
|
||||
// @router /space/create [POST]
|
||||
func CreateSpace(ctx context.Context, c *app.RequestContext) {
|
||||
var err error
|
||||
var req space.CreateSpaceParams
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
userID := middleware.GetUserID(ctx)
|
||||
|
||||
// 检查该用户是否已经加入空间了
|
||||
_, err = db.Queries.GetSpaceByUserId(ctx, userID)
|
||||
|
||||
if err != nil {
|
||||
if errorx.IsNotFound(err) {
|
||||
// 忽略
|
||||
} else {
|
||||
errorx.AddError(c, err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
response.Fail(c).Message("请先退出已加入的空间").Send()
|
||||
return
|
||||
}
|
||||
|
||||
// 生成邀请码
|
||||
var inviteCode string
|
||||
|
||||
for {
|
||||
// 生成邀请码
|
||||
code, err := utils.GenerateCode(6)
|
||||
if err != nil {
|
||||
errorx.AddError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
// 检查数据库是否存在
|
||||
_, err = db.Queries.GetSpaceByInviteCode(ctx, code)
|
||||
if err != nil {
|
||||
if errorx.IsNotFound(err) {
|
||||
// 不存在,唯一,直接使用
|
||||
inviteCode = code
|
||||
break
|
||||
} else {
|
||||
// 系统错误
|
||||
errorx.AddError(c, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 如果存在,继续循环重新生成
|
||||
}
|
||||
|
||||
spaceId := idgen.NextId()
|
||||
|
||||
err = db.WithTx(ctx, func(q *repo.Queries) error {
|
||||
// 创建空间
|
||||
params := repo.InsertSpaceParams{
|
||||
ID: spaceId,
|
||||
InviteCode: inviteCode,
|
||||
}
|
||||
|
||||
err = q.InsertSpace(ctx, params)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 将创建用户默认添加到该空间内
|
||||
userParams := repo.InsertSpaceUserParams{
|
||||
ID: idgen.NextId(),
|
||||
SpaceID: spaceId,
|
||||
UserID: userID,
|
||||
Role: 0,
|
||||
}
|
||||
err := q.InsertSpaceUser(ctx, userParams)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
errorx.AddError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
resp := &space.CreateSpaceResult{
|
||||
Id: spaceId,
|
||||
InviteCode: inviteCode,
|
||||
}
|
||||
|
||||
response.Success(c).Data(resp).Send()
|
||||
}
|
||||
|
||||
// DissolveSpace .
|
||||
// @router /space/dissolve [POST]
|
||||
func DissolveSpace(ctx context.Context, c *app.RequestContext) {
|
||||
var err error
|
||||
var req space.DissolveSpaceParams
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
userID := middleware.GetUserID(ctx)
|
||||
spaceByUserId, err := db.Queries.GetSpaceByUserId(ctx, userID)
|
||||
|
||||
if err != nil {
|
||||
if errorx.IsNotFound(err) {
|
||||
response.Success(c).Send()
|
||||
return
|
||||
} else {
|
||||
errorx.AddError(c, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
spaceId := spaceByUserId.ID
|
||||
|
||||
err = db.WithTx(ctx, func(q *repo.Queries) error {
|
||||
err := q.DeleteSpace(ctx, spaceId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = q.DeleteSpaceUserAll(ctx, spaceId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
errorx.AddError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(c).Send()
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
// Code generated by hertz generator.
|
||||
|
||||
package space
|
||||
|
||||
import (
|
||||
space "allapp/biz/model/space"
|
||||
"allapp/biz/router/middleware"
|
||||
"allapp/db"
|
||||
"allapp/db/repo"
|
||||
"allapp/utils/errorx"
|
||||
"allapp/utils/idgen"
|
||||
"allapp/utils/pgtypex"
|
||||
"allapp/utils/response"
|
||||
"context"
|
||||
|
||||
"github.com/cloudwego/hertz/pkg/app"
|
||||
"github.com/cloudwego/hertz/pkg/protocol/consts"
|
||||
)
|
||||
|
||||
// ExitSpace .
|
||||
// @router /space/user/exit [POST]
|
||||
func ExitSpace(ctx context.Context, c *app.RequestContext) {
|
||||
var err error
|
||||
var req space.ExitSpaceParams
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
userID := middleware.GetUserID(ctx)
|
||||
|
||||
err = db.Queries.DeleteSpaceUser(ctx, userID)
|
||||
|
||||
if err != nil {
|
||||
errorx.AddError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(c).Send()
|
||||
}
|
||||
|
||||
// ListSpaceUsers .
|
||||
// @router /space/user/list [POST]
|
||||
func ListSpaceUsers(ctx context.Context, c *app.RequestContext) {
|
||||
var err error
|
||||
var req space.ListSpaceUsersParams
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 先创建空返回对象
|
||||
resp := &space.ListSpaceUsersResult{
|
||||
Users: []*space.SpaceUser{},
|
||||
}
|
||||
|
||||
userID := middleware.GetUserID(ctx)
|
||||
|
||||
// 获取用户所在空间
|
||||
spaceByUserId, err := db.Queries.GetSpaceByUserId(ctx, userID)
|
||||
if err != nil || errorx.IsNotFound(err) {
|
||||
// 未加入空间或查询出错,直接返回空数组
|
||||
response.Success(c).Data(resp).Send()
|
||||
return
|
||||
}
|
||||
|
||||
spaceId := spaceByUserId.ID
|
||||
|
||||
// 查询空间内用户
|
||||
users, err := db.Queries.ListSpaceUsers(ctx, spaceId)
|
||||
if err != nil {
|
||||
// 查询出错,返回空数组
|
||||
errorx.AddError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
// 填充用户列表
|
||||
for _, u := range users {
|
||||
resp.Users = append(resp.Users, &space.SpaceUser{
|
||||
UserId: u.UserID,
|
||||
Username: u.Username.String,
|
||||
SpaceRole: u.Role,
|
||||
ActiveTime: pgtypex.TimestampToDateTimeString(u.ActiveTime),
|
||||
})
|
||||
}
|
||||
|
||||
response.Success(c).Data(resp).Send()
|
||||
}
|
||||
|
||||
// RemoveSpaceUser 移除空间用户
|
||||
// @router /space/user/remove [POST]
|
||||
func RemoveSpaceUser(ctx context.Context, c *app.RequestContext) {
|
||||
var req space.RemoveSpaceUserParams
|
||||
if err := c.BindAndValidate(&req); err != nil {
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
delUserID := req.UserId
|
||||
currentUserID := middleware.GetUserID(ctx)
|
||||
|
||||
// 不能删除自己
|
||||
if currentUserID == delUserID {
|
||||
response.Fail(c).Message("请退出空间或解散空间").Send()
|
||||
return
|
||||
}
|
||||
|
||||
// 获取当前操作者所在空间及角色
|
||||
spaceUser, err := db.Queries.GetSpaceUserByUserId(ctx, currentUserID)
|
||||
if err != nil {
|
||||
if errorx.IsNotFound(err) {
|
||||
response.Fail(c).Message("权限不足").Send()
|
||||
return
|
||||
}
|
||||
errorx.AddError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
// 检查权限
|
||||
if spaceUser.Role != 0 && spaceUser.Role != 1 {
|
||||
response.Fail(c).Message("权限不足").Send()
|
||||
return
|
||||
}
|
||||
|
||||
// 获取待删除用户的空间信息
|
||||
delUserSpace, err := db.Queries.GetSpaceByUserId(ctx, delUserID)
|
||||
if err != nil {
|
||||
if errorx.IsNotFound(err) {
|
||||
response.Fail(c).Message("待删除用户不存在或权限不足").Send()
|
||||
return
|
||||
}
|
||||
errorx.AddError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
// 校验是否在同一个空间
|
||||
if spaceUser.SpaceID != delUserSpace.ID {
|
||||
response.Fail(c).Message("权限不足").Send()
|
||||
return
|
||||
}
|
||||
|
||||
// 删除用户
|
||||
if err := db.Queries.DeleteSpaceUser(ctx, delUserID); err != nil {
|
||||
errorx.AddError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(c).Message("移除成功").Send()
|
||||
}
|
||||
|
||||
// JoinSpace .
|
||||
// @router /space/user/join [POST]
|
||||
func JoinSpace(ctx context.Context, c *app.RequestContext) {
|
||||
var err error
|
||||
var req space.JoinSpaceParams
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
userID := middleware.GetUserID(ctx)
|
||||
inviteCode := req.InviteCode
|
||||
// 检查该用户是否已加入其他空间
|
||||
_, err = db.Queries.GetSpaceByUserId(ctx, userID)
|
||||
if err != nil {
|
||||
if errorx.IsNotFound(err) {
|
||||
|
||||
} else {
|
||||
errorx.AddError(c, err)
|
||||
}
|
||||
} else {
|
||||
response.Fail(c).Message("请先退出已加入的空间").Send()
|
||||
return
|
||||
}
|
||||
|
||||
// 检查验证码是否有效
|
||||
spaceByCode, err := db.Queries.GetSpaceByInviteCode(ctx, inviteCode)
|
||||
|
||||
if err != nil {
|
||||
if errorx.IsNotFound(err) {
|
||||
response.Fail(c).Message("邀请码无效").Send()
|
||||
return
|
||||
} else {
|
||||
errorx.AddError(c, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 加入空间,默认
|
||||
params := repo.InsertSpaceUserParams{
|
||||
ID: idgen.NextId(),
|
||||
SpaceID: spaceByCode.ID,
|
||||
UserID: userID,
|
||||
Role: 1,
|
||||
}
|
||||
|
||||
err = db.Queries.InsertSpaceUser(ctx, params)
|
||||
|
||||
if err != nil {
|
||||
errorx.AddError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(c).Message("加入空间成功").Send()
|
||||
}
|
||||
|
||||
// GetUserSpace .
|
||||
// @router /space/user/get [GET]
|
||||
func GetUserSpace(ctx context.Context, c *app.RequestContext) {
|
||||
var err error
|
||||
var req space.GetUserSpaceParams
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
resp := new(space.GetUserSpaceResult)
|
||||
|
||||
userID := middleware.GetUserID(ctx)
|
||||
|
||||
spaceByUserId, err := db.Queries.GetUserSpaceDetail(ctx, userID)
|
||||
|
||||
if err != nil {
|
||||
if errorx.IsNotFound(err) {
|
||||
response.Success(c).Data(nil).Send()
|
||||
return
|
||||
} else {
|
||||
errorx.AddError(c, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
resp.SpaceId = spaceByUserId.SpaceID
|
||||
resp.SpaceName = spaceByUserId.SpaceName.String
|
||||
resp.InviteCode = spaceByUserId.SpaceInviteCode
|
||||
resp.Role = spaceByUserId.Role
|
||||
|
||||
response.Success(c).Data(resp).Send()
|
||||
}
|
||||
Reference in new issue
Block a user