Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop
This commit is contained in:
commit
3f78cfd824
|
@ -22,6 +22,7 @@ type FsAddress struct {
|
|||
Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` // 创建时间
|
||||
Utime *time.Time `gorm:"index;default:'0000-00-00 00:00:00';" json:"utime"` // 更新时间
|
||||
Ltime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ltime"` // 上次被使用的时间
|
||||
IsDefault *int64 `gorm:"default:0;" json:"is_default"` // 1默认值,0非默认值
|
||||
}
|
||||
type FsAddressModel struct {
|
||||
db *gorm.DB
|
||||
|
|
|
@ -14,7 +14,7 @@ func (a *FsAddressModel) GetOne(ctx context.Context, addressId int64, userId int
|
|||
}
|
||||
|
||||
func (a *FsAddressModel) GetUserAllAddress(ctx context.Context, userId int64) (resp []FsAddress, err error) {
|
||||
err = a.db.WithContext(ctx).Model(&FsAddress{}).Where("`user_id` = ? and `status` = 1", userId).Order("`ltime` DESC").Find(&resp).Error
|
||||
err = a.db.WithContext(ctx).Model(&FsAddress{}).Where("`user_id` = ? and `status` = 1", userId).Order("`ctime` DESC").Find(&resp).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -37,26 +37,11 @@ func (a *FsAddressModel) CreateOne(ctx context.Context, address *FsAddress) (res
|
|||
Country: address.Country,
|
||||
ZipCode: address.ZipCode,
|
||||
Status: address.Status,
|
||||
|
||||
Ctime: &now,
|
||||
Utime: &now,
|
||||
Ltime: &now,
|
||||
IsDefault: address.IsDefault,
|
||||
Ctime: &now,
|
||||
Utime: &now,
|
||||
Ltime: &now,
|
||||
}
|
||||
|
||||
// lastOne := &FsAddress{}
|
||||
// err = tx.Where("user_id = ?", lastOne.UserId).Order("ltime ASC").Take(&lastOne).Error
|
||||
// if err == gorm.ErrRecordNotFound {
|
||||
// result.Ltime = &now
|
||||
// return tx.Model(&FsAddress{}).Create(result).Error
|
||||
// }
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
// // 根据lastOne处理时间
|
||||
|
||||
// ltime := (*lastOne.Ltime).Add(-time.Second)
|
||||
// result.Ltime = <ime
|
||||
return tx.Model(&FsAddress{}).Create(result).Error
|
||||
})
|
||||
|
||||
|
@ -80,44 +65,46 @@ func (a *FsAddressModel) UpdateAddress(ctx context.Context, address *FsAddress)
|
|||
return err
|
||||
}
|
||||
|
||||
func (a *FsAddressModel) SettingUserDefaultAddress(ctx context.Context, userId int64, addressId int64, isDefault int64) (err error) {
|
||||
func (a *FsAddressModel) SettingUserDefaultAddressMutex(ctx context.Context, userId int64, addressId int64, isDefault int64) (err error) {
|
||||
|
||||
err = a.db.WithContext(ctx).Model(&FsAddress{}).Transaction(func(tx *gorm.DB) error {
|
||||
|
||||
logx.Info("address_id:", addressId, " set default ", isDefault)
|
||||
now := time.Now().UTC()
|
||||
|
||||
err = tx.Where("`address_id` = ? and `user_id` = ? and `status` = 1 ", addressId, userId).Take(nil).Error
|
||||
err = tx.Where("`user_id` = ? and `status` = 1 and `is_default` = 1", userId).
|
||||
UpdateColumn("is_default", 0).
|
||||
UpdateColumn("utime", now).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if isDefault == 0 {
|
||||
err = tx.Where("`address_id` = ? and `user_id` = ? and `status` = 1", addressId, userId).
|
||||
UpdateColumn("is_default", isDefault).
|
||||
UpdateColumn("ltime", now).
|
||||
UpdateColumn("utime", now).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = tx.Model(&FsAddress{}).Where("`address_id` = ? and `user_id` = ? and `status` = 1 and `ltime` > ?", addressId, userId, now.AddDate(10, 0, 0)).
|
||||
UpdateColumn("ltime", now).
|
||||
UpdateColumn("utime", now).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
|
||||
err = tx.Where("`address_id` = ? and `user_id` = ? and `status` = 1 ", addressId, userId).
|
||||
UpdateColumn("ltime", now.AddDate(250, 0, 0)).
|
||||
UpdateColumn("utime", now).Error
|
||||
func (a *FsAddressModel) SettingUserDefaultAddress(ctx context.Context, userId int64, addressId int64, isDefault int64) (err error) {
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = tx.Model(&FsAddress{}).Where("`address_id` != ? and `user_id` = ? and `status` = 1 and `ltime` > ?", addressId, userId, now.AddDate(10, 0, 0)).
|
||||
UpdateColumn("ltime", now).
|
||||
UpdateColumn("utime", now).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = a.db.WithContext(ctx).Model(&FsAddress{}).Transaction(func(tx *gorm.DB) error {
|
||||
|
||||
logx.Info("address_id:", addressId, " set default ", isDefault)
|
||||
now := time.Now().UTC()
|
||||
err = tx.Where("`address_id` = ? and `user_id` = ? and `status` = 1", addressId, userId).
|
||||
UpdateColumn("is_default", isDefault).
|
||||
UpdateColumn("ltime", now).
|
||||
UpdateColumn("utime", now).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -138,7 +125,8 @@ func (a *FsAddressModel) UpdateUsedAddress(ctx context.Context, addressId int64,
|
|||
err = a.db.WithContext(ctx).Model(&FsAddress{}).Transaction(func(tx *gorm.DB) error {
|
||||
logx.Info("address_id:", addressId, " update used")
|
||||
now := time.Now().UTC()
|
||||
err = tx.Where("`address_id` = ? and `user_id` = ? and `status` = 1 and `ltime` < ?", addressId, userId, now).
|
||||
err = tx.Where("`address_id` = ? and `user_id` = ? and `status` = 1", addressId, userId).
|
||||
UpdateColumn("utime", now).
|
||||
UpdateColumn("ltime", now).Error
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
36
server/collection/collection.go
Normal file
36
server/collection/collection.go
Normal file
|
@ -0,0 +1,36 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"fusenapi/utils/auth"
|
||||
"fusenapi/utils/fsconfig"
|
||||
|
||||
"fusenapi/server/collection/internal/config"
|
||||
"fusenapi/server/collection/internal/handler"
|
||||
"fusenapi/server/collection/internal/svc"
|
||||
"github.com/zeromicro/go-zero/rest"
|
||||
)
|
||||
|
||||
var configFile = flag.String("f", "etc/collection.yaml", "the config file")
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
var c config.Config
|
||||
fsconfig.StartNacosConfig(*configFile, &c, nil)
|
||||
|
||||
c.Timeout = int64(time.Second * 15)
|
||||
server := rest.MustNewServer(c.RestConf, rest.WithCustomCors(auth.FsCors, func(w http.ResponseWriter) {
|
||||
}))
|
||||
defer server.Stop()
|
||||
|
||||
ctx := svc.NewServiceContext(c)
|
||||
handler.RegisterHandlers(server, ctx)
|
||||
|
||||
fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
|
||||
server.Start()
|
||||
}
|
10
server/collection/etc/collection.yaml
Normal file
10
server/collection/etc/collection.yaml
Normal file
|
@ -0,0 +1,10 @@
|
|||
Name: collection
|
||||
Host: 0.0.0.0
|
||||
Port: 8888
|
||||
Timeout: 15000 #服务超时时间(毫秒)
|
||||
SourceMysql: fsreaderwriter:XErSYmLELKMnf3Dh@tcp(fusen.cdmigcvz3rle.us-east-2.rds.amazonaws.com:3306)/fusen
|
||||
SourceRabbitMq: ""
|
||||
Auth:
|
||||
AccessSecret: fusen2023
|
||||
AccessExpire: 2592000
|
||||
RefreshAfter: 1592000
|
13
server/collection/internal/config/config.go
Normal file
13
server/collection/internal/config/config.go
Normal file
|
@ -0,0 +1,13 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"fusenapi/server/collection/internal/types"
|
||||
"github.com/zeromicro/go-zero/rest"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
rest.RestConf
|
||||
SourceMysql string
|
||||
Auth types.Auth
|
||||
SourceRabbitMq string
|
||||
}
|
|
@ -6,27 +6,27 @@ import (
|
|||
|
||||
"fusenapi/utils/basic"
|
||||
|
||||
"fusenapi/server/product/internal/logic"
|
||||
"fusenapi/server/product/internal/svc"
|
||||
"fusenapi/server/product/internal/types"
|
||||
"fusenapi/server/collection/internal/logic"
|
||||
"fusenapi/server/collection/internal/svc"
|
||||
"fusenapi/server/collection/internal/types"
|
||||
)
|
||||
|
||||
func GetProductInfoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
func CollectProductHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var req types.GetProductInfoReq
|
||||
var req types.CollectProductReq
|
||||
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 创建一个业务逻辑层实例
|
||||
l := logic.NewGetProductInfoLogic(r.Context(), svcCtx)
|
||||
l := logic.NewCollectProductLogic(r.Context(), svcCtx)
|
||||
|
||||
rl := reflect.ValueOf(l)
|
||||
basic.BeforeLogic(w, r, rl)
|
||||
|
||||
resp := l.GetProductInfo(&req, userinfo)
|
||||
resp := l.CollectProduct(&req, userinfo)
|
||||
|
||||
if !basic.AfterLogic(w, r, rl, resp) {
|
||||
basic.NormalAfterLogic(w, r, resp)
|
22
server/collection/internal/handler/routes.go
Normal file
22
server/collection/internal/handler/routes.go
Normal file
|
@ -0,0 +1,22 @@
|
|||
// Code generated by goctl. DO NOT EDIT.
|
||||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"fusenapi/server/collection/internal/svc"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest"
|
||||
)
|
||||
|
||||
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||
server.AddRoutes(
|
||||
[]rest.Route{
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/api/collection/collect_product",
|
||||
Handler: CollectProductHandler(serverCtx),
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
|
@ -6,20 +6,20 @@ import (
|
|||
|
||||
"context"
|
||||
|
||||
"fusenapi/server/product/internal/svc"
|
||||
"fusenapi/server/product/internal/types"
|
||||
"fusenapi/server/collection/internal/svc"
|
||||
"fusenapi/server/collection/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetSizeByProductLogic struct {
|
||||
type CollectProductLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGetSizeByProductLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetSizeByProductLogic {
|
||||
return &GetSizeByProductLogic{
|
||||
func NewCollectProductLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CollectProductLogic {
|
||||
return &CollectProductLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
|
@ -27,10 +27,10 @@ func NewGetSizeByProductLogic(ctx context.Context, svcCtx *svc.ServiceContext) *
|
|||
}
|
||||
|
||||
// 处理进入前逻辑w,r
|
||||
// func (l *GetSizeByProductLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
||||
// func (l *CollectProductLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
||||
// }
|
||||
|
||||
func (l *GetSizeByProductLogic) GetSizeByProduct(req *types.Request, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||
func (l *CollectProductLogic) CollectProduct(req *types.CollectProductReq, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
||||
// userinfo 传入值时, 一定不为null
|
||||
|
||||
|
@ -38,6 +38,6 @@ func (l *GetSizeByProductLogic) GetSizeByProduct(req *types.Request, userinfo *a
|
|||
}
|
||||
|
||||
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
||||
// func (l *GetSizeByProductLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
||||
// func (l *CollectProductLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
||||
// // httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
// }
|
26
server/collection/internal/svc/servicecontext.go
Normal file
26
server/collection/internal/svc/servicecontext.go
Normal file
|
@ -0,0 +1,26 @@
|
|||
package svc
|
||||
|
||||
import (
|
||||
"fusenapi/initalize"
|
||||
"fusenapi/model/gmodel"
|
||||
"fusenapi/server/collection/internal/config"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type ServiceContext struct {
|
||||
Config config.Config
|
||||
MysqlConn *gorm.DB
|
||||
AllModels *gmodel.AllModelsGen
|
||||
RabbitMq *initalize.RabbitMqHandle
|
||||
}
|
||||
|
||||
func NewServiceContext(c config.Config) *ServiceContext {
|
||||
conn := initalize.InitMysql(c.SourceMysql)
|
||||
|
||||
return &ServiceContext{
|
||||
Config: c,
|
||||
MysqlConn: conn,
|
||||
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
||||
RabbitMq: initalize.InitRabbitMq(c.SourceRabbitMq, nil),
|
||||
}
|
||||
}
|
82
server/collection/internal/types/types.go
Normal file
82
server/collection/internal/types/types.go
Normal file
|
@ -0,0 +1,82 @@
|
|||
// Code generated by goctl. DO NOT EDIT.
|
||||
package types
|
||||
|
||||
import (
|
||||
"fusenapi/utils/basic"
|
||||
)
|
||||
|
||||
type CollectProductReq struct {
|
||||
ProductId int64 `json:"product_id"`
|
||||
Logo string `json:"logo"`
|
||||
SelectColorIndex int64 `json:"select_color_index"`
|
||||
TemplateTag string `json:"template_tag"`
|
||||
}
|
||||
|
||||
type Request struct {
|
||||
}
|
||||
|
||||
type Response struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"msg"`
|
||||
Data interface{} `json:"data"`
|
||||
}
|
||||
|
||||
type Auth struct {
|
||||
AccessSecret string `json:"accessSecret"`
|
||||
AccessExpire int64 `json:"accessExpire"`
|
||||
RefreshAfter int64 `json:"refreshAfter"`
|
||||
}
|
||||
|
||||
type File struct {
|
||||
Filename string `fsfile:"filename"`
|
||||
Header map[string][]string `fsfile:"header"`
|
||||
Size int64 `fsfile:"size"`
|
||||
Data []byte `fsfile:"data"`
|
||||
}
|
||||
|
||||
type Meta struct {
|
||||
TotalCount int64 `json:"total_count"`
|
||||
PageCount int64 `json:"page_count"`
|
||||
CurrentPage int `json:"current_page"`
|
||||
PerPage int `json:"per_page"`
|
||||
}
|
||||
|
||||
// Set 设置Response的Code和Message值
|
||||
func (resp *Response) Set(Code int, Message string) *Response {
|
||||
return &Response{
|
||||
Code: Code,
|
||||
Message: Message,
|
||||
}
|
||||
}
|
||||
|
||||
// Set 设置整个Response
|
||||
func (resp *Response) SetWithData(Code int, Message string, Data interface{}) *Response {
|
||||
return &Response{
|
||||
Code: Code,
|
||||
Message: Message,
|
||||
Data: Data,
|
||||
}
|
||||
}
|
||||
|
||||
// SetStatus 设置默认StatusResponse(内部自定义) 默认msg, 可以带data, data只使用一个参数
|
||||
func (resp *Response) SetStatus(sr *basic.StatusResponse, data ...interface{}) *Response {
|
||||
newResp := &Response{
|
||||
Code: sr.Code,
|
||||
}
|
||||
if len(data) == 1 {
|
||||
newResp.Data = data[0]
|
||||
}
|
||||
return newResp
|
||||
}
|
||||
|
||||
// SetStatusWithMessage 设置默认StatusResponse(内部自定义) 非默认msg, 可以带data, data只使用一个参数
|
||||
func (resp *Response) SetStatusWithMessage(sr *basic.StatusResponse, msg string, data ...interface{}) *Response {
|
||||
newResp := &Response{
|
||||
Code: sr.Code,
|
||||
Message: msg,
|
||||
}
|
||||
if len(data) == 1 {
|
||||
newResp.Data = data[0]
|
||||
}
|
||||
return newResp
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"reflect"
|
||||
|
||||
"fusenapi/utils/basic"
|
||||
|
||||
"fusenapi/server/product/internal/logic"
|
||||
"fusenapi/server/product/internal/svc"
|
||||
"fusenapi/server/product/internal/types"
|
||||
)
|
||||
|
||||
func DesignGatherHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var req types.DesignGatherReq
|
||||
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 创建一个业务逻辑层实例
|
||||
l := logic.NewDesignGatherLogic(r.Context(), svcCtx)
|
||||
|
||||
rl := reflect.ValueOf(l)
|
||||
basic.BeforeLogic(w, r, rl)
|
||||
|
||||
resp := l.DesignGather(&req, userinfo)
|
||||
|
||||
if !basic.AfterLogic(w, r, rl, resp) {
|
||||
basic.NormalAfterLogic(w, r, resp)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"reflect"
|
||||
|
||||
"fusenapi/utils/basic"
|
||||
|
||||
"fusenapi/server/product/internal/logic"
|
||||
"fusenapi/server/product/internal/svc"
|
||||
"fusenapi/server/product/internal/types"
|
||||
)
|
||||
|
||||
func GetLastProductDesignHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var req types.Request
|
||||
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 创建一个业务逻辑层实例
|
||||
l := logic.NewGetLastProductDesignLogic(r.Context(), svcCtx)
|
||||
|
||||
rl := reflect.ValueOf(l)
|
||||
basic.BeforeLogic(w, r, rl)
|
||||
|
||||
resp := l.GetLastProductDesign(&req, userinfo)
|
||||
|
||||
if !basic.AfterLogic(w, r, rl, resp) {
|
||||
basic.NormalAfterLogic(w, r, resp)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"reflect"
|
||||
|
||||
"fusenapi/utils/basic"
|
||||
|
||||
"fusenapi/server/product/internal/logic"
|
||||
"fusenapi/server/product/internal/svc"
|
||||
"fusenapi/server/product/internal/types"
|
||||
)
|
||||
|
||||
func GetProductDesignHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var req types.GetProductDesignReq
|
||||
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 创建一个业务逻辑层实例
|
||||
l := logic.NewGetProductDesignLogic(r.Context(), svcCtx)
|
||||
|
||||
rl := reflect.ValueOf(l)
|
||||
basic.BeforeLogic(w, r, rl)
|
||||
|
||||
resp := l.GetProductDesign(&req, userinfo)
|
||||
|
||||
if !basic.AfterLogic(w, r, rl, resp) {
|
||||
basic.NormalAfterLogic(w, r, resp)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"reflect"
|
||||
|
||||
"fusenapi/utils/basic"
|
||||
|
||||
"fusenapi/server/product/internal/logic"
|
||||
"fusenapi/server/product/internal/svc"
|
||||
"fusenapi/server/product/internal/types"
|
||||
)
|
||||
|
||||
func GetRenderDesignHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var req types.GetRenderDesignReq
|
||||
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 创建一个业务逻辑层实例
|
||||
l := logic.NewGetRenderDesignLogic(r.Context(), svcCtx)
|
||||
|
||||
rl := reflect.ValueOf(l)
|
||||
basic.BeforeLogic(w, r, rl)
|
||||
|
||||
resp := l.GetRenderDesign(&req, userinfo)
|
||||
|
||||
if !basic.AfterLogic(w, r, rl, resp) {
|
||||
basic.NormalAfterLogic(w, r, resp)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"reflect"
|
||||
|
||||
"fusenapi/utils/basic"
|
||||
|
||||
"fusenapi/server/product/internal/logic"
|
||||
"fusenapi/server/product/internal/svc"
|
||||
"fusenapi/server/product/internal/types"
|
||||
)
|
||||
|
||||
func GetSizeByProductHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var req types.Request
|
||||
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 创建一个业务逻辑层实例
|
||||
l := logic.NewGetSizeByProductLogic(r.Context(), svcCtx)
|
||||
|
||||
rl := reflect.ValueOf(l)
|
||||
basic.BeforeLogic(w, r, rl)
|
||||
|
||||
resp := l.GetSizeByProduct(&req, userinfo)
|
||||
|
||||
if !basic.AfterLogic(w, r, rl, resp) {
|
||||
basic.NormalAfterLogic(w, r, resp)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"reflect"
|
||||
|
||||
"fusenapi/utils/basic"
|
||||
|
||||
"fusenapi/server/product/internal/logic"
|
||||
"fusenapi/server/product/internal/svc"
|
||||
"fusenapi/server/product/internal/types"
|
||||
)
|
||||
|
||||
func OtherProductListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var req types.OtherProductListReq
|
||||
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 创建一个业务逻辑层实例
|
||||
l := logic.NewOtherProductListLogic(r.Context(), svcCtx)
|
||||
|
||||
rl := reflect.ValueOf(l)
|
||||
basic.BeforeLogic(w, r, rl)
|
||||
|
||||
resp := l.OtherProductList(&req, userinfo)
|
||||
|
||||
if !basic.AfterLogic(w, r, rl, resp) {
|
||||
basic.NormalAfterLogic(w, r, resp)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,46 +12,11 @@ import (
|
|||
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||
server.AddRoutes(
|
||||
[]rest.Route{
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/api/product/get-size-by-product",
|
||||
Handler: GetSizeByProductHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/api/product/design",
|
||||
Handler: GetProductDesignHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/api/product/design-gather",
|
||||
Handler: DesignGatherHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/api/product/info",
|
||||
Handler: GetProductInfoHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/api/product/save-design",
|
||||
Handler: SaveDesignHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/api/product/other-list",
|
||||
Handler: OtherProductListHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/api/product/tag_product_list",
|
||||
Handler: GetTagProductListHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/api/product/render_design",
|
||||
Handler: GetRenderDesignHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/api/product/get_model_by_pid",
|
||||
|
@ -97,11 +62,6 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|||
Path: "/api/product/get_render_setting_by_pid",
|
||||
Handler: GetRenderSettingByPidHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/api/product/get_last_product_design",
|
||||
Handler: GetLastProductDesignHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/api/product/recommand",
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"reflect"
|
||||
|
||||
"fusenapi/utils/basic"
|
||||
|
||||
"fusenapi/server/product/internal/logic"
|
||||
"fusenapi/server/product/internal/svc"
|
||||
"fusenapi/server/product/internal/types"
|
||||
)
|
||||
|
||||
func SaveDesignHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var req types.SaveDesignReq
|
||||
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 创建一个业务逻辑层实例
|
||||
l := logic.NewSaveDesignLogic(r.Context(), svcCtx)
|
||||
|
||||
rl := reflect.ValueOf(l)
|
||||
basic.BeforeLogic(w, r, rl)
|
||||
|
||||
resp := l.SaveDesign(&req, userinfo)
|
||||
|
||||
if !basic.AfterLogic(w, r, rl, resp) {
|
||||
basic.NormalAfterLogic(w, r, resp)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,159 +0,0 @@
|
|||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fusenapi/model/gmodel"
|
||||
"fusenapi/server/product/internal/svc"
|
||||
"fusenapi/server/product/internal/types"
|
||||
"fusenapi/utils/auth"
|
||||
"fusenapi/utils/basic"
|
||||
"fusenapi/utils/encryption_decryption"
|
||||
"fusenapi/utils/id_generator"
|
||||
"fusenapi/utils/ip"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type DesignGatherLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
ipAddr string
|
||||
}
|
||||
|
||||
func NewDesignGatherLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DesignGatherLogic {
|
||||
return &DesignGatherLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
// 处理进入前逻辑w,r
|
||||
func (l *DesignGatherLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
||||
//获取ip地址
|
||||
ipAddr, err := ip.GetClientIP(r)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return
|
||||
// return resp.SetStatusWithMessage(basic.CodeServiceErr, "client ip is not available")
|
||||
}
|
||||
l.ipAddr = ipAddr
|
||||
}
|
||||
|
||||
func (l *DesignGatherLogic) DesignGather(req *types.DesignGatherReq, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||
if l.ipAddr == "" {
|
||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "client ip is not available")
|
||||
}
|
||||
|
||||
encryptWebsetting, err := l.svcCtx.AllModels.FsWebSet.FindValueByKey(l.ctx, "is_encrypt")
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "web setting is_encrypt is not exists")
|
||||
}
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get web setting")
|
||||
}
|
||||
var postInfo map[string]interface{}
|
||||
//不加密
|
||||
if encryptWebsetting.Value == nil || *encryptWebsetting.Value == "0" {
|
||||
if err = json.Unmarshal([]byte(req.Data), &postInfo); err != nil {
|
||||
return resp.SetStatusWithMessage(basic.CodeJsonErr, "failed to parse json data,format may be invalid")
|
||||
}
|
||||
} else { //加密的
|
||||
//解密数据
|
||||
desData, err := encryption_decryption.CBCDecrypt(req.Data)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "failed to decryption data")
|
||||
}
|
||||
if err = json.Unmarshal([]byte(desData), &postInfo); err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeJsonErr, "failed to parse json data,format may be invalid")
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "client ip is not available")
|
||||
}
|
||||
postInfo["client_ip"] = l.ipAddr
|
||||
var (
|
||||
optionalId int64
|
||||
sizeId int64
|
||||
productId int64
|
||||
templateId int64
|
||||
materialId int64
|
||||
cover string
|
||||
info string
|
||||
clientNo string
|
||||
)
|
||||
//校验数据
|
||||
if _, ok := postInfo["optional_id"].(float64); !ok {
|
||||
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "invalid param optional_id")
|
||||
}
|
||||
optionalId = int64(postInfo["optional_id"].(float64))
|
||||
if _, ok := postInfo["size_id"].(float64); !ok {
|
||||
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "invalid param size_id")
|
||||
}
|
||||
sizeId = int64(postInfo["size_id"].(float64))
|
||||
if _, ok := postInfo["product_id"].(float64); !ok {
|
||||
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "invalid param product_id")
|
||||
}
|
||||
productId = int64(postInfo["product_id"].(float64))
|
||||
if _, ok := postInfo["template_id"].(float64); !ok {
|
||||
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "invalid param template_id")
|
||||
}
|
||||
templateId = int64(postInfo["template_id"].(float64))
|
||||
if _, ok := postInfo["material_id"].(float64); !ok {
|
||||
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "invalid param material_id")
|
||||
}
|
||||
materialId = int64(postInfo["material_id"].(float64))
|
||||
if _, ok := postInfo["client_no"].(string); !ok {
|
||||
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "invalid param client_no")
|
||||
}
|
||||
clientNo = postInfo["client_no"].(string)
|
||||
if postInfo["info"] == nil {
|
||||
info = ""
|
||||
} else {
|
||||
jsonInfoBytes, _ := json.Marshal(postInfo["info"])
|
||||
info = string(jsonInfoBytes)
|
||||
}
|
||||
if postInfo["cover"] != nil {
|
||||
cover = postInfo["cover"].(string)
|
||||
}
|
||||
//保存数据
|
||||
designSn, err := id_generator.GenSnowFlakeId()
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to generate design sn")
|
||||
}
|
||||
now := time.Now().UTC().Unix()
|
||||
err = l.svcCtx.AllModels.FsProductDesignGather.Create(l.ctx, &gmodel.FsProductDesignGather{
|
||||
Sn: &designSn,
|
||||
UserId: &userinfo.UserId,
|
||||
ProductId: &productId,
|
||||
TemplateId: &templateId,
|
||||
MaterialId: &materialId,
|
||||
SizeId: &sizeId,
|
||||
OptionalId: &optionalId,
|
||||
Cover: &cover,
|
||||
Info: &info,
|
||||
Utime: &now,
|
||||
ClientIp: &l.ipAddr,
|
||||
ClientNo: &clientNo,
|
||||
})
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeSaveErr, "failed to save data")
|
||||
}
|
||||
return resp.SetStatusWithMessage(basic.CodeOK, "success", types.DesignGatherRsp{
|
||||
Sn: designSn,
|
||||
})
|
||||
}
|
|
@ -1,106 +0,0 @@
|
|||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fusenapi/utils/auth"
|
||||
"fusenapi/utils/basic"
|
||||
|
||||
"fusenapi/server/product/internal/svc"
|
||||
"fusenapi/server/product/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetLastProductDesignLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGetLastProductDesignLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetLastProductDesignLogic {
|
||||
return &GetLastProductDesignLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetLastProductDesignLogic) GetLastProductDesign(req *types.Request, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||
if !userinfo.IsUser() {
|
||||
return resp.SetStatusAddMessage(basic.CodeUnAuth, "please sign in")
|
||||
}
|
||||
//获取用户信息
|
||||
// user, err := l.svcCtx.AllModels.FsUser.FindUserById(l.ctx, userinfo.UserId)
|
||||
// if err != nil {
|
||||
// if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
// return resp.SetStatusWithMessage(basic.CodeUnAuth, "user not found")
|
||||
// }
|
||||
// logx.Error(err)
|
||||
// return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get user info")
|
||||
// }
|
||||
// //若没打开了个性化渲染按钮
|
||||
// if *user.IsOpenRender != 1 {
|
||||
// return resp.SetStatusWithMessage(basic.CodeOK, "success:IsOpenRender switch is closed")
|
||||
// }
|
||||
//查询用户最近下单成功的数据
|
||||
// orderInfo, err := l.svcCtx.AllModels.FsOrder.FindLastSuccessOneOrder(l.ctx, user.Id, int64(constants.STATUS_NEW_NOT_PAY))
|
||||
// if err != nil {
|
||||
// if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
// return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "none of order is found")
|
||||
// }
|
||||
// logx.Error(err)
|
||||
// return resp.SetStatusAddMessage(basic.CodeDbSqlErr, "failed to get your last order")
|
||||
// }
|
||||
//获取该订单相关设计信息
|
||||
// orderDetail, err := l.svcCtx.AllModels.FsOrderDetail.GetOneOrderDetailByOrderId(l.ctx, orderInfo.Id)
|
||||
// if err != nil {
|
||||
// if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
// return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "order detail is not found")
|
||||
// }
|
||||
// logx.Error(err)
|
||||
// return resp.SetStatusAddMessage(basic.CodeDbSqlErr, "failed to get order detail")
|
||||
// }
|
||||
// //获取设计模板详情,便于获得design_id
|
||||
// orderDetailTemplate, err := l.svcCtx.AllModels.FsOrderDetailTemplate.FindOne(l.ctx, *orderDetail.OrderDetailTemplateId)
|
||||
// if err != nil {
|
||||
// if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
// return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "order detail template is not found")
|
||||
// }
|
||||
// logx.Error(err)
|
||||
// return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get order detail template")
|
||||
// }
|
||||
//最后一次设计不存在,则不返回该设计相关数据
|
||||
// if *orderDetailTemplate.DesignId <= 0 {
|
||||
// return resp.SetStatusWithMessage(basic.CodeOK, "success:last design id is not set")
|
||||
// }
|
||||
//获取设计数据
|
||||
// productDesign, err := l.svcCtx.AllModels.FsProductDesign.FindOne(l.ctx, *orderDetailTemplate.DesignId, user.Id)
|
||||
// if err != nil {
|
||||
// if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
// return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "product design is not found")
|
||||
// }
|
||||
// logx.Error(err)
|
||||
// return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product design")
|
||||
// }
|
||||
// var info interface{}
|
||||
// if productDesign.Info != nil && *productDesign.Info != "" {
|
||||
// if err := json.Unmarshal([]byte(*productDesign.Info), &info); err != nil {
|
||||
// logx.Error(err)
|
||||
// return nil
|
||||
// }
|
||||
// }
|
||||
// var logoColor interface{}
|
||||
// if productDesign.LogoColor != nil && *productDesign.LogoColor != "" {
|
||||
// if err := json.Unmarshal([]byte(*productDesign.LogoColor), &logoColor); err != nil {
|
||||
// logx.Error(err)
|
||||
// return nil
|
||||
// }
|
||||
// }
|
||||
return resp.SetStatusWithMessage(basic.CodeOK, "success", types.GetLastProductDesignRsp{
|
||||
Id: 1,
|
||||
OptionalId: 1,
|
||||
SizeId: 1,
|
||||
LogoColor: 1,
|
||||
Info: nil,
|
||||
})
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
package logic
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fusenapi/model/gmodel"
|
||||
"fusenapi/utils/auth"
|
||||
"fusenapi/utils/basic"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"context"
|
||||
|
||||
"fusenapi/server/product/internal/svc"
|
||||
"fusenapi/server/product/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetProductDesignLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGetProductDesignLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetProductDesignLogic {
|
||||
return &GetProductDesignLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetProductDesignLogic) GetProductDesign(req *types.GetProductDesignReq, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||
if userinfo.GetIdType() != auth.IDTYPE_User {
|
||||
return resp.SetStatusWithMessage(basic.CodeUnAuth, "please sign in first")
|
||||
}
|
||||
if req.Sn == "" {
|
||||
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "param sn is required")
|
||||
}
|
||||
//获取设计数据
|
||||
productDesignModel := gmodel.NewFsProductDesignModel(l.svcCtx.MysqlConn)
|
||||
designInfo, err := productDesignModel.FindOneBySn(l.ctx, req.Sn, userinfo.UserId)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "design info is not exists")
|
||||
}
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get design info")
|
||||
}
|
||||
//获取产品尺寸信息
|
||||
productSizeModel := gmodel.NewFsProductSizeModel(l.svcCtx.MysqlConn)
|
||||
sizeInfo, err := productSizeModel.FindOne(l.ctx, *designInfo.SizeId)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "product size info is not exists")
|
||||
}
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get product size info")
|
||||
}
|
||||
//获取模板信息
|
||||
productTemplateV2Model := gmodel.NewFsProductTemplateV2Model(l.svcCtx.MysqlConn)
|
||||
productTemplateV2Info, err := productTemplateV2Model.FindOne(l.ctx, *designInfo.TemplateId)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "template info is not exists")
|
||||
}
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get template info")
|
||||
}
|
||||
//获取产品模型信息
|
||||
productModel3dModel := gmodel.NewFsProductModel3dModel(l.svcCtx.MysqlConn)
|
||||
model3dInfo, err := productModel3dModel.FindOne(l.ctx, *designInfo.OptionalId)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "product 3D model info is not exists")
|
||||
}
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get product 3D model info")
|
||||
}
|
||||
optionalId := *designInfo.OptionalId
|
||||
if *model3dInfo.Status == 0 && *sizeInfo.Status == 1 && *productTemplateV2Info.Status == 1 && *productTemplateV2Info.IsDel == 0 {
|
||||
optionalId = 0
|
||||
}
|
||||
return resp.SetStatusWithMessage(basic.CodeOK, "success", types.GetProductDesignRsp{
|
||||
ProductId: *designInfo.ProductId,
|
||||
TemplateId: *designInfo.TemplateId,
|
||||
//MaterialId: *designInfo.MaterialId,
|
||||
SizeId: *designInfo.SizeId,
|
||||
OptionalId: optionalId,
|
||||
Cover: *designInfo.Cover,
|
||||
Info: *designInfo.Info,
|
||||
})
|
||||
}
|
|
@ -1,535 +0,0 @@
|
|||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"fusenapi/constants"
|
||||
"fusenapi/model/gmodel"
|
||||
"fusenapi/utils/auth"
|
||||
"fusenapi/utils/basic"
|
||||
"fusenapi/utils/color_list"
|
||||
"fusenapi/utils/encryption_decryption"
|
||||
"fusenapi/utils/format"
|
||||
"fusenapi/utils/image"
|
||||
"fusenapi/utils/step_price"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"gorm.io/gorm"
|
||||
|
||||
"fusenapi/server/product/internal/svc"
|
||||
"fusenapi/server/product/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetProductInfoLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGetProductInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetProductInfoLogic {
|
||||
return &GetProductInfoLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetProductInfoLogic) GetProductInfo(req *types.GetProductInfoReq, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||
//获取产品信息
|
||||
productInfo, err := l.svcCtx.AllModels.FsProduct.FindOneBySn(l.ctx, req.Pid)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "the product is not exists")
|
||||
}
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product info")
|
||||
}
|
||||
if req.Size > 0 {
|
||||
req.Size = image.GetCurrentSize(req.Size)
|
||||
}
|
||||
materialIdSlice, err := format.StrSlicToInt64Slice(strings.Split(*productInfo.MaterialIds, ","))
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to parse product material Id list")
|
||||
}
|
||||
//材料列表
|
||||
materials := make([]types.MaterialItem, 0, len(materialIdSlice))
|
||||
for _, v := range materialIdSlice {
|
||||
if title, ok := constants.MAP_MATERIAL[v]; ok {
|
||||
materials = append(materials, types.MaterialItem{
|
||||
Id: v,
|
||||
Title: title,
|
||||
})
|
||||
}
|
||||
}
|
||||
//尺寸列表
|
||||
sizeList, err := l.svcCtx.AllModels.FsProductSize.GetAllByStatus(l.ctx, int64(constants.FAQ_STATUS_ON), 1, "id,title,capacity,cover,sort,parts_can_deleted")
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product size list")
|
||||
}
|
||||
sizeIds := make([]int64, 0, len(sizeList))
|
||||
for _, v := range sizeList {
|
||||
sizeIds = append(sizeIds, v.Id)
|
||||
}
|
||||
//获取产品标签
|
||||
tagInfo, err := l.svcCtx.AllModels.FsTags.FindOne(l.ctx, *productInfo.Type)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "tag info is not exists")
|
||||
}
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get tag info")
|
||||
}
|
||||
typeName := *tagInfo.Title
|
||||
//获取该尺寸下的模型数据
|
||||
model3dList, err := l.svcCtx.AllModels.FsProductModel3d.GetAllBySizeIdsTag(l.ctx, sizeIds, constants.TAG_MODEL)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product 3d model list")
|
||||
}
|
||||
model3dIds := make([]int64, 0, len(model3dList))
|
||||
mapModel3dWithSizeIdIndex := make(map[int64]gmodel.FsProductModel3d) //sizeid为key
|
||||
for _, v := range model3dList {
|
||||
model3dIds = append(model3dIds, v.Id)
|
||||
mapModel3dWithSizeIdIndex[*v.SizeId] = v
|
||||
}
|
||||
//通过产品id和模型id获取模板信息
|
||||
productTemplateList, err := l.svcCtx.AllModels.FsProductTemplateV2.FindAllByProductIdModelIds(l.ctx, model3dIds, productInfo.Id)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product template list")
|
||||
}
|
||||
//获取模板包含的model_id
|
||||
mapTemplateModelId := make(map[int64]struct{})
|
||||
tagIds := make([]int64, 0, len(productTemplateList))
|
||||
for _, v := range productTemplateList {
|
||||
mapTemplateModelId[*v.ModelId] = struct{}{}
|
||||
if v.TemplateTag != nil && *v.TemplateTag != "" {
|
||||
tagId, err := strconv.ParseInt(*v.TemplateTag, 10, 64)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "tag is not a number")
|
||||
}
|
||||
tagIds = append(tagIds, tagId)
|
||||
}
|
||||
}
|
||||
//过滤没有模板的尺寸数据
|
||||
sizeListRsp := make([]types.SizeItem, 0, len(sizeList))
|
||||
for _, v := range sizeList {
|
||||
model3dInfo, ok := mapModel3dWithSizeIdIndex[v.Id]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if _, ok = mapTemplateModelId[model3dInfo.Id]; !ok {
|
||||
continue
|
||||
}
|
||||
var title types.SizeTitle
|
||||
if err = json.Unmarshal([]byte(*v.Title), &title); err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeJsonErr, "failed to parse size info`s title")
|
||||
}
|
||||
var modelInfo map[string]interface{}
|
||||
if model3dInfo.ModelInfo != nil && *model3dInfo.ModelInfo != "" {
|
||||
if err = json.Unmarshal([]byte(*model3dInfo.ModelInfo), &modelInfo); err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeJsonErr, "failed to parse model info")
|
||||
}
|
||||
}
|
||||
cover := ""
|
||||
if modelInfo["cover"] != nil && modelInfo["cover"].(string) != "" {
|
||||
cover = modelInfo["cover"].(string)
|
||||
if req.Size >= 200 {
|
||||
coverArr := strings.Split(modelInfo["cover"].(string), ".")
|
||||
cover = fmt.Sprintf("%s_%d.%s", coverArr[0], req.Size, coverArr[1])
|
||||
}
|
||||
}
|
||||
sizeListRsp = append(sizeListRsp, types.SizeItem{
|
||||
Id: v.Id,
|
||||
Title: title,
|
||||
Capacity: *v.Capacity,
|
||||
Cover: cover,
|
||||
Sort: *v.Sort,
|
||||
PartsCanDeleted: *v.PartsCanDeleted > 0,
|
||||
})
|
||||
}
|
||||
//获取标签列表
|
||||
tagList, err := l.svcCtx.AllModels.FsTags.GetAllByIdsWithoutStatus(l.ctx, tagIds)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get tag list")
|
||||
}
|
||||
mapTag := make(map[string]gmodel.FsTags)
|
||||
for _, v := range tagList {
|
||||
mapTag[fmt.Sprintf("%d", v.Id)] = v
|
||||
}
|
||||
//获取全部模型信息
|
||||
allModel3dList, err := l.svcCtx.AllModels.FsProductModel3d.GetAll(l.ctx)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get all 3d model list")
|
||||
}
|
||||
mapAllmodel3d := make(map[int64]gmodel.FsProductModel3d)
|
||||
optionTemplateIds := make([]int64, 0, len(allModel3dList))
|
||||
lightIds := make([]int64, 0, len(allModel3dList))
|
||||
for _, v := range allModel3dList {
|
||||
mapAllmodel3d[v.Id] = v
|
||||
optionTemplateIds = append(optionTemplateIds, *v.OptionTemplate)
|
||||
lightIds = append(lightIds, *v.Light)
|
||||
}
|
||||
//获取公共模板信息
|
||||
optionTemplateList, err := l.svcCtx.AllModels.FsProductTemplateV2.FindAllByIdsWithoutStatus(l.ctx, optionTemplateIds, "id,material_img")
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get option template list")
|
||||
}
|
||||
mapOptionTemplate := make(map[int64]gmodel.FsProductTemplateV2)
|
||||
for _, v := range optionTemplateList {
|
||||
mapOptionTemplate[v.Id] = v
|
||||
}
|
||||
//获取灯光信息
|
||||
lightList, err := l.svcCtx.AllModels.FsProductModel3dLight.GetAllByIdsWithoutStatus(l.ctx, lightIds)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get light list")
|
||||
}
|
||||
mapLight := make(map[int64]gmodel.FsProductModel3dLight)
|
||||
for _, v := range lightList {
|
||||
mapLight[v.Id] = v
|
||||
}
|
||||
//材料尺寸模板
|
||||
mapMaterialSizeTmp := make(map[string][]interface{})
|
||||
//循环阶梯价计算
|
||||
type MaterialSizePrice struct {
|
||||
Items []interface{} `json:"items"`
|
||||
MinPrice float64 `json:"min_price"`
|
||||
MaxPrice float64 `json:"max_price"`
|
||||
}
|
||||
mapMaterialSizePrice := make(map[string]*MaterialSizePrice)
|
||||
//循环处理组装模板信息
|
||||
for _, tmp := range productTemplateList {
|
||||
model3dInfo, ok := mapAllmodel3d[*tmp.ModelId]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
//如果是配件信息就跳过,不返回
|
||||
if *model3dInfo.Tag == constants.TAG_PARTS {
|
||||
continue
|
||||
}
|
||||
//未编辑模板信息的数据跳过
|
||||
if tmp.TemplateInfo == nil || *tmp.TemplateInfo == "" {
|
||||
continue
|
||||
}
|
||||
//解码template info
|
||||
var templateInfoRsp map[string]interface{}
|
||||
if tmp.TemplateInfo != nil && *tmp.TemplateInfo != "" {
|
||||
if err = json.Unmarshal([]byte(*tmp.TemplateInfo), &templateInfoRsp); err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeJsonErr, "failed to parse template info")
|
||||
}
|
||||
}
|
||||
if templateInfoRsp["cover"] != nil && templateInfoRsp["cover"].(string) != "" {
|
||||
cover := templateInfoRsp["cover"].(string)
|
||||
if req.Size >= 200 {
|
||||
coverArr := strings.Split(templateInfoRsp["cover"].(string), ".")
|
||||
cover = fmt.Sprintf("%s_%d.%s", coverArr[0], req.Size, coverArr[1])
|
||||
}
|
||||
templateInfoRsp["cover"] = cover
|
||||
delete(templateInfoRsp, "isPublic")
|
||||
delete(templateInfoRsp, "name")
|
||||
}
|
||||
//解码模型数据
|
||||
var modelInfoRsp map[string]interface{}
|
||||
if model3dInfo.ModelInfo != nil && *model3dInfo.ModelInfo != "" {
|
||||
if err = json.Unmarshal([]byte(*model3dInfo.ModelInfo), &modelInfoRsp); err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeJsonErr, "failed to parse model info")
|
||||
}
|
||||
}
|
||||
modelInfoRsp["id"] = model3dInfo.Id
|
||||
//解码灯光数据
|
||||
var lightInfoRsp interface{}
|
||||
lightInfo, ok := mapLight[*model3dInfo.Light]
|
||||
if ok && lightInfo.Info != nil && *lightInfo.Info != "" {
|
||||
if err = json.Unmarshal([]byte(*lightInfo.Info), &lightInfoRsp); err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeJsonErr, "failed to parse light info")
|
||||
}
|
||||
}
|
||||
//配件备选项
|
||||
modelPartIds, err := format.StrSlicToInt64Slice(strings.Split(*model3dInfo.PartList, ","))
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to parse 3d model`s part_list")
|
||||
}
|
||||
partListRsp := make([]interface{}, 0, len(modelPartIds))
|
||||
for _, partId := range modelPartIds {
|
||||
//判断配件信息是否正常
|
||||
temModelInfo, ok := mapAllmodel3d[partId]
|
||||
if !ok || *temModelInfo.Status != 1 {
|
||||
continue
|
||||
}
|
||||
var thisInfo map[string]interface{}
|
||||
temBytes, _ := json.Marshal(temModelInfo)
|
||||
_ = json.Unmarshal(temBytes, &thisInfo)
|
||||
thisInfo["material_img"] = ""
|
||||
if *temModelInfo.OptionTemplate != 0 {
|
||||
if optionTemplateInfo, ok := mapOptionTemplate[*temModelInfo.OptionTemplate]; ok {
|
||||
thisInfo["material_img"] = *optionTemplateInfo.MaterialImg
|
||||
}
|
||||
} else {
|
||||
tmpv2, err := l.svcCtx.AllModels.FsProductTemplateV2.FindOneByModelId(l.ctx, partId)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
|
||||
} else {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product template")
|
||||
}
|
||||
}
|
||||
thisInfo["material_img"] = *tmpv2.MaterialImg
|
||||
}
|
||||
partListRsp = append(partListRsp, thisInfo)
|
||||
}
|
||||
tagName := ""
|
||||
if tagData, ok := mapTag[*tmp.TemplateTag]; ok {
|
||||
tagName = *tagData.Title
|
||||
}
|
||||
//按照材质和尺寸来存放模板信息
|
||||
mapMaterialSizeTmpKey := l.getMapMaterialSizeTmpKey(*productInfo.MaterialIds, *model3dInfo.SizeId)
|
||||
mapMaterialSizeTmp[mapMaterialSizeTmpKey] = append(mapMaterialSizeTmp[mapMaterialSizeTmpKey], map[string]interface{}{
|
||||
"id": tmp.Id,
|
||||
"title": *tmp.Title,
|
||||
"templateData": templateInfoRsp,
|
||||
"modelData": modelInfoRsp,
|
||||
"lightData": lightInfoRsp,
|
||||
"partList": partListRsp,
|
||||
"tag_name": tagName,
|
||||
})
|
||||
}
|
||||
//产品价格查询
|
||||
productPriceList, err := l.svcCtx.AllModels.FsProductPrice.GetAllByProductIdStatus(l.ctx, productInfo.Id, 1)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product price list")
|
||||
}
|
||||
for _, priceItem := range productPriceList {
|
||||
stepNumSlice, err := format.StrSlicToIntSlice(strings.Split(*priceItem.StepNum, ","))
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "split step num err")
|
||||
}
|
||||
stepPriceSlice, err := format.StrSlicToIntSlice(strings.Split(*priceItem.StepPrice, ","))
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "split step price err")
|
||||
}
|
||||
lenStepNum := len(stepNumSlice)
|
||||
lenStepPrice := len(stepPriceSlice)
|
||||
if lenStepNum == 0 {
|
||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "count of step num is empty")
|
||||
}
|
||||
for *priceItem.MinBuyNum < int64(stepNumSlice[lenStepNum-1]+5) {
|
||||
price := step_price.GetCentStepPrice(int(*priceItem.MinBuyNum), stepNumSlice, stepPriceSlice)
|
||||
mapMaterialSizePriceKey := l.getMapMaterialSizePriceKey(*priceItem.MaterialId, *priceItem.SizeId)
|
||||
minPriceStr := fmt.Sprintf("%.2f", float64(stepPriceSlice[lenStepPrice-1])/100)
|
||||
minPrice, _ := strconv.ParseFloat(minPriceStr, 64)
|
||||
maxPriceStr := fmt.Sprintf("%.2f", float64(stepPriceSlice[0])/100)
|
||||
maxPrice, _ := strconv.ParseFloat(maxPriceStr, 64)
|
||||
if _, ok := mapMaterialSizePrice[mapMaterialSizePriceKey]; ok {
|
||||
mapMaterialSizePrice[mapMaterialSizePriceKey].Items = append(mapMaterialSizePrice[mapMaterialSizePriceKey].Items, map[string]interface{}{
|
||||
"num": *priceItem.MinBuyNum,
|
||||
"total_num": *priceItem.MinBuyNum * (*priceItem.EachBoxNum),
|
||||
"price": price,
|
||||
})
|
||||
mapMaterialSizePrice[mapMaterialSizePriceKey].MinPrice = minPrice
|
||||
mapMaterialSizePrice[mapMaterialSizePriceKey].MaxPrice = maxPrice
|
||||
} else {
|
||||
items := map[string]interface{}{
|
||||
"num": *priceItem.MinBuyNum,
|
||||
"total_num": *priceItem.MinBuyNum * (*priceItem.EachBoxNum),
|
||||
"price": price,
|
||||
}
|
||||
mapMaterialSizePrice[mapMaterialSizePriceKey] = &MaterialSizePrice{
|
||||
Items: []interface{}{items},
|
||||
MinPrice: minPrice,
|
||||
MaxPrice: maxPrice,
|
||||
}
|
||||
}
|
||||
*priceItem.MinBuyNum++
|
||||
}
|
||||
}
|
||||
isLowRendering := false
|
||||
isRemoveBg := false
|
||||
var lastDesign interface{}
|
||||
if userinfo.UserId != 0 {
|
||||
//获取用户信息
|
||||
user, err := l.svcCtx.AllModels.FsUser.FindUserById(l.ctx, userinfo.UserId)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "user info not found")
|
||||
}
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get user info")
|
||||
}
|
||||
isLowRendering = true
|
||||
isRemoveBg = true
|
||||
lastDesign = l.getLastDesign(user)
|
||||
}
|
||||
var renderDesign interface{}
|
||||
if req.HaveCloudRendering == true {
|
||||
renderDesign = l.getRenderDesign(req.ClientNo)
|
||||
}
|
||||
//查询是否是加密的(不太合理)
|
||||
encryptWebsetting, err := l.svcCtx.AllModels.FsWebSet.FindValueByKey(l.ctx, "is_encrypt")
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "web setting is_encrypt is not exists")
|
||||
}
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get web setting")
|
||||
}
|
||||
//不加密
|
||||
rspData := types.GetProductInfoRsp{
|
||||
Id: productInfo.Id,
|
||||
Type: *productInfo.Type,
|
||||
Title: *productInfo.Title,
|
||||
IsEnv: *productInfo.IsProtection,
|
||||
IsMicro: *productInfo.IsMicrowave,
|
||||
TypeName: typeName,
|
||||
IsLowRendering: isLowRendering,
|
||||
IsRemoveBg: isRemoveBg,
|
||||
Materials: materials,
|
||||
Sizes: sizeListRsp,
|
||||
Templates: mapMaterialSizeTmp,
|
||||
Prices: mapMaterialSizePrice,
|
||||
LastDesign: lastDesign,
|
||||
RenderDesign: renderDesign,
|
||||
Colors: color_list.GetColor(),
|
||||
}
|
||||
if encryptWebsetting.Value == nil || *encryptWebsetting.Value == "0" {
|
||||
return resp.SetStatusWithMessage(basic.CodeOK, "success", rspData)
|
||||
}
|
||||
bytesData, _ := json.Marshal(rspData)
|
||||
enData, err := encryption_decryption.CBCEncrypt(string(bytesData))
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to encryption response data")
|
||||
}
|
||||
return resp.SetStatusWithMessage(basic.CodeOK, "success", enData)
|
||||
}
|
||||
|
||||
// 获取渲染设计
|
||||
func (l *GetProductInfoLogic) getRenderDesign(clientNo string) interface{} {
|
||||
if clientNo == "" {
|
||||
return nil
|
||||
}
|
||||
renderDesign, err := l.svcCtx.AllModels.FsProductRenderDesign.FindOneRenderDesignByParams(l.ctx, gmodel.FindOneRenderDesignByParamsReq{
|
||||
ClientNo: &clientNo,
|
||||
Fields: "id,info,material_id,optional_id,size_id,template_id",
|
||||
OrderBy: "`id` DESC",
|
||||
})
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil
|
||||
}
|
||||
logx.Error(err)
|
||||
return nil
|
||||
}
|
||||
var info interface{}
|
||||
if renderDesign.Info != nil && *renderDesign.Info != "" {
|
||||
if err = json.Unmarshal([]byte(*renderDesign.Info), &info); err != nil {
|
||||
logx.Error(err)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return map[string]interface{}{
|
||||
"id": renderDesign.Id,
|
||||
"info": info,
|
||||
"material_id": *renderDesign.MaterialId,
|
||||
"optional_id": *renderDesign.OptionalId,
|
||||
"size_id": *renderDesign.SizeId,
|
||||
"template_id": *renderDesign.TemplateId,
|
||||
}
|
||||
}
|
||||
|
||||
// 获取用户最新设计
|
||||
func (l *GetProductInfoLogic) getLastDesign(userInfo gmodel.FsUser) interface{} {
|
||||
//查询用户最近下单成功的数据
|
||||
// orderInfo, err := l.svcCtx.AllModels.FsOrder.FindLastSuccessOneOrder(l.ctx, userInfo.Id, int64(constants.STATUS_NEW_NOT_PAY))
|
||||
// if err != nil {
|
||||
// if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
// return nil
|
||||
// }
|
||||
// logx.Error(err)
|
||||
// return nil
|
||||
// }
|
||||
//获取该订单相关设计信息
|
||||
// orderDetail, err := l.svcCtx.AllModels.FsOrderDetail.GetOneOrderDetailByOrderId(l.ctx, orderInfo.Id)
|
||||
// if err != nil {
|
||||
// if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
// return nil
|
||||
// }
|
||||
// logx.Error(err)
|
||||
// return nil
|
||||
// }
|
||||
// //获取设计模板详情,便于获得design_id
|
||||
// orderDetailTemplate, err := l.svcCtx.AllModels.FsOrderDetailTemplate.FindOne(l.ctx, *orderDetail.OrderDetailTemplateId)
|
||||
// if err != nil {
|
||||
// if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
// return nil
|
||||
// }
|
||||
// logx.Error(err)
|
||||
// return nil
|
||||
// }
|
||||
//若没打开了个性化渲染按钮或者最后一次设计不存在,则不返回该设计相关数据
|
||||
// if *userInfo.IsOpenRender != 1 || *orderDetailTemplate.DesignId <= 0 {
|
||||
// return nil
|
||||
// }
|
||||
// //获取设计数据
|
||||
// productDesign, err := l.svcCtx.AllModels.FsProductDesign.FindOne(l.ctx, *orderDetailTemplate.DesignId, userInfo.Id)
|
||||
// if err != nil {
|
||||
// if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
// return nil
|
||||
// }
|
||||
// logx.Error(err)
|
||||
// return nil
|
||||
// }
|
||||
// var info interface{}
|
||||
// if productDesign.Info != nil && *productDesign.Info != "" {
|
||||
// if err := json.Unmarshal([]byte(*productDesign.Info), &info); err != nil {
|
||||
// logx.Error(err)
|
||||
// return nil
|
||||
// }
|
||||
// }
|
||||
// var logoColor interface{}
|
||||
// if productDesign.LogoColor != nil && *productDesign.LogoColor != "" {
|
||||
// if err := json.Unmarshal([]byte(*productDesign.LogoColor), &logoColor); err != nil {
|
||||
// logx.Error(err)
|
||||
// return nil
|
||||
// }
|
||||
// }
|
||||
return map[string]interface{}{
|
||||
"id": 1,
|
||||
"info": 1,
|
||||
"logo_color": 1,
|
||||
"material_id": 1,
|
||||
"optional_id": 1,
|
||||
"size_id": 1,
|
||||
}
|
||||
}
|
||||
|
||||
// 获取按照材料跟尺寸分类的模板map key
|
||||
func (l *GetProductInfoLogic) getMapMaterialSizeTmpKey(materialIds string, sizeId int64) string {
|
||||
return fmt.Sprintf("%s_%d", materialIds, sizeId)
|
||||
}
|
||||
|
||||
// 获取按照材料跟尺寸分类的价格map key
|
||||
func (l *GetProductInfoLogic) getMapMaterialSizePriceKey(materialId int64, sizeId int64) string {
|
||||
return fmt.Sprintf("%d_%d", materialId, sizeId)
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
package logic
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fusenapi/model/gmodel"
|
||||
"fusenapi/utils/auth"
|
||||
"fusenapi/utils/basic"
|
||||
"gorm.io/gorm"
|
||||
"strings"
|
||||
|
||||
"context"
|
||||
|
||||
"fusenapi/server/product/internal/svc"
|
||||
"fusenapi/server/product/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetRenderDesignLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGetRenderDesignLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetRenderDesignLogic {
|
||||
return &GetRenderDesignLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetRenderDesignLogic) GetRenderDesign(req *types.GetRenderDesignReq, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||
req.Sn = strings.Trim(req.Sn, " ")
|
||||
if req.Sn == "" {
|
||||
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "err param:sn is empty")
|
||||
}
|
||||
renderDesign, err := l.svcCtx.AllModels.FsProductRenderDesign.FindOneRenderDesignByParams(l.ctx, gmodel.FindOneRenderDesignByParamsReq{
|
||||
Sn: &req.Sn,
|
||||
Fields: "id,info,material_id,optional_id,size_id,template_id",
|
||||
OrderBy: "`id` DESC",
|
||||
})
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "render design is not exists")
|
||||
}
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get render design info")
|
||||
}
|
||||
var color []string
|
||||
if renderDesign.LogoColor != nil && *renderDesign.LogoColor != "" {
|
||||
if err = json.Unmarshal([]byte(*renderDesign.LogoColor), &color); err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeJsonErr, "failed to parse render logo color")
|
||||
}
|
||||
}
|
||||
var info interface{}
|
||||
if renderDesign.Info != nil && *renderDesign.Info != "" {
|
||||
if err = json.Unmarshal([]byte(*renderDesign.Info), &info); err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeJsonErr, "failed to parse render design info")
|
||||
}
|
||||
}
|
||||
return resp.SetStatusWithMessage(basic.CodeOK, "success", types.GetRenderDesignRsp{
|
||||
Id: renderDesign.Id,
|
||||
Info: info,
|
||||
OptionalId: *renderDesign.OptionalId,
|
||||
SizeId: *renderDesign.SizeId,
|
||||
TemplateId: *renderDesign.TemplateId,
|
||||
LogoColor: color,
|
||||
})
|
||||
}
|
|
@ -1,142 +0,0 @@
|
|||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fusenapi/model/gmodel"
|
||||
"fusenapi/utils/auth"
|
||||
"fusenapi/utils/basic"
|
||||
"fusenapi/utils/format"
|
||||
"fusenapi/utils/image"
|
||||
"strings"
|
||||
|
||||
"gorm.io/gorm"
|
||||
|
||||
"fusenapi/server/product/internal/svc"
|
||||
"fusenapi/server/product/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type OtherProductListLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewOtherProductListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *OtherProductListLogic {
|
||||
return &OtherProductListLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *OtherProductListLogic) OtherProductList(req *types.OtherProductListReq, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||
if req.Num <= 0 || req.Num > 100 {
|
||||
req.Num = 4
|
||||
}
|
||||
if req.Size > 0 {
|
||||
req.Size = image.GetCurrentSize(req.Size)
|
||||
}
|
||||
//获取用户信息
|
||||
user, err := l.svcCtx.AllModels.FsUser.FindUserById(l.ctx, userinfo.UserId)
|
||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get user info")
|
||||
}
|
||||
tagInfo, err := l.svcCtx.AllModels.FsTags.FindOne(l.ctx, req.Cid)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "the tag info is not exists")
|
||||
}
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get tage info")
|
||||
}
|
||||
if *tagInfo.Status != 1 {
|
||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "tage info is not available")
|
||||
}
|
||||
if tagInfo.RecommendProduct == nil || *tagInfo.RecommendProduct == "" {
|
||||
return resp.SetStatusWithMessage(basic.CodeOK, "success")
|
||||
}
|
||||
pids, err := format.StrSlicToInt64Slice(strings.Split(*tagInfo.RecommendProduct, ","))
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to parse recommend product")
|
||||
}
|
||||
list, err := l.getRandom(pids, int(req.Num))
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get random list")
|
||||
}
|
||||
if req.Size <= 0 {
|
||||
return resp.SetStatusWithMessage(basic.CodeOK, "success,", list)
|
||||
}
|
||||
//千人前面处理
|
||||
for _, v := range list {
|
||||
r := &image.ThousandFaceImageFormatReq{
|
||||
Size: int(req.Size),
|
||||
IsThousandFace: 0,
|
||||
Cover: v.Cover,
|
||||
CoverImg: v.CoverImg,
|
||||
CoverDefault: "",
|
||||
ProductId: v.Id,
|
||||
UserId: user.Id,
|
||||
}
|
||||
if user.Id > 0 {
|
||||
r.IsThousandFace = 1
|
||||
}
|
||||
image.ThousandFaceImageFormat(r)
|
||||
v.Cover = r.Cover
|
||||
v.CoverImg = r.CoverImg
|
||||
v.CoverDefault = r.CoverDefault
|
||||
}
|
||||
return resp.SetStatusWithMessage(basic.CodeOK, "success,", list)
|
||||
}
|
||||
func (l *OtherProductListLogic) getRandom(productIds []int64, limit int) (result []types.OtherProductListRsp, err error) {
|
||||
if len(productIds) == 0 {
|
||||
return
|
||||
}
|
||||
//获取推荐产品信息
|
||||
recommendProductList, err := l.svcCtx.AllModels.FsProduct.GetRandomProductListInIds(l.ctx, productIds, limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(recommendProductList) == 0 {
|
||||
return
|
||||
}
|
||||
mapProduct := make(map[int64]int)
|
||||
newProductIds := make([]int64, 0, len(recommendProductList))
|
||||
for k, v := range recommendProductList {
|
||||
newProductIds = append(newProductIds, v.Id)
|
||||
mapProduct[v.Id] = k
|
||||
}
|
||||
//查询最新的sku
|
||||
reqStatus := int64(1)
|
||||
productTemplateIds, err := l.svcCtx.AllModels.FsProductTemplateV2.GetProductTemplateListByParams(l.ctx, gmodel.GetProductTemplateListByParamsReq{
|
||||
ProductIds: newProductIds,
|
||||
GroupBy: "product_id",
|
||||
OrderBy: "id DESC,sort DESC",
|
||||
Fields: "product_id,max(id) as id",
|
||||
Status: &reqStatus,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, v := range productTemplateIds {
|
||||
productIndex, ok := mapProduct[*v.ProductId]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
productInfo := recommendProductList[productIndex]
|
||||
result = append(result, types.OtherProductListRsp{
|
||||
Title: *productInfo.Title,
|
||||
Cover: *productInfo.Cover,
|
||||
CoverImg: *productInfo.CoverImg,
|
||||
Sn: *productInfo.Sn,
|
||||
Id: *v.ProductId,
|
||||
SkuId: v.Id,
|
||||
})
|
||||
}
|
||||
return result, nil
|
||||
}
|
|
@ -1,169 +0,0 @@
|
|||
package logic
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"fusenapi/constants"
|
||||
"fusenapi/model/gmodel"
|
||||
"fusenapi/utils/auth"
|
||||
"fusenapi/utils/basic"
|
||||
"fusenapi/utils/encryption_decryption"
|
||||
"fusenapi/utils/id_generator"
|
||||
"image"
|
||||
"image/gif"
|
||||
"image/jpeg"
|
||||
"image/png"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/nfnt/resize"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"context"
|
||||
|
||||
"fusenapi/server/product/internal/svc"
|
||||
"fusenapi/server/product/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type SaveDesignLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewSaveDesignLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SaveDesignLogic {
|
||||
return &SaveDesignLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *SaveDesignLogic) SaveDesign(req *types.SaveDesignReq, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||
if userinfo.GetIdType() != auth.IDTYPE_User {
|
||||
return resp.SetStatusWithMessage(basic.CodeUnAuth, "please sign in first")
|
||||
}
|
||||
//查询是否是加密的(不太合理)
|
||||
encryptWebsetting, err := l.svcCtx.AllModels.FsWebSet.FindValueByKey(l.ctx, "is_encrypt")
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "web setting is_encrypt is not exists")
|
||||
}
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get web setting")
|
||||
}
|
||||
var postInfo types.SaveDesignReqRealStruct
|
||||
//不加密
|
||||
if encryptWebsetting.Value == nil || *encryptWebsetting.Value == "0" {
|
||||
if err = json.Unmarshal([]byte(req.Data), &postInfo); err != nil {
|
||||
return resp.SetStatusWithMessage(basic.CodeJsonErr, "failed to parse json data,format may be invalid")
|
||||
}
|
||||
} else { //加密的
|
||||
//解密数据
|
||||
desData, err := encryption_decryption.CBCDecrypt(req.Data)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "failed to decryption data")
|
||||
}
|
||||
if err = json.Unmarshal([]byte(desData), &postInfo); err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeJsonErr, "failed to parse json data")
|
||||
}
|
||||
}
|
||||
infoBytes, _ := json.Marshal(postInfo.Data)
|
||||
info := string(infoBytes)
|
||||
now := time.Now().UTC()
|
||||
logoColorBytes, _ := json.Marshal(postInfo.Data.Logo.Colors)
|
||||
logoColor := string(logoColorBytes)
|
||||
saveData := gmodel.FsProductDesign{
|
||||
UserId: &userinfo.UserId,
|
||||
ProductId: &postInfo.ProductId,
|
||||
TemplateId: &postInfo.TemplateId,
|
||||
SizeId: &postInfo.SizeId,
|
||||
OptionalId: &postInfo.OptionalId,
|
||||
Cover: &postInfo.Cover,
|
||||
Info: &info,
|
||||
Utime: &now,
|
||||
LogoColor: &logoColor,
|
||||
PageGuid: &postInfo.PageGuid,
|
||||
}
|
||||
switch postInfo.Sn {
|
||||
case "": //新增
|
||||
status := int64(1)
|
||||
postInfo.Sn, err = id_generator.GenSnowFlakeId()
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to gen sn ")
|
||||
}
|
||||
saveData.Status = &status
|
||||
saveData.Sn = &postInfo.Sn
|
||||
err = l.svcCtx.AllModels.FsProductDesign.Create(l.ctx, &saveData)
|
||||
default: //更新
|
||||
err = l.svcCtx.AllModels.FsProductDesign.UpdateBySn(l.ctx, postInfo.Sn, &saveData)
|
||||
}
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to save design")
|
||||
}
|
||||
if postInfo.Cover == "" {
|
||||
return resp.SetStatusWithMessage(basic.CodeOK, "success", types.SaveDesignRsp{Sn: postInfo.Sn})
|
||||
}
|
||||
// TODO 图片待优化处理
|
||||
/*if err = l.CreateStepThumbnailImage(l.ctx, postInfo.Cover); err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to create step thumbnail image ")
|
||||
}*/
|
||||
return resp.SetStatusWithMessage(basic.CodeOK, "success", types.SaveDesignRsp{Sn: postInfo.Sn})
|
||||
}
|
||||
|
||||
// 创建阶梯缩略图
|
||||
func (l *SaveDesignLogic) CreateStepThumbnailImage(ctx context.Context, coverImage string) error {
|
||||
httpRsp, err := http.Get(coverImage)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer httpRsp.Body.Close()
|
||||
coverImg, _, err := image.Decode(httpRsp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
coverImgOrgWith := coverImg.Bounds().Dx()
|
||||
coverImgOrgHeight := coverImg.Bounds().Dy()
|
||||
fileExt := path.Ext(coverImage)
|
||||
for _, size := range constants.IMAGE_CROPPING_STEP_SIZE {
|
||||
//尺寸大于原图
|
||||
if size > coverImgOrgWith {
|
||||
continue
|
||||
}
|
||||
//缩放比例按照宽度来设定
|
||||
scale := size / coverImgOrgWith
|
||||
height := scale * coverImgOrgHeight
|
||||
tmpImage := resize.Resize(uint(size), uint(height), coverImg, resize.Lanczos3)
|
||||
fileName := fmt.Sprintf("%s_%d_%s", uuid.New().String(), size, fileExt)
|
||||
targetFile, err := os.Create(fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer targetFile.Close()
|
||||
switch fileExt {
|
||||
case ".png":
|
||||
err = png.Encode(targetFile, tmpImage)
|
||||
case ".jpg", ".jpeg":
|
||||
err = jpeg.Encode(targetFile, tmpImage, &jpeg.Options{Quality: 100})
|
||||
case ".gif":
|
||||
err = gif.Encode(targetFile, tmpImage, nil)
|
||||
default:
|
||||
err = errors.New("unSupport image format")
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -5,180 +5,6 @@ import (
|
|||
"fusenapi/utils/basic"
|
||||
)
|
||||
|
||||
type GetSizeByProductRsp struct {
|
||||
Id int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Children []Children `json:"children"`
|
||||
}
|
||||
|
||||
type Children struct {
|
||||
Id int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Cycle int `json:"cycle"`
|
||||
ChildrenList []ChildrenObj `json:"children"`
|
||||
}
|
||||
|
||||
type ChildrenObj struct {
|
||||
Id int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
PriceList []PriceObj `json:"price_list"`
|
||||
}
|
||||
|
||||
type PriceObj struct {
|
||||
Num int `json:"num"`
|
||||
Price float64 `json:"price"`
|
||||
}
|
||||
|
||||
type GetProductDesignReq struct {
|
||||
Sn string `form:"sn"`
|
||||
}
|
||||
|
||||
type GetProductDesignRsp struct {
|
||||
ProductId int64 `json:"product_id"`
|
||||
TemplateId int64 `json:"template_id"`
|
||||
SizeId int64 `json:"size_id"`
|
||||
OptionalId int64 `json:"optional_id"`
|
||||
Cover string `json:"cover"`
|
||||
Info string `json:"info"`
|
||||
}
|
||||
|
||||
type DesignGatherReq struct {
|
||||
Data string `json:"data"`
|
||||
}
|
||||
|
||||
type DesignGatherRsp struct {
|
||||
Sn string `json:"sn"`
|
||||
}
|
||||
|
||||
type GetProductInfoReq struct {
|
||||
Pid string `form:"pid"`
|
||||
Size uint32 `form:"size"`
|
||||
ClientNo string `form:"client_no"`
|
||||
HaveCloudRendering bool `form:"haveCloudRendering,optional"`
|
||||
}
|
||||
|
||||
type GetProductInfoRsp struct {
|
||||
Id int64 `json:"id"`
|
||||
Type int64 `json:"type"`
|
||||
Title string `json:"title"`
|
||||
IsEnv int64 `json:"isEnv"`
|
||||
IsMicro int64 `json:"isMicro"`
|
||||
TypeName string `json:"typeName"`
|
||||
IsLowRendering bool `json:"is_low_rendering"`
|
||||
IsRemoveBg bool `json:"is_remove_bg"`
|
||||
Materials []MaterialItem `json:"materials"`
|
||||
Sizes []SizeItem `json:"sizes"`
|
||||
Templates interface{} `json:"templates"`
|
||||
Prices interface{} `json:"prices"`
|
||||
LastDesign interface{} `json:"last_design"`
|
||||
RenderDesign interface{} `json:"render_design"`
|
||||
Colors interface{} `json:"colors"`
|
||||
}
|
||||
|
||||
type SizeItem struct {
|
||||
Id int64 `json:"id"`
|
||||
Title SizeTitle `json:"title"`
|
||||
Capacity string `json:"capacity"`
|
||||
Cover string `json:"cover"`
|
||||
Sort int64 `json:"sort"`
|
||||
PartsCanDeleted bool `json:"parts_can_deleted"`
|
||||
}
|
||||
|
||||
type SizeTitle struct {
|
||||
Cm string `json:"cm"`
|
||||
Inch string `json:"inch"`
|
||||
}
|
||||
|
||||
type MaterialItem struct {
|
||||
Id int64 `json:"id"`
|
||||
Title string `json:"title"`
|
||||
}
|
||||
|
||||
type SaveDesignReq struct {
|
||||
Data string `json:"data"` //加密信息
|
||||
}
|
||||
|
||||
type SaveDesignRsp struct {
|
||||
Sn string `json:"sn"`
|
||||
}
|
||||
|
||||
type SaveDesignReqRealStruct struct {
|
||||
ProductId int64 `json:"product_id"`
|
||||
SizeId int64 `json:"size_id"`
|
||||
OptionalId int64 `json:"optional_id"`
|
||||
TemplateId int64 `json:"template_id"`
|
||||
Sn string `json:"sn"`
|
||||
Data DesignData `json:"data"`
|
||||
Cover string `json:"cover"`
|
||||
PageGuid string `json:"pageGuid"`
|
||||
}
|
||||
|
||||
type DesignData struct {
|
||||
MainColor ColorFill `json:"MainColor"`
|
||||
SecondaryColor ColorFill `json:"SecondaryColor"`
|
||||
Logo DesignLogo `json:"Logo"`
|
||||
Slogan DesignSlogan `json:"Slogan"`
|
||||
QRcode DesignQRcode `json:"QRcode"`
|
||||
Website DesignWebsite `json:"Website"`
|
||||
Phone DesignPhone `json:"Phone"`
|
||||
Address DesignAddress `json:"Address"`
|
||||
}
|
||||
|
||||
type DesignAddress struct {
|
||||
Text string `json:"text"`
|
||||
IfShow bool `json:"ifShow"`
|
||||
}
|
||||
|
||||
type DesignPhone struct {
|
||||
Text string `json:"text"`
|
||||
IfShow bool `json:"ifShow"`
|
||||
}
|
||||
|
||||
type DesignWebsite struct {
|
||||
Text string `json:"text"`
|
||||
IfShow bool `json:"ifShow"`
|
||||
}
|
||||
|
||||
type DesignQRcode struct {
|
||||
Text string `json:"text"`
|
||||
SvgPath string `json:"svgPath"`
|
||||
IfShow bool `json:"ifShow"`
|
||||
}
|
||||
|
||||
type DesignSlogan struct {
|
||||
Text string `json:"text"`
|
||||
IfShow bool `json:"ifShow"`
|
||||
}
|
||||
|
||||
type DesignLogo struct {
|
||||
Material string `json:"material"`
|
||||
MaterialName string `json:"materialName"`
|
||||
MaterialTime string `json:"materialTime"`
|
||||
Fill string `json:"fill"`
|
||||
FillName string `json:"fill_name"`
|
||||
Colors []string `json:"colors"`
|
||||
}
|
||||
|
||||
type ColorFill struct {
|
||||
Fill string `json:"fill"`
|
||||
}
|
||||
|
||||
type OtherProductListReq struct {
|
||||
Cid int64 `form:"cid"`
|
||||
Num int64 `form:"num"`
|
||||
Size uint32 `form:"size"`
|
||||
}
|
||||
|
||||
type OtherProductListRsp struct {
|
||||
Title string `json:"title"`
|
||||
Cover string `json:"cover"`
|
||||
CoverImg string `json:"cover_img"`
|
||||
CoverDefault string `json:"cover_default"`
|
||||
Sn string `json:"sn"`
|
||||
Id int64 `json:"id"`
|
||||
SkuId int64 `json:"sku_id"`
|
||||
}
|
||||
|
||||
type GetRecommandProductListReq struct {
|
||||
Size int32 `form:"size,optional"`
|
||||
Num int64 `form:"num,optional"`
|
||||
|
@ -243,19 +69,6 @@ type CoverDefaultItem struct {
|
|||
CoverMetadata interface{} `json:"cover_metadata"`
|
||||
}
|
||||
|
||||
type GetRenderDesignReq struct {
|
||||
Sn string `form:"sn"`
|
||||
}
|
||||
|
||||
type GetRenderDesignRsp struct {
|
||||
Id int64 `json:"id"`
|
||||
Info interface{} `json:"info"`
|
||||
OptionalId int64 `json:"optional_id"`
|
||||
SizeId int64 `json:"size_id"`
|
||||
TemplateId int64 `json:"template_id"`
|
||||
LogoColor []string `json:"logo_color"`
|
||||
}
|
||||
|
||||
type GetModelByPidReq struct {
|
||||
Pid string `form:"pid"` //实际上是产品sn
|
||||
}
|
||||
|
@ -360,14 +173,6 @@ type GetRenderSettingByPidRsp struct {
|
|||
Colors interface{} `json:"colors"`
|
||||
}
|
||||
|
||||
type GetLastProductDesignRsp struct {
|
||||
Id int64 `json:"id"`
|
||||
OptionalId int64 `json:"optional_id"`
|
||||
SizeId int64 `json:"size_id"`
|
||||
LogoColor interface{} `json:"logo_color"`
|
||||
Info interface{} `json:"info"`
|
||||
}
|
||||
|
||||
type HomePageRecommendProductListReq struct {
|
||||
Size uint32 `form:"size"`
|
||||
MerchantType int64 `form:"merchant_type"`
|
||||
|
|
23
server_api/collection.api
Normal file
23
server_api/collection.api
Normal file
|
@ -0,0 +1,23 @@
|
|||
syntax = "v1"
|
||||
|
||||
info (
|
||||
title: "collection"// TODO: add title
|
||||
desc: "收藏服务"// TODO: add description
|
||||
author: ""
|
||||
email: ""
|
||||
)
|
||||
|
||||
import "basic.api"
|
||||
service collection {
|
||||
//收藏产品
|
||||
@handler CollectProductHandler
|
||||
post /api/collection/collect_product(CollectProductReq) returns (response);
|
||||
}
|
||||
|
||||
//收藏产品
|
||||
type CollectProductReq {
|
||||
ProductId int64 `json:"product_id"`
|
||||
Logo string `json:"logo"`
|
||||
SelectColorIndex int64 `json:"select_color_index"`
|
||||
TemplateTag string `json:"template_tag"`
|
||||
}
|
|
@ -10,31 +10,9 @@ info (
|
|||
import "basic.api"
|
||||
|
||||
service product {
|
||||
//获取分类下的产品以及尺寸
|
||||
@handler GetSizeByProductHandler
|
||||
get /api/product/get-size-by-product(request) returns (response);
|
||||
//获取保存的设计信息
|
||||
@handler GetProductDesignHandler
|
||||
get /api/product/design(GetProductDesignReq) returns (response);
|
||||
//产品设计数据采集
|
||||
@handler DesignGatherHandler
|
||||
post /api/product/design-gather(DesignGatherReq) returns (response);
|
||||
//获取产品信息
|
||||
@handler GetProductInfoHandler
|
||||
get /api/product/info(GetProductInfoReq) returns (response);
|
||||
//保存设计信息
|
||||
@handler SaveDesignHandler
|
||||
post /api/product/save-design(SaveDesignReq) returns (response);
|
||||
//其他产品推荐列表
|
||||
@handler OtherProductListHandler
|
||||
get /api/product/other-list(OtherProductListReq) returns (response);
|
||||
//获取分类产品列表
|
||||
@handler GetTagProductListHandler
|
||||
get /api/product/tag_product_list(GetTagProductListReq) returns (response);
|
||||
//*********************产品详情分解接口开始***********************
|
||||
//获取云渲染设计方案信息
|
||||
@handler GetRenderDesignHandler
|
||||
get /api/product/render_design(GetRenderDesignReq) returns (response);
|
||||
//获取产品模型信息
|
||||
@handler GetModelByPidHandler
|
||||
get /api/product/get_model_by_pid(GetModelByPidReq) returns (response);
|
||||
|
@ -62,178 +40,14 @@ service product {
|
|||
//获取产品渲染设置
|
||||
@handler GetRenderSettingByPidHandler
|
||||
get /api/product/get_render_setting_by_pid(GetRenderSettingByPidReq) returns (response);
|
||||
//获取产品千人千面设计方案
|
||||
@handler GetLastProductDesignHandler
|
||||
get /api/product/get_last_product_design(request) returns (response);
|
||||
//获取详情页推荐产品列表
|
||||
@handler GetRecommandProductListHandler
|
||||
get /api/product/recommand(GetRecommandProductListReq) returns (response);
|
||||
//获取列表页推荐产品列表
|
||||
@handler HomePageRecommendProductListHandler
|
||||
get /api/product/home_page_recommend(HomePageRecommendProductListReq) returns (response);
|
||||
//*********************产品详情分解接口结束***********************
|
||||
//*********************推荐产品接口开始××××××××××××××××××××××××××
|
||||
|
||||
//*********************推荐产品接口结束××××××××××××××××××××××××××
|
||||
}
|
||||
|
||||
//获取分类下的产品以及尺寸
|
||||
type GetSizeByProductRsp {
|
||||
Id int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Children []Children `json:"children"`
|
||||
}
|
||||
type Children {
|
||||
Id int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Cycle int `json:"cycle"`
|
||||
ChildrenList []ChildrenObj `json:"children"`
|
||||
}
|
||||
type ChildrenObj {
|
||||
Id int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
PriceList []PriceObj `json:"price_list"`
|
||||
}
|
||||
type PriceObj {
|
||||
Num int `json:"num"`
|
||||
Price float64 `json:"price"`
|
||||
}
|
||||
//获取保存的设计信息
|
||||
type GetProductDesignReq {
|
||||
Sn string `form:"sn"`
|
||||
}
|
||||
type GetProductDesignRsp {
|
||||
ProductId int64 `json:"product_id"`
|
||||
TemplateId int64 `json:"template_id"`
|
||||
//MaterialId int64 `json:"material_id"`
|
||||
SizeId int64 `json:"size_id"`
|
||||
OptionalId int64 `json:"optional_id"`
|
||||
Cover string `json:"cover"`
|
||||
Info string `json:"info"`
|
||||
}
|
||||
//产品设计数据采集
|
||||
type DesignGatherReq {
|
||||
Data string `json:"data"`
|
||||
}
|
||||
type DesignGatherRsp {
|
||||
Sn string `json:"sn"`
|
||||
}
|
||||
//获取产品信息
|
||||
type GetProductInfoReq {
|
||||
Pid string `form:"pid"`
|
||||
Size uint32 `form:"size"`
|
||||
ClientNo string `form:"client_no"`
|
||||
HaveCloudRendering bool `form:"haveCloudRendering,optional"`
|
||||
}
|
||||
type GetProductInfoRsp {
|
||||
Id int64 `json:"id"`
|
||||
Type int64 `json:"type"`
|
||||
Title string `json:"title"`
|
||||
IsEnv int64 `json:"isEnv"`
|
||||
IsMicro int64 `json:"isMicro"`
|
||||
TypeName string `json:"typeName"`
|
||||
IsLowRendering bool `json:"is_low_rendering"`
|
||||
IsRemoveBg bool `json:"is_remove_bg"`
|
||||
Materials []MaterialItem `json:"materials"`
|
||||
Sizes []SizeItem `json:"sizes"`
|
||||
Templates interface{} `json:"templates"`
|
||||
Prices interface{} `json:"prices"`
|
||||
LastDesign interface{} `json:"last_design"`
|
||||
RenderDesign interface{} `json:"render_design"`
|
||||
Colors interface{} `json:"colors"`
|
||||
}
|
||||
type SizeItem {
|
||||
Id int64 `json:"id"`
|
||||
Title SizeTitle `json:"title"`
|
||||
Capacity string `json:"capacity"`
|
||||
Cover string `json:"cover"`
|
||||
Sort int64 `json:"sort"`
|
||||
PartsCanDeleted bool `json:"parts_can_deleted"`
|
||||
}
|
||||
type SizeTitle {
|
||||
Cm string `json:"cm"`
|
||||
Inch string `json:"inch"`
|
||||
}
|
||||
type MaterialItem {
|
||||
Id int64 `json:"id"`
|
||||
Title string `json:"title"`
|
||||
}
|
||||
//保存设计信息
|
||||
type SaveDesignReq {
|
||||
Data string `json:"data"` //加密信息
|
||||
}
|
||||
type SaveDesignRsp {
|
||||
Sn string `json:"sn"`
|
||||
}
|
||||
//保存设计信息(解密结构体)
|
||||
type SaveDesignReqRealStruct {
|
||||
ProductId int64 `json:"product_id"`
|
||||
SizeId int64 `json:"size_id"`
|
||||
OptionalId int64 `json:"optional_id"`
|
||||
TemplateId int64 `json:"template_id"`
|
||||
Sn string `json:"sn"`
|
||||
Data DesignData `json:"data"`
|
||||
Cover string `json:"cover"`
|
||||
PageGuid string `json:"pageGuid"`
|
||||
}
|
||||
|
||||
type DesignData {
|
||||
MainColor ColorFill `json:"MainColor"`
|
||||
SecondaryColor ColorFill `json:"SecondaryColor"`
|
||||
Logo DesignLogo `json:"Logo"`
|
||||
Slogan DesignSlogan `json:"Slogan"`
|
||||
QRcode DesignQRcode `json:"QRcode"`
|
||||
Website DesignWebsite `json:"Website"`
|
||||
Phone DesignPhone `json:"Phone"`
|
||||
Address DesignAddress `json:"Address"`
|
||||
}
|
||||
type DesignAddress {
|
||||
Text string `json:"text"`
|
||||
IfShow bool `json:"ifShow"`
|
||||
}
|
||||
type DesignPhone {
|
||||
Text string `json:"text"`
|
||||
IfShow bool `json:"ifShow"`
|
||||
}
|
||||
type DesignWebsite {
|
||||
Text string `json:"text"`
|
||||
IfShow bool `json:"ifShow"`
|
||||
}
|
||||
type DesignQRcode {
|
||||
Text string `json:"text"`
|
||||
SvgPath string `json:"svgPath"`
|
||||
IfShow bool `json:"ifShow"`
|
||||
}
|
||||
type DesignSlogan {
|
||||
Text string `json:"text"`
|
||||
IfShow bool `json:"ifShow"`
|
||||
}
|
||||
type DesignLogo {
|
||||
Material string `json:"material"`
|
||||
MaterialName string `json:"materialName"`
|
||||
MaterialTime string `json:"materialTime"`
|
||||
Fill string `json:"fill"`
|
||||
FillName string `json:"fill_name"`
|
||||
Colors []string `json:"colors"`
|
||||
}
|
||||
type ColorFill {
|
||||
Fill string `json:"fill"`
|
||||
}
|
||||
//其他产品推荐列表
|
||||
type OtherProductListReq {
|
||||
Cid int64 `form:"cid"`
|
||||
Num int64 `form:"num"`
|
||||
Size uint32 `form:"size"`
|
||||
}
|
||||
type OtherProductListRsp {
|
||||
Title string `json:"title"`
|
||||
Cover string `json:"cover"`
|
||||
CoverImg string `json:"cover_img"`
|
||||
CoverDefault string `json:"cover_default"`
|
||||
Sn string `json:"sn"`
|
||||
Id int64 `json:"id"`
|
||||
SkuId int64 `json:"sku_id"`
|
||||
}
|
||||
//获取详情页推荐产品列表
|
||||
type GetRecommandProductListReq {
|
||||
Size int32 `form:"size,optional"`
|
||||
|
@ -294,19 +108,6 @@ type CoverDefaultItem {
|
|||
Cover string `json:"cover"`
|
||||
CoverMetadata interface{} `json:"cover_metadata"`
|
||||
}
|
||||
//获取云渲染设计方案信息
|
||||
type GetRenderDesignReq {
|
||||
Sn string `form:"sn"`
|
||||
}
|
||||
type GetRenderDesignRsp {
|
||||
Id int64 `json:"id"`
|
||||
Info interface{} `json:"info"`
|
||||
OptionalId int64 `json:"optional_id"`
|
||||
SizeId int64 `json:"size_id"`
|
||||
TemplateId int64 `json:"template_id"`
|
||||
LogoColor []string `json:"logo_color"`
|
||||
}
|
||||
|
||||
//获取产品模型信息
|
||||
type GetModelByPidReq {
|
||||
Pid string `form:"pid"` //实际上是产品sn
|
||||
|
@ -404,14 +205,6 @@ type GetRenderSettingByPidRsp {
|
|||
LastDesign bool `json:"last_design"` //是否拥有千人千面设计方案
|
||||
Colors interface{} `json:"colors"`
|
||||
}
|
||||
//获取产品千人千面设计方案
|
||||
type GetLastProductDesignRsp {
|
||||
Id int64 `json:"id"`
|
||||
OptionalId int64 `json:"optional_id"`
|
||||
SizeId int64 `json:"size_id"`
|
||||
LogoColor interface{} `json:"logo_color"`
|
||||
Info interface{} `json:"info"`
|
||||
}
|
||||
//获取列表页推荐产品(返回是这个维度数组)
|
||||
type HomePageRecommendProductListReq {
|
||||
Size uint32 `form:"size"`
|
||||
|
|
Loading…
Reference in New Issue
Block a user