chore: update auth and portal
This commit is contained in:
@@ -64,9 +64,6 @@ func (m *Middlewares) authenticate(ctx fiber.Ctx, requireToken bool) error {
|
||||
if user.Status == consts.UserStatusBanned {
|
||||
return errorx.ErrAccountDisabled
|
||||
}
|
||||
if user.Status == consts.UserStatusBanned {
|
||||
return errorx.ErrAccountDisabled
|
||||
}
|
||||
|
||||
// Set Context
|
||||
ctx.Locals(consts.CtxKeyUser, user)
|
||||
@@ -104,6 +101,9 @@ func (m *Middlewares) SuperAuth(ctx fiber.Ctx) error {
|
||||
if err != nil {
|
||||
return errorx.ErrUnauthorized.WithCause(err).WithMsg("UserNotFound")
|
||||
}
|
||||
if user.Status == consts.UserStatusBanned {
|
||||
return errorx.ErrAccountDisabled
|
||||
}
|
||||
|
||||
if !hasRole(user.Roles, consts.RoleSuperAdmin) {
|
||||
return errorx.ErrForbidden.WithMsg("无权限访问")
|
||||
|
||||
@@ -27,12 +27,22 @@ type super struct {
|
||||
}
|
||||
|
||||
func (s *super) Login(ctx context.Context, form *super_dto.LoginForm) (*super_dto.LoginResponse, error) {
|
||||
tbl, q := models.UserQuery.QueryContext(ctx)
|
||||
u, err := q.Where(tbl.Username.Eq(form.Username)).First()
|
||||
if err != nil {
|
||||
return nil, errorx.ErrInvalidCredentials.WithMsg("账号或密码错误")
|
||||
if form == nil {
|
||||
return nil, errorx.ErrInvalidParameter.WithMsg("登录参数不能为空")
|
||||
}
|
||||
if u.Password != form.Password {
|
||||
username := strings.TrimSpace(form.Username)
|
||||
password := strings.TrimSpace(form.Password)
|
||||
if username == "" || password == "" {
|
||||
return nil, errorx.ErrInvalidParameter.WithMsg("账号或密码不能为空")
|
||||
}
|
||||
|
||||
// 校验账号与权限。
|
||||
tbl, q := models.UserQuery.QueryContext(ctx)
|
||||
u, err := q.Where(tbl.Username.Eq(username)).First()
|
||||
if err != nil {
|
||||
return nil, errorx.ErrInvalidCredentials.WithCause(err).WithMsg("账号或密码错误")
|
||||
}
|
||||
if u.Password != password {
|
||||
return nil, errorx.ErrInvalidCredentials.WithMsg("账号或密码错误")
|
||||
}
|
||||
if u.Status == consts.UserStatusBanned {
|
||||
@@ -42,11 +52,12 @@ func (s *super) Login(ctx context.Context, form *super_dto.LoginForm) (*super_dt
|
||||
return nil, errorx.ErrForbidden.WithMsg("无权限访问")
|
||||
}
|
||||
|
||||
// 生成登录令牌。
|
||||
token, err := s.jwt.CreateToken(s.jwt.CreateClaims(jwt_provider.BaseClaims{
|
||||
UserID: u.ID,
|
||||
}))
|
||||
if err != nil {
|
||||
return nil, errorx.ErrInternalError.WithMsg("生成令牌失败")
|
||||
return nil, errorx.ErrInternalError.WithCause(err).WithMsg("生成令牌失败")
|
||||
}
|
||||
|
||||
return &super_dto.LoginResponse{
|
||||
@@ -68,7 +79,10 @@ func (s *super) CheckToken(ctx context.Context, token string) (*super_dto.LoginR
|
||||
tbl, q := models.UserQuery.QueryContext(ctx)
|
||||
u, err := q.Where(tbl.ID.Eq(claims.UserID)).First()
|
||||
if err != nil {
|
||||
return nil, errorx.ErrUnauthorized.WithMsg("UserNotFound")
|
||||
return nil, errorx.ErrUnauthorized.WithCause(err).WithMsg("UserNotFound")
|
||||
}
|
||||
if u.Status == consts.UserStatusBanned {
|
||||
return nil, errorx.ErrAccountDisabled
|
||||
}
|
||||
if !hasRole(u.Roles, consts.RoleSuperAdmin) {
|
||||
return nil, errorx.ErrForbidden.WithMsg("无权限访问")
|
||||
@@ -78,7 +92,7 @@ func (s *super) CheckToken(ctx context.Context, token string) (*super_dto.LoginR
|
||||
UserID: u.ID,
|
||||
}))
|
||||
if err != nil {
|
||||
return nil, errorx.ErrInternalError.WithMsg("生成令牌失败")
|
||||
return nil, errorx.ErrInternalError.WithCause(err).WithMsg("生成令牌失败")
|
||||
}
|
||||
|
||||
return &super_dto.LoginResponse{
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"go.ipao.vip/atom/contracts"
|
||||
"go.ipao.vip/gen/types"
|
||||
"go.uber.org/dig"
|
||||
)
|
||||
|
||||
@@ -74,6 +75,60 @@ func (s *SuperTestSuite) Test_ListUsers() {
|
||||
})
|
||||
}
|
||||
|
||||
func (s *SuperTestSuite) Test_LoginAndCheckToken() {
|
||||
Convey("Login and CheckToken", s.T(), func() {
|
||||
ctx := s.T().Context()
|
||||
database.Truncate(ctx, s.DB, models.TableNameUser)
|
||||
|
||||
admin := &models.User{
|
||||
Username: "super_admin",
|
||||
Password: "pass123",
|
||||
Roles: types.Array[consts.Role]{consts.RoleSuperAdmin},
|
||||
Status: consts.UserStatusVerified,
|
||||
}
|
||||
normal := &models.User{
|
||||
Username: "normal_user",
|
||||
Password: "pass123",
|
||||
Status: consts.UserStatusVerified,
|
||||
}
|
||||
models.UserQuery.WithContext(ctx).Create(admin, normal)
|
||||
|
||||
Convey("should login as super admin", func() {
|
||||
res, err := Super.Login(ctx, &super_dto.LoginForm{
|
||||
Username: admin.Username,
|
||||
Password: admin.Password,
|
||||
})
|
||||
So(err, ShouldBeNil)
|
||||
So(res, ShouldNotBeNil)
|
||||
So(res.Token, ShouldNotBeBlank)
|
||||
So(res.User.ID, ShouldEqual, admin.ID)
|
||||
})
|
||||
|
||||
Convey("should reject non-super admin", func() {
|
||||
_, err := Super.Login(ctx, &super_dto.LoginForm{
|
||||
Username: normal.Username,
|
||||
Password: normal.Password,
|
||||
})
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
|
||||
Convey("should refresh token", func() {
|
||||
loginRes, err := Super.Login(ctx, &super_dto.LoginForm{
|
||||
Username: admin.Username,
|
||||
Password: admin.Password,
|
||||
})
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
token := "Bearer " + loginRes.Token
|
||||
checkRes, err := Super.CheckToken(ctx, token)
|
||||
So(err, ShouldBeNil)
|
||||
So(checkRes, ShouldNotBeNil)
|
||||
So(checkRes.Token, ShouldNotBeBlank)
|
||||
So(checkRes.User.ID, ShouldEqual, admin.ID)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func (s *SuperTestSuite) Test_CreateTenant() {
|
||||
Convey("CreateTenant", s.T(), func() {
|
||||
ctx := s.T().Context()
|
||||
|
||||
@@ -1708,6 +1708,208 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/t/{tenantCode}/v1/creator/coupons": {
|
||||
"get": {
|
||||
"description": "List coupon templates",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"CreatorCenter"
|
||||
],
|
||||
"summary": "List coupons",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Page",
|
||||
"name": "page",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Limit",
|
||||
"name": "limit",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Type (fix_amount/discount)",
|
||||
"name": "type",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Status (active/expired)",
|
||||
"name": "status",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Keyword",
|
||||
"name": "keyword",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/requests.Pager"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"description": "Create coupon template",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"CreatorCenter"
|
||||
],
|
||||
"summary": "Create coupon",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Coupon form",
|
||||
"name": "form",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.CouponCreateForm"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.CouponItem"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/t/{tenantCode}/v1/creator/coupons/{id}": {
|
||||
"get": {
|
||||
"description": "Get coupon template detail",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"CreatorCenter"
|
||||
],
|
||||
"summary": "Get coupon",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"description": "Coupon ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.CouponItem"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"description": "Update coupon template",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"CreatorCenter"
|
||||
],
|
||||
"summary": "Update coupon",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"description": "Coupon ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"description": "Coupon form",
|
||||
"name": "form",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.CouponUpdateForm"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.CouponItem"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/t/{tenantCode}/v1/creator/coupons/{id}/grant": {
|
||||
"post": {
|
||||
"description": "Grant coupon to users",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"CreatorCenter"
|
||||
],
|
||||
"summary": "Grant coupon",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"description": "Coupon ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"description": "Grant form",
|
||||
"name": "form",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.CouponGrantForm"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Granted",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/t/{tenantCode}/v1/creator/dashboard": {
|
||||
"get": {
|
||||
"description": "Get creator dashboard stats",
|
||||
@@ -2278,6 +2480,76 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/t/{tenantCode}/v1/me/coupons/available": {
|
||||
"get": {
|
||||
"description": "List coupons available for the given order amount",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"UserCenter"
|
||||
],
|
||||
"summary": "List available coupons",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"description": "Order amount (cents)",
|
||||
"name": "amount",
|
||||
"in": "query",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/dto.UserCouponItem"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/t/{tenantCode}/v1/me/coupons/receive": {
|
||||
"post": {
|
||||
"description": "Receive a coupon by coupon_id",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"UserCenter"
|
||||
],
|
||||
"summary": "Receive coupon",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Receive form",
|
||||
"name": "form",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.CouponReceiveForm"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.UserCouponItem"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/t/{tenantCode}/v1/me/favorites": {
|
||||
"get": {
|
||||
"description": "Get favorites",
|
||||
@@ -4187,6 +4459,166 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.CouponCreateForm": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"description": {
|
||||
"description": "Description 优惠券描述。",
|
||||
"type": "string"
|
||||
},
|
||||
"end_at": {
|
||||
"description": "EndAt 过期时间(RFC3339,可为空)。",
|
||||
"type": "string"
|
||||
},
|
||||
"max_discount": {
|
||||
"description": "MaxDiscount 折扣券最高抵扣金额(分)。",
|
||||
"type": "integer"
|
||||
},
|
||||
"min_order_amount": {
|
||||
"description": "MinOrderAmount 使用门槛金额(分)。",
|
||||
"type": "integer"
|
||||
},
|
||||
"start_at": {
|
||||
"description": "StartAt 生效时间(RFC3339,可为空)。",
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"description": "Title 优惠券标题。",
|
||||
"type": "string"
|
||||
},
|
||||
"total_quantity": {
|
||||
"description": "TotalQuantity 发行总量(0 表示不限量)。",
|
||||
"type": "integer"
|
||||
},
|
||||
"type": {
|
||||
"description": "Type 优惠券类型(fix_amount/discount)。",
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"description": "Value 优惠券面值(分/折扣百分比)。",
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.CouponGrantForm": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"user_ids": {
|
||||
"description": "UserIDs 领取用户ID集合。",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.CouponItem": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created_at": {
|
||||
"description": "CreatedAt 创建时间(RFC3339)。",
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"description": "Description 优惠券描述。",
|
||||
"type": "string"
|
||||
},
|
||||
"end_at": {
|
||||
"description": "EndAt 过期时间(RFC3339)。",
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"description": "ID 券模板ID。",
|
||||
"type": "integer"
|
||||
},
|
||||
"max_discount": {
|
||||
"description": "MaxDiscount 折扣券最高抵扣金额(分)。",
|
||||
"type": "integer"
|
||||
},
|
||||
"min_order_amount": {
|
||||
"description": "MinOrderAmount 使用门槛金额(分)。",
|
||||
"type": "integer"
|
||||
},
|
||||
"start_at": {
|
||||
"description": "StartAt 生效时间(RFC3339)。",
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"description": "Title 优惠券标题。",
|
||||
"type": "string"
|
||||
},
|
||||
"total_quantity": {
|
||||
"description": "TotalQuantity 发行总量。",
|
||||
"type": "integer"
|
||||
},
|
||||
"type": {
|
||||
"description": "Type 优惠券类型(fix_amount/discount)。",
|
||||
"type": "string"
|
||||
},
|
||||
"updated_at": {
|
||||
"description": "UpdatedAt 更新时间(RFC3339)。",
|
||||
"type": "string"
|
||||
},
|
||||
"used_quantity": {
|
||||
"description": "UsedQuantity 已使用数量。",
|
||||
"type": "integer"
|
||||
},
|
||||
"value": {
|
||||
"description": "Value 优惠券面值(分/折扣百分比)。",
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.CouponReceiveForm": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"coupon_id": {
|
||||
"description": "CouponID 券模板ID。",
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.CouponUpdateForm": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"description": {
|
||||
"description": "Description 优惠券描述(为空表示不修改)。",
|
||||
"type": "string"
|
||||
},
|
||||
"end_at": {
|
||||
"description": "EndAt 过期时间(RFC3339,可为空)。",
|
||||
"type": "string"
|
||||
},
|
||||
"max_discount": {
|
||||
"description": "MaxDiscount 折扣券最高抵扣金额(分)。",
|
||||
"type": "integer"
|
||||
},
|
||||
"min_order_amount": {
|
||||
"description": "MinOrderAmount 使用门槛金额(分)。",
|
||||
"type": "integer"
|
||||
},
|
||||
"start_at": {
|
||||
"description": "StartAt 生效时间(RFC3339,可为空)。",
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"description": "Title 优惠券标题(为空表示不修改)。",
|
||||
"type": "string"
|
||||
},
|
||||
"total_quantity": {
|
||||
"description": "TotalQuantity 发行总量(0 表示不限量)。",
|
||||
"type": "integer"
|
||||
},
|
||||
"type": {
|
||||
"description": "Type 优惠券类型(fix_amount/discount)。",
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"description": "Value 优惠券面值(分/折扣百分比)。",
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.DashboardStats": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
@@ -1702,6 +1702,208 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/t/{tenantCode}/v1/creator/coupons": {
|
||||
"get": {
|
||||
"description": "List coupon templates",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"CreatorCenter"
|
||||
],
|
||||
"summary": "List coupons",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Page",
|
||||
"name": "page",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Limit",
|
||||
"name": "limit",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Type (fix_amount/discount)",
|
||||
"name": "type",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Status (active/expired)",
|
||||
"name": "status",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Keyword",
|
||||
"name": "keyword",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/requests.Pager"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"description": "Create coupon template",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"CreatorCenter"
|
||||
],
|
||||
"summary": "Create coupon",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Coupon form",
|
||||
"name": "form",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.CouponCreateForm"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.CouponItem"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/t/{tenantCode}/v1/creator/coupons/{id}": {
|
||||
"get": {
|
||||
"description": "Get coupon template detail",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"CreatorCenter"
|
||||
],
|
||||
"summary": "Get coupon",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"description": "Coupon ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.CouponItem"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"description": "Update coupon template",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"CreatorCenter"
|
||||
],
|
||||
"summary": "Update coupon",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"description": "Coupon ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"description": "Coupon form",
|
||||
"name": "form",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.CouponUpdateForm"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.CouponItem"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/t/{tenantCode}/v1/creator/coupons/{id}/grant": {
|
||||
"post": {
|
||||
"description": "Grant coupon to users",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"CreatorCenter"
|
||||
],
|
||||
"summary": "Grant coupon",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"description": "Coupon ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"description": "Grant form",
|
||||
"name": "form",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.CouponGrantForm"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Granted",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/t/{tenantCode}/v1/creator/dashboard": {
|
||||
"get": {
|
||||
"description": "Get creator dashboard stats",
|
||||
@@ -2272,6 +2474,76 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/t/{tenantCode}/v1/me/coupons/available": {
|
||||
"get": {
|
||||
"description": "List coupons available for the given order amount",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"UserCenter"
|
||||
],
|
||||
"summary": "List available coupons",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"description": "Order amount (cents)",
|
||||
"name": "amount",
|
||||
"in": "query",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/dto.UserCouponItem"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/t/{tenantCode}/v1/me/coupons/receive": {
|
||||
"post": {
|
||||
"description": "Receive a coupon by coupon_id",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"UserCenter"
|
||||
],
|
||||
"summary": "Receive coupon",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Receive form",
|
||||
"name": "form",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.CouponReceiveForm"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.UserCouponItem"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/t/{tenantCode}/v1/me/favorites": {
|
||||
"get": {
|
||||
"description": "Get favorites",
|
||||
@@ -4181,6 +4453,166 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.CouponCreateForm": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"description": {
|
||||
"description": "Description 优惠券描述。",
|
||||
"type": "string"
|
||||
},
|
||||
"end_at": {
|
||||
"description": "EndAt 过期时间(RFC3339,可为空)。",
|
||||
"type": "string"
|
||||
},
|
||||
"max_discount": {
|
||||
"description": "MaxDiscount 折扣券最高抵扣金额(分)。",
|
||||
"type": "integer"
|
||||
},
|
||||
"min_order_amount": {
|
||||
"description": "MinOrderAmount 使用门槛金额(分)。",
|
||||
"type": "integer"
|
||||
},
|
||||
"start_at": {
|
||||
"description": "StartAt 生效时间(RFC3339,可为空)。",
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"description": "Title 优惠券标题。",
|
||||
"type": "string"
|
||||
},
|
||||
"total_quantity": {
|
||||
"description": "TotalQuantity 发行总量(0 表示不限量)。",
|
||||
"type": "integer"
|
||||
},
|
||||
"type": {
|
||||
"description": "Type 优惠券类型(fix_amount/discount)。",
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"description": "Value 优惠券面值(分/折扣百分比)。",
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.CouponGrantForm": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"user_ids": {
|
||||
"description": "UserIDs 领取用户ID集合。",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.CouponItem": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created_at": {
|
||||
"description": "CreatedAt 创建时间(RFC3339)。",
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"description": "Description 优惠券描述。",
|
||||
"type": "string"
|
||||
},
|
||||
"end_at": {
|
||||
"description": "EndAt 过期时间(RFC3339)。",
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"description": "ID 券模板ID。",
|
||||
"type": "integer"
|
||||
},
|
||||
"max_discount": {
|
||||
"description": "MaxDiscount 折扣券最高抵扣金额(分)。",
|
||||
"type": "integer"
|
||||
},
|
||||
"min_order_amount": {
|
||||
"description": "MinOrderAmount 使用门槛金额(分)。",
|
||||
"type": "integer"
|
||||
},
|
||||
"start_at": {
|
||||
"description": "StartAt 生效时间(RFC3339)。",
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"description": "Title 优惠券标题。",
|
||||
"type": "string"
|
||||
},
|
||||
"total_quantity": {
|
||||
"description": "TotalQuantity 发行总量。",
|
||||
"type": "integer"
|
||||
},
|
||||
"type": {
|
||||
"description": "Type 优惠券类型(fix_amount/discount)。",
|
||||
"type": "string"
|
||||
},
|
||||
"updated_at": {
|
||||
"description": "UpdatedAt 更新时间(RFC3339)。",
|
||||
"type": "string"
|
||||
},
|
||||
"used_quantity": {
|
||||
"description": "UsedQuantity 已使用数量。",
|
||||
"type": "integer"
|
||||
},
|
||||
"value": {
|
||||
"description": "Value 优惠券面值(分/折扣百分比)。",
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.CouponReceiveForm": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"coupon_id": {
|
||||
"description": "CouponID 券模板ID。",
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.CouponUpdateForm": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"description": {
|
||||
"description": "Description 优惠券描述(为空表示不修改)。",
|
||||
"type": "string"
|
||||
},
|
||||
"end_at": {
|
||||
"description": "EndAt 过期时间(RFC3339,可为空)。",
|
||||
"type": "string"
|
||||
},
|
||||
"max_discount": {
|
||||
"description": "MaxDiscount 折扣券最高抵扣金额(分)。",
|
||||
"type": "integer"
|
||||
},
|
||||
"min_order_amount": {
|
||||
"description": "MinOrderAmount 使用门槛金额(分)。",
|
||||
"type": "integer"
|
||||
},
|
||||
"start_at": {
|
||||
"description": "StartAt 生效时间(RFC3339,可为空)。",
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"description": "Title 优惠券标题(为空表示不修改)。",
|
||||
"type": "string"
|
||||
},
|
||||
"total_quantity": {
|
||||
"description": "TotalQuantity 发行总量(0 表示不限量)。",
|
||||
"type": "integer"
|
||||
},
|
||||
"type": {
|
||||
"description": "Type 优惠券类型(fix_amount/discount)。",
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"description": "Value 优惠券面值(分/折扣百分比)。",
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.DashboardStats": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
@@ -472,6 +472,122 @@ definitions:
|
||||
description: Title 内容标题(为空表示不修改)。
|
||||
type: string
|
||||
type: object
|
||||
dto.CouponCreateForm:
|
||||
properties:
|
||||
description:
|
||||
description: Description 优惠券描述。
|
||||
type: string
|
||||
end_at:
|
||||
description: EndAt 过期时间(RFC3339,可为空)。
|
||||
type: string
|
||||
max_discount:
|
||||
description: MaxDiscount 折扣券最高抵扣金额(分)。
|
||||
type: integer
|
||||
min_order_amount:
|
||||
description: MinOrderAmount 使用门槛金额(分)。
|
||||
type: integer
|
||||
start_at:
|
||||
description: StartAt 生效时间(RFC3339,可为空)。
|
||||
type: string
|
||||
title:
|
||||
description: Title 优惠券标题。
|
||||
type: string
|
||||
total_quantity:
|
||||
description: TotalQuantity 发行总量(0 表示不限量)。
|
||||
type: integer
|
||||
type:
|
||||
description: Type 优惠券类型(fix_amount/discount)。
|
||||
type: string
|
||||
value:
|
||||
description: Value 优惠券面值(分/折扣百分比)。
|
||||
type: integer
|
||||
type: object
|
||||
dto.CouponGrantForm:
|
||||
properties:
|
||||
user_ids:
|
||||
description: UserIDs 领取用户ID集合。
|
||||
items:
|
||||
type: integer
|
||||
type: array
|
||||
type: object
|
||||
dto.CouponItem:
|
||||
properties:
|
||||
created_at:
|
||||
description: CreatedAt 创建时间(RFC3339)。
|
||||
type: string
|
||||
description:
|
||||
description: Description 优惠券描述。
|
||||
type: string
|
||||
end_at:
|
||||
description: EndAt 过期时间(RFC3339)。
|
||||
type: string
|
||||
id:
|
||||
description: ID 券模板ID。
|
||||
type: integer
|
||||
max_discount:
|
||||
description: MaxDiscount 折扣券最高抵扣金额(分)。
|
||||
type: integer
|
||||
min_order_amount:
|
||||
description: MinOrderAmount 使用门槛金额(分)。
|
||||
type: integer
|
||||
start_at:
|
||||
description: StartAt 生效时间(RFC3339)。
|
||||
type: string
|
||||
title:
|
||||
description: Title 优惠券标题。
|
||||
type: string
|
||||
total_quantity:
|
||||
description: TotalQuantity 发行总量。
|
||||
type: integer
|
||||
type:
|
||||
description: Type 优惠券类型(fix_amount/discount)。
|
||||
type: string
|
||||
updated_at:
|
||||
description: UpdatedAt 更新时间(RFC3339)。
|
||||
type: string
|
||||
used_quantity:
|
||||
description: UsedQuantity 已使用数量。
|
||||
type: integer
|
||||
value:
|
||||
description: Value 优惠券面值(分/折扣百分比)。
|
||||
type: integer
|
||||
type: object
|
||||
dto.CouponReceiveForm:
|
||||
properties:
|
||||
coupon_id:
|
||||
description: CouponID 券模板ID。
|
||||
type: integer
|
||||
type: object
|
||||
dto.CouponUpdateForm:
|
||||
properties:
|
||||
description:
|
||||
description: Description 优惠券描述(为空表示不修改)。
|
||||
type: string
|
||||
end_at:
|
||||
description: EndAt 过期时间(RFC3339,可为空)。
|
||||
type: string
|
||||
max_discount:
|
||||
description: MaxDiscount 折扣券最高抵扣金额(分)。
|
||||
type: integer
|
||||
min_order_amount:
|
||||
description: MinOrderAmount 使用门槛金额(分)。
|
||||
type: integer
|
||||
start_at:
|
||||
description: StartAt 生效时间(RFC3339,可为空)。
|
||||
type: string
|
||||
title:
|
||||
description: Title 优惠券标题(为空表示不修改)。
|
||||
type: string
|
||||
total_quantity:
|
||||
description: TotalQuantity 发行总量(0 表示不限量)。
|
||||
type: integer
|
||||
type:
|
||||
description: Type 优惠券类型(fix_amount/discount)。
|
||||
type: string
|
||||
value:
|
||||
description: Value 优惠券面值(分/折扣百分比)。
|
||||
type: integer
|
||||
type: object
|
||||
dto.DashboardStats:
|
||||
properties:
|
||||
new_messages:
|
||||
@@ -2916,6 +3032,140 @@ paths:
|
||||
summary: Update content
|
||||
tags:
|
||||
- CreatorCenter
|
||||
/t/{tenantCode}/v1/creator/coupons:
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: List coupon templates
|
||||
parameters:
|
||||
- description: Page
|
||||
in: query
|
||||
name: page
|
||||
type: integer
|
||||
- description: Limit
|
||||
in: query
|
||||
name: limit
|
||||
type: integer
|
||||
- description: Type (fix_amount/discount)
|
||||
in: query
|
||||
name: type
|
||||
type: string
|
||||
- description: Status (active/expired)
|
||||
in: query
|
||||
name: status
|
||||
type: string
|
||||
- description: Keyword
|
||||
in: query
|
||||
name: keyword
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/requests.Pager'
|
||||
summary: List coupons
|
||||
tags:
|
||||
- CreatorCenter
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: Create coupon template
|
||||
parameters:
|
||||
- description: Coupon form
|
||||
in: body
|
||||
name: form
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/dto.CouponCreateForm'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/dto.CouponItem'
|
||||
summary: Create coupon
|
||||
tags:
|
||||
- CreatorCenter
|
||||
/t/{tenantCode}/v1/creator/coupons/{id}:
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: Get coupon template detail
|
||||
parameters:
|
||||
- description: Coupon ID
|
||||
format: int64
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: integer
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/dto.CouponItem'
|
||||
summary: Get coupon
|
||||
tags:
|
||||
- CreatorCenter
|
||||
put:
|
||||
consumes:
|
||||
- application/json
|
||||
description: Update coupon template
|
||||
parameters:
|
||||
- description: Coupon ID
|
||||
format: int64
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: integer
|
||||
- description: Coupon form
|
||||
in: body
|
||||
name: form
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/dto.CouponUpdateForm'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/dto.CouponItem'
|
||||
summary: Update coupon
|
||||
tags:
|
||||
- CreatorCenter
|
||||
/t/{tenantCode}/v1/creator/coupons/{id}/grant:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: Grant coupon to users
|
||||
parameters:
|
||||
- description: Coupon ID
|
||||
format: int64
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: integer
|
||||
- description: Grant form
|
||||
in: body
|
||||
name: form
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/dto.CouponGrantForm'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: Granted
|
||||
schema:
|
||||
type: string
|
||||
summary: Grant coupon
|
||||
tags:
|
||||
- CreatorCenter
|
||||
/t/{tenantCode}/v1/creator/dashboard:
|
||||
get:
|
||||
consumes:
|
||||
@@ -3290,6 +3540,52 @@ paths:
|
||||
summary: List coupons
|
||||
tags:
|
||||
- UserCenter
|
||||
/t/{tenantCode}/v1/me/coupons/available:
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: List coupons available for the given order amount
|
||||
parameters:
|
||||
- description: Order amount (cents)
|
||||
format: int64
|
||||
in: query
|
||||
name: amount
|
||||
required: true
|
||||
type: integer
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
items:
|
||||
$ref: '#/definitions/dto.UserCouponItem'
|
||||
type: array
|
||||
summary: List available coupons
|
||||
tags:
|
||||
- UserCenter
|
||||
/t/{tenantCode}/v1/me/coupons/receive:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: Receive a coupon by coupon_id
|
||||
parameters:
|
||||
- description: Receive form
|
||||
in: body
|
||||
name: form
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/dto.CouponReceiveForm'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/dto.UserCouponItem'
|
||||
summary: Receive coupon
|
||||
tags:
|
||||
- UserCenter
|
||||
/t/{tenantCode}/v1/me/favorites:
|
||||
get:
|
||||
consumes:
|
||||
|
||||
Reference in New Issue
Block a user