fix:合图调整

This commit is contained in:
momo
2023-09-19 14:55:26 +08:00
161 changed files with 4621 additions and 1502 deletions

View File

@@ -74,7 +74,7 @@ func AutoGetEtcYaml() *string {
dirs = dirs[0 : len(dirs)-1]
// 列出所有 curPath 下的文件夹
files, err := ioutil.ReadDir(curPath)
files, err := os.ReadDir(curPath)
if err != nil {
log.Println(err)
continue

View File

@@ -1,7 +1,10 @@
package autoconfig
import "testing"
import (
"log"
"testing"
)
func TestAutoConfig(t *testing.T) {
AutoGetEtcYaml()
log.Println(*AutoGetEtcYaml())
}

View File

@@ -100,7 +100,12 @@ var (
CodeLogoCombineErr = &StatusResponse{5115, "logo combine fail"} // 合图失败
CodeLogoCombineNoFoundErr = &StatusResponse{5116, "template record not found"} // 模版不存在
CodeLogoSetTemplateErr = &StatusResponse{5117, "logo set template fail"} // 设置模版标签失败
CodeErrOrder = &StatusResponse{5300, "ocreate order failed"} // 订单错误
CodeErrOrderCreatShoppingCartEmpty = &StatusResponse{5301, "ocreate order failed, shopping cart is empty"} // 订单创建失败,购物车为空
CodeErrOrderCreatShoppingCartNotMatched = &StatusResponse{5302, "ocreate order failed, shopping cart not matched"} // 订单创建失败,购物车不相符
CodeErrOrderCreatProductAbsent = &StatusResponse{5303, "ocreate order failed, product is absent"} // 订单创建失败,商品不存在
CodeErrOrderCreatProductPriceAbsent = &StatusResponse{5304, "ocreate order failed, price of product is absent"} // 订单创建失败,商品价格不存在
CodeErrOrderCreatProductAccessoryAbsent = &StatusResponse{5305, "ocreate order failed, accessory of product is absent"} // 订单创建失败,商品配件不存在
)
type Response struct {

View File

@@ -119,7 +119,7 @@ func Array2MapByKey[KEY comparable, VALUE any](arrSrc []VALUE, fieldName string)
}
fv := srcv.FieldByName(fieldName)
k := fv.Interface().(KEY)
result[k] = srcv.Interface().(VALUE)
result[k] = arr.Index(i).Interface().(VALUE)
}
return result
@@ -166,7 +166,7 @@ func Array2MapByKeyTag[KEY comparable, VALUE any](arrSrc []VALUE, tag string) (r
fv = fv.Elem()
}
k := fv.Interface().(KEY)
result[k] = srcv.Interface().(VALUE)
result[k] = arr.Index(i).Interface().(VALUE)
}
return

View File

@@ -2,13 +2,7 @@ package configs
import (
"context"
"encoding/json"
"errors"
"fusenapi/constants"
"fusenapi/model/gmodel"
"strconv"
"github.com/zeromicro/go-zero/core/logx"
"gorm.io/gorm"
)
@@ -27,49 +21,49 @@ type WebSetTimeInfoData struct {
}
func GetOrderTimeConfig(ctx context.Context, db *gorm.DB) (res WebSetTimeInfo, err error) {
resData, err := gmodel.NewFsWebSetModel(db).FindValueByKey(ctx, string(constants.WEBSET_TIME_INFO))
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
res.ProductDay = int64(constants.ORDER_PRODUCT_DAY)
res.FactoryDeliverDay = int64(constants.ORDER_FACTORY_DELIVER_DAY)
res.DeliverUpsDay = int64(constants.ORDER_DELIVER_UPS_DAY)
res.UpsTransDay = int64(constants.ORDER_UPS_TRANS_DAY)
return res, nil
}
logx.Error(err)
return res, err
} else {
var timeInfo WebSetTimeInfoData
err = json.Unmarshal([]byte(*resData.Value), &timeInfo)
if err != nil {
logx.Error(err)
return res, err
}
productDay, err := strconv.Atoi(timeInfo.ProductDay)
if err != nil {
logx.Error(err)
return res, err
}
factoryDeliverDay, err := strconv.Atoi(timeInfo.FactoryDeliverDay)
if err != nil {
logx.Error(err)
return res, err
}
deliverUpsDay, err := strconv.Atoi(timeInfo.DeliverUpsDay)
if err != nil {
logx.Error(err)
return res, err
}
upsTransDay, err := strconv.Atoi(timeInfo.UpsTransDay)
if err != nil {
logx.Error(err)
return res, err
}
res.ProductDay = int64(productDay)
res.FactoryDeliverDay = int64(factoryDeliverDay)
res.DeliverUpsDay = int64(deliverUpsDay)
res.UpsTransDay = int64(upsTransDay)
}
// resData, err := gmodel.NewFsWebSetModel(db).FindValueByKey(ctx, string(constants.WEBSET_TIME_INFO))
// if err != nil {
// if errors.Is(err, gorm.ErrRecordNotFound) {
// res.ProductDay = int64(constants.ORDER_PRODUCT_DAY)
// res.FactoryDeliverDay = int64(constants.ORDER_FACTORY_DELIVER_DAY)
// res.DeliverUpsDay = int64(constants.ORDER_DELIVER_UPS_DAY)
// res.UpsTransDay = int64(constants.ORDER_UPS_TRANS_DAY)
// return res, nil
// }
// logx.Error(err)
// return res, err
// } else {
// var timeInfo WebSetTimeInfoData
// err = json.Unmarshal([]byte(*resData.Value), &timeInfo)
// if err != nil {
// logx.Error(err)
// return res, err
// }
// productDay, err := strconv.Atoi(timeInfo.ProductDay)
// if err != nil {
// logx.Error(err)
// return res, err
// }
// factoryDeliverDay, err := strconv.Atoi(timeInfo.FactoryDeliverDay)
// if err != nil {
// logx.Error(err)
// return res, err
// }
// deliverUpsDay, err := strconv.Atoi(timeInfo.DeliverUpsDay)
// if err != nil {
// logx.Error(err)
// return res, err
// }
// upsTransDay, err := strconv.Atoi(timeInfo.UpsTransDay)
// if err != nil {
// logx.Error(err)
// return res, err
// }
// res.ProductDay = int64(productDay)
// res.FactoryDeliverDay = int64(factoryDeliverDay)
// res.DeliverUpsDay = int64(deliverUpsDay)
// res.UpsTransDay = int64(upsTransDay)
// }
return res, nil
}

View File

@@ -5,9 +5,9 @@ import (
"strconv"
)
// 美分转美元
func CentoDollar(price int64) float64 {
str := fmt.Sprintf("%.2f", float64(price)/float64(100))
// 转美元
func CentitoDollar(price int64) float64 {
str := fmt.Sprintf("%.3f", float64(price)/float64(1000))
dollar, _ := strconv.ParseFloat(str, 64)
return dollar
}

1
utils/fsconfig/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
log

144
utils/fsconfig/config.go Normal file
View File

@@ -0,0 +1,144 @@
package fsconfig
import (
"log"
"os"
"path/filepath"
"strconv"
"strings"
"github.com/nacos-group/nacos-sdk-go/v2/clients"
"github.com/nacos-group/nacos-sdk-go/v2/common/constant"
"github.com/nacos-group/nacos-sdk-go/v2/vo"
"gopkg.in/yaml.v2"
)
type EnvConfig struct {
NacosServers []string `yaml:"nacos"`
UserName string `yaml:"username"`
Password string `yaml:"password"`
NamespaceId string `yaml:"namespace"`
DataId string `yaml:"dataid"`
Group string `yaml:"group"`
}
var optPathDirs = []string{"/opt", "./", "../", "../../"}
var nacosConfig *EnvConfig
func GetEnvCofing() *EnvConfig {
if nacosConfig != nil {
return nacosConfig
}
for _, optDir := range optPathDirs {
if optDir[len(optDir)-1] != '/' {
optDir = optDir + "/"
}
for _, yname := range []string{"env.yaml", "env.yml"} {
f, err := os.Open(optDir + yname)
if err != nil {
// log.Println(err)
continue
}
cfg := &EnvConfig{}
err = yaml.NewDecoder(f).Decode(&cfg)
if err != nil {
// log.Println(err)
continue
}
nacosConfig = cfg
return nacosConfig
}
}
panic("Can't find env.yaml or env.yml in the specified directories")
}
func init() {
}
func StartNacosConfig(configFile string, OnChange func(namespace, group, dataId, data string)) string {
env := GetEnvCofing()
// 创建serverConfig
// 支持多个;至少一个ServerConfig
var serverConfig []constant.ServerConfig
for _, s := range env.NacosServers {
sp := strings.Split(s, ":")
host := sp[0]
port, err := strconv.ParseUint(sp[1], 10, 64)
if err != nil {
panic(err)
}
serverConfig = append(serverConfig, constant.ServerConfig{
IpAddr: host,
Port: port,
})
}
// 创建clientConfig
clientConfig := constant.ClientConfig{
NamespaceId: env.NamespaceId, // 如果需要支持多namespace我们可以场景多个client,它们有不同的NamespaceId。当namespace是public时此处填空字符串。
TimeoutMs: 50000,
NotLoadCacheAtStart: true,
LogLevel: "debug",
LogDir: "/tmp/nacos/log",
CacheDir: "/tmp/nacos/cache",
Username: env.UserName,
Password: env.Password,
}
// 创建服务发现客户端的另一种方式 (推荐)
// namingClient, err := clients.NewNamingClient(
// vo.NacosClientParam{
// ClientConfig: &clientConfig,
// ServerConfigs: serverConfig,
// },
// )
// if err != nil {
// log.Fatalf("初始化nacos失败: %s", err.Error())
// }
// log.Println(namingClient)
// 创建 Nacos 配置客户端
configClient, err := clients.CreateConfigClient(map[string]interface{}{
"clientConfig": clientConfig,
"serverConfigs": serverConfig,
})
if err != nil {
log.Fatalf("Failed to create Nacos config client: %v", err)
}
cfgYamls := strings.Split(configFile, "/")
cfgYaml := cfgYamls[len(cfgYamls)-1]
yamlExt := filepath.Ext(cfgYaml)
if !(yamlExt == ".yaml" || yamlExt == ".yml") {
log.Panic(configFile)
}
// 获取配置
content, err := configClient.GetConfig(vo.ConfigParam{
DataId: cfgYaml,
Group: env.Group,
OnChange: OnChange,
})
if err != nil {
log.Fatalf("Failed to get config from Nacos: %v", err)
}
log.Println("加载成功:", cfgYaml)
return content
// log.Println(content)
}

View File

@@ -0,0 +1,10 @@
package fsconfig_test
import (
"fusenapi/utils/fsconfig"
"testing"
)
func TestCase1(t *testing.T) {
fsconfig.StartNacosConfig("auth.yaml", nil)
}

77
utils/order/order.go Normal file
View File

@@ -0,0 +1,77 @@
package order
import (
"fusenapi/model/gmodel"
)
type AmountCurrencyReq struct {
ExchangeRate int64 `json:"exchange_rate"` // 换算汇率
CurrentAmount int64 `json:"current_amount"` // 当前金额
OriginalAmount int64 `json:"original_amount"` // 原始金额
CurrentCurrency string `json:"current_currency"` // 当前货币
OriginalCurrency string `json:"original_currency"` // 原始货币
}
// 汇率换算
func GetAmountCurrency(req *AmountCurrencyReq) gmodel.AmountCurrency {
if req.CurrentAmount != 0 {
if req.CurrentCurrency == req.OriginalCurrency {
req.CurrentAmount = req.OriginalAmount
} else {
req.CurrentAmount = req.OriginalAmount * req.ExchangeRate
}
}
return gmodel.AmountCurrency{
ExchangeRate: req.ExchangeRate,
CurrentAmount: req.CurrentAmount,
OriginalAmount: req.OriginalAmount,
CurrentCurrency: req.CurrentCurrency,
OriginalCurrency: req.OriginalCurrency,
}
}
type GetAmountInfoReq struct {
ExchangeRate int64
Initiate int64
Current int64
Change int64
ChangeRemark string
Metadata map[string]interface{}
CurrentCurrency string
OriginalCurrency string
}
// Change AmountCurrency `json:"change,omitempty"` // 变动金额
// ChangeRemark string `json:"change_remark,omitempty"` // 变动备注
// Current AmountCurrency `json:"current"` // 当前金额
// Initiate AmountCurrency `json:"initiate"` // 初始金额
// Metadata map[string]interface{} `json:"metadata"` // 额外明细
func GetAmountInfo(req GetAmountInfoReq) gmodel.AmountInfo {
return gmodel.AmountInfo{
Change: GetAmountCurrency(&AmountCurrencyReq{
ExchangeRate: req.ExchangeRate,
CurrentAmount: req.Change,
OriginalAmount: req.Change,
CurrentCurrency: req.OriginalCurrency,
OriginalCurrency: req.OriginalCurrency,
}),
ChangeRemark: req.ChangeRemark,
Current: GetAmountCurrency(&AmountCurrencyReq{
ExchangeRate: req.ExchangeRate,
CurrentAmount: req.Current,
OriginalAmount: req.Current,
CurrentCurrency: req.OriginalCurrency,
OriginalCurrency: req.OriginalCurrency,
}),
Initiate: GetAmountCurrency(&AmountCurrencyReq{
ExchangeRate: req.ExchangeRate,
CurrentAmount: req.Initiate,
OriginalAmount: req.Initiate,
CurrentCurrency: req.OriginalCurrency,
OriginalCurrency: req.OriginalCurrency,
}),
Metadata: req.Metadata,
}
}

View File

@@ -0,0 +1,41 @@
package shopping_cart
// 购物车快照数据结构
type CartSnapshot struct {
Logo string `json:"logo"` //logo地址
CombineImage string `json:"combine_image"` //刀版图地址
RenderImage string `json:"render_image"` //渲染结果图
TemplateInfo TemplateInfo `json:"template_info"` //模板数据
ModelInfo ModelInfo `json:"model_info"` //模型的数据
FittingInfo FittingInfo `json:"fitting_info"` //配件信息
SizeInfo SizeInfo `json:"size_info"` //尺寸基本信息
ProductInfo ProductInfo `json:"product_info"` //产品基本信息(只记录不要使用)
UserDiyInformation UserDiyInformation `json:"user_diy_information"` //用户diy数据
}
type ProductInfo struct {
ProductName string `json:"product_name"`
ProductSn string `json:"product_sn"`
}
type ModelInfo struct {
ModelJson string `json:"model_json"` //模型设计json数据
}
type FittingInfo struct {
FittingJson string `json:"fitting_json"` //配件设计json数据
FittingName string `json:"fitting_name"` //配件名称
}
type TemplateInfo struct {
TemplateJson string `json:"template_json"` //模板设计json数据
TemplateTag string `json:"template_tag"` //模板标签
}
type SizeInfo struct {
Inch string `json:"inch"`
Cm string `json:"cm"`
Capacity string `json:"capacity"`
}
type UserDiyInformation struct {
Phone string `json:"phone"` //电话
Address string `json:"address"` //地址
Website string `json:"website"` //网站
Qrcode string `json:"qrcode"` //二维码
Slogan string `json:"slogan"` //slogan
}

View File

@@ -0,0 +1,102 @@
package shopping_cart
import (
"encoding/json"
"fusenapi/model/gmodel"
"fusenapi/utils/hash"
"strings"
)
// 校验购物车快照数据跟目前是否一致
type VerifyShoppingCartSnapshotDataChangeReq struct {
Carts []gmodel.FsShoppingCart
MapSize map[int64]gmodel.FsProductSize
MapModel map[int64]gmodel.FsProductModel3d //模型跟配件都在
MapTemplate map[int64]gmodel.FsProductTemplateV2
MapCartChange map[int64]string
MapSnapshot map[int64]CartSnapshot
MapProduct map[int64]gmodel.FsProduct
}
func VerifyShoppingCartSnapshotDataChange(req VerifyShoppingCartSnapshotDataChangeReq) error {
for _, cartInfo := range req.Carts {
descrptionBuilder := strings.Builder{}
//产品下架/删除
if _, ok := req.MapProduct[*cartInfo.ProductId]; !ok {
descrptionBuilder.WriteString("<p>the product is off shelf or deleted </p>")
}
var snapShotParseInfo CartSnapshot
if err := json.Unmarshal([]byte(*cartInfo.Snapshot), &snapShotParseInfo); err != nil {
return err
}
req.MapSnapshot[cartInfo.Id] = snapShotParseInfo
//快照中模板设计json数据哈希值
snapshotTemplateJsonHash := hash.JsonHashKey(snapShotParseInfo.TemplateInfo.TemplateJson)
//快照中模型设计json数据哈希值
snapshotModelJsonHash := hash.JsonHashKey(snapShotParseInfo.ModelInfo.ModelJson)
//快照中配件设计json数据哈希值
snapshotFittingJsonHash := hash.JsonHashKey(snapShotParseInfo.FittingInfo.FittingJson)
//有模板验证模板相关
if *cartInfo.TemplateId > 0 {
if curTemplateInfo, ok := req.MapTemplate[*cartInfo.TemplateId]; !ok {
descrptionBuilder.WriteString("<p>the template is lose</p>")
} else {
//当前模板设计json数据哈希值
curTemplateJsonHash := hash.JsonHashKey(*curTemplateInfo.TemplateInfo)
//模板设计信息改变了
if snapshotTemplateJsonHash != curTemplateJsonHash {
descrptionBuilder.WriteString("<p>the template design info has changed</p>")
}
//模板标签改变了
if snapShotParseInfo.TemplateInfo.TemplateTag != *curTemplateInfo.TemplateTag {
descrptionBuilder.WriteString("<p>the template`s template tag has changed</p>")
}
}
}
//有模型验证模型相关
if *cartInfo.ModelId > 0 {
if curModelInfo, ok := req.MapModel[*cartInfo.ModelId]; !ok { //不存在
descrptionBuilder.WriteString("<p>the model is lose</p>")
} else {
//当前模型设计json数据哈希值
curModelJsonHash := hash.JsonHashKey(*curModelInfo.ModelInfo)
if snapshotModelJsonHash != curModelJsonHash {
descrptionBuilder.WriteString("<p>the model design info has changed</p>")
}
}
}
//有配件验证配件相关
if *cartInfo.FittingId > 0 {
if curFittingInfo, ok := req.MapModel[*cartInfo.FittingId]; !ok { //不存在
descrptionBuilder.WriteString("<p>the fitting is lose</p>")
} else {
//当前配件设计json数据哈希值
curFittingJsonHash := hash.JsonHashKey(*curFittingInfo.ModelInfo)
if snapshotFittingJsonHash != curFittingJsonHash {
descrptionBuilder.WriteString("<p>the fitting design info has changed</p>")
}
}
}
//验证尺寸相关
if *cartInfo.SizeId > 0 {
curSize, ok := req.MapSize[*cartInfo.SizeId]
if !ok {
descrptionBuilder.WriteString("<p>the size is lose</p>")
} else {
var curSizeTitle SizeInfo
if err := json.Unmarshal([]byte(*curSize.Title), &curSizeTitle); err != nil {
return err
}
if snapShotParseInfo.SizeInfo.Inch != curSizeTitle.Inch || snapShotParseInfo.SizeInfo.Cm != curSizeTitle.Cm {
descrptionBuilder.WriteString("<p>the size design info has changed</p>")
}
}
}
//收集错误
descrption := descrptionBuilder.String()
if descrption != "" {
req.MapCartChange[cartInfo.Id] = descrption
}
}
return nil
}

View File

@@ -3,20 +3,20 @@ package step_price
// 返回美元
func GetStepPrice(minBuyNum int, stepNum []int, stepPrice []int) float64 {
if minBuyNum > stepNum[len(stepNum)-1] {
return float64(stepPrice[len(stepPrice)-1]) / float64(100)
return float64(stepPrice[len(stepPrice)-1]) / float64(1000)
}
for k, v := range stepNum {
if minBuyNum <= v {
if k <= (len(stepPrice) - 1) {
return float64(stepPrice[k]) / float64(100)
return float64(stepPrice[k]) / float64(1000)
}
return float64(stepPrice[len(stepPrice)-1]) / float64(100)
return float64(stepPrice[len(stepPrice)-1]) / float64(1000)
}
}
return float64(stepPrice[len(stepPrice)-1]) / float64(100)
return float64(stepPrice[len(stepPrice)-1]) / float64(1000)
}
// 返回美分
// 返回
func GetCentStepPrice(minBuyNum int, stepNum []int, stepPrice []int) int64 {
if minBuyNum > stepNum[len(stepNum)-1] {
return int64(stepPrice[len(stepPrice)-1])

View File

@@ -15,17 +15,22 @@ type RenderImageReqMsg struct {
RenderData RenderData `json:"render_data"`
}
type RenderData struct {
TemplateTag string `json:"template_tag"` //模板标签(必须)
ProductId int64 `json:"product_id"` //产品id(必须)
Website string `json:"website"` //网站(可选)
Slogan string `json:"slogan"` //slogan(可选)
Address string `json:"address"` //地址(可选)
Phone string `json:"phone"` //电话(可选)
Qrcode string `json:"qrcode"` //二维码(可选)
ProductSizeId int64 `json:"product_size_id"` //尺寸id(可选)
UserId int64 `json:"user_id"` //用户id(websocket连接建立再赋值)
GuestId int64 `json:"guest_id"` //游客id(websocket连接建立再赋值)
Logo string `json:"logo"` //log资源地址(websocket连接建立再赋值)
TemplateTag string `json:"template_tag"` //模板标签(必须)
TemplateTagColor TemplateTagColor `json:"template_tag_color"` //模板标签组合颜色
ProductId int64 `json:"product_id"` //产品id(必须)
Website string `json:"website"` //网站(可选)
Slogan string `json:"slogan"` //slogan(可选)
Address string `json:"address"` //地址(可选)
Phone string `json:"phone"` //电话(可选)
Qrcode string `json:"qrcode"` //二维码(可选)
ProductSizeId int64 `json:"product_size_id"` //尺寸id(可选)
UserId int64 `json:"user_id"` //用户id(websocket连接建立再赋值)
GuestId int64 `json:"guest_id"` //游客id(websocket连接建立再赋值)
Logo string `json:"logo"` //log资源地址(websocket连接建立再赋值)
}
type TemplateTagColor struct {
Color [][]string `json:"color"` //颜色组合
SelectedIndex int `json:"selected_index"` //主色的下标索引
}
// websocket发送渲染完的数据