u
This commit is contained in:
1 parent
5a79414319
commit
8663cb2e3d
28 files changed
+743
-755
No files matched your search
@@ -63,3 +63,21 @@ func DissolveSpace(ctx context.Context, c *app.RequestContext) {
|
||||
|
||||
response.Success(c).Send()
|
||||
}
|
||||
|
||||
// EnterSpace .
|
||||
// @router /space/enter [POST]
|
||||
func EnterSpace(ctx context.Context, c *app.RequestContext) {
|
||||
var err error
|
||||
var req space.EnterSpaceParams
|
||||
err = c.BindAndValidate(&req)
|
||||
if err != nil {
|
||||
c.String(consts.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
resp := new(space.EnterSpaceResult)
|
||||
|
||||
userID := middleware.GetUserID(ctx)
|
||||
|
||||
c.JSON(consts.StatusOK, resp)
|
||||
}
|
||||
@@ -28,77 +28,86 @@ 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, 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,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0xbe, 0x01, 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, 0x12, 0x50, 0x0a, 0x0a, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x53, 0x70,
|
||||
0x61, 0x63, 0x65, 0x12, 0x17, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x45, 0x6e, 0x74, 0x65,
|
||||
0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x17, 0x2e, 0x73,
|
||||
0x70, 0x61, 0x63, 0x65, 0x2e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52,
|
||||
0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x10, 0xd2, 0xc1, 0x18, 0x0c, 0x2f, 0x73, 0x70, 0x61, 0x63,
|
||||
0x65, 0x2f, 0x65, 0x6e, 0x74, 0x65, 0x72, 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,
|
||||
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,
|
||||
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{}{
|
||||
(*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
|
||||
(*EnterSpaceParams)(nil), // 1: space.EnterSpaceParams
|
||||
(*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
|
||||
(*EnterSpaceResult)(nil), // 8: space.EnterSpaceResult
|
||||
(*GetUserSpaceResult)(nil), // 9: space.GetUserSpaceResult
|
||||
(*ExitSpaceResult)(nil), // 10: space.ExitSpaceResult
|
||||
(*ListSpaceUsersResult)(nil), // 11: space.ListSpaceUsersResult
|
||||
(*RemoveSpaceUserResult)(nil), // 12: space.RemoveSpaceUserResult
|
||||
(*JoinSpaceResult)(nil), // 13: space.JoinSpaceResult
|
||||
}
|
||||
var file_space_proto_depIdxs = []int32{
|
||||
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
|
||||
1, // 1: space.SpaceService.EnterSpace:input_type -> space.EnterSpaceParams
|
||||
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
|
||||
7, // 7: space.SpaceService.DissolveSpace:output_type -> space.DissolveSpaceResult
|
||||
8, // 8: space.SpaceService.EnterSpace:output_type -> space.EnterSpaceResult
|
||||
9, // 9: space.SpaceUserService.getUserSpace:output_type -> space.GetUserSpaceResult
|
||||
10, // 10: space.SpaceUserService.ExitSpace:output_type -> space.ExitSpaceResult
|
||||
11, // 11: space.SpaceUserService.ListSpaceUsers:output_type -> space.ListSpaceUsersResult
|
||||
12, // 12: space.SpaceUserService.RemoveSpaceUser:output_type -> space.RemoveSpaceUserResult
|
||||
13, // 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: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
|
||||
|
||||
@@ -192,6 +192,91 @@ func (*DissolveSpaceResult) Descriptor() ([]byte, []int) {
|
||||
return file_space_space_types_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
type EnterSpaceParams struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
SpaceId int64 `protobuf:"varint,1,opt,name=SpaceId,proto3" form:"space_id" json:"space_id"`
|
||||
}
|
||||
|
||||
func (x *EnterSpaceParams) Reset() {
|
||||
*x = EnterSpaceParams{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_space_space_types_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *EnterSpaceParams) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*EnterSpaceParams) ProtoMessage() {}
|
||||
|
||||
func (x *EnterSpaceParams) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_space_space_types_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 EnterSpaceParams.ProtoReflect.Descriptor instead.
|
||||
func (*EnterSpaceParams) Descriptor() ([]byte, []int) {
|
||||
return file_space_space_types_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *EnterSpaceParams) GetSpaceId() int64 {
|
||||
if x != nil {
|
||||
return x.SpaceId
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type EnterSpaceResult struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *EnterSpaceResult) Reset() {
|
||||
*x = EnterSpaceResult{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_space_space_types_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *EnterSpaceResult) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*EnterSpaceResult) ProtoMessage() {}
|
||||
|
||||
func (x *EnterSpaceResult) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_space_space_types_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 EnterSpaceResult.ProtoReflect.Descriptor instead.
|
||||
func (*EnterSpaceResult) Descriptor() ([]byte, []int) {
|
||||
return file_space_space_types_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
var File_space_space_types_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_space_space_types_proto_rawDesc = []byte{
|
||||
@@ -207,7 +292,12 @@ 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, 0x18, 0x5a, 0x16,
|
||||
0x65, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x3a, 0x0a, 0x10,
|
||||
0x45, 0x6e, 0x74, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73,
|
||||
0x12, 0x26, 0x0a, 0x07, 0x53, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x03, 0x42, 0x0c, 0xca, 0xbb, 0x18, 0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x52,
|
||||
0x07, 0x53, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x22, 0x12, 0x0a, 0x10, 0x45, 0x6e, 0x74, 0x65,
|
||||
0x72, 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,
|
||||
}
|
||||
@@ -224,12 +314,14 @@ func file_space_space_types_proto_rawDescGZIP() []byte {
|
||||
return file_space_space_types_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_space_space_types_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||
var file_space_space_types_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
|
||||
var file_space_space_types_proto_goTypes = []interface{}{
|
||||
(*CreateSpaceParams)(nil), // 0: space.CreateSpaceParams
|
||||
(*CreateSpaceResult)(nil), // 1: space.CreateSpaceResult
|
||||
(*DissolveSpaceParams)(nil), // 2: space.DissolveSpaceParams
|
||||
(*DissolveSpaceResult)(nil), // 3: space.DissolveSpaceResult
|
||||
(*EnterSpaceParams)(nil), // 4: space.EnterSpaceParams
|
||||
(*EnterSpaceResult)(nil), // 5: space.EnterSpaceResult
|
||||
}
|
||||
var file_space_space_types_proto_depIdxs = []int32{
|
||||
0, // [0:0] is the sub-list for method output_type
|
||||
@@ -293,6 +385,30 @@ func file_space_space_types_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_space_space_types_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*EnterSpaceParams); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_space_space_types_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*EnterSpaceResult); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
@@ -300,7 +416,7 @@ func file_space_space_types_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_space_space_types_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 4,
|
||||
NumMessages: 6,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
|
||||
@@ -80,3 +80,8 @@ func _getuserspaceMw() []app.HandlerFunc {
|
||||
// your code...
|
||||
return nil
|
||||
}
|
||||
|
||||
func _enterspaceMw() []app.HandlerFunc {
|
||||
// your code...
|
||||
return nil
|
||||
}
|
||||
@@ -20,6 +20,7 @@ func Register(r *server.Hertz) {
|
||||
{
|
||||
_space := root.Group("/space", _spaceMw()...)
|
||||
_space.POST("/dissolve", append(_dissolvespaceMw(), space.DissolveSpace)...)
|
||||
_space.POST("/enter", append(_enterspaceMw(), space.EnterSpace)...)
|
||||
{
|
||||
_user := _space.Group("/user", _userMw()...)
|
||||
_user.POST("/exit", append(_exitspaceMw(), space.ExitSpace)...)
|
||||
|
||||
@@ -23,6 +23,7 @@ type Config struct {
|
||||
Pgsql PgsqlConfig `mapstructure:"pgsql" yaml:"pgsql"`
|
||||
Log LogConfig `mapstructure:"log" yaml:"log"`
|
||||
Wx WxConfig `mapstructure:"wx" yaml:"wx"`
|
||||
Redis RedisConfig `mapstructure:"redis" yaml:"redis"`
|
||||
}
|
||||
|
||||
type ServerConfig struct {
|
||||
@@ -67,6 +68,13 @@ type WxConfig struct {
|
||||
AppSecret string `mapstructure:"app_secret" yaml:"app_secret"`
|
||||
}
|
||||
|
||||
type RedisConfig struct {
|
||||
Host string `mapstructure:"host" yaml:"host"`
|
||||
Port int `mapstructure:"port" yaml:"port"`
|
||||
Db int `mapstructure:"db" yaml:"db"`
|
||||
Password string `mapstructure:"password" yaml:"password"`
|
||||
}
|
||||
|
||||
func GetConf() *Config {
|
||||
once.Do(initConf)
|
||||
return conf
|
||||
|
||||
@@ -22,6 +22,12 @@ pgsql:
|
||||
conn_max_lifetime: 30m
|
||||
sll_mode: false
|
||||
|
||||
redis:
|
||||
host: 117.72.182.135
|
||||
port: 6379
|
||||
password: zhang520..
|
||||
db: 0
|
||||
|
||||
log:
|
||||
level: "debug"
|
||||
dir: "./logs"
|
||||
@@ -33,3 +39,4 @@ log:
|
||||
wx:
|
||||
app_id: wxdab3e21a1f7e392f
|
||||
app_secret: 0895443c6fedfc21cb92c9cd60de2a26
|
||||
|
||||
@@ -3,15 +3,15 @@ module allapp
|
||||
go 1.25.3
|
||||
|
||||
require (
|
||||
github.com/cloudwego/hertz v0.10.3
|
||||
github.com/cloudwego/hertz v0.10.4
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2
|
||||
github.com/hertz-contrib/jwt v1.0.4
|
||||
github.com/hertz-contrib/requestid v1.1.0
|
||||
github.com/jackc/pgx/v5 v5.7.6
|
||||
github.com/jackc/pgx/v5 v5.8.0
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/shopspring/decimal v1.4.0
|
||||
github.com/spf13/viper v1.21.0
|
||||
go.uber.org/zap v1.27.1
|
||||
google.golang.org/protobuf v1.36.10
|
||||
google.golang.org/protobuf v1.36.11
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||
)
|
||||
|
||||
@@ -23,22 +23,25 @@ require (
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
|
||||
github.com/bmatcuk/doublestar v1.3.4 // indirect
|
||||
github.com/bytedance/gopkg v0.1.3 // indirect
|
||||
github.com/bytedance/sonic v1.14.2 // indirect
|
||||
github.com/bytedance/sonic/loader v0.4.0 // indirect
|
||||
github.com/bytedance/sonic v1.15.0 // indirect
|
||||
github.com/bytedance/sonic/loader v0.5.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/cloudwego/base64x v0.1.6 // indirect
|
||||
github.com/cloudwego/gopkg v0.1.7 // indirect
|
||||
github.com/cloudwego/gopkg v0.1.8 // indirect
|
||||
github.com/cloudwego/netpoll v0.7.2 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/elastic/pkcs8 v1.0.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/go-errors/errors v1.5.1 // indirect
|
||||
github.com/go-openapi/inflect v0.21.3 // indirect
|
||||
github.com/go-sql-driver/mysql v1.9.3 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.5.0 // indirect
|
||||
github.com/goccy/go-json v0.10.5 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.24.0 // indirect
|
||||
github.com/hertz-contrib/jwt v1.0.4 // indirect
|
||||
github.com/hertz-contrib/logger/zap v1.1.0 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||
@@ -47,10 +50,10 @@ require (
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
|
||||
github.com/lib/pq v1.10.9 // indirect
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||
github.com/nyaruka/phonenumbers v1.6.7 // indirect
|
||||
github.com/nyaruka/phonenumbers v1.6.8 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/redis/go-redis/v9 v9.17.3 // indirect
|
||||
github.com/sagikazarmark/locafero v0.12.0 // indirect
|
||||
github.com/shopspring/decimal v1.4.0 // indirect
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
|
||||
github.com/spf13/afero v1.15.0 // indirect
|
||||
github.com/spf13/cast v1.10.0 // indirect
|
||||
@@ -66,13 +69,13 @@ require (
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/arch v0.23.0 // indirect
|
||||
golang.org/x/crypto v0.45.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20251125195548-87e1e737ad39 // indirect
|
||||
golang.org/x/mod v0.30.0 // indirect
|
||||
golang.org/x/sync v0.18.0 // indirect
|
||||
golang.org/x/sys v0.38.0 // indirect
|
||||
golang.org/x/text v0.31.0 // indirect
|
||||
golang.org/x/tools v0.39.0 // indirect
|
||||
golang.org/x/crypto v0.47.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20260112195511-716be5621a96 // indirect
|
||||
golang.org/x/mod v0.32.0 // indirect
|
||||
golang.org/x/sync v0.19.0 // indirect
|
||||
golang.org/x/sys v0.40.0 // indirect
|
||||
golang.org/x/text v0.33.0 // indirect
|
||||
golang.org/x/tools v0.41.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
xorm.io/builder v0.3.13 // indirect
|
||||
xorm.io/xorm v1.3.11 // indirect
|
||||
|
||||
@@ -21,17 +21,27 @@ github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP
|
||||
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
||||
github.com/bytedance/sonic v1.14.2 h1:k1twIoe97C1DtYUo+fZQy865IuHia4PR5RPiuGPPIIE=
|
||||
github.com/bytedance/sonic v1.14.2/go.mod h1:T80iDELeHiHKSc0C9tubFygiuXoGzrkjKzX2quAx980=
|
||||
github.com/bytedance/sonic v1.15.0 h1:/PXeWFaR5ElNcVE84U0dOHjiMHQOwNIx3K4ymzh/uSE=
|
||||
github.com/bytedance/sonic v1.15.0/go.mod h1:tFkWrPz0/CUCLEF4ri4UkHekCIcdnkqXw9VduqpJh0k=
|
||||
github.com/bytedance/sonic/loader v0.4.0 h1:olZ7lEqcxtZygCK9EKYKADnpQoYkRQxaeY2NYzevs+o=
|
||||
github.com/bytedance/sonic/loader v0.4.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo=
|
||||
github.com/bytedance/sonic/loader v0.5.0 h1:gXH3KVnatgY7loH5/TkeVyXPfESoqSBSBEiDd5VjlgE=
|
||||
github.com/bytedance/sonic/loader v0.5.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
|
||||
github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M=
|
||||
github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU=
|
||||
github.com/cloudwego/gopkg v0.1.4/go.mod h1:FQuXsRWRsSqJLsMVd5SYzp8/Z1y5gXKnVvRrWUOsCMI=
|
||||
github.com/cloudwego/gopkg v0.1.7 h1:P9+HwBwKIayJOg0V6hsxS3WVPzlad5BKxmDlZ8c8EkI=
|
||||
github.com/cloudwego/gopkg v0.1.7/go.mod h1:FQuXsRWRsSqJLsMVd5SYzp8/Z1y5gXKnVvRrWUOsCMI=
|
||||
github.com/cloudwego/gopkg v0.1.8 h1:ma9oACsY3v6xJwQ8NUc/h19GLV2ZCIjx0P6hqaSIlt4=
|
||||
github.com/cloudwego/gopkg v0.1.8/go.mod h1:FQuXsRWRsSqJLsMVd5SYzp8/Z1y5gXKnVvRrWUOsCMI=
|
||||
github.com/cloudwego/hertz v0.4.2/go.mod h1:K1U0RlU07CDeBINfHNbafH/3j9uSgIW8otbjUys3OPY=
|
||||
github.com/cloudwego/hertz v0.10.3 h1:NFcQAjouVJsod79XPLC/PaFfHgjMTYbiErmW+vGBi8A=
|
||||
github.com/cloudwego/hertz v0.10.3/go.mod h1:W5dUFXZPZkyfjMMo3EQrMQbofuvTsctM9IxmhbkuT18=
|
||||
github.com/cloudwego/hertz v0.10.4 h1:xJxomApZYR67cROevam6SrtUBDvhcI4ZZhx/WgvpHwU=
|
||||
github.com/cloudwego/hertz v0.10.4/go.mod h1:tZXEi/4o7R0Ho9yw5V2C+k/wVx3S8+wuuiJGDMopnpg=
|
||||
github.com/cloudwego/netpoll v0.3.1/go.mod h1:1T2WVuQ+MQw6h6DpE45MohSvDTKdy2DlzCx2KsnPI4E=
|
||||
github.com/cloudwego/netpoll v0.7.2 h1:4qDBGQ6CG2SvEXhZSDxMdtqt/NLDxjAVk0PC/biKiJo=
|
||||
github.com/cloudwego/netpoll v0.7.2/go.mod h1:PI+YrmyS7cIr0+SD4seJz3Eo3ckkXdu2ZVKBLhURLNU=
|
||||
@@ -39,6 +49,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/elastic/pkcs8 v1.0.0 h1:HhitlUKxhN288kcNcYkjW6/ouvuwJWd9ioxpjnD9jVA=
|
||||
github.com/elastic/pkcs8 v1.0.0/go.mod h1:ipsZToJfq1MxclVTwpG7U/bgeDtf+0HkUiOxebk95+0=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
@@ -56,6 +68,8 @@ github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
|
||||
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro=
|
||||
github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
||||
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
|
||||
@@ -92,6 +106,8 @@ github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7Ulw
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgx/v5 v5.7.6 h1:rWQc5FwZSPX58r1OQmkuaNicxdmExaEz5A2DO2hUuTk=
|
||||
github.com/jackc/pgx/v5 v5.7.6/go.mod h1:aruU7o91Tc2q2cFp5h4uP3f6ztExVpyVv88Xl/8Vl8M=
|
||||
github.com/jackc/pgx/v5 v5.8.0 h1:TYPDoleBBme0xGSAX3/+NujXXtpZn9HBONkQC7IEZSo=
|
||||
github.com/jackc/pgx/v5 v5.8.0/go.mod h1:QVeDInX2m9VyzvNeiCJVjCkNFqzsNb43204HshNSZKw=
|
||||
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
||||
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||
github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
|
||||
@@ -119,6 +135,8 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA
|
||||
github.com/nyaruka/phonenumbers v1.0.55/go.mod h1:sDaTZ/KPX5f8qyV9qN+hIm+4ZBARJrupC6LuhshJq1U=
|
||||
github.com/nyaruka/phonenumbers v1.6.7 h1:WmebT8TNEzNaui5QlrGqbccRC6dZkEkYc+MGQoILSSo=
|
||||
github.com/nyaruka/phonenumbers v1.6.7/go.mod h1:7gjs+Lchqm49adhAKB5cdcng5ZXgt6x7Jgvi0ZorUtU=
|
||||
github.com/nyaruka/phonenumbers v1.6.8 h1:k7HAJ/LeBkXE0vfbajITzTCZD0z0j+epdBNx43yTygk=
|
||||
github.com/nyaruka/phonenumbers v1.6.8/go.mod h1:IUu45lj2bSeYXQuxDyyuzOrdV10tyRa1YSsfH8EKN5c=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
@@ -130,6 +148,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/redis/go-redis/v9 v9.17.3 h1:fN29NdNrE17KttK5Ndf20buqfDZwGNgoUr9qjl1DQx4=
|
||||
github.com/redis/go-redis/v9 v9.17.3/go.mod h1:u410H11HMLoB+TP67dz8rL9s6QW2j76l0//kSOd3370=
|
||||
github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=
|
||||
github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=
|
||||
github.com/sagikazarmark/locafero v0.12.0 h1:/NQhBAkUb4+fH1jivKHWusDYFjMOOKU88eegjfxfHb4=
|
||||
@@ -206,14 +226,20 @@ golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDf
|
||||
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
|
||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||
golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8=
|
||||
golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A=
|
||||
golang.org/x/exp v0.0.0-20251113190631-e25ba8c21ef6 h1:zfMcR1Cs4KNuomFFgGefv5N0czO2XZpUbxGUy8i8ug0=
|
||||
golang.org/x/exp v0.0.0-20251113190631-e25ba8c21ef6/go.mod h1:46edojNIoXTNOhySWIWdix628clX9ODXwPsQuG6hsK0=
|
||||
golang.org/x/exp v0.0.0-20251125195548-87e1e737ad39 h1:DHNhtq3sNNzrvduZZIiFyXWOL9IWaDPHqTnLJp+rCBY=
|
||||
golang.org/x/exp v0.0.0-20251125195548-87e1e737ad39/go.mod h1:46edojNIoXTNOhySWIWdix628clX9ODXwPsQuG6hsK0=
|
||||
golang.org/x/exp v0.0.0-20260112195511-716be5621a96 h1:Z/6YuSHTLOHfNFdb8zVZomZr7cqNgTJvA8+Qz75D8gU=
|
||||
golang.org/x/exp v0.0.0-20260112195511-716be5621a96/go.mod h1:nzimsREAkjBCIEFtHiYkrJyT+2uy9YZJB7H1k68CXZU=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk=
|
||||
golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc=
|
||||
golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c=
|
||||
golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
@@ -230,6 +256,8 @@ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
|
||||
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -244,6 +272,8 @@ golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
|
||||
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
@@ -258,18 +288,24 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
||||
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
|
||||
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ=
|
||||
golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ=
|
||||
golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc=
|
||||
golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
|
||||
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
|
||||
@@ -13,6 +13,10 @@ service SpaceService {
|
||||
rpc DissolveSpace(DissolveSpaceParams) returns (DissolveSpaceResult){
|
||||
option (api.post) = '/space/dissolve';
|
||||
};
|
||||
// 进入空间
|
||||
rpc EnterSpace(EnterSpaceParams) returns (EnterSpaceResult){
|
||||
option (api.post) = '/space/enter';
|
||||
}
|
||||
}
|
||||
|
||||
service SpaceUserService{
|
||||
|
||||
@@ -25,3 +25,8 @@ message DissolveSpaceResult {
|
||||
|
||||
}
|
||||
|
||||
message EnterSpaceParams {
|
||||
int64 SpaceId = 1 [(api.body)="space_id"];
|
||||
}
|
||||
message EnterSpaceResult {
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"allapp/logx"
|
||||
"allapp/utils/idgen"
|
||||
"allapp/utils/jwtx"
|
||||
"allapp/utils/redisx"
|
||||
|
||||
"github.com/cloudwego/hertz/pkg/app/server"
|
||||
"github.com/hertz-contrib/requestid"
|
||||
@@ -19,6 +20,8 @@ func main() {
|
||||
|
||||
// 数据库
|
||||
db.InitDB()
|
||||
// Redis
|
||||
redisx.Init()
|
||||
// 日志
|
||||
logx.InitLog()
|
||||
// jwt
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package redisx
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Set 设置 key
|
||||
func Set(ctx context.Context, key string, value any, ttl time.Duration) error {
|
||||
return Client().Set(ctx, key, value, ttl).Err()
|
||||
}
|
||||
|
||||
// Get 获取 string
|
||||
func Get(ctx context.Context, key string) (string, error) {
|
||||
return Client().Get(ctx, key).Result()
|
||||
}
|
||||
|
||||
// Del 删除
|
||||
func Del(ctx context.Context, keys ...string) error {
|
||||
return Client().Del(ctx, keys...).Err()
|
||||
}
|
||||
|
||||
// Exists 是否存在
|
||||
func Exists(ctx context.Context, key string) (bool, error) {
|
||||
n, err := Client().Exists(ctx, key).Result()
|
||||
return n > 0, err
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package redisx
|
||||
|
||||
import (
|
||||
"allapp/conf"
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
|
||||
var (
|
||||
client *redis.Client
|
||||
once sync.Once
|
||||
)
|
||||
|
||||
// Init 初始化 Redis(只会执行一次)
|
||||
func Init() *redis.Client {
|
||||
once.Do(func() {
|
||||
redisConfig := conf.GetConf().Redis
|
||||
|
||||
addr := fmt.Sprintf("%s:%d", redisConfig.Host, redisConfig.Port)
|
||||
|
||||
client = redis.NewClient(&redis.Options{
|
||||
Addr: addr,
|
||||
Password: redisConfig.Password,
|
||||
DB: redisConfig.Db,
|
||||
})
|
||||
|
||||
// 启动时检测连接
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
if err := client.Ping(ctx).Err(); err != nil {
|
||||
panic("redis 连接失败: " + err.Error())
|
||||
}
|
||||
})
|
||||
|
||||
return client
|
||||
}
|
||||
|
||||
// Client 获取 Redis 客户端
|
||||
func Client() *redis.Client {
|
||||
if client == nil {
|
||||
panic("redis 尚未初始化")
|
||||
}
|
||||
return client
|
||||
}
|
||||
@@ -1,43 +1,40 @@
|
||||
import type { icons } from 'lucide-react-native'
|
||||
import type { SortableGridRenderItem } from 'react-native-sortables'
|
||||
import type { NavItem } from '@/store/navigation'
|
||||
import { Slot, usePathname, useRouter } from 'expo-router'
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { Pressable, Text, TouchableOpacity, Vibration, View } from 'react-native'
|
||||
import { Text, TouchableOpacity, View } from 'react-native'
|
||||
import Animated, { useAnimatedRef } from 'react-native-reanimated'
|
||||
import Sortable from 'react-native-sortables'
|
||||
import { ADrawer, LucideIcon } from '@/components/common/ao'
|
||||
|
||||
interface NavItem {
|
||||
label: string
|
||||
path: string
|
||||
icon: keyof typeof icons
|
||||
}
|
||||
|
||||
const NAV_MENUS: NavItem[] = [
|
||||
{ label: '记账', path: '/money', icon: 'CircleDollarSign' },
|
||||
{ label: '恋爱记', path: '/love', icon: 'Heart' },
|
||||
{ label: '聊天', path: '/chat', icon: 'MessageCircle' },
|
||||
{ label: '个人中心', path: '/user', icon: 'CircleUserRound' },
|
||||
]
|
||||
import { useNavStore } from '@/store/navigation'
|
||||
|
||||
export default function TabsLayout() {
|
||||
const scrollableRef = useAnimatedRef<Animated.ScrollView>()
|
||||
|
||||
const router = useRouter()
|
||||
const pathname = usePathname()
|
||||
const navStore = useNavStore()
|
||||
|
||||
const [showNavDrawer, setShowNavDrawer] = useState(false)
|
||||
const [draggingId, setDraggingId] = useState<string>('')
|
||||
|
||||
const [currentNav, setCurrentNav] = useState<NavItem>({
|
||||
label: '',
|
||||
path: '',
|
||||
icon: 'AArrowDown',
|
||||
label: 'Welcome',
|
||||
path: '/',
|
||||
icon: 'Sparkles',
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
const current = NAV_MENUS.find(item => item.path === pathname)
|
||||
const current = navStore.navMenus.find(item => item.path === pathname)
|
||||
if (current) {
|
||||
setCurrentNav(current)
|
||||
}
|
||||
else {
|
||||
setCurrentNav({
|
||||
label: 'Welcome',
|
||||
path: '/',
|
||||
icon: 'Sparkles',
|
||||
})
|
||||
}
|
||||
}, [pathname])
|
||||
|
||||
const refreshPage = () => {
|
||||
@@ -46,15 +43,14 @@ export default function TabsLayout() {
|
||||
|
||||
const renderNavItem = useCallback<SortableGridRenderItem<NavItem>>(
|
||||
({ item }) => (
|
||||
<Pressable
|
||||
<TouchableOpacity
|
||||
className="
|
||||
flex
|
||||
flex-col
|
||||
items-center
|
||||
justify-center
|
||||
bg-[white]
|
||||
bg-[#f9f9f9]
|
||||
rounded-md
|
||||
shadow-md
|
||||
p-3
|
||||
"
|
||||
onPress={() => {
|
||||
@@ -66,7 +62,7 @@ export default function TabsLayout() {
|
||||
<Text className="text-sm mt-2">
|
||||
{item.label}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</TouchableOpacity>
|
||||
),
|
||||
[],
|
||||
)
|
||||
@@ -86,6 +82,7 @@ export default function TabsLayout() {
|
||||
px-2
|
||||
gap-4
|
||||
"
|
||||
style={{ zIndex: 0 }}
|
||||
>
|
||||
<View className="bg-white rounded-md shadow-lg h-12 w-12">
|
||||
<TouchableOpacity className="w-full h-full items-center justify-center">
|
||||
@@ -128,11 +125,15 @@ export default function TabsLayout() {
|
||||
columnGap={16}
|
||||
rowGap={16}
|
||||
columns={3}
|
||||
data={NAV_MENUS}
|
||||
data={navStore.navMenus}
|
||||
keyExtractor={item => item.path}
|
||||
renderItem={renderNavItem}
|
||||
scrollableRef={scrollableRef}
|
||||
autoScrollActivationOffset={200}
|
||||
showDropIndicator
|
||||
onDragEnd={(dragData) => {
|
||||
navStore.setNavMenus(dragData.data)
|
||||
}}
|
||||
/>
|
||||
</Animated.ScrollView>
|
||||
</ADrawer>
|
||||
|
||||
Whitespace-only changes.
@@ -1,20 +1,34 @@
|
||||
import { useRouter } from 'expo-router'
|
||||
import { Text, View } from 'react-native'
|
||||
import { Image, Text, View } from 'react-native'
|
||||
import { SafeAreaView } from 'react-native-safe-area-context'
|
||||
import { AButton } from '@/components/common/ao'
|
||||
// 这个页面的作用是作为占位页,避免进入 (tabs) layout 时出现 404 页面。
|
||||
// 如果想指定默认页面,可以通过 router.replace 或 TabTrigger 指向具体子页面。
|
||||
|
||||
export default function Index() {
|
||||
const router = useRouter()
|
||||
|
||||
return (
|
||||
<SafeAreaView>
|
||||
<View>
|
||||
<AButton onPress={() => {
|
||||
router.push('/money')
|
||||
}}
|
||||
<SafeAreaView className="flex-1 bg-white">
|
||||
<View className="flex-1 items-center justify-center px-6">
|
||||
|
||||
<Image
|
||||
source={require('@/static/images/welcome.png')}
|
||||
className="w-86 h-48 mb-6"
|
||||
resizeMode="contain"
|
||||
/>
|
||||
|
||||
<Text className="text-2xl font-semibold text-gray-900 mb-3">
|
||||
🎉 欢迎使用 OneAO
|
||||
</Text>
|
||||
|
||||
<Text className="text-base text-gray-500 text-center mb-10">
|
||||
记录生活,记录情绪,也记录每一笔重要的支出
|
||||
</Text>
|
||||
|
||||
<AButton
|
||||
className="w-full"
|
||||
onPress={() => router.replace('/money')}
|
||||
>
|
||||
测试
|
||||
开始使用
|
||||
</AButton>
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
|
||||
@@ -1,20 +1,17 @@
|
||||
import { useFocusEffect, useRouter } from 'expo-router'
|
||||
import React, { useCallback, useEffect, useState } from 'react'
|
||||
import { Image, Text, TouchableOpacity, View } from 'react-native'
|
||||
import { Drawer } from 'react-native-drawer-layout'
|
||||
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context'
|
||||
import { ADatePicker, AListItem, LucideIcon } from '@/components/common/ao'
|
||||
import { ADatePicker, ADrawer, AListItem, LucideIcon } from '@/components/common/ao'
|
||||
import { Fab, FabIcon } from '@/components/ui/fab'
|
||||
import { AddIcon } from '@/components/ui/icon'
|
||||
import { queryMoneyRecordsApi } from '@/request/api/money/record'
|
||||
import { useAppStore } from '@/store/app'
|
||||
import { useMoneyRecordStore } from '@/store/moneyRecord'
|
||||
import { getCurrentYearMonth } from '@/utils/time'
|
||||
import { toast } from '@/utils/toast'
|
||||
import TransactionsList from './components/TransactionsList'
|
||||
|
||||
export default function Money() {
|
||||
const appStore = useAppStore()
|
||||
const moneyRecordStore = useMoneyRecordStore()
|
||||
const router = useRouter()
|
||||
// 安全高度
|
||||
@@ -47,12 +44,6 @@ export default function Money() {
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!appStore.ready)
|
||||
return
|
||||
getMoneyRecords()
|
||||
}, [appStore.ready, searchParams])
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
// 页面显示 / 返回时
|
||||
@@ -68,120 +59,78 @@ export default function Money() {
|
||||
<View
|
||||
className="flex-1"
|
||||
>
|
||||
<Drawer
|
||||
open={showActionsMenu}
|
||||
onOpen={() => setShowActionsMenu(true)}
|
||||
onClose={() => setShowActionsMenu(false)}
|
||||
drawerPosition="right"
|
||||
drawerStyle={{
|
||||
width: '70%',
|
||||
}}
|
||||
renderDrawerContent={() => {
|
||||
return (
|
||||
<SafeAreaView className="flex-col px-3">
|
||||
<Image
|
||||
source={require('@/static/images/logo.png')}
|
||||
style={{ width: 40, height: 40 }}
|
||||
className="self-center"
|
||||
/>
|
||||
|
||||
<View className="mt-2">
|
||||
<Text className="text-gray-600 font-semibold text-sm">管理功能</Text>
|
||||
|
||||
<View className="p-1">
|
||||
<AListItem
|
||||
icon="LayoutGrid"
|
||||
text="类别设置"
|
||||
onPress={() => {
|
||||
router.navigate('/money/category/setting')
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View className="mt-2">
|
||||
<Text className="text-gray-600 font-semibold text-sm">统计分析</Text>
|
||||
|
||||
<View className="p-1">
|
||||
<AListItem icon="ChartSpline" text="图表分析" />
|
||||
</View>
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
)
|
||||
<View
|
||||
style={{
|
||||
paddingTop: insets.top,
|
||||
backgroundColor: '#fff',
|
||||
elevation: 3,
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
paddingTop: insets.top,
|
||||
backgroundColor: '#fff',
|
||||
elevation: 3,
|
||||
}}
|
||||
>
|
||||
<View className="flex flex-row justify-between items-center px-3">
|
||||
<TouchableOpacity
|
||||
onPress={() => setShowDatePicker(true)}
|
||||
className="flex flex-row items-center gap-1"
|
||||
>
|
||||
<Text className="font-semibold text-lg">{searchParams.record_time}</Text>
|
||||
<LucideIcon icon="ChevronDown" size={16} color="#666" clickable={false} />
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity
|
||||
className="flex flex-row items-center gap-2"
|
||||
onPress={() => {
|
||||
setShowActionsMenu(true)
|
||||
}}
|
||||
>
|
||||
<LucideIcon icon="Menu" size={24} clickable={false} />
|
||||
</TouchableOpacity>
|
||||
|
||||
</View>
|
||||
|
||||
<View
|
||||
className="px-3 py-3"
|
||||
<View className="flex flex-row justify-between items-center px-3">
|
||||
<TouchableOpacity
|
||||
onPress={() => setShowDatePicker(true)}
|
||||
className="flex flex-row items-center gap-1"
|
||||
>
|
||||
<View
|
||||
className="flex flex-row gap-4"
|
||||
style={{
|
||||
borderBottomLeftRadius: 16,
|
||||
borderBottomRightRadius: 18,
|
||||
}}
|
||||
>
|
||||
<View className="flex-1">
|
||||
<Text className="text-gray-500 text-sm">收入</Text>
|
||||
<Text
|
||||
className="text-lg font-semibold mt-0.5"
|
||||
numberOfLines={1}
|
||||
ellipsizeMode="tail"
|
||||
>
|
||||
{moneyRecordStore.getTotalIncome()}
|
||||
</Text>
|
||||
</View>
|
||||
<Text className="font-semibold text-lg">{searchParams.record_time}</Text>
|
||||
<LucideIcon icon="ChevronDown" size={16} color="#666" clickable={false} />
|
||||
</TouchableOpacity>
|
||||
|
||||
<View className="flex-1">
|
||||
<Text className="text-gray-500 text-sm">支出</Text>
|
||||
<Text
|
||||
className="text-lg font-semibold mt-0.5"
|
||||
numberOfLines={1}
|
||||
ellipsizeMode="tail"
|
||||
>
|
||||
{moneyRecordStore.getTotalExpense()}
|
||||
</Text>
|
||||
</View>
|
||||
<TouchableOpacity
|
||||
className="flex flex-row items-center gap-2"
|
||||
onPress={() => {
|
||||
setShowActionsMenu(true)
|
||||
}}
|
||||
>
|
||||
<LucideIcon icon="Menu" size={24} clickable={false} />
|
||||
</TouchableOpacity>
|
||||
|
||||
<View className="flex-1">
|
||||
<Text className="text-gray-500 text-sm">结余</Text>
|
||||
<Text
|
||||
className="text-lg font-semibold mt-0.5"
|
||||
numberOfLines={1}
|
||||
ellipsizeMode="tail"
|
||||
>
|
||||
{moneyRecordStore.getTotalBalance()}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View
|
||||
className="px-3 py-3"
|
||||
>
|
||||
<View
|
||||
className="flex flex-row gap-4"
|
||||
style={{
|
||||
borderBottomLeftRadius: 16,
|
||||
borderBottomRightRadius: 18,
|
||||
}}
|
||||
>
|
||||
<View className="flex-1">
|
||||
<Text className="text-gray-500 text-sm">收入</Text>
|
||||
<Text
|
||||
className="text-lg font-semibold mt-0.5"
|
||||
numberOfLines={1}
|
||||
ellipsizeMode="tail"
|
||||
>
|
||||
{moneyRecordStore.getTotalIncome()}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
{/* <View
|
||||
<View className="flex-1">
|
||||
<Text className="text-gray-500 text-sm">支出</Text>
|
||||
<Text
|
||||
className="text-lg font-semibold mt-0.5"
|
||||
numberOfLines={1}
|
||||
ellipsizeMode="tail"
|
||||
>
|
||||
{moneyRecordStore.getTotalExpense()}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<View className="flex-1">
|
||||
<Text className="text-gray-500 text-sm">结余</Text>
|
||||
<Text
|
||||
className="text-lg font-semibold mt-0.5"
|
||||
numberOfLines={1}
|
||||
ellipsizeMode="tail"
|
||||
>
|
||||
{moneyRecordStore.getTotalBalance()}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* <View
|
||||
className="flex-row items-center gap-3 mt-2"
|
||||
style={{
|
||||
borderBottomLeftRadius: 8,
|
||||
@@ -196,58 +145,98 @@ export default function Money() {
|
||||
</View>
|
||||
<Text className="text-xs text-blue-500">点击设置</Text>
|
||||
</View> */}
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View className="flex-1 mt-2">
|
||||
<TransactionsList
|
||||
records={moneyRecordStore.records}
|
||||
onUpdate={(data) => {
|
||||
router.navigate({
|
||||
pathname: '/money/record/editor',
|
||||
params: { id: data.id },
|
||||
})
|
||||
}}
|
||||
onDetail={(id) => {
|
||||
router.navigate({
|
||||
pathname: '/money/record/detail',
|
||||
params: { id },
|
||||
})
|
||||
}}
|
||||
onDelete={(id) => {
|
||||
moneyRecordStore.deleteMoneyRecord(id)
|
||||
}}
|
||||
onRefreshData={() => {
|
||||
getMoneyRecords()
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<Fab
|
||||
size="lg"
|
||||
onPress={() => {
|
||||
router.navigate('/money/record/editor')
|
||||
}}
|
||||
>
|
||||
<FabIcon as={AddIcon} size="xl" />
|
||||
</Fab>
|
||||
|
||||
<ADatePicker
|
||||
show={showDatePicker}
|
||||
mode="month"
|
||||
date={searchParams.record_time}
|
||||
onConfirm={(val) => {
|
||||
setSearchParams({
|
||||
...searchParams,
|
||||
record_time: val,
|
||||
<View className="flex-1 mt-2">
|
||||
<TransactionsList
|
||||
records={moneyRecordStore.records}
|
||||
onUpdate={(data) => {
|
||||
router.navigate({
|
||||
pathname: '/money/record/editor',
|
||||
params: { id: data.id },
|
||||
})
|
||||
setShowDatePicker(false)
|
||||
}}
|
||||
onClose={() => {
|
||||
setShowDatePicker(false)
|
||||
onDetail={(id) => {
|
||||
router.navigate({
|
||||
pathname: '/money/record/detail',
|
||||
params: { id },
|
||||
})
|
||||
}}
|
||||
onDelete={(id) => {
|
||||
moneyRecordStore.deleteMoneyRecord(id)
|
||||
}}
|
||||
onRefreshData={() => {
|
||||
getMoneyRecords()
|
||||
}}
|
||||
/>
|
||||
</Drawer>
|
||||
</View>
|
||||
|
||||
<Fab
|
||||
size="lg"
|
||||
onPress={() => {
|
||||
router.navigate('/money/record/editor')
|
||||
}}
|
||||
className="mb-20"
|
||||
>
|
||||
<FabIcon as={AddIcon} size="xl" />
|
||||
</Fab>
|
||||
|
||||
<ADatePicker
|
||||
show={showDatePicker}
|
||||
mode="month"
|
||||
date={searchParams.record_time}
|
||||
onConfirm={(val) => {
|
||||
setSearchParams({
|
||||
...searchParams,
|
||||
record_time: val,
|
||||
})
|
||||
setShowDatePicker(false)
|
||||
}}
|
||||
onClose={() => {
|
||||
setShowDatePicker(false)
|
||||
}}
|
||||
/>
|
||||
|
||||
<ADrawer
|
||||
visible={showActionsMenu}
|
||||
hideModal={() => {
|
||||
setShowActionsMenu(false)
|
||||
}}
|
||||
menuPosition="right"
|
||||
height="60%"
|
||||
showHeader={false}
|
||||
>
|
||||
<SafeAreaView className="flex-col px-3">
|
||||
<Image
|
||||
source={require('@/static/images/logo.png')}
|
||||
style={{ width: 40, height: 40 }}
|
||||
className="self-center"
|
||||
/>
|
||||
|
||||
<View className="mt-2">
|
||||
<Text className="text-gray-600 font-semibold text-sm">管理功能</Text>
|
||||
|
||||
<View className="p-1">
|
||||
<AListItem
|
||||
icon="LayoutGrid"
|
||||
text="类别设置"
|
||||
onPress={() => {
|
||||
router.navigate('/money/category/setting')
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View className="mt-2">
|
||||
<Text className="text-gray-600 font-semibold text-sm">统计分析</Text>
|
||||
|
||||
<View className="p-1">
|
||||
<AListItem icon="ChartSpline" text="图表分析" />
|
||||
</View>
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
</ADrawer>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
@@ -1,152 +0,0 @@
|
||||
import { useRouter } from 'expo-router'
|
||||
import { useState } from 'react'
|
||||
import { Image, Text, View } from 'react-native'
|
||||
import { AButton, ACheckbox, AForm, AFormItem, AInput } from '@/components/common/ao'
|
||||
import CustomHeader from '@/components/custom/Header'
|
||||
import { IconQq, IconWeixin, IconZhiwen } from '@/components/iconfont'
|
||||
import { Divider } from '@/components/ui/divider'
|
||||
import useFormValidation from '@/hooks/useFormValidation'
|
||||
import { loginDefaultApi } from '@/request/api/auth'
|
||||
import { useAppStore } from '@/store/app'
|
||||
import { useUserStore } from '@/store/user'
|
||||
import { toast } from '@/utils/toast'
|
||||
|
||||
interface LoginForm {
|
||||
account: string
|
||||
password: string
|
||||
rememberMe: boolean
|
||||
socialType?: 'qq' | 'weixin' | 'fingerprint'
|
||||
}
|
||||
|
||||
export default function AuthLogin() {
|
||||
const router = useRouter()
|
||||
const userStore = useUserStore()
|
||||
const appStore = useAppStore()
|
||||
|
||||
const [loading, setLoading] = useState<boolean>(false)
|
||||
const [form, setForm] = useState<LoginForm>({
|
||||
account: userStore.userInfo?.account || '',
|
||||
password: '',
|
||||
rememberMe: true,
|
||||
})
|
||||
|
||||
const handleInputChange = (field: keyof LoginForm, value: string) => {
|
||||
setForm(prev => ({ ...prev, [field]: value }))
|
||||
}
|
||||
|
||||
const rules = {
|
||||
account: { required: true, message: '账号是必填项' },
|
||||
password: { required: true, message: '密码是必填项' },
|
||||
}
|
||||
|
||||
const { isValid } = useFormValidation(form, rules)
|
||||
|
||||
const loginDefault = () => {
|
||||
setLoading(true)
|
||||
loginDefaultApi({
|
||||
account: form.account,
|
||||
password: form.password,
|
||||
}).then((res) => {
|
||||
if (res.isSuccess) {
|
||||
toast.show({
|
||||
title: '登录成功',
|
||||
})
|
||||
|
||||
userStore.setUserInfo({
|
||||
account: form.account,
|
||||
id: res.data.userId,
|
||||
seqNo: res.data.seqNo,
|
||||
username: res.data.username,
|
||||
gender: res.data.gender,
|
||||
token: res.data.token,
|
||||
refreshToken: res.data.refreshToken,
|
||||
rememberMe: form.rememberMe,
|
||||
})
|
||||
|
||||
appStore.init()
|
||||
|
||||
router.replace('/money')
|
||||
}
|
||||
else {
|
||||
toast.show({
|
||||
title: res.message || '登录失败',
|
||||
})
|
||||
}
|
||||
}).catch((_err) => {
|
||||
|
||||
}).finally(() => {
|
||||
setLoading(false)
|
||||
})
|
||||
}
|
||||
|
||||
const loginQq = () => {
|
||||
toast.show({ title: '功能待开发,请稍等. . .' })
|
||||
}
|
||||
const loginWx = () => {
|
||||
toast.show({ title: '功能待开发,请稍等. . .' })
|
||||
}
|
||||
const loginZhiwen = () => {
|
||||
toast.show({ title: '功能待开发,请稍等. . .' })
|
||||
}
|
||||
|
||||
return (
|
||||
<View className="flex-1">
|
||||
<CustomHeader title="登录" />
|
||||
<View className="flex flex-col items-center px-6 h-full">
|
||||
<Image
|
||||
source={require('@/static/images/logo.png')}
|
||||
style={{ width: 120, height: 120 }}
|
||||
className="my-12"
|
||||
/>
|
||||
|
||||
<AForm form={form}>
|
||||
<AFormItem label="账号">
|
||||
<AInput
|
||||
value={form.account}
|
||||
onChangeText={text => handleInputChange('account', text)}
|
||||
/>
|
||||
</AFormItem>
|
||||
|
||||
<AFormItem label="密码">
|
||||
<AInput
|
||||
isPassword
|
||||
value={form.password}
|
||||
onChangeText={text => handleInputChange('password', text)}
|
||||
/>
|
||||
</AFormItem>
|
||||
</AForm>
|
||||
|
||||
<View className="w-full flex-row justify-between items-center mb-6">
|
||||
<ACheckbox
|
||||
isChecked={form.rememberMe}
|
||||
onChange={checked => setForm(prev => ({ ...prev, rememberMe: checked }))}
|
||||
label="记住我"
|
||||
/>
|
||||
|
||||
<Text className="text-blue-500">忘记密码?</Text>
|
||||
</View>
|
||||
|
||||
<AButton className="w-full" onPress={loginDefault} disabled={!isValid} loading={loading}>
|
||||
登录
|
||||
</AButton>
|
||||
|
||||
<View className="flex-row items-center my-8 w-full">
|
||||
<View className="flex-1">
|
||||
<Divider />
|
||||
</View>
|
||||
<Text className="mx-3 text-gray-500 text-sm">社交账号</Text>
|
||||
<View className="flex-1">
|
||||
<Divider />
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View className="w-full flex-row justify-between items-center">
|
||||
<IconQq size={32} onPress={loginQq} />
|
||||
<IconWeixin size={32} onPress={loginWx} />
|
||||
<IconZhiwen size={32} onPress={loginZhiwen} />
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
)
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
import type { AFormRef } from '@/components/common/ao'
|
||||
import { useRouter } from 'expo-router'
|
||||
import { Lock, UserRound } from 'lucide-react-native'
|
||||
import { useRef, useState } from 'react'
|
||||
|
||||
import { Image, ScrollView, View } from 'react-native'
|
||||
import { AButton, AForm, AFormItem, AInput } from '@/components/common/ao'
|
||||
import CustomHeader from '@/components/custom/Header'
|
||||
import { registerDefaultApi } from '@/request/api/auth'
|
||||
import { toast } from '@/utils/toast'
|
||||
|
||||
interface RegisterForm {
|
||||
username: string
|
||||
password: string
|
||||
confirmPassword: string
|
||||
}
|
||||
|
||||
export default function AuthRegister() {
|
||||
const router = useRouter()
|
||||
const scrollRef = useRef<ScrollView>(null)
|
||||
|
||||
const [form, setForm] = useState<RegisterForm>({
|
||||
username: '',
|
||||
password: '',
|
||||
confirmPassword: '',
|
||||
})
|
||||
const [loading, setLoading] = useState(false)
|
||||
const formRef = useRef<AFormRef>(null)
|
||||
|
||||
const handleInputChange = (field: keyof RegisterForm, value: string) => {
|
||||
setForm(prev => ({ ...prev, [field]: value }))
|
||||
}
|
||||
|
||||
const handleRegister = async () => {
|
||||
if (formRef.current?.validate()) {
|
||||
setLoading(true)
|
||||
|
||||
await registerDefaultApi({
|
||||
account: form.username,
|
||||
password: form.password,
|
||||
}).then((res) => {
|
||||
if (res.isSuccess) {
|
||||
toast.show({
|
||||
title: '注册成功',
|
||||
})
|
||||
router.replace('/auth/login')
|
||||
}
|
||||
else {
|
||||
toast.show({
|
||||
title: res.message || '注册失败',
|
||||
})
|
||||
}
|
||||
}).catch((_err) => {
|
||||
}).finally(() => {
|
||||
setLoading(false)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<View className="flex-1">
|
||||
<CustomHeader title="注册" />
|
||||
<ScrollView ref={scrollRef} style={{ flex: 1 }}>
|
||||
<View className="flex flex-col items-center px-6 bg-white ">
|
||||
<Image
|
||||
source={require('@/static/images/logo.png')}
|
||||
style={{ width: 120, height: 120 }}
|
||||
className="my-12"
|
||||
/>
|
||||
|
||||
<AForm ref={formRef} form={form} scrollRef={scrollRef}>
|
||||
<AFormItem
|
||||
name="username"
|
||||
label="账号"
|
||||
isRequired
|
||||
>
|
||||
<AInput
|
||||
placeholder="请输入账号"
|
||||
leftIcon={UserRound}
|
||||
value={form.username}
|
||||
onChangeText={text => handleInputChange('username', text)}
|
||||
/>
|
||||
</AFormItem>
|
||||
|
||||
<AFormItem
|
||||
name="password"
|
||||
label="密码"
|
||||
isRequired
|
||||
>
|
||||
<AInput
|
||||
placeholder="请输入密码"
|
||||
leftIcon={Lock}
|
||||
isPassword
|
||||
value={form.password}
|
||||
onChangeText={text => handleInputChange('password', text)}
|
||||
/>
|
||||
</AFormItem>
|
||||
|
||||
<AFormItem
|
||||
name="confirmPassword"
|
||||
label="确认密码"
|
||||
isRequired
|
||||
rules={[
|
||||
{
|
||||
validator: val => val === form.password,
|
||||
message: '两次密码不一致',
|
||||
},
|
||||
]}
|
||||
>
|
||||
<AInput
|
||||
placeholder="请再次输入密码"
|
||||
leftIcon={Lock}
|
||||
isPassword
|
||||
value={form.confirmPassword}
|
||||
onChangeText={text => handleInputChange('confirmPassword', text)}
|
||||
/>
|
||||
</AFormItem>
|
||||
</AForm>
|
||||
|
||||
<AButton className="w-full mb-4" onPress={handleRegister} loading={loading}>
|
||||
|
||||
注册
|
||||
</AButton>
|
||||
</View>
|
||||
</ScrollView>
|
||||
</View>
|
||||
|
||||
)
|
||||
}
|
||||
@@ -1,19 +1,18 @@
|
||||
import type { ReactNode } from 'react'
|
||||
import type { DimensionValue, ViewStyle } from 'react-native'
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import {
|
||||
Animated,
|
||||
Dimensions,
|
||||
Modal,
|
||||
Platform,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableWithoutFeedback,
|
||||
View,
|
||||
} from 'react-native'
|
||||
import React, { useEffect, useMemo, useState } from 'react'
|
||||
import { Dimensions, StyleSheet, Text, View } from 'react-native'
|
||||
import { Gesture, GestureDetector } from 'react-native-gesture-handler'
|
||||
import Animated, {
|
||||
interpolate,
|
||||
runOnJS,
|
||||
useAnimatedStyle,
|
||||
useSharedValue,
|
||||
withTiming,
|
||||
} from 'react-native-reanimated'
|
||||
import LucideIcon from './LucideIcon'
|
||||
|
||||
const WINDOW = Dimensions.get('window')
|
||||
const SCREEN = Dimensions.get('screen')
|
||||
|
||||
interface DrawerMenuProps {
|
||||
visible: boolean
|
||||
@@ -27,218 +26,145 @@ interface DrawerMenuProps {
|
||||
CircleNum?: number
|
||||
isShadowHideModal?: boolean
|
||||
title?: string
|
||||
showHeader?: boolean
|
||||
}
|
||||
|
||||
export default function Drawer({
|
||||
visible,
|
||||
height,
|
||||
height = 300,
|
||||
hideModal,
|
||||
duration = 300,
|
||||
isCircle,
|
||||
menuPosition = 'bottom',
|
||||
children,
|
||||
CircleNum = 8,
|
||||
CircleNum = 12,
|
||||
isShadowHideModal = true,
|
||||
header,
|
||||
title,
|
||||
showHeader = true,
|
||||
}: DrawerMenuProps) {
|
||||
const [menuPositionStyle, setMenuPositionStyle] = useState<ViewStyle>()
|
||||
const [drawerMenuBox, setDrawerMenuBox] = useState<ViewStyle>()
|
||||
const progress = useSharedValue(0)
|
||||
const drag = useSharedValue(0)
|
||||
const [innerVisible, setInnerVisible] = useState(false)
|
||||
|
||||
const anim = useRef(new Animated.Value(0)).current
|
||||
|
||||
/* ================= 显隐 ================= */
|
||||
useEffect(() => {
|
||||
if (visible) {
|
||||
setInnerVisible(true)
|
||||
open()
|
||||
progress.value = withTiming(1, { duration })
|
||||
}
|
||||
else {
|
||||
close()
|
||||
progress.value = withTiming(0, { duration }, () => {
|
||||
runOnJS(setInnerVisible)(false)
|
||||
})
|
||||
}
|
||||
}, [visible])
|
||||
|
||||
useEffect(() => {
|
||||
/* ================= Drawer 尺寸 ================= */
|
||||
const drawerBox = useMemo<ViewStyle>(() => {
|
||||
switch (menuPosition) {
|
||||
case 'left':
|
||||
setMenuPositionStyle({
|
||||
flex: 1,
|
||||
backgroundColor: '#fff',
|
||||
borderTopRightRadius: isCircle ? CircleNum : 0,
|
||||
borderBottomRightRadius: isCircle ? CircleNum : 0,
|
||||
})
|
||||
setDrawerMenuBox({
|
||||
width: height,
|
||||
height: WINDOW.height,
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
top: 0,
|
||||
})
|
||||
break
|
||||
|
||||
return { width: height, left: 0, top: 0, bottom: 0 }
|
||||
case 'right':
|
||||
setMenuPositionStyle({
|
||||
flex: 1,
|
||||
backgroundColor: '#fff',
|
||||
borderTopLeftRadius: isCircle ? CircleNum : 0,
|
||||
borderBottomLeftRadius: isCircle ? CircleNum : 0,
|
||||
})
|
||||
setDrawerMenuBox({
|
||||
width: height,
|
||||
height: WINDOW.height,
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
top: 0,
|
||||
})
|
||||
break
|
||||
|
||||
return { width: height, right: 0, top: 0, bottom: 0 }
|
||||
case 'top':
|
||||
setMenuPositionStyle({
|
||||
flex: 1,
|
||||
backgroundColor: '#fff',
|
||||
borderBottomLeftRadius: isCircle ? CircleNum : 0,
|
||||
borderBottomRightRadius: isCircle ? CircleNum : 0,
|
||||
})
|
||||
setDrawerMenuBox({
|
||||
width: WINDOW.width,
|
||||
height,
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
right: 0,
|
||||
})
|
||||
break
|
||||
|
||||
return { height, left: 0, right: 0, top: 0 }
|
||||
case 'bottom':
|
||||
default:
|
||||
setMenuPositionStyle({
|
||||
flex: 1,
|
||||
backgroundColor: '#fff',
|
||||
borderTopLeftRadius: isCircle ? CircleNum : 0,
|
||||
borderTopRightRadius: isCircle ? CircleNum : 0,
|
||||
})
|
||||
setDrawerMenuBox({
|
||||
width: WINDOW.width,
|
||||
height,
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
})
|
||||
break
|
||||
return { height, left: 0, right: 0, bottom: 0 }
|
||||
}
|
||||
}, [menuPosition, height, isCircle, CircleNum])
|
||||
}, [menuPosition, height])
|
||||
|
||||
/* ================== 动画 ================== */
|
||||
const open = () => {
|
||||
Animated.timing(anim, {
|
||||
toValue: 1,
|
||||
duration,
|
||||
useNativeDriver: true,
|
||||
}).start()
|
||||
}
|
||||
/* ================= 动画样式(关键) ================= */
|
||||
const drawerStyle = useAnimatedStyle(() => {
|
||||
switch (menuPosition) {
|
||||
case 'bottom': {
|
||||
const y = interpolate(progress.value, [0, 1], [SCREEN.height, 0], 'clamp')
|
||||
return { transform: [{ translateY: y + drag.value }] }
|
||||
}
|
||||
case 'top': {
|
||||
const y = interpolate(progress.value, [0, 1], [-SCREEN.height, 0], 'clamp')
|
||||
return { transform: [{ translateY: y }] }
|
||||
}
|
||||
case 'left': {
|
||||
const x = interpolate(progress.value, [0, 1], [-SCREEN.width, 0], 'clamp')
|
||||
return { transform: [{ translateX: x }] }
|
||||
}
|
||||
case 'right': {
|
||||
const x = interpolate(progress.value, [0, 1], [SCREEN.width, 0], 'clamp')
|
||||
return { transform: [{ translateX: x }] }
|
||||
}
|
||||
default:
|
||||
return {}
|
||||
}
|
||||
})
|
||||
|
||||
const close = () => {
|
||||
Animated.timing(anim, {
|
||||
toValue: 0,
|
||||
duration,
|
||||
useNativeDriver: true,
|
||||
}).start(({ finished }) => {
|
||||
if (finished) {
|
||||
setInnerVisible(false)
|
||||
hideModal()
|
||||
const maskStyle = useAnimatedStyle(() => ({
|
||||
opacity: interpolate(progress.value, [0, 1], [0, 0.45], 'clamp'),
|
||||
}))
|
||||
|
||||
/* ================= 手势(只给 bottom) ================= */
|
||||
const pan = Gesture.Pan()
|
||||
.onUpdate((e) => {
|
||||
if (menuPosition === 'bottom' && e.translationY > 0) {
|
||||
drag.value = e.translationY
|
||||
}
|
||||
})
|
||||
.onEnd(() => {
|
||||
if (menuPosition === 'bottom' && drag.value > 120) {
|
||||
progress.value = withTiming(0, { duration }, () => {
|
||||
drag.value = 0
|
||||
runOnJS(hideModal)()
|
||||
})
|
||||
}
|
||||
else {
|
||||
drag.value = withTiming(0)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/* ================== 位移 ================== */
|
||||
const getTransform = useCallback(() => {
|
||||
switch (menuPosition) {
|
||||
case 'left':
|
||||
return {
|
||||
translateX: anim.interpolate({
|
||||
inputRange: [0, 1],
|
||||
outputRange: [-WINDOW.width, 0],
|
||||
}),
|
||||
}
|
||||
case 'right':
|
||||
return {
|
||||
translateX: anim.interpolate({
|
||||
inputRange: [0, 1],
|
||||
outputRange: [WINDOW.width, 0],
|
||||
}),
|
||||
}
|
||||
case 'top':
|
||||
return {
|
||||
translateY: anim.interpolate({
|
||||
inputRange: [0, 1],
|
||||
outputRange: [-WINDOW.height, 0],
|
||||
}),
|
||||
}
|
||||
case 'bottom':
|
||||
default:
|
||||
return {
|
||||
translateY: anim.interpolate({
|
||||
inputRange: [0, 1],
|
||||
outputRange: [WINDOW.height, 0],
|
||||
}),
|
||||
}
|
||||
}
|
||||
}, [menuPosition])
|
||||
|
||||
if (!innerVisible)
|
||||
return null
|
||||
|
||||
return (
|
||||
<Modal transparent visible animationType="none">
|
||||
<View style={StyleSheet.absoluteFill} pointerEvents="box-none" className="z-[99]">
|
||||
{/* 遮罩 */}
|
||||
<TouchableWithoutFeedback onPress={() => isShadowHideModal && close()}>
|
||||
<Animated.View
|
||||
style={[
|
||||
styles.mask,
|
||||
{
|
||||
opacity: anim.interpolate({
|
||||
inputRange: [0, 1],
|
||||
outputRange: [0, 0.5],
|
||||
}),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</TouchableWithoutFeedback>
|
||||
<Animated.View
|
||||
style={[styles.mask, maskStyle]}
|
||||
onTouchEnd={() => isShadowHideModal && hideModal()}
|
||||
/>
|
||||
|
||||
{/* Drawer */}
|
||||
<View style={drawerMenuBox} pointerEvents="box-none">
|
||||
<Animated.View
|
||||
pointerEvents="box-none"
|
||||
style={[
|
||||
styles.container,
|
||||
{
|
||||
transform: [getTransform()],
|
||||
},
|
||||
]}
|
||||
>
|
||||
<View style={menuPositionStyle}>
|
||||
{menuPosition !== 'bottom' && (
|
||||
<View style={{ paddingTop: Platform.OS === 'ios' ? 50 : 0 }} />
|
||||
)}
|
||||
|
||||
{
|
||||
header || (
|
||||
<View style={[styles.drawerBox, drawerBox]}>
|
||||
<GestureDetector gesture={pan}>
|
||||
<Animated.View
|
||||
style={[
|
||||
styles.drawer,
|
||||
drawerStyle,
|
||||
{
|
||||
borderTopLeftRadius: isCircle ? CircleNum : 0,
|
||||
borderTopRightRadius: isCircle ? CircleNum : 0,
|
||||
},
|
||||
]}
|
||||
>
|
||||
{showHeader && (
|
||||
header ?? (
|
||||
<View style={styles.headTitle}>
|
||||
<Text style={styles.title}>{title}</Text>
|
||||
<LucideIcon
|
||||
icon="X"
|
||||
size={22}
|
||||
color="black"
|
||||
style={{ position: 'absolute', right: 15, top: 11 }}
|
||||
onPress={close}
|
||||
style={styles.close}
|
||||
onPress={hideModal}
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
)}
|
||||
|
||||
{children}
|
||||
</View>
|
||||
</Animated.View>
|
||||
</Animated.View>
|
||||
</GestureDetector>
|
||||
</View>
|
||||
</Modal>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -247,18 +173,25 @@ const styles = StyleSheet.create({
|
||||
...StyleSheet.absoluteFillObject,
|
||||
backgroundColor: '#000',
|
||||
},
|
||||
container: {
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
drawerBox: {
|
||||
position: 'absolute',
|
||||
},
|
||||
drawer: {
|
||||
flex: 1,
|
||||
backgroundColor: '#fff',
|
||||
},
|
||||
headTitle: {
|
||||
width: '100%',
|
||||
padding: 10,
|
||||
justifyContent: 'center',
|
||||
padding: 12,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
title: {
|
||||
fontSize: 18,
|
||||
fontWeight: '600',
|
||||
},
|
||||
close: {
|
||||
position: 'absolute',
|
||||
right: 16,
|
||||
top: 12,
|
||||
},
|
||||
})
|
||||
@@ -30,8 +30,8 @@ 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,
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 91 KiB |
@@ -26,14 +26,12 @@ export const useAppStore = create<AppState>((set, get) => ({
|
||||
const moneyCategoryStore = useMoneyCategoryStore.getState()
|
||||
const spaceStore = useSpaceStore.getState()
|
||||
|
||||
// 未登录:跳转到登录页,但认为初始化已完成(允许 UI 继续渲染)
|
||||
if (!userStore.isLoggedIn()) {
|
||||
navStore.navigateToAuth()
|
||||
set({ ready: true })
|
||||
return
|
||||
}
|
||||
|
||||
// 登录状态:执行完整初始化流程
|
||||
try {
|
||||
// 分类初始化
|
||||
await moneyCategoryStore.init()
|
||||
|
||||
@@ -1,21 +1,49 @@
|
||||
import type { icons } from 'lucide-react-native'
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage'
|
||||
import { router } from 'expo-router'
|
||||
// store/navigation.ts
|
||||
import { create } from 'zustand'
|
||||
import { createJSONStorage, persist } from 'zustand/middleware'
|
||||
|
||||
export interface NavItem {
|
||||
label: string
|
||||
path: string
|
||||
icon: keyof typeof icons
|
||||
}
|
||||
|
||||
interface NavState {
|
||||
navMenus: NavItem[]
|
||||
pathname: string
|
||||
setPathname: (p: string) => void
|
||||
navigateToAuth: () => void
|
||||
setNavMenus: (menus: NavItem[]) => void
|
||||
}
|
||||
|
||||
export const useNavStore = create<NavState>(set => ({
|
||||
pathname: '/',
|
||||
setPathname: (p: string) => set({ pathname: p }),
|
||||
navigateToAuth: () => {
|
||||
const pathname = useNavStore.getState().pathname
|
||||
const DEFAULT_NAV_MENUS: NavItem[] = [
|
||||
{ label: '记账', path: '/money', icon: 'CircleDollarSign' },
|
||||
{ label: '恋爱记', path: '/love', icon: 'Heart' },
|
||||
{ label: '聊天', path: '/chat', icon: 'MessageCircle' },
|
||||
{ label: '个人中心', path: '/user', icon: 'CircleUserRound' },
|
||||
]
|
||||
|
||||
if (!pathname.startsWith('/auth')) {
|
||||
router.replace('/auth')
|
||||
}
|
||||
},
|
||||
}))
|
||||
export const useNavStore = create<NavState>()(
|
||||
persist(
|
||||
(set, get) => ({
|
||||
pathname: '/',
|
||||
navMenus: DEFAULT_NAV_MENUS,
|
||||
|
||||
setPathname: (p: string) => set({ pathname: p }),
|
||||
navigateToAuth: () => {
|
||||
const pathname = useNavStore.getState().pathname
|
||||
|
||||
if (!pathname.startsWith('/auth')) {
|
||||
router.replace('/auth')
|
||||
}
|
||||
},
|
||||
setNavMenus: navMenus => set({ navMenus }),
|
||||
}),
|
||||
{
|
||||
name: 'nav-storage',
|
||||
storage: createJSONStorage(() => AsyncStorage),
|
||||
},
|
||||
),
|
||||
)
|
||||
@@ -0,0 +1,9 @@
|
||||
module allapp-go
|
||||
|
||||
go 1.25.3
|
||||
|
||||
require (
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/redis/go-redis/v9 v9.17.3 // indirect
|
||||
)
|
||||
@@ -0,0 +1,6 @@
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/redis/go-redis/v9 v9.17.3 h1:fN29NdNrE17KttK5Ndf20buqfDZwGNgoUr9qjl1DQx4=
|
||||
github.com/redis/go-redis/v9 v9.17.3/go.mod h1:u410H11HMLoB+TP67dz8rL9s6QW2j76l0//kSOd3370=
|
||||
+1
-1
Submodule code/docusaurus updated: 55d88676f3...4f58d5b99b.
Reference in new issue
Block a user