实现商户注册、管理员审核商户申请接口
This commit is contained in:
@ -13,5 +13,7 @@ import (
|
||||
type IAuthV1 interface {
|
||||
AdminLogin(ctx context.Context, req *v1.AdminLoginReq) (res *v1.AdminLoginRes, err error)
|
||||
MerchantLogin(ctx context.Context, req *v1.MerchantLoginReq) (res *v1.MerchantLoginRes, err error)
|
||||
MerchantCode(ctx context.Context, req *v1.MerchantCodeReq) (res *v1.MerchantCodeRes, err error)
|
||||
MerchantRegister(ctx context.Context, req *v1.MerchantRegisterReq) (res *v1.MerchantRegisterRes, err error)
|
||||
StoreLogin(ctx context.Context, req *v1.StoreLoginReq) (res *v1.StoreLoginRes, err error)
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ type AdminLoginReq struct {
|
||||
Username string `json:"username" v:"required" dc:"用户名"`
|
||||
Password string `json:"password" v:"required" dc:"密码"`
|
||||
}
|
||||
|
||||
type AdminLoginRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
Token string `json:"token"`
|
||||
@ -14,16 +15,37 @@ type AdminLoginRes struct {
|
||||
|
||||
type MerchantLoginReq struct {
|
||||
g.Meta `path:"/merchant/login" method:"post" tags:"Merchant" summary:"(商户管理员)商户登录"`
|
||||
Usernaem string `json:"username" v:"required" dc:"用户名"`
|
||||
Username string `json:"username" dc:"用户名"`
|
||||
Phone string `json:"phone" v:"regex:^1[3-9]\\d{9}$" dc:"手机号"`
|
||||
Code string `json:"code" dc:"验证码"`
|
||||
Password string `json:"password" v:"required" dc:"密码"`
|
||||
}
|
||||
|
||||
type MerchantLoginRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
Token string `json:"token"`
|
||||
}
|
||||
type MerchantRegisterReq struct {
|
||||
|
||||
type MerchantCodeReq struct {
|
||||
g.Meta `path:"/merchant/code" method:"get" tags:"Merchant" summary:"(商户管理员)商户获取短信验证码"`
|
||||
Phone string `json:"phone" v:"required" dc:"手机号"`
|
||||
}
|
||||
|
||||
type MerchantCodeRes struct{}
|
||||
|
||||
type MerchantRegisterReq struct {
|
||||
g.Meta `path:"/merchant/register" method:"post" tags:"Merchant" summary:"(商户管理员)商户注册"`
|
||||
Username string `json:"username" v:"required" dc:"用户名"`
|
||||
Phone string `json:"phone" v:"required|regex:^1[3-9]\\d{9}$" dc:"手机号"`
|
||||
Code string `json:"code" v:"required" dc:"验证码"`
|
||||
Password string `json:"password" v:"required|length:6,20" dc:"密码(6-20位)"`
|
||||
Password2 string `json:"password2" v:"required|same:password" dc:"确认密码"`
|
||||
ApplicationReason string `json:"applicationReason" v:"required|length:5,200" dc:"申请理由(5~200字)"`
|
||||
}
|
||||
|
||||
type MerchantRegisterRes struct {
|
||||
Success bool `json:"success" dc:"是否成功"`
|
||||
Msg string `json:"msg" dc:"提示信息"`
|
||||
}
|
||||
|
||||
type StoreLoginReq struct {
|
||||
@ -31,6 +53,7 @@ type StoreLoginReq struct {
|
||||
Username string `json:"username" v:"required" dc:"用户名"`
|
||||
Password string `json:"password" v:"required" dc:"密码"`
|
||||
}
|
||||
|
||||
type StoreLoginRes struct {
|
||||
g.Meta `mime:"application/json"`
|
||||
Token string `json:"token"`
|
||||
|
||||
@ -2,15 +2,17 @@
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package roleMenu
|
||||
package merchant
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"server/api/roleMenu/v1"
|
||||
"server/api/merchant/v1"
|
||||
)
|
||||
|
||||
type IRoleMenuV1 interface {
|
||||
type IMerchantV1 interface {
|
||||
List(ctx context.Context, req *v1.ListReq) (res *v1.ListRes, err error)
|
||||
SaveRoleMenu(ctx context.Context, req *v1.SaveRoleMenuReq) (res *v1.SaveRoleMenuRes, err error)
|
||||
Create(ctx context.Context, req *v1.CreateReq) (res *v1.CreateRes, err error)
|
||||
Update(ctx context.Context, req *v1.UpdateReq) (res *v1.UpdateRes, err error)
|
||||
Audit(ctx context.Context, req *v1.AuditReq) (res *v1.AuditRes, err error)
|
||||
}
|
||||
39
api/merchant/v1/merchant.go
Normal file
39
api/merchant/v1/merchant.go
Normal file
@ -0,0 +1,39 @@
|
||||
package v1
|
||||
|
||||
import "github.com/gogf/gf/v2/frame/g"
|
||||
|
||||
type ListReq struct {
|
||||
g.Meta `path:"/merchant" method:"get" tags:"Merchant" summary:"(系统管理员)获取商户列表"`
|
||||
Page int `json:"page" dc:"页数"`
|
||||
Size int `json:"size" dc:"每页数量"`
|
||||
Status int `json:"status" dc:"状态:1=启用,2=禁用"`
|
||||
AuditStatus int `json:"auditStatus" dc:"审核状态:0=待审核,1=审核通过,2=审核拒绝"`
|
||||
}
|
||||
type ListRes struct {
|
||||
List interface{} `json:"list" dc:"商户列表"`
|
||||
Total int `json:"total" dc:"总数"`
|
||||
}
|
||||
|
||||
type CreateReq struct {
|
||||
g.Meta `path:"/merchant" method:"post" tags:"Merchant" summary:"(系统管理员)创建商户"`
|
||||
}
|
||||
type CreateRes struct {
|
||||
Id int64 `json:"id" dc:"商户ID"`
|
||||
}
|
||||
|
||||
type UpdateReq struct {
|
||||
g.Meta `path:"/merchant" method:"put" tags:"Merchant" summary:"(系统管理员、商户管理员)更新商户"`
|
||||
}
|
||||
type UpdateRes struct {
|
||||
Success bool `json:"success" dc:"是否成功"`
|
||||
}
|
||||
|
||||
type AuditReq struct {
|
||||
g.Meta `path:"/merchant/audit" method:"post" tags:"Merchant" summary:"(系统管理员)商户审核"`
|
||||
Id int64 `json:"id" v:"required" dc:"商户ID"`
|
||||
AuditStatus int `json:"auditStatus" v:"required" dc:"审核状态:1=审核通过,2=审核拒绝" `
|
||||
AuditRemark string `json:"auditRemark" dc:"审核备注"`
|
||||
RejectReason string `json:"rejectReason" dc:"拒绝原因"`
|
||||
}
|
||||
type AuditRes struct {
|
||||
}
|
||||
15
api/merchantAdmin/merchantAdmin.go
Normal file
15
api/merchantAdmin/merchantAdmin.go
Normal file
@ -0,0 +1,15 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package merchantAdmin
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"server/api/merchantAdmin/v1"
|
||||
)
|
||||
|
||||
type IMerchantAdminV1 interface {
|
||||
MerchantAdminInfo(ctx context.Context, req *v1.MerchantAdminInfoReq) (res *v1.MerchantAdminInfoRes, err error)
|
||||
}
|
||||
11
api/merchantAdmin/v1/merchantAdmin.go
Normal file
11
api/merchantAdmin/v1/merchantAdmin.go
Normal file
@ -0,0 +1,11 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
type MerchantAdminInfoReq struct {
|
||||
g.Meta `path:"/merchant/info" method:"get" tags:"MerchantAdmin" summary:"(商户管理员)获取商户管理员信息"`
|
||||
}
|
||||
type MerchantAdminInfoRes struct {
|
||||
}
|
||||
@ -1,27 +0,0 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// ListReq 角色菜单列表请求
|
||||
type ListReq struct {
|
||||
g.Meta `path:"/role-menu" method:"get" tags:"角色菜单" summary:"获取角色菜单列表"`
|
||||
RoleId int64 `json:"roleId" v:"required#角色ID不能为空" dc:"角色ID"`
|
||||
}
|
||||
|
||||
// ListRes 角色菜单列表响应
|
||||
type ListRes struct {
|
||||
List interface{} `json:"list" dc:"角色菜单列表"`
|
||||
Total int `json:"total" dc:"总条数"`
|
||||
}
|
||||
|
||||
type SaveRoleMenuReq struct {
|
||||
g.Meta `path:"/role-menu" method:"post" tags:"角色菜单" summary:"保存角色菜单"`
|
||||
RoleId int `json:"roleId" v:"required#角色ID不能为空" dc:"角色ID"`
|
||||
MenuIds []int `json:"menuIds" v:"required#菜单ID列表不能为空" dc:"菜单ID列表"`
|
||||
}
|
||||
|
||||
type SaveRoleMenuRes struct {
|
||||
Success bool `json:"success" dc:"是否成功"`
|
||||
}
|
||||
37
api/store/v1/store.go
Normal file
37
api/store/v1/store.go
Normal file
@ -0,0 +1,37 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
type ListReq struct {
|
||||
g.Meta `path:"/store" method:"get" tags:"Store" summary:"(系统管理员、商户管理员)获取门店列表"`
|
||||
Page int `json:"page" dc:"页数"`
|
||||
Size int `json:"size" dc:"每页数量"`
|
||||
MerchantId int `json:"merchantId" dc:"商户ID"`
|
||||
}
|
||||
type ListRes struct {
|
||||
List interface{} `json:"list" dc:"商户列表"`
|
||||
Total int `json:"total" dc:"总数"`
|
||||
}
|
||||
type CreateReq struct {
|
||||
g.Meta `path:"/store" method:"post" tags:"Store" summary:"(商户管理员)创建门店"`
|
||||
Name string `json:"name" v:"required" dc:"门店名称"`
|
||||
ContactName string `json:"contactName" v:"required" dc:"联系人"`
|
||||
ContactPhone string `json:"contactPhone" v:"required" dc:"联系人电话"`
|
||||
}
|
||||
type CreateRes struct {
|
||||
Id int64 `json:"id" dc:"门店ID"`
|
||||
}
|
||||
type UpdateReq struct {
|
||||
g.Meta `path:"/store" method:"put" tags:"Store" summary:"(商户管理员)更新门店"`
|
||||
Id int64 `json:"id" v:"required" dc:"门店ID"`
|
||||
Name string `json:"name" v:"required" dc:"门店名称"`
|
||||
Address string `json:"address" v:"required" dc:"门店地址"`
|
||||
ContactName string `json:"contactName" v:"required" dc:"联系人"`
|
||||
ContactPhone string `json:"contactPhone" v:"required" dc:"联系人电话"`
|
||||
}
|
||||
|
||||
type UpdateRes struct {
|
||||
Success bool `json:"success" dc:"是否成功"`
|
||||
}
|
||||
3
go.mod
3
go.mod
@ -3,6 +3,7 @@ module server
|
||||
go 1.24.2
|
||||
|
||||
require (
|
||||
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible
|
||||
github.com/casbin/casbin/v2 v2.105.0
|
||||
github.com/go-resty/resty/v2 v2.16.5
|
||||
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.9.0
|
||||
@ -12,7 +13,6 @@ require (
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/hailaz/gf-casbin-adapter/v2 v2.8.1
|
||||
golang.org/x/crypto v0.38.0
|
||||
golang.org/x/sync v0.14.0
|
||||
)
|
||||
|
||||
require (
|
||||
@ -44,5 +44,6 @@ require (
|
||||
golang.org/x/net v0.33.0 // indirect
|
||||
golang.org/x/sys v0.33.0 // indirect
|
||||
golang.org/x/text v0.25.0 // indirect
|
||||
golang.org/x/time v0.6.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
4
go.sum
4
go.sum
@ -1,5 +1,7 @@
|
||||
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
|
||||
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible h1:8psS8a+wKfiLt1iVDX79F7Y6wUM49Lcha2FMXt4UM8g=
|
||||
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
|
||||
github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I=
|
||||
github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
|
||||
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
|
||||
@ -95,8 +97,6 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
|
||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
|
||||
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
||||
@ -8,6 +8,7 @@ import (
|
||||
"server/internal/controller/admin"
|
||||
"server/internal/controller/auth"
|
||||
"server/internal/controller/menu"
|
||||
"server/internal/controller/merchant"
|
||||
"server/internal/controller/role"
|
||||
"server/internal/controller/wx"
|
||||
"server/internal/middleware"
|
||||
@ -34,6 +35,7 @@ var (
|
||||
admin.NewV1(),
|
||||
role.NewV1(),
|
||||
menu.NewV1(),
|
||||
merchant.NewV1(),
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
@ -1,8 +1 @@
|
||||
package consts
|
||||
|
||||
const (
|
||||
UserRoleCode = "user"
|
||||
AdminRoleCode = "admin"
|
||||
MerchantRoleCode = "merchant"
|
||||
StoreRoleCode = "store"
|
||||
)
|
||||
|
||||
20
internal/consts/merchant.go
Normal file
20
internal/consts/merchant.go
Normal file
@ -0,0 +1,20 @@
|
||||
package consts
|
||||
|
||||
// 商户状态
|
||||
const (
|
||||
MerchantNormalStatus = iota + 1
|
||||
MerchantDisabledStatus
|
||||
)
|
||||
|
||||
// 商户审核状态
|
||||
const (
|
||||
MerchantPendingReview = iota
|
||||
MerchantReviewPassed
|
||||
MerchantReviewRejected
|
||||
)
|
||||
|
||||
// 商户注册类型
|
||||
const (
|
||||
MerchantRegisterByAdmin = iota + 1
|
||||
MerchantRegisterBySelf
|
||||
)
|
||||
7
internal/consts/merchant_admin.go
Normal file
7
internal/consts/merchant_admin.go
Normal file
@ -0,0 +1,7 @@
|
||||
package consts
|
||||
|
||||
// 商户管理员状态
|
||||
const (
|
||||
MerchantAdministratorEnable = iota + 1
|
||||
MerchantAdministratorDisable
|
||||
)
|
||||
14
internal/consts/role.go
Normal file
14
internal/consts/role.go
Normal file
@ -0,0 +1,14 @@
|
||||
package consts
|
||||
|
||||
const (
|
||||
GuestRoleCode = "guest"
|
||||
UserRoleCode = "user"
|
||||
AdminRoleCode = "admin"
|
||||
MerchantRoleCode = "merchant"
|
||||
StoreRoleCode = "store"
|
||||
)
|
||||
|
||||
const (
|
||||
RoleEnable = iota + 1
|
||||
RoleDisable
|
||||
)
|
||||
@ -11,7 +11,7 @@ import (
|
||||
)
|
||||
|
||||
func (c *ControllerV1) AdminInfo(ctx context.Context, req *v1.AdminInfoReq) (res *v1.AdminInfoRes, err error) {
|
||||
userId := g.RequestFromCtx(ctx).GetCtxVar("userId").Int()
|
||||
userId := g.RequestFromCtx(ctx).GetCtxVar("userId").Int64()
|
||||
out, err := service.Admin().Info(ctx, &model.AdminInfoIn{Id: userId})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
16
internal/controller/auth/auth_v1_merchant_code.go
Normal file
16
internal/controller/auth/auth_v1_merchant_code.go
Normal file
@ -0,0 +1,16 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
|
||||
"server/api/auth/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) MerchantCode(ctx context.Context, req *v1.MerchantCodeReq) (res *v1.MerchantCodeRes, err error) {
|
||||
if _, err = service.MerchantAdmin().Code(ctx, &model.MerchantAdminCodeIn{Phone: req.Phone}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.MerchantCodeRes{}, nil
|
||||
}
|
||||
@ -2,13 +2,16 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
|
||||
"server/api/auth/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) MerchantLogin(ctx context.Context, req *v1.MerchantLoginReq) (res *v1.MerchantLoginRes, err error) {
|
||||
return nil, gerror.NewCode(gcode.CodeNotImplemented)
|
||||
out, err := service.MerchantAdmin().Login(ctx, &model.MerchantLoginIn{Password: req.Password, Username: req.Username})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.MerchantLoginRes{Token: out.Token}, nil
|
||||
}
|
||||
|
||||
20
internal/controller/auth/auth_v1_merchant_register.go
Normal file
20
internal/controller/auth/auth_v1_merchant_register.go
Normal file
@ -0,0 +1,20 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
|
||||
"server/api/auth/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) MerchantRegister(ctx context.Context, req *v1.MerchantRegisterReq) (res *v1.MerchantRegisterRes, err error) {
|
||||
out, err := service.MerchantAdmin().Register(ctx, &model.MerchantAdminRegisterIn{Username: req.Username, Password: req.Password, Phone: req.Phone, ApplicationReason: req.ApplicationReason, Code: req.Code})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.MerchantRegisterRes{
|
||||
Msg: "申请成功, 等待系统管理员审核申请",
|
||||
Success: out.Success,
|
||||
}, nil
|
||||
}
|
||||
@ -2,4 +2,4 @@
|
||||
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
|
||||
// =================================================================================
|
||||
|
||||
package roleMenu
|
||||
package merchant
|
||||
@ -2,14 +2,14 @@
|
||||
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
|
||||
// =================================================================================
|
||||
|
||||
package roleMenu
|
||||
package merchant
|
||||
|
||||
import (
|
||||
"server/api/roleMenu"
|
||||
"server/api/merchant"
|
||||
)
|
||||
|
||||
type ControllerV1 struct{}
|
||||
|
||||
func NewV1() roleMenu.IRoleMenuV1 {
|
||||
func NewV1() merchant.IMerchantV1 {
|
||||
return &ControllerV1{}
|
||||
}
|
||||
19
internal/controller/merchant/merchant_v1_audit.go
Normal file
19
internal/controller/merchant/merchant_v1_audit.go
Normal file
@ -0,0 +1,19 @@
|
||||
package merchant
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
|
||||
"server/api/merchant/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) Audit(ctx context.Context, req *v1.AuditReq) (res *v1.AuditRes, err error) {
|
||||
adminId := g.RequestFromCtx(ctx).GetCtxVar("adminId").Int64()
|
||||
_, err = service.Merchant().Audit(ctx, &model.MerchantAuditIn{Id: req.Id, AuditStatus: req.AuditStatus, AuditRemark: req.AuditRemark, AdminId: adminId, RejectReason: req.RejectReason})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.AuditRes{}, nil
|
||||
}
|
||||
14
internal/controller/merchant/merchant_v1_create.go
Normal file
14
internal/controller/merchant/merchant_v1_create.go
Normal file
@ -0,0 +1,14 @@
|
||||
package merchant
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
|
||||
"server/api/merchant/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) Create(ctx context.Context, req *v1.CreateReq) (res *v1.CreateRes, err error) {
|
||||
return nil, gerror.NewCode(gcode.CodeNotImplemented)
|
||||
}
|
||||
@ -1,20 +1,20 @@
|
||||
package roleMenu
|
||||
package merchant
|
||||
|
||||
import (
|
||||
"context"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
|
||||
"server/api/roleMenu/v1"
|
||||
"server/api/merchant/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) List(ctx context.Context, req *v1.ListReq) (res *v1.ListRes, err error) {
|
||||
list, err := service.RoleMenu().List(ctx, &model.RoleMenuListInput{RoleId: req.RoleId})
|
||||
out, err := service.Merchant().List(ctx, &model.MerchantListIn{Page: req.Page, Size: req.Size, AuditStatus: req.AuditStatus, Status: req.Status})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.ListRes{
|
||||
List: list.List,
|
||||
Total: list.Total,
|
||||
List: out.List,
|
||||
Total: out.Total,
|
||||
}, nil
|
||||
}
|
||||
14
internal/controller/merchant/merchant_v1_update.go
Normal file
14
internal/controller/merchant/merchant_v1_update.go
Normal file
@ -0,0 +1,14 @@
|
||||
package merchant
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
|
||||
"server/api/merchant/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) Update(ctx context.Context, req *v1.UpdateReq) (res *v1.UpdateRes, err error) {
|
||||
return nil, gerror.NewCode(gcode.CodeNotImplemented)
|
||||
}
|
||||
5
internal/controller/merchantAdmin/merchantAdmin.go
Normal file
5
internal/controller/merchantAdmin/merchantAdmin.go
Normal file
@ -0,0 +1,5 @@
|
||||
// =================================================================================
|
||||
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
|
||||
// =================================================================================
|
||||
|
||||
package merchantAdmin
|
||||
15
internal/controller/merchantAdmin/merchantAdmin_new.go
Normal file
15
internal/controller/merchantAdmin/merchantAdmin_new.go
Normal file
@ -0,0 +1,15 @@
|
||||
// =================================================================================
|
||||
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
|
||||
// =================================================================================
|
||||
|
||||
package merchantAdmin
|
||||
|
||||
import (
|
||||
"server/api/merchantAdmin"
|
||||
)
|
||||
|
||||
type ControllerV1 struct{}
|
||||
|
||||
func NewV1() merchantAdmin.IMerchantAdminV1 {
|
||||
return &ControllerV1{}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package merchantAdmin
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
|
||||
"server/api/merchantAdmin/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) MerchantAdminInfo(ctx context.Context, req *v1.MerchantAdminInfoReq) (res *v1.MerchantAdminInfoRes, err error) {
|
||||
return nil, gerror.NewCode(gcode.CodeNotImplemented)
|
||||
}
|
||||
@ -1,20 +0,0 @@
|
||||
package roleMenu
|
||||
|
||||
import (
|
||||
"context"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
|
||||
"server/api/roleMenu/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) SaveRoleMenu(ctx context.Context, req *v1.SaveRoleMenuReq) (res *v1.SaveRoleMenuRes, err error) {
|
||||
out, err := service.RoleMenu().Save(ctx, &model.RoleMenuSaveInput{RoleId: req.RoleId, MenuIds: req.MenuIds})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.SaveRoleMenuRes{
|
||||
Success: out.Success,
|
||||
}, nil
|
||||
|
||||
}
|
||||
@ -33,6 +33,9 @@ type MerchantAdminsColumns struct {
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 更新时间
|
||||
DeletedAt string // 软删除时间戳
|
||||
IsPrimary string // 是否主账号:0=否,1=是
|
||||
LastLoginIp string // 最后登录IP
|
||||
RoleId string // 角色ID
|
||||
}
|
||||
|
||||
// merchantAdminsColumns holds the columns for the table merchant_admins.
|
||||
@ -50,6 +53,9 @@ var merchantAdminsColumns = MerchantAdminsColumns{
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
DeletedAt: "deleted_at",
|
||||
IsPrimary: "is_primary",
|
||||
LastLoginIp: "last_login_ip",
|
||||
RoleId: "role_id",
|
||||
}
|
||||
|
||||
// NewMerchantAdminsDao creates and returns a new DAO object for table data access.
|
||||
|
||||
@ -28,11 +28,19 @@ type MerchantsColumns struct {
|
||||
ContactPhone string // 联系人电话
|
||||
ContactEmail string // 联系人邮箱
|
||||
Address string // 商户地址
|
||||
Status string // 状态:1=正常,2=禁用,3=待审核
|
||||
Status string // 状态:1=正常,2=禁用
|
||||
ExpireAt string // 服务到期时间
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 更新时间
|
||||
DeletedAt string // 软删除时间戳
|
||||
ApplicationReason string // 申请理由
|
||||
CreatedBy string // 创建人ID
|
||||
CreatedByType string // 创建人类型:1=系统管理员,2=商户注册
|
||||
AuditStatus string // 审核状态:0=待审核,1=审核通过,2=审核拒绝
|
||||
AuditBy string // 审核人ID
|
||||
AuditAt string // 审核时间
|
||||
AuditRemark string // 审核备注
|
||||
RejectReason string // 拒绝原因
|
||||
}
|
||||
|
||||
// merchantsColumns holds the columns for the table merchants.
|
||||
@ -50,6 +58,14 @@ var merchantsColumns = MerchantsColumns{
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
DeletedAt: "deleted_at",
|
||||
ApplicationReason: "application_reason",
|
||||
CreatedBy: "created_by",
|
||||
CreatedByType: "created_by_type",
|
||||
AuditStatus: "audit_status",
|
||||
AuditBy: "audit_by",
|
||||
AuditAt: "audit_at",
|
||||
AuditRemark: "audit_remark",
|
||||
RejectReason: "reject_reason",
|
||||
}
|
||||
|
||||
// NewMerchantsDao creates and returns a new DAO object for table data access.
|
||||
|
||||
@ -33,6 +33,7 @@ type StoreAdminsColumns struct {
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 更新时间
|
||||
DeletedAt string // 软删除时间戳
|
||||
RoleId string // 角色ID
|
||||
}
|
||||
|
||||
// storeAdminsColumns holds the columns for the table store_admins.
|
||||
@ -50,6 +51,7 @@ var storeAdminsColumns = StoreAdminsColumns{
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
DeletedAt: "deleted_at",
|
||||
RoleId: "role_id",
|
||||
}
|
||||
|
||||
// NewStoreAdminsDao creates and returns a new DAO object for table data access.
|
||||
|
||||
@ -27,7 +27,6 @@ type StoresColumns struct {
|
||||
Address string // 门店地址
|
||||
ContactName string // 联系人姓名
|
||||
ContactPhone string // 联系人电话
|
||||
BusinessHours string // 营业时间
|
||||
Status string // 状态:1=正常营业,2=暂停营业,3=已关闭
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 更新时间
|
||||
@ -43,7 +42,6 @@ var storesColumns = StoresColumns{
|
||||
Address: "address",
|
||||
ContactName: "contact_name",
|
||||
ContactPhone: "contact_phone",
|
||||
BusinessHours: "business_hours",
|
||||
Status: "status",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
|
||||
@ -37,7 +37,7 @@ func checkAdmin() {
|
||||
Name: "系统管理员",
|
||||
Code: consts.AdminRoleCode,
|
||||
Description: "管理员角色",
|
||||
Status: 1,
|
||||
Status: consts.RoleEnable,
|
||||
IsDeletable: false,
|
||||
})
|
||||
} else {
|
||||
|
||||
@ -7,9 +7,8 @@ package logic
|
||||
import (
|
||||
_ "server/internal/logic/admin"
|
||||
_ "server/internal/logic/menu"
|
||||
_ "server/internal/logic/merchant"
|
||||
_ "server/internal/logic/merchantAdmin"
|
||||
_ "server/internal/logic/role"
|
||||
_ "server/internal/logic/roleMenu"
|
||||
_ "server/internal/logic/storeAdmin"
|
||||
_ "server/internal/logic/user"
|
||||
)
|
||||
|
||||
83
internal/logic/merchant/merchant.go
Normal file
83
internal/logic/merchant/merchant.go
Normal file
@ -0,0 +1,83 @@
|
||||
package merchant
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"server/internal/consts"
|
||||
"server/internal/dao"
|
||||
"server/internal/model"
|
||||
"server/internal/model/do"
|
||||
"server/internal/service"
|
||||
"server/utility/ecode"
|
||||
)
|
||||
|
||||
type sMerchant struct {
|
||||
}
|
||||
|
||||
func New() service.IMerchant {
|
||||
return &sMerchant{}
|
||||
}
|
||||
|
||||
func init() {
|
||||
service.RegisterMerchant(New())
|
||||
}
|
||||
|
||||
func (s *sMerchant) List(ctx context.Context, in *model.MerchantListIn) (out *model.MerchantListOut, err error) {
|
||||
list := make([]model.Merchant, 0)
|
||||
var total int
|
||||
orm := dao.Merchants.Ctx(ctx)
|
||||
if in.Status != 0 {
|
||||
orm = orm.Where(dao.Merchants.Columns().Status, in.Status)
|
||||
}
|
||||
if in.AuditStatus != 0 {
|
||||
orm = orm.Where(dao.Merchants.Columns().AuditStatus, in.AuditStatus)
|
||||
}
|
||||
if err = orm.Page(in.Page, in.Size).ScanAndCount(&list, &total, false); err != nil {
|
||||
return nil, ecode.Fail.Sub("查询商户列表失败")
|
||||
}
|
||||
return &model.MerchantListOut{
|
||||
List: list,
|
||||
Total: total,
|
||||
}, nil
|
||||
}
|
||||
func (s *sMerchant) Audit(ctx context.Context, in *model.MerchantAuditIn) (out *model.MerchantAuditOut, err error) {
|
||||
merchant, err := dao.Merchants.Ctx(ctx).WherePri(in.Id).One()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("查询商户失败")
|
||||
}
|
||||
if merchant.IsEmpty() {
|
||||
return nil, ecode.Params.Sub("商户不存在")
|
||||
}
|
||||
if merchant[dao.Merchants.Columns().AuditStatus].Int() != 0 {
|
||||
return nil, ecode.Params.Sub("商户已审核")
|
||||
}
|
||||
if err = dao.Merchants.Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) {
|
||||
if _, err = tx.Model(dao.Merchants.Table()).WherePri(in.Id).Data(do.Merchants{
|
||||
AuditBy: in.AdminId,
|
||||
AuditRemark: in.AuditRemark,
|
||||
AuditStatus: in.AuditStatus,
|
||||
AuditAt: gtime.Now(),
|
||||
Status: in.AuditStatus, // 暂定审核通过商户即可使用
|
||||
RejectReason: in.RejectReason,
|
||||
}).OmitEmptyData().Update(); err != nil {
|
||||
|
||||
return ecode.Fail.Sub("审核商户失败")
|
||||
}
|
||||
if _, err = tx.Model(dao.MerchantAdmins.Table()).Where(do.MerchantAdmins{MerchantId: in.Id, IsPrimary: true}).Data(do.MerchantAdmins{
|
||||
Status: consts.MerchantAdministratorEnable,
|
||||
}).Update(); err != nil {
|
||||
return ecode.Fail.Sub("审核商户失败")
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sMerchant) Create(ctx context.Context, in *model.MerchantCreateIn) (out *model.CreateOut, err error) {
|
||||
|
||||
return
|
||||
}
|
||||
@ -1 +1,168 @@
|
||||
package merchantAdmin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/util/grand"
|
||||
"server/internal/consts"
|
||||
"server/internal/dao"
|
||||
"server/internal/model"
|
||||
"server/internal/model/do"
|
||||
"server/internal/service"
|
||||
"server/utility/ecode"
|
||||
utility "server/utility/encrypt"
|
||||
"server/utility/jwt"
|
||||
)
|
||||
|
||||
type sMerchantAdmin struct {
|
||||
}
|
||||
|
||||
func New() service.IMerchantAdmin {
|
||||
return &sMerchantAdmin{}
|
||||
}
|
||||
func init() {
|
||||
service.RegisterMerchantAdmin(New())
|
||||
go checkMerchantRole()
|
||||
}
|
||||
|
||||
func checkMerchantRole() {
|
||||
ctx := context.Background()
|
||||
exist, err := dao.Roles.Ctx(ctx).Where(do.Roles{Code: consts.MerchantRoleCode}).Exist()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if !exist {
|
||||
_, err = dao.Roles.Ctx(ctx).Insert(do.Roles{
|
||||
Name: "商户管理员",
|
||||
Code: consts.MerchantRoleCode,
|
||||
Description: "商户管理员角色",
|
||||
Status: consts.RoleEnable,
|
||||
IsDeletable: false,
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (s *sMerchantAdmin) Login(ctx context.Context, in *model.MerchantLoginIn) (out *model.MerchantLoginOut, err error) {
|
||||
mAdmin, err := dao.MerchantAdmins.Ctx(ctx).Where(do.MerchantAdmins{Username: in.Username}).One()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("查询商户管理员失败")
|
||||
}
|
||||
|
||||
if mAdmin.IsEmpty() {
|
||||
return nil, ecode.Params.Sub("该用户不存在")
|
||||
}
|
||||
|
||||
if mAdmin[dao.MerchantAdmins.Columns().Status].Int() == consts.MerchantAdministratorDisable {
|
||||
return nil, ecode.Params.Sub("该用户已被禁用")
|
||||
}
|
||||
if !utility.ComparePassword(mAdmin[dao.MerchantAdmins.Columns().PasswordHash].String(), in.Password) {
|
||||
return nil, ecode.Params.Sub("密码错误")
|
||||
}
|
||||
value, err := dao.Roles.Ctx(ctx).WherePri(mAdmin[dao.MerchantAdmins.Columns().RoleId].Int()).Fields(dao.Roles.Columns().Code).Value()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("查询角色失败")
|
||||
}
|
||||
mAdminId := mAdmin[dao.MerchantAdmins.Columns().Id].Int64()
|
||||
token, err := jwt.GenerateToken(&jwt.TokenIn{UserId: mAdminId, Role: value.String()})
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("生成token失败")
|
||||
}
|
||||
out = &model.MerchantLoginOut{
|
||||
Token: token,
|
||||
}
|
||||
go func(ctx context.Context, merchantAdminId int64) {
|
||||
// 更新商户管理员登录时间
|
||||
dao.MerchantAdmins.Ctx(ctx).WherePri(merchantAdminId).Update(do.MerchantAdmins{
|
||||
LastLoginAt: gtime.Now(),
|
||||
LastLoginIp: ghttp.RequestFromCtx(ctx).RemoteAddr,
|
||||
})
|
||||
}(ctx, mAdminId)
|
||||
return
|
||||
}
|
||||
func (s *sMerchantAdmin) Info(ctx context.Context, in *model.MerchantAdminInfoIn) (out *model.MerchantAdminInfoOut, err error) {
|
||||
return
|
||||
}
|
||||
func (s *sMerchantAdmin) Code(ctx context.Context, in *model.MerchantAdminCodeIn) (out *model.MerchantAdminCodeOut, err error) {
|
||||
exist, err := dao.MerchantAdmins.Ctx(ctx).Where(do.MerchantAdmins{Phone: in.Phone}).Exist()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("查询商户管理员失败")
|
||||
}
|
||||
if exist {
|
||||
return nil, ecode.Fail.Sub("该手机号已被注册")
|
||||
}
|
||||
// TODO 调用验证码服务发送验证码
|
||||
// 插入缓存,过期时间为 5 分钟
|
||||
if err = g.Redis().SetEX(ctx, "merchant_admin_code:"+in.Phone, grand.Digits(6), 5*60); err != nil {
|
||||
return nil, ecode.Fail.Sub("插入验证码缓存失败")
|
||||
}
|
||||
|
||||
return &model.MerchantAdminCodeOut{}, nil
|
||||
}
|
||||
|
||||
func (s *sMerchantAdmin) VertifyPhone(ctx context.Context, in *model.MerchantAdminVertifyPhoneIn) (out *model.MerchantAdminVertifyPhoneOut, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sMerchantAdmin) Register(ctx context.Context, in *model.MerchantAdminRegisterIn) (out *model.MerchantAdminRegisterOut, err error) {
|
||||
exist, err := dao.MerchantAdmins.Ctx(ctx).Where(do.MerchantAdmins{Username: in.Username}).Exist()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("查询商户管理员失败")
|
||||
}
|
||||
if exist {
|
||||
return nil, ecode.Fail.Sub("该用户名已被注册")
|
||||
}
|
||||
// 验证码校验
|
||||
code, err := g.Redis().Get(ctx, "merchant_admin_code:"+in.Phone)
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("获取验证码缓存失败")
|
||||
}
|
||||
if code.IsEmpty() {
|
||||
return nil, ecode.Fail.Sub("验证码已过期")
|
||||
}
|
||||
if code.String() != in.Code {
|
||||
return nil, ecode.Fail.Sub("验证码错误")
|
||||
}
|
||||
hashPass, err := utility.EncryptPassword(in.Password)
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("密码加密失败")
|
||||
}
|
||||
if err = dao.MerchantAdmins.Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) {
|
||||
// 插入商户数据
|
||||
id, err := tx.Model(dao.Merchants.Table()).Data(do.Merchants{
|
||||
Name: fmt.Sprintf("%s的商铺", in.Username),
|
||||
CreatedByType: consts.MerchantRegisterByAdmin,
|
||||
Status: consts.MerchantDisabledStatus,
|
||||
AuditStatus: consts.MerchantPendingReview,
|
||||
ContactPhone: in.Phone,
|
||||
ApplicationReason: in.ApplicationReason,
|
||||
}).InsertAndGetId()
|
||||
if err != nil {
|
||||
return ecode.Fail.Sub("插入商户数据失败")
|
||||
}
|
||||
|
||||
// 插入商户管理员数据
|
||||
if _, err = tx.Model(dao.MerchantAdmins.Table()).Data(do.MerchantAdmins{
|
||||
MerchantId: id,
|
||||
PasswordHash: hashPass,
|
||||
Phone: in.Phone,
|
||||
IsPrimary: true,
|
||||
Username: in.Username,
|
||||
Status: consts.MerchantAdministratorEnable,
|
||||
}).Insert(); err != nil {
|
||||
return ecode.Fail.Sub("插入商户管理员数据失败")
|
||||
}
|
||||
return
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
g.Redis().Del(ctx, "merchant_admin_code:"+in.Phone)
|
||||
return &model.MerchantAdminRegisterOut{Success: true}, nil
|
||||
}
|
||||
|
||||
@ -1,28 +0,0 @@
|
||||
package roleMenu
|
||||
|
||||
import (
|
||||
"context"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
)
|
||||
|
||||
type sRoleMenu struct {
|
||||
}
|
||||
|
||||
func New() service.IRoleMenu {
|
||||
return &sRoleMenu{}
|
||||
}
|
||||
func init() {
|
||||
service.RegisterRoleMenu(New())
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
}
|
||||
func (s *sRoleMenu) List(ctx context.Context, in *model.RoleMenuListInput) (out *model.MenuListOutput, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sRoleMenu) Save(ctx context.Context, in *model.RoleMenuSaveInput) (out *model.UpdateOut, err error) {
|
||||
return
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
package storeAdmin
|
||||
@ -33,7 +33,7 @@ func checkUserRole() {
|
||||
Name: "用户",
|
||||
Code: consts.UserRoleCode,
|
||||
Description: "用户角色",
|
||||
Status: 1,
|
||||
Status: consts.RoleEnable,
|
||||
IsDeletable: false,
|
||||
}).Insert()
|
||||
if err != nil {
|
||||
|
||||
@ -1,16 +1,55 @@
|
||||
package model
|
||||
|
||||
type (
|
||||
AdminLoginIn struct {
|
||||
// Admin 管理员信息
|
||||
type Admin struct {
|
||||
Id int64 `json:"id" orm:"id,primary"` // 管理员ID
|
||||
RoleId int64 `json:"roleId" orm:"role_id,not null"` // 角色ID
|
||||
Username string `json:"username" orm:"username,not null"` // 管理员用户名
|
||||
PasswordHash string `json:"passwordHash" orm:"password_hash,not null"` // 密码哈希
|
||||
RealName string `json:"realName" orm:"real_name"` // 真实姓名
|
||||
Phone string `json:"phone" orm:"phone"` // 手机号
|
||||
Email string `json:"email" orm:"email"` // 邮箱
|
||||
Status int `json:"status" orm:"status,default:1"` // 状态:1=正常,2=禁用
|
||||
}
|
||||
|
||||
// AdminCreateIn 创建管理员请求
|
||||
type AdminCreateIn struct {
|
||||
RoleId int64
|
||||
Username string
|
||||
Password string
|
||||
}
|
||||
RealName string
|
||||
Phone string
|
||||
Email string
|
||||
Status int
|
||||
}
|
||||
|
||||
AdminInfoIn struct {
|
||||
Id int
|
||||
}
|
||||
AdminInfoOut struct {
|
||||
// AdminUpdateIn 更新管理员请求
|
||||
type AdminUpdateIn struct {
|
||||
Id int64
|
||||
RoleId int64
|
||||
RealName string
|
||||
Phone string
|
||||
Email string
|
||||
Status int
|
||||
}
|
||||
|
||||
// AdminOut 管理员响应
|
||||
type AdminOut struct {
|
||||
*Admin
|
||||
}
|
||||
|
||||
type AdminLoginIn struct {
|
||||
Username string
|
||||
Password string
|
||||
}
|
||||
type AdminInfoIn struct {
|
||||
Id int64
|
||||
}
|
||||
type AdminInfoOut struct {
|
||||
Id int64
|
||||
Username string
|
||||
}
|
||||
)
|
||||
PasswordHash string
|
||||
RealName string
|
||||
Phone string
|
||||
Email string
|
||||
}
|
||||
|
||||
@ -25,4 +25,7 @@ type MerchantAdmins struct {
|
||||
CreatedAt *gtime.Time // 创建时间
|
||||
UpdatedAt *gtime.Time // 更新时间
|
||||
DeletedAt *gtime.Time // 软删除时间戳
|
||||
IsPrimary interface{} // 是否主账号:0=否,1=是
|
||||
LastLoginIp interface{} // 最后登录IP
|
||||
RoleId interface{} // 角色ID
|
||||
}
|
||||
|
||||
@ -20,9 +20,17 @@ type Merchants struct {
|
||||
ContactPhone interface{} // 联系人电话
|
||||
ContactEmail interface{} // 联系人邮箱
|
||||
Address interface{} // 商户地址
|
||||
Status interface{} // 状态:1=正常,2=禁用,3=待审核
|
||||
Status interface{} // 状态:1=正常,2=禁用
|
||||
ExpireAt *gtime.Time // 服务到期时间
|
||||
CreatedAt *gtime.Time // 创建时间
|
||||
UpdatedAt *gtime.Time // 更新时间
|
||||
DeletedAt *gtime.Time // 软删除时间戳
|
||||
ApplicationReason interface{} // 申请理由
|
||||
CreatedBy interface{} // 创建人ID
|
||||
CreatedByType interface{} // 创建人类型:1=系统管理员,2=商户注册
|
||||
AuditStatus interface{} // 审核状态:0=待审核,1=审核通过,2=审核拒绝
|
||||
AuditBy interface{} // 审核人ID
|
||||
AuditAt *gtime.Time // 审核时间
|
||||
AuditRemark interface{} // 审核备注
|
||||
RejectReason interface{} // 拒绝原因
|
||||
}
|
||||
|
||||
@ -25,4 +25,5 @@ type StoreAdmins struct {
|
||||
CreatedAt *gtime.Time // 创建时间
|
||||
UpdatedAt *gtime.Time // 更新时间
|
||||
DeletedAt *gtime.Time // 软删除时间戳
|
||||
RoleId interface{} // 角色ID
|
||||
}
|
||||
|
||||
@ -19,7 +19,6 @@ type Stores struct {
|
||||
Address interface{} // 门店地址
|
||||
ContactName interface{} // 联系人姓名
|
||||
ContactPhone interface{} // 联系人电话
|
||||
BusinessHours interface{} // 营业时间
|
||||
Status interface{} // 状态:1=正常营业,2=暂停营业,3=已关闭
|
||||
CreatedAt *gtime.Time // 创建时间
|
||||
UpdatedAt *gtime.Time // 更新时间
|
||||
|
||||
@ -23,4 +23,7 @@ type MerchantAdmins struct {
|
||||
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"` // 创建时间
|
||||
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"` // 更新时间
|
||||
DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:"软删除时间戳"` // 软删除时间戳
|
||||
IsPrimary bool `json:"isPrimary" orm:"is_primary" description:"是否主账号:0=否,1=是"` // 是否主账号:0=否,1=是
|
||||
LastLoginIp string `json:"lastLoginIp" orm:"last_login_ip" description:"最后登录IP"` // 最后登录IP
|
||||
RoleId int64 `json:"roleId" orm:"role_id" description:"角色ID"` // 角色ID
|
||||
}
|
||||
|
||||
@ -18,9 +18,17 @@ type Merchants struct {
|
||||
ContactPhone string `json:"contactPhone" orm:"contact_phone" description:"联系人电话"` // 联系人电话
|
||||
ContactEmail string `json:"contactEmail" orm:"contact_email" description:"联系人邮箱"` // 联系人邮箱
|
||||
Address string `json:"address" orm:"address" description:"商户地址"` // 商户地址
|
||||
Status int `json:"status" orm:"status" description:"状态:1=正常,2=禁用,3=待审核"` // 状态:1=正常,2=禁用,3=待审核
|
||||
Status int `json:"status" orm:"status" description:"状态:1=正常,2=禁用"` // 状态:1=正常,2=禁用
|
||||
ExpireAt *gtime.Time `json:"expireAt" orm:"expire_at" description:"服务到期时间"` // 服务到期时间
|
||||
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"` // 创建时间
|
||||
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"` // 更新时间
|
||||
DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:"软删除时间戳"` // 软删除时间戳
|
||||
ApplicationReason string `json:"applicationReason" orm:"application_reason" description:"申请理由"` // 申请理由
|
||||
CreatedBy int64 `json:"createdBy" orm:"created_by" description:"创建人ID"` // 创建人ID
|
||||
CreatedByType int `json:"createdByType" orm:"created_by_type" description:"创建人类型:1=系统管理员,2=商户注册"` // 创建人类型:1=系统管理员,2=商户注册
|
||||
AuditStatus int `json:"auditStatus" orm:"audit_status" description:"审核状态:0=待审核,1=审核通过,2=审核拒绝"` // 审核状态:0=待审核,1=审核通过,2=审核拒绝
|
||||
AuditBy int64 `json:"auditBy" orm:"audit_by" description:"审核人ID"` // 审核人ID
|
||||
AuditAt *gtime.Time `json:"auditAt" orm:"audit_at" description:"审核时间"` // 审核时间
|
||||
AuditRemark string `json:"auditRemark" orm:"audit_remark" description:"审核备注"` // 审核备注
|
||||
RejectReason string `json:"rejectReason" orm:"reject_reason" description:"拒绝原因"` // 拒绝原因
|
||||
}
|
||||
|
||||
@ -23,4 +23,5 @@ type StoreAdmins struct {
|
||||
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"` // 创建时间
|
||||
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"` // 更新时间
|
||||
DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:"软删除时间戳"` // 软删除时间戳
|
||||
RoleId int64 `json:"roleId" orm:"role_id" description:"角色ID"` // 角色ID
|
||||
}
|
||||
|
||||
@ -17,7 +17,6 @@ type Stores struct {
|
||||
Address string `json:"address" orm:"address" description:"门店地址"` // 门店地址
|
||||
ContactName string `json:"contactName" orm:"contact_name" description:"联系人姓名"` // 联系人姓名
|
||||
ContactPhone string `json:"contactPhone" orm:"contact_phone" description:"联系人电话"` // 联系人电话
|
||||
BusinessHours string `json:"businessHours" orm:"business_hours" description:"营业时间"` // 营业时间
|
||||
Status int `json:"status" orm:"status" description:"状态:1=正常营业,2=暂停营业,3=已关闭"` // 状态:1=正常营业,2=暂停营业,3=已关闭
|
||||
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"` // 创建时间
|
||||
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"` // 更新时间
|
||||
|
||||
80
internal/model/merchant.go
Normal file
80
internal/model/merchant.go
Normal file
@ -0,0 +1,80 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// Merchant 商户信息
|
||||
type Merchant struct {
|
||||
Id int64 `json:"id" orm:"id,primary"` // 商户ID
|
||||
Name string `json:"name" orm:"name,not null"` // 商户名称
|
||||
BusinessLicense string `json:"businessLicense" orm:"business_license"` // 营业执照号
|
||||
LegalPerson string `json:"legalPerson" orm:"legal_person"` // 法人姓名
|
||||
ContactName string `json:"contactName" orm:"contact_name"` // 联系人姓名
|
||||
ContactPhone string `json:"contactPhone" orm:"contact_phone"` // 联系人电话
|
||||
ContactEmail string `json:"contactEmail" orm:"contact_email"` // 联系人邮箱
|
||||
Address string `json:"address" orm:"address"` // 商户地址
|
||||
Status int `json:"status" orm:"status,default:1"` // 状态:1=正常,2=禁用
|
||||
ExpireAt *gtime.Time `json:"expireAt" orm:"expire_at"` // 服务到期时间
|
||||
ApplicationReason int64 `json:"applicationReason" orm:"application_reason"` // 申请理由
|
||||
CreatedBy int64 `json:"createdBy" orm:"created_by"` // 创建人ID
|
||||
CreatedByType int `json:"createdByType" orm:"created_by_type"` // 创建人类型:1=系统管理员,2=商户注册
|
||||
AuditStatus int `json:"auditStatus" orm:"audit_status,default:0"` // 审核状态:0=待审核,1=审核通过,2=审核拒绝
|
||||
AuditBy int64 `json:"auditBy" orm:"audit_by"` // 审核人ID
|
||||
AuditAt *gtime.Time `json:"auditAt" orm:"audit_at"` // 审核时间
|
||||
AuditRemark string `json:"auditRemark" orm:"audit_remark"` // 审核备注
|
||||
RejectReason string `json:"rejectReason" orm:"reject_reason"` // 拒绝原因
|
||||
}
|
||||
|
||||
// MerchantCreateIn 创建商户请求
|
||||
type MerchantCreateIn struct {
|
||||
Name string
|
||||
BusinessLicense string
|
||||
LegalPerson string
|
||||
ContactName string
|
||||
ContactPhone string
|
||||
ContactEmail string
|
||||
Address string
|
||||
ApplicationReason int64
|
||||
}
|
||||
|
||||
// MerchantUpdateIn 更新商户请求
|
||||
type MerchantUpdateIn struct {
|
||||
Id int64
|
||||
Name string
|
||||
BusinessLicense string
|
||||
LegalPerson string
|
||||
ContactName string
|
||||
ContactPhone string
|
||||
ContactEmail string
|
||||
Address string
|
||||
Status int
|
||||
ExpireAt *gtime.Time
|
||||
}
|
||||
|
||||
// MerchantAuditIn 审核商户请求
|
||||
type MerchantAuditIn struct {
|
||||
AdminId int64
|
||||
Id int64
|
||||
AuditStatus int
|
||||
AuditRemark string
|
||||
RejectReason string
|
||||
}
|
||||
type MerchantAuditOut struct {
|
||||
}
|
||||
|
||||
// MerchantOut 商户响应
|
||||
type MerchantOut struct {
|
||||
*Merchant
|
||||
}
|
||||
|
||||
type MerchantListIn struct {
|
||||
Page int
|
||||
Size int
|
||||
Status int
|
||||
AuditStatus int
|
||||
}
|
||||
type MerchantListOut struct {
|
||||
List []Merchant
|
||||
Total int
|
||||
}
|
||||
46
internal/model/merchant_admin.go
Normal file
46
internal/model/merchant_admin.go
Normal file
@ -0,0 +1,46 @@
|
||||
package model
|
||||
|
||||
// MerchantAdmin 商户管理员信息
|
||||
type MerchantAdmin struct {
|
||||
}
|
||||
|
||||
// MerchantLoginIn 商户登录入参
|
||||
type MerchantLoginIn struct {
|
||||
Phone string
|
||||
Username string
|
||||
Password string
|
||||
Code string
|
||||
}
|
||||
|
||||
type MerchantLoginOut struct {
|
||||
Token string
|
||||
}
|
||||
type MerchantAdminInfoIn struct {
|
||||
MerchantAdminId int64
|
||||
}
|
||||
type MerchantAdminInfoOut struct {
|
||||
*MerchantAdmin
|
||||
}
|
||||
type MerchantAdminCodeIn struct {
|
||||
Phone string
|
||||
}
|
||||
type MerchantAdminCodeOut struct {
|
||||
}
|
||||
type MerchantAdminVertifyPhoneIn struct {
|
||||
MerchantAdminId int64
|
||||
Phone string
|
||||
Code string
|
||||
}
|
||||
type MerchantAdminVertifyPhoneOut struct {
|
||||
}
|
||||
type MerchantAdminRegisterIn struct {
|
||||
Username string
|
||||
Phone string
|
||||
Password string
|
||||
Password2 string
|
||||
Code string
|
||||
ApplicationReason string
|
||||
}
|
||||
type MerchantAdminRegisterOut struct {
|
||||
Success bool
|
||||
}
|
||||
@ -1,24 +0,0 @@
|
||||
package model
|
||||
|
||||
import "github.com/gogf/gf/v2/frame/g"
|
||||
|
||||
type RoleMenu struct {
|
||||
g.Meta `orm:"table:role_menus"`
|
||||
Id int64 `json:"id" orm:"id" dc:"角色菜单ID"`
|
||||
RoleId int64 `json:"roleId" orm:"role_id" dc:"角色ID"`
|
||||
MenuId int64 `json:"menuId" orm:"menu_id" dc:"菜单ID"`
|
||||
}
|
||||
type RoleMenuListInput struct {
|
||||
Page int
|
||||
Size int
|
||||
RoleId int64
|
||||
}
|
||||
type RoleMenuListOutput struct {
|
||||
List []RoleMenu
|
||||
Total int
|
||||
}
|
||||
|
||||
type RoleMenuSaveInput struct {
|
||||
RoleId int
|
||||
MenuIds []int
|
||||
}
|
||||
29
internal/model/upload.go
Normal file
29
internal/model/upload.go
Normal file
@ -0,0 +1,29 @@
|
||||
package model
|
||||
|
||||
import "github.com/gogf/gf/v2/net/ghttp"
|
||||
|
||||
type UploadIn struct {
|
||||
File *ghttp.UploadFile
|
||||
}
|
||||
|
||||
type UploadOut struct {
|
||||
Url string
|
||||
}
|
||||
type OssOutput struct {
|
||||
Url string
|
||||
}
|
||||
|
||||
type OssBytesInput struct {
|
||||
Bytes []byte
|
||||
Name string
|
||||
}
|
||||
|
||||
type OssGetFileInput struct {
|
||||
FilePath string
|
||||
Name string
|
||||
}
|
||||
|
||||
type OssUploadFileInput struct {
|
||||
Filename string
|
||||
File *ghttp.UploadFile
|
||||
}
|
||||
@ -1,6 +1,58 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// User 用户信息
|
||||
type User struct {
|
||||
Id int64 `json:"id" orm:"id,primary"` // 用户ID
|
||||
Username string `json:"username" orm:"username,not null"` // 用户名
|
||||
PasswordHash string `json:"passwordHash" orm:"password_hash,not null"` // 密码哈希
|
||||
Nickname string `json:"nickname" orm:"nickname"` // 昵称
|
||||
Avatar string `json:"avatar" orm:"avatar"` // 头像
|
||||
Phone string `json:"phone" orm:"phone"` // 手机号
|
||||
Email string `json:"email" orm:"email"` // 邮箱
|
||||
Gender int `json:"gender" orm:"gender,default:0"` // 性别:0=未知,1=男,2=女
|
||||
Birthday *gtime.Time `json:"birthday" orm:"birthday"` // 生日
|
||||
Status int `json:"status" orm:"status,default:1"` // 状态:1=正常,2=禁用
|
||||
LastLoginAt *gtime.Time `json:"lastLoginAt" orm:"last_login_at"` // 最后登录时间
|
||||
LastLoginIp string `json:"lastLoginIp" orm:"last_login_ip"` // 最后登录IP
|
||||
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at"` // 创建时间
|
||||
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at"` // 更新时间
|
||||
DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at"` // 软删除时间戳
|
||||
}
|
||||
|
||||
// UserCreateIn 创建用户请求
|
||||
type UserCreateIn struct {
|
||||
Username string
|
||||
Password string
|
||||
Nickname string
|
||||
Avatar string
|
||||
Phone string
|
||||
Email string
|
||||
Gender int
|
||||
Birthday *gtime.Time
|
||||
}
|
||||
|
||||
// UserUpdateIn 更新用户请求
|
||||
type UserUpdateIn struct {
|
||||
Id int64
|
||||
Nickname string
|
||||
Avatar string
|
||||
Phone string
|
||||
Email string
|
||||
Gender int
|
||||
Birthday *gtime.Time
|
||||
Status int
|
||||
}
|
||||
|
||||
// UserOut 用户响应
|
||||
type UserOut struct {
|
||||
*User
|
||||
}
|
||||
|
||||
type LoginCache struct {
|
||||
Token string `json:"token"`
|
||||
@ -23,7 +75,5 @@ type UserInfoOut struct {
|
||||
Id int64
|
||||
}
|
||||
|
||||
type UserUpdateIn struct {
|
||||
}
|
||||
type UserBindPhoneIn struct {
|
||||
}
|
||||
|
||||
34
internal/service/merchant.go
Normal file
34
internal/service/merchant.go
Normal file
@ -0,0 +1,34 @@
|
||||
// ================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// You can delete these comments if you wish manually maintain this interface file.
|
||||
// ================================================================================
|
||||
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"server/internal/model"
|
||||
)
|
||||
|
||||
type (
|
||||
IMerchant interface {
|
||||
List(ctx context.Context, in *model.MerchantListIn) (out *model.MerchantListOut, err error)
|
||||
Audit(ctx context.Context, in *model.MerchantAuditIn) (out *model.MerchantAuditOut, err error)
|
||||
Create(ctx context.Context, in *model.MerchantCreateIn) (out *model.CreateOut, err error)
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
localMerchant IMerchant
|
||||
)
|
||||
|
||||
func Merchant() IMerchant {
|
||||
if localMerchant == nil {
|
||||
panic("implement not found for interface IMerchant, forgot register?")
|
||||
}
|
||||
return localMerchant
|
||||
}
|
||||
|
||||
func RegisterMerchant(i IMerchant) {
|
||||
localMerchant = i
|
||||
}
|
||||
@ -5,4 +5,32 @@
|
||||
|
||||
package service
|
||||
|
||||
type ()
|
||||
import (
|
||||
"context"
|
||||
"server/internal/model"
|
||||
)
|
||||
|
||||
type (
|
||||
IMerchantAdmin interface {
|
||||
Login(ctx context.Context, in *model.MerchantLoginIn) (out *model.MerchantLoginOut, err error)
|
||||
Info(ctx context.Context, in *model.MerchantAdminInfoIn) (out *model.MerchantAdminInfoOut, err error)
|
||||
Code(ctx context.Context, in *model.MerchantAdminCodeIn) (out *model.MerchantAdminCodeOut, err error)
|
||||
VertifyPhone(ctx context.Context, in *model.MerchantAdminVertifyPhoneIn) (out *model.MerchantAdminVertifyPhoneOut, err error)
|
||||
Register(ctx context.Context, in *model.MerchantAdminRegisterIn) (out *model.MerchantAdminRegisterOut, err error)
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
localMerchantAdmin IMerchantAdmin
|
||||
)
|
||||
|
||||
func MerchantAdmin() IMerchantAdmin {
|
||||
if localMerchantAdmin == nil {
|
||||
panic("implement not found for interface IMerchantAdmin, forgot register?")
|
||||
}
|
||||
return localMerchantAdmin
|
||||
}
|
||||
|
||||
func RegisterMerchantAdmin(i IMerchantAdmin) {
|
||||
localMerchantAdmin = i
|
||||
}
|
||||
|
||||
@ -1,33 +0,0 @@
|
||||
// ================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// You can delete these comments if you wish manually maintain this interface file.
|
||||
// ================================================================================
|
||||
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"server/internal/model"
|
||||
)
|
||||
|
||||
type (
|
||||
IRoleMenu interface {
|
||||
List(ctx context.Context, in *model.RoleMenuListInput) (out *model.MenuListOutput, err error)
|
||||
Save(ctx context.Context, in *model.RoleMenuSaveInput) (out *model.UpdateOut, err error)
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
localRoleMenu IRoleMenu
|
||||
)
|
||||
|
||||
func RoleMenu() IRoleMenu {
|
||||
if localRoleMenu == nil {
|
||||
panic("implement not found for interface IRoleMenu, forgot register?")
|
||||
}
|
||||
return localRoleMenu
|
||||
}
|
||||
|
||||
func RegisterRoleMenu(i IRoleMenu) {
|
||||
localRoleMenu = i
|
||||
}
|
||||
@ -1,8 +0,0 @@
|
||||
// ================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// You can delete these comments if you wish manually maintain this interface file.
|
||||
// ================================================================================
|
||||
|
||||
package service
|
||||
|
||||
type ()
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/glog"
|
||||
"github.com/hailaz/gf-casbin-adapter/v2"
|
||||
"server/internal/consts"
|
||||
"sync"
|
||||
)
|
||||
|
||||
@ -33,6 +34,10 @@ func init() {
|
||||
}
|
||||
|
||||
enforcer.LoadPolicy()
|
||||
enforcer.AddGroupingPolicy(consts.UserRoleCode, consts.GuestRoleCode) // 用户继承游客角色权限
|
||||
|
||||
enforcer.AddGroupingPolicy(consts.MerchantRoleCode, consts.StoreRoleCode) // 商户继承门店角色权限
|
||||
enforcer.AddGroupingPolicy(consts.AdminRoleCode, consts.MerchantRoleCode) // 管理员继承商户角色权限
|
||||
// 管理员
|
||||
{
|
||||
// admin
|
||||
@ -45,6 +50,10 @@ func init() {
|
||||
enforcer.AddPolicy("admin", "/x/role", "DELETE", "管理员给角色分配权限")
|
||||
enforcer.AddPolicy("admin", "/x/role/*", "DELETE", "管理员删除单个角色")
|
||||
|
||||
// merchant
|
||||
enforcer.AddPolicy("admin", "/x/merchant", "GET", "管理员获取商户列表")
|
||||
enforcer.AddPolicy("admin", "/x/merchant/audit", "POST", "管理员审核商户申请")
|
||||
|
||||
}
|
||||
instance = &myCasbin{Enforcer: enforcer}
|
||||
|
||||
|
||||
97
utility/oss/aliyun/aliyun.go
Normal file
97
utility/oss/aliyun/aliyun.go
Normal file
@ -0,0 +1,97 @@
|
||||
package aliyun
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/aliyun/aliyun-oss-go-sdk/oss"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/util/grand"
|
||||
"server/internal/model"
|
||||
ioss "server/utility/oss"
|
||||
)
|
||||
|
||||
type aliyunClient struct {
|
||||
bucketName string
|
||||
key string
|
||||
secret string
|
||||
endpoint string
|
||||
}
|
||||
|
||||
// 初始化并注册
|
||||
func init() {
|
||||
ctx := context.Background()
|
||||
client := &aliyunClient{
|
||||
endpoint: g.Config().MustGet(ctx, "oss.aliyun.endpoint").String(),
|
||||
key: g.Config().MustGet(ctx, "oss.aliyun.key").String(),
|
||||
secret: g.Config().MustGet(ctx, "oss.aliyun.secret").String(),
|
||||
bucketName: g.Config().MustGet(ctx, "oss.aliyun.bucket").String(),
|
||||
}
|
||||
ioss.Register("aliyun", client)
|
||||
}
|
||||
|
||||
func (a *aliyunClient) client(ctx context.Context, endpoint, key, sercret string) (*oss.Client, error) {
|
||||
client, err := oss.New(endpoint, key, sercret)
|
||||
return client, err
|
||||
}
|
||||
|
||||
func (a *aliyunClient) bucket(ctx context.Context, client *oss.Client) (*oss.Bucket, error) {
|
||||
bucket, err := client.Bucket(a.bucketName)
|
||||
return bucket, err
|
||||
}
|
||||
func (a *aliyunClient) bytes(ctx context.Context, in *model.OssBytesInput) (*model.OssOutput, error) {
|
||||
client, err := a.client(ctx, a.endpoint, a.key, a.secret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bucket, err := a.bucket(ctx, client)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if in.Name == "" {
|
||||
in.Name = grand.Digits(32)
|
||||
}
|
||||
err = bucket.PutObject(in.Name, bytes.NewReader(in.Bytes))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &model.OssOutput{
|
||||
Url: fmt.Sprintf("https://%s.%s/%s", a.bucketName, a.endpoint, in.Name),
|
||||
}, nil
|
||||
}
|
||||
func (a *aliyunClient) UploadFile(ctx context.Context, in *model.OssUploadFileInput) (out *model.OssOutput, err error) {
|
||||
f, err := in.File.Open()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
body := make([]byte, in.File.Size)
|
||||
_, err = f.Read(body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return a.bytes(ctx, &model.OssBytesInput{
|
||||
Name: in.Filename,
|
||||
Bytes: body,
|
||||
})
|
||||
}
|
||||
func (a *aliyunClient) GetFileURL(ctx context.Context, in *model.OssGetFileInput) (out *model.OssOutput, err error) {
|
||||
client, err := a.client(ctx, a.endpoint, a.key, a.secret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bucket, err := a.bucket(ctx, client)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if in.Name == "" {
|
||||
in.Name = grand.Digits(32)
|
||||
}
|
||||
err = bucket.PutObjectFromFile(in.Name, in.FilePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &model.OssOutput{
|
||||
Url: fmt.Sprintf("https://%s.%s/%s", a.bucketName, a.endpoint, in.Name),
|
||||
}, nil
|
||||
}
|
||||
26
utility/oss/oss.go
Normal file
26
utility/oss/oss.go
Normal file
@ -0,0 +1,26 @@
|
||||
package oss
|
||||
|
||||
import (
|
||||
"context"
|
||||
"server/internal/model"
|
||||
)
|
||||
|
||||
// OssClient 是所有云存储平台要实现的统一接口
|
||||
type OssClient interface {
|
||||
UploadFile(ctx context.Context, in *model.OssUploadFileInput) (out *model.OssOutput, err error)
|
||||
GetFileURL(ctx context.Context, in *model.OssGetFileInput) (out *model.OssOutput, err error)
|
||||
}
|
||||
|
||||
// registry 存储各个平台的实现
|
||||
var clients = make(map[string]OssClient)
|
||||
|
||||
// Register 用于注册平台实现
|
||||
func Register(name string, client OssClient) {
|
||||
clients[name] = client
|
||||
}
|
||||
|
||||
// GetClient 获取指定平台的实现
|
||||
func GetClient(name string) (OssClient, bool) {
|
||||
client, ok := clients[name]
|
||||
return client, ok
|
||||
}
|
||||
4
utility/sms/aliyun/aliyun.go
Normal file
4
utility/sms/aliyun/aliyun.go
Normal file
@ -0,0 +1,4 @@
|
||||
package aliyun
|
||||
|
||||
type aliyunClient struct {
|
||||
}
|
||||
21
utility/sms/sms.go
Normal file
21
utility/sms/sms.go
Normal file
@ -0,0 +1,21 @@
|
||||
package sms
|
||||
|
||||
import (
|
||||
"context"
|
||||
"server/internal/model"
|
||||
)
|
||||
|
||||
type SMSClient interface {
|
||||
UploadFile(ctx context.Context, in *model.OssUploadFileInput) (out *model.OssOutput, err error)
|
||||
GetFileURL(ctx context.Context, in *model.OssGetFileInput) (out *model.OssOutput, err error)
|
||||
}
|
||||
|
||||
var clients = make(map[string]SMSClient)
|
||||
|
||||
func Register(name string, client SMSClient) {
|
||||
clients[name] = client
|
||||
}
|
||||
func GetClient(name string) (SMSClient, bool) {
|
||||
client, ok := clients[name]
|
||||
return client, ok
|
||||
}
|
||||
Reference in New Issue
Block a user