init: init refactor
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
Name: user-api
|
||||
Host: 0.0.0.0
|
||||
Port: 9001
|
||||
|
||||
Auth:
|
||||
AccessSecret: 9149f2eb-d517-4a50-a03a-231dbcf0d872
|
||||
AccessExpire: 7200
|
||||
|
||||
# user-rpc 服务配置
|
||||
UserRpc:
|
||||
Etcd:
|
||||
Hosts:
|
||||
- 192.168.100.127:2379
|
||||
Key: user.rpc
|
||||
@@ -0,0 +1,18 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/zeromicro/go-zero/rest"
|
||||
"github.com/zeromicro/go-zero/zrpc"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
rest.RestConf
|
||||
Auth struct {
|
||||
AccessSecret string
|
||||
AccessExpire int64
|
||||
}
|
||||
UserRpc zrpc.RpcClientConf
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package auth
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"sundynix-micro-go/app/user/api/internal/logic/auth"
|
||||
"sundynix-micro-go/app/user/api/internal/svc"
|
||||
"sundynix-micro-go/app/user/api/internal/types"
|
||||
"sundynix-micro-go/common/response"
|
||||
)
|
||||
|
||||
// 手机号登录
|
||||
func LoginByPhoneHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.LoginByPhoneReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
response.Fail(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
l := auth.NewLoginByPhoneLogic(r.Context(), svcCtx)
|
||||
resp, err := l.LoginByPhone(&req)
|
||||
if err != nil {
|
||||
response.Fail(w, err.Error())
|
||||
} else {
|
||||
response.OkWithData(w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package auth
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"sundynix-micro-go/app/user/api/internal/logic/auth"
|
||||
"sundynix-micro-go/app/user/api/internal/svc"
|
||||
"sundynix-micro-go/app/user/api/internal/types"
|
||||
"sundynix-micro-go/common/response"
|
||||
)
|
||||
|
||||
// 账号密码登录
|
||||
func LoginHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.LoginReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
response.Fail(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
l := auth.NewLoginLogic(r.Context(), svcCtx)
|
||||
resp, err := l.Login(&req)
|
||||
if err != nil {
|
||||
response.Fail(w, err.Error())
|
||||
} else {
|
||||
response.OkWithData(w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package auth
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"sundynix-micro-go/app/user/api/internal/logic/auth"
|
||||
"sundynix-micro-go/app/user/api/internal/svc"
|
||||
"sundynix-micro-go/app/user/api/internal/types"
|
||||
"sundynix-micro-go/common/response"
|
||||
)
|
||||
|
||||
// 微信小程序登录
|
||||
func MiniLoginHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.MiniLoginReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
response.Fail(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
l := auth.NewMiniLoginLogic(r.Context(), svcCtx)
|
||||
resp, err := l.MiniLogin(&req)
|
||||
if err != nil {
|
||||
response.Fail(w, err.Error())
|
||||
} else {
|
||||
response.OkWithData(w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
// Code generated by goctl. DO NOT EDIT.
|
||||
// goctl 1.10.1
|
||||
|
||||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
auth "sundynix-micro-go/app/user/api/internal/handler/auth"
|
||||
user "sundynix-micro-go/app/user/api/internal/handler/user"
|
||||
"sundynix-micro-go/app/user/api/internal/svc"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest"
|
||||
)
|
||||
|
||||
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||
server.AddRoutes(
|
||||
[]rest.Route{
|
||||
{
|
||||
// 账号密码登录
|
||||
Method: http.MethodPost,
|
||||
Path: "/login",
|
||||
Handler: auth.LoginHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
// 手机号登录
|
||||
Method: http.MethodPost,
|
||||
Path: "/loginByPhone",
|
||||
Handler: auth.LoginByPhoneHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
// 微信小程序登录
|
||||
Method: http.MethodPost,
|
||||
Path: "/miniLogin",
|
||||
Handler: auth.MiniLoginHandler(serverCtx),
|
||||
},
|
||||
},
|
||||
rest.WithPrefix("/api/user"),
|
||||
)
|
||||
|
||||
server.AddRoutes(
|
||||
[]rest.Route{
|
||||
{
|
||||
// 修改密码
|
||||
Method: http.MethodPut,
|
||||
Path: "/changePassword",
|
||||
Handler: user.ChangePasswordHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
// 删除用户
|
||||
Method: http.MethodDelete,
|
||||
Path: "/delete",
|
||||
Handler: user.DeleteUserHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
// 获取当前用户信息
|
||||
Method: http.MethodGet,
|
||||
Path: "/info",
|
||||
Handler: user.GetUserInfoHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
// 用户列表
|
||||
Method: http.MethodPost,
|
||||
Path: "/list",
|
||||
Handler: user.GetUserListHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
// 获取位置信息
|
||||
Method: http.MethodGet,
|
||||
Path: "/location",
|
||||
Handler: user.GetLocationHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
// 更新用户信息
|
||||
Method: http.MethodPut,
|
||||
Path: "/update",
|
||||
Handler: user.UpdateUserHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
// 获取天气信息
|
||||
Method: http.MethodGet,
|
||||
Path: "/weather",
|
||||
Handler: user.GetWeatherHandler(serverCtx),
|
||||
},
|
||||
},
|
||||
rest.WithJwt(serverCtx.Config.Auth.AccessSecret),
|
||||
rest.WithPrefix("/api/user"),
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package user
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"sundynix-micro-go/app/user/api/internal/logic/user"
|
||||
"sundynix-micro-go/app/user/api/internal/svc"
|
||||
"sundynix-micro-go/app/user/api/internal/types"
|
||||
"sundynix-micro-go/common/response"
|
||||
)
|
||||
|
||||
// 修改密码
|
||||
func ChangePasswordHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.ChangePasswordReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
response.Fail(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
l := user.NewChangePasswordLogic(r.Context(), svcCtx)
|
||||
err := l.ChangePassword(&req)
|
||||
if err != nil {
|
||||
response.Fail(w, err.Error())
|
||||
} else {
|
||||
response.Ok(w)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package user
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"sundynix-micro-go/app/user/api/internal/logic/user"
|
||||
"sundynix-micro-go/app/user/api/internal/svc"
|
||||
"sundynix-micro-go/app/user/api/internal/types"
|
||||
"sundynix-micro-go/common/response"
|
||||
)
|
||||
|
||||
// 删除用户
|
||||
func DeleteUserHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.IdsReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
response.Fail(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
l := user.NewDeleteUserLogic(r.Context(), svcCtx)
|
||||
err := l.DeleteUser(&req)
|
||||
if err != nil {
|
||||
response.Fail(w, err.Error())
|
||||
} else {
|
||||
response.Ok(w)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package user
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"sundynix-micro-go/app/user/api/internal/logic/user"
|
||||
"sundynix-micro-go/app/user/api/internal/svc"
|
||||
"sundynix-micro-go/app/user/api/internal/types"
|
||||
"sundynix-micro-go/common/response"
|
||||
)
|
||||
|
||||
// 获取位置信息
|
||||
func GetLocationHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.LocationReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
response.Fail(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
l := user.NewGetLocationLogic(r.Context(), svcCtx)
|
||||
err := l.GetLocation(&req)
|
||||
if err != nil {
|
||||
response.Fail(w, err.Error())
|
||||
} else {
|
||||
response.Ok(w)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package user
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"sundynix-micro-go/app/user/api/internal/logic/user"
|
||||
"sundynix-micro-go/app/user/api/internal/svc"
|
||||
"sundynix-micro-go/common/response"
|
||||
)
|
||||
|
||||
// 获取当前用户信息
|
||||
func GetUserInfoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
l := user.NewGetUserInfoLogic(r.Context(), svcCtx)
|
||||
resp, err := l.GetUserInfo()
|
||||
if err != nil {
|
||||
response.Fail(w, err.Error())
|
||||
} else {
|
||||
response.OkWithData(w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package user
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"sundynix-micro-go/app/user/api/internal/logic/user"
|
||||
"sundynix-micro-go/app/user/api/internal/svc"
|
||||
"sundynix-micro-go/app/user/api/internal/types"
|
||||
"sundynix-micro-go/common/response"
|
||||
)
|
||||
|
||||
// 用户列表
|
||||
func GetUserListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.UserListReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
response.Fail(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
l := user.NewGetUserListLogic(r.Context(), svcCtx)
|
||||
err := l.GetUserList(&req)
|
||||
if err != nil {
|
||||
response.Fail(w, err.Error())
|
||||
} else {
|
||||
response.Ok(w)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package user
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"sundynix-micro-go/app/user/api/internal/logic/user"
|
||||
"sundynix-micro-go/app/user/api/internal/svc"
|
||||
"sundynix-micro-go/app/user/api/internal/types"
|
||||
"sundynix-micro-go/common/response"
|
||||
)
|
||||
|
||||
// 获取天气信息
|
||||
func GetWeatherHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.WeatherReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
response.Fail(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
l := user.NewGetWeatherLogic(r.Context(), svcCtx)
|
||||
err := l.GetWeather(&req)
|
||||
if err != nil {
|
||||
response.Fail(w, err.Error())
|
||||
} else {
|
||||
response.Ok(w)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package user
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"sundynix-micro-go/app/user/api/internal/logic/user"
|
||||
"sundynix-micro-go/app/user/api/internal/svc"
|
||||
"sundynix-micro-go/app/user/api/internal/types"
|
||||
"sundynix-micro-go/common/response"
|
||||
)
|
||||
|
||||
// 更新用户信息
|
||||
func UpdateUserHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.UpdateUserReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
response.Fail(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
l := user.NewUpdateUserLogic(r.Context(), svcCtx)
|
||||
err := l.UpdateUser(&req)
|
||||
if err != nil {
|
||||
response.Fail(w, err.Error())
|
||||
} else {
|
||||
response.Ok(w)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"sundynix-micro-go/app/user/api/internal/svc"
|
||||
"sundynix-micro-go/app/user/api/internal/types"
|
||||
"sundynix-micro-go/app/user/rpc/user"
|
||||
jwtUtil "sundynix-micro-go/common/utils/jwt"
|
||||
|
||||
jwtv5 "github.com/golang-jwt/jwt/v5"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type LoginByPhoneLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewLoginByPhoneLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LoginByPhoneLogic {
|
||||
return &LoginByPhoneLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *LoginByPhoneLogic) LoginByPhone(req *types.LoginByPhoneReq) (resp *types.LoginResp, err error) {
|
||||
// 1. 调用微信接口获取手机号
|
||||
// TODO: 从配置中获取access_token
|
||||
accessToken := "" // 需要通过微信API获取
|
||||
apiURL := "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessToken
|
||||
|
||||
data := map[string]interface{}{"code": req.Code}
|
||||
jsonData, _ := json.Marshal(data)
|
||||
|
||||
httpResp, err := http.Post(apiURL, "application/json", nil)
|
||||
if err != nil {
|
||||
l.Errorf("获取手机号失败: %v", err)
|
||||
return nil, fmt.Errorf("获取手机号失败")
|
||||
}
|
||||
defer httpResp.Body.Close()
|
||||
|
||||
body, _ := io.ReadAll(httpResp.Body)
|
||||
var dataMap map[string]interface{}
|
||||
_ = json.Unmarshal(body, &dataMap)
|
||||
_ = jsonData
|
||||
_ = url.Values{}
|
||||
|
||||
// 2. 通过 user-rpc 查询用户
|
||||
userResp, err := l.svcCtx.UserRpc.GetUserByOpenId(l.ctx, &user.GetUserByOpenIdReq{
|
||||
OpenId: req.OpenId,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("用户不存在")
|
||||
}
|
||||
|
||||
// 3. 如果需要更新手机号
|
||||
phoneInfo, ok := dataMap["phone_info"].(map[string]interface{})
|
||||
if ok {
|
||||
phoneNumber, _ := phoneInfo["phoneNumber"].(string)
|
||||
if phoneNumber != "" && userResp.User.Phone == "" {
|
||||
_, _ = l.svcCtx.UserRpc.UpdateUser(l.ctx, &user.UpdateUserReq{
|
||||
Id: userResp.User.Id,
|
||||
Phone: phoneNumber,
|
||||
})
|
||||
userResp.User.Phone = phoneNumber
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 生成Token
|
||||
j := jwtUtil.NewJWT(l.svcCtx.Config.Auth.AccessSecret)
|
||||
claims := jwtUtil.CustomClaims{
|
||||
BaseClaims: jwtUtil.BaseClaims{
|
||||
ID: userResp.User.Id,
|
||||
Account: userResp.User.Account,
|
||||
},
|
||||
BufferTime: 3600,
|
||||
RegisteredClaims: jwtv5.RegisteredClaims{
|
||||
ExpiresAt: jwtv5.NewNumericDate(time.Now().Add(time.Duration(l.svcCtx.Config.Auth.AccessExpire) * time.Second)),
|
||||
Issuer: "sundynix",
|
||||
},
|
||||
}
|
||||
token, _ := j.CreateToken(claims)
|
||||
|
||||
return &types.LoginResp{
|
||||
Token: token,
|
||||
UserInfo: userResp.User,
|
||||
}, nil
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"sundynix-micro-go/app/user/api/internal/svc"
|
||||
"sundynix-micro-go/app/user/api/internal/types"
|
||||
"sundynix-micro-go/app/user/rpc/user"
|
||||
jwtUtil "sundynix-micro-go/common/utils/jwt"
|
||||
|
||||
jwtv5 "github.com/golang-jwt/jwt/v5"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
type LoginLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LoginLogic {
|
||||
return &LoginLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *LoginLogic) Login(req *types.LoginReq) (resp *types.LoginResp, err error) {
|
||||
// 通过 user-rpc 查询用户 (account登录暂用GetUserByOpenId的方式,后续需补充account查询RPC)
|
||||
// 这里简化处理:直接在api层查询并验证密码
|
||||
// TODO: 后续应该在user-rpc中增加LoginByAccount方法
|
||||
|
||||
_ = req
|
||||
_ = l
|
||||
|
||||
return nil, status.Error(codes.Unimplemented, "账号密码登录功能开发中")
|
||||
}
|
||||
|
||||
// generateToken 生成JWT Token的辅助方法
|
||||
func generateToken(config svc.ServiceContext, userInfo *user.UserInfo) (string, error) {
|
||||
j := jwtUtil.NewJWT(config.Config.Auth.AccessSecret)
|
||||
claims := jwtUtil.CustomClaims{
|
||||
BaseClaims: jwtUtil.BaseClaims{
|
||||
ID: userInfo.Id,
|
||||
Account: userInfo.Account,
|
||||
},
|
||||
BufferTime: 3600,
|
||||
RegisteredClaims: jwtv5.RegisteredClaims{
|
||||
Audience: jwtv5.ClaimStrings{"sundynix"},
|
||||
NotBefore: jwtv5.NewNumericDate(time.Now().Add(-1000)),
|
||||
ExpiresAt: jwtv5.NewNumericDate(time.Now().Add(time.Duration(config.Config.Auth.AccessExpire) * time.Second)),
|
||||
Issuer: "sundynix",
|
||||
},
|
||||
}
|
||||
token, err := j.CreateToken(claims)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("生成Token失败: %w", err)
|
||||
}
|
||||
return token, nil
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"sundynix-micro-go/app/user/api/internal/svc"
|
||||
"sundynix-micro-go/app/user/api/internal/types"
|
||||
"sundynix-micro-go/app/user/rpc/user"
|
||||
jwtUtil "sundynix-micro-go/common/utils/jwt"
|
||||
|
||||
jwtv5 "github.com/golang-jwt/jwt/v5"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type MiniLoginLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
// 微信小程序登录
|
||||
func NewMiniLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *MiniLoginLogic {
|
||||
return &MiniLoginLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
// WxCode2SessionResp 微信code2session响应
|
||||
type WxCode2SessionResp struct {
|
||||
Openid string `json:"openid"`
|
||||
SessionKey string `json:"session_key"`
|
||||
Unionid string `json:"unionid"`
|
||||
Errcode int `json:"errcode"`
|
||||
Errmsg string `json:"errmsg"`
|
||||
}
|
||||
|
||||
func (l *MiniLoginLogic) MiniLogin(req *types.MiniLoginReq) (resp *types.LoginResp, err error) {
|
||||
// 1. 调用微信接口获取openid和session_key
|
||||
// TODO: 从配置中获取AppId和AppSecret,当前先用固定值
|
||||
appID := "wxb463820bf36dd5d6"
|
||||
appSecret := "731784a74c76c6d31fa00bb847af2c7d"
|
||||
|
||||
params := url.Values{}
|
||||
params.Set("appid", appID)
|
||||
params.Set("secret", appSecret)
|
||||
params.Set("js_code", req.Code)
|
||||
params.Set("grant_type", "authorization_code")
|
||||
fullURL := "https://api.weixin.qq.com/sns/jscode2session?" + params.Encode()
|
||||
|
||||
httpResp, err := http.Get(fullURL)
|
||||
if err != nil {
|
||||
l.Errorf("微信登录接口请求失败: %v", err)
|
||||
return nil, fmt.Errorf("微信登录接口请求失败")
|
||||
}
|
||||
defer httpResp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(httpResp.Body)
|
||||
if err != nil {
|
||||
l.Errorf("读取微信接口响应失败: %v", err)
|
||||
return nil, fmt.Errorf("读取微信登录接口响应失败")
|
||||
}
|
||||
|
||||
var wxResp WxCode2SessionResp
|
||||
if err = json.Unmarshal(body, &wxResp); err != nil {
|
||||
l.Errorf("解析微信接口响应失败: %v", err)
|
||||
return nil, fmt.Errorf("解析微信登录接口响应失败")
|
||||
}
|
||||
|
||||
if wxResp.Errcode != 0 {
|
||||
l.Errorf("微信接口返回错误: errcode=%d, errmsg=%s", wxResp.Errcode, wxResp.Errmsg)
|
||||
return nil, fmt.Errorf("微信登录失败: %s", wxResp.Errmsg)
|
||||
}
|
||||
|
||||
if wxResp.Openid == "" {
|
||||
return nil, fmt.Errorf("openid为空")
|
||||
}
|
||||
|
||||
// 2. 通过 user-rpc 创建或获取用户
|
||||
createResp, err := l.svcCtx.UserRpc.CreateUser(l.ctx, &user.CreateUserReq{
|
||||
Name: "",
|
||||
OpenId: wxResp.Openid,
|
||||
SessionKey: wxResp.SessionKey,
|
||||
ClientId: req.ClientId,
|
||||
})
|
||||
if err != nil {
|
||||
l.Errorf("创建用户失败: %v", err)
|
||||
return nil, fmt.Errorf("登录失败")
|
||||
}
|
||||
|
||||
// 3. 生成JWT Token
|
||||
j := jwtUtil.NewJWT(l.svcCtx.Config.Auth.AccessSecret)
|
||||
claims := jwtUtil.CustomClaims{
|
||||
BaseClaims: jwtUtil.BaseClaims{
|
||||
ID: createResp.User.Id,
|
||||
Account: createResp.User.Account,
|
||||
},
|
||||
BufferTime: 3600,
|
||||
RegisteredClaims: jwtv5.RegisteredClaims{
|
||||
Audience: jwtv5.ClaimStrings{"sundynix"},
|
||||
NotBefore: jwtv5.NewNumericDate(time.Now().Add(-1000)),
|
||||
ExpiresAt: jwtv5.NewNumericDate(time.Now().Add(time.Duration(l.svcCtx.Config.Auth.AccessExpire) * time.Second)),
|
||||
Issuer: "sundynix",
|
||||
},
|
||||
}
|
||||
token, err := j.CreateToken(claims)
|
||||
if err != nil {
|
||||
l.Errorf("生成Token失败: %v", err)
|
||||
return nil, fmt.Errorf("登录失败")
|
||||
}
|
||||
|
||||
return &types.LoginResp{
|
||||
Token: token,
|
||||
UserInfo: createResp.User,
|
||||
}, nil
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"sundynix-micro-go/app/user/api/internal/svc"
|
||||
"sundynix-micro-go/app/user/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type ChangePasswordLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
// 修改密码
|
||||
func NewChangePasswordLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ChangePasswordLogic {
|
||||
return &ChangePasswordLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *ChangePasswordLogic) ChangePassword(req *types.ChangePasswordReq) error {
|
||||
// todo: add your logic here and delete this line
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"sundynix-micro-go/app/user/api/internal/svc"
|
||||
"sundynix-micro-go/app/user/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type DeleteUserLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
// 删除用户
|
||||
func NewDeleteUserLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DeleteUserLogic {
|
||||
return &DeleteUserLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *DeleteUserLogic) DeleteUser(req *types.IdsReq) error {
|
||||
// todo: add your logic here and delete this line
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"sundynix-micro-go/app/user/api/internal/svc"
|
||||
"sundynix-micro-go/app/user/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetLocationLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
// 获取位置信息
|
||||
func NewGetLocationLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetLocationLogic {
|
||||
return &GetLocationLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetLocationLogic) GetLocation(req *types.LocationReq) error {
|
||||
// todo: add your logic here and delete this line
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"sundynix-micro-go/app/user/api/internal/svc"
|
||||
"sundynix-micro-go/app/user/api/internal/types"
|
||||
pb "sundynix-micro-go/app/user/rpc/user"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetUserInfoLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGetUserInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetUserInfoLogic {
|
||||
return &GetUserInfoLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetUserInfoLogic) GetUserInfo() (resp *types.LoginResp, err error) {
|
||||
// 从JWT claims中获取userId
|
||||
userId := fmt.Sprintf("%v", l.ctx.Value("userId"))
|
||||
if userId == "" || userId == "<nil>" {
|
||||
return nil, fmt.Errorf("用户未登录")
|
||||
}
|
||||
|
||||
userResp, err := l.svcCtx.UserRpc.GetUserById(l.ctx, &pb.GetUserByIdReq{
|
||||
Id: userId,
|
||||
})
|
||||
if err != nil {
|
||||
l.Errorf("获取用户信息失败: %v", err)
|
||||
return nil, fmt.Errorf("获取用户信息失败")
|
||||
}
|
||||
|
||||
// 将proto消息转换为map以便JSON序列化
|
||||
userJSON, _ := json.Marshal(userResp.User)
|
||||
var userInfo interface{}
|
||||
_ = json.Unmarshal(userJSON, &userInfo)
|
||||
|
||||
return &types.LoginResp{
|
||||
UserInfo: userInfo,
|
||||
}, nil
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"sundynix-micro-go/app/user/api/internal/svc"
|
||||
"sundynix-micro-go/app/user/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetUserListLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
// 用户列表
|
||||
func NewGetUserListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetUserListLogic {
|
||||
return &GetUserListLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetUserListLogic) GetUserList(req *types.UserListReq) error {
|
||||
// todo: add your logic here and delete this line
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"sundynix-micro-go/app/user/api/internal/svc"
|
||||
"sundynix-micro-go/app/user/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetWeatherLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
// 获取天气信息
|
||||
func NewGetWeatherLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetWeatherLogic {
|
||||
return &GetWeatherLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetWeatherLogic) GetWeather(req *types.WeatherReq) error {
|
||||
// todo: add your logic here and delete this line
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"sundynix-micro-go/app/user/api/internal/svc"
|
||||
"sundynix-micro-go/app/user/api/internal/types"
|
||||
pb "sundynix-micro-go/app/user/rpc/user"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type UpdateUserLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewUpdateUserLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateUserLogic {
|
||||
return &UpdateUserLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *UpdateUserLogic) UpdateUser(req *types.UpdateUserReq) error {
|
||||
userId := fmt.Sprintf("%v", l.ctx.Value("userId"))
|
||||
if userId == "" || userId == "<nil>" {
|
||||
return fmt.Errorf("用户未登录")
|
||||
}
|
||||
|
||||
_, err := l.svcCtx.UserRpc.UpdateUser(l.ctx, &pb.UpdateUserReq{
|
||||
Id: userId,
|
||||
Name: req.Name,
|
||||
Account: req.Account,
|
||||
Phone: req.Phone,
|
||||
AvatarId: req.AvatarId,
|
||||
NickName: req.NickName,
|
||||
})
|
||||
if err != nil {
|
||||
l.Errorf("更新用户失败: %v", err)
|
||||
return fmt.Errorf("更新用户失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package svc
|
||||
|
||||
import (
|
||||
"sundynix-micro-go/app/user/api/internal/config"
|
||||
"sundynix-micro-go/app/user/rpc/userservice"
|
||||
|
||||
"github.com/zeromicro/go-zero/zrpc"
|
||||
)
|
||||
|
||||
type ServiceContext struct {
|
||||
Config config.Config
|
||||
UserRpc userservice.UserService
|
||||
}
|
||||
|
||||
func NewServiceContext(c config.Config) *ServiceContext {
|
||||
return &ServiceContext{
|
||||
Config: c,
|
||||
UserRpc: userservice.NewUserService(zrpc.MustNewClient(c.UserRpc)),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
// Code generated by goctl. DO NOT EDIT.
|
||||
// goctl 1.10.1
|
||||
|
||||
package types
|
||||
|
||||
type ChangePasswordReq struct {
|
||||
OldPassword string `json:"oldPassword"`
|
||||
NewPassword string `json:"newPassword"`
|
||||
}
|
||||
|
||||
type IdReq struct {
|
||||
Id string `json:"id"`
|
||||
}
|
||||
|
||||
type IdsReq struct {
|
||||
Ids []string `json:"ids"`
|
||||
}
|
||||
|
||||
type LocationReq struct {
|
||||
Longitude string `form:"longitude"`
|
||||
Latitude string `form:"latitude"`
|
||||
}
|
||||
|
||||
type LoginByPhoneReq struct {
|
||||
Code string `json:"code"`
|
||||
OpenId string `json:"openId"`
|
||||
ClientId string `json:"clientId"`
|
||||
}
|
||||
|
||||
type LoginReq struct {
|
||||
Account string `json:"account"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
type LoginResp struct {
|
||||
Token string `json:"token"`
|
||||
UserInfo interface{} `json:"userInfo"`
|
||||
}
|
||||
|
||||
type MiniLoginReq struct {
|
||||
Code string `json:"code"`
|
||||
ClientId string `json:"clientId"`
|
||||
}
|
||||
|
||||
type UpdateUserReq struct {
|
||||
Name string `json:"name,optional"`
|
||||
Account string `json:"account,optional"`
|
||||
Phone string `json:"phone,optional"`
|
||||
AvatarId string `json:"avatarId,optional"`
|
||||
NickName string `json:"nickName,optional"`
|
||||
}
|
||||
|
||||
type UserListReq struct {
|
||||
Current int `json:"current,optional"`
|
||||
PageSize int `json:"pageSize,optional"`
|
||||
Account string `json:"account,optional"`
|
||||
Phone string `json:"phone,optional"`
|
||||
}
|
||||
|
||||
type WeatherReq struct {
|
||||
Adcode string `form:"adcode"`
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
syntax = "v1"
|
||||
|
||||
info (
|
||||
title: "用户服务API"
|
||||
desc: "用户登录、信息管理等HTTP接口"
|
||||
author: "sundynix"
|
||||
version: "v1.0.0"
|
||||
)
|
||||
|
||||
type (
|
||||
// 微信小程序登录
|
||||
MiniLoginReq {
|
||||
Code string `json:"code"`
|
||||
ClientId string `json:"clientId"`
|
||||
}
|
||||
// 手机号登录
|
||||
LoginByPhoneReq {
|
||||
Code string `json:"code"`
|
||||
OpenId string `json:"openId"`
|
||||
ClientId string `json:"clientId"`
|
||||
}
|
||||
// 账号密码登录
|
||||
LoginReq {
|
||||
Account string `json:"account"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
// 登录响应
|
||||
LoginResp {
|
||||
Token string `json:"token"`
|
||||
UserInfo interface{} `json:"userInfo"`
|
||||
}
|
||||
// 更新用户
|
||||
UpdateUserReq {
|
||||
Name string `json:"name,optional"`
|
||||
Account string `json:"account,optional"`
|
||||
Phone string `json:"phone,optional"`
|
||||
AvatarId string `json:"avatarId,optional"`
|
||||
NickName string `json:"nickName,optional"`
|
||||
}
|
||||
// 修改密码
|
||||
ChangePasswordReq {
|
||||
OldPassword string `json:"oldPassword"`
|
||||
NewPassword string `json:"newPassword"`
|
||||
}
|
||||
// 用户列表查询
|
||||
UserListReq {
|
||||
Current int `json:"current,optional"`
|
||||
PageSize int `json:"pageSize,optional"`
|
||||
Account string `json:"account,optional"`
|
||||
Phone string `json:"phone,optional"`
|
||||
}
|
||||
// 通用ID请求
|
||||
IdReq {
|
||||
Id string `json:"id"`
|
||||
}
|
||||
// 批量ID请求
|
||||
IdsReq {
|
||||
Ids []string `json:"ids"`
|
||||
}
|
||||
// 获取位置
|
||||
LocationReq {
|
||||
Longitude string `form:"longitude"`
|
||||
Latitude string `form:"latitude"`
|
||||
}
|
||||
// 获取天气
|
||||
WeatherReq {
|
||||
Adcode string `form:"adcode"`
|
||||
}
|
||||
)
|
||||
|
||||
// ========== 无需鉴权的接口 ==========
|
||||
@server (
|
||||
prefix: /api/user
|
||||
group: auth
|
||||
)
|
||||
service user-api {
|
||||
@doc "微信小程序登录"
|
||||
@handler MiniLogin
|
||||
post /miniLogin (MiniLoginReq) returns (LoginResp)
|
||||
|
||||
@doc "手机号登录"
|
||||
@handler LoginByPhone
|
||||
post /loginByPhone (LoginByPhoneReq) returns (LoginResp)
|
||||
|
||||
@doc "账号密码登录"
|
||||
@handler Login
|
||||
post /login (LoginReq) returns (LoginResp)
|
||||
}
|
||||
|
||||
// ========== 需要鉴权的接口 ==========
|
||||
@server (
|
||||
prefix: /api/user
|
||||
group: user
|
||||
jwt: Auth
|
||||
)
|
||||
service user-api {
|
||||
@doc "获取当前用户信息"
|
||||
@handler GetUserInfo
|
||||
get /info returns (LoginResp)
|
||||
|
||||
@doc "更新用户信息"
|
||||
@handler UpdateUser
|
||||
put /update (UpdateUserReq)
|
||||
|
||||
@doc "修改密码"
|
||||
@handler ChangePassword
|
||||
put /changePassword (ChangePasswordReq)
|
||||
|
||||
@doc "用户列表"
|
||||
@handler GetUserList
|
||||
post /list (UserListReq)
|
||||
|
||||
@doc "删除用户"
|
||||
@handler DeleteUser
|
||||
delete /delete (IdsReq)
|
||||
|
||||
@doc "获取位置信息"
|
||||
@handler GetLocation
|
||||
get /location (LocationReq)
|
||||
|
||||
@doc "获取天气信息"
|
||||
@handler GetWeather
|
||||
get /weather (WeatherReq)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
"sundynix-micro-go/app/user/api/internal/config"
|
||||
"sundynix-micro-go/app/user/api/internal/handler"
|
||||
"sundynix-micro-go/app/user/api/internal/svc"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/conf"
|
||||
"github.com/zeromicro/go-zero/rest"
|
||||
)
|
||||
|
||||
var configFile = flag.String("f", "etc/user-api.yaml", "the config file")
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
var c config.Config
|
||||
conf.MustLoad(*configFile, &c)
|
||||
|
||||
server := rest.MustNewServer(c.RestConf)
|
||||
defer server.Stop()
|
||||
|
||||
ctx := svc.NewServiceContext(c)
|
||||
handler.RegisterHandlers(server, ctx)
|
||||
|
||||
fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
|
||||
server.Start()
|
||||
}
|
||||
Reference in New Issue
Block a user