Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop
This commit is contained in:
commit
2853d8599f
|
@ -2,28 +2,30 @@ package constants
|
|||
|
||||
type Websocket string
|
||||
|
||||
// websocket消息类型
|
||||
// websocket消息类型(主类别)
|
||||
const (
|
||||
//鉴权失败
|
||||
WEBSOCKET_UNAUTH Websocket = "WEBSOCKET_UNAUTH"
|
||||
//获取ws连接标识错误
|
||||
WEBSOCKET_GEN_UNIQUE_ID_ERR Websocket = "WEBSOCKET_GEN_UNIQUE_ID_ERR"
|
||||
//ws连接成功
|
||||
WEBSOCKET_CONNECT_SUCCESS Websocket = "WEBSOCKET_CONNECT_SUCCESS"
|
||||
//请求恢复为上次连接的标识
|
||||
WEBSOCKET_REQUEST_REUSE_LAST_CONNECT Websocket = "WEBSOCKET_REQUEST_REUSE_LAST_CONNECT"
|
||||
//请求恢复为上次连接的标识错误
|
||||
WEBSOCKET_REQUEST_RESUME_LAST_CONNECT_ERR Websocket = "WEBSOCKET_REQUEST_RESUME_LAST_CONNECT_ERR"
|
||||
//图片渲染消息
|
||||
WEBSOCKET_RENDER_IMAGE Websocket = "WEBSOCKET_RENDER_IMAGE"
|
||||
//图片渲染失败消息
|
||||
WEBSOCKET_RENDER_IMAGE_ERR Websocket = "WEBSOCKET_RENDER_IMAGE_ERR"
|
||||
//反回合成刀版图消息
|
||||
WEBSOCKET_COMBINE_IMAGE Websocket = "WEBSOCKET_COMBINE_IMAGE"
|
||||
//传入数据格式错误
|
||||
WEBSOCKET_ERR_DATA_FORMAT Websocket = "WEBSOCKET_ERR_DATA_FORMAT"
|
||||
//通用回调通知
|
||||
WEBSOCKET_COMMON_NOTIFY Websocket = "WEBSOCKET_COMMON_NOTIFY"
|
||||
//数据接收速度超过数据消费速度(缓冲队列满了)
|
||||
WEBSOCKET_INCOME_CACHE_QUEUE_OVERFLOW = "WEBSOCKET_INCOME_CACHE_QUEUE_OVERFLOW"
|
||||
WEBSOCKET_UNAUTH Websocket = "WEBSOCKET_UNAUTH" //鉴权失败 (1级消息,单向通信)
|
||||
WEBSOCKET_GEN_UNIQUE_ID_ERR Websocket = "WEBSOCKET_GEN_UNIQUE_ID_ERR" //获取ws连接标识错误 (1级消息,单向通信)
|
||||
WEBSOCKET_CONNECT_SUCCESS Websocket = "WEBSOCKET_CONNECT_SUCCESS" //ws连接成功 (1级消息,单向通信)
|
||||
WEBSOCKET_REQUEST_REUSE_LAST_CONNECT Websocket = "WEBSOCKET_REQUEST_REUSE_LAST_CONNECT" //请求恢复为上次连接的标识 (1级消息,单向通信)
|
||||
WEBSOCKET_REQUEST_RESUME_LAST_CONNECT_ERR Websocket = "WEBSOCKET_REQUEST_RESUME_LAST_CONNECT_ERR" //请求恢复为上次连接的标识错误 (1级消息,单向通信)
|
||||
WEBSOCKET_INCOME_CACHE_QUEUE_OVERFLOW = "WEBSOCKET_INCOME_CACHE_QUEUE_OVERFLOW" //数据接收速度超过数据消费速度(缓冲队列满了)(1级消息,单向通信)
|
||||
)
|
||||
|
||||
// websocket消息类型(通用通知类别)
|
||||
const (
|
||||
WEBSOCKET_COMMON_NOTIFY Websocket = "WEBSOCKET_COMMON_NOTIFY" //通用回调通知(1级消息,单向通信)
|
||||
)
|
||||
|
||||
// websocket消息类型(基本传输结构类别)
|
||||
const (
|
||||
WEBSOCKET_ERR_DATA_FORMAT Websocket = "WEBSOCKET_ERR_DATA_FORMAT" //传入数据格式错误(1级消息,单向通信)
|
||||
)
|
||||
|
||||
// websocket消息类型(云渲染类别)
|
||||
const (
|
||||
WEBSOCKET_RENDER_IMAGE Websocket = "WEBSOCKET_RENDER_IMAGE" //图片渲染消息(1级消息,双向通信)
|
||||
WEBSOCKET_RENDER_IMAGE_ERR Websocket = "WEBSOCKET_RENDER_IMAGE_ERR" //图片渲染失败消息(1级消息,单向通信)
|
||||
WEBSOCKET_COMBINE_IMAGE Websocket = "WEBSOCKET_COMBINE_IMAGE" //反回合成刀版图消息(2级消息,单向通信,属于 WEBSOCKET_RENDER_IMAGE 消息的子流程)
|
||||
WEBSOCKET_SEND_DATA_TO_UNITY Websocket = "WEBSOCKET_SEND_DATA_TO_UNITY" //发送到unity进行渲染
|
||||
)
|
||||
|
|
1
go.mod
1
go.mod
|
@ -28,6 +28,7 @@ require (
|
|||
require (
|
||||
cloud.google.com/go/compute v1.20.1 // 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/HdrHistogram/hdrhistogram-go v1.1.2 // indirect
|
||||
github.com/VictoriaMetrics/metrics v1.18.1 // indirect
|
||||
|
|
2
go.sum
2
go.sum
|
@ -35,6 +35,8 @@ 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.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=
|
||||
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/go.mod h1:MmnnrF9d51sPkFzdRq2pQtxQKqyjburVM1LjMbOCezE=
|
||||
github.com/474420502/random v0.4.1 h1:HUUyLXRWMijVb7CJoEC16f0aFQOW25Lkr80Mut6PoKU=
|
||||
|
|
|
@ -100,9 +100,10 @@ func (l *UserEmailConfirmationLogic) UserEmailConfirmation(req *types.RequestEma
|
|||
|
||||
switch token.OperateType {
|
||||
case auth.OpTypeRegister:
|
||||
if time.Since(token.CreateAt) >= 24*time.Hour {
|
||||
return resp.SetStatus(basic.CodeOAuthConfirmationTimeoutErr)
|
||||
if time.Since(token.CreateAt) > 30*time.Minute {
|
||||
return resp.SetStatusWithMessage(basic.CodeOAuthConfirmationTimeoutErr, "Verification links expire after 30 minute.")
|
||||
}
|
||||
|
||||
logx.Info(token.Platform)
|
||||
switch token.Platform {
|
||||
case string(auth.PLATFORM_GOOGLE):
|
||||
|
@ -110,7 +111,7 @@ func (l *UserEmailConfirmationLogic) UserEmailConfirmation(req *types.RequestEma
|
|||
user, err := l.svcCtx.AllModels.FsUser.RegisterByGoogleOAuth(l.ctx, token)
|
||||
if err != nil {
|
||||
logx.Error(err, token.TraceId)
|
||||
return resp.SetStatus(basic.CodeDbSqlErr)
|
||||
return resp.SetStatus(basic.CodeDbSqlErr, err.Error())
|
||||
}
|
||||
|
||||
err = FinishRegister(l.svcCtx, user, token)
|
||||
|
@ -120,11 +121,12 @@ func (l *UserEmailConfirmationLogic) UserEmailConfirmation(req *types.RequestEma
|
|||
logx.Info("success", token.TraceId)
|
||||
|
||||
case string(auth.PLATFORM_FACEBOOK):
|
||||
|
||||
case string(auth.PLATFORM_FUSEN):
|
||||
// log.Println("aaaa", token)
|
||||
user, err := l.svcCtx.AllModels.FsUser.RegisterByFusen(l.ctx, token)
|
||||
if err != nil && err != gorm.ErrRecordNotFound {
|
||||
logx.Error(err, ":", token.TraceId)
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, err.Error())
|
||||
}
|
||||
err = FinishRegister(l.svcCtx, user, token)
|
||||
|
@ -147,39 +149,44 @@ func (l *UserEmailConfirmationLogic) AfterLogic(w http.ResponseWriter, r *http.R
|
|||
successHtml := `<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>注册成功</title>
|
||||
<title>Registration Successful</title>
|
||||
|
||||
<style>
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 24px;
|
||||
color: red;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
font-size: 16px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 24px;
|
||||
color: red;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
body {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 18px;
|
||||
}
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>恭喜!您的注册成功。</h1>
|
||||
|
||||
<p>感谢您在我们网站进行注册。您的账号已经激活。</p>
|
||||
<h1>Congratulations! Your registration is successful.</h1>
|
||||
|
||||
<p>您现在可以使用您的邮箱地址和密码登录我们的网站,享受完整的服务和功能。</p>
|
||||
<p>Thank you for registering on our website. Your account has been activated.</p>
|
||||
|
||||
<p>再次感谢您的信任和支持。如果您有任何问题,请随时联系我们。</p>
|
||||
<p>You can now login using your email address and password to enjoy full services and features on our website.</p>
|
||||
|
||||
<p>Thanks again for your trust and support. If you have any questions, please feel free to contact us.</p>
|
||||
|
||||
<p>We wish you a pleasant experience!</p>
|
||||
|
||||
<p>祝您使用愉快!</p>
|
||||
</body>
|
||||
</html>`
|
||||
w.Write([]byte(successHtml))
|
||||
|
@ -190,7 +197,7 @@ func (l *UserEmailConfirmationLogic) AfterLogic(w http.ResponseWriter, r *http.R
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>注册失败</title>
|
||||
<title>Failed to register</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
|
|
|
@ -131,8 +131,10 @@ func (l *UserGoogleLoginLogic) AfterLogic(w http.ResponseWriter, r *http.Request
|
|||
|
||||
if resp.Code == 200 {
|
||||
|
||||
logx.Info(l)
|
||||
|
||||
rurl := fmt.Sprintf(
|
||||
"http://www.fusen.3718.cn/"+"/oauth?token=%s&is_registered=%t®ister_token=%s",
|
||||
"http://www.fusen.3718.cn"+"/oauth?token=%s&is_registered=%t®ister_token=%s",
|
||||
l.token,
|
||||
l.isRegistered,
|
||||
l.registerToken,
|
||||
|
|
|
@ -85,117 +85,26 @@ func (l *GetTagProductListLogic) GetTagProductList(req *types.GetTagProductListR
|
|||
var (
|
||||
productList []gmodel.FsProduct //产品列表(select 字段需要看查询的地方)
|
||||
mapTagProp = make(map[int64][]types.CoverDefaultItem)
|
||||
productOptionalPartList []gmodel.GetGroupPartListByProductIdsRsp //产品配件列表
|
||||
mapProductHaveOptionFitting = make(map[int64]struct{})
|
||||
productPriceList []gmodel.GetPriceListByProductIdsRsp //产品价格列表(select 字段需要看查询的地方)
|
||||
mapProductMinPrice = make(map[int64]int64) //产品最小价格map
|
||||
productTemplatesV2 []gmodel.FsProductTemplateV2 //产品模板列表(select 字段需要看查询的地方)
|
||||
productSizeCountList []gmodel.CountProductSizeByStatusRsp //产品尺寸数量列表(select 字段需要看查询的地方)
|
||||
mapProductSizeCount = make(map[int64]int64) //产品尺寸数量map
|
||||
mapProductTemplate = make(map[int64]int64) //产品模板map
|
||||
mapProductMinPrice = make(map[int64]int64) //产品最小价格map
|
||||
mapProductSizeCount = make(map[int64]int64) //产品尺寸数量map
|
||||
mapProductTemplate = make(map[int64]int64) //产品模板map
|
||||
)
|
||||
//携带产品
|
||||
if req.WithProduct {
|
||||
//查询符合的产品列表
|
||||
pIsDel := int64(0)
|
||||
pStatus := int64(1)
|
||||
pIsShelf := int64(1)
|
||||
//获取产品列表
|
||||
productList, err = l.svcCtx.AllModels.FsProduct.GetProductListByParams(l.ctx,
|
||||
gmodel.GetProductListByParamsReq{
|
||||
Type: typeIds,
|
||||
IsDel: &pIsDel,
|
||||
IsShelf: &pIsShelf,
|
||||
Status: &pStatus,
|
||||
OrderBy: "`is_recommend` DESC,`sort` ASC",
|
||||
})
|
||||
productList, err = l.getProductRelationInfo(getProductRelationInfoReq{
|
||||
Ctx: l.ctx,
|
||||
TemplateTag: req.TemplateTag,
|
||||
TypeIds: typeIds,
|
||||
MapTagProp: mapTagProp,
|
||||
MapProductHaveOptionFitting: mapProductHaveOptionFitting,
|
||||
MapProductMinPrice: mapProductMinPrice,
|
||||
MapProductSizeCount: mapProductSizeCount,
|
||||
MapProductTemplate: mapProductTemplate,
|
||||
})
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get product list")
|
||||
}
|
||||
productIds := make([]int64, 0, len(productList))
|
||||
for _, product := range productList {
|
||||
productIds = append(productIds, product.Id)
|
||||
}
|
||||
//获取商品可选配件
|
||||
productOptionalPartList, err = l.svcCtx.AllModels.FsProductModel3d.GetGroupPartListByProductIds(l.ctx, productIds)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product part list")
|
||||
}
|
||||
//存储有配件的map
|
||||
for _, partList := range productOptionalPartList {
|
||||
partList.PartList = strings.Trim(partList.PartList, " ")
|
||||
partList.PartList = strings.Trim(partList.PartList, ",")
|
||||
if partList.PartList == "" {
|
||||
continue
|
||||
}
|
||||
mapProductHaveOptionFitting[partList.ProductId] = struct{}{}
|
||||
}
|
||||
//获取产品标签相关属性
|
||||
productTagPropList, err := l.svcCtx.AllModels.FsProductTagProp.GetTagPropByProductIdsWithProductTag(l.ctx, productIds)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product tag property")
|
||||
}
|
||||
for _, v := range productTagPropList {
|
||||
mapTagProp[*v.ProductId] = append(mapTagProp[*v.ProductId], types.CoverDefaultItem{
|
||||
Tag: v.TemplateTag,
|
||||
Cover: *v.Cover,
|
||||
})
|
||||
}
|
||||
//获取产品价格列表
|
||||
productPriceList, err = l.svcCtx.AllModels.FsProductPrice.GetSimplePriceListByProductIds(l.ctx, productIds)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get product min price list")
|
||||
}
|
||||
//存储产品最小价格
|
||||
for _, v := range productPriceList {
|
||||
priceStrSlic := strings.Split(v.Price, ",")
|
||||
priceSlice, err := format.StrSlicToIntSlice(priceStrSlic)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, err.Error())
|
||||
}
|
||||
if len(priceSlice) == 0 {
|
||||
continue
|
||||
}
|
||||
//正序排序价格(注意排序后的阶梯价格不能用作阶梯数量价格计算)
|
||||
sort.Ints(priceSlice)
|
||||
if min, ok := mapProductMinPrice[v.ProductId]; ok {
|
||||
if min > int64(priceSlice[0]) {
|
||||
mapProductMinPrice[v.ProductId] = int64(priceSlice[0])
|
||||
}
|
||||
} else {
|
||||
mapProductMinPrice[v.ProductId] = int64(priceSlice[0])
|
||||
}
|
||||
}
|
||||
//获取模板(只是获取产品product_id,id)
|
||||
if req.TemplateTag != "" { //指定模板tag
|
||||
productTemplatesV2, err = l.svcCtx.AllModels.FsProductTemplateV2.FindAllByProductIdsTemplateTag(l.ctx, productIds, req.TemplateTag, "sort ASC", "product_id,id")
|
||||
} else { //没指定模板tag
|
||||
productTemplatesV2, err = l.svcCtx.AllModels.FsProductTemplateV2.FindAllByProductIds(l.ctx, productIds, "sort ASC", "product_id,id")
|
||||
}
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get product templates")
|
||||
}
|
||||
//只存第一个
|
||||
for _, v := range productTemplatesV2 {
|
||||
if _, ok := mapProductTemplate[*v.ProductId]; ok {
|
||||
continue
|
||||
}
|
||||
mapProductTemplate[*v.ProductId] = v.Id
|
||||
}
|
||||
//获取产品尺寸数量
|
||||
productSizeCountList, err = l.svcCtx.AllModels.FsProductSize.GetGroupProductSizeByStatus(l.ctx, productIds, 1)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "get product size count err")
|
||||
}
|
||||
for _, v := range productSizeCountList {
|
||||
mapProductSizeCount[v.ProductId] = v.Num
|
||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get product series info")
|
||||
}
|
||||
}
|
||||
//map tag菜单
|
||||
|
@ -227,6 +136,128 @@ func (l *GetTagProductListLogic) GetTagProductList(req *types.GetTagProductListR
|
|||
})
|
||||
}
|
||||
|
||||
// 如果携带产品,就查询产品相关信息
|
||||
type getProductRelationInfoReq struct {
|
||||
Ctx context.Context
|
||||
TemplateTag string
|
||||
TypeIds []int64
|
||||
MapTagProp map[int64][]types.CoverDefaultItem
|
||||
MapProductHaveOptionFitting map[int64]struct{}
|
||||
MapProductMinPrice map[int64]int64
|
||||
MapProductSizeCount map[int64]int64
|
||||
MapProductTemplate map[int64]int64
|
||||
}
|
||||
|
||||
func (l *GetTagProductListLogic) getProductRelationInfo(req getProductRelationInfoReq) (productList []gmodel.FsProduct, err error) {
|
||||
var (
|
||||
productTemplatesV2List []gmodel.FsProductTemplateV2
|
||||
productSizeCountList []gmodel.CountProductSizeByStatusRsp
|
||||
productOptionalPartList []gmodel.GetGroupPartListByProductIdsRsp
|
||||
)
|
||||
//查询符合的产品列表
|
||||
pIsDel := int64(0)
|
||||
pStatus := int64(1)
|
||||
pIsShelf := int64(1)
|
||||
//获取产品列表
|
||||
productList, err = l.svcCtx.AllModels.FsProduct.GetProductListByParams(l.ctx,
|
||||
gmodel.GetProductListByParamsReq{
|
||||
Type: req.TypeIds,
|
||||
IsDel: &pIsDel,
|
||||
IsShelf: &pIsShelf,
|
||||
Status: &pStatus,
|
||||
OrderBy: "`is_recommend` DESC,`sort` ASC",
|
||||
})
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return nil, errors.New("failed to get product list")
|
||||
}
|
||||
productIds := make([]int64, 0, len(productList))
|
||||
for _, product := range productList {
|
||||
productIds = append(productIds, product.Id)
|
||||
}
|
||||
//获取商品可选配件
|
||||
productOptionalPartList, err = l.svcCtx.AllModels.FsProductModel3d.GetGroupPartListByProductIds(l.ctx, productIds)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return nil, errors.New("failed to get product part list")
|
||||
}
|
||||
//存储有配件的map
|
||||
for _, partList := range productOptionalPartList {
|
||||
partList.PartList = strings.Trim(partList.PartList, " ")
|
||||
partList.PartList = strings.Trim(partList.PartList, ",")
|
||||
if partList.PartList == "" {
|
||||
continue
|
||||
}
|
||||
req.MapProductHaveOptionFitting[partList.ProductId] = struct{}{}
|
||||
}
|
||||
//获取产品标签相关属性
|
||||
productTagPropList, err := l.svcCtx.AllModels.FsProductTagProp.GetTagPropByProductIdsWithProductTag(l.ctx, productIds)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return nil, errors.New("failed to get product tag property")
|
||||
}
|
||||
for _, v := range productTagPropList {
|
||||
req.MapTagProp[*v.ProductId] = append(req.MapTagProp[*v.ProductId], types.CoverDefaultItem{
|
||||
Tag: v.TemplateTag,
|
||||
Cover: *v.Cover,
|
||||
})
|
||||
}
|
||||
//获取产品价格列表
|
||||
productPriceList, err := l.svcCtx.AllModels.FsProductPrice.GetSimplePriceListByProductIds(l.ctx, productIds)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return nil, errors.New("failed to get product min price list")
|
||||
}
|
||||
//存储产品最小价格
|
||||
for _, v := range productPriceList {
|
||||
priceStrSlic := strings.Split(v.Price, ",")
|
||||
priceSlice, err := format.StrSlicToIntSlice(priceStrSlic)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return nil, errors.New("parse price err")
|
||||
}
|
||||
if len(priceSlice) == 0 {
|
||||
continue
|
||||
}
|
||||
//正序排序价格(注意排序后的阶梯价格不能用作阶梯数量价格计算)
|
||||
sort.Ints(priceSlice)
|
||||
if min, ok := req.MapProductMinPrice[v.ProductId]; ok {
|
||||
if min > int64(priceSlice[0]) {
|
||||
req.MapProductMinPrice[v.ProductId] = int64(priceSlice[0])
|
||||
}
|
||||
} else {
|
||||
req.MapProductMinPrice[v.ProductId] = int64(priceSlice[0])
|
||||
}
|
||||
}
|
||||
//获取模板(只是获取产品product_id,id)
|
||||
if req.TemplateTag != "" { //指定模板tag
|
||||
productTemplatesV2List, err = l.svcCtx.AllModels.FsProductTemplateV2.FindAllByProductIdsTemplateTag(l.ctx, productIds, req.TemplateTag, "sort ASC", "product_id,id")
|
||||
} else { //没指定模板tag
|
||||
productTemplatesV2List, err = l.svcCtx.AllModels.FsProductTemplateV2.FindAllByProductIds(l.ctx, productIds, "sort ASC", "product_id,id")
|
||||
}
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return nil, errors.New("failed to get product templates")
|
||||
}
|
||||
//只存第一个
|
||||
for _, v := range productTemplatesV2List {
|
||||
if _, ok := req.MapProductTemplate[*v.ProductId]; ok {
|
||||
continue
|
||||
}
|
||||
req.MapProductTemplate[*v.ProductId] = v.Id
|
||||
}
|
||||
//获取产品尺寸数量
|
||||
productSizeCountList, err = l.svcCtx.AllModels.FsProductSize.GetGroupProductSizeByStatus(l.ctx, productIds, 1)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return nil, errors.New("get product size count err")
|
||||
}
|
||||
for _, v := range productSizeCountList {
|
||||
req.MapProductSizeCount[v.ProductId] = v.Num
|
||||
}
|
||||
return productList, nil
|
||||
}
|
||||
|
||||
// 处理tag菜单数据
|
||||
type dealWithTagMenuDataReq struct {
|
||||
TagList []gmodel.FsTags
|
||||
|
@ -351,6 +382,7 @@ type getTagProductsReq struct {
|
|||
User gmodel.FsUser
|
||||
}
|
||||
|
||||
// 返回每个标签下的直接从属产品,不包含子tag的产品
|
||||
func (l *GetTagProductListLogic) getTagProducts(req getTagProductsReq) (productListRsp []types.TagProduct) {
|
||||
//默认给50个容量
|
||||
productListRsp = make([]types.TagProduct, 0, 50)
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
package logic
|
||||
|
||||
import (
|
||||
"fusenapi/constants"
|
||||
)
|
||||
|
||||
// 消息分发工厂
|
||||
type allocationProcessorFactory interface {
|
||||
allocationMessage(w *wsConnectItem, data []byte)
|
||||
}
|
||||
|
||||
var mapAllocationProcessor = make(map[constants.Websocket]allocationProcessorFactory)
|
||||
|
||||
func (w *wsConnectItem) newAllocationProcessor(msgType constants.Websocket) allocationProcessorFactory {
|
||||
if val, ok := mapAllocationProcessor[msgType]; ok {
|
||||
return val
|
||||
}
|
||||
var obj allocationProcessorFactory
|
||||
switch msgType {
|
||||
//图片渲染
|
||||
case constants.WEBSOCKET_RENDER_IMAGE:
|
||||
obj = &renderProcessor{}
|
||||
//刷新重连请求恢复上次连接的标识
|
||||
case constants.WEBSOCKET_REQUEST_REUSE_LAST_CONNECT:
|
||||
obj = &reuseConnProcessor{}
|
||||
default:
|
||||
|
||||
}
|
||||
if obj != nil {
|
||||
mapAllocationProcessor[msgType] = obj
|
||||
}
|
||||
return obj
|
||||
}
|
|
@ -313,7 +313,8 @@ func (w *wsConnectItem) consumeInChanData() {
|
|||
case <-w.closeChan:
|
||||
return
|
||||
case data := <-w.inChan:
|
||||
w.dealwithReciveData(data)
|
||||
//对不同消息类型分发处理
|
||||
w.allocationProcessing(data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -382,7 +383,7 @@ func (w *wsConnectItem) respondDataFormat(msgType constants.Websocket, data inte
|
|||
}
|
||||
|
||||
// 处理入口缓冲队列中不同类型的数据(分发处理)
|
||||
func (w *wsConnectItem) dealwithReciveData(data []byte) {
|
||||
func (w *wsConnectItem) allocationProcessing(data []byte) {
|
||||
var parseInfo websocket_data.DataTransferData
|
||||
if err := json.Unmarshal(data, &parseInfo); err != nil {
|
||||
w.incomeDataFormatErrResponse("invalid format of income message:" + string(data))
|
||||
|
@ -390,15 +391,12 @@ func (w *wsConnectItem) dealwithReciveData(data []byte) {
|
|||
return
|
||||
}
|
||||
d, _ := json.Marshal(parseInfo.D)
|
||||
//分消息类型给到不同逻辑处理,可扩展
|
||||
switch parseInfo.T {
|
||||
//图片渲染
|
||||
case constants.WEBSOCKET_RENDER_IMAGE:
|
||||
w.sendToRenderChan(d)
|
||||
//刷新重连请求恢复上次连接的标识
|
||||
case constants.WEBSOCKET_REQUEST_REUSE_LAST_CONNECT:
|
||||
w.reuseLastConnect(d)
|
||||
default:
|
||||
logx.Error("未知消息类型:uid:", w.userId, "gid:", w.guestId, "data:", string(data))
|
||||
//获取工厂实例
|
||||
processor := w.newAllocationProcessor(parseInfo.T)
|
||||
if processor == nil {
|
||||
logx.Error("未知消息类型:", string(data))
|
||||
return
|
||||
}
|
||||
//执行工厂方法
|
||||
processor.allocationMessage(w, d)
|
||||
}
|
||||
|
|
|
@ -18,6 +18,10 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// 渲染处理器
|
||||
type renderProcessor struct {
|
||||
}
|
||||
|
||||
// 云渲染属性
|
||||
type extendRenderProperty struct {
|
||||
renderImageTask map[string]*renderTask //需要渲染的图片任务 key是taskId val 是renderId
|
||||
|
@ -44,8 +48,9 @@ type renderTask struct {
|
|||
uploadUnityRenderImageTakesTime int64 //上传unity渲染结果图时间
|
||||
}
|
||||
|
||||
// 发送到渲染缓冲队列
|
||||
func (w *wsConnectItem) sendToRenderChan(data []byte) {
|
||||
// 处理分发到这里的数据
|
||||
func (r *renderProcessor) allocationMessage(w *wsConnectItem, data []byte) {
|
||||
logx.Info("收到渲染任务消息:", string(data))
|
||||
select {
|
||||
case <-w.closeChan: //已经关闭
|
||||
return
|
||||
|
@ -246,14 +251,14 @@ func (w *wsConnectItem) renderImage(data []byte) {
|
|||
},
|
||||
})
|
||||
//组装数据
|
||||
if err = w.assembleRenderData(taskId, combineImage, renderImageData, productTemplate, model3dInfo, element, productSize); err != nil {
|
||||
if err = w.assembleRenderDataToUnity(taskId, combineImage, renderImageData, productTemplate, model3dInfo, element, productSize); err != nil {
|
||||
logx.Error("组装数据失败:", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 组装数据发送给unity
|
||||
func (w *wsConnectItem) assembleRenderData(taskId string, combineImage string, info websocket_data.RenderImageReqMsg, productTemplate *gmodel.FsProductTemplateV2, model3dInfo *gmodel.FsProductModel3d, element *gmodel.FsProductTemplateElement, productSize *gmodel.FsProductSize) (err error) {
|
||||
func (w *wsConnectItem) assembleRenderDataToUnity(taskId string, combineImage string, info websocket_data.RenderImageReqMsg, productTemplate *gmodel.FsProductTemplateV2, model3dInfo *gmodel.FsProductModel3d, element *gmodel.FsProductTemplateElement, productSize *gmodel.FsProductSize) (err error) {
|
||||
//组装数据
|
||||
refletion := -1
|
||||
if element.Refletion != nil && *element.Refletion != "" {
|
||||
|
@ -354,6 +359,8 @@ func (w *wsConnectItem) assembleRenderData(taskId string, combineImage string, i
|
|||
unityRenderBeginTime: unityRenderBeginTime,
|
||||
},
|
||||
})
|
||||
//发送send 到unity 运行阶段信息
|
||||
w.sendToOutChan(w.respondDataFormat(constants.WEBSOCKET_SEND_DATA_TO_UNITY, websocket_data.ToUnityRspMsg{RenderId: info.RenderId}))
|
||||
logx.Info("发送到unity成功,刀版图:", combineImage /*, " 请求unity的数据:", string(postDataBytes)*/)
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -9,8 +9,12 @@ import (
|
|||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
// 刷新重连请求恢复上次连接的标识
|
||||
func (w *wsConnectItem) reuseLastConnect(data []byte) {
|
||||
// 复用连接处理器
|
||||
type reuseConnProcessor struct {
|
||||
}
|
||||
|
||||
// 处理分发到这里的数据
|
||||
func (r *reuseConnProcessor) allocationMessage(w *wsConnectItem, data []byte) {
|
||||
logx.Info("收到请求恢复上次连接标识数据:", string(data))
|
||||
var wid string
|
||||
if err := json.Unmarshal(data, &wid); err != nil {
|
||||
|
@ -41,7 +45,9 @@ func (w *wsConnectItem) reuseLastConnect(data []byte) {
|
|||
if v, ok := mapConnPool.Load(wid); ok {
|
||||
obj, ok := v.(wsConnectItem)
|
||||
if !ok {
|
||||
w.reuseLastConnErrResponse("连接断言失败")
|
||||
logx.Error("连接断言失败")
|
||||
return
|
||||
}
|
||||
//是当前自己占用(无需处理)
|
||||
if obj.uniqueId == w.uniqueId {
|
||||
|
@ -54,11 +60,12 @@ func (w *wsConnectItem) reuseLastConnect(data []byte) {
|
|||
}
|
||||
}
|
||||
//重新绑定
|
||||
logx.Info("开始重新绑定>>>>>")
|
||||
w.uniqueId = wid
|
||||
mapConnPool.Store(wid, *w)
|
||||
rsp := w.respondDataFormat(constants.WEBSOCKET_CONNECT_SUCCESS, wid)
|
||||
w.sendToOutChan(rsp)
|
||||
return
|
||||
logx.Info("重新绑定成功")
|
||||
}
|
||||
|
||||
// 获取用户拼接部分(复用标识用到)
|
||||
|
|
1
utils/check/limit.go
Normal file
1
utils/check/limit.go
Normal file
|
@ -0,0 +1 @@
|
|||
package check
|
|
@ -51,3 +51,8 @@ type CombineProcessTime struct {
|
|||
CombineTakesTime string `json:"combine_takes_time"` //合图时间
|
||||
UploadCombineImageTakesTime string `json:"upload_combine_image_takes_time"` //上传刀版图耗时
|
||||
}
|
||||
|
||||
// 发送到unity阶段信息返回数据
|
||||
type ToUnityRspMsg struct {
|
||||
RenderId string `json:"render_id"` //渲染id
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user