first commit
This commit is contained in:
31
apps/gateway/Dockerfile
Normal file
31
apps/gateway/Dockerfile
Normal file
@@ -0,0 +1,31 @@
|
||||
FROM golang:alpine AS builder
|
||||
|
||||
LABEL stage=gobuilder
|
||||
|
||||
ENV CGO_ENABLED 0
|
||||
ENV GOPROXY https://goproxy.cn,direct
|
||||
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
|
||||
|
||||
RUN apk update --no-cache && apk add --no-cache tzdata
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
ADD go.mod .
|
||||
ADD go.sum .
|
||||
RUN go mod download
|
||||
COPY . .
|
||||
COPY apps/gateway/etc /app/etc
|
||||
RUN go build -ldflags="-s -w" -o /app/gateway apps/gateway/.\gateway.go
|
||||
|
||||
|
||||
FROM scratch
|
||||
|
||||
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
|
||||
COPY --from=builder /usr/share/zoneinfo/Asia/Shanghai /usr/share/zoneinfo/Asia/Shanghai
|
||||
ENV TZ Asia/Shanghai
|
||||
|
||||
WORKDIR /app
|
||||
COPY --from=builder /app/gateway /app/gateway
|
||||
COPY --from=builder /app/etc /app/etc
|
||||
|
||||
CMD ["./gateway", "-f", "etc/gateway-api.yaml"]
|
||||
38
apps/gateway/etc/gateway-api.yaml
Normal file
38
apps/gateway/etc/gateway-api.yaml
Normal file
@@ -0,0 +1,38 @@
|
||||
Name: gateway-api
|
||||
Host: 0.0.0.0
|
||||
Port: 10001
|
||||
DataSource: "tianyuanapi:g3h98u0291j@tcp(127.0.0.1:3307)/tianyuanapi?charset=utf8mb4&parseTime=True&loc=Local"
|
||||
AuthJWT:
|
||||
AccessSecret: "Mf5Xph3PoyKzVpRw0Zy1+X4uR/tM7JvGMEV/5p2M/tU="
|
||||
AccessExpire: 86400 # JWT过期时间
|
||||
CacheRedis:
|
||||
- Host: "127.0.0.1:6379"
|
||||
Pass: "" # Redis 密码,如果未设置则留空
|
||||
Type: "node" # 单节点模式
|
||||
VerifyCode:
|
||||
AccessKeyID: "LTAI5tHKcV1RbC8t68UfsATy"
|
||||
AccessKeySecret: "wLWjMBnAlchFMa9gC8B7ZVBKaew4t5"
|
||||
EndpointURL: "dysmsapi.aliyuncs.com"
|
||||
SignName: "天远查"
|
||||
TemplateCode: "SMS_299200388"
|
||||
ValidTime: 300
|
||||
Qiniu:
|
||||
AccessKey: "AO6u6sDWi6L9TsPfr4awC7FYP85JTjt3bodZACCM"
|
||||
SecretKey: "2fjxweGtSAEaUdVgDkWEmN7JbBxHBQDv1cLORb9_"
|
||||
Bucket: "tianyuanapi"
|
||||
Domain: "https://file.tianyuanapi.com"
|
||||
|
||||
Baidu:
|
||||
ApiKey: "aMsrBNGUJxgcgqdm3SEdcumm"
|
||||
SecretKey: "sWlv2h2AWA3aAt5bjXCkE6WeA5AzpAAD"
|
||||
|
||||
UserRpc:
|
||||
Etcd:
|
||||
Hosts:
|
||||
- 127.0.0.1:2379
|
||||
Key: user.rpc
|
||||
SentinelRpc:
|
||||
Etcd:
|
||||
Hosts:
|
||||
- 127.0.0.1:2379
|
||||
Key: sentinel.rpc
|
||||
252
apps/gateway/gateway.api
Normal file
252
apps/gateway/gateway.api
Normal file
@@ -0,0 +1,252 @@
|
||||
syntax = "console"
|
||||
|
||||
//---------------------------- Base ------------------------
|
||||
type (
|
||||
healthResp {
|
||||
time string `json:"time"`
|
||||
}
|
||||
)
|
||||
|
||||
@server (
|
||||
group: base
|
||||
prefix: /api/console/base
|
||||
)
|
||||
service gateway-api {
|
||||
@handler health
|
||||
get /health returns (healthResp)
|
||||
}
|
||||
|
||||
//--------------------------- Auth ------------------------
|
||||
type (
|
||||
LoginReq {
|
||||
username string `json:"username"`
|
||||
password string `json:"password"`
|
||||
}
|
||||
phoneLoginReq {
|
||||
phone string `json:"phone"`
|
||||
code string `json:"code"`
|
||||
}
|
||||
RegisterReq {
|
||||
username string `json:"username"`
|
||||
password string `json:"password"`
|
||||
confirmPassword string `json:"confirmPassword"`
|
||||
phone string `json:"phone"`
|
||||
code string `json:"code"`
|
||||
}
|
||||
GetVerifyCodeReq {
|
||||
phone string `json:"phone"`
|
||||
actionType string `json:"actionType"`
|
||||
}
|
||||
)
|
||||
|
||||
@server (
|
||||
group: auth
|
||||
prefix: /api/console/auth
|
||||
)
|
||||
service gateway-api {
|
||||
@handler registerUser
|
||||
post /register (RegisterReq)
|
||||
|
||||
@handler loginUser
|
||||
post /login (LoginReq)
|
||||
|
||||
@handler phoneLoginUser
|
||||
post /phoneLogin (phoneLoginReq)
|
||||
|
||||
@handler getVerifyCode
|
||||
post /getVerifyCode (GetVerifyCodeReq)
|
||||
|
||||
@handler Logout
|
||||
post /logout
|
||||
}
|
||||
|
||||
//------------------------------ User -----------------------------
|
||||
type (
|
||||
enterpriseAuthReq {
|
||||
enterpriseName string `json:"enterpriseName"`
|
||||
creditCode string `json:"creditCode"`
|
||||
legalPerson string `json:"legalPerson"`
|
||||
businessLicense string `json:"businessLicense"`
|
||||
enterpriseContact string `json:"enterpriseContact"`
|
||||
}
|
||||
UserInfoResp {
|
||||
username string `json:"username"`
|
||||
phone string `json:"phone"`
|
||||
enterpriseAuthStatus string `json:"enterpriseAuthStatus"`
|
||||
enterpriseName string `json:"enterpriseName"`
|
||||
creditCode string `json:"creditCode"`
|
||||
legalPerson string `json:"legalPerson"`
|
||||
}
|
||||
UploadBusinessLicenseResp {
|
||||
url string `json:"url"`
|
||||
enterpriseName string `json:"enterpriseName"`
|
||||
creditCode string `json:"creditCode"`
|
||||
legalPerson string `json:"legalPerson"`
|
||||
}
|
||||
secretInfoResp {
|
||||
AccessId string `json:"accessId"`
|
||||
AccessKey string `json:"accessKey"`
|
||||
}
|
||||
)
|
||||
|
||||
@server (
|
||||
group: user
|
||||
prefix: /api/console/user
|
||||
middleware: AuthInterceptor
|
||||
)
|
||||
service gateway-api {
|
||||
@handler getUserInfo
|
||||
get /info returns (UserInfoResp)
|
||||
|
||||
@handler enterpriseAuth
|
||||
post /enterpriseAuth (enterpriseAuthReq)
|
||||
|
||||
@handler UploadBusinessLicense
|
||||
post /businessLicenseUpload returns (UploadBusinessLicenseResp)
|
||||
|
||||
@handler GetSecretInfo
|
||||
post /getSecretInfo returns (secretInfoResp)
|
||||
}
|
||||
|
||||
type (
|
||||
GetProductByIdReq {
|
||||
ProductId int64 `path:"productId"`
|
||||
}
|
||||
GetProductByIdResp {
|
||||
ProductItem
|
||||
}
|
||||
GetProductListReq {
|
||||
Page int64 `form:"page"`
|
||||
PageSize int64 `form:"pageSize"`
|
||||
}
|
||||
GetProductListResp {
|
||||
Total int64 `json:"total"`
|
||||
List []ProductItem `json:"list"`
|
||||
}
|
||||
ProductItem {
|
||||
ProductId int64 `json:"productId"`
|
||||
ProductName string `json:"productName"`
|
||||
ProductCode string `json:"productCode"`
|
||||
ProductDescription string `json:"productDescription"`
|
||||
ProductContent string `json:"productContent"`
|
||||
ProductGroup string `json:"productGroup"`
|
||||
ProductPrice float64 `json:"productPrice"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
UpdatedAt string `json:"updatedAt"`
|
||||
}
|
||||
)
|
||||
|
||||
@server (
|
||||
group: product
|
||||
prefix: /api/console/product
|
||||
middleware: AuthInterceptor
|
||||
)
|
||||
service gateway-api {
|
||||
@handler getProductById
|
||||
get /:productId (GetProductByIdReq) returns (GetProductByIdResp)
|
||||
|
||||
@handler getProductList
|
||||
get /list (GetProductListReq) returns (GetProductListResp)
|
||||
}
|
||||
|
||||
type (
|
||||
// 添加用户产品请求
|
||||
AddUserProductReq {
|
||||
ProductId int64 `json:"productId"`
|
||||
}
|
||||
// 删除用户产品请求
|
||||
DeleteUserProductReq {
|
||||
Id int64 `json:"id"`
|
||||
}
|
||||
// 分页查询用户产品列表请求
|
||||
GetUserProductListReq {
|
||||
Page int64 `form:"page"`
|
||||
PageSize int64 `form:"pageSize"`
|
||||
}
|
||||
// 分页查询用户产品列表响应
|
||||
GetUserProductListResp {
|
||||
Total int64 `json:"total"`
|
||||
List []UserProductItem `json:"list"`
|
||||
}
|
||||
// 用户产品条目
|
||||
UserProductItem {
|
||||
Id int64 `json:"id"` // 用户产品ID
|
||||
ProductId int64 `json:"productId"` // 产品ID
|
||||
ProductName string `json:"productName"` // 产品名称
|
||||
ProductCode string `json:"productCode"` // 产品编号
|
||||
ProductDescription string `json:"productDescription"` // 产品简介
|
||||
ProductGroup string `json:"productGroup"` // 产品分类
|
||||
ProductPrice float64 `json:"productPrice"` // 产品价格
|
||||
CreatedAt string `json:"createdAt"` // 创建时间
|
||||
UpdatedAt string `json:"updatedAt"` // 更新时间
|
||||
}
|
||||
)
|
||||
|
||||
@server (
|
||||
group: userProduct
|
||||
prefix: /api/console/user-product
|
||||
middleware: AuthInterceptor
|
||||
)
|
||||
service gateway-api {
|
||||
@handler getUserProductList
|
||||
get /userProductList (GetUserProductListReq) returns (GetUserProductListResp)
|
||||
}
|
||||
@server (
|
||||
group: userProduct
|
||||
prefix: /api/console/user-product
|
||||
middleware: AuthInterceptor,EntAuthInterceptor
|
||||
)
|
||||
service gateway-api {
|
||||
@handler addUserProduct
|
||||
post /userProductAdd (AddUserProductReq)
|
||||
|
||||
@handler deleteUserProduct
|
||||
delete /userProductDel/:id (DeleteUserProductReq)
|
||||
|
||||
}
|
||||
type (
|
||||
AddWhitelistReq {
|
||||
Ip string `json:"ip"`
|
||||
}
|
||||
DeleteWhitelistReq {
|
||||
Id int64 `json:"id"`
|
||||
}
|
||||
GetWhitelistListReq {
|
||||
Page int64 `form:"page"`
|
||||
PageSize int64 `form:"pageSize"`
|
||||
}
|
||||
GetWhitelistListResp {
|
||||
Total int64 `json:"total"`
|
||||
List []WhitelistItem `json:"list"`
|
||||
}
|
||||
WhitelistItem {
|
||||
Id int64 `json:"id"` // 用户产品ID
|
||||
WhitelistIp string `json:"whiteIp"` // 产品名称
|
||||
CreatedAt string `json:"createdAt"` // 创建时间
|
||||
UpdatedAt string `json:"updatedAt"` // 更新时间
|
||||
}
|
||||
)
|
||||
|
||||
@server (
|
||||
group: whitelistr
|
||||
prefix: /api/console/whitelist
|
||||
middleware: AuthInterceptor
|
||||
)
|
||||
service gateway-api {
|
||||
@handler getWhitelistList
|
||||
get /getWhitelistList (GetWhitelistListReq) returns (GetUserProductListResp)
|
||||
}
|
||||
|
||||
@server (
|
||||
group: whitelistr
|
||||
prefix: /api/console/whitelist
|
||||
middleware: AuthInterceptor,EntAuthInterceptor
|
||||
)
|
||||
service gateway-api {
|
||||
@handler addWhitelist
|
||||
post /addWhitelist (AddWhitelistReq)
|
||||
|
||||
@handler deleteWhitelist
|
||||
delete /delWhitelist (DeleteWhitelistReq)
|
||||
}
|
||||
|
||||
31
apps/gateway/gateway.go
Normal file
31
apps/gateway/gateway.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
"tianyuan-api/apps/gateway/internal/config"
|
||||
"tianyuan-api/apps/gateway/internal/handler"
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/conf"
|
||||
"github.com/zeromicro/go-zero/rest"
|
||||
)
|
||||
|
||||
var configFile = flag.String("f", "etc/gateway-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()
|
||||
}
|
||||
46
apps/gateway/internal/config/config.go
Normal file
46
apps/gateway/internal/config/config.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/zeromicro/go-zero/core/stores/cache"
|
||||
"github.com/zeromicro/go-zero/rest"
|
||||
"github.com/zeromicro/go-zero/zrpc"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
rest.RestConf
|
||||
DataSource string // 数据库连接的 DSN 字符串
|
||||
AuthJWT AuthConfig // JWT 鉴权相关配置
|
||||
CacheRedis cache.CacheConf // 缓存配置,使用 go-zero 自带的缓存配置结构体
|
||||
UserRpc zrpc.RpcClientConf
|
||||
SentinelRpc zrpc.RpcClientConf
|
||||
VerifyCode VerifyCode
|
||||
Qiniu QiniuConfig
|
||||
Baidu BaiduConfig
|
||||
}
|
||||
|
||||
// AuthConfig 用于 JWT 鉴权配置
|
||||
type AuthConfig struct {
|
||||
AccessSecret string // JWT 密钥,用于签发 Token
|
||||
AccessExpire int64 // Token 过期时间,单位为秒
|
||||
}
|
||||
|
||||
type VerifyCode struct {
|
||||
AccessKeyID string
|
||||
AccessKeySecret string
|
||||
EndpointURL string
|
||||
SignName string
|
||||
TemplateCode string
|
||||
ValidTime int
|
||||
}
|
||||
|
||||
type QiniuConfig struct {
|
||||
AccessKey string
|
||||
SecretKey string
|
||||
Bucket string
|
||||
Domain string
|
||||
}
|
||||
|
||||
type BaiduConfig struct {
|
||||
ApiKey string
|
||||
SecretKey string
|
||||
}
|
||||
30
apps/gateway/internal/handler/auth/getverifycodehandler.go
Normal file
30
apps/gateway/internal/handler/auth/getverifycodehandler.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"tianyuan-api/apps/gateway/internal/logic/auth"
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
"tianyuan-api/apps/gateway/internal/types"
|
||||
|
||||
xhttp "github.com/zeromicro/x/http"
|
||||
)
|
||||
|
||||
func GetVerifyCodeHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.GetVerifyCodeReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := auth.NewGetVerifyCodeLogic(r.Context(), svcCtx)
|
||||
err := l.GetVerifyCode(&req)
|
||||
if err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
} else {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
40
apps/gateway/internal/handler/auth/loginuserhandler.go
Normal file
40
apps/gateway/internal/handler/auth/loginuserhandler.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"tianyuan-api/apps/gateway/internal/logic/auth"
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
"tianyuan-api/apps/gateway/internal/types"
|
||||
|
||||
xhttp "github.com/zeromicro/x/http"
|
||||
)
|
||||
|
||||
func LoginUserHandler(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 {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := auth.NewLoginUserLogic(r.Context(), svcCtx)
|
||||
token, err := l.LoginUser(&req)
|
||||
if err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
} else {
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: "Authorization",
|
||||
Value: token, // JWT 令牌
|
||||
HttpOnly: true, // 防止 JavaScript 访问
|
||||
Secure: false, // HTTPS 使用
|
||||
SameSite: http.SameSiteLaxMode, // 防止 CSRF 攻击
|
||||
Path: "/",
|
||||
Expires: time.Now().Add(time.Duration(svcCtx.Config.AuthJWT.AccessExpire) * time.Second), // 过期时间
|
||||
})
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
23
apps/gateway/internal/handler/auth/logouthandler.go
Normal file
23
apps/gateway/internal/handler/auth/logouthandler.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
xhttp "github.com/zeromicro/x/http"
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
)
|
||||
|
||||
func LogoutHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
// 设置空的JWT Cookie,覆盖之前的JWT
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: "Authorization", // 你的JWT cookie名
|
||||
Value: "", // 清空cookies
|
||||
Path: "/",
|
||||
HttpOnly: true,
|
||||
Expires: time.Unix(0, 0), // 过期时间设置为过去
|
||||
})
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, nil)
|
||||
}
|
||||
}
|
||||
40
apps/gateway/internal/handler/auth/phoneloginuserhandler.go
Normal file
40
apps/gateway/internal/handler/auth/phoneloginuserhandler.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"tianyuan-api/apps/gateway/internal/logic/auth"
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
"tianyuan-api/apps/gateway/internal/types"
|
||||
|
||||
xhttp "github.com/zeromicro/x/http"
|
||||
)
|
||||
|
||||
func PhoneLoginUserHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.PhoneLoginReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := auth.NewPhoneLoginUserLogic(r.Context(), svcCtx)
|
||||
token, err := l.PhoneLoginUser(&req)
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: "Authorization",
|
||||
Value: token, // JWT 令牌
|
||||
HttpOnly: true, // 防止 JavaScript 访问
|
||||
Secure: false, // HTTPS 使用
|
||||
SameSite: http.SameSiteLaxMode, // 防止 CSRF 攻击
|
||||
Path: "/",
|
||||
Expires: time.Now().Add(time.Duration(svcCtx.Config.AuthJWT.AccessExpire) * time.Second), // 过期时间
|
||||
})
|
||||
if err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
} else {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
30
apps/gateway/internal/handler/auth/registeruserhandler.go
Normal file
30
apps/gateway/internal/handler/auth/registeruserhandler.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"tianyuan-api/apps/gateway/internal/logic/auth"
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
"tianyuan-api/apps/gateway/internal/types"
|
||||
|
||||
xhttp "github.com/zeromicro/x/http"
|
||||
)
|
||||
|
||||
func RegisterUserHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.RegisterReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := auth.NewRegisterUserLogic(r.Context(), svcCtx)
|
||||
err := l.RegisterUser(&req)
|
||||
if err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
} else {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
21
apps/gateway/internal/handler/base/healthhandler.go
Normal file
21
apps/gateway/internal/handler/base/healthhandler.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package base
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
xhttp "github.com/zeromicro/x/http"
|
||||
"tianyuan-api/apps/gateway/internal/logic/base"
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
)
|
||||
|
||||
func HealthHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
l := base.NewHealthLogic(r.Context(), svcCtx)
|
||||
resp, err := l.Health()
|
||||
if err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
} else {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package product
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"tianyuan-api/apps/gateway/internal/logic/product"
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
"tianyuan-api/apps/gateway/internal/types"
|
||||
|
||||
xhttp "github.com/zeromicro/x/http"
|
||||
)
|
||||
|
||||
func GetProductByIdHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.GetProductByIdReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := product.NewGetProductByIdLogic(r.Context(), svcCtx)
|
||||
resp, err := l.GetProductById(&req)
|
||||
if err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
} else {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package product
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"tianyuan-api/apps/gateway/internal/logic/product"
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
"tianyuan-api/apps/gateway/internal/types"
|
||||
|
||||
xhttp "github.com/zeromicro/x/http"
|
||||
)
|
||||
|
||||
func GetProductListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.GetProductListReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := product.NewGetProductListLogic(r.Context(), svcCtx)
|
||||
resp, err := l.GetProductList(&req)
|
||||
if err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
} else {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
167
apps/gateway/internal/handler/routes.go
Normal file
167
apps/gateway/internal/handler/routes.go
Normal file
@@ -0,0 +1,167 @@
|
||||
// Code generated by goctl. DO NOT EDIT.
|
||||
// goctl 1.7.2
|
||||
|
||||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
auth "tianyuan-api/apps/gateway/internal/handler/auth"
|
||||
base "tianyuan-api/apps/gateway/internal/handler/base"
|
||||
product "tianyuan-api/apps/gateway/internal/handler/product"
|
||||
user "tianyuan-api/apps/gateway/internal/handler/user"
|
||||
userProduct "tianyuan-api/apps/gateway/internal/handler/userProduct"
|
||||
whitelistr "tianyuan-api/apps/gateway/internal/handler/whitelistr"
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest"
|
||||
)
|
||||
|
||||
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||
server.AddRoutes(
|
||||
[]rest.Route{
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/getVerifyCode",
|
||||
Handler: auth.GetVerifyCodeHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/login",
|
||||
Handler: auth.LoginUserHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/logout",
|
||||
Handler: auth.LogoutHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/phoneLogin",
|
||||
Handler: auth.PhoneLoginUserHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/register",
|
||||
Handler: auth.RegisterUserHandler(serverCtx),
|
||||
},
|
||||
},
|
||||
rest.WithPrefix("/api/console/auth"),
|
||||
)
|
||||
|
||||
server.AddRoutes(
|
||||
[]rest.Route{
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/health",
|
||||
Handler: base.HealthHandler(serverCtx),
|
||||
},
|
||||
},
|
||||
rest.WithPrefix("/api/console/base"),
|
||||
)
|
||||
|
||||
server.AddRoutes(
|
||||
rest.WithMiddlewares(
|
||||
[]rest.Middleware{serverCtx.AuthInterceptor},
|
||||
[]rest.Route{
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/:productId",
|
||||
Handler: product.GetProductByIdHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/list",
|
||||
Handler: product.GetProductListHandler(serverCtx),
|
||||
},
|
||||
}...,
|
||||
),
|
||||
rest.WithPrefix("/api/console/product"),
|
||||
)
|
||||
|
||||
server.AddRoutes(
|
||||
rest.WithMiddlewares(
|
||||
[]rest.Middleware{serverCtx.AuthInterceptor},
|
||||
[]rest.Route{
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/businessLicenseUpload",
|
||||
Handler: user.UploadBusinessLicenseHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/enterpriseAuth",
|
||||
Handler: user.EnterpriseAuthHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/getSecretInfo",
|
||||
Handler: user.GetSecretInfoHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/info",
|
||||
Handler: user.GetUserInfoHandler(serverCtx),
|
||||
},
|
||||
}...,
|
||||
),
|
||||
rest.WithPrefix("/api/console/user"),
|
||||
)
|
||||
|
||||
server.AddRoutes(
|
||||
rest.WithMiddlewares(
|
||||
[]rest.Middleware{serverCtx.AuthInterceptor},
|
||||
[]rest.Route{
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/userProductAdd",
|
||||
Handler: userProduct.AddUserProductHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodDelete,
|
||||
Path: "/userProductDel/:id",
|
||||
Handler: userProduct.DeleteUserProductHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/userProductList",
|
||||
Handler: userProduct.GetUserProductListHandler(serverCtx),
|
||||
},
|
||||
}...,
|
||||
),
|
||||
rest.WithPrefix("/api/console/user-product"),
|
||||
)
|
||||
|
||||
server.AddRoutes(
|
||||
rest.WithMiddlewares(
|
||||
[]rest.Middleware{serverCtx.AuthInterceptor},
|
||||
[]rest.Route{
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/getWhitelistList",
|
||||
Handler: whitelistr.GetWhitelistListHandler(serverCtx),
|
||||
},
|
||||
}...,
|
||||
),
|
||||
rest.WithPrefix("/api/console/whitelist"),
|
||||
)
|
||||
|
||||
server.AddRoutes(
|
||||
rest.WithMiddlewares(
|
||||
[]rest.Middleware{serverCtx.AuthInterceptor, serverCtx.EntAuthInterceptor},
|
||||
[]rest.Route{
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/addWhitelist",
|
||||
Handler: whitelistr.AddWhitelistHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodDelete,
|
||||
Path: "/delWhitelist",
|
||||
Handler: whitelistr.DeleteWhitelistHandler(serverCtx),
|
||||
},
|
||||
}...,
|
||||
),
|
||||
rest.WithPrefix("/api/console/whitelist"),
|
||||
)
|
||||
}
|
||||
30
apps/gateway/internal/handler/user/enterpriseauthhandler.go
Normal file
30
apps/gateway/internal/handler/user/enterpriseauthhandler.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"tianyuan-api/apps/gateway/internal/logic/user"
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
"tianyuan-api/apps/gateway/internal/types"
|
||||
|
||||
xhttp "github.com/zeromicro/x/http"
|
||||
)
|
||||
|
||||
func EnterpriseAuthHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.EnterpriseAuthReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := user.NewEnterpriseAuthLogic(r.Context(), svcCtx)
|
||||
err := l.EnterpriseAuth(&req)
|
||||
if err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
} else {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
21
apps/gateway/internal/handler/user/getsecretinfohandler.go
Normal file
21
apps/gateway/internal/handler/user/getsecretinfohandler.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
xhttp "github.com/zeromicro/x/http"
|
||||
"tianyuan-api/apps/gateway/internal/logic/user"
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
)
|
||||
|
||||
func GetSecretInfoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
l := user.NewGetSecretInfoLogic(r.Context(), svcCtx)
|
||||
resp, err := l.GetSecretInfo()
|
||||
if err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
} else {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
21
apps/gateway/internal/handler/user/getuserinfohandler.go
Normal file
21
apps/gateway/internal/handler/user/getuserinfohandler.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
xhttp "github.com/zeromicro/x/http"
|
||||
"tianyuan-api/apps/gateway/internal/logic/user"
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
)
|
||||
|
||||
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 {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
} else {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
xhttp "github.com/zeromicro/x/http"
|
||||
"tianyuan-api/apps/gateway/internal/logic/user"
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
)
|
||||
|
||||
func UploadBusinessLicenseHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
l := user.NewUploadBusinessLicenseLogic(r.Context(), svcCtx)
|
||||
resp, err := l.UploadBusinessLicense(r)
|
||||
if err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
} else {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package userProduct
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"tianyuan-api/apps/gateway/internal/logic/userProduct"
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
"tianyuan-api/apps/gateway/internal/types"
|
||||
|
||||
xhttp "github.com/zeromicro/x/http"
|
||||
)
|
||||
|
||||
func AddUserProductHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.AddUserProductReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := userProduct.NewAddUserProductLogic(r.Context(), svcCtx)
|
||||
err := l.AddUserProduct(&req)
|
||||
if err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
} else {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package userProduct
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"tianyuan-api/apps/gateway/internal/logic/userProduct"
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
"tianyuan-api/apps/gateway/internal/types"
|
||||
|
||||
xhttp "github.com/zeromicro/x/http"
|
||||
)
|
||||
|
||||
func DeleteUserProductHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.DeleteUserProductReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := userProduct.NewDeleteUserProductLogic(r.Context(), svcCtx)
|
||||
err := l.DeleteUserProduct(&req)
|
||||
if err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
} else {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package userProduct
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"tianyuan-api/apps/gateway/internal/logic/userProduct"
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
"tianyuan-api/apps/gateway/internal/types"
|
||||
|
||||
xhttp "github.com/zeromicro/x/http"
|
||||
)
|
||||
|
||||
func GetUserProductListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.GetUserProductListReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := userProduct.NewGetUserProductListLogic(r.Context(), svcCtx)
|
||||
resp, err := l.GetUserProductList(&req)
|
||||
if err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
} else {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package whitelistr
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"tianyuan-api/apps/gateway/internal/logic/whitelistr"
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
"tianyuan-api/apps/gateway/internal/types"
|
||||
|
||||
xhttp "github.com/zeromicro/x/http"
|
||||
)
|
||||
|
||||
func AddWhitelistHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.AddWhitelistReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := whitelistr.NewAddWhitelistLogic(r.Context(), svcCtx)
|
||||
err := l.AddWhitelist(&req)
|
||||
if err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
} else {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package whitelistr
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"tianyuan-api/apps/gateway/internal/logic/whitelistr"
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
"tianyuan-api/apps/gateway/internal/types"
|
||||
|
||||
xhttp "github.com/zeromicro/x/http"
|
||||
)
|
||||
|
||||
func DeleteWhitelistHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.DeleteWhitelistReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := whitelistr.NewDeleteWhitelistLogic(r.Context(), svcCtx)
|
||||
err := l.DeleteWhitelist(&req)
|
||||
if err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
} else {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package whitelistr
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"tianyuan-api/apps/gateway/internal/logic/whitelistr"
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
"tianyuan-api/apps/gateway/internal/types"
|
||||
|
||||
xhttp "github.com/zeromicro/x/http"
|
||||
)
|
||||
|
||||
func GetWhitelistListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.GetWhitelistListReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := whitelistr.NewGetWhitelistListLogic(r.Context(), svcCtx)
|
||||
resp, err := l.GetWhitelistList(&req)
|
||||
if err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
} else {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
95
apps/gateway/internal/logic/auth/getverifycodelogic.go
Normal file
95
apps/gateway/internal/logic/auth/getverifycodelogic.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
|
||||
dysmsapi "github.com/alibabacloud-go/dysmsapi-20170525/v3/client"
|
||||
"github.com/alibabacloud-go/tea-utils/v2/service"
|
||||
"github.com/alibabacloud-go/tea/tea"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
"tianyuan-api/apps/gateway/internal/types"
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
type GetVerifyCodeLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGetVerifyCodeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetVerifyCodeLogic {
|
||||
return &GetVerifyCodeLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetVerifyCodeLogic) GetVerifyCode(req *types.GetVerifyCodeReq) (err error) {
|
||||
// 校验 actionType 参数的值是否为 "login" 或 "register"
|
||||
if req.ActionType != "login" && req.ActionType != "register" {
|
||||
return fmt.Errorf("action_type 参数只能是 'login' 或 'register'")
|
||||
}
|
||||
// 检查手机号是否在一分钟内已发送过验证码
|
||||
redisKey := fmt.Sprintf("%s:%s", req.ActionType, req.Phone)
|
||||
exists, err := l.svcCtx.Redis.Exists(redisKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if exists {
|
||||
// 如果 Redis 中已经存在标记,说明在 1 分钟内请求过,返回错误
|
||||
return fmt.Errorf("一分钟内不能重复发送验证码")
|
||||
}
|
||||
// 生成随机验证码
|
||||
code := fmt.Sprintf("%06d", rand.New(rand.NewSource(time.Now().UnixNano())).Intn(1000000))
|
||||
|
||||
// 调用阿里云短信服务发送验证码
|
||||
client, err := l.CreateClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sendSmsRequest := &dysmsapi.SendSmsRequest{
|
||||
SignName: tea.String(l.svcCtx.Config.VerifyCode.SignName),
|
||||
TemplateCode: tea.String(l.svcCtx.Config.VerifyCode.TemplateCode),
|
||||
PhoneNumbers: tea.String(req.Phone),
|
||||
TemplateParam: tea.String(fmt.Sprintf("{\"code\":\"%s\"}", code)),
|
||||
}
|
||||
|
||||
runtime := &service.RuntimeOptions{}
|
||||
// 这里使用 *dysmsapi.SendSmsResponse 接收返回值
|
||||
smsResp, err := client.SendSmsWithOptions(sendSmsRequest, runtime)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if *smsResp.Body.Code != "OK" {
|
||||
return fmt.Errorf("短信发送失败: %s", *smsResp.Body.Message)
|
||||
}
|
||||
// 将验证码保存到 Redis,设置过期时间
|
||||
err = l.svcCtx.Redis.Setex(req.Phone, code, l.svcCtx.Config.VerifyCode.ValidTime) // 验证码有效期5分钟
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 在 Redis 中设置 1 分钟的标记,限制重复请求
|
||||
err = l.svcCtx.Redis.Setex(redisKey, code, 60) // 标记 1 分钟内不能重复请求
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 构建返回给前端的响应
|
||||
return nil
|
||||
}
|
||||
|
||||
// 创建阿里云短信客户端
|
||||
func (l *GetVerifyCodeLogic) CreateClient() (*dysmsapi.Client, error) {
|
||||
config := &openapi.Config{
|
||||
AccessKeyId: &l.svcCtx.Config.VerifyCode.AccessKeyID,
|
||||
AccessKeySecret: &l.svcCtx.Config.VerifyCode.AccessKeySecret,
|
||||
}
|
||||
config.Endpoint = tea.String(l.svcCtx.Config.VerifyCode.EndpointURL)
|
||||
return dysmsapi.NewClient(config)
|
||||
}
|
||||
35
apps/gateway/internal/logic/auth/loginuserlogic.go
Normal file
35
apps/gateway/internal/logic/auth/loginuserlogic.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
"tianyuan-api/apps/gateway/internal/types"
|
||||
"tianyuan-api/apps/user/user"
|
||||
)
|
||||
|
||||
type LoginUserLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewLoginUserLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LoginUserLogic {
|
||||
return &LoginUserLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *LoginUserLogic) LoginUser(req *types.LoginReq) (token string, err error) {
|
||||
loginResp, err := l.svcCtx.AuthRpc.LoginUser(l.ctx, &user.LoginReq{
|
||||
Username: req.Username,
|
||||
Password: req.Password,
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
// 返回成功的登录响应
|
||||
return loginResp.Token, nil
|
||||
}
|
||||
28
apps/gateway/internal/logic/auth/logoutlogic.go
Normal file
28
apps/gateway/internal/logic/auth/logoutlogic.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
)
|
||||
|
||||
type LogoutLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewLogoutLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LogoutLogic {
|
||||
return &LogoutLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *LogoutLogic) Logout() error {
|
||||
// todo: add your logic here and delete this line
|
||||
|
||||
return nil
|
||||
}
|
||||
35
apps/gateway/internal/logic/auth/phoneloginuserlogic.go
Normal file
35
apps/gateway/internal/logic/auth/phoneloginuserlogic.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
"tianyuan-api/apps/gateway/internal/types"
|
||||
"tianyuan-api/apps/user/user"
|
||||
)
|
||||
|
||||
type PhoneLoginUserLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewPhoneLoginUserLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PhoneLoginUserLogic {
|
||||
return &PhoneLoginUserLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *PhoneLoginUserLogic) PhoneLoginUser(req *types.PhoneLoginReq) (token string, err error) {
|
||||
loginResp, err := l.svcCtx.AuthRpc.PhoneLoginUser(l.ctx, &user.PhoneLoginReq{
|
||||
Phone: req.Phone,
|
||||
Code: req.Code,
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
// 返回成功的登录响应
|
||||
return loginResp.Token, nil
|
||||
}
|
||||
32
apps/gateway/internal/logic/auth/registeruserlogic.go
Normal file
32
apps/gateway/internal/logic/auth/registeruserlogic.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
"tianyuan-api/apps/gateway/internal/types"
|
||||
"tianyuan-api/apps/user/user"
|
||||
)
|
||||
|
||||
type RegisterUserLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewRegisterUserLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RegisterUserLogic {
|
||||
return &RegisterUserLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *RegisterUserLogic) RegisterUser(req *types.RegisterReq) error {
|
||||
_, err := l.svcCtx.AuthRpc.RegisterUser(l.ctx, &user.RegisterReq{Username: req.Username, Password: req.Password, ConfirmPassword: req.ConfirmPassword, Phone: req.Phone, Code: req.Code})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
33
apps/gateway/internal/logic/base/healthlogic.go
Normal file
33
apps/gateway/internal/logic/base/healthlogic.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package base
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
"tianyuan-api/apps/gateway/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type HealthLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewHealthLogic(ctx context.Context, svcCtx *svc.ServiceContext) *HealthLogic {
|
||||
return &HealthLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *HealthLogic) Health() (resp *types.HealthResp, err error) {
|
||||
nowTime := time.Now()
|
||||
resp = &types.HealthResp{
|
||||
Time: nowTime.Format("2006-01-02 15:04:05"),
|
||||
}
|
||||
return
|
||||
}
|
||||
48
apps/gateway/internal/logic/product/getproductbyidlogic.go
Normal file
48
apps/gateway/internal/logic/product/getproductbyidlogic.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package product
|
||||
|
||||
import (
|
||||
"context"
|
||||
"tianyuan-api/apps/sentinel/client/product"
|
||||
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
"tianyuan-api/apps/gateway/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetProductByIdLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGetProductByIdLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetProductByIdLogic {
|
||||
return &GetProductByIdLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetProductByIdLogic) GetProductById(req *types.GetProductByIdReq) (resp *types.GetProductByIdResp, err error) {
|
||||
productResp, err := l.svcCtx.ProductRpc.GetProductById(l.ctx, &product.GetRecordByIdRequest{
|
||||
Id: req.ProductId,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.GetProductByIdResp{
|
||||
ProductItem: types.ProductItem{
|
||||
ProductId: productResp.Id,
|
||||
ProductName: productResp.ProductName,
|
||||
ProductCode: productResp.ProductCode,
|
||||
ProductDescription: productResp.ProductDescription,
|
||||
ProductContent: productResp.ProductContent,
|
||||
ProductGroup: productResp.ProductGroup,
|
||||
ProductPrice: productResp.ProductPrice,
|
||||
},
|
||||
}, nil
|
||||
|
||||
return
|
||||
}
|
||||
51
apps/gateway/internal/logic/product/getproductlistlogic.go
Normal file
51
apps/gateway/internal/logic/product/getproductlistlogic.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package product
|
||||
|
||||
import (
|
||||
"context"
|
||||
"tianyuan-api/apps/sentinel/client/product"
|
||||
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
"tianyuan-api/apps/gateway/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetProductListLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGetProductListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetProductListLogic {
|
||||
return &GetProductListLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetProductListLogic) GetProductList(req *types.GetProductListReq) (resp *types.GetProductListResp, err error) {
|
||||
productList, err := l.svcCtx.ProductRpc.GetProductPageList(l.ctx, &product.PageListRequest{Page: req.Page, PageSize: req.PageSize})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var list []types.ProductItem
|
||||
|
||||
for _, p := range productList.Products {
|
||||
list = append(list, types.ProductItem{
|
||||
ProductId: p.Id,
|
||||
ProductName: p.ProductName,
|
||||
ProductCode: p.ProductCode,
|
||||
ProductDescription: p.ProductDescription,
|
||||
ProductPrice: p.ProductPrice,
|
||||
ProductGroup: p.ProductGroup,
|
||||
CreatedAt: p.CreatedAt,
|
||||
UpdatedAt: p.UpdatedAt,
|
||||
})
|
||||
}
|
||||
resp = &types.GetProductListResp{
|
||||
Total: productList.Total,
|
||||
List: list,
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
40
apps/gateway/internal/logic/user/enterpriseauthlogic.go
Normal file
40
apps/gateway/internal/logic/user/enterpriseauthlogic.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"tianyuan-api/apps/user/user"
|
||||
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
"tianyuan-api/apps/gateway/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type EnterpriseAuthLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewEnterpriseAuthLogic(ctx context.Context, svcCtx *svc.ServiceContext) *EnterpriseAuthLogic {
|
||||
return &EnterpriseAuthLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *EnterpriseAuthLogic) EnterpriseAuth(req *types.EnterpriseAuthReq) error {
|
||||
// 从上下文中解析 JWT,获取用户ID
|
||||
userId, ok := l.ctx.Value("userId").(int64)
|
||||
if !ok {
|
||||
return errors.New("无法获取 userId")
|
||||
}
|
||||
_, err := l.svcCtx.EntRpc.CreateEnterpriseAuth(l.ctx, &user.EnterpriseAuthReq{UserId: userId, EnterpriseName: req.EnterpriseName, EnterpriseContact: req.EnterpriseContact, CreditCode: req.CreditCode, LegalPerson: req.LegalPerson, BusinessLicense: req.BusinessLicense})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
44
apps/gateway/internal/logic/user/getsecretinfologic.go
Normal file
44
apps/gateway/internal/logic/user/getsecretinfologic.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"tianyuan-api/apps/sentinel/sentinel"
|
||||
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
"tianyuan-api/apps/gateway/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetSecretInfoLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGetSecretInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetSecretInfoLogic {
|
||||
return &GetSecretInfoLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetSecretInfoLogic) GetSecretInfo() (resp *types.SecretInfoResp, err error) {
|
||||
// 从上下文中解析 JWT,获取用户ID
|
||||
userId, ok := l.ctx.Value("userId").(int64)
|
||||
if !ok {
|
||||
return nil, errors.New("无法获取 userId")
|
||||
}
|
||||
secret, err := l.svcCtx.SecretRpc.GetSecretByUserId(l.ctx, &sentinel.GetRecordByIdRequest{
|
||||
Id: userId,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &types.SecretInfoResp{
|
||||
AccessId: secret.SecretId,
|
||||
AccessKey: secret.AesKey,
|
||||
}, nil
|
||||
}
|
||||
48
apps/gateway/internal/logic/user/getuserinfologic.go
Normal file
48
apps/gateway/internal/logic/user/getuserinfologic.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
"tianyuan-api/apps/gateway/internal/types"
|
||||
"tianyuan-api/apps/user/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.UserInfoResp, err error) {
|
||||
|
||||
// 从上下文中解析 JWT,获取用户ID
|
||||
userId, ok := l.ctx.Value("userId").(int64)
|
||||
if !ok {
|
||||
return nil, errors.New("无法获取 userId")
|
||||
}
|
||||
|
||||
info, err := l.svcCtx.UserRpc.UserInfo(l.ctx, &user.UserInfoReq{UserId: userId})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 如果查到了企业信息,连带企业信息一起返回
|
||||
return &types.UserInfoResp{
|
||||
Username: info.Username,
|
||||
Phone: info.Phone,
|
||||
EnterpriseAuthStatus: info.EnterpriseAuthStatus,
|
||||
EnterpriseName: info.EnterpriseName,
|
||||
CreditCode: info.CreditCode,
|
||||
LegalPerson: info.LegalPerson,
|
||||
}, nil
|
||||
}
|
||||
249
apps/gateway/internal/logic/user/uploadbusinesslicenselogic.go
Normal file
249
apps/gateway/internal/logic/user/uploadbusinesslicenselogic.go
Normal file
@@ -0,0 +1,249 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/qiniu/go-sdk/v7/storagev2/credentials"
|
||||
"github.com/qiniu/go-sdk/v7/storagev2/http_client"
|
||||
"github.com/qiniu/go-sdk/v7/storagev2/uploader"
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
"tianyuan-api/apps/gateway/internal/types"
|
||||
"io"
|
||||
"math/big"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type UploadBusinessLicenseLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewUploadBusinessLicenseLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UploadBusinessLicenseLogic {
|
||||
return &UploadBusinessLicenseLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
func (l *UploadBusinessLicenseLogic) UploadBusinessLicense(r *http.Request) (resp *types.UploadBusinessLicenseResp, err error) {
|
||||
// 1. 解析文件上传表单,限制文件大小
|
||||
err = r.ParseMultipartForm(4 << 20) // 限制最大文件大小为4MB
|
||||
if err != nil {
|
||||
return nil, errors.New("图片不能超过4MB")
|
||||
}
|
||||
|
||||
// 2. 获取上传的文件
|
||||
file, handler, err := r.FormFile("file")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// 3. 创建临时文件保存上传的内容
|
||||
tempFile, err := os.CreateTemp("", "upload-*.jpg")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("创建临时文件失败: %v", err)
|
||||
}
|
||||
defer tempFile.Close()
|
||||
|
||||
// 4. 将文件内容保存到临时文件
|
||||
_, err = io.Copy(tempFile, file)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("保存文件失败: %v", err)
|
||||
}
|
||||
|
||||
// 5. 调用百度智能云进行营业执照识别
|
||||
tempFilePath := tempFile.Name()
|
||||
fileBytes, err := os.ReadFile(tempFilePath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("读取临时文件失败: %v", err)
|
||||
}
|
||||
|
||||
licenseInfo, err := l.RecognizeBusinessLicense(fileBytes)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("营业执照识别失败: %v", err)
|
||||
}
|
||||
|
||||
// 6. 生成新的文件名
|
||||
newFileName := l.GenerateFileName("business_license_", handler.Filename)
|
||||
|
||||
// 7. 确认是营业执照后,将图片上传到七牛云
|
||||
imageUrl, err := l.UploadToQiniu(tempFilePath, newFileName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("上传图片到七牛云失败: %v", err)
|
||||
}
|
||||
|
||||
// 8. 返回百度智能云的识别信息和图片URL给前端
|
||||
return &types.UploadBusinessLicenseResp{
|
||||
Url: imageUrl,
|
||||
EnterpriseName: licenseInfo["company_name"],
|
||||
CreditCode: licenseInfo["credit_code"],
|
||||
LegalPerson: licenseInfo["legal_person"],
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 百度智能云营业执照识别
|
||||
func (l *UploadBusinessLicenseLogic) RecognizeBusinessLicense(fileBytes []byte) (map[string]string, error) {
|
||||
// 获取百度智能云Access Token
|
||||
accessToken := l.GetAccessToken()
|
||||
if accessToken == "" {
|
||||
return nil, errors.New("获取百度智能云Access Token失败")
|
||||
}
|
||||
|
||||
// 调用百度智能云营业执照识别接口
|
||||
baiduUrl := "https://aip.baidubce.com/rest/2.0/ocr/v1/business_license?access_token=" + accessToken
|
||||
|
||||
// 将图片文件进行Base64编码
|
||||
fileBase64 := base64.StdEncoding.EncodeToString(fileBytes)
|
||||
fileBase64UrlEncoded := url.QueryEscape(fileBase64)
|
||||
// 准备POST请求的Payload
|
||||
payload := strings.NewReader(fmt.Sprintf("image=%s", fileBase64UrlEncoded))
|
||||
|
||||
req, err := http.NewRequest("POST", baiduUrl, payload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
||||
client := &http.Client{}
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 解析响应体
|
||||
var result map[string]interface{}
|
||||
if err := json.Unmarshal(body, &result); err != nil {
|
||||
return nil, fmt.Errorf("解析响应失败: %v", err)
|
||||
}
|
||||
|
||||
// 检查是否有错误码
|
||||
if _, exists := result["error_code"]; exists {
|
||||
return nil, fmt.Errorf("图片解析失败,请上传清晰正确的图片")
|
||||
}
|
||||
|
||||
// 成功,提取所需的字段
|
||||
wordsResult := result["words_result"].(map[string]interface{})
|
||||
companyName := wordsResult["单位名称"].(map[string]interface{})["words"].(string)
|
||||
socialCreditCode := wordsResult["社会信用代码"].(map[string]interface{})["words"].(string)
|
||||
legalPerson := wordsResult["法人"].(map[string]interface{})["words"].(string)
|
||||
|
||||
// 返回提取的信息
|
||||
return map[string]string{
|
||||
"company_name": companyName,
|
||||
"credit_code": socialCreditCode,
|
||||
"legal_person": legalPerson,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 获取百度智能云Access Token
|
||||
func (l *UploadBusinessLicenseLogic) GetAccessToken() string {
|
||||
apiKey := l.svcCtx.Config.Baidu.ApiKey
|
||||
secretKey := l.svcCtx.Config.Baidu.SecretKey
|
||||
|
||||
baiduUrl := "https://aip.baidubce.com/oauth/2.0/token"
|
||||
postData := fmt.Sprintf("grant_type=client_credentials&client_id=%s&client_secret=%s", apiKey, secretKey)
|
||||
resp, err := http.Post(baiduUrl, "application/x-www-form-urlencoded", strings.NewReader(postData))
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
accessTokenObj := map[string]interface{}{}
|
||||
_ = json.Unmarshal(body, &accessTokenObj)
|
||||
return accessTokenObj["access_token"].(string)
|
||||
}
|
||||
|
||||
// 七牛云上传图片
|
||||
func (l *UploadBusinessLicenseLogic) UploadToQiniu(localFilePath string, fileName string) (string, error) {
|
||||
// 从配置中获取七牛云的AccessKey和SecretKey
|
||||
accessKey := l.svcCtx.Config.Qiniu.AccessKey
|
||||
secretKey := l.svcCtx.Config.Qiniu.SecretKey
|
||||
bucket := l.svcCtx.Config.Qiniu.Bucket
|
||||
domain := l.svcCtx.Config.Qiniu.Domain
|
||||
|
||||
// 1. 构建上传凭证
|
||||
mac := credentials.NewCredentials(accessKey, secretKey)
|
||||
|
||||
// 2. 构建上传管理器
|
||||
options := uploader.UploadManagerOptions{
|
||||
Options: http_client.Options{
|
||||
Credentials: mac, // 这里传入认证信息
|
||||
},
|
||||
}
|
||||
|
||||
uploadManager := uploader.NewUploadManager(&options)
|
||||
|
||||
objectOptions := &uploader.ObjectOptions{
|
||||
BucketName: bucket,
|
||||
ObjectName: &fileName,
|
||||
FileName: fileName,
|
||||
}
|
||||
|
||||
// 3. 执行文件上传
|
||||
err := uploadManager.UploadFile(context.Background(), localFilePath, objectOptions, nil)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// 返回文件的URL地址
|
||||
fileUrl := fmt.Sprintf("%s/%s", domain, fileName)
|
||||
return fileUrl, nil
|
||||
}
|
||||
|
||||
// 生成新的文件名,包含前缀、时间戳和随机数
|
||||
func (l *UploadBusinessLicenseLogic) GenerateFileName(prefix, originalFileName string) string {
|
||||
timestamp := time.Now().Format("20060102150405") // 生成时间戳
|
||||
randomNumber := l.GenerateRandomNumber(4) // 生成4位随机数
|
||||
fileExtension := l.GetFileExtension(originalFileName) // 获取原文件扩展名
|
||||
|
||||
// 返回生成的文件名
|
||||
return fmt.Sprintf("%s%s_%s%s", prefix, timestamp, randomNumber, fileExtension)
|
||||
}
|
||||
|
||||
// 生成指定长度的随机数
|
||||
func (l *UploadBusinessLicenseLogic) GenerateRandomNumber(length int) string {
|
||||
var digits = "0123456789"
|
||||
result := make([]byte, length)
|
||||
for i := range result {
|
||||
n, _ := rand.Int(rand.Reader, big.NewInt(int64(len(digits))))
|
||||
result[i] = digits[n.Int64()]
|
||||
}
|
||||
return string(result)
|
||||
}
|
||||
|
||||
// 获取文件扩展名
|
||||
func (l *UploadBusinessLicenseLogic) GetFileExtension(fileName string) string {
|
||||
if len(fileName) > 0 {
|
||||
for i := len(fileName) - 1; i >= 0 && fileName[i] != '.'; i-- {
|
||||
if i == 0 {
|
||||
return "" // 无扩展名
|
||||
}
|
||||
}
|
||||
return fileName[strings.LastIndex(fileName, "."):]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package userProduct
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"tianyuan-api/apps/sentinel/client/userproduct"
|
||||
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
"tianyuan-api/apps/gateway/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type AddUserProductLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewAddUserProductLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AddUserProductLogic {
|
||||
return &AddUserProductLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *AddUserProductLogic) AddUserProduct(req *types.AddUserProductReq) error {
|
||||
userId, ok := l.ctx.Value("userId").(int64)
|
||||
if !ok {
|
||||
return errors.New("无法获取 userId")
|
||||
}
|
||||
_, err := l.svcCtx.UserProductRpc.CreateUserProduct(l.ctx, &userproduct.CreateUserProductRequest{
|
||||
UserId: userId,
|
||||
ProductId: req.ProductId,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package userProduct
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
"tianyuan-api/apps/gateway/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type DeleteUserProductLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewDeleteUserProductLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DeleteUserProductLogic {
|
||||
return &DeleteUserProductLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *DeleteUserProductLogic) DeleteUserProduct(req *types.DeleteUserProductReq) error {
|
||||
return errors.New("not implements")
|
||||
// 未完善,应加上判断是否该用户订阅后删除,id也不是这个id,暂不开放,开放也没用
|
||||
//_, ok := l.ctx.Value("userId").(int64)
|
||||
//if !ok {
|
||||
// return errors.New("无法获取 userId")
|
||||
//}
|
||||
//_, err := l.svcCtx.UserProductRpc.DeleteUserProduct(l.ctx, &userproduct.DeleteUserProductRequest{
|
||||
// Id: req.Id,
|
||||
//})
|
||||
//if err != nil {
|
||||
// return err
|
||||
//}
|
||||
//return nil
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package userProduct
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"tianyuan-api/apps/sentinel/client/userproduct"
|
||||
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
"tianyuan-api/apps/gateway/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetUserProductListLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGetUserProductListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetUserProductListLogic {
|
||||
return &GetUserProductListLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetUserProductListLogic) GetUserProductList(req *types.GetUserProductListReq) (resp *types.GetUserProductListResp, err error) {
|
||||
userId, ok := l.ctx.Value("userId").(int64)
|
||||
if !ok {
|
||||
return nil, errors.New("无法获取 userId")
|
||||
}
|
||||
userProductPageListResp, err := l.svcCtx.UserProductRpc.GetUserProductPageList(l.ctx, &userproduct.UserProuctPageListRequest{
|
||||
UserId: userId,
|
||||
Page: req.Page,
|
||||
PageSize: req.PageSize,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var list []types.UserProductItem
|
||||
for _, up := range userProductPageListResp.UserProducts {
|
||||
list = append(list, types.UserProductItem{
|
||||
Id: up.Id,
|
||||
ProductId: up.ProductId,
|
||||
ProductName: up.ProductName,
|
||||
ProductPrice: up.ProductPrice,
|
||||
ProductGroup: up.ProductGroup,
|
||||
ProductCode: up.ProductCode,
|
||||
ProductDescription: up.ProductDescription,
|
||||
CreatedAt: up.CreatedAt,
|
||||
UpdatedAt: up.UpdatedAt,
|
||||
})
|
||||
}
|
||||
resp = &types.GetUserProductListResp{
|
||||
Total: userProductPageListResp.Total,
|
||||
List: list,
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
46
apps/gateway/internal/logic/whitelistr/addwhitelistlogic.go
Normal file
46
apps/gateway/internal/logic/whitelistr/addwhitelistlogic.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package whitelistr
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"tianyuan-api/apps/gateway/internal/validator"
|
||||
"tianyuan-api/apps/sentinel/client/whitelist"
|
||||
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
"tianyuan-api/apps/gateway/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type AddWhitelistLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewAddWhitelistLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AddWhitelistLogic {
|
||||
return &AddWhitelistLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *AddWhitelistLogic) AddWhitelist(req *types.AddWhitelistReq) error {
|
||||
userId, ok := l.ctx.Value("userId").(int64)
|
||||
if !ok {
|
||||
return errors.New("无法获取 userId")
|
||||
}
|
||||
isIp := validator.IsValidIPAddress(req.Ip)
|
||||
if !isIp {
|
||||
return errors.New("请输入正确的IP地址")
|
||||
}
|
||||
_, err := l.svcCtx.WhitelistRpc.CreateWhitelist(l.ctx, &whitelist.CreateWhitelistRequest{
|
||||
UserId: userId,
|
||||
WhitelistIp: req.Ip,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package whitelistr
|
||||
|
||||
import (
|
||||
"context"
|
||||
"tianyuan-api/apps/sentinel/client/whitelist"
|
||||
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
"tianyuan-api/apps/gateway/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type DeleteWhitelistLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewDeleteWhitelistLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DeleteWhitelistLogic {
|
||||
return &DeleteWhitelistLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *DeleteWhitelistLogic) DeleteWhitelist(req *types.DeleteWhitelistReq) error {
|
||||
_, err := l.svcCtx.WhitelistRpc.DeleteWhitelist(l.ctx, &whitelist.DeleteWhitelistRequest{
|
||||
Id: req.Id,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package whitelistr
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"tianyuan-api/apps/sentinel/client/whitelist"
|
||||
|
||||
"tianyuan-api/apps/gateway/internal/svc"
|
||||
"tianyuan-api/apps/gateway/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetWhitelistListLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGetWhitelistListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetWhitelistListLogic {
|
||||
return &GetWhitelistListLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetWhitelistListLogic) GetWhitelistList(req *types.GetWhitelistListReq) (resp *types.GetWhitelistListResp, err error) {
|
||||
userId, ok := l.ctx.Value("userId").(int64)
|
||||
if !ok {
|
||||
return nil, errors.New("无法获取 userId")
|
||||
}
|
||||
whitelistPageResp, err := l.svcCtx.WhitelistRpc.GetWhitePageList(l.ctx, &whitelist.WhitePageListRequest{
|
||||
UserId: userId,
|
||||
Page: req.Page,
|
||||
PageSize: req.PageSize,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var list []types.WhitelistItem
|
||||
for _, up := range whitelistPageResp.Whitelists {
|
||||
list = append(list, types.WhitelistItem{
|
||||
Id: up.Id,
|
||||
WhitelistIp: up.WhitelistIp,
|
||||
CreatedAt: up.CreatedAt,
|
||||
UpdatedAt: up.UpdatedAt,
|
||||
})
|
||||
}
|
||||
resp = &types.GetWhitelistListResp{
|
||||
Total: whitelistPageResp.Total,
|
||||
List: list,
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
xhttp "github.com/zeromicro/x/http"
|
||||
"tianyuan-api/apps/gateway/internal/config"
|
||||
jwtx "tianyuan-api/pkg/jwt"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
type AuthInterceptorMiddleware struct {
|
||||
Config config.Config
|
||||
}
|
||||
|
||||
func NewAuthInterceptorMiddleware(c config.Config) *AuthInterceptorMiddleware {
|
||||
return &AuthInterceptorMiddleware{
|
||||
Config: c,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *AuthInterceptorMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
// 从 Cookie 中获取 JWT
|
||||
cookie, err := r.Cookie("Authorization")
|
||||
if err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, errors.New("用户未登录"))
|
||||
return
|
||||
}
|
||||
|
||||
tokenStr := cookie.Value
|
||||
// 验证并解析 JWT
|
||||
userId, err := jwtx.ParseJwtToken(tokenStr, m.Config.AuthJWT.AccessSecret)
|
||||
if err != nil {
|
||||
// 设置过期的 Cookie 来删除无效的 Token
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: "Authorization",
|
||||
Value: "",
|
||||
Path: "/",
|
||||
HttpOnly: true,
|
||||
Expires: time.Unix(0, 0), // 过期时间设置为过去
|
||||
})
|
||||
logx.Error("Invalid JWT: ", err)
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, errors.New("未经授权的访问"))
|
||||
return
|
||||
}
|
||||
|
||||
// 将 userId 存入 context,供后续逻辑使用
|
||||
ctx := context.WithValue(r.Context(), "userId", userId)
|
||||
next(w, r.WithContext(ctx))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
xhttp "github.com/zeromicro/x/http"
|
||||
"tianyuan-api/apps/user/user"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type EntAuthInterceptorMiddleware struct {
|
||||
UserRpc user.UserClient
|
||||
}
|
||||
|
||||
func NewEntAuthInterceptorMiddleware(userRpc user.UserClient) *EntAuthInterceptorMiddleware {
|
||||
return &EntAuthInterceptorMiddleware{
|
||||
UserRpc: userRpc,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *EntAuthInterceptorMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
userId, ok := r.Context().Value("userId").(int64)
|
||||
if !ok {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, errors.New("无法获取 userId"))
|
||||
}
|
||||
status, err := m.UserRpc.GetEnterpriseAuthStatus(r.Context(), &user.GetEnterpriseAuthStatusReq{UserId: userId})
|
||||
if err != nil {
|
||||
logx.Error("校验认证状态错误: %v", err)
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, errors.New("系统错误"))
|
||||
return
|
||||
}
|
||||
if !status.IsAuth {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, errors.New("请先通过企业认证"))
|
||||
return
|
||||
}
|
||||
next(w, r)
|
||||
}
|
||||
}
|
||||
57
apps/gateway/internal/svc/servicecontext.go
Normal file
57
apps/gateway/internal/svc/servicecontext.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package svc
|
||||
|
||||
import (
|
||||
"github.com/zeromicro/go-zero/core/stores/redis"
|
||||
"github.com/zeromicro/go-zero/rest"
|
||||
"github.com/zeromicro/go-zero/zrpc"
|
||||
"tianyuan-api/apps/gateway/internal/config"
|
||||
"tianyuan-api/apps/gateway/internal/middleware"
|
||||
"tianyuan-api/apps/sentinel/sentinel"
|
||||
"tianyuan-api/apps/user/user"
|
||||
)
|
||||
|
||||
type ServiceContext struct {
|
||||
Config config.Config
|
||||
AuthInterceptor rest.Middleware
|
||||
EntAuthInterceptor rest.Middleware
|
||||
Redis *redis.Redis
|
||||
AuthRpc user.AuthClient
|
||||
EntRpc user.EnterpriseClient
|
||||
UserRpc user.UserClient
|
||||
ProductRpc sentinel.ProductClient
|
||||
UserProductRpc sentinel.UserProductClient
|
||||
WhitelistRpc sentinel.WhitelistClient
|
||||
SecretRpc sentinel.SecretClient
|
||||
}
|
||||
|
||||
func NewServiceContext(c config.Config) *ServiceContext {
|
||||
redisConf := redis.RedisConf{
|
||||
Host: c.CacheRedis[0].Host,
|
||||
Pass: c.CacheRedis[0].Pass,
|
||||
Type: c.CacheRedis[0].Type, // Redis 节点类型,如 "node"
|
||||
}
|
||||
|
||||
// 使用 MustNewRedis 来初始化 Redis 客户端
|
||||
rds := redis.MustNewRedis(redisConf)
|
||||
authRpc := user.NewAuthClient(zrpc.MustNewClient(c.UserRpc).Conn())
|
||||
entRpc := user.NewEnterpriseClient(zrpc.MustNewClient(c.UserRpc).Conn())
|
||||
userRpc := user.NewUserClient(zrpc.MustNewClient(c.UserRpc).Conn())
|
||||
productRpc := sentinel.NewProductClient(zrpc.MustNewClient(c.SentinelRpc).Conn())
|
||||
userProductRpc := sentinel.NewUserProductClient(zrpc.MustNewClient(c.SentinelRpc).Conn())
|
||||
whitelistRpc := sentinel.NewWhitelistClient(zrpc.MustNewClient(c.SentinelRpc).Conn())
|
||||
secretRpc := sentinel.NewSecretClient(zrpc.MustNewClient(c.SentinelRpc).Conn())
|
||||
|
||||
return &ServiceContext{
|
||||
Config: c,
|
||||
AuthInterceptor: middleware.NewAuthInterceptorMiddleware(c).Handle,
|
||||
EntAuthInterceptor: middleware.NewEntAuthInterceptorMiddleware(userRpc).Handle,
|
||||
Redis: rds, // 单独使用的 Redis 客户端
|
||||
AuthRpc: authRpc,
|
||||
EntRpc: entRpc,
|
||||
UserRpc: userRpc,
|
||||
ProductRpc: productRpc,
|
||||
UserProductRpc: userProductRpc,
|
||||
WhitelistRpc: whitelistRpc,
|
||||
SecretRpc: secretRpc,
|
||||
}
|
||||
}
|
||||
145
apps/gateway/internal/types/types.go
Normal file
145
apps/gateway/internal/types/types.go
Normal file
@@ -0,0 +1,145 @@
|
||||
// Code generated by goctl. DO NOT EDIT.
|
||||
// goctl 1.7.2
|
||||
|
||||
package types
|
||||
|
||||
type AddUserProductReq struct {
|
||||
ProductId int64 `json:"productId"`
|
||||
}
|
||||
|
||||
type AddWhitelistReq struct {
|
||||
Ip string `json:"ip"`
|
||||
}
|
||||
|
||||
type DeleteUserProductReq struct {
|
||||
Id int64 `json:"id"`
|
||||
}
|
||||
|
||||
type DeleteWhitelistReq struct {
|
||||
Id int64 `json:"id"`
|
||||
}
|
||||
|
||||
type GetProductByIdReq struct {
|
||||
ProductId int64 `path:"productId"`
|
||||
}
|
||||
|
||||
type GetProductByIdResp struct {
|
||||
ProductItem
|
||||
}
|
||||
|
||||
type GetProductListReq struct {
|
||||
Page int64 `form:"page"`
|
||||
PageSize int64 `form:"pageSize"`
|
||||
}
|
||||
|
||||
type GetProductListResp struct {
|
||||
Total int64 `json:"total"`
|
||||
List []ProductItem `json:"list"`
|
||||
}
|
||||
|
||||
type GetUserProductListReq struct {
|
||||
Page int64 `form:"page"`
|
||||
PageSize int64 `form:"pageSize"`
|
||||
}
|
||||
|
||||
type GetUserProductListResp struct {
|
||||
Total int64 `json:"total"`
|
||||
List []UserProductItem `json:"list"`
|
||||
}
|
||||
|
||||
type GetVerifyCodeReq struct {
|
||||
Phone string `json:"phone"`
|
||||
ActionType string `json:"actionType"`
|
||||
}
|
||||
|
||||
type GetWhitelistListReq struct {
|
||||
Page int64 `form:"page"`
|
||||
PageSize int64 `form:"pageSize"`
|
||||
}
|
||||
|
||||
type GetWhitelistListResp struct {
|
||||
Total int64 `json:"total"`
|
||||
List []WhitelistItem `json:"list"`
|
||||
}
|
||||
|
||||
type LoginReq struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
type ProductItem struct {
|
||||
ProductId int64 `json:"productId"`
|
||||
ProductName string `json:"productName"`
|
||||
ProductCode string `json:"productCode"`
|
||||
ProductDescription string `json:"productDescription"`
|
||||
ProductContent string `json:"productContent"`
|
||||
ProductGroup string `json:"productGroup"`
|
||||
ProductPrice float64 `json:"productPrice"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
UpdatedAt string `json:"updatedAt"`
|
||||
}
|
||||
|
||||
type RegisterReq struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
ConfirmPassword string `json:"confirmPassword"`
|
||||
Phone string `json:"phone"`
|
||||
Code string `json:"code"`
|
||||
}
|
||||
|
||||
type UploadBusinessLicenseResp struct {
|
||||
Url string `json:"url"`
|
||||
EnterpriseName string `json:"enterpriseName"`
|
||||
CreditCode string `json:"creditCode"`
|
||||
LegalPerson string `json:"legalPerson"`
|
||||
}
|
||||
|
||||
type UserInfoResp struct {
|
||||
Username string `json:"username"`
|
||||
Phone string `json:"phone"`
|
||||
EnterpriseAuthStatus string `json:"enterpriseAuthStatus"`
|
||||
EnterpriseName string `json:"enterpriseName"`
|
||||
CreditCode string `json:"creditCode"`
|
||||
LegalPerson string `json:"legalPerson"`
|
||||
}
|
||||
|
||||
type UserProductItem struct {
|
||||
Id int64 `json:"id"` // 用户产品ID
|
||||
ProductId int64 `json:"productId"` // 产品ID
|
||||
ProductName string `json:"productName"` // 产品名称
|
||||
ProductCode string `json:"productCode"` // 产品编号
|
||||
ProductDescription string `json:"productDescription"` // 产品简介
|
||||
ProductGroup string `json:"productGroup"` // 产品分类
|
||||
ProductPrice float64 `json:"productPrice"` // 产品价格
|
||||
CreatedAt string `json:"createdAt"` // 创建时间
|
||||
UpdatedAt string `json:"updatedAt"` // 更新时间
|
||||
}
|
||||
|
||||
type WhitelistItem struct {
|
||||
Id int64 `json:"id"` // 用户产品ID
|
||||
WhitelistIp string `json:"whiteIp"` // 产品名称
|
||||
CreatedAt string `json:"createdAt"` // 创建时间
|
||||
UpdatedAt string `json:"updatedAt"` // 更新时间
|
||||
}
|
||||
|
||||
type EnterpriseAuthReq struct {
|
||||
EnterpriseName string `json:"enterpriseName"`
|
||||
CreditCode string `json:"creditCode"`
|
||||
LegalPerson string `json:"legalPerson"`
|
||||
BusinessLicense string `json:"businessLicense"`
|
||||
EnterpriseContact string `json:"enterpriseContact"`
|
||||
}
|
||||
|
||||
type HealthResp struct {
|
||||
Time string `json:"time"`
|
||||
}
|
||||
|
||||
type PhoneLoginReq struct {
|
||||
Phone string `json:"phone"`
|
||||
Code string `json:"code"`
|
||||
}
|
||||
|
||||
type SecretInfoResp struct {
|
||||
AccessId string `json:"accessId"`
|
||||
AccessKey string `json:"accessKey"`
|
||||
}
|
||||
20
apps/gateway/internal/types/validator.go
Normal file
20
apps/gateway/internal/types/validator.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"tianyuan-api/apps/gateway/internal/validator"
|
||||
)
|
||||
|
||||
func (l *RegisterReq) Validate() error {
|
||||
if err := validator.ValidateUsername(l.Username); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := validator.ValidatePassword(l.Password); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := validator.ValidatePhoneNumber(l.Phone); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 其他逻辑
|
||||
return nil
|
||||
}
|
||||
72
apps/gateway/internal/validator/validator.go
Normal file
72
apps/gateway/internal/validator/validator.go
Normal file
@@ -0,0 +1,72 @@
|
||||
// internal/validator/validation.go
|
||||
|
||||
package validator
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/zeromicro/go-zero/core/stores/redis"
|
||||
"regexp"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
func ValidateUsername(username string) error {
|
||||
if utf8.RuneCountInString(username) < 2 {
|
||||
return errors.New("用户名长度不能少于2个中文或4个英文字符")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ValidatePassword(password string) error {
|
||||
if len(password) < 8 {
|
||||
return errors.New("密码长度不能少于8位")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ValidatePhoneNumber(phone string) error {
|
||||
phoneRegex := `^1[3-9]\d{9}$`
|
||||
re := regexp.MustCompile(phoneRegex)
|
||||
if !re.MatchString(phone) {
|
||||
return errors.New("手机号格式不正确")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func ValidateVerifyCode(redisClient *redis.Redis, phone, code string) error {
|
||||
// 从 Redis 获取验证码
|
||||
savedCode, err := redisClient.Get(phone)
|
||||
if err != nil {
|
||||
if errors.Is(err, redis.Nil) {
|
||||
return errors.New("验证码已过期")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// 验证码不匹配
|
||||
if savedCode != code {
|
||||
return errors.New("验证码不正确")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
func IsValidIPAddress(ip string) bool {
|
||||
// 正则表达式:匹配 IPv4 地址格式
|
||||
var ipRegex = regexp.MustCompile(`^([0-9]{1,3}\.){3}[0-9]{1,3}$`)
|
||||
|
||||
// 判断格式是否匹配
|
||||
if !ipRegex.MatchString(ip) {
|
||||
return false
|
||||
}
|
||||
|
||||
// 验证每个段是否在 0 到 255 之间
|
||||
var segments = ipRegex.FindStringSubmatch(ip)
|
||||
for _, segment := range segments {
|
||||
var num int
|
||||
fmt.Sscanf(segment, "%d", &num)
|
||||
if num < 0 || num > 255 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
Reference in New Issue
Block a user