Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop

This commit is contained in:
momo 2023-08-31 11:56:18 +08:00
commit 8fbab52044
25 changed files with 279 additions and 103 deletions

View File

@ -24,8 +24,9 @@ const (
// websocket消息类型(云渲染类别) // websocket消息类型(云渲染类别)
const ( const (
WEBSOCKET_RENDER_IMAGE Websocket = "WEBSOCKET_RENDER_IMAGE" //图片渲染消息(1级消息双向通信) WEBSOCKET_RENDER_IMAGE Websocket = "WEBSOCKET_RENDER_IMAGE" //图片渲染消息(1级消息双向通信)
WEBSOCKET_RENDER_IMAGE_ERR Websocket = "WEBSOCKET_RENDER_IMAGE_ERR" //图片渲染失败消息1级消息单向通信 WEBSOCKET_RENDER_IMAGE_ERR Websocket = "WEBSOCKET_RENDER_IMAGE_ERR" //图片渲染失败消息1级消息单向通信
WEBSOCKET_COMBINE_IMAGE Websocket = "WEBSOCKET_COMBINE_IMAGE" //反回合成刀版图消息2级消息单向通信属于 WEBSOCKET_RENDER_IMAGE 消息的子流程) WEBSOCKET_COMBINE_IMAGE Websocket = "WEBSOCKET_COMBINE_IMAGE" //反回合成刀版图消息2级消息单向通信属于 WEBSOCKET_RENDER_IMAGE 消息的子流程)
WEBSOCKET_SEND_DATA_TO_UNITY Websocket = "WEBSOCKET_SEND_DATA_TO_UNITY" //发送到unity进行渲染 WEBSOCKET_ASSEMBLE_RENDER_DATA Websocket = "WEBSOCKET_ASSEMBLE_RENDER_DATA" //组装unity需要的数据 2级消息单向通信属于 WEBSOCKET_RENDER_IMAGE 消息的子流程)
WEBSOCKET_SEND_DATA_TO_UNITY Websocket = "WEBSOCKET_SEND_DATA_TO_UNITY" //发送到unity进行渲染 2级消息单向通信属于 WEBSOCKET_RENDER_IMAGE 消息的子流程)
) )

1
go.mod
View File

@ -28,7 +28,6 @@ require (
require ( require (
cloud.google.com/go/compute v1.20.1 // indirect cloud.google.com/go/compute v1.20.1 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect
github.com/474420502/execute v0.2.2 // indirect
github.com/DataDog/zstd v1.4.5 // indirect github.com/DataDog/zstd v1.4.5 // indirect
github.com/HdrHistogram/hdrhistogram-go v1.1.2 // indirect github.com/HdrHistogram/hdrhistogram-go v1.1.2 // indirect
github.com/VictoriaMetrics/metrics v1.18.1 // indirect github.com/VictoriaMetrics/metrics v1.18.1 // indirect

2
go.sum
View File

@ -35,8 +35,6 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/474420502/execute v0.2.2 h1:Hzzb/HFa/urRvi3xWe+p/DnJgRyxXFVyEBEXbbITy/E=
github.com/474420502/execute v0.2.2/go.mod h1:wkKeKBIXYp7T844eU1YS2nPvFj8lra4VRcQYnWyXej4=
github.com/474420502/passer v0.0.1 h1:ZWnt7hpFzsYDV7LHSEyLvLUvW5mRxrnDmgFdIl17q3w= github.com/474420502/passer v0.0.1 h1:ZWnt7hpFzsYDV7LHSEyLvLUvW5mRxrnDmgFdIl17q3w=
github.com/474420502/passer v0.0.1/go.mod h1:MmnnrF9d51sPkFzdRq2pQtxQKqyjburVM1LjMbOCezE= github.com/474420502/passer v0.0.1/go.mod h1:MmnnrF9d51sPkFzdRq2pQtxQKqyjburVM1LjMbOCezE=
github.com/474420502/random v0.4.1 h1:HUUyLXRWMijVb7CJoEC16f0aFQOW25Lkr80Mut6PoKU= github.com/474420502/random v0.4.1 h1:HUUyLXRWMijVb7CJoEC16f0aFQOW25Lkr80Mut6PoKU=

View File

@ -0,0 +1,33 @@
package gmodel
import (
"gorm.io/gorm"
"time"
)
// fs_admin_role 后台--角色表
type FsAdminRole struct {
Id int64 `gorm:"primary_key;default:0;" json:"id"` // 序号
RolePid *int64 `gorm:"default:0;" json:"role_pid"` // 上级角色
RoleName *string `gorm:"default:'';" json:"role_name"` //
DataAuthType *int64 `gorm:"default:1;" json:"data_auth_type"` // 数据权限类型
DataAuth *string `gorm:"default:'';" json:"data_auth"` //
Status *int64 `gorm:"default:2;" json:"status"` // 状态:1=启用,2=停用
Remark *string `gorm:"default:'';" json:"remark"` //
Sort *int64 `gorm:"default:0;" json:"sort"` // 排序权重
CreateTime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"create_time"` //
UpdateTime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"update_time"` //
DeleteTime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"delete_time"` //
CreateUid *int64 `gorm:"default:0;" json:"create_uid"` // 创建人
UpdateUid *int64 `gorm:"default:0;" json:"update_uid"` // 更新人
DeleteUid *int64 `gorm:"default:0;" json:"delete_uid"` // 删除人
IsDel *int64 `gorm:"default:0;" json:"is_del"` // 是否删除1=是 0=否
}
type FsAdminRoleModel struct {
db *gorm.DB
name string
}
func NewFsAdminRoleModel(db *gorm.DB) *FsAdminRoleModel {
return &FsAdminRoleModel{db: db, name: "fs_admin_role"}
}

View File

@ -0,0 +1,2 @@
package gmodel
// TODO: 使用model的属性做你想做的

View File

@ -0,0 +1,44 @@
package gmodel
import (
"gorm.io/gorm"
"time"
)
// fs_admin_user 后台--管理员表
type FsAdminUser struct {
Id int64 `gorm:"primary_key;default:0;" json:"id"` // 序号
DepartmentId *int64 `gorm:"default:0;" json:"department_id"` // 部门
RoleId *int64 `gorm:"default:0;" json:"role_id"` // 角色
EmployeeId *int64 `gorm:"default:0;" json:"employee_id"` // 员工
Type *int64 `gorm:"default:0;" json:"type"` // 类型1=超级管理员2=普通管理员
Account *string `gorm:"default:'';" json:"account"` //
Password *string `gorm:"default:'';" json:"password"` //
Nickname *string `gorm:"default:'';" json:"nickname"` //
Mobile *string `gorm:"default:'';" json:"mobile"` //
Email *string `gorm:"default:'';" json:"email"` //
Salt *string `gorm:"default:'';" json:"salt"` //
LoginInitPassword *string `gorm:"default:'';" json:"login_init_password"` //
LoginLastTime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"login_last_time"` //
LoginLastIp *string `gorm:"default:'';" json:"login_last_ip"` //
LoginNum *int64 `gorm:"default:0;" json:"login_num"` // 登录次数
Status *int64 `gorm:"default:2;" json:"status"` // 状态:1=启用,2=停用
Remark *string `gorm:"default:'';" json:"remark"` //
Sort *int64 `gorm:"default:0;" json:"sort"` // 排序权重
CreateTime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"create_time"` //
UpdateTime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"update_time"` //
DeleteTime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"delete_time"` //
CreateUid *int64 `gorm:"default:0;" json:"create_uid"` // 创建人
UpdateUid *int64 `gorm:"default:0;" json:"update_uid"` // 更新人
DeleteUid *int64 `gorm:"default:0;" json:"delete_uid"` // 删除人
IsDel *int64 `gorm:"default:0;" json:"is_del"` // 是否删除1=是 0=否
RoleIds *string `gorm:"default:'';" json:"role_ids"` //
}
type FsAdminUserModel struct {
db *gorm.DB
name string
}
func NewFsAdminUserModel(db *gorm.DB) *FsAdminUserModel {
return &FsAdminUserModel{db: db, name: "fs_admin_user"}
}

View File

@ -0,0 +1,2 @@
package gmodel
// TODO: 使用model的属性做你想做的

View File

@ -22,7 +22,7 @@ type FsProduct struct {
SizeIds *string `gorm:"default:'';" json:"size_ids"` // 尺寸 1,2,3,4 SizeIds *string `gorm:"default:'';" json:"size_ids"` // 尺寸 1,2,3,4
MaterialIds *string `gorm:"default:'';" json:"material_ids"` // 材质 1,2,3 MaterialIds *string `gorm:"default:'';" json:"material_ids"` // 材质 1,2,3
TagIds *string `gorm:"default:'';" json:"tag_ids"` // 标签 逗号间隔 TagIds *string `gorm:"default:'';" json:"tag_ids"` // 标签 逗号间隔
Status *int64 `gorm:"default:0;" json:"status"` // 状态位 弃用 Status *int64 `gorm:"default:1;" json:"status"` // 状态位 弃用
ProduceDays *int64 `gorm:"default:0;" json:"produce_days"` // 生产天数 ProduceDays *int64 `gorm:"default:0;" json:"produce_days"` // 生产天数
DeliveryDays *int64 `gorm:"default:0;" json:"delivery_days"` // 运送天数 DeliveryDays *int64 `gorm:"default:0;" json:"delivery_days"` // 运送天数
CoverImg *string `gorm:"default:'';" json:"cover_img"` // 背景图 CoverImg *string `gorm:"default:'';" json:"cover_img"` // 背景图

View File

@ -18,7 +18,7 @@ type FsProductModel3d struct {
Light *int64 `gorm:"default:0;" json:"light"` // 灯光组 Light *int64 `gorm:"default:0;" json:"light"` // 灯光组
LightList *string `gorm:"default:'';" json:"light_list"` // 灯光备选项 LightList *string `gorm:"default:'';" json:"light_list"` // 灯光备选项
PartId *int64 `gorm:"default:0;" json:"part_id"` // 配件选项id配件就是模型的id PartId *int64 `gorm:"default:0;" json:"part_id"` // 配件选项id配件就是模型的id
PartList *string `gorm:"default:'';" json:"part_list"` // 配件备选项 PartList *string `gorm:"default:'';" json:"part_list"` //
Status *int64 `gorm:"default:0;" json:"status"` // 状态位 显示 删除 Status *int64 `gorm:"default:0;" json:"status"` // 状态位 显示 删除
Ctime *int64 `gorm:"default:0;" json:"ctime"` // 添加时间 Ctime *int64 `gorm:"default:0;" json:"ctime"` // 添加时间
OptionTemplate *int64 `gorm:"default:0;" json:"option_template"` // 配件绑定的公共模板 OptionTemplate *int64 `gorm:"default:0;" json:"option_template"` // 配件绑定的公共模板

View File

@ -7,9 +7,10 @@ import (
// fs_product_template_tags 模板标签表 // fs_product_template_tags 模板标签表
type FsProductTemplateTags struct { type FsProductTemplateTags struct {
Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` // ID Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` // ID
TemplateTag *string `gorm:"unique_key;default:'';" json:"template_tag"` // 标题 TemplateTag *string `gorm:"unique_key;default:'';" json:"template_tag"` //
Cover *string `gorm:"default:'';" json:"cover"` // 缩略图 Cover *string `gorm:"default:'';" json:"cover"` // 缩略图
Status *int64 `gorm:"default:0;" json:"status"` // 状态 1可用 Status *int64 `gorm:"default:0;" json:"status"` // 状态 1可用
IsHide *int64 `gorm:"default:0;" json:"is_hide"` // 是否隐藏
CreateAt *int64 `gorm:"default:0;" json:"create_at"` // 创建时间 CreateAt *int64 `gorm:"default:0;" json:"create_at"` // 创建时间
Groups *string `gorm:"default:'';" json:"groups"` // 分组信息 Groups *string `gorm:"default:'';" json:"groups"` // 分组信息
} }

View File

@ -23,8 +23,8 @@ func (pt *FsProductTemplateTagsModel) FindOne(ctx context.Context, id int64, fie
err = db.Take(&resp).Error err = db.Take(&resp).Error
return resp, err return resp, err
} }
func (pt *FsProductTemplateTagsModel) GetList(ctx context.Context, page, limit int, orderBy string) (resp []FsProductTemplateTags, err error) { func (pt *FsProductTemplateTagsModel) GetList(ctx context.Context, page, limit int, isHide, status int64, orderBy string) (resp []FsProductTemplateTags, err error) {
db := pt.db.WithContext(ctx).Model(&FsProductTemplateTags{}).Where("`status` = ?", 1) db := pt.db.WithContext(ctx).Model(&FsProductTemplateTags{}).Where("`is_hide` = ? and `status` = ?", isHide, status)
if orderBy != "" { if orderBy != "" {
db = db.Order(orderBy) db = db.Order(orderBy)
} }
@ -32,11 +32,11 @@ func (pt *FsProductTemplateTagsModel) GetList(ctx context.Context, page, limit i
err = db.Offset(offset).Limit(limit).Find(&resp).Error err = db.Offset(offset).Limit(limit).Find(&resp).Error
return resp, err return resp, err
} }
func (pt *FsProductTemplateTagsModel) GetListByTagNames(ctx context.Context, tagNames []string, limit int, orderBy string) (resp []FsProductTemplateTags, err error) { func (pt *FsProductTemplateTagsModel) GetListByTagNames(ctx context.Context, tagNames []string, limit int, isHide, status int64, orderBy string) (resp []FsProductTemplateTags, err error) {
if len(tagNames) == 0 { if len(tagNames) == 0 {
return nil, nil return nil, nil
} }
db := pt.db.WithContext(ctx).Model(&FsProductTemplateTags{}).Where("`template_tag` in (?) and `status` = ?", tagNames, 1) db := pt.db.WithContext(ctx).Model(&FsProductTemplateTags{}).Where("`template_tag` in (?) and `is_hide` = ? and `status` = ?", tagNames, isHide, status)
if orderBy != "" { if orderBy != "" {
db = db.Order(orderBy) db = db.Order(orderBy)
} }

View File

@ -117,7 +117,7 @@ func (t *FsProductTemplateV2Model) GetProductTemplateListByParams(ctx context.Co
func (t *FsProductTemplateV2Model) FindFirstOneCloudRenderByProductIdModelIdTemplateTag(ctx context.Context, productId, modelId int64, templateTag string) (resp *FsProductTemplateV2, err error) { func (t *FsProductTemplateV2Model) FindFirstOneCloudRenderByProductIdModelIdTemplateTag(ctx context.Context, productId, modelId int64, templateTag string) (resp *FsProductTemplateV2, err error) {
err = t.db.WithContext(ctx).Model(&FsProductTemplateV2{}). err = t.db.WithContext(ctx).Model(&FsProductTemplateV2{}).
Where("product_id = ? and model_id = ? and template_tag = ? ", productId, modelId, templateTag). Where("product_id = ? and model_id = ? and template_tag = ? ", productId, modelId, templateTag).
Where("status = ? and is_del = ? and element_model_id != ?", 1, 0, 0). Where("status = ? and is_del = ?", 1, 0).
Order("sort ASC"). Order("sort ASC").
Take(&resp).Error Take(&resp).Error
return resp, err return resp, err

View File

@ -15,7 +15,7 @@ type FsResource struct {
Version *string `gorm:"index;default:'0';" json:"version"` // 版本信息 Version *string `gorm:"index;default:'0';" json:"version"` // 版本信息
UploadedAt *time.Time `gorm:"index;default:'0000-00-00 00:00:00';" json:"uploaded_at"` // UploadedAt *time.Time `gorm:"index;default:'0000-00-00 00:00:00';" json:"uploaded_at"` //
Metadata *string `gorm:"default:'';" json:"metadata"` // 元数据,json格式,存储图像分率 Metadata *string `gorm:"default:'';" json:"metadata"` // 元数据,json格式,存储图像分率
MetaKey1 *string `gorm:"index;default:'';" json:"meta_key1"` // 需要关键信息查询的自定义属性1,可以动态增加 MetaKey1 *string `gorm:"default:'';" json:"meta_key1"` // 需要关键信息查询的自定义属性1,可以动态增加
ApiType *int64 `gorm:"default:1;" json:"api_type"` // 调用类型1=对外2=对内 ApiType *int64 `gorm:"default:1;" json:"api_type"` // 调用类型1=对外2=对内
BucketName *string `gorm:"default:'';" json:"bucket_name"` // 存储桶名: 1=持久 2=缓存 BucketName *string `gorm:"default:'';" json:"bucket_name"` // 存储桶名: 1=持久 2=缓存
Source *string `gorm:"default:'';" json:"source"` // 来源 Source *string `gorm:"default:'';" json:"source"` // 来源

View File

@ -6,32 +6,32 @@ import (
// fs_user 用户表 // fs_user 用户表
type FsUser struct { type FsUser struct {
Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` // ID Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` // ID
FaceId *int64 `gorm:"default:0;" json:"face_id"` // facebook的userid FaceId *int64 `gorm:"default:0;" json:"face_id"` // facebook的userid
GoogleId *int64 `gorm:"default:0;" json:"google_id"` // google的sub GoogleId *int64 `gorm:"default:0;" json:"google_id"` // google的sub
FirstName *string `gorm:"default:'';" json:"first_name"` // FirstName FirstName *string `gorm:"default:'';" json:"first_name"` // FirstName
LastName *string `gorm:"default:'';" json:"last_name"` // LastName LastName *string `gorm:"default:'';" json:"last_name"` // LastName
Username *string `gorm:"unique_key;default:'';" json:"username"` // Username *string `gorm:"index;default:'';" json:"username"` //
Company *string `gorm:"default:'';" json:"company"` // 公司名称 Company *string `gorm:"default:'';" json:"company"` // 公司名称
Mobile *string `gorm:"default:'';" json:"mobile"` // 手机号码 Mobile *string `gorm:"default:'';" json:"mobile"` // 手机号码
AuthKey *string `gorm:"default:'';" json:"auth_key"` // AuthKey *string `gorm:"default:'';" json:"auth_key"` //
PasswordHash *string `gorm:"default:'';" json:"password_hash"` // PasswordHash *string `gorm:"default:'';" json:"password_hash"` //
VerificationToken *string `gorm:"default:'';" json:"verification_token"` // VerificationToken *string `gorm:"default:'';" json:"verification_token"` //
PasswordResetToken *string `gorm:"unique_key;default:'';" json:"password_reset_token"` // PasswordResetToken *string `gorm:"default:'';" json:"password_reset_token"` //
Email *string `gorm:"unique_key;default:'';" json:"email"` // 邮箱 Email *string `gorm:"unique_key;default:'';" json:"email"` // 邮箱
Type *int64 `gorm:"default:0;" json:"type"` // 1普通餐厅 2连锁餐厅 Type *int64 `gorm:"default:0;" json:"type"` // 1普通餐厅 2连锁餐厅
Status *int64 `gorm:"default:1;" json:"status"` // 1正常 0不正常 Status *int64 `gorm:"default:1;" json:"status"` // 1正常 0不正常
IsDel *int64 `gorm:"default:0;" json:"is_del"` // 是否删除 1删除 IsDel *int64 `gorm:"default:0;" json:"is_del"` // 是否删除 1删除
CreatedAt *int64 `gorm:"default:0;" json:"created_at"` // 添加时间 CreatedAt *int64 `gorm:"default:0;" json:"created_at"` // 添加时间
UpdatedAt *int64 `gorm:"default:0;" json:"updated_at"` // 更新时间 UpdatedAt *int64 `gorm:"default:0;" json:"updated_at"` // 更新时间
IsOrderStatusEmail *int64 `gorm:"default:0;" json:"is_order_status_email"` // 订单状态改变时是否接收邮件 IsOrderStatusEmail *int64 `gorm:"default:0;" json:"is_order_status_email"` // 订单状态改变时是否接收邮件
IsEmailAdvertisement *int64 `gorm:"default:0;" json:"is_email_advertisement"` // 是否接收邮件广告 IsEmailAdvertisement *int64 `gorm:"default:0;" json:"is_email_advertisement"` // 是否接收邮件广告
IsOrderStatusPhone *int64 `gorm:"default:0;" json:"is_order_status_phone"` // 订单状态改变是是否接收电话 IsOrderStatusPhone *int64 `gorm:"default:0;" json:"is_order_status_phone"` // 订单状态改变是是否接收电话
IsPhoneAdvertisement *int64 `gorm:"default:0;" json:"is_phone_advertisement"` // 是否接收短信广告 IsPhoneAdvertisement *int64 `gorm:"default:0;" json:"is_phone_advertisement"` // 是否接收短信广告
IsOpenRender *int64 `gorm:"default:0;" json:"is_open_render"` // 是否打开个性化渲染1开启0关闭 IsOpenRender *int64 `gorm:"default:0;" json:"is_open_render"` // 是否打开个性化渲染1开启0关闭
IsThousandFace *int64 `gorm:"default:0;" json:"is_thousand_face"` // 是否已经存在千人千面1存在0不存在 IsThousandFace *int64 `gorm:"default:0;" json:"is_thousand_face"` // 是否已经存在千人千面1存在0不存在
IsLowRendering *int64 `gorm:"default:0;" json:"is_low_rendering"` // IsLowRendering *int64 `gorm:"default:0;" json:"is_low_rendering"` //
IsRemoveBg *int64 `gorm:"default:1;" json:"is_remove_bg"` // 用户上传logo是否去除背景 IsRemoveBg *int64 `gorm:"default:1;" json:"is_remove_bg"` // 用户上传logo是否去除背景
} }
type FsUserModel struct { type FsUserModel struct {
db *gorm.DB db *gorm.DB

View File

@ -272,7 +272,7 @@ func (u *FsUserModel) DebugAuthDelete(ctx context.Context, email string) (err er
} }
} }
return nil return err
}) })
return err return err

View File

@ -9,6 +9,8 @@ type AllModelsGen struct {
FsAdminAuthRole *FsAdminAuthRoleModel // fs_admin_auth_role 后台--角色表 FsAdminAuthRole *FsAdminAuthRoleModel // fs_admin_auth_role 后台--角色表
FsAdminDepartment *FsAdminDepartmentModel // fs_admin_department 后台--部门表 FsAdminDepartment *FsAdminDepartmentModel // fs_admin_department 后台--部门表
FsAdminMenu *FsAdminMenuModel // fs_admin_menu 后台--菜单表 FsAdminMenu *FsAdminMenuModel // fs_admin_menu 后台--菜单表
FsAdminRole *FsAdminRoleModel // fs_admin_role 后台--角色表
FsAdminUser *FsAdminUserModel // fs_admin_user 后台--管理员表
FsAuthAssignment *FsAuthAssignmentModel // fs_auth_assignment 用户角色和权限信息 FsAuthAssignment *FsAuthAssignmentModel // fs_auth_assignment 用户角色和权限信息
FsAuthItem *FsAuthItemModel // fs_auth_item 用户角色和权限信息 FsAuthItem *FsAuthItemModel // fs_auth_item 用户角色和权限信息
FsAuthItemChild *FsAuthItemChildModel // fs_auth_item_child 角色和权限关系表 FsAuthItemChild *FsAuthItemChildModel // fs_auth_item_child 角色和权限关系表
@ -112,6 +114,8 @@ func NewAllModels(gdb *gorm.DB) *AllModelsGen {
FsAdminAuthRole: NewFsAdminAuthRoleModel(gdb), FsAdminAuthRole: NewFsAdminAuthRoleModel(gdb),
FsAdminDepartment: NewFsAdminDepartmentModel(gdb), FsAdminDepartment: NewFsAdminDepartmentModel(gdb),
FsAdminMenu: NewFsAdminMenuModel(gdb), FsAdminMenu: NewFsAdminMenuModel(gdb),
FsAdminRole: NewFsAdminRoleModel(gdb),
FsAdminUser: NewFsAdminUserModel(gdb),
FsAuthAssignment: NewFsAuthAssignmentModel(gdb), FsAuthAssignment: NewFsAuthAssignmentModel(gdb),
FsAuthItem: NewFsAuthItemModel(gdb), FsAuthItem: NewFsAuthItemModel(gdb),
FsAuthItemChild: NewFsAuthItemChildModel(gdb), FsAuthItemChild: NewFsAuthItemChildModel(gdb),

View File

@ -2,6 +2,7 @@ package logic
import ( import (
"bytes" "bytes"
"fusenapi/utils/check"
"log" "log"
"net/smtp" "net/smtp"
"sync" "sync"
@ -9,8 +10,35 @@ import (
"time" "time"
) )
var TimeLimit *check.TimeLimit[string]
var EmailManager *EmailSender var EmailManager *EmailSender
func init() {
TimeLimit = check.NewTimelimit[string](time.Second * 25)
// Initialize the email manager
EmailManager = &EmailSender{
EmailTasks: make(chan *EmailFormat, 10),
Auth: smtp.PlainAuth(
"",
"support@fusenpack.com",
"wfbjpdgvaozjvwah",
"smtp.gmail.com",
),
FromEmail: "support@fusenpack.com",
emailSending: make(map[string]*EmailTask, 10),
ResendTimeLimit: time.Minute * 1,
semaphore: make(chan struct{}, 10), // Initialize semaphore with a capacity of 10
}
// Start processing email tasks
go EmailManager.ProcessEmailTasks()
// Start clearing expired tasks
go EmailManager.ClearExpiredTasks()
}
type EmailFormat struct { type EmailFormat struct {
TargetEmail string // 发送的目标email TargetEmail string // 发送的目标email
CompanyName string // fs公司名 CompanyName string // fs公司名
@ -110,30 +138,6 @@ func (m *EmailSender) ClearExpiredTasks() {
} }
} }
func init() {
// Initialize the email manager
EmailManager = &EmailSender{
EmailTasks: make(chan *EmailFormat, 10),
Auth: smtp.PlainAuth(
"",
"support@fusenpack.com",
"wfbjpdgvaozjvwah",
"smtp.gmail.com",
),
FromEmail: "support@fusenpack.com",
emailSending: make(map[string]*EmailTask, 10),
ResendTimeLimit: time.Minute * 1,
semaphore: make(chan struct{}, 10), // Initialize semaphore with a capacity of 10
}
// Start processing email tasks
go EmailManager.ProcessEmailTasks()
// Start clearing expired tasks
go EmailManager.ClearExpiredTasks()
}
const emailTemplate = `Subject: Your {{.CompanyName}} Account Confirmation const emailTemplate = `Subject: Your {{.CompanyName}} Account Confirmation
Dear Dear

View File

@ -47,6 +47,10 @@ func (l *UserEmailRegisterLogic) UserEmailRegister(req *types.RequestEmailRegist
return resp.SetStatus(basic.CodeOAuthEmailErr) return resp.SetStatus(basic.CodeOAuthEmailErr)
} }
if !TimeLimit.Is(req.Email) {
return resp.SetStatus(basic.CodeEmailTimeShortErr)
}
token, err := l.svcCtx.OAuthTokenManger.Decrypt(req.RegisterToken) token, err := l.svcCtx.OAuthTokenManger.Decrypt(req.RegisterToken)
if err != nil { if err != nil {
logx.Error(err) logx.Error(err)

View File

@ -46,6 +46,10 @@ func (l *UserRegisterLogic) UserRegister(req *types.RequestUserRegister, userinf
return resp.SetStatus(basic.CodeEmailExistsErr) return resp.SetStatus(basic.CodeEmailExistsErr)
} }
if !TimeLimit.Is(req.Email) {
return resp.SetStatus(basic.CodeEmailTimeShortErr)
}
token := &auth.RegisterToken{ token := &auth.RegisterToken{
OperateType: auth.OpTypeRegister, OperateType: auth.OpTypeRegister,
GuestId: userinfo.GuestId, GuestId: userinfo.GuestId,

View File

@ -53,12 +53,12 @@ func (l *GetProductTemplateTagsLogic) GetProductTemplateTags(req *types.GetProdu
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get ai recommend product template tag list") return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get ai recommend product template tag list")
} }
// 返回固定模板标签列表 // 返回固定模板标签列表
productTemplateTags, err = l.svcCtx.AllModels.FsProductTemplateTags.GetList(l.ctx, 1, req.Limit, "`id` DESC") productTemplateTags, err = l.svcCtx.AllModels.FsProductTemplateTags.GetList(l.ctx, 1, req.Limit, 0, 1, "`id` DESC")
} else { } else {
//元数据是空的 //元数据是空的
if userMaterial.Metadata == nil || *userMaterial.Metadata == "" { if userMaterial.Metadata == nil || *userMaterial.Metadata == "" {
// 返回固定模板标签列表 // 返回固定模板标签列表
productTemplateTags, err = l.svcCtx.AllModels.FsProductTemplateTags.GetList(l.ctx, 1, req.Limit, "`id` DESC") productTemplateTags, err = l.svcCtx.AllModels.FsProductTemplateTags.GetList(l.ctx, 1, req.Limit, 0, 1, "`id` DESC")
} else { } else {
//解析元数据 //解析元数据
var metaData map[string]interface{} var metaData map[string]interface{}
@ -72,7 +72,7 @@ func (l *GetProductTemplateTagsLogic) GetProductTemplateTags(req *types.GetProdu
logx.Error(err) logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeJsonErr, "invalid format of metadata`s template_tagid") return resp.SetStatusWithMessage(basic.CodeJsonErr, "invalid format of metadata`s template_tagid")
} }
productTemplateTags, err = l.svcCtx.AllModels.FsProductTemplateTags.GetListByTagNames(l.ctx, templateTagNameList, req.Limit, "id DESC") productTemplateTags, err = l.svcCtx.AllModels.FsProductTemplateTags.GetListByTagNames(l.ctx, templateTagNameList, req.Limit, 0, 1, "id DESC")
} }
} }
if err != nil { if err != nil {

View File

@ -92,7 +92,7 @@ func (w *wsConnectItem) renderImage(data []byte) {
userMaterial, err := w.logic.svcCtx.AllModels.FsUserMaterial.FindLatestOne(w.logic.ctx, w.userId, w.guestId) userMaterial, err := w.logic.svcCtx.AllModels.FsUserMaterial.FindLatestOne(w.logic.ctx, w.userId, w.guestId)
if err != nil { if err != nil {
if !errors.Is(err, gorm.ErrRecordNotFound) { if !errors.Is(err, gorm.ErrRecordNotFound) {
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "failed to get user logo", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, 0, 0) w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "获取用户上传logo素材失败", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, 0, 0)
logx.Error("failed to get user logo") logx.Error("failed to get user logo")
return return
} }
@ -100,10 +100,10 @@ func (w *wsConnectItem) renderImage(data []byte) {
userMaterialDefault, err := w.logic.svcCtx.AllModels.FsUserMaterial.FindOneById(w.logic.ctx, 0) userMaterialDefault, err := w.logic.svcCtx.AllModels.FsUserMaterial.FindOneById(w.logic.ctx, 0)
if err != nil { if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "default logo is not exists", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, 0, 0) w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "默认logo不存在", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, 0, 0)
return return
} }
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "failed to get default logo", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, 0, 0) w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "获取默认logo失败", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, 0, 0)
logx.Error("default logo is not exists") logx.Error("default logo is not exists")
return return
} }
@ -123,11 +123,11 @@ func (w *wsConnectItem) renderImage(data []byte) {
} }
if err != nil { if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "product first size is not exists", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, renderImageData.RenderData.ProductSizeId, 0) w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "找不到产品的第一个尺寸", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, renderImageData.RenderData.ProductSizeId, 0)
logx.Error("product size is not found") logx.Error("product size is not found")
return return
} }
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "failed to get product first size", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, renderImageData.RenderData.ProductSizeId, 0) w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "获取产品的第一个尺寸失败", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, renderImageData.RenderData.ProductSizeId, 0)
logx.Error("failed to get product size:", err) logx.Error("failed to get product size:", err)
return return
} }
@ -135,11 +135,11 @@ func (w *wsConnectItem) renderImage(data []byte) {
model3dInfo, err := w.logic.svcCtx.AllModels.FsProductModel3d.GetOneBySizeIdTag(w.logic.ctx, productSize.Id, constants.TAG_MODEL, "id") model3dInfo, err := w.logic.svcCtx.AllModels.FsProductModel3d.GetOneBySizeIdTag(w.logic.ctx, productSize.Id, constants.TAG_MODEL, "id")
if err != nil { if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "product model is not exists", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, productSize.Id, 0) w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "产品第一个尺寸对应的模型不存在", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, productSize.Id, 0)
logx.Error("product model is not found") logx.Error("product model is not found")
return return
} }
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "failed to get product model", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, productSize.Id, 0) w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "获取产品第一个尺寸对应的模型失败", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, productSize.Id, 0)
logx.Error("failed to get product model:", err) logx.Error("failed to get product model:", err)
return return
} }
@ -147,23 +147,28 @@ func (w *wsConnectItem) renderImage(data []byte) {
productTemplate, err := w.logic.svcCtx.AllModels.FsProductTemplateV2.FindFirstOneCloudRenderByProductIdModelIdTemplateTag(w.logic.ctx, renderImageData.RenderData.ProductId, model3dInfo.Id, renderImageData.RenderData.TemplateTag) productTemplate, err := w.logic.svcCtx.AllModels.FsProductTemplateV2.FindFirstOneCloudRenderByProductIdModelIdTemplateTag(w.logic.ctx, renderImageData.RenderData.ProductId, model3dInfo.Id, renderImageData.RenderData.TemplateTag)
if err != nil { if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "product template is not exists", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, model3dInfo.Id, productSize.Id, 0) w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "找不到对应模板", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, model3dInfo.Id, productSize.Id, 0)
logx.Error("template info is not found") logx.Error("template info is not found")
return return
} }
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "failed to get product template", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, model3dInfo.Id, productSize.Id, 0) w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "获取对应模板失败", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, model3dInfo.Id, productSize.Id, 0)
logx.Error("failed to get template info:", err) logx.Error("failed to get template info:", err)
return return
} }
//如果未开启云渲染
if *productTemplate.ElementModelId <= 0 {
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "模板未开启云渲染", renderImageData.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId)
return
}
//获取渲染设置信息 //获取渲染设置信息
element, err := w.logic.svcCtx.AllModels.FsProductTemplateElement.FindOneByModelId(w.logic.ctx, *productTemplate.ElementModelId) element, err := w.logic.svcCtx.AllModels.FsProductTemplateElement.FindOneByModelId(w.logic.ctx, *productTemplate.ElementModelId)
if err != nil { if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "render element is not exists", renderImageData.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId) w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "云渲染设置不存在", renderImageData.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId)
logx.Error("element info is not found,element_model_id = ", 0) logx.Error("element info is not found,element_model_id = ", 0)
return return
} }
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "failed to get render element", renderImageData.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId) w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "获取云渲染设置失败", renderImageData.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId)
logx.Error("failed to get element ,", err) logx.Error("failed to get element ,", err)
return return
} }
@ -182,7 +187,7 @@ func (w *wsConnectItem) renderImage(data []byte) {
} }
res, err := w.logic.svcCtx.Repositories.ImageHandle.LogoCombine(w.logic.ctx, &combineReq) res, err := w.logic.svcCtx.Repositories.ImageHandle.LogoCombine(w.logic.ctx, &combineReq)
if err != nil { if err != nil {
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "failed to combine image:"+err.Error(), renderImageData.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId) w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "合成刀版图失败:"+err.Error(), renderImageData.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId)
logx.Error("合成刀版图失败,合成请求数据:", combineReq, "错误信息:", err) logx.Error("合成刀版图失败,合成请求数据:", combineReq, "错误信息:", err)
return return
} }
@ -190,19 +195,12 @@ func (w *wsConnectItem) renderImage(data []byte) {
if res != nil && res.ResourceUrl != nil { if res != nil && res.ResourceUrl != nil {
combineImage = *res.ResourceUrl combineImage = *res.ResourceUrl
} else { } else {
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "combine image is empty", renderImageData.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId) w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "合成的刀版图是空的地址", renderImageData.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId)
logx.Error("合成刀版图失败,合成的刀版图是空指针:", err) logx.Error("合成刀版图失败,合成的刀版图是空指针:", err)
return return
} }
//发送合图结果消息 //发送合图完毕阶段消息
w.sendToOutChan(w.respondDataFormat(constants.WEBSOCKET_COMBINE_IMAGE, websocket_data.CombineImageRspMsg{ w.sendCombineImageStepResponseMessage(renderImageData.RenderId, combineImage, res.DiffTimeLogoCombine, res.DiffTimeUploadFile)
RenderId: renderImageData.RenderId,
CombineImage: combineImage,
CombineProcessTime: websocket_data.CombineProcessTime{
CombineTakesTime: fmt.Sprintf("%dms", res.DiffTimeLogoCombine),
UploadCombineImageTakesTime: fmt.Sprintf("%dms", res.DiffTimeUploadFile),
},
}))
//如果指定指定只返回刀版图 //如果指定指定只返回刀版图
if renderImageData.OnlyReturnCombineImage { if renderImageData.OnlyReturnCombineImage {
logx.Info("云渲染传入size id则不走unity云渲染,只返回刀版图render_id:", renderImageData.RenderId) logx.Info("云渲染传入size id则不走unity云渲染,只返回刀版图render_id:", renderImageData.RenderId)
@ -214,7 +212,7 @@ func (w *wsConnectItem) renderImage(data []byte) {
resource, err := w.logic.svcCtx.AllModels.FsResource.FindOneById(w.logic.ctx, taskId) resource, err := w.logic.svcCtx.AllModels.FsResource.FindOneById(w.logic.ctx, taskId)
if err != nil { if err != nil {
if !errors.Is(err, gorm.ErrRecordNotFound) { if !errors.Is(err, gorm.ErrRecordNotFound) {
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, taskId, "failed to get render cache", renderImageData.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId) w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, taskId, "获取unity云渲染缓存失败", renderImageData.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId)
logx.Error("failed to find render resource:", err) logx.Error("failed to find render resource:", err)
return return
} }
@ -265,7 +263,7 @@ func (w *wsConnectItem) assembleRenderDataToUnity(taskId string, combineImage st
refletion, err = strconv.Atoi(*element.Refletion) refletion, err = strconv.Atoi(*element.Refletion)
if err != nil { if err != nil {
logx.Error("err refletion:set default -1") logx.Error("err refletion:set default -1")
w.renderErrResponse(info.RenderId, info.RenderData.TemplateTag, taskId, "parse element.Refletion from string to number err", info.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId) w.renderErrResponse(info.RenderId, info.RenderData.TemplateTag, taskId, "解析云渲染设置把Refletion字段值从字符串转数字失败", info.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId)
return err return err
} }
} }
@ -274,7 +272,7 @@ func (w *wsConnectItem) assembleRenderDataToUnity(taskId string, combineImage st
if element.Mode != nil && *element.Mode != "" { if element.Mode != nil && *element.Mode != "" {
if err = json.Unmarshal([]byte(*element.Mode), &mode); err != nil { if err = json.Unmarshal([]byte(*element.Mode), &mode); err != nil {
logx.Error("faile to parse element mode json:", err) logx.Error("faile to parse element mode json:", err)
w.renderErrResponse(info.RenderId, info.RenderData.TemplateTag, taskId, "parse element.Mode err", info.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId) w.renderErrResponse(info.RenderId, info.RenderData.TemplateTag, taskId, "解析云渲染设置字段 mode 为map对象失败", info.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId)
return err return err
} }
} }
@ -321,6 +319,8 @@ func (w *wsConnectItem) assembleRenderDataToUnity(taskId string, combineImage st
"data": tempData, "data": tempData,
}, },
} }
//发送运行阶段消息(组装数据)
w.sendAssembleRenderDataStepResponseMessage(info.RenderId)
sendData := map[string]interface{}{ sendData := map[string]interface{}{
"id": taskId, "id": taskId,
"order_id": 0, "order_id": 0,
@ -347,7 +347,7 @@ func (w *wsConnectItem) assembleRenderDataToUnity(taskId string, combineImage st
unityRenderBeginTime := time.Now().UTC().UnixMilli() unityRenderBeginTime := time.Now().UTC().UnixMilli()
_, err = curl.ApiCall(url, "POST", header, bytes.NewReader(postDataBytes), time.Second*10) _, err = curl.ApiCall(url, "POST", header, bytes.NewReader(postDataBytes), time.Second*10)
if err != nil { if err != nil {
w.renderErrResponse(info.RenderId, info.RenderData.TemplateTag, taskId, "request unity api err", info.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId) w.renderErrResponse(info.RenderId, info.RenderData.TemplateTag, taskId, "请求unity接口失败", info.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId)
logx.Error("failed to send data to unity") logx.Error("failed to send data to unity")
return err return err
} }
@ -359,12 +359,34 @@ func (w *wsConnectItem) assembleRenderDataToUnity(taskId string, combineImage st
unityRenderBeginTime: unityRenderBeginTime, unityRenderBeginTime: unityRenderBeginTime,
}, },
}) })
//发送send 到unity 运行阶段信 //发送运行阶段消
w.sendToOutChan(w.respondDataFormat(constants.WEBSOCKET_SEND_DATA_TO_UNITY, websocket_data.ToUnityRspMsg{RenderId: info.RenderId})) w.sendRenderDataToUnityStepResponseMessage(info.RenderId)
logx.Info("发送到unity成功,刀版图:", combineImage /*, " 请求unity的数据:", string(postDataBytes)*/) logx.Info("发送到unity成功,刀版图:", combineImage /*, " 请求unity的数据:", string(postDataBytes)*/)
return nil return nil
} }
// 发送合图完毕阶段通知消息
func (w *wsConnectItem) sendCombineImageStepResponseMessage(renderId, combineImage string, combineMsTime, uploadMsTime int64) {
w.sendToOutChan(w.respondDataFormat(constants.WEBSOCKET_COMBINE_IMAGE, websocket_data.CombineImageRspMsg{
RenderId: renderId,
CombineImage: combineImage,
CombineProcessTime: websocket_data.CombineProcessTime{
CombineTakesTime: fmt.Sprintf("%dms", combineMsTime),
UploadCombineImageTakesTime: fmt.Sprintf("%dms", uploadMsTime),
},
}))
}
// 发送组装unity渲染数据完毕阶段通知消息
func (w *wsConnectItem) sendAssembleRenderDataStepResponseMessage(renderId string) {
w.sendToOutChan(w.respondDataFormat(constants.WEBSOCKET_ASSEMBLE_RENDER_DATA, websocket_data.ToUnityRspMsg{RenderId: renderId}))
}
// 发送组装unity渲染数据完毕阶段通知消息
func (w *wsConnectItem) sendRenderDataToUnityStepResponseMessage(renderId string) {
w.sendToOutChan(w.respondDataFormat(constants.WEBSOCKET_SEND_DATA_TO_UNITY, websocket_data.AssembleRenderDataRspMsg{RenderId: renderId}))
}
// 增加渲染任务 // 增加渲染任务
func (w *wsConnectItem) createRenderTask(data renderImageControlChanItem) { func (w *wsConnectItem) createRenderTask(data renderImageControlChanItem) {
if data.taskId == "" { if data.taskId == "" {

View File

@ -52,10 +52,11 @@ var (
CodeS3PutSizeLimitErr = &StatusResponse{5061, "s3 over limit size error"} // s3 超过文件大小限制 错误 CodeS3PutSizeLimitErr = &StatusResponse{5061, "s3 over limit size error"} // s3 超过文件大小限制 错误
CodeS3CategoryErr = &StatusResponse{5062, "s3 category not exists error"} // s3 类别不存在 错误 CodeS3CategoryErr = &StatusResponse{5062, "s3 category not exists error"} // s3 类别不存在 错误
CodeEmailNotFoundErr = &StatusResponse{5050, "email not found"} // 未找到email CodeEmailNotFoundErr = &StatusResponse{5050, "email not found"} // 未找到email
CodeUserIdNotFoundErr = &StatusResponse{5051, "user not found"} // 未找到用户 CodeUserIdNotFoundErr = &StatusResponse{5051, "user not found"} // 未找到用户
CodePasswordErr = &StatusResponse{5052, "invalid password"} // 无效密码 CodePasswordErr = &StatusResponse{5052, "invalid password"} // 无效密码
CodeEmailExistsErr = &StatusResponse{5053, "email exists"} // email存在 CodeEmailExistsErr = &StatusResponse{5053, "email exists"} // email存在
CodeEmailTimeShortErr = &StatusResponse{5053, "email with the time of resend is too short"} // email存在
CodeSafeValueRangeErr = &StatusResponse{5040, "value not in range"} // 值不在范围内 CodeSafeValueRangeErr = &StatusResponse{5040, "value not in range"} // 值不在范围内
CodeTemplateErr = &StatusResponse{5040, "template parsed error"} // 模板解析错误 CodeTemplateErr = &StatusResponse{5040, "template parsed error"} // 模板解析错误

View File

@ -82,7 +82,7 @@ func ParseJwtToken(r *http.Request, svcCtx any) (*auth.UserInfo, error) {
if err != nil { if err != nil {
// logx.Println("error", info) // logx.Println("error", info)
logx.Error(err, ":", info) logx.Error(err, ":", info)
return nil, err return nil, errors.New("user not found:" + err.Error())
} }
secret = us.PwdHash // 获取密码的hash做jwt, 便于重置密码的使用 secret = us.PwdHash // 获取密码的hash做jwt, 便于重置密码的使用

View File

@ -1 +1,53 @@
// Timeup是一个限制某个值的重复频率的工具
// 通过内部计时器实现限制同一个值的访问频率不超过指定时间间隔
package check package check
import (
"sync"
"time"
)
// TimeLimit结构体包含需要限频的映射表,以及时间间隔
// 使用sync.Mutex保证对字典的线程安全访问
type TimeLimit[T comparable] struct {
mu sync.Mutex
dict map[T]struct{}
dur time.Duration
}
// NewTimelimit构造函数,接收限频的时间间隔
// 并初始化内部字典和间隔字段
func NewTimelimit[T comparable](dur time.Duration) *TimeLimit[T] {
return &TimeLimit[T]{
dict: make(map[T]struct{}),
dur: dur,
}
}
// WithTime方法用于更新限频的时间间隔
func (tup *TimeLimit[T]) WithTime(dur time.Duration) *TimeLimit[T] {
tup.mu.Lock()
defer tup.mu.Unlock()
tup.dur = dur
return tup
}
// Is方法检查传入值是否是一个新的值
// 首先会查询字典,如果存在则表示在间隔内已经访问过
// 否则将其添加到字典,并启动一个定时器在间隔后删除
// 返回true表示新值,false表示重复值
func (tup *TimeLimit[T]) Is(v T) bool {
tup.mu.Lock()
defer tup.mu.Unlock()
if _, ok := tup.dict[v]; ok {
return false
}
tup.dict[v] = struct{}{}
time.AfterFunc(tup.dur, func() {
tup.mu.Lock()
defer tup.mu.Unlock()
delete(tup.dict, v)
})
return true
}

View File

@ -52,6 +52,11 @@ type CombineProcessTime struct {
UploadCombineImageTakesTime string `json:"upload_combine_image_takes_time"` //上传刀版图耗时 UploadCombineImageTakesTime string `json:"upload_combine_image_takes_time"` //上传刀版图耗时
} }
// 发送到组装渲染阶段信息返回数据
type AssembleRenderDataRspMsg struct {
RenderId string `json:"render_id"` //渲染id
}
// 发送到unity阶段信息返回数据 // 发送到unity阶段信息返回数据
type ToUnityRspMsg struct { type ToUnityRspMsg struct {
RenderId string `json:"render_id"` //渲染id RenderId string `json:"render_id"` //渲染id