first commit
This commit is contained in:
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
|
||||
}
|
||||
Reference in New Issue
Block a user