443 lines
8.8 KiB
Go
443 lines
8.8 KiB
Go
package space
|
|
|
|
import (
|
|
"allapp/api/router/middleware"
|
|
"allapp/api/types"
|
|
"allapp/db"
|
|
"allapp/db/repo"
|
|
"allapp/utils"
|
|
"allapp/utils/errorx"
|
|
"allapp/utils/requestx"
|
|
"allapp/utils/responsex"
|
|
"allapp/utils/uniqueid"
|
|
"context"
|
|
|
|
"github.com/gofiber/fiber/v3"
|
|
)
|
|
|
|
// CreateSpace 创建空间
|
|
func CreateSpace(c fiber.Ctx) error {
|
|
dto := new(types.CreateSpaceDTO)
|
|
vo := new(types.CreateSpaceVO)
|
|
|
|
if err := requestx.BindAndValidate(c, dto); err != nil {
|
|
return err
|
|
}
|
|
|
|
userID, err2 := middleware.GetUserID(c)
|
|
|
|
if err2 != nil {
|
|
return err2
|
|
}
|
|
|
|
var inviteCode string
|
|
|
|
for {
|
|
// 生成邀请码
|
|
code := utils.GenerateCode(6)
|
|
|
|
// 检查数据库是否存在
|
|
|
|
_, err := db.Queries.GetSpaceByInviteCode(c.Context(), code)
|
|
|
|
if err != nil {
|
|
if errorx.IsNotFound(err) {
|
|
inviteCode = code
|
|
break
|
|
} else {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
|
|
spaceId := uniqueid.NextId()
|
|
|
|
err := db.WithTx(c.Context(), func(q *repo.Queries) error {
|
|
// 查询是否存在空间
|
|
countSpaces, err3 := q.CountUserSpaces(c.Context(), userID)
|
|
if err3 != nil {
|
|
return err3
|
|
}
|
|
|
|
isDefault := 0
|
|
|
|
if countSpaces == 0 {
|
|
isDefault = 1
|
|
}
|
|
|
|
// 创建空间
|
|
params := repo.InsertSpaceParams{
|
|
ID: spaceId,
|
|
Name: dto.Name,
|
|
InviteCode: inviteCode,
|
|
OwnerID: userID,
|
|
}
|
|
|
|
err := q.InsertSpace(c.Context(), params)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// 将创建用户默认添加到该空间内
|
|
spaceMemberParams := repo.InsertSpaceMemberParams{
|
|
ID: uniqueid.NextId(),
|
|
SpaceID: spaceId,
|
|
UserID: userID,
|
|
Role: 0,
|
|
IsDefault: int16(isDefault),
|
|
MemberName: dto.MemberName,
|
|
SortNumber: dto.SortNumber,
|
|
}
|
|
|
|
err = q.InsertSpaceMember(c.Context(), spaceMemberParams)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// 初始化记账
|
|
err = initFinanceCategory(c.Context(), q, spaceId, userID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
})
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
vo.SpaceId = spaceId
|
|
vo.InviteCode = inviteCode
|
|
|
|
return responsex.OK(c, vo)
|
|
}
|
|
|
|
// ListUserSpaces 查询该用户的空间
|
|
func ListUserSpaces(c fiber.Ctx) error {
|
|
vo := new(types.ListSpacesVO)
|
|
|
|
userID, err := middleware.GetUserID(c)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
rows, err := db.Queries.ListSpacesByUserId(c.Context(), userID)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
userSpaces := make([]types.UserSpace, 0, len(rows))
|
|
|
|
for _, row := range rows {
|
|
userSpaces = append(userSpaces, types.UserSpace{
|
|
SpaceId: row.SpaceID,
|
|
OwnerId: row.OwnerID,
|
|
Name: row.Name,
|
|
Role: row.Role,
|
|
MemberCount: row.MemberCount,
|
|
IsDefault: row.IsDefault,
|
|
MemberName: row.MemberName,
|
|
SortNumber: row.SortNumber,
|
|
})
|
|
}
|
|
|
|
vo.Spaces = userSpaces
|
|
|
|
return responsex.OK(c, vo)
|
|
}
|
|
|
|
// DissolveSpace 解散空间
|
|
func DissolveSpace(c fiber.Ctx) error {
|
|
dto := new(types.DissolveSpaceDTO)
|
|
if err := requestx.BindAndValidate(c, dto); err != nil {
|
|
return err
|
|
}
|
|
|
|
userId, err := middleware.GetUserID(c)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
spaceId := dto.SpaceId
|
|
|
|
space, err := db.Queries.GetSpaceById(c.Context(), spaceId)
|
|
if err != nil {
|
|
if errorx.IsNotFound(err) {
|
|
return responsex.Error(c, "空间不存在或已解散")
|
|
}
|
|
return err
|
|
}
|
|
|
|
if userId != space.OwnerID {
|
|
return responsex.Error(c, "您不是该空间的拥有者,无法解散")
|
|
}
|
|
|
|
if err := db.Queries.DissolveSpace(c.Context(), spaceId); err != nil {
|
|
return err
|
|
}
|
|
|
|
return responsex.OK(c, "空间已成功解散")
|
|
}
|
|
|
|
// ExitSpace 退出空间
|
|
func ExitSpace(c fiber.Ctx) error {
|
|
dto := new(types.ExitSpaceDTO)
|
|
if err := requestx.BindAndValidate(c, dto); err != nil {
|
|
return err
|
|
}
|
|
|
|
userId, err := middleware.GetUserID(c)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
spaceId := dto.SpaceId
|
|
|
|
_, err = db.Queries.GetSpaceById(c.Context(), spaceId)
|
|
if err != nil {
|
|
if errorx.IsNotFound(err) {
|
|
return responsex.Error(c, "空间不存在或已解散")
|
|
}
|
|
return err
|
|
}
|
|
|
|
if err := db.Queries.UpdateSpaceMemberExit(c.Context(), repo.UpdateSpaceMemberExitParams{
|
|
SpaceID: spaceId,
|
|
UserID: userId,
|
|
}); err != nil {
|
|
return err
|
|
}
|
|
|
|
return responsex.OK(c, "空间已成功退出")
|
|
}
|
|
|
|
// UpdateMemberName 更新群成员名称
|
|
func UpdateMemberName(c fiber.Ctx) error {
|
|
dto := new(types.UpdateMemberNameDTO)
|
|
if err := requestx.BindAndValidate(c, dto); err != nil {
|
|
return err
|
|
}
|
|
|
|
userId, err := middleware.GetUserID(c)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = db.Queries.UpdateSpaceMemberName(c.Context(), repo.UpdateSpaceMemberNameParams{
|
|
SpaceID: dto.SpaceId,
|
|
UserID: userId,
|
|
MemberName: dto.MemberName,
|
|
})
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return responsex.OK(c, "更新成功")
|
|
}
|
|
|
|
// UpdateSpaceDefault 更新空间默认情况
|
|
func UpdateSpaceDefault(c fiber.Ctx) error {
|
|
dto := new(types.UpdateSpaceIsDefaultDTO)
|
|
if err := requestx.BindAndValidate(c, dto); err != nil {
|
|
return err
|
|
}
|
|
|
|
userId, err := middleware.GetUserID(c)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = db.WithTx(c.Context(), func(q *repo.Queries) error {
|
|
err = q.UpdateSpaceIsDefault(c.Context(), repo.UpdateSpaceIsDefaultParams{
|
|
SpaceID: dto.SpaceId,
|
|
UserID: userId,
|
|
IsDefault: dto.IsDefault,
|
|
})
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var otherDefault int16
|
|
|
|
if dto.IsDefault == 1 {
|
|
otherDefault = 0
|
|
}
|
|
|
|
err = q.UpdateOtherSpacesIsDefault(c.Context(), repo.UpdateOtherSpacesIsDefaultParams{
|
|
IsDefault: otherDefault,
|
|
UserID: userId,
|
|
SpaceID: dto.SpaceId,
|
|
})
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
})
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return responsex.OK(c, "更新成功")
|
|
}
|
|
|
|
// UpdateSpaceName 更新空间名称
|
|
func UpdateSpaceName(c fiber.Ctx) error {
|
|
dto := new(types.UpdateSpaceNameDTO)
|
|
if err := requestx.BindAndValidate(c, dto); err != nil {
|
|
return err
|
|
}
|
|
|
|
userId, err := middleware.GetUserID(c)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
spaceId := dto.SpaceId
|
|
|
|
space, err := db.Queries.GetSpaceById(c.Context(), spaceId)
|
|
|
|
if err != nil {
|
|
if errorx.IsNotFound(err) {
|
|
return responsex.Error(c, "空间不存在或已解散")
|
|
}
|
|
return err
|
|
}
|
|
|
|
if userId != space.OwnerID {
|
|
return responsex.Error(c, "您不是该空间的拥有者,无法修改群名称")
|
|
}
|
|
|
|
err = db.Queries.UpdateSpaceName(c.Context(), repo.UpdateSpaceNameParams{
|
|
Name: dto.SpaceName,
|
|
ID: spaceId,
|
|
})
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return responsex.OK(c, "更新成功")
|
|
}
|
|
|
|
// GetSpaceSettings 获取空间配置信息
|
|
func GetSpaceSettings(c fiber.Ctx) error {
|
|
dto := new(types.GetSpaceSettingDTO)
|
|
if err := requestx.BindAndValidate(c, dto); err != nil {
|
|
return err
|
|
}
|
|
|
|
userId, err := middleware.GetUserID(c)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
spaceId := dto.SpaceId
|
|
|
|
row, err := db.Queries.GetSpaceByUserIdAndSpaceId(c.Context(), repo.GetSpaceByUserIdAndSpaceIdParams{
|
|
UserID: userId,
|
|
ID: spaceId,
|
|
})
|
|
|
|
if err != nil {
|
|
if errorx.IsNotFound(err) {
|
|
return responsex.SpaceError(c, "不在该空间或该空间已解散")
|
|
}
|
|
return err
|
|
}
|
|
vo := new(types.UserSpace)
|
|
|
|
vo.SpaceId = row.SpaceID
|
|
vo.Name = row.Name
|
|
vo.IsDefault = row.IsDefault
|
|
vo.MemberName = row.MemberName
|
|
vo.Role = row.Role
|
|
vo.MemberCount = row.MemberCount
|
|
vo.OwnerId = row.OwnerID
|
|
vo.SortNumber = row.SortNumber
|
|
vo.InviteCode = row.InviteCode
|
|
|
|
return responsex.OK(c, vo)
|
|
}
|
|
|
|
// UpdateSpaceSortNumber 更新空间排序
|
|
func UpdateSpaceSortNumber(c fiber.Ctx) error {
|
|
dto := new(types.UpdateSpaceSortNumberDTO)
|
|
if err := requestx.BindAndValidate(c, dto); err != nil {
|
|
return err
|
|
}
|
|
|
|
userId, err := middleware.GetUserID(c)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// 组装批量更新参数
|
|
params := make([]repo.BatchUpdateSpaceSortNumberParams, 0, len(dto.Spaces))
|
|
|
|
for _, datum := range dto.Spaces {
|
|
params = append(params, repo.BatchUpdateSpaceSortNumberParams{
|
|
SortNumber: datum.SortNumber,
|
|
SpaceID: datum.SpaceId,
|
|
UserID: userId,
|
|
})
|
|
}
|
|
|
|
// 使用统一事务封装
|
|
err = db.WithTx(c.Context(), func(q *repo.Queries) error {
|
|
batch := q.BatchUpdateSpaceSortNumber(c.Context(), params)
|
|
|
|
if err := db.RunBatch(c.Context(), batch); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
})
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return responsex.OK(c, "更新成功")
|
|
}
|
|
|
|
// 初始化记账分类
|
|
func initFinanceCategory(ctx context.Context, q *repo.Queries, spaceId int64, userId int64) error {
|
|
categoryDefaults, err := q.ListFinanceCategoryDefault(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if len(categoryDefaults) == 0 {
|
|
return nil
|
|
}
|
|
|
|
categorySpaces := make([]repo.BatchInsertFinanceCategorySpaceParams, 0, len(categoryDefaults))
|
|
|
|
for _, sysCat := range categoryDefaults {
|
|
categorySpaces = append(categorySpaces, repo.BatchInsertFinanceCategorySpaceParams{
|
|
ID: uniqueid.NextId(),
|
|
SpaceID: spaceId,
|
|
Name: sysCat.Name,
|
|
Icon: sysCat.Icon,
|
|
Type: sysCat.Type,
|
|
SortNumber: sysCat.SortNumber,
|
|
CreateBy: userId,
|
|
UpdateBy: userId,
|
|
})
|
|
}
|
|
|
|
if _, err := q.BatchInsertFinanceCategorySpace(ctx, categorySpaces); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|