实现用户咨询数据收集接口
This commit is contained in:
16
.vscode/launch.json
vendored
16
.vscode/launch.json
vendored
@@ -1,16 +0,0 @@
|
|||||||
{
|
|
||||||
// 使用 IntelliSense 了解相关属性。
|
|
||||||
// 悬停以查看现有属性的描述。
|
|
||||||
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
|
|
||||||
"version": "0.2.0",
|
|
||||||
"configurations": [
|
|
||||||
{
|
|
||||||
"name": "main",
|
|
||||||
"type": "go",
|
|
||||||
"request": "launch",
|
|
||||||
"mode": "debug",
|
|
||||||
"program": "${workspaceFolder}/cmd/main",
|
|
||||||
"cwd": "${workspaceFolder}"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
13
.zed/debug.json
Normal file
13
.zed/debug.json
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
// Project-local debug tasks
|
||||||
|
//
|
||||||
|
// For more documentation on how to configure debug tasks,
|
||||||
|
// see: https://zed.dev/docs/debugger
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"label": "debug main",
|
||||||
|
"adapter": "Delve",
|
||||||
|
"request": "launch",
|
||||||
|
"mode": "debug",
|
||||||
|
"program": "./cmd/main"
|
||||||
|
}
|
||||||
|
]
|
||||||
18
README.md
18
README.md
@@ -1,19 +1,15 @@
|
|||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
|
价格与优惠
|
||||||
|
|
||||||
优化中间件,配置通用限速
|
优化中间件,配置通用限速
|
||||||
|
|
||||||
trade/create 性能问题,缩短事务时间,考虑其他方式实现可靠分布式事务
|
observe 部署,蓝狐部署
|
||||||
|
|
||||||
jsonb 类型转换问题,考虑一个高效的 any 到 struct 转换工具
|
|
||||||
|
|
||||||
端口资源池的 gc 实现
|
|
||||||
|
|
||||||
channel 服务代码结构,用 provider 代替整个 service 的复用
|
|
||||||
|
|
||||||
用反射实现环境变量解析,以简化函数签名
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
用反射实现环境变量解析,以简化函数签名
|
||||||
|
|
||||||
分离 task 的客户端,支持多进程(prefork 必要!)
|
分离 task 的客户端,支持多进程(prefork 必要!)
|
||||||
|
|
||||||
调整目录结构:
|
调整目录结构:
|
||||||
@@ -39,6 +35,10 @@ http 调用 clients 的初始化函数
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
数据库转模型文件
|
||||||
|
|
||||||
|
jsonb 类型转换问题,考虑一个高效的 any 到 struct 转换工具
|
||||||
|
|
||||||
慢速请求底层调用埋点监控
|
慢速请求底层调用埋点监控
|
||||||
- redis
|
- redis
|
||||||
- gorm
|
- gorm
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ func main() {
|
|||||||
m.User{},
|
m.User{},
|
||||||
m.UserRole{},
|
m.UserRole{},
|
||||||
m.Whitelist{},
|
m.Whitelist{},
|
||||||
|
m.Inquiry{},
|
||||||
)
|
)
|
||||||
g.Execute()
|
g.Execute()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,6 +108,76 @@ comment on column logs_user_bandwidth.time is '记录时间';
|
|||||||
|
|
||||||
-- endregion
|
-- endregion
|
||||||
|
|
||||||
|
-- ====================
|
||||||
|
-- region 系统信息
|
||||||
|
-- ====================
|
||||||
|
|
||||||
|
-- announcement
|
||||||
|
drop table if exists announcement cascade;
|
||||||
|
create table announcement (
|
||||||
|
id int generated by default as identity primary key,
|
||||||
|
title text not null,
|
||||||
|
content text,
|
||||||
|
type int not null default 1,
|
||||||
|
pin bool not null default false,
|
||||||
|
status int not null default 1,
|
||||||
|
sort int not null default 0,
|
||||||
|
created_at timestamptz default current_timestamp,
|
||||||
|
updated_at timestamptz default current_timestamp,
|
||||||
|
deleted_at timestamptz
|
||||||
|
);
|
||||||
|
create index idx_announcement_type on announcement (type) where deleted_at is null;
|
||||||
|
create index idx_announcement_pin on announcement (pin) where deleted_at is null;
|
||||||
|
create index idx_announcement_created_at on announcement (created_at) where deleted_at is null;
|
||||||
|
|
||||||
|
-- announcement表字段注释
|
||||||
|
comment on table announcement is '公告表';
|
||||||
|
comment on column announcement.id is '公告ID';
|
||||||
|
comment on column announcement.title is '公告标题';
|
||||||
|
comment on column announcement.content is '公告内容';
|
||||||
|
comment on column announcement.type is '公告类型:1-普通公告';
|
||||||
|
comment on column announcement.status is '公告状态:0-禁用,1-正常';
|
||||||
|
comment on column announcement.pin is '是否置顶';
|
||||||
|
comment on column announcement.sort is '公告排序';
|
||||||
|
comment on column announcement.created_at is '创建时间';
|
||||||
|
comment on column announcement.updated_at is '更新时间';
|
||||||
|
comment on column announcement.deleted_at is '删除时间';
|
||||||
|
|
||||||
|
-- inquiry
|
||||||
|
drop table if exists inquiry cascade;
|
||||||
|
create table inquiry (
|
||||||
|
id int generated by default as identity primary key,
|
||||||
|
company text,
|
||||||
|
name text,
|
||||||
|
phone text,
|
||||||
|
email text,
|
||||||
|
content text,
|
||||||
|
status int not null default 0,
|
||||||
|
remark text,
|
||||||
|
created_at timestamptz default current_timestamp,
|
||||||
|
updated_at timestamptz default current_timestamp,
|
||||||
|
deleted_at timestamptz
|
||||||
|
);
|
||||||
|
create index idx_inquiry_phone on inquiry (phone) where deleted_at is null;
|
||||||
|
create index idx_inquiry_status on inquiry (status) where deleted_at is null;
|
||||||
|
create index idx_inquiry_created_at on inquiry (created_at) where deleted_at is null;
|
||||||
|
|
||||||
|
-- inquiry表字段注释
|
||||||
|
comment on table inquiry is '用户咨询表';
|
||||||
|
comment on column inquiry.id is '咨询ID';
|
||||||
|
comment on column inquiry.name is '联系人姓名';
|
||||||
|
comment on column inquiry.phone is '联系电话';
|
||||||
|
comment on column inquiry.email is '联系邮箱';
|
||||||
|
comment on column inquiry.company is '公司名称';
|
||||||
|
comment on column inquiry.content is '咨询内容';
|
||||||
|
comment on column inquiry.status is '处理状态:0-待处理,1-已处理';
|
||||||
|
comment on column inquiry.remark is '备注';
|
||||||
|
comment on column inquiry.created_at is '创建时间';
|
||||||
|
comment on column inquiry.updated_at is '更新时间';
|
||||||
|
comment on column inquiry.deleted_at is '删除时间';
|
||||||
|
|
||||||
|
-- endregion
|
||||||
|
|
||||||
-- ====================
|
-- ====================
|
||||||
-- region 管理员信息
|
-- region 管理员信息
|
||||||
-- ====================
|
-- ====================
|
||||||
@@ -177,37 +247,6 @@ comment on column admin_role.created_at is '创建时间';
|
|||||||
comment on column admin_role.updated_at is '更新时间';
|
comment on column admin_role.updated_at is '更新时间';
|
||||||
comment on column admin_role.deleted_at is '删除时间';
|
comment on column admin_role.deleted_at is '删除时间';
|
||||||
|
|
||||||
-- announcement
|
|
||||||
drop table if exists announcement cascade;
|
|
||||||
create table announcement (
|
|
||||||
id int generated by default as identity primary key,
|
|
||||||
title text not null,
|
|
||||||
content text,
|
|
||||||
type int not null default 1,
|
|
||||||
pin bool not null default false,
|
|
||||||
status int not null default 1,
|
|
||||||
sort int not null default 0,
|
|
||||||
created_at timestamptz default current_timestamp,
|
|
||||||
updated_at timestamptz default current_timestamp,
|
|
||||||
deleted_at timestamptz
|
|
||||||
);
|
|
||||||
create index idx_announcement_type on announcement (type) where deleted_at is null;
|
|
||||||
create index idx_announcement_pin on announcement (pin) where deleted_at is null;
|
|
||||||
create index idx_announcement_created_at on announcement (created_at) where deleted_at is null;
|
|
||||||
|
|
||||||
-- announcement表字段注释
|
|
||||||
comment on table announcement is '公告表';
|
|
||||||
comment on column announcement.id is '公告ID';
|
|
||||||
comment on column announcement.title is '公告标题';
|
|
||||||
comment on column announcement.content is '公告内容';
|
|
||||||
comment on column announcement.type is '公告类型:1-普通公告';
|
|
||||||
comment on column announcement.status is '公告状态:0-禁用,1-正常';
|
|
||||||
comment on column announcement.pin is '是否置顶';
|
|
||||||
comment on column announcement.sort is '公告排序';
|
|
||||||
comment on column announcement.created_at is '创建时间';
|
|
||||||
comment on column announcement.updated_at is '更新时间';
|
|
||||||
comment on column announcement.deleted_at is '删除时间';
|
|
||||||
|
|
||||||
-- endregion
|
-- endregion
|
||||||
|
|
||||||
-- ====================
|
-- ====================
|
||||||
|
|||||||
48
web/handlers/inquiry.go
Normal file
48
web/handlers/inquiry.go
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"platform/pkg/u"
|
||||||
|
"platform/web/core"
|
||||||
|
g "platform/web/globals"
|
||||||
|
m "platform/web/models"
|
||||||
|
q "platform/web/queries"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// region CreateInquiry
|
||||||
|
|
||||||
|
type CreateInquiryRequest struct {
|
||||||
|
Company string `json:"company" validate:"omitempty,max=200"`
|
||||||
|
Name string `json:"name" validate:"required,max=100"`
|
||||||
|
Phone string `json:"phone" validate:"required,max=20"`
|
||||||
|
Email string `json:"email" validate:"omitempty,email,max=100"`
|
||||||
|
Content string `json:"content" validate:"required,max=1000"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateInquiry(c *fiber.Ctx) error {
|
||||||
|
|
||||||
|
// 解析请求参数
|
||||||
|
req := new(CreateInquiryRequest)
|
||||||
|
err := g.Validator.ParseBody(c, req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建咨询记录
|
||||||
|
err = q.Inquiry.Create(&m.Inquiry{
|
||||||
|
Company: u.X(req.Company),
|
||||||
|
Name: u.X(req.Name),
|
||||||
|
Phone: u.X(req.Phone),
|
||||||
|
Email: u.X(req.Email),
|
||||||
|
Content: u.X(req.Content),
|
||||||
|
Status: m.InquiryStatusPending,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return core.NewServErr("提交咨询失败", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.SendStatus(fiber.StatusNoContent)
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
@@ -439,7 +439,7 @@ func ResourcePrice(c *fiber.Ctx) error {
|
|||||||
// 解析请求参数
|
// 解析请求参数
|
||||||
var req = new(CreateResourceReq)
|
var req = new(CreateResourceReq)
|
||||||
if err := g.Validator.ParseBody(c, req); err != nil {
|
if err := g.Validator.ParseBody(c, req); err != nil {
|
||||||
return err
|
return core.NewBizErr("接口参数解析异常", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取套餐价格
|
// 获取套餐价格
|
||||||
|
|||||||
25
web/models/inquiry.go
Normal file
25
web/models/inquiry.go
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"platform/web/core"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Inquiry 用户咨询表
|
||||||
|
type Inquiry struct {
|
||||||
|
core.Model
|
||||||
|
Company *string `json:"company,omitempty" gorm:"column:company"` // 公司名称
|
||||||
|
Name *string `json:"name,omitempty" gorm:"column:name"` // 联系人姓名
|
||||||
|
Phone *string `json:"phone,omitempty" gorm:"column:phone"` // 联系电话
|
||||||
|
Email *string `json:"email,omitempty" gorm:"column:email"` // 联系邮箱
|
||||||
|
Content *string `json:"content,omitempty" gorm:"column:content"` // 咨询内容
|
||||||
|
Status InquiryStatus `json:"status" gorm:"column:status"` // 处理状态:0-待处理,1-已处理
|
||||||
|
Remark *string `json:"remark,omitempty" gorm:"column:remark"` // 备注
|
||||||
|
}
|
||||||
|
|
||||||
|
// InquiryStatus 咨询处理状态枚举
|
||||||
|
type InquiryStatus int
|
||||||
|
|
||||||
|
const (
|
||||||
|
InquiryStatusPending InquiryStatus = 0 // 待处理
|
||||||
|
InquiryStatusProcessed InquiryStatus = 1 // 已处理
|
||||||
|
)
|
||||||
@@ -25,6 +25,7 @@ var (
|
|||||||
Client *client
|
Client *client
|
||||||
Coupon *coupon
|
Coupon *coupon
|
||||||
Edge *edge
|
Edge *edge
|
||||||
|
Inquiry *inquiry
|
||||||
LinkAdminRole *linkAdminRole
|
LinkAdminRole *linkAdminRole
|
||||||
LinkAdminRolePermission *linkAdminRolePermission
|
LinkAdminRolePermission *linkAdminRolePermission
|
||||||
LinkClientPermission *linkClientPermission
|
LinkClientPermission *linkClientPermission
|
||||||
@@ -58,6 +59,7 @@ func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
|
|||||||
Client = &Q.Client
|
Client = &Q.Client
|
||||||
Coupon = &Q.Coupon
|
Coupon = &Q.Coupon
|
||||||
Edge = &Q.Edge
|
Edge = &Q.Edge
|
||||||
|
Inquiry = &Q.Inquiry
|
||||||
LinkAdminRole = &Q.LinkAdminRole
|
LinkAdminRole = &Q.LinkAdminRole
|
||||||
LinkAdminRolePermission = &Q.LinkAdminRolePermission
|
LinkAdminRolePermission = &Q.LinkAdminRolePermission
|
||||||
LinkClientPermission = &Q.LinkClientPermission
|
LinkClientPermission = &Q.LinkClientPermission
|
||||||
@@ -92,6 +94,7 @@ func Use(db *gorm.DB, opts ...gen.DOOption) *Query {
|
|||||||
Client: newClient(db, opts...),
|
Client: newClient(db, opts...),
|
||||||
Coupon: newCoupon(db, opts...),
|
Coupon: newCoupon(db, opts...),
|
||||||
Edge: newEdge(db, opts...),
|
Edge: newEdge(db, opts...),
|
||||||
|
Inquiry: newInquiry(db, opts...),
|
||||||
LinkAdminRole: newLinkAdminRole(db, opts...),
|
LinkAdminRole: newLinkAdminRole(db, opts...),
|
||||||
LinkAdminRolePermission: newLinkAdminRolePermission(db, opts...),
|
LinkAdminRolePermission: newLinkAdminRolePermission(db, opts...),
|
||||||
LinkClientPermission: newLinkClientPermission(db, opts...),
|
LinkClientPermission: newLinkClientPermission(db, opts...),
|
||||||
@@ -127,6 +130,7 @@ type Query struct {
|
|||||||
Client client
|
Client client
|
||||||
Coupon coupon
|
Coupon coupon
|
||||||
Edge edge
|
Edge edge
|
||||||
|
Inquiry inquiry
|
||||||
LinkAdminRole linkAdminRole
|
LinkAdminRole linkAdminRole
|
||||||
LinkAdminRolePermission linkAdminRolePermission
|
LinkAdminRolePermission linkAdminRolePermission
|
||||||
LinkClientPermission linkClientPermission
|
LinkClientPermission linkClientPermission
|
||||||
@@ -163,6 +167,7 @@ func (q *Query) clone(db *gorm.DB) *Query {
|
|||||||
Client: q.Client.clone(db),
|
Client: q.Client.clone(db),
|
||||||
Coupon: q.Coupon.clone(db),
|
Coupon: q.Coupon.clone(db),
|
||||||
Edge: q.Edge.clone(db),
|
Edge: q.Edge.clone(db),
|
||||||
|
Inquiry: q.Inquiry.clone(db),
|
||||||
LinkAdminRole: q.LinkAdminRole.clone(db),
|
LinkAdminRole: q.LinkAdminRole.clone(db),
|
||||||
LinkAdminRolePermission: q.LinkAdminRolePermission.clone(db),
|
LinkAdminRolePermission: q.LinkAdminRolePermission.clone(db),
|
||||||
LinkClientPermission: q.LinkClientPermission.clone(db),
|
LinkClientPermission: q.LinkClientPermission.clone(db),
|
||||||
@@ -206,6 +211,7 @@ func (q *Query) ReplaceDB(db *gorm.DB) *Query {
|
|||||||
Client: q.Client.replaceDB(db),
|
Client: q.Client.replaceDB(db),
|
||||||
Coupon: q.Coupon.replaceDB(db),
|
Coupon: q.Coupon.replaceDB(db),
|
||||||
Edge: q.Edge.replaceDB(db),
|
Edge: q.Edge.replaceDB(db),
|
||||||
|
Inquiry: q.Inquiry.replaceDB(db),
|
||||||
LinkAdminRole: q.LinkAdminRole.replaceDB(db),
|
LinkAdminRole: q.LinkAdminRole.replaceDB(db),
|
||||||
LinkAdminRolePermission: q.LinkAdminRolePermission.replaceDB(db),
|
LinkAdminRolePermission: q.LinkAdminRolePermission.replaceDB(db),
|
||||||
LinkClientPermission: q.LinkClientPermission.replaceDB(db),
|
LinkClientPermission: q.LinkClientPermission.replaceDB(db),
|
||||||
@@ -239,6 +245,7 @@ type queryCtx struct {
|
|||||||
Client *clientDo
|
Client *clientDo
|
||||||
Coupon *couponDo
|
Coupon *couponDo
|
||||||
Edge *edgeDo
|
Edge *edgeDo
|
||||||
|
Inquiry *inquiryDo
|
||||||
LinkAdminRole *linkAdminRoleDo
|
LinkAdminRole *linkAdminRoleDo
|
||||||
LinkAdminRolePermission *linkAdminRolePermissionDo
|
LinkAdminRolePermission *linkAdminRolePermissionDo
|
||||||
LinkClientPermission *linkClientPermissionDo
|
LinkClientPermission *linkClientPermissionDo
|
||||||
@@ -272,6 +279,7 @@ func (q *Query) WithContext(ctx context.Context) *queryCtx {
|
|||||||
Client: q.Client.WithContext(ctx),
|
Client: q.Client.WithContext(ctx),
|
||||||
Coupon: q.Coupon.WithContext(ctx),
|
Coupon: q.Coupon.WithContext(ctx),
|
||||||
Edge: q.Edge.WithContext(ctx),
|
Edge: q.Edge.WithContext(ctx),
|
||||||
|
Inquiry: q.Inquiry.WithContext(ctx),
|
||||||
LinkAdminRole: q.LinkAdminRole.WithContext(ctx),
|
LinkAdminRole: q.LinkAdminRole.WithContext(ctx),
|
||||||
LinkAdminRolePermission: q.LinkAdminRolePermission.WithContext(ctx),
|
LinkAdminRolePermission: q.LinkAdminRolePermission.WithContext(ctx),
|
||||||
LinkClientPermission: q.LinkClientPermission.WithContext(ctx),
|
LinkClientPermission: q.LinkClientPermission.WithContext(ctx),
|
||||||
|
|||||||
359
web/queries/inquiry.gen.go
Normal file
359
web/queries/inquiry.gen.go
Normal file
@@ -0,0 +1,359 @@
|
|||||||
|
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||||
|
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||||
|
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package queries
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"gorm.io/gorm/clause"
|
||||||
|
"gorm.io/gorm/schema"
|
||||||
|
|
||||||
|
"gorm.io/gen"
|
||||||
|
"gorm.io/gen/field"
|
||||||
|
|
||||||
|
"gorm.io/plugin/dbresolver"
|
||||||
|
|
||||||
|
"platform/web/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newInquiry(db *gorm.DB, opts ...gen.DOOption) inquiry {
|
||||||
|
_inquiry := inquiry{}
|
||||||
|
|
||||||
|
_inquiry.inquiryDo.UseDB(db, opts...)
|
||||||
|
_inquiry.inquiryDo.UseModel(&models.Inquiry{})
|
||||||
|
|
||||||
|
tableName := _inquiry.inquiryDo.TableName()
|
||||||
|
_inquiry.ALL = field.NewAsterisk(tableName)
|
||||||
|
_inquiry.ID = field.NewInt32(tableName, "id")
|
||||||
|
_inquiry.CreatedAt = field.NewTime(tableName, "created_at")
|
||||||
|
_inquiry.UpdatedAt = field.NewTime(tableName, "updated_at")
|
||||||
|
_inquiry.DeletedAt = field.NewField(tableName, "deleted_at")
|
||||||
|
_inquiry.Company = field.NewString(tableName, "company")
|
||||||
|
_inquiry.Name = field.NewString(tableName, "name")
|
||||||
|
_inquiry.Phone = field.NewString(tableName, "phone")
|
||||||
|
_inquiry.Email = field.NewString(tableName, "email")
|
||||||
|
_inquiry.Content = field.NewString(tableName, "content")
|
||||||
|
_inquiry.Status = field.NewInt(tableName, "status")
|
||||||
|
_inquiry.Remark = field.NewString(tableName, "remark")
|
||||||
|
|
||||||
|
_inquiry.fillFieldMap()
|
||||||
|
|
||||||
|
return _inquiry
|
||||||
|
}
|
||||||
|
|
||||||
|
type inquiry struct {
|
||||||
|
inquiryDo
|
||||||
|
|
||||||
|
ALL field.Asterisk
|
||||||
|
ID field.Int32
|
||||||
|
CreatedAt field.Time
|
||||||
|
UpdatedAt field.Time
|
||||||
|
DeletedAt field.Field
|
||||||
|
Company field.String
|
||||||
|
Name field.String
|
||||||
|
Phone field.String
|
||||||
|
Email field.String
|
||||||
|
Content field.String
|
||||||
|
Status field.Int
|
||||||
|
Remark field.String
|
||||||
|
|
||||||
|
fieldMap map[string]field.Expr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiry) Table(newTableName string) *inquiry {
|
||||||
|
i.inquiryDo.UseTable(newTableName)
|
||||||
|
return i.updateTableName(newTableName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiry) As(alias string) *inquiry {
|
||||||
|
i.inquiryDo.DO = *(i.inquiryDo.As(alias).(*gen.DO))
|
||||||
|
return i.updateTableName(alias)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *inquiry) updateTableName(table string) *inquiry {
|
||||||
|
i.ALL = field.NewAsterisk(table)
|
||||||
|
i.ID = field.NewInt32(table, "id")
|
||||||
|
i.CreatedAt = field.NewTime(table, "created_at")
|
||||||
|
i.UpdatedAt = field.NewTime(table, "updated_at")
|
||||||
|
i.DeletedAt = field.NewField(table, "deleted_at")
|
||||||
|
i.Company = field.NewString(table, "company")
|
||||||
|
i.Name = field.NewString(table, "name")
|
||||||
|
i.Phone = field.NewString(table, "phone")
|
||||||
|
i.Email = field.NewString(table, "email")
|
||||||
|
i.Content = field.NewString(table, "content")
|
||||||
|
i.Status = field.NewInt(table, "status")
|
||||||
|
i.Remark = field.NewString(table, "remark")
|
||||||
|
|
||||||
|
i.fillFieldMap()
|
||||||
|
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *inquiry) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||||
|
_f, ok := i.fieldMap[fieldName]
|
||||||
|
if !ok || _f == nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
_oe, ok := _f.(field.OrderExpr)
|
||||||
|
return _oe, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *inquiry) fillFieldMap() {
|
||||||
|
i.fieldMap = make(map[string]field.Expr, 11)
|
||||||
|
i.fieldMap["id"] = i.ID
|
||||||
|
i.fieldMap["created_at"] = i.CreatedAt
|
||||||
|
i.fieldMap["updated_at"] = i.UpdatedAt
|
||||||
|
i.fieldMap["deleted_at"] = i.DeletedAt
|
||||||
|
i.fieldMap["company"] = i.Company
|
||||||
|
i.fieldMap["name"] = i.Name
|
||||||
|
i.fieldMap["phone"] = i.Phone
|
||||||
|
i.fieldMap["email"] = i.Email
|
||||||
|
i.fieldMap["content"] = i.Content
|
||||||
|
i.fieldMap["status"] = i.Status
|
||||||
|
i.fieldMap["remark"] = i.Remark
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiry) clone(db *gorm.DB) inquiry {
|
||||||
|
i.inquiryDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiry) replaceDB(db *gorm.DB) inquiry {
|
||||||
|
i.inquiryDo.ReplaceDB(db)
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
|
type inquiryDo struct{ gen.DO }
|
||||||
|
|
||||||
|
func (i inquiryDo) Debug() *inquiryDo {
|
||||||
|
return i.withDO(i.DO.Debug())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) WithContext(ctx context.Context) *inquiryDo {
|
||||||
|
return i.withDO(i.DO.WithContext(ctx))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) ReadDB() *inquiryDo {
|
||||||
|
return i.Clauses(dbresolver.Read)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) WriteDB() *inquiryDo {
|
||||||
|
return i.Clauses(dbresolver.Write)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) Session(config *gorm.Session) *inquiryDo {
|
||||||
|
return i.withDO(i.DO.Session(config))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) Clauses(conds ...clause.Expression) *inquiryDo {
|
||||||
|
return i.withDO(i.DO.Clauses(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) Returning(value interface{}, columns ...string) *inquiryDo {
|
||||||
|
return i.withDO(i.DO.Returning(value, columns...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) Not(conds ...gen.Condition) *inquiryDo {
|
||||||
|
return i.withDO(i.DO.Not(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) Or(conds ...gen.Condition) *inquiryDo {
|
||||||
|
return i.withDO(i.DO.Or(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) Select(conds ...field.Expr) *inquiryDo {
|
||||||
|
return i.withDO(i.DO.Select(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) Where(conds ...gen.Condition) *inquiryDo {
|
||||||
|
return i.withDO(i.DO.Where(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) Order(conds ...field.Expr) *inquiryDo {
|
||||||
|
return i.withDO(i.DO.Order(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) Distinct(cols ...field.Expr) *inquiryDo {
|
||||||
|
return i.withDO(i.DO.Distinct(cols...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) Omit(cols ...field.Expr) *inquiryDo {
|
||||||
|
return i.withDO(i.DO.Omit(cols...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) Join(table schema.Tabler, on ...field.Expr) *inquiryDo {
|
||||||
|
return i.withDO(i.DO.Join(table, on...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) LeftJoin(table schema.Tabler, on ...field.Expr) *inquiryDo {
|
||||||
|
return i.withDO(i.DO.LeftJoin(table, on...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) RightJoin(table schema.Tabler, on ...field.Expr) *inquiryDo {
|
||||||
|
return i.withDO(i.DO.RightJoin(table, on...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) Group(cols ...field.Expr) *inquiryDo {
|
||||||
|
return i.withDO(i.DO.Group(cols...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) Having(conds ...gen.Condition) *inquiryDo {
|
||||||
|
return i.withDO(i.DO.Having(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) Limit(limit int) *inquiryDo {
|
||||||
|
return i.withDO(i.DO.Limit(limit))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) Offset(offset int) *inquiryDo {
|
||||||
|
return i.withDO(i.DO.Offset(offset))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *inquiryDo {
|
||||||
|
return i.withDO(i.DO.Scopes(funcs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) Unscoped() *inquiryDo {
|
||||||
|
return i.withDO(i.DO.Unscoped())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) Create(values ...*models.Inquiry) error {
|
||||||
|
if len(values) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return i.DO.Create(values)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) CreateInBatches(values []*models.Inquiry, batchSize int) error {
|
||||||
|
return i.DO.CreateInBatches(values, batchSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save : !!! underlying implementation is different with GORM
|
||||||
|
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
|
||||||
|
func (i inquiryDo) Save(values ...*models.Inquiry) error {
|
||||||
|
if len(values) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return i.DO.Save(values)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) First() (*models.Inquiry, error) {
|
||||||
|
if result, err := i.DO.First(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return result.(*models.Inquiry), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) Take() (*models.Inquiry, error) {
|
||||||
|
if result, err := i.DO.Take(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return result.(*models.Inquiry), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) Last() (*models.Inquiry, error) {
|
||||||
|
if result, err := i.DO.Last(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return result.(*models.Inquiry), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) Find() ([]*models.Inquiry, error) {
|
||||||
|
result, err := i.DO.Find()
|
||||||
|
return result.([]*models.Inquiry), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*models.Inquiry, err error) {
|
||||||
|
buf := make([]*models.Inquiry, 0, batchSize)
|
||||||
|
err = i.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
|
||||||
|
defer func() { results = append(results, buf...) }()
|
||||||
|
return fc(tx, batch)
|
||||||
|
})
|
||||||
|
return results, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) FindInBatches(result *[]*models.Inquiry, batchSize int, fc func(tx gen.Dao, batch int) error) error {
|
||||||
|
return i.DO.FindInBatches(result, batchSize, fc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) Attrs(attrs ...field.AssignExpr) *inquiryDo {
|
||||||
|
return i.withDO(i.DO.Attrs(attrs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) Assign(attrs ...field.AssignExpr) *inquiryDo {
|
||||||
|
return i.withDO(i.DO.Assign(attrs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) Joins(fields ...field.RelationField) *inquiryDo {
|
||||||
|
for _, _f := range fields {
|
||||||
|
i = *i.withDO(i.DO.Joins(_f))
|
||||||
|
}
|
||||||
|
return &i
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) Preload(fields ...field.RelationField) *inquiryDo {
|
||||||
|
for _, _f := range fields {
|
||||||
|
i = *i.withDO(i.DO.Preload(_f))
|
||||||
|
}
|
||||||
|
return &i
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) FirstOrInit() (*models.Inquiry, error) {
|
||||||
|
if result, err := i.DO.FirstOrInit(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return result.(*models.Inquiry), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) FirstOrCreate() (*models.Inquiry, error) {
|
||||||
|
if result, err := i.DO.FirstOrCreate(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return result.(*models.Inquiry), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) FindByPage(offset int, limit int) (result []*models.Inquiry, count int64, err error) {
|
||||||
|
result, err = i.Offset(offset).Limit(limit).Find()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if size := len(result); 0 < limit && 0 < size && size < limit {
|
||||||
|
count = int64(size + offset)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
count, err = i.Offset(-1).Limit(-1).Count()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
|
||||||
|
count, err = i.Count()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = i.Offset(offset).Limit(limit).Scan(result)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) Scan(result interface{}) (err error) {
|
||||||
|
return i.DO.Scan(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i inquiryDo) Delete(models ...*models.Inquiry) (result gen.ResultInfo, err error) {
|
||||||
|
return i.DO.Delete(models)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *inquiryDo) withDO(do gen.Dao) *inquiryDo {
|
||||||
|
i.DO = *do.(*gen.DO)
|
||||||
|
return i
|
||||||
|
}
|
||||||
@@ -73,6 +73,10 @@ func ApplyRouters(app *fiber.App) {
|
|||||||
edge.Post("/assign", handlers.AssignEdge)
|
edge.Post("/assign", handlers.AssignEdge)
|
||||||
edge.Post("/all", handlers.AllEdgesAvailable)
|
edge.Post("/all", handlers.AllEdgesAvailable)
|
||||||
|
|
||||||
|
// 其他系统接口
|
||||||
|
inquiry := api.Group("/inquiry")
|
||||||
|
inquiry.Post("/create", handlers.CreateInquiry)
|
||||||
|
|
||||||
// 回调
|
// 回调
|
||||||
callbacks := app.Group("/callback")
|
callbacks := app.Group("/callback")
|
||||||
callbacks.Get("/identify", handlers.IdentifyCallbackNew)
|
callbacks.Get("/identify", handlers.IdentifyCallbackNew)
|
||||||
|
|||||||
@@ -20,16 +20,16 @@ import (
|
|||||||
|
|
||||||
// 通道服务
|
// 通道服务
|
||||||
var Channel = &channelServer{
|
var Channel = &channelServer{
|
||||||
provider: &channelBaiyinService{},
|
provider: &channelBaiyinProvider{},
|
||||||
}
|
}
|
||||||
|
|
||||||
type ChanProviderAdapter interface {
|
type ChannelServiceProvider interface {
|
||||||
CreateChannels(source netip.Addr, resourceId int32, authWhitelist bool, authPassword bool, count int, edgeFilter ...EdgeFilter) ([]*m.Channel, error)
|
CreateChannels(source netip.Addr, resourceId int32, authWhitelist bool, authPassword bool, count int, edgeFilter ...EdgeFilter) ([]*m.Channel, error)
|
||||||
RemoveChannels(batch string) error
|
RemoveChannels(batch string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type channelServer struct {
|
type channelServer struct {
|
||||||
provider ChanProviderAdapter
|
provider ChannelServiceProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *channelServer) CreateChannels(source netip.Addr, resourceId int32, authWhitelist bool, authPassword bool, count int, edgeFilter ...EdgeFilter) ([]*m.Channel, error) {
|
func (s *channelServer) CreateChannels(source netip.Addr, resourceId int32, authWhitelist bool, authPassword bool, count int, edgeFilter ...EdgeFilter) ([]*m.Channel, error) {
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ import (
|
|||||||
"gorm.io/gen/field"
|
"gorm.io/gen/field"
|
||||||
)
|
)
|
||||||
|
|
||||||
type channelBaiyinService struct{}
|
type channelBaiyinProvider struct{}
|
||||||
|
|
||||||
func (s *channelBaiyinService) CreateChannels(source netip.Addr, resourceId int32, authWhitelist bool, authPassword bool, count int, edgeFilter ...EdgeFilter) ([]*m.Channel, error) {
|
func (s *channelBaiyinProvider) CreateChannels(source netip.Addr, resourceId int32, authWhitelist bool, authPassword bool, count int, edgeFilter ...EdgeFilter) ([]*m.Channel, error) {
|
||||||
var filter *EdgeFilter = nil
|
var filter *EdgeFilter = nil
|
||||||
if len(edgeFilter) > 0 {
|
if len(edgeFilter) > 0 {
|
||||||
filter = &edgeFilter[0]
|
filter = &edgeFilter[0]
|
||||||
@@ -256,7 +256,7 @@ func (s *channelBaiyinService) CreateChannels(source netip.Addr, resourceId int3
|
|||||||
return channels, nil
|
return channels, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *channelBaiyinService) RemoveChannels(batch string) error {
|
func (s *channelBaiyinProvider) RemoveChannels(batch string) error {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
// 获取连接数据
|
// 获取连接数据
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"platform/pkg/u"
|
"platform/pkg/u"
|
||||||
"platform/web/core"
|
"platform/web/core"
|
||||||
g "platform/web/globals"
|
|
||||||
m "platform/web/models"
|
m "platform/web/models"
|
||||||
q "platform/web/queries"
|
q "platform/web/queries"
|
||||||
"time"
|
"time"
|
||||||
@@ -19,8 +18,7 @@ var Resource = &resourceService{}
|
|||||||
type resourceService struct{}
|
type resourceService struct{}
|
||||||
|
|
||||||
func (s *resourceService) CreateResourceByBalance(uid int32, now time.Time, data *CreateResourceData) error {
|
func (s *resourceService) CreateResourceByBalance(uid int32, now time.Time, data *CreateResourceData) error {
|
||||||
return g.Redsync.WithLock(userBalanceKey(uid), func() error {
|
|
||||||
return q.Q.Transaction(func(q *q.Query) error {
|
|
||||||
// 找到用户
|
// 找到用户
|
||||||
user, err := q.User.
|
user, err := q.User.
|
||||||
Where(q.User.ID.Eq(uid)).
|
Where(q.User.ID.Eq(uid)).
|
||||||
@@ -34,15 +32,20 @@ func (s *resourceService) CreateResourceByBalance(uid int32, now time.Time, data
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
balance := user.Balance.Sub(amount)
|
newBalance := user.Balance.Sub(amount)
|
||||||
if balance.IsNegative() {
|
if newBalance.IsNegative() {
|
||||||
return ErrBalanceNotEnough
|
return ErrBalanceNotEnough
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return q.Q.Transaction(func(q *q.Query) error {
|
||||||
|
|
||||||
// 更新用户余额
|
// 更新用户余额
|
||||||
_, err = q.User.
|
_, err = q.User.
|
||||||
Where(q.User.ID.Eq(uid), q.User.Balance.Eq(user.Balance)).
|
Where(
|
||||||
UpdateSimple(q.User.Balance.Value(balance))
|
q.User.ID.Eq(uid),
|
||||||
|
q.User.Balance.Eq(user.Balance),
|
||||||
|
).
|
||||||
|
UpdateSimple(q.User.Balance.Value(newBalance))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return core.NewServErr("更新用户余额失败", err)
|
return core.NewServErr("更新用户余额失败", err)
|
||||||
}
|
}
|
||||||
@@ -65,12 +68,9 @@ func (s *resourceService) CreateResourceByBalance(uid int32, now time.Time, data
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *resourceService) CreateResourceByTrade(uid int32, now time.Time, data *CreateResourceData, trade *m.Trade) error {
|
func (s *resourceService) CreateResourceByTrade(uid int32, now time.Time, data *CreateResourceData, trade *m.Trade) error { // 检查交易
|
||||||
return q.Q.Transaction(func(q *q.Query) error {
|
|
||||||
// 检查交易
|
|
||||||
if trade == nil {
|
if trade == nil {
|
||||||
return core.NewBizErr("交易数据不能为空")
|
return core.NewBizErr("交易数据不能为空")
|
||||||
}
|
}
|
||||||
@@ -78,6 +78,8 @@ func (s *resourceService) CreateResourceByTrade(uid int32, now time.Time, data *
|
|||||||
return core.NewBizErr("交易状态不正确")
|
return core.NewBizErr("交易状态不正确")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return q.Q.Transaction(func(q *q.Query) error {
|
||||||
|
|
||||||
// 保存套餐
|
// 保存套餐
|
||||||
resource, err := createResource(q, uid, now, data)
|
resource, err := createResource(q, uid, now, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -171,7 +173,7 @@ type CreateResourceData struct {
|
|||||||
type CreateShortResourceData struct {
|
type CreateShortResourceData struct {
|
||||||
Live int32 `json:"live" validate:"required,min=180"`
|
Live int32 `json:"live" validate:"required,min=180"`
|
||||||
Mode m.ResourceMode `json:"mode" validate:"required"`
|
Mode m.ResourceMode `json:"mode" validate:"required"`
|
||||||
Quota int32 `json:"quota"`
|
Quota int32 `json:"quota" validate:"required"`
|
||||||
Expire *int32 `json:"expire"`
|
Expire *int32 `json:"expire"`
|
||||||
|
|
||||||
name string
|
name string
|
||||||
@@ -182,7 +184,7 @@ type CreateLongResourceData struct {
|
|||||||
Live int32 `json:"live" validate:"required"`
|
Live int32 `json:"live" validate:"required"`
|
||||||
Mode m.ResourceMode `json:"mode" validate:"required"`
|
Mode m.ResourceMode `json:"mode" validate:"required"`
|
||||||
Quota int32 `json:"quota" validate:"required"`
|
Quota int32 `json:"quota" validate:"required"`
|
||||||
Expire *int32 `json:"expire" validate:"required"`
|
Expire *int32 `json:"expire"`
|
||||||
|
|
||||||
name string
|
name string
|
||||||
price *decimal.Decimal
|
price *decimal.Decimal
|
||||||
@@ -193,25 +195,25 @@ func (c *CreateResourceData) GetType() m.TradeType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *CreateResourceData) GetSubject() (string, error) {
|
func (c *CreateResourceData) GetSubject() (string, error) {
|
||||||
switch c.Type {
|
switch {
|
||||||
default:
|
default:
|
||||||
return "", errors.New("无效的套餐类型")
|
return "", errors.New("无效的套餐类型")
|
||||||
|
|
||||||
case m.ResourceTypeShort:
|
case c.Type == m.ResourceTypeShort && c.Short != nil:
|
||||||
return c.Short.GetSubject()
|
return c.Short.GetSubject()
|
||||||
case m.ResourceTypeLong:
|
case c.Type == m.ResourceTypeLong && c.Long != nil:
|
||||||
return c.Long.GetSubject()
|
return c.Long.GetSubject()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CreateResourceData) GetAmount() (decimal.Decimal, error) {
|
func (c *CreateResourceData) GetAmount() (decimal.Decimal, error) {
|
||||||
switch c.Type {
|
switch {
|
||||||
default:
|
default:
|
||||||
return decimal.Zero, errors.New("无效的套餐类型")
|
return decimal.Zero, errors.New("无效的套餐类型")
|
||||||
|
|
||||||
case m.ResourceTypeShort:
|
case c.Type == m.ResourceTypeShort && c.Short != nil:
|
||||||
return c.Short.GetAmount()
|
return c.Short.GetAmount()
|
||||||
case m.ResourceTypeLong:
|
case c.Type == m.ResourceTypeLong && c.Long != nil:
|
||||||
return c.Long.GetAmount()
|
return c.Long.GetAmount()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -339,6 +341,7 @@ func (data *CreateLongResourceData) GetAmount() (decimal.Decimal, error) {
|
|||||||
return *data.price, nil
|
return *data.price, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 交易后创建套餐
|
||||||
type ResourceOnTradeComplete struct{}
|
type ResourceOnTradeComplete struct{}
|
||||||
|
|
||||||
func (r ResourceOnTradeComplete) Check(t m.TradeType) (ProductInfo, bool) {
|
func (r ResourceOnTradeComplete) Check(t m.TradeType) (ProductInfo, bool) {
|
||||||
@@ -352,6 +355,7 @@ func (r ResourceOnTradeComplete) OnTradeComplete(info ProductInfo, trade *m.Trad
|
|||||||
return Resource.CreateResourceByTrade(trade.UserID, time.Time(*trade.CompletedAt), info.(*CreateResourceData), trade)
|
return Resource.CreateResourceByTrade(trade.UserID, time.Time(*trade.CompletedAt), info.(*CreateResourceData), trade)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 服务错误
|
||||||
type ResourceServiceErr string
|
type ResourceServiceErr string
|
||||||
|
|
||||||
func (e ResourceServiceErr) Error() string {
|
func (e ResourceServiceErr) Error() string {
|
||||||
|
|||||||
Reference in New Issue
Block a user