This commit is contained in:
oneao committed 2026-01-25 22:18:27 +08:00
1 parent 500fab7a80
commit 8f3f6982db
54 files changed
+2075 -1876

No files matched your search

@@ -3,65 +3,289 @@
package auth
import (
"allapp/biz/model/auth"
"allapp/conf"
"allapp/db"
"allapp/db/repo"
"allapp/logx"
"allapp/utils"
"allapp/utils/errorx"
"allapp/utils/httpx"
"allapp/utils/idgen"
"allapp/utils/jwtx"
"allapp/utils/response"
"context"
"allapp/biz/model/auth"
"fmt"
"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 {
// LoginQq QQ 登录
// @router /auth/login/qq [POST]
func LoginQq(ctx context.Context, c *app.RequestContext) {
var req auth.LoginQqReq
if err := c.BindAndValidate(&req); err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
// 登录
account := req.Account
password := req.Password
resp := &auth.LoginResp{}
openid := req.Openid
nickname := req.Username
avatar := req.Avatar
params := repo.GetUserForLoginParams{
Account: account,
Password: password,
}
loginUser, err := db.Queries.GetUserForLogin(ctx, params)
// ---------- 通用逻辑:查询用户 ----------
user, err := db.Queries.FindUserByOpenID(ctx, repo.FindUserByOpenIDParams{
Openid: openid,
Type: 1,
})
isExist := true
if err != nil {
response.Fail(c).Message("账号或密码错误!").Send()
if errorx.IsNotFound(err) {
isExist = false
} else {
errorx.AddError(c, err)
return
}
}
if isExist {
if user.Status == 0 {
response.Fail(c).Message("账号已被禁用").Send()
return
}
_ = db.Queries.UpdateUserLastLoginTime(ctx, user.UserID)
token, _ := jwtx.CreateToken(user.UserID)
resp.Token = token
resp.UserId = user.UserID
resp.Username = user.Username
resp.Avatar = user.Avatar
response.Success(c).Data(resp).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)
// ---------- 用户不存在 → 注册 ----------
registerUser(ctx, c, openid, nickname, avatar, 1)
}
// LoginWx 微信登录
// @router /auth/login/wx [POST]
func LoginWx(ctx context.Context, c *app.RequestContext) {
var req auth.LoginWxReq
if err := c.BindAndValidate(&req); err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := &auth.LoginResp{}
openid := ""
nickname := ""
avatar := ""
accessToken := ""
// 微信登录:code换access_token + openid
status, body, err := httpx.Get(ctx, "https://api.weixin.qq.com/sns/oauth2/access_token", map[string][]any{
"appid": {conf.GetConf().Wx.AppId},
"secret": {conf.GetConf().Wx.AppSecret},
"code": {req.Code},
"grant_type": {"authorization_code"},
})
if err != nil || status != 200 {
errorx.AddError(c, fmt.Errorf("获取 openid 失败: %w, body: %s", err, body))
return
}
accessMap, err := httpx.JSONStringToMap(body)
if err != nil {
errorx.AddError(c, fmt.Errorf("解析 access_token 失败: %w", err))
return
}
accessTokenVal, ok1 := accessMap["access_token"].(string)
openidVal, ok2 := accessMap["openid"].(string)
if !ok1 || !ok2 || accessTokenVal == "" || openidVal == "" {
errorx.AddError(c, fmt.Errorf("access_token 或 openid 不存在, body: %s", body))
return
}
openid = openidVal
accessToken = accessTokenVal
// ---------- 通用逻辑:查询用户 ----------
user, err := db.Queries.FindUserByOpenID(ctx, repo.FindUserByOpenIDParams{
Openid: openid,
Type: 0,
})
// 是否已注册
isExist := true
if err != nil {
if errorx.IsNotFound(err) {
isExist = false
} else {
errorx.AddError(c, err)
return
}
}(loginUser.ID)
}
// 包装数据
token, err := jwtx.CreateAccessToken(loginUser.ID)
refreshToken, err := jwtx.CreateRefreshToken(loginUser.ID)
if isExist {
if user.Status == 0 {
response.Fail(c).Message("账号已被禁用").Send()
return
}
resp := new(auth.LoginDefaultResp)
_ = db.Queries.UpdateUserLastLoginTime(ctx, user.UserID)
token, _ := jwtx.CreateToken(user.UserID)
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
resp.Token = token
resp.UserId = user.UserID
resp.Username = user.Username
resp.Avatar = user.Avatar
response.Success(c).Data(resp).Send()
return
}
// ---------- 用户不存在 → 注册 ----------
// 用 access_token 获取用户信息
status, body, err = httpx.Get(ctx, "https://api.weixin.qq.com/sns/userinfo", map[string][]any{
"access_token": {accessToken},
"openid": {openid},
})
if err != nil || status != 200 {
errorx.AddError(c, fmt.Errorf("获取用户信息失败: %w, body: %s", err, body))
return
}
userMap, err := httpx.JSONStringToMap(body)
if err != nil {
errorx.AddError(c, fmt.Errorf("解析用户信息失败: %w", err))
return
}
nickname, _ = userMap["nickname"].(string)
avatar, _ = userMap["headimgurl"].(string)
registerUser(ctx, c, openid, nickname, avatar, 0) // 0 = 微信
}
// registerUser 注册通用函数
func registerUser(ctx context.Context, c *app.RequestContext, openid, nickname, avatar string, loginType int32) {
userId := idgen.NextId()
spaceId := idgen.NextId()
if nickname == "" {
nickname = fmt.Sprintf("用户_%d", userId)
}
if avatar == "" {
avatar = "https://default-avatar-url.com/default.png"
}
err := db.WithTx(ctx, func(q *repo.Queries) error {
// 生成唯一邀请码
var inviteCode string
for {
code := utils.GenerateCode(6)
_, err := q.FindSpaceByInviteCode(ctx, code)
if errorx.IsNotFound(err) {
inviteCode = code
break
} else if err != nil {
return err
}
}
// 插入空间
if err := q.InsertSpace(ctx, repo.InsertSpaceParams{
ID: spaceId,
InviteCode: inviteCode,
}); err != nil {
return err
}
// 插入空间用户
if err := q.InsertSpaceUser(ctx, repo.InsertSpaceUserParams{
ID: idgen.NextId(),
SpaceID: spaceId,
UserID: userId,
}); err != nil {
return err
}
// 插入用户
if err := q.InsertUser(ctx, repo.InsertUserParams{
ID: userId,
Username: nickname,
Avatar: avatar,
Status: 1,
}); err != nil {
return err
}
// 插入第三方登录信息
if err := q.InsertUserOAuth(ctx, repo.InsertUserOAuthParams{
ID: idgen.NextId(),
UserID: userId,
Type: loginType,
Openid: openid,
}); err != nil {
return err
}
// 初始化记账分类
if err := initMoneyCategoryTx(ctx, q, userId); err != nil {
return fmt.Errorf("初始化记账分类失败: %w", err)
}
return nil
})
if err != nil {
errorx.AddError(c, err)
return
}
token, _ := jwtx.CreateToken(userId)
resp := &auth.LoginResp{
Token: token,
UserId: userId,
Username: nickname,
Avatar: avatar,
}
response.Success(c).Data(resp).Send()
}
func initMoneyCategoryTx(ctx context.Context, q *repo.Queries, userId int64) error {
sysCategories, err := q.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,
})
}
if err := q.DeleteMoneyCategoryByUserId(ctx, userId); err != nil {
return err
}
if _, err := q.BatchInsertMoneyUserCategories(ctx, userCategories); err != nil {
return err
}
return nil
}
@@ -1,138 +0,0 @@
// 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 {
q := db.Queries.WithTx(tx)
sysCategories, err := q.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,
})
}
// ⚠️ 注意:这里是 DeleteMoneyCategoryByUserId,不是 ById(你代码里疑似写错)
if err := q.DeleteMoneyCategoryByUserId(ctx, userId); err != nil {
return err
}
if _, err := q.BatchInsertMoneyUserCategories(ctx, userCategories); err != nil {
return err
}
return nil
}
@@ -1,60 +0,0 @@
// 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()
}
@@ -6,9 +6,7 @@ import (
"allapp/biz/router/middleware"
"allapp/db"
"allapp/db/repo"
"allapp/utils"
"allapp/utils/errorx"
"allapp/utils/idgen"
"allapp/utils/response"
"context"
@@ -18,105 +16,6 @@ import (
"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) {
@@ -177,7 +177,7 @@ func JoinSpace(ctx context.Context, c *app.RequestContext) {
}
// 检查验证码是否有效
spaceByCode, err := db.Queries.GetSpaceByInviteCode(ctx, inviteCode)
spaceByCode, err := db.Queries.FindSpaceByInviteCode(ctx, inviteCode)
if err != nil {
if errorx.IsNotFound(err) {
+109 -324
View File
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.0
// protoc v4.25.3
// protoc v6.33.1
// source: auth.proto
package auth
@@ -21,18 +21,18 @@ const (
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// 登录请求
type LoginDefaultReq struct {
type LoginQqReq struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Account string `protobuf:"bytes,1,opt,name=Account,proto3" form:"account" json:"account" vd:"$!=''"`
Password string `protobuf:"bytes,2,opt,name=Password,proto3" form:"password" json:"password" vd:"$!=''"`
Openid string `protobuf:"bytes,1,opt,name=openid,proto3" form:"openid" json:"openid" query:"openid"`
Username string `protobuf:"bytes,2,opt,name=username,proto3" form:"username" json:"username" query:"username"`
Avatar string `protobuf:"bytes,3,opt,name=avatar,proto3" form:"avatar" json:"avatar" query:"avatar"`
}
func (x *LoginDefaultReq) Reset() {
*x = LoginDefaultReq{}
func (x *LoginQqReq) Reset() {
*x = LoginQqReq{}
if protoimpl.UnsafeEnabled {
mi := &file_auth_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -40,13 +40,13 @@ func (x *LoginDefaultReq) Reset() {
}
}
func (x *LoginDefaultReq) String() string {
func (x *LoginQqReq) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*LoginDefaultReq) ProtoMessage() {}
func (*LoginQqReq) ProtoMessage() {}
func (x *LoginDefaultReq) ProtoReflect() protoreflect.Message {
func (x *LoginQqReq) ProtoReflect() protoreflect.Message {
mi := &file_auth_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -58,41 +58,42 @@ func (x *LoginDefaultReq) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x)
}
// Deprecated: Use LoginDefaultReq.ProtoReflect.Descriptor instead.
func (*LoginDefaultReq) Descriptor() ([]byte, []int) {
// Deprecated: Use LoginQqReq.ProtoReflect.Descriptor instead.
func (*LoginQqReq) Descriptor() ([]byte, []int) {
return file_auth_proto_rawDescGZIP(), []int{0}
}
func (x *LoginDefaultReq) GetAccount() string {
func (x *LoginQqReq) GetOpenid() string {
if x != nil {
return x.Account
return x.Openid
}
return ""
}
func (x *LoginDefaultReq) GetPassword() string {
func (x *LoginQqReq) GetUsername() string {
if x != nil {
return x.Password
return x.Username
}
return ""
}
// 登录响应
type LoginDefaultResp struct {
func (x *LoginQqReq) GetAvatar() string {
if x != nil {
return x.Avatar
}
return ""
}
type LoginWxReq struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Token string `protobuf:"bytes,1,opt,name=Token,proto3" form:"token" json:"token"`
RefreshToken string `protobuf:"bytes,2,opt,name=RefreshToken,proto3" form:"refreshToken" json:"refreshToken"`
UserId int64 `protobuf:"varint,3,opt,name=UserId,proto3" form:"userId" json:"userId"`
Username string `protobuf:"bytes,4,opt,name=Username,proto3" form:"username" json:"username"`
SeqNo int32 `protobuf:"varint,5,opt,name=SeqNo,proto3" form:"seqNo" json:"seqNo"`
Gender int32 `protobuf:"varint,6,opt,name=Gender,proto3" form:"gender" json:"gender"`
Code string `protobuf:"bytes,1,opt,name=code,proto3" form:"code" json:"code" query:"code"`
}
func (x *LoginDefaultResp) Reset() {
*x = LoginDefaultResp{}
func (x *LoginWxReq) Reset() {
*x = LoginWxReq{}
if protoimpl.UnsafeEnabled {
mi := &file_auth_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -100,13 +101,13 @@ func (x *LoginDefaultResp) Reset() {
}
}
func (x *LoginDefaultResp) String() string {
func (x *LoginWxReq) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*LoginDefaultResp) ProtoMessage() {}
func (*LoginWxReq) ProtoMessage() {}
func (x *LoginDefaultResp) ProtoReflect() protoreflect.Message {
func (x *LoginWxReq) ProtoReflect() protoreflect.Message {
mi := &file_auth_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -118,65 +119,36 @@ func (x *LoginDefaultResp) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x)
}
// Deprecated: Use LoginDefaultResp.ProtoReflect.Descriptor instead.
func (*LoginDefaultResp) Descriptor() ([]byte, []int) {
// Deprecated: Use LoginWxReq.ProtoReflect.Descriptor instead.
func (*LoginWxReq) Descriptor() ([]byte, []int) {
return file_auth_proto_rawDescGZIP(), []int{1}
}
func (x *LoginDefaultResp) GetToken() string {
func (x *LoginWxReq) GetCode() string {
if x != nil {
return x.Token
return x.Code
}
return ""
}
func (x *LoginDefaultResp) GetRefreshToken() string {
if x != nil {
return x.RefreshToken
}
return ""
}
func (x *LoginDefaultResp) GetUserId() int64 {
if x != nil {
return x.UserId
}
return 0
}
func (x *LoginDefaultResp) GetUsername() string {
if x != nil {
return x.Username
}
return ""
}
func (x *LoginDefaultResp) GetSeqNo() int32 {
if x != nil {
return x.SeqNo
}
return 0
}
func (x *LoginDefaultResp) GetGender() int32 {
if x != nil {
return x.Gender
}
return 0
}
// 注册请求
type RegisterDefaultReq struct {
// 登录响应
type LoginResp struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Account string `protobuf:"bytes,1,opt,name=Account,proto3" form:"account" json:"account" vd:"$!=''"`
Password string `protobuf:"bytes,2,opt,name=Password,proto3" form:"password" json:"password" vd:"$!=''"`
// JWT
Token string `protobuf:"bytes,1,opt,name=token,proto3" form:"token" json:"token"`
// 用户ID
UserId int64 `protobuf:"varint,2,opt,name=userId,proto3" form:"userId" json:"userId"`
// 昵称
Username string `protobuf:"bytes,3,opt,name=username,proto3" form:"username" json:"username"`
// 头像
Avatar string `protobuf:"bytes,4,opt,name=avatar,proto3" form:"avatar" json:"avatar"`
}
func (x *RegisterDefaultReq) Reset() {
*x = RegisterDefaultReq{}
func (x *LoginResp) Reset() {
*x = LoginResp{}
if protoimpl.UnsafeEnabled {
mi := &file_auth_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -184,13 +156,13 @@ func (x *RegisterDefaultReq) Reset() {
}
}
func (x *RegisterDefaultReq) String() string {
func (x *LoginResp) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RegisterDefaultReq) ProtoMessage() {}
func (*LoginResp) ProtoMessage() {}
func (x *RegisterDefaultReq) ProtoReflect() protoreflect.Message {
func (x *LoginResp) ProtoReflect() protoreflect.Message {
mi := &file_auth_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -202,147 +174,35 @@ func (x *RegisterDefaultReq) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x)
}
// Deprecated: Use RegisterDefaultReq.ProtoReflect.Descriptor instead.
func (*RegisterDefaultReq) Descriptor() ([]byte, []int) {
// Deprecated: Use LoginResp.ProtoReflect.Descriptor instead.
func (*LoginResp) Descriptor() ([]byte, []int) {
return file_auth_proto_rawDescGZIP(), []int{2}
}
func (x *RegisterDefaultReq) GetAccount() string {
func (x *LoginResp) GetToken() string {
if x != nil {
return x.Account
return x.Token
}
return ""
}
func (x *RegisterDefaultReq) GetPassword() string {
func (x *LoginResp) GetUserId() int64 {
if x != nil {
return x.Password
return x.UserId
}
return 0
}
func (x *LoginResp) GetUsername() string {
if x != nil {
return x.Username
}
return ""
}
// 注册响应
type RegisterDefaultResp struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *RegisterDefaultResp) Reset() {
*x = RegisterDefaultResp{}
if protoimpl.UnsafeEnabled {
mi := &file_auth_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *RegisterDefaultResp) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RegisterDefaultResp) ProtoMessage() {}
func (x *RegisterDefaultResp) ProtoReflect() protoreflect.Message {
mi := &file_auth_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RegisterDefaultResp.ProtoReflect.Descriptor instead.
func (*RegisterDefaultResp) Descriptor() ([]byte, []int) {
return file_auth_proto_rawDescGZIP(), []int{3}
}
// 刷新 access token 请求
type RefreshAccessTokenReq struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *RefreshAccessTokenReq) Reset() {
*x = RefreshAccessTokenReq{}
if protoimpl.UnsafeEnabled {
mi := &file_auth_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *RefreshAccessTokenReq) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RefreshAccessTokenReq) ProtoMessage() {}
func (x *RefreshAccessTokenReq) ProtoReflect() protoreflect.Message {
mi := &file_auth_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RefreshAccessTokenReq.ProtoReflect.Descriptor instead.
func (*RefreshAccessTokenReq) Descriptor() ([]byte, []int) {
return file_auth_proto_rawDescGZIP(), []int{4}
}
// 刷新 access token 响应
type RefreshAccessTokenResp struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
AccessToken string `protobuf:"bytes,1,opt,name=AccessToken,proto3" form:"accessToken" json:"accessToken"`
}
func (x *RefreshAccessTokenResp) Reset() {
*x = RefreshAccessTokenResp{}
if protoimpl.UnsafeEnabled {
mi := &file_auth_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *RefreshAccessTokenResp) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RefreshAccessTokenResp) ProtoMessage() {}
func (x *RefreshAccessTokenResp) ProtoReflect() protoreflect.Message {
mi := &file_auth_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RefreshAccessTokenResp.ProtoReflect.Descriptor instead.
func (*RefreshAccessTokenResp) Descriptor() ([]byte, []int) {
return file_auth_proto_rawDescGZIP(), []int{5}
}
func (x *RefreshAccessTokenResp) GetAccessToken() string {
func (x *LoginResp) GetAvatar() string {
if x != nil {
return x.AccessToken
return x.Avatar
}
return ""
}
@@ -351,70 +211,36 @@ var File_auth_proto protoreflect.FileDescriptor
var file_auth_proto_rawDesc = []byte{
0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, 0x61, 0x75,
0x74, 0x68, 0x1a, 0x09, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x74, 0x0a,
0x0f, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x52, 0x65, 0x71,
0x12, 0x2e, 0x0a, 0x07, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x42, 0x14, 0xca, 0xbb, 0x18, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0xda, 0xbb,
0x18, 0x05, 0x24, 0x21, 0x3d, 0x27, 0x27, 0x52, 0x07, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74,
0x12, 0x31, 0x0a, 0x08, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x42, 0x15, 0xca, 0xbb, 0x18, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64,
0xda, 0xbb, 0x18, 0x05, 0x24, 0x21, 0x3d, 0x27, 0x27, 0x52, 0x08, 0x50, 0x61, 0x73, 0x73, 0x77,
0x6f, 0x72, 0x64, 0x22, 0xfc, 0x01, 0x0a, 0x10, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x44, 0x65, 0x66,
0x61, 0x75, 0x6c, 0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1f, 0x0a, 0x05, 0x54, 0x6f, 0x6b, 0x65,
0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x09, 0xca, 0xbb, 0x18, 0x05, 0x74, 0x6f, 0x6b,
0x65, 0x6e, 0x52, 0x05, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x34, 0x0a, 0x0c, 0x52, 0x65, 0x66,
0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42,
0x10, 0xca, 0xbb, 0x18, 0x0c, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65,
0x6e, 0x52, 0x0c, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12,
0x22, 0x0a, 0x06, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x42,
0x0a, 0xca, 0xbb, 0x18, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x52, 0x06, 0x55, 0x73, 0x65,
0x72, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18,
0x04, 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, 0x1f, 0x0a,
0x05, 0x53, 0x65, 0x71, 0x4e, 0x6f, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x42, 0x09, 0xca, 0xbb,
0x18, 0x05, 0x73, 0x65, 0x71, 0x4e, 0x6f, 0x52, 0x05, 0x53, 0x65, 0x71, 0x4e, 0x6f, 0x12, 0x22,
0x0a, 0x06, 0x47, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x42, 0x0a,
0xca, 0xbb, 0x18, 0x06, 0x67, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x52, 0x06, 0x47, 0x65, 0x6e, 0x64,
0x65, 0x72, 0x22, 0x77, 0x0a, 0x12, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x44, 0x65,
0x66, 0x61, 0x75, 0x6c, 0x74, 0x52, 0x65, 0x71, 0x12, 0x2e, 0x0a, 0x07, 0x41, 0x63, 0x63, 0x6f,
0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x14, 0xca, 0xbb, 0x18, 0x07, 0x61,
0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0xda, 0xbb, 0x18, 0x05, 0x24, 0x21, 0x3d, 0x27, 0x27, 0x52,
0x07, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x31, 0x0a, 0x08, 0x50, 0x61, 0x73, 0x73,
0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x15, 0xca, 0xbb, 0x18, 0x08,
0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0xda, 0xbb, 0x18, 0x05, 0x24, 0x21, 0x3d, 0x27,
0x27, 0x52, 0x08, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x15, 0x0a, 0x13, 0x52,
0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x52, 0x65,
0x73, 0x70, 0x22, 0x17, 0x0a, 0x15, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x41, 0x63, 0x63,
0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x22, 0x4b, 0x0a, 0x16, 0x52,
0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65,
0x6e, 0x52, 0x65, 0x73, 0x70, 0x12, 0x31, 0x0a, 0x0b, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54,
0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0f, 0xca, 0xbb, 0x18, 0x0b,
0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x0b, 0x41, 0x63, 0x63,
0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x32, 0x66, 0x0a, 0x0c, 0x4c, 0x6f, 0x67, 0x69,
0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x56, 0x0a, 0x0c, 0x4c, 0x6f, 0x67, 0x69,
0x6e, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x15, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e,
0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x52, 0x65, 0x71, 0x1a,
0x16, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x44, 0x65, 0x66, 0x61,
0x75, 0x6c, 0x74, 0x52, 0x65, 0x73, 0x70, 0x22, 0x17, 0xd2, 0xc1, 0x18, 0x13, 0x2f, 0x61, 0x75,
0x74, 0x68, 0x2f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x2f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74,
0x32, 0x75, 0x0a, 0x0f, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76,
0x69, 0x63, 0x65, 0x12, 0x62, 0x0a, 0x0f, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x44,
0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x18, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x52, 0x65,
0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x52, 0x65, 0x71,
0x1a, 0x19, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72,
0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x52, 0x65, 0x73, 0x70, 0x22, 0x1a, 0xd2, 0xc1, 0x18,
0x16, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x2f,
0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x32, 0x78, 0x0a, 0x0c, 0x54, 0x6f, 0x6b, 0x65, 0x6e,
0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x68, 0x0a, 0x12, 0x52, 0x65, 0x66, 0x72, 0x65,
0x73, 0x68, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1b, 0x2e,
0x61, 0x75, 0x74, 0x68, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x41, 0x63, 0x63, 0x65,
0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x1c, 0x2e, 0x61, 0x75, 0x74,
0x68, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54,
0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x22, 0x17, 0xca, 0xc1, 0x18, 0x13, 0x2f, 0x61,
0x75, 0x74, 0x68, 0x2f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x2f, 0x74, 0x6f, 0x6b, 0x65,
0x6e, 0x42, 0x21, 0x5a, 0x1f, 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,
0x61, 0x75, 0x74, 0x68, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x74, 0x68, 0x1a, 0x09, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x58, 0x0a,
0x0a, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x51, 0x71, 0x52, 0x65, 0x71, 0x12, 0x16, 0x0a, 0x06, 0x6f,
0x70, 0x65, 0x6e, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x70, 0x65,
0x6e, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18,
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12,
0x16, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x22, 0x20, 0x0a, 0x0a, 0x4c, 0x6f, 0x67, 0x69, 0x6e,
0x57, 0x78, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x22, 0x9e, 0x01, 0x0a, 0x09, 0x4c, 0x6f,
0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1f, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x09, 0xca, 0xbb, 0x18, 0x05, 0x74, 0x6f, 0x6b, 0x65,
0x6e, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x22, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72,
0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x42, 0x0a, 0xca, 0xbb, 0x18, 0x06, 0x75, 0x73,
0x65, 0x72, 0x49, 0x64, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x08,
0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0c,
0xca, 0xbb, 0x18, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x08, 0x75, 0x73,
0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72,
0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xca, 0xbb, 0x18, 0x06, 0x61, 0x76, 0x61, 0x74,
0x61, 0x72, 0x52, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x32, 0x92, 0x01, 0x0a, 0x0c, 0x4c,
0x6f, 0x67, 0x69, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x40, 0x0a, 0x07, 0x4c,
0x6f, 0x67, 0x69, 0x6e, 0x51, 0x71, 0x12, 0x10, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x4c, 0x6f,
0x67, 0x69, 0x6e, 0x51, 0x71, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e,
0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x22, 0x12, 0xd2, 0xc1, 0x18, 0x0e, 0x2f,
0x61, 0x75, 0x74, 0x68, 0x2f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x2f, 0x71, 0x71, 0x12, 0x40, 0x0a,
0x07, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x57, 0x78, 0x12, 0x10, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e,
0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x57, 0x78, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x61, 0x75, 0x74,
0x68, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x22, 0x12, 0xd2, 0xc1, 0x18,
0x0e, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x2f, 0x77, 0x78, 0x42,
0x17, 0x5a, 0x15, 0x61, 0x6c, 0x6c, 0x61, 0x70, 0x70, 0x2f, 0x62, 0x69, 0x7a, 0x2f, 0x6d, 0x6f,
0x64, 0x65, 0x6c, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -429,24 +255,19 @@ func file_auth_proto_rawDescGZIP() []byte {
return file_auth_proto_rawDescData
}
var file_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
var file_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_auth_proto_goTypes = []interface{}{
(*LoginDefaultReq)(nil), // 0: auth.LoginDefaultReq
(*LoginDefaultResp)(nil), // 1: auth.LoginDefaultResp
(*RegisterDefaultReq)(nil), // 2: auth.RegisterDefaultReq
(*RegisterDefaultResp)(nil), // 3: auth.RegisterDefaultResp
(*RefreshAccessTokenReq)(nil), // 4: auth.RefreshAccessTokenReq
(*RefreshAccessTokenResp)(nil), // 5: auth.RefreshAccessTokenResp
(*LoginQqReq)(nil), // 0: auth.LoginQqReq
(*LoginWxReq)(nil), // 1: auth.LoginWxReq
(*LoginResp)(nil), // 2: auth.LoginResp
}
var file_auth_proto_depIdxs = []int32{
0, // 0: auth.LoginService.LoginDefault:input_type -> auth.LoginDefaultReq
2, // 1: auth.RegisterService.RegisterDefault:input_type -> auth.RegisterDefaultReq
4, // 2: auth.TokenService.RefreshAccessToken:input_type -> auth.RefreshAccessTokenReq
1, // 3: auth.LoginService.LoginDefault:output_type -> auth.LoginDefaultResp
3, // 4: auth.RegisterService.RegisterDefault:output_type -> auth.RegisterDefaultResp
5, // 5: auth.TokenService.RefreshAccessToken:output_type -> auth.RefreshAccessTokenResp
3, // [3:6] is the sub-list for method output_type
0, // [0:3] is the sub-list for method input_type
0, // 0: auth.LoginService.LoginQq:input_type -> auth.LoginQqReq
1, // 1: auth.LoginService.LoginWx:input_type -> auth.LoginWxReq
2, // 2: auth.LoginService.LoginQq:output_type -> auth.LoginResp
2, // 3: auth.LoginService.LoginWx:output_type -> auth.LoginResp
2, // [2:4] is the sub-list for method output_type
0, // [0:2] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
@@ -459,7 +280,7 @@ func file_auth_proto_init() {
}
if !protoimpl.UnsafeEnabled {
file_auth_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*LoginDefaultReq); i {
switch v := v.(*LoginQqReq); i {
case 0:
return &v.state
case 1:
@@ -471,7 +292,7 @@ func file_auth_proto_init() {
}
}
file_auth_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*LoginDefaultResp); i {
switch v := v.(*LoginWxReq); i {
case 0:
return &v.state
case 1:
@@ -483,43 +304,7 @@ func file_auth_proto_init() {
}
}
file_auth_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RegisterDefaultReq); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_auth_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RegisterDefaultResp); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_auth_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RefreshAccessTokenReq); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_auth_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RefreshAccessTokenResp); i {
switch v := v.(*LoginResp); i {
case 0:
return &v.state
case 1:
@@ -537,9 +322,9 @@ func file_auth_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_auth_proto_rawDesc,
NumEnums: 0,
NumMessages: 6,
NumMessages: 3,
NumExtensions: 0,
NumServices: 3,
NumServices: 1,
},
GoTypes: file_auth_proto_goTypes,
DependencyIndexes: file_auth_proto_depIdxs,
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.0
// protoc v4.25.3
// protoc v6.33.1
// source: space.proto
package space
@@ -28,86 +28,77 @@ var file_space_proto_rawDesc = []byte{
0x17, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70,
0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f,
0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0xc2, 0x01, 0x0a, 0x0c, 0x53, 0x70, 0x61, 0x63, 0x65,
0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x54, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74,
0x65, 0x53, 0x70, 0x61, 0x63, 0x65, 0x12, 0x18, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x43,
0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73,
0x1a, 0x18, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53,
0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x11, 0xd2, 0xc1, 0x18, 0x0d,
0x2f, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x5c, 0x0a,
0x0d, 0x44, 0x69, 0x73, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x53, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1a,
0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x44, 0x69, 0x73, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x53,
0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x1a, 0x2e, 0x73, 0x70, 0x61,
0x63, 0x65, 0x2e, 0x44, 0x69, 0x73, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x53, 0x70, 0x61, 0x63, 0x65,
0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x13, 0xd2, 0xc1, 0x18, 0x0f, 0x2f, 0x73, 0x70, 0x61,
0x63, 0x65, 0x2f, 0x64, 0x69, 0x73, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x32, 0xdc, 0x03, 0x0a, 0x10,
0x53, 0x70, 0x61, 0x63, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
0x12, 0x59, 0x0a, 0x0c, 0x67, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65,
0x12, 0x19, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72,
0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x19, 0x2e, 0x73, 0x70,
0x61, 0x63, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65,
0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x13, 0xca, 0xc1, 0x18, 0x0f, 0x2f, 0x73, 0x70, 0x61,
0x63, 0x65, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2f, 0x67, 0x65, 0x74, 0x12, 0x51, 0x0a, 0x09, 0x45,
0x78, 0x69, 0x74, 0x53, 0x70, 0x61, 0x63, 0x65, 0x12, 0x16, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65,
0x2e, 0x45, 0x78, 0x69, 0x74, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73,
0x1a, 0x16, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x45, 0x78, 0x69, 0x74, 0x53, 0x70, 0x61,
0x63, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x14, 0xd2, 0xc1, 0x18, 0x10, 0x2f, 0x73,
0x70, 0x61, 0x63, 0x65, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2f, 0x65, 0x78, 0x69, 0x74, 0x12, 0x60,
0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x70, 0x61, 0x63, 0x65, 0x55, 0x73, 0x65, 0x72, 0x73,
0x12, 0x1b, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x70, 0x61,
0x63, 0x65, 0x55, 0x73, 0x65, 0x72, 0x73, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x1b, 0x2e,
0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x70, 0x61, 0x63, 0x65, 0x55,
0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x14, 0xd2, 0xc1, 0x18, 0x10,
0x2f, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2f, 0x6c, 0x69, 0x73, 0x74,
0x12, 0x65, 0x0a, 0x0f, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x70, 0x61, 0x63, 0x65, 0x55,
0x73, 0x65, 0x72, 0x12, 0x1c, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x6d, 0x6f,
0x76, 0x65, 0x53, 0x70, 0x61, 0x63, 0x65, 0x55, 0x73, 0x65, 0x72, 0x50, 0x61, 0x72, 0x61, 0x6d,
0x73, 0x1a, 0x1c, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65,
0x53, 0x70, 0x61, 0x63, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22,
0x16, 0xd2, 0xc1, 0x18, 0x12, 0x2f, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f, 0x75, 0x73, 0x65, 0x72,
0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x12, 0x51, 0x0a, 0x09, 0x4a, 0x6f, 0x69, 0x6e, 0x53,
0x70, 0x61, 0x63, 0x65, 0x12, 0x16, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x4a, 0x6f, 0x69,
0x6e, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x16, 0x2e, 0x73,
0x70, 0x61, 0x63, 0x65, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65,
0x73, 0x75, 0x6c, 0x74, 0x22, 0x14, 0xd2, 0xc1, 0x18, 0x10, 0x2f, 0x73, 0x70, 0x61, 0x63, 0x65,
0x2f, 0x75, 0x73, 0x65, 0x72, 0x2f, 0x6a, 0x6f, 0x69, 0x6e, 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,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x6c, 0x0a, 0x0c, 0x53, 0x70, 0x61, 0x63, 0x65, 0x53,
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5c, 0x0a, 0x0d, 0x44, 0x69, 0x73, 0x73, 0x6f, 0x6c,
0x76, 0x65, 0x53, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1a, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e,
0x44, 0x69, 0x73, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x72,
0x61, 0x6d, 0x73, 0x1a, 0x1a, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x44, 0x69, 0x73, 0x73,
0x6f, 0x6c, 0x76, 0x65, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22,
0x13, 0xd2, 0xc1, 0x18, 0x0f, 0x2f, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f, 0x64, 0x69, 0x73, 0x73,
0x6f, 0x6c, 0x76, 0x65, 0x32, 0xdc, 0x03, 0x0a, 0x10, 0x53, 0x70, 0x61, 0x63, 0x65, 0x55, 0x73,
0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x59, 0x0a, 0x0c, 0x67, 0x65, 0x74,
0x55, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x12, 0x19, 0x2e, 0x73, 0x70, 0x61, 0x63,
0x65, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61,
0x72, 0x61, 0x6d, 0x73, 0x1a, 0x19, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x47, 0x65, 0x74,
0x55, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22,
0x13, 0xca, 0xc1, 0x18, 0x0f, 0x2f, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f, 0x75, 0x73, 0x65, 0x72,
0x2f, 0x67, 0x65, 0x74, 0x12, 0x51, 0x0a, 0x09, 0x45, 0x78, 0x69, 0x74, 0x53, 0x70, 0x61, 0x63,
0x65, 0x12, 0x16, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x45, 0x78, 0x69, 0x74, 0x53, 0x70,
0x61, 0x63, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x16, 0x2e, 0x73, 0x70, 0x61, 0x63,
0x65, 0x2e, 0x45, 0x78, 0x69, 0x74, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c,
0x74, 0x22, 0x14, 0xd2, 0xc1, 0x18, 0x10, 0x2f, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f, 0x75, 0x73,
0x65, 0x72, 0x2f, 0x65, 0x78, 0x69, 0x74, 0x12, 0x60, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x53,
0x70, 0x61, 0x63, 0x65, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x1b, 0x2e, 0x73, 0x70, 0x61, 0x63,
0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x70, 0x61, 0x63, 0x65, 0x55, 0x73, 0x65, 0x72, 0x73,
0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x1b, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x4c,
0x69, 0x73, 0x74, 0x53, 0x70, 0x61, 0x63, 0x65, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73,
0x75, 0x6c, 0x74, 0x22, 0x14, 0xd2, 0xc1, 0x18, 0x10, 0x2f, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f,
0x75, 0x73, 0x65, 0x72, 0x2f, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x65, 0x0a, 0x0f, 0x52, 0x65, 0x6d,
0x6f, 0x76, 0x65, 0x53, 0x70, 0x61, 0x63, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1c, 0x2e, 0x73,
0x70, 0x61, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x70, 0x61, 0x63, 0x65,
0x55, 0x73, 0x65, 0x72, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x1c, 0x2e, 0x73, 0x70, 0x61,
0x63, 0x65, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x70, 0x61, 0x63, 0x65, 0x55, 0x73,
0x65, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x16, 0xd2, 0xc1, 0x18, 0x12, 0x2f, 0x73,
0x70, 0x61, 0x63, 0x65, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65,
0x12, 0x51, 0x0a, 0x09, 0x4a, 0x6f, 0x69, 0x6e, 0x53, 0x70, 0x61, 0x63, 0x65, 0x12, 0x16, 0x2e,
0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50,
0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x16, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x4a, 0x6f,
0x69, 0x6e, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x14, 0xd2,
0xc1, 0x18, 0x10, 0x2f, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2f, 0x6a,
0x6f, 0x69, 0x6e, 0x42, 0x18, 0x5a, 0x16, 0x61, 0x6c, 0x6c, 0x61, 0x70, 0x70, 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 file_space_proto_goTypes = []interface{}{
(*CreateSpaceParams)(nil), // 0: space.CreateSpaceParams
(*DissolveSpaceParams)(nil), // 1: space.DissolveSpaceParams
(*GetUserSpaceParams)(nil), // 2: space.GetUserSpaceParams
(*ExitSpaceParams)(nil), // 3: space.ExitSpaceParams
(*ListSpaceUsersParams)(nil), // 4: space.ListSpaceUsersParams
(*RemoveSpaceUserParams)(nil), // 5: space.RemoveSpaceUserParams
(*JoinSpaceParams)(nil), // 6: space.JoinSpaceParams
(*DissolveSpaceResult)(nil), // 7: space.DissolveSpaceResult
(*GetUserSpaceResult)(nil), // 8: space.GetUserSpaceResult
(*ExitSpaceResult)(nil), // 9: space.ExitSpaceResult
(*ListSpaceUsersResult)(nil), // 10: space.ListSpaceUsersResult
(*RemoveSpaceUserResult)(nil), // 11: space.RemoveSpaceUserResult
(*JoinSpaceResult)(nil), // 12: space.JoinSpaceResult
(*DissolveSpaceParams)(nil), // 0: space.DissolveSpaceParams
(*GetUserSpaceParams)(nil), // 1: space.GetUserSpaceParams
(*ExitSpaceParams)(nil), // 2: space.ExitSpaceParams
(*ListSpaceUsersParams)(nil), // 3: space.ListSpaceUsersParams
(*RemoveSpaceUserParams)(nil), // 4: space.RemoveSpaceUserParams
(*JoinSpaceParams)(nil), // 5: space.JoinSpaceParams
(*DissolveSpaceResult)(nil), // 6: space.DissolveSpaceResult
(*GetUserSpaceResult)(nil), // 7: space.GetUserSpaceResult
(*ExitSpaceResult)(nil), // 8: space.ExitSpaceResult
(*ListSpaceUsersResult)(nil), // 9: space.ListSpaceUsersResult
(*RemoveSpaceUserResult)(nil), // 10: space.RemoveSpaceUserResult
(*JoinSpaceResult)(nil), // 11: space.JoinSpaceResult
}
var file_space_proto_depIdxs = []int32{
0, // 0: space.SpaceService.CreateSpace:input_type -> space.CreateSpaceParams
1, // 1: space.SpaceService.DissolveSpace:input_type -> space.DissolveSpaceParams
2, // 2: space.SpaceUserService.getUserSpace:input_type -> space.GetUserSpaceParams
3, // 3: space.SpaceUserService.ExitSpace:input_type -> space.ExitSpaceParams
4, // 4: space.SpaceUserService.ListSpaceUsers:input_type -> space.ListSpaceUsersParams
5, // 5: space.SpaceUserService.RemoveSpaceUser:input_type -> space.RemoveSpaceUserParams
6, // 6: space.SpaceUserService.JoinSpace:input_type -> space.JoinSpaceParams
0, // 7: space.SpaceService.CreateSpace:output_type -> space.CreateSpaceParams
7, // 8: space.SpaceService.DissolveSpace:output_type -> space.DissolveSpaceResult
8, // 9: space.SpaceUserService.getUserSpace:output_type -> space.GetUserSpaceResult
9, // 10: space.SpaceUserService.ExitSpace:output_type -> space.ExitSpaceResult
10, // 11: space.SpaceUserService.ListSpaceUsers:output_type -> space.ListSpaceUsersResult
11, // 12: space.SpaceUserService.RemoveSpaceUser:output_type -> space.RemoveSpaceUserResult
12, // 13: space.SpaceUserService.JoinSpace:output_type -> space.JoinSpaceResult
7, // [7:14] is the sub-list for method output_type
0, // [0:7] is the sub-list for method input_type
0, // 0: space.SpaceService.DissolveSpace:input_type -> space.DissolveSpaceParams
1, // 1: space.SpaceUserService.getUserSpace:input_type -> space.GetUserSpaceParams
2, // 2: space.SpaceUserService.ExitSpace:input_type -> space.ExitSpaceParams
3, // 3: space.SpaceUserService.ListSpaceUsers:input_type -> space.ListSpaceUsersParams
4, // 4: space.SpaceUserService.RemoveSpaceUser:input_type -> space.RemoveSpaceUserParams
5, // 5: space.SpaceUserService.JoinSpace:input_type -> space.JoinSpaceParams
6, // 6: space.SpaceService.DissolveSpace:output_type -> space.DissolveSpaceResult
7, // 7: space.SpaceUserService.getUserSpace:output_type -> space.GetUserSpaceResult
8, // 8: space.SpaceUserService.ExitSpace:output_type -> space.ExitSpaceResult
9, // 9: space.SpaceUserService.ListSpaceUsers:output_type -> space.ListSpaceUsersResult
10, // 10: space.SpaceUserService.RemoveSpaceUser:output_type -> space.RemoveSpaceUserResult
11, // 11: space.SpaceUserService.JoinSpace:output_type -> space.JoinSpaceResult
6, // [6:12] is the sub-list for method output_type
0, // [0:6] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.0
// protoc v4.25.3
// protoc v6.33.1
// source: space/space_types.proto
package space
@@ -207,10 +207,9 @@ var file_space_space_types_proto_rawDesc = []byte{
0x64, 0x65, 0x52, 0x0a, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x22, 0x15,
0x0a, 0x13, 0x44, 0x69, 0x73, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50,
0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x15, 0x0a, 0x13, 0x44, 0x69, 0x73, 0x73, 0x6f, 0x6c, 0x76,
0x65, 0x53, 0x70, 0x61, 0x63, 0x65, 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, 0x73, 0x70, 0x61, 0x63, 0x65,
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x65, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x42, 0x18, 0x5a, 0x16,
0x61, 0x6c, 0x6c, 0x61, 0x70, 0x70, 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 (
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.0
// protoc v4.25.3
// protoc v6.33.1
// source: space/space_user_types.proto
package space
@@ -588,9 +588,9 @@ var file_space_space_user_types_proto_rawDesc = []byte{
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,
0x18, 0x5a, 0x16, 0x61, 0x6c, 0x6c, 0x61, 0x70, 0x70, 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 (
@@ -21,15 +21,8 @@ func Register(r *server.Hertz) {
_auth := root.Group("/auth", _authMw()...)
{
_login := _auth.Group("/login", _loginMw()...)
_login.POST("/default", append(_logindefaultMw(), auth.LoginDefault)...)
}
{
_refresh := _auth.Group("/refresh", _refreshMw()...)
_refresh.GET("/token", append(_refreshaccesstokenMw(), auth.RefreshAccessToken)...)
}
{
_register := _auth.Group("/register", _registerMw()...)
_register.POST("/default", append(_registerdefaultMw(), auth.RegisterDefault)...)
_login.POST("/qq", append(_loginqqMw(), auth.LoginQq)...)
_login.POST("/wx", append(_loginwxMw(), auth.LoginWx)...)
}
}
}
@@ -45,3 +45,18 @@ func _refreshMw() []app.HandlerFunc {
// your code...
return nil
}
func _loginthirdpartyMw() []app.HandlerFunc {
// your code...
return nil
}
func _loginqqMw() []app.HandlerFunc {
// your code...
return nil
}
func _loginwxMw() []app.HandlerFunc {
// your code...
return nil
}
@@ -43,11 +43,11 @@ func Auth() app.HandlerFunc {
return
}
verifyToken := jwtx.VerifyToken(token)
verifyToken, flag := jwtx.VerifyToken(token)
if verifyToken.IsValid {
if flag {
user := &ContextUser{
UserID: verifyToken.Claims.UserID,
UserID: verifyToken.UserID,
SpaceID: 0,
}
if spaceId != "" {
@@ -19,7 +19,6 @@ func Register(r *server.Hertz) {
root := r.Group("/", rootMw()...)
{
_space := root.Group("/space", _spaceMw()...)
_space.POST("/create", append(_createspaceMw(), space.CreateSpace)...)
_space.POST("/dissolve", append(_dissolvespaceMw(), space.DissolveSpace)...)
{
_user := _space.Group("/user", _userMw()...)
+10 -4
View File
@@ -1,11 +1,12 @@
package conf
import (
"github.com/spf13/viper"
"os"
"path/filepath"
"sync"
"time"
"github.com/spf13/viper"
)
var (
@@ -21,6 +22,7 @@ type Config struct {
Snowflake SnowflakeConfig `mapstructure:"snowflake" yaml:"snowflake"`
Pgsql PgsqlConfig `mapstructure:"pgsql" yaml:"pgsql"`
Log LogConfig `mapstructure:"log" yaml:"log"`
Wx WxConfig `mapstructure:"wx" yaml:"wx"`
}
type ServerConfig struct {
@@ -29,9 +31,8 @@ type ServerConfig struct {
}
type JwtConfig struct {
Secret string `mapstructure:"secret" yaml:"secret"`
AccessExpiry time.Duration `mapstructure:"access_expiry" yaml:"access_expiry"`
RefreshExpiry time.Duration `mapstructure:"refresh_expiry" yaml:"refresh_expiry"`
Secret string `mapstructure:"secret" yaml:"secret"`
AccessExpiry time.Duration `mapstructure:"access_expiry" yaml:"access_expiry"`
}
type SnowflakeConfig struct {
@@ -61,6 +62,11 @@ type LogConfig struct {
Compress bool `mapstructure:"compress" yaml:"compress"`
}
type WxConfig struct {
AppId string `mapstructure:"app_id" yaml:"app_id"`
AppSecret string `mapstructure:"app_secret" yaml:"app_secret"`
}
func GetConf() *Config {
once.Do(initConf)
return conf
+4 -1
View File
@@ -5,7 +5,6 @@ server:
jwt:
secret: 3Bde3BGEbYqtqyEUzW3ry8jKFcaPH17fRmTmqE7MDr05Lwj95uruRKrrkb44TJ4s
access_expiry: -1
refresh_expiry: -1
snowflake:
datacenter_id: 1
@@ -30,3 +29,7 @@ log:
max_backups: 30
max_age: 7
compress: true
wx:
app_id: wxdab3e21a1f7e392f
app_secret: 0895443c6fedfc21cb92c9cd60de2a26
+1 -2
View File
@@ -18,7 +18,6 @@ FROM space s
ON s.id = m.space_id
WHERE m.user_id = $1;
-- 根据验证码获取空间
-- name: GetSpaceByInviteCode :one
-- name: FindSpaceByInviteCode :one
SELECT * FROM space WHERE invite_code = $1;
+32
View File
@@ -0,0 +1,32 @@
-- name: FindUserByOpenID :one
SELECT
u.id AS user_id,
u.username,
u.avatar,
u.status,
o.type AS login_type,
o.openid
FROM user_oauth o
JOIN "user" u ON u.id = o.user_id
WHERE o.openid = $1
AND o.type = $2
LIMIT 1;
-- name: InsertUser :exec
INSERT INTO "user" (
id,
username,
avatar,
status,
create_time,
update_time,
last_login_time
) VALUES (
$1, $2, $3,$4, NOW(), NOW(),now()
)
RETURNING id;
-- name: UpdateUserLastLoginTime :exec
UPDATE "user"
SET last_login_time = NOW()
WHERE id = $1;
@@ -1,8 +1,3 @@
-- 插入用户并返回刚创建的记录
-- name: InsertUser :execrows
INSERT INTO user_info (id, account, password,username)
VALUES ($1, $2, $3,$4);
-- 根据 ID 查询单条用户记录
-- name: GetUserById :one
SELECT *
@@ -0,0 +1,13 @@
-- name: InsertUserOAuth :exec
INSERT INTO user_oauth (
id,
user_id,
type,
openid,
create_time,
update_time
) VALUES (
$1, $2, $3, $4, NOW(), NOW()
);
+26 -18
View File
@@ -38,34 +38,32 @@ type MoneyUserCategory struct {
CreateTime pgtype.Timestamp
}
// 共享空间(一个空间包含多个成员)
type Space struct {
// 空间ID
ID int64
// 空间名称
Name pgtype.Text
// 空间邀请码
ID int64
Name pgtype.Text
InviteCode string
// 空间创建时间
CreateTime pgtype.Timestamp
// 空间更新时间
UpdateTime pgtype.Timestamp
}
// 共享空间成员表
type SpaceUser struct {
// 主键ID
ID int64
// 所属空间ID
SpaceID int64
// 用户ID(唯一,每用户只加入一个空间)
UserID int64
// 成员角色:0创建者 1管理员 2普通
Role int32
// 加入空间时间
ID int64
SpaceID int64
UserID int64
Role int32
JoinTime pgtype.Timestamp
}
type User struct {
ID int64
Username string
Avatar string
Status int32
LastLoginTime pgtype.Timestamptz
CreateTime pgtype.Timestamptz
UpdateTime pgtype.Timestamptz
}
type UserInfo struct {
ID int64
SeqNo pgtype.Int4
@@ -79,3 +77,13 @@ type UserInfo struct {
ActiveTime pgtype.Timestamp
LastLoginTime pgtype.Timestamp
}
type UserOauth struct {
ID int64
UserID int64
Type int32
Openid string
Unionid pgtype.Text
CreateTime pgtype.Timestamptz
UpdateTime pgtype.Timestamptz
}
+9 -10
View File
@@ -19,13 +19,12 @@ func (q *Queries) DeleteSpace(ctx context.Context, id int64) error {
return err
}
const getSpaceById = `-- name: GetSpaceById :one
SELECT id, name, invite_code, create_time, update_time FROM space WHERE id = $1
const findSpaceByInviteCode = `-- name: FindSpaceByInviteCode :one
SELECT id, name, invite_code, create_time, update_time FROM space WHERE invite_code = $1
`
// 根据id获取分享空间信息
func (q *Queries) GetSpaceById(ctx context.Context, id int64) (Space, error) {
row := q.db.QueryRow(ctx, getSpaceById, id)
func (q *Queries) FindSpaceByInviteCode(ctx context.Context, inviteCode string) (Space, error) {
row := q.db.QueryRow(ctx, findSpaceByInviteCode, inviteCode)
var i Space
err := row.Scan(
&i.ID,
@@ -37,13 +36,13 @@ func (q *Queries) GetSpaceById(ctx context.Context, id int64) (Space, error) {
return i, err
}
const getSpaceByInviteCode = `-- name: GetSpaceByInviteCode :one
SELECT id, name, invite_code, create_time, update_time FROM space WHERE invite_code = $1
const getSpaceById = `-- name: GetSpaceById :one
SELECT id, name, invite_code, create_time, update_time FROM space WHERE id = $1
`
// 根据验证码获取空间
func (q *Queries) GetSpaceByInviteCode(ctx context.Context, inviteCode string) (Space, error) {
row := q.db.QueryRow(ctx, getSpaceByInviteCode, inviteCode)
// 根据id获取分享空间信息
func (q *Queries) GetSpaceById(ctx context.Context, id int64) (Space, error) {
row := q.db.QueryRow(ctx, getSpaceById, id)
var i Space
err := row.Scan(
&i.ID,
+95
View File
@@ -0,0 +1,95 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.30.0
// source: user.sql
package repo
import (
"context"
)
const findUserByOpenID = `-- name: FindUserByOpenID :one
SELECT
u.id AS user_id,
u.username,
u.avatar,
u.status,
o.type AS login_type,
o.openid
FROM user_oauth o
JOIN "user" u ON u.id = o.user_id
WHERE o.openid = $1
AND o.type = $2
LIMIT 1
`
type FindUserByOpenIDParams struct {
Openid string
Type int32
}
type FindUserByOpenIDRow struct {
UserID int64
Username string
Avatar string
Status int32
LoginType int32
Openid string
}
func (q *Queries) FindUserByOpenID(ctx context.Context, arg FindUserByOpenIDParams) (FindUserByOpenIDRow, error) {
row := q.db.QueryRow(ctx, findUserByOpenID, arg.Openid, arg.Type)
var i FindUserByOpenIDRow
err := row.Scan(
&i.UserID,
&i.Username,
&i.Avatar,
&i.Status,
&i.LoginType,
&i.Openid,
)
return i, err
}
const insertUser = `-- name: InsertUser :exec
INSERT INTO "user" (
id,
username,
avatar,
status,
create_time,
update_time
) VALUES (
$1, $2, $3,$4, NOW(), NOW()
)
RETURNING id
`
type InsertUserParams struct {
ID int64
Username string
Avatar string
Status int32
}
func (q *Queries) InsertUser(ctx context.Context, arg InsertUserParams) error {
_, err := q.db.Exec(ctx, insertUser,
arg.ID,
arg.Username,
arg.Avatar,
arg.Status,
)
return err
}
const updateUserLastLoginTime = `-- name: UpdateUserLastLoginTime :exec
UPDATE "user"
SET last_login_time = NOW()
WHERE id = $1
`
func (q *Queries) UpdateUserLastLoginTime(ctx context.Context, id int64) error {
_, err := q.db.Exec(ctx, updateUserLastLoginTime, id)
return err
}
@@ -7,8 +7,6 @@ package repo
import (
"context"
"github.com/jackc/pgx/v5/pgtype"
)
const getUserByAccount = `-- name: GetUserByAccount :one
@@ -95,32 +93,6 @@ func (q *Queries) GetUserForLogin(ctx context.Context, arg GetUserForLoginParams
return i, err
}
const insertUser = `-- name: InsertUser :execrows
INSERT INTO user_info (id, account, password,username)
VALUES ($1, $2, $3,$4)
`
type InsertUserParams struct {
ID int64
Account string
Password string
Username pgtype.Text
}
// 插入用户并返回刚创建的记录
func (q *Queries) InsertUser(ctx context.Context, arg InsertUserParams) (int64, error) {
result, err := q.db.Exec(ctx, insertUser,
arg.ID,
arg.Account,
arg.Password,
arg.Username,
)
if err != nil {
return 0, err
}
return result.RowsAffected(), nil
}
const updateUserActiveTime = `-- name: UpdateUserActiveTime :exec
UPDATE user_info
SET active_time = now()
@@ -0,0 +1,40 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.30.0
// source: user_oauth.sql
package repo
import (
"context"
)
const insertUserOAuth = `-- name: InsertUserOAuth :exec
INSERT INTO user_oauth (
id,
user_id,
type,
openid,
create_time,
update_time
) VALUES (
$1, $2, $3, $4, NOW(), NOW()
)
`
type InsertUserOAuthParams struct {
ID int64
UserID int64
Type int32
Openid string
}
func (q *Queries) InsertUserOAuth(ctx context.Context, arg InsertUserOAuthParams) error {
_, err := q.db.Exec(ctx, insertUserOAuth,
arg.ID,
arg.UserID,
arg.Type,
arg.Openid,
)
return err
}
+19 -16
View File
@@ -12,6 +12,25 @@ CREATE TABLE user_info (
last_login_time TIMESTAMP
);
CREATE TABLE "user" (
"id" int8 NOT NULL,
"username" varchar(255) NOT NULL ,
"avatar" varchar(255) NOT NULL ,
"status" int4 NOT NULL DEFAULT 1,
"last_login_time" timestamptz(6),
"create_time" timestamptz(6),
"update_time" timestamptz(6)
);
CREATE TABLE "user_oauth" (
"id" int8 NOT NULL,
"user_id" int8 NOT NULL,
"type" int4 NOT NULL,
"openid" varchar(255) COLLATE "pg_catalog"."default" NOT NULL,
"create_time" timestamptz(6) NOT NULL,
"update_time" timestamptz(6) NOT NULL
);
CREATE TABLE money_record(
id BIGINT PRIMARY KEY,
category_id BIGINT NOT NULL,
@@ -51,18 +70,9 @@ CREATE TABLE space (
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-- 注释
COMMENT ON TABLE space IS '共享空间(一个空间包含多个成员)';
COMMENT ON COLUMN space.id IS '空间ID';
COMMENT ON COLUMN space.name IS '空间名称';
COMMENT ON COLUMN space.invite_code IS '空间邀请码';
COMMENT ON COLUMN space.create_time IS '空间创建时间';
COMMENT ON COLUMN space.update_time IS '空间更新时间';
ALTER TABLE space
ADD CONSTRAINT space_invite_code_key UNIQUE (invite_code);
-- 空间成员表(每个用户只能加入一个空间)
CREATE TABLE space_user (
id BIGSERIAL PRIMARY KEY,
@@ -72,10 +82,3 @@ CREATE TABLE space_user (
join_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-- 注释
COMMENT ON TABLE space_user IS '共享空间成员表';
COMMENT ON COLUMN space_user.id IS '主键ID';
COMMENT ON COLUMN space_user.space_id IS '所属空间ID';
COMMENT ON COLUMN space_user.user_id IS '用户ID(唯一,每用户只加入一个空间)';
COMMENT ON COLUMN space_user.role IS '成员角色:0创建者 1管理员 2普通';
COMMENT ON COLUMN space_user.join_time IS '加入空间时间';
+21 -43
View File
@@ -6,56 +6,34 @@ option go_package = "auth";
import "api.proto";
// 登录请求
message LoginDefaultReq {
string Account = 1 [(api.body)="account", (api.vd)="$!=''"];
string Password = 2 [(api.body)="password", (api.vd)="$!=''"];
message LoginQqReq {
string openid = 1;
string username = 2;
string avatar = 3;
}
message LoginWxReq {
string code = 1;
}
// 登录响应
message LoginDefaultResp {
string Token = 1 [(api.body)="token"];
string RefreshToken = 2 [(api.body)="refreshToken"];
int64 UserId = 3 [(api.body)="userId"];
string Username = 4 [(api.body)="username"];
int32 SeqNo = 5 [(api.body)="seqNo"];
int32 Gender = 6 [(api.body)="gender"];
}
// 注册请求
message RegisterDefaultReq {
string Account = 1 [(api.body)="account", (api.vd)="$!=''"];
string Password = 2 [(api.body)="password", (api.vd)="$!=''"];
}
// 注册响应
message RegisterDefaultResp {}
// 刷新 access token 请求
message RefreshAccessTokenReq {}
// 刷新 access token 响应
message RefreshAccessTokenResp {
string AccessToken = 1 [(api.body)="accessToken"];
message LoginResp {
// JWT
string token = 1 [(api.body)="token"];
// 用户ID
int64 userId = 2 [(api.body)="userId"];
// 昵称
string username = 3 [(api.body)="username"];
// 头像
string avatar = 4 [(api.body)="avatar"];
}
// 登录服务
service LoginService {
rpc LoginDefault(LoginDefaultReq) returns(LoginDefaultResp) {
option (api.post) = "/auth/login/default";
rpc LoginQq(LoginQqReq) returns (LoginResp) {
option (api.post) = "/auth/login/qq";
}
}
// 注册服务
service RegisterService {
rpc RegisterDefault(RegisterDefaultReq) returns(RegisterDefaultResp) {
option (api.post) = "/auth/register/default";
}
}
// token 服务
service TokenService {
rpc RefreshAccessToken(RefreshAccessTokenReq) returns(RefreshAccessTokenResp) {
option (api.get) = "/auth/refresh/token";
rpc LoginWx(LoginWxReq) returns (LoginResp) {
option (api.post) = "/auth/login/wx";
}
}
@@ -10,10 +10,6 @@ import "space/space_types.proto";
import "space/space_user_types.proto";
service SpaceService {
rpc CreateSpace(CreateSpaceParams) returns (CreateSpaceParams){
option (api.post) = '/space/create';
};
rpc DissolveSpace(DissolveSpaceParams) returns (DissolveSpaceResult){
option (api.post) = '/space/dissolve';
};
+165
View File
@@ -0,0 +1,165 @@
package httpx
import (
"context"
"encoding/json"
"fmt"
"net/url"
"sync"
"time"
"github.com/cloudwego/hertz/pkg/app/client"
"github.com/cloudwego/hertz/pkg/protocol"
"github.com/cloudwego/hertz/pkg/protocol/consts"
)
var (
once sync.Once
clientInstance *HertzClient
)
// HertzClient 定义
type HertzClient struct {
Client *client.Client
Timeout time.Duration
Header map[string]string
}
// Init 初始化单例
func Init() {
once.Do(func() {
c, _ := client.NewClient()
clientInstance = &HertzClient{
Client: c,
Timeout: 5 * time.Second,
Header: make(map[string]string),
}
})
}
// SetHeader 设置默认 header
func SetHeader(key, value string) {
if clientInstance == nil {
Init()
}
clientInstance.Header[key] = value
}
// 支持 value 为任意类型
func buildQueryString(query map[string][]any) string {
if len(query) == 0 {
return ""
}
values := url.Values{}
for k, arr := range query {
for _, v := range arr {
values.Add(k, fmt.Sprintf("%v", v)) // 自动转 string
}
}
return values.Encode()
}
func Get(ctx context.Context, urlStr string, query map[string][]any) (int, string, error) {
if clientInstance == nil {
Init()
}
h := clientInstance
req := &protocol.Request{}
res := &protocol.Response{}
req.Header.SetMethod(consts.MethodGet)
req.SetRequestURI(urlStr)
if qs := buildQueryString(query); qs != "" {
req.SetQueryString(qs)
}
for k, v := range h.Header {
req.Header.Set(k, v)
}
ctx, cancel := context.WithTimeout(ctx, h.Timeout)
defer cancel()
err := h.Client.Do(ctx, req, res)
if err != nil {
return 0, "", err
}
return res.StatusCode(), string(res.Body()), nil
}
func PostJSON(ctx context.Context, urlStr string, query map[string][]any, payload any) (int, string, error) {
if clientInstance == nil {
Init()
}
h := clientInstance
req := &protocol.Request{}
res := &protocol.Response{}
req.Header.SetMethod(consts.MethodPost)
req.Header.SetContentTypeBytes([]byte("application/json"))
req.SetRequestURI(urlStr)
if qs := buildQueryString(query); qs != "" {
req.SetQueryString(qs)
}
data, err := json.Marshal(payload)
if err != nil {
return 0, "", fmt.Errorf("marshal json error: %w", err)
}
req.SetBody(data)
for k, v := range h.Header {
req.Header.Set(k, v)
}
ctx, cancel := context.WithTimeout(ctx, h.Timeout)
defer cancel()
err = h.Client.Do(ctx, req, res)
if err != nil {
return 0, "", err
}
return res.StatusCode(), string(res.Body()), nil
}
func PostForm(ctx context.Context, urlStr string, query map[string][]any, form map[string]string) (int, string, error) {
if clientInstance == nil {
Init()
}
h := clientInstance
req := &protocol.Request{}
res := &protocol.Response{}
req.Header.SetMethod(consts.MethodPost)
req.SetRequestURI(urlStr)
if qs := buildQueryString(query); qs != "" {
req.SetQueryString(qs)
}
req.SetFormData(form)
for k, v := range h.Header {
req.Header.Set(k, v)
}
ctx, cancel := context.WithTimeout(ctx, h.Timeout)
defer cancel()
err := h.Client.Do(ctx, req, res)
if err != nil {
return 0, "", err
}
return res.StatusCode(), string(res.Body()), nil
}
func JSONStringToMap(jsonStr string) (map[string]interface{}, error) {
var result map[string]interface{}
if err := json.Unmarshal([]byte(jsonStr), &result); err != nil {
return nil, err
}
return result, nil
}
+11 -6
View File
@@ -6,17 +6,22 @@ import (
)
// GenerateCode 生成指定长度的随机邀请码(大写字母+数字)
func GenerateCode(length int) (string, error) {
// 不会返回错误,如果随机失败,会自动重试
func GenerateCode(length int) string {
const charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
code := make([]byte, length)
for i := 0; i < length; i++ {
num, err := rand.Int(rand.Reader, big.NewInt(int64(len(charset))))
if err != nil {
return "", err
for {
num, err := rand.Int(rand.Reader, big.NewInt(int64(len(charset))))
if err != nil {
// 随机失败,重试
continue
}
code[i] = charset[num.Int64()]
break
}
code[i] = charset[num.Int64()]
}
return string(code), nil
return string(code)
}
+25 -49
View File
@@ -13,16 +13,9 @@ type CustomClaims struct {
jwt.RegisteredClaims
}
type TokenResult struct {
Claims *CustomClaims
IsValid bool
IsExpired bool
}
type jwtManager struct {
secret string
accessExpiry time.Duration
refreshExpiry time.Duration
secret string
tokenExpiry time.Duration
}
var (
@@ -30,76 +23,59 @@ var (
once sync.Once
)
// InitJwt 初始化全局 JWT 配置,只能调用一次
// InitJwt 初始化全局 JWT 配置
func InitJwt() {
once.Do(func() {
manager = &jwtManager{
secret: conf.GetConf().JWT.Secret,
accessExpiry: conf.GetConf().JWT.AccessExpiry,
refreshExpiry: conf.GetConf().JWT.RefreshExpiry,
secret: conf.GetConf().JWT.Secret,
tokenExpiry: conf.GetConf().JWT.AccessExpiry, // 直接当唯一 token
}
})
}
// CreateAccessToken 全局函数创建 Access Token
func CreateAccessToken(userID int64) (string, error) {
return manager.createToken(userID, manager.accessExpiry)
// CreateToken 创建 JWT
func CreateToken(userID int64) (string, error) {
if manager == nil {
return "", jwt.ErrTokenInvalidClaims
}
return manager.createToken(userID)
}
// CreateRefreshToken 全局函数创建 Refresh Token
func CreateRefreshToken(userID int64) (string, error) {
return manager.createToken(userID, manager.refreshExpiry)
}
// VerifyToken 全局函数验证 Token
func VerifyToken(tokenString string) TokenResult {
result := TokenResult{IsValid: false, IsExpired: false}
// VerifyToken 校验 JWT(合法 or 不合法)
func VerifyToken(tokenString string) (*CustomClaims, bool) {
if tokenString == "" || manager == nil {
return result
return nil, false
}
token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
return []byte(manager.secret), nil
})
if token == nil {
return result
if err != nil || !token.Valid {
return nil, false
}
claims, ok := token.Claims.(*CustomClaims)
if !ok {
return result
return nil, false
}
if err != nil || !token.Valid {
return result
}
result.Claims = claims
result.IsValid = true
if claims.ExpiresAt != nil && time.Now().After(claims.ExpiresAt.Time) {
result.IsExpired = true
}
return result
return claims, true
}
// 内部方法,生成 Token
func (j *jwtManager) createToken(userID int64, expiry time.Duration) (string, error) {
func (j *jwtManager) createToken(userID int64) (string, error) {
now := time.Now()
claims := &CustomClaims{
UserID: userID,
RegisteredClaims: jwt.RegisteredClaims{
IssuedAt: jwt.NewNumericDate(time.Now()),
IssuedAt: jwt.NewNumericDate(now),
},
}
switch {
case expiry > 0:
claims.ExpiresAt = jwt.NewNumericDate(time.Now().Add(expiry))
case expiry == -1:
claims.ExpiresAt = nil // 永不过期
default:
claims.ExpiresAt = jwt.NewNumericDate(time.Now().Add(time.Hour))
// 只有大于 0 才设置过期时间
if j.tokenExpiry > 0 {
claims.ExpiresAt = jwt.NewNumericDate(now.Add(j.tokenExpiry))
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
@@ -135,3 +135,10 @@ func DateToString(d pgtype.Date) string {
}
return d.Time.Format("2006-01-02")
}
func Int32ToPgInt4(value int32) pgtype.Int4 {
return pgtype.Int4{
Int32: value,
Valid: true,
}
}
+1
View File
@@ -0,0 +1 @@
EXPO_PUBLIC_QQ_ID=102826474
+13 -1
View File
@@ -9,7 +9,8 @@
"newArchEnabled": true,
"scheme": [
"oneao",
"tencent102826474"
"tencent102826474",
"wxdab3e21a1f7e392f"
],
"splash": {
"image": "./assets/splash-icon.png",
@@ -32,6 +33,7 @@
"favicon": "./assets/favicon.png"
},
"plugins": [
"./plugins/withAndroidSignature",
"expo-router",
"expo-font",
[
@@ -39,6 +41,16 @@
{
"appId": "102826474"
}
],
"expo-wechat",
[
"expo-build-properties",
{
"android": {
"usesCleartextTraffic": true,
"extraProguardRules": "-keep class com.tencent.mm.opensdk.** { *; }\n-keep class com.tencent.wxop.** { *; }\n-keep class com.tencent.mm.sdk.** { *; }"
}
}
]
]
}
+1 -12
View File
@@ -4,17 +4,6 @@ module.exports = function (api) {
presets: [
['babel-preset-expo', { jsxImportSource: 'nativewind' }],
'nativewind/babel',
],
plugins: [
[
'module-resolver',
{
root: ['./src'],
alias: {
'@': './src',
},
},
],
],
]
}
}
@@ -0,0 +1,17 @@
{
"android": {
"keystore": {
"keystorePath": "credentials/oneao-android.keystore",
"keystorePassword": "zhang520..",
"keyAlias": "oneao-android",
"keyPassword": "zhang520.."
}
},
"ios": {
"provisioningProfilePath": "ios/certs/profile.mobileprovision",
"distributionCertificate": {
"path": "ios/certs/dist-cert.p12",
"password": "password"
}
}
}
+16 -15
View File
@@ -17,27 +17,26 @@
"@gluestack/ui-next-adapter": "^3.0.3",
"@legendapp/motion": "2.4.0",
"@react-native-async-storage/async-storage": "2.2.0",
"@react-native-community/datetimepicker": "8.4.4",
"@react-native-segmented-control/segmented-control": "2.5.7",
"@react-navigation/drawer": "^7.7.9",
"@react-navigation/drawer": "^7.5.0",
"@yz1311/react-native-wheel-picker": "^0.4.5",
"alova": "^3.3.4",
"axios": "^1.13.2",
"big.js": "^7.0.1",
"dayjs": "^1.11.19",
"expo": "~54.0.23",
"expo-blur": "~15.0.7",
"expo-clipboard": "~8.0.7",
"expo-constants": "~18.0.10",
"expo-font": "~14.0.9",
"expo-linear-gradient": "~15.0.7",
"expo-linking": "~8.0.8",
"expo-qq": "^0.1.5",
"expo-router": "~6.0.17",
"expo-splash-screen": "~31.0.10",
"expo-status-bar": "~3.0.8",
"expo": "~54.0.32",
"expo-blur": "~15.0.8",
"expo-build-properties": "~1.0.10",
"expo-clipboard": "~8.0.8",
"expo-constants": "~18.0.13",
"expo-font": "~14.0.11",
"expo-linear-gradient": "~15.0.8",
"expo-linking": "~8.0.11",
"expo-qq": "^0.1.6",
"expo-router": "~6.0.22",
"expo-splash-screen": "~31.0.13",
"expo-status-bar": "~3.0.9",
"expo-wechat": "^0.2.6",
"lucide-react-native": "^0.510.0",
"moment": "^2.30.1",
"nativewind": "^4.2.1",
"react": "19.1.0",
"react-dom": "19.1.0",
@@ -61,9 +60,11 @@
},
"devDependencies": {
"@antfu/eslint-config": "^6.2.0",
"@babel/plugin-transform-react-jsx": "^7.28.6",
"@types/big.js": "^6.2.2",
"@types/react": "~19.1.0",
"babel-plugin-module-resolver": "^5.0.2",
"babel-preset-expo": "^54.0.10",
"baseline-browser-mapping": "^2.9.14",
"eslint": "^9.38.0",
"react-native-iconfont-cli": "^2.2.4",
@@ -0,0 +1,47 @@
// plugins/withAndroidSignature.js
const fs = require('node:fs')
const path = require('node:path')
const { withAppBuildGradle } = require('expo/config-plugins')
module.exports = function withAndroidSignature(config) {
return withAppBuildGradle(config, (config) => {
if (config.modResults.language === 'groovy') {
config.modResults.contents = setAndroidSignature(config.modResults.contents)
}
else {
throw new Error('如果不是 groovy,则无法在 app/build.gradle 中设置 signingConfigs')
}
return config
})
}
function setAndroidSignature(appBuildGradle) {
if (!fs.existsSync(path.resolve(__dirname, '../credentials/credentials.json'))) {
console.warn('警告:没有设置正式版本的 Android Keystore 文件,因为 credentials.json 不存在。')
return appBuildGradle
}
const info = JSON.parse(fs.readFileSync(path.resolve(__dirname, '../credentials/credentials.json'), { encoding: 'utf8' }))
// 使用正则表达式插入签名信息
let output = appBuildGradle.replace(
/(signingConfigs\s*\{)/,
`$1
release {
storeFile file(${JSON.stringify(path.resolve(__dirname, '../credentials/oneao-android.keystore'))})
storePassword ${JSON.stringify(info.android.keystore.keystorePassword)}
keyAlias ${JSON.stringify(info.android.keystore.keyAlias)}
keyPassword ${JSON.stringify(info.android.keystore.keyPassword)}
}`,
)
// 使用正则表达式替换 signingConfig
output = output.replace(
/(release\s*\{)[^}]*?signingConfig\s+signingConfigs\.debug/,
`$1
signingConfig signingConfigs.release
`,
)
return output
}
+497 -611
View File
File diff suppressed because it is too large. Load diff
@@ -1,47 +1,27 @@
import type { TabbarItem } from '@/components/custom/Tabbar'
import CustomTabbar from '@/components/custom/Tabbar'
import { toast } from '@/utils/toast'
export const unstable_settings = {
initialRouteName: 'money/index',
}
import { TabSlot } from 'expo-router/ui'
import { Text, View } from 'react-native'
export default function TabsLayout() {
const tabbarOptions: TabbarItem[] = [
{
name: 'money',
href: '/money',
icon: 'CircleDollarSign',
},
{
name: 'love',
href: '/love',
icon: 'Heart',
},
{
name: 'app',
icon: 'LayoutGrid',
activeIcon: 'Smile',
iconSize: 26,
onPress: () => {
toast.show({
title: '该功能尚未开发,请尽情期待!',
})
},
},
{
name: 'chat',
href: '/chat',
icon: 'MessageCircle',
},
{
name: 'user',
href: '/user',
icon: 'CircleUserRound',
},
]
return (
<CustomTabbar data={tabbarOptions} />
<View className="flex-1 bg-gray-100">
<View className="flex-1 px-4 pt-4 pb-24">
<TabSlot />
</View>
<View
className="
absolute
left-3 right-3 bottom-8
h-14
flex-row items-center
px-2
gap-4
"
>
<View className="bg-white rounded-md shadow-lg h-12 w-12"></View>
<View className="flex-1 bg-white rounded-md shadow-lg h-12"></View>
<View className="bg-white rounded-md shadow-lg h-12 w-12"></View>
</View>
</View>
)
}
Whitespace-only changes.
@@ -13,11 +13,11 @@ export default function User() {
return (
<SafeAreaView className="flex-1 p-4">
<View className="flex flex-row items-center ">
<View className="flex flex-row items-center">
<Avatar size="md" className="border-0">
<AvatarImage
className="bg-white"
source={require('@/static/images/logo.png')}
source={{ uri: userStore.userInfo?.avatar }}
/>
</Avatar>
<Text className="text-xl font-semibold ml-3">{userStore.userInfo?.username}</Text>
+230 -61
View File
@@ -1,94 +1,263 @@
import { useEvent } from 'expo'
import ExpoQQ from 'expo-qq'
import { useRouter } from 'expo-router'
import { useEffect } from 'react'
import ExpoWeChat from 'expo-wechat'
import { useEffect, useState } from 'react'
import { Image, Text, View } from 'react-native'
import { AButton, ACheckbox } from '@/components/common/ao'
import CustomHeader from '@/components/custom/Header'
import { Button, ButtonText } from '@/components/ui/button'
import { IconQq, IconWeixin } from '@/components/iconfont'
import { loginQqApi, loginWxApi } from '@/request/api/auth'
import { useUserStore } from '@/store/user'
import { toast } from '@/utils/toast'
export default function LoginScreen() {
const [loading, setLoading] = useState(false)
const [isAgree, setIsAgree] = useState(true)
const [form, setForm] = useState({
type: 0,
openid: '',
code: '',
})
export default function AuthIndex() {
const router = useRouter()
const userStore = useUserStore()
function toPath(url: string) {
router.push(url)
const onLoginFinished = useEvent(ExpoQQ, 'onLoginFinished')
const onGetUserInfo = useEvent(ExpoQQ, 'onGetUserInfo')
const authResult = useEvent(ExpoWeChat, 'onAuthResult')
async function onQQLogin() {
setLoading(true)
setForm(val => ({
...val,
type: 1,
}))
await ExpoQQ.login(['get_user_info'])
}
// /// 监听登录结果,你也可以使用ExpoQQ.addListener('onLoginFinished', callback)来实现,但请不要忘记移除监听
// const onSendLoginFinished = useEvent(ExpoQQ, 'onGetUserInfo')
// const onLoginFinished = useEvent(ExpoQQ, 'onLoginFinished')
async function onWeChatLogin() {
setLoading(true)
// useEffect(() => {
// console.log(onSendLoginFinished)
// }, [onSendLoginFinished])
// 检查微信是否安装
const isInstalled = await ExpoWeChat.isWXAppInstalled()
if (!isInstalled) {
toast.show({
title: onLoginFinished?.errorMessage || '请先安装微信',
})
setLoading(false)
return
}
// /// 国内应用需要在用户接受隐私协议后再初始化
// useEffect(() => {
// const init = async () => {
// await ExpoQQ.init('102826474', 'universal link')
// }
// init()
// }, [])
setForm(val => ({
...val,
type: 0,
}))
// useEffect(() => {
// if (!onLoginFinished || !onLoginFinished.success)
// return
ExpoWeChat.sendAuthRequest('snsapi_userinfo', 'state123')
}
// const fetchUserInfo = async () => {
// try {
// // 1️⃣ 确认 SDK 已经拿到 token
// const tokenInfo = await ExpoQQ.getLoginTokenInfo()
// console.log('tokenInfo', tokenInfo)
useEffect(() => {
ExpoQQ.init('102826474', '')
ExpoWeChat.registerApp('wxdab3e21a1f7e392f', '')
}, [])
// // 2️⃣ 再请求用户信息
// await ExpoQQ.sendGetUserInfoReq()
// }
// catch (e) {
// console.error('QQ 登录未完成', e)
// }
// }
useEffect(() => {
if (!onLoginFinished) {
return
}
// fetchUserInfo()
// }, [onLoginFinished])
if (!onLoginFinished.success) {
toast.show({
title: onLoginFinished?.errorMessage || '授权失败,请检查手机是否安装 QQ 或确认授权',
})
setLoading(false)
return
}
// /// 调用qq登陆
// const loginByQQ = async () => {
// await ExpoQQ.login(['get_user_info'])
// }
const fetchUserInfo = async () => {
try {
const tokenInfo = await ExpoQQ.getLoginTokenInfo()
if (!tokenInfo.openId) {
toast.show({
title: tokenInfo?.errorMessage || '授权失败,请检查手机是否安装 QQ 或确认授权',
})
setLoading(false)
return
}
setForm(val => ({
...val,
openid: String(tokenInfo.openId),
}))
await ExpoQQ.sendGetUserInfoReq()
}
catch (e) {
console.error('QQ 登录未完成', e)
setLoading(false)
}
}
fetchUserInfo()
}, [onLoginFinished])
// QQ登录
useEffect(() => {
const handleLogin = async () => {
if (!onGetUserInfo)
return
try {
const loginRes = await loginQqApi({
openid: form.openid,
username: onGetUserInfo.nickname || '',
avatar: onGetUserInfo.figureurlQq_2 || onGetUserInfo.figureurl_2,
})
if (loginRes.isSuccess) {
userStore.setUserInfo({
token: loginRes.data.token,
id: loginRes.data.userId,
username: loginRes.data.username,
avatar: loginRes.data.avatar,
})
console.log(loginRes.data.token)
router.push('/')
}
}
catch (err) {
console.error('登录接口出错', err)
}
finally {
setLoading(false)
}
}
handleLogin()
}, [onGetUserInfo])
// 微信登录
useEffect(() => {
if (!authResult)
return
const handleLogin = async () => {
if (authResult.errorCode === 0) {
try {
const loginRes = await loginWxApi({
code: authResult.code,
})
if (loginRes.isSuccess) {
userStore.setUserInfo({
token: loginRes.data.token,
id: loginRes.data.userId,
username: loginRes.data.username,
avatar: loginRes.data.avatar,
})
router.push('/')
}
}
catch (err) {
console.error('登录接口出错', err)
}
finally {
setLoading(false)
}
}
else {
console.log('授权失败:', authResult.errorMessage)
setLoading(false)
}
}
handleLogin()
}, [authResult])
function testLogin() {
// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjo3NjY3ODU5ODIxNjUwNjEsImlhdCI6MTc2OTM0ODI0Nn0.17ZNaHD3HSLM8dVn_JQK-gvsG9MKj47IRYV9D4xZkzs
userStore.setUserInfo({
token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjo3NjY3ODU5ODIxNjUwNjEsImlhdCI6MTc2OTM0ODI0Nn0.17ZNaHD3HSLM8dVn_JQK-gvsG9MKj47IRYV9D4xZkzs',
id: 766785982165061,
username: 'Zhang',
avatar: 'http://thirdqq.qlogo.cn/ek_qqapp/AQHVialeUibE42oV8RvTTVZ4tyRlPYeJrUibWTwtCPfV68E4rSzn9cw00GkXQ3QDTiawwhjoqQb7/100',
})
router.push('/')
}
return (
<View className="flex-1">
<View className="flex-1 bg-white px-6 justify-center">
<CustomHeader
showHeader={false}
/>
<View className="flex-1 bg-white items-center justify-center">
<Image
source={require('@/static/images/work.png')}
style={{ width: '100%', height: 280 }}
className="mb-6"
/>
<View className="items-center mb-12">
<Image
source={require('@/static/images/logo.png')}
style={{ width: 60, height: 60 }}
className="mb-6"
className="w-20 h-20 mb-4"
resizeMode="contain"
/>
<Text className="font-bold text-3xl text-[#333] tracking-wide">
ONEAO
<Text className="text-xl font-semibold text-gray-900">
Welcome to OneAO
</Text>
</View>
<View className="w-full flex flex-col gap-3 mt-12 px-3">
<Button action="secondary" onPress={() => toPath('/auth/login')}>
<ButtonText>登录</ButtonText>
</Button>
<View className="flex flex-col gap-4">
<AButton
leftIcon={
<IconWeixin color="#fff" />
}
loading={loading}
onPress={onWeChatLogin}
>
WeChat
</AButton>
<Button action="secondary" onPress={() => toPath('/auth/register')}>
<ButtonText>注册</ButtonText>
</Button>
</View>
<AButton
variant="outline"
leftIcon={
<IconQq />
}
loading={loading}
onPress={onQQLogin}
>
QQ
</AButton>
<AButton
variant="outline"
leftIcon={
<IconQq />
}
loading={loading}
onPress={testLogin}
>
模拟登录
</AButton>
</View>
<View className="mt-10 items-center flex flex-row justify-center">
<ACheckbox
checked={isAgree}
size="sm"
label={(
<Text className="text-sm text-gray-400 text-center leading-4">
登录即表示你同意我们的
<Text className="text-gray-600"> 用户协议 </Text>
和
<Text className="text-gray-600"> 隐私政策</Text>
</Text>
)}
onChange={(val) => {
setIsAgree(val)
}}
/>
</View>
</View>
)
}
@@ -157,7 +157,6 @@ export default function CreateCategory({
data={flatListData}
keyExtractor={([groupName]) => groupName}
renderItem={renderGroup}
initialNumToRender={1}
/>
</ADrawer>
)
@@ -1,15 +1,13 @@
import type { icons } from 'lucide-react-native'
import type { ViewStyle } from 'react-native'
import type { LucideIconProps } from './LucideIcon'
import React from 'react'
import { View } from 'react-native'
import {
ButtonSpinner,
ButtonText,
Button as NativeButton,
} from '@/components/ui/button'
import LucideIcon from './LucideIcon'
type IconProp = (LucideIconProps & { icon: keyof typeof icons }) | React.ReactNode
type IconProp = React.ReactNode | (() => React.ReactNode)
interface CustomButtonProps {
children?: React.ReactNode
@@ -21,7 +19,6 @@ interface CustomButtonProps {
action?: 'primary' | 'secondary' | 'positive' | 'negative' | 'default'
variant?: 'solid' | 'outline' | 'link'
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'
leftIcon?: IconProp
rightIcon?: IconProp
}
@@ -41,31 +38,39 @@ const Button: React.FC<CustomButtonProps> = ({
}) => {
const isDisabled = disabled || loading
const hasChildren = !!children
const renderLeftIcon = () => {
if (loading)
return <ButtonSpinner color="#fff" className={hasChildren ? 'mr-2' : ''} />
if (!leftIcon)
const renderIcon = (
icon?: IconProp,
position: 'left' | 'right' = 'left',
) => {
if (!icon)
return null
if (React.isValidElement(leftIcon)) {
return <span className={hasChildren ? 'mr-2' : ''}>{leftIcon}</span>
if (loading && position === 'left') {
const spinnerColor = variant === 'outline'
? 'rgba(0,0,0,0.6)'
: 'rgba(255,255,255,0.9)'
return (
<View className={hasChildren ? 'mr-2' : undefined}>
<ButtonSpinner color={spinnerColor} />
</View>
)
}
const { icon, ...props } = leftIcon as LucideIconProps & { icon: keyof typeof icons }
return <LucideIcon icon={icon} className={hasChildren ? 'mr-2' : ''} {...props} />
}
const node = typeof icon === 'function'
? icon()
: icon
const renderRightIcon = () => {
if (!rightIcon)
return null
if (React.isValidElement(rightIcon)) {
return <span className={hasChildren ? 'ml-2' : ''}>{rightIcon}</span>
}
const { icon, ...props } = rightIcon as LucideIconProps & { icon: keyof typeof icons }
return <LucideIcon icon={icon} className={hasChildren ? 'ml-2' : ''} {...props} />
return (
<View className={hasChildren
? position === 'left'
? 'mr-2'
: 'ml-2'
: undefined}
>
{node}
</View>
)
}
return (
@@ -78,13 +83,9 @@ const Button: React.FC<CustomButtonProps> = ({
variant={variant}
size={size}
>
{renderLeftIcon()}
{
children && (
<ButtonText>{children}</ButtonText>
)
}
{renderRightIcon()}
{renderIcon(leftIcon, 'left')}
{children && <ButtonText>{children}</ButtonText>}
{renderIcon(rightIcon, 'right')}
</NativeButton>
)
}
@@ -11,33 +11,36 @@ import { CheckIcon } from '@/components/ui/icon'
interface CustomCheckboxProps {
value?: string
isChecked: boolean
onChange: (checked: boolean) => void
label: React.ReactNode
checked?: boolean
onChange?: (checked: boolean) => void
label?: React.ReactNode
className?: string
style?: ViewStyle
disabled?: boolean
icon?: React.ElementType
size?: 'sm' | 'md' | 'lg'
}
const Checkbox: React.FC<CustomCheckboxProps> = ({
value,
isChecked,
checked,
onChange,
label,
className,
style,
disabled,
icon,
size,
}) => {
return (
<NativeCheckbox
value={value ?? ''} // 避免 undefined
isChecked={isChecked}
value={value ?? ''}
isChecked={checked}
onChange={onChange}
className={className}
style={style}
isDisabled={disabled}
size={size}
>
<CheckboxIndicator>
<CheckboxIcon as={icon ?? CheckIcon} />
@@ -1,24 +1,21 @@
'use client';
import React from 'react';
import { createAvatar } from '@gluestack-ui/core/avatar/creator';
'use client'
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils'
import { createAvatar } from '@gluestack-ui/core/avatar/creator'
import { View, Text, Image, Platform } from 'react-native';
import { tva, useStyleContext, withStyleContext } from '@gluestack-ui/utils/nativewind-utils'
import { tva } from '@gluestack-ui/utils/nativewind-utils';
import {
withStyleContext,
useStyleContext,
} from '@gluestack-ui/utils/nativewind-utils';
const SCOPE = 'AVATAR';
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
import React from 'react'
import { Image, Platform, Text, View } from 'react-native'
const SCOPE = 'AVATAR'
const UIAvatar = createAvatar({
Root: withStyleContext(View, SCOPE),
Badge: View,
Group: View,
Image: Image,
Image,
FallbackText: Text,
});
})
const avatarStyle = tva({
base: 'rounded-full justify-center items-center relative bg-primary-600 group-[.avatar-group]/avatar-group:-ml-2.5',
@@ -32,7 +29,7 @@ const avatarStyle = tva({
'2xl': 'w-32 h-32',
},
},
});
})
const avatarFallbackTextStyle = tva({
base: 'text-typography-0 font-semibold overflow-hidden text-transform:uppercase web:cursor-default',
@@ -47,11 +44,11 @@ const avatarFallbackTextStyle = tva({
'2xl': 'text-5xl',
},
},
});
})
const avatarGroupStyle = tva({
base: 'group/avatar-group flex-row-reverse relative avatar-group',
});
})
const avatarBadgeStyle = tva({
base: 'w-5 h-5 bg-success-500 rounded-full absolute right-0 bottom-0 border-background-0 border-2',
@@ -65,22 +62,22 @@ const avatarBadgeStyle = tva({
'2xl': 'w-8 h-8',
},
},
});
})
const avatarImageStyle = tva({
base: 'h-full w-full rounded-full absolute',
});
})
type IAvatarProps = Omit<
React.ComponentPropsWithoutRef<typeof UIAvatar>,
'context'
> &
VariantProps<typeof avatarStyle>;
>
& VariantProps<typeof avatarStyle>
const Avatar = React.forwardRef<
React.ComponentRef<typeof UIAvatar>,
IAvatarProps
>(function Avatar({ className, size = 'md', ...props }, ref) {
>(({ className, size = 'md', ...props }, ref) => {
return (
<UIAvatar
ref={ref}
@@ -88,17 +85,17 @@ const Avatar = React.forwardRef<
className={avatarStyle({ size, class: className })}
context={{ size }}
/>
);
});
)
})
type IAvatarBadgeProps = React.ComponentPropsWithoutRef<typeof UIAvatar.Badge> &
VariantProps<typeof avatarBadgeStyle>;
type IAvatarBadgeProps = React.ComponentPropsWithoutRef<typeof UIAvatar.Badge>
& VariantProps<typeof avatarBadgeStyle>
const AvatarBadge = React.forwardRef<
React.ComponentRef<typeof UIAvatar.Badge>,
IAvatarBadgeProps
>(function AvatarBadge({ className, size, ...props }, ref) {
const { size: parentSize } = useStyleContext(SCOPE);
>(({ className, size, ...props }, ref) => {
const { size: parentSize } = useStyleContext(SCOPE)
return (
<UIAvatar.Badge
@@ -112,18 +109,18 @@ const AvatarBadge = React.forwardRef<
class: className,
})}
/>
);
});
)
})
type IAvatarFallbackTextProps = React.ComponentPropsWithoutRef<
typeof UIAvatar.FallbackText
> &
VariantProps<typeof avatarFallbackTextStyle>;
>
& VariantProps<typeof avatarFallbackTextStyle>
const AvatarFallbackText = React.forwardRef<
React.ComponentRef<typeof UIAvatar.FallbackText>,
IAvatarFallbackTextProps
>(function AvatarFallbackText({ className, size, ...props }, ref) {
const { size: parentSize } = useStyleContext(SCOPE);
>(({ className, size, ...props }, ref) => {
const { size: parentSize } = useStyleContext(SCOPE)
return (
<UIAvatar.FallbackText
@@ -137,16 +134,16 @@ const AvatarFallbackText = React.forwardRef<
class: className,
})}
/>
);
});
)
})
type IAvatarImageProps = React.ComponentPropsWithoutRef<typeof UIAvatar.Image> &
VariantProps<typeof avatarImageStyle>;
type IAvatarImageProps = React.ComponentPropsWithoutRef<typeof UIAvatar.Image>
& VariantProps<typeof avatarImageStyle>
const AvatarImage = React.forwardRef<
React.ComponentRef<typeof UIAvatar.Image>,
IAvatarImageProps
>(function AvatarImage({ className, ...props }, ref) {
>(({ className, ...props }, ref) => {
return (
<UIAvatar.Image
ref={ref}
@@ -161,16 +158,16 @@ const AvatarImage = React.forwardRef<
: undefined
}
/>
);
});
)
})
type IAvatarGroupProps = React.ComponentPropsWithoutRef<typeof UIAvatar.Group> &
VariantProps<typeof avatarGroupStyle>;
type IAvatarGroupProps = React.ComponentPropsWithoutRef<typeof UIAvatar.Group>
& VariantProps<typeof avatarGroupStyle>
const AvatarGroup = React.forwardRef<
React.ComponentRef<typeof UIAvatar.Group>,
IAvatarGroupProps
>(function AvatarGroup({ className, ...props }, ref) {
>(({ className, ...props }, ref) => {
return (
<UIAvatar.Group
ref={ref}
@@ -179,7 +176,7 @@ const AvatarGroup = React.forwardRef<
class: className,
})}
/>
);
});
)
})
export { Avatar, AvatarBadge, AvatarFallbackText, AvatarImage, AvatarGroup };
export { Avatar, AvatarBadge, AvatarFallbackText, AvatarGroup, AvatarImage }
@@ -1,12 +1,12 @@
import type { LoginDefaultParams, LoginDefaultResult, RegisterDefaultParams } from '@/types/auth'
import type { LoginQqParams, LoginResult, LoginWxParams } from '@/types/auth'
import alovaInstance from '../index'
const API_PREFIX = '/auth'
export function registerDefaultApi(params: RegisterDefaultParams) {
return alovaInstance.Post<ResponseData<any>>(`${API_PREFIX}/register/default`, params)
export function loginQqApi(params: LoginQqParams) {
return alovaInstance.Post<ResponseData<LoginResult>>(`${API_PREFIX}/login/qq`, params)
}
export function loginDefaultApi(params: LoginDefaultParams) {
return alovaInstance.Post<ResponseData<LoginDefaultResult>>(`${API_PREFIX}/login/default`, params)
export function loginWxApi(params: LoginWxParams) {
return alovaInstance.Post<ResponseData<LoginResult>>(`${API_PREFIX}/login/wx`, params)
}
+38 -77
View File
@@ -1,6 +1,5 @@
import type { Method } from 'alova'
import type { AxiosError } from 'axios'
import type { RefreshTokenResult } from '@/types/auth'
import { axiosRequestAdapter } from '@alova/adapter-axios'
import { createAlova } from 'alova'
import { useNavStore } from '@/store/navigation'
@@ -11,14 +10,13 @@ import { toast } from '@/utils/toast'
enum HttpCode {
Success = 200,
Unauthorized = 401,
RefreshToken = 402,
Fail = 500,
}
// 仅保留「无需登录」接口
const WhiteList = [
'/auth/login/**',
'/auth/register/**',
'/auth/refresh/token',
]
function isWhiteListed(url: string) {
@@ -32,13 +30,14 @@ function isWhiteListed(url: string) {
}
const alovaInstance = createAlova({
// baseURL: 'http://192.168.5.6:8086/app',
baseURL: 'http://192.168.1.137:8086/app',
baseURL: 'http://192.168.5.6:8086/app',
// baseURL: 'http://192.168.1.137:8086/app',
requestAdapter: axiosRequestAdapter(),
timeout: 5000,
cacheFor: null,
responded: {
onSuccess: async (response, method: Method) => {
onSuccess: async (response, _method: Method) => {
const resData = response.data as ResponseData<any>
const result = {
@@ -46,116 +45,78 @@ const alovaInstance = createAlova({
isSuccess: resData.code === HttpCode.Success,
}
// Access Token 失效 → 重新登录
/**
* 登录态失效:
* - 清空本地状态
* - 跳转登录页
* - 不做 token 刷新、不重试请求
*/
if (resData.code === HttpCode.Unauthorized) {
useUserStore.getState().clear()
useNavStore.getState().navigateToAuth()
return
}
// Access Token 过期但 Refresh Token 有效 → 刷新 token 并重试
if (resData.code === HttpCode.RefreshToken) {
try {
const refreshToken = useUserStore.getState().userInfo?.refreshToken
if (!refreshToken) {
useNavStore.getState().navigateToAuth()
return
}
// 调用刷新接口
const res = await alovaInstance.Get<ResponseData<RefreshTokenResult>>('/auth/refresh/token', {
headers: { refreshToken },
}).send()
const newToken = res.data.refreshToken
// 更新 store
useUserStore.getState().setUserInfo({
...useUserStore.getState().userInfo!,
token: newToken,
})
// 重试原请求
method.config.headers.token = newToken
const retryResult = await method.send()
return retryResult
}
catch (err) {
return Promise.reject(err)
}
return Promise.reject(new Error('登录已失效'))
}
return result
},
onError: (error: AxiosError, _method) => {
console.log(error.status)
switch (error.status) {
onError: (error: AxiosError) => {
const status = error.status
switch (status) {
case 400:
toast.show({
title: '请求错误,请检查输入参数',
})
toast.show({ title: '请求错误,请检查输入参数' })
break
case 401:
toast.show({
title: '未授权,请重新登录',
})
toast.show({ title: '未授权,请重新登录' })
break
case 403:
toast.show({
title: '没有权限访问该资源',
})
toast.show({ title: '没有权限访问该资源' })
break
case 404:
toast.show({
title: '请求丢失啦,请稍后再试!',
})
toast.show({ title: '请求丢失啦,请稍后再试!' })
break
case 500:
toast.show({
title: '服务器出错啦,请稍后重试',
})
toast.show({ title: '服务器出错啦,请稍后重试' })
break
case 502:
toast.show({
title: '网关错误,请稍后重试',
})
toast.show({ title: '网关错误,请稍后重试' })
break
case 503:
toast.show({
title: '服务暂不可用,请稍后再试',
})
toast.show({ title: '服务暂不可用,请稍后再试' })
break
case 504:
toast.show({
title: '网关超时,请稍后再试',
})
toast.show({ title: '网关超时,请稍后再试' })
break
default:
toast.show({
title: `服务器出错啦,请稍后重试`,
})
toast.show({ title: '服务器出错啦,请稍后重试' })
break
}
return Promise.reject(error)
},
},
beforeRequest(method) {
// 白名单接口直接放行
if (isWhiteListed(method.url))
return
if (!useUserStore.getState().isLoggedIn()) {
const userStore = useUserStore.getState()
// 未登录直接拦截
if (!userStore.isLoggedIn()) {
useNavStore.getState().navigateToAuth()
return Promise.reject(new Error('未登录'))
}
method.config.headers.token = useUserStore.getState().userInfo?.token ?? ''
// 注入 JWT
method.config.headers.token = userStore.userInfo!.token
// 注入 space 信息(如果存在)
const userSpace = useSpaceStore.getState().userSpace
if (userSpace !== null) {
const spaceID = userSpace.space_id
method.config.headers['x-space-id'] = spaceID
if (userSpace) {
method.config.headers['x-space-id'] = userSpace.space_id
}
},
})
+1 -1
View File
@@ -26,7 +26,7 @@ const useUserStore = create<UserState>()(
set({ userInfo: null, userSpace: null })
},
isLoggedIn: () => !!get().userInfo?.token,
isLoggedIn: () => Boolean(get().userInfo?.token),
}),
{
name: 'user-storage',
+8 -14
View File
@@ -1,22 +1,16 @@
export interface RefreshTokenResult {
refreshToken: string
export interface LoginQqParams {
openid: string
username: string
avatar: string
}
export interface RegisterDefaultParams {
account: string
password: string
export interface LoginWxParams {
code: string
}
export interface LoginDefaultParams {
account: string
password: string
}
export interface LoginDefaultResult {
export interface LoginResult {
token: string
refreshToken: string
userId: number
username: string
seqNo: number
gender: number
avatar: string
}
+3 -7
View File
@@ -10,14 +10,10 @@ declare global {
}
interface UserInfo {
account: string
id: number
seqNo: number
username: string
gender: number
token?: string
refreshToken?: string
rememberMe?: boolean
token: string
username?: string
avatar?: string
}
interface UserSpace {
+147
View File
@@ -0,0 +1,147 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Bottom Nav Demo</title>
<link rel="stylesheet" href="style.css" />
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: system-ui, -apple-system, BlinkMacSystemFont;
}
body {
background: #f6f7f9;
height: 100vh;
}
.content {
padding: 16px;
padding-bottom: 80px;
color: #555;
}
/* 底部栏 */
.bottom-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 56px;
background: #fff;
border-top: 1px solid #e5e5e5;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 12px;
}
/* 左右按钮 */
.nav-btn {
width: 40px;
height: 40px;
border: none;
background: none;
font-size: 18px;
color: #333;
}
/* 中间区域 */
.nav-center {
flex: 1;
text-align: center;
font-size: 14px;
font-weight: 500;
color: #222;
display: flex;
justify-content: center;
align-items: center;
gap: 4px;
}
.nav-center .arrow {
font-size: 12px;
color: #999;
}
/* 扩展菜单 */
.extension {
position: fixed;
bottom: 56px;
left: 12px;
right: 12px;
background: #fff;
border-radius: 12px;
box-shadow: 0 8px 24px rgba(0,0,0,0.08);
transform: translateY(20px);
opacity: 0;
pointer-events: none;
transition: all 0.2s ease;
}
.extension.show {
transform: translateY(0);
opacity: 1;
pointer-events: auto;
}
.extension-item {
padding: 14px 16px;
font-size: 14px;
color: #333;
border-bottom: 1px solid #eee;
}
.extension-item:last-child {
border-bottom: none;
}
.extension-item.danger {
color: #d93026;
}
</style>
</head>
<body>
<main class="content">
<p>当前工具内容区域</p>
</main>
<!-- 扩展菜单 -->
<div class="extension" id="extension">
<div class="extension-item">视图切换</div>
<div class="extension-item">工具设置</div>
<div class="extension-item">导出数据</div>
<div class="extension-item danger">清空记录</div>
</div>
<!-- 底部导航 -->
<nav class="bottom-bar">
<button class="nav-btn">←</button>
<div class="nav-center">
<span class="title">记账 · 本月</span>
<span class="arrow">▾</span>
</div>
<button class="nav-btn" onclick="toggleExt()">⋯</button>
</nav>
<script>
function toggleExt() {
document.getElementById('extension')
.classList.toggle('show')
}
</script>
</body>
</html>
+1 -1
View File
@@ -4,4 +4,4 @@
https://www.bootstrapmb.com/item/14502/preview
111
sqlc generate -f sqlc.yaml