Commit 21f42d26 by hcy

Merge branch 'hcy/2025.9.10-香港自营' into dev

parents b2fe0668 932a1cb0
/go.sum
/.idea/
gowatch.yml
*.exe
*.exe~
cmd.exe~
/cmd/logs/
/cmd/*.exe~
/cmd/logs
/bat/logs/
/conf/prod/*.ini
/go.mod
/logs
/mylogs
/doc/test
/vm.sh
/cmd/http
/doc/spuTest
/doc/test3
/.history
/.vscode
...@@ -4,9 +4,11 @@ import ( ...@@ -4,9 +4,11 @@ import (
"flag" "flag"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/micro/go-micro/v2/web" "github.com/micro/go-micro/v2/web"
"github.com/syyongx/php2go"
"go_sku_server/boot" "go_sku_server/boot"
"go_sku_server/pkg/config" "go_sku_server/pkg/config"
"go_sku_server/routes" "go_sku_server/routes"
"go_sku_server/service"
) )
func main() { func main() {
...@@ -16,21 +18,23 @@ func main() { ...@@ -16,21 +18,23 @@ func main() {
if err := boot.Boot(path); err != nil { if err := boot.Boot(path); err != nil {
panic(err) panic(err)
} }
Self_supplier_code_str := config.Get("web.self_supplier_code").String()
service.Self_supplier_code = php2go.Explode(",", Self_supplier_code_str)
gin.SetMode(config.Get("web.mode").String()) gin.SetMode(config.Get("web.mode").String())
r := routes.InitRouter() r := routes.InitRouter()
port := config.Get("web.port").String() port := config.Get("web.port").String()
//web改成micro 就是grpc,并直接注册到etcd里面 //web改成micro 就是grpc,并直接注册到etcd里面
service := web.NewService( serviceT := web.NewService(
web.Name("go.micro.api.http.search"), web.Name("go.micro.api.http.search"),
web.Handler(r), web.Handler(r),
web.Address(":"+port), web.Address(":"+port),
) )
if err := service.Init(); err != nil { if err := serviceT.Init(); err != nil {
panic(err) panic(err)
} }
if err := service.Run(); err != nil { if err := serviceT.Run(); err != nil {
panic(err) panic(err)
} }
......
...@@ -4,9 +4,11 @@ import ( ...@@ -4,9 +4,11 @@ import (
"flag" "flag"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/micro/go-micro/v2/web" "github.com/micro/go-micro/v2/web"
"github.com/syyongx/php2go"
"go_sku_server/boot" "go_sku_server/boot"
"go_sku_server/pkg/config" "go_sku_server/pkg/config"
"go_sku_server/routes" "go_sku_server/routes"
"go_sku_server/service"
) )
func main() { func main() {
...@@ -16,6 +18,8 @@ func main() { ...@@ -16,6 +18,8 @@ func main() {
if err := boot.Boot(path); err != nil { if err := boot.Boot(path); err != nil {
panic(err) panic(err)
} }
Self_supplier_code_str := config.Get("web.self_supplier_code").String()
service.Self_supplier_code = php2go.Explode(",", Self_supplier_code_str)
gin.SetMode(config.Get("web.mode").String()) gin.SetMode(config.Get("web.mode").String())
r := routes.InitRouter() r := routes.InitRouter()
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
port = 60014 port = 60014
mode = debug mode = debug
cors_domain = http://bom.liexin.com cors_domain = http://bom.liexin.com
;专营自营
self_supplier_code =L0012413,L0017764,L0018319,L0018562
[message] [message]
api_domain = http://api.ichunt.com/msg/sendMessageByAuto api_domain = http://api.ichunt.com/msg/sendMessageByAuto
...@@ -16,3 +18,5 @@ SEARCH_API_MONITOR = 6d0fa85e01a02c39347d011ae973fd21b76c6c7ce582d3ea470c6b65a31 ...@@ -16,3 +18,5 @@ SEARCH_API_MONITOR = 6d0fa85e01a02c39347d011ae973fd21b76c6c7ce582d3ea470c6b65a31
[spu_server] [spu_server]
;api_domain = http://192.168.2.72:8005 ;api_domain = http://192.168.2.72:8005
api_domain = http://localhost:8005 api_domain = http://localhost:8005
...@@ -4,4 +4,11 @@ host = 192.168.1.237:27017 ...@@ -4,4 +4,11 @@ host = 192.168.1.237:27017
username = "ichunt" username = "ichunt"
password = "huntmon6699" password = "huntmon6699"
database = ichunt database = ichunt
maxPoolSize=8000
[pre_sku_mongo]
host = 192.168.1.237:27017
username = "ichunt"
password = "huntmon6699"
database = ichunt
maxPoolSize=8000 maxPoolSize=8000
\ No newline at end of file
...@@ -2,15 +2,16 @@ package controller ...@@ -2,15 +2,16 @@ package controller
import ( import (
"encoding/json" "encoding/json"
"github.com/gin-gonic/gin"
"github.com/gogf/gf/util/gconv"
"github.com/syyongx/php2go"
"go_sku_server/pkg/common" "go_sku_server/pkg/common"
"go_sku_server/pkg/gredis" "go_sku_server/pkg/gredis"
"go_sku_server/pkg/logger" "go_sku_server/pkg/logger"
"go_sku_server/service" "go_sku_server/service"
"sync" "sync"
"time" "time"
"github.com/gin-gonic/gin"
"github.com/gogf/gf/util/gconv"
"github.com/syyongx/php2go"
) )
const goodsSliceCount = 10 //每多少个型号id开启一个协程 const goodsSliceCount = 10 //每多少个型号id开启一个协程
...@@ -52,11 +53,16 @@ func CommonController(ctx *gin.Context) map[string]interface{} { ...@@ -52,11 +53,16 @@ func CommonController(ctx *gin.Context) map[string]interface{} {
return nil return nil
} }
ch := make(chan sync.Map) //管道 var wg sync.WaitGroup
p := 0 //总共协程 ch := make(chan sync.Map, 50) //管道
zyGoodsId := make([]string, 0)
lyGoodsId := make([]string, 0) zyGoodsId := make([]string, 0, goodsSliceCount)
lyGoodsId := make([]string, 0, goodsSliceCount)
for _, goodsId := range goodsIdArr { for _, goodsId := range goodsIdArr {
//if len(goodsIdArr) > 100 {
// common.Output(ctx, 1001, "查询型号ID不得超过100个", "")
// return nil
//}
if goodsId == "" { if goodsId == "" {
continue continue
} }
...@@ -65,20 +71,32 @@ func CommonController(ctx *gin.Context) map[string]interface{} { ...@@ -65,20 +71,32 @@ func CommonController(ctx *gin.Context) map[string]interface{} {
if len(zyGoodsId) >= goodsSliceCount { if len(zyGoodsId) >= goodsSliceCount {
common.PrintDebugHtml(ctx, "zy增加协程1001:") common.PrintDebugHtml(ctx, "zy增加协程1001:")
common.PrintDebugHtml(ctx, zyGoodsId) common.PrintDebugHtml(ctx, zyGoodsId)
//wg.Add(1) //协程计数一 wg.Add(1) //协程计数一
go zyService.ZyGoodsDetail(ctx, zyGoodsId, ch)
zyGoodsId = zyGoodsId[:0:0] idsToProcess := make([]string, len(zyGoodsId))
p++ copy(idsToProcess, zyGoodsId)
go func(ctx_in *gin.Context, goodsIds_in []string, chs_in chan sync.Map) {
defer wg.Done()
zyService.ZyGoodsDetail(ctx_in, goodsIds_in, chs_in)
}(ctx, idsToProcess, ch)
zyGoodsId = zyGoodsId[:0]
} }
} else { //联营 } else { //联营
lyGoodsId = append(lyGoodsId, goodsId) lyGoodsId = append(lyGoodsId, goodsId)
if len(lyGoodsId) >= goodsSliceCount { if len(lyGoodsId) >= goodsSliceCount {
common.PrintDebugHtml(ctx, "ly增加协程1002:") common.PrintDebugHtml(ctx, "ly增加协程1002:")
common.PrintDebugHtml(ctx, lyGoodsId) common.PrintDebugHtml(ctx, lyGoodsId)
//wg.Add(1) wg.Add(1)
go lyService.LyGoodsDetail(ctx, lyGoodsId, ch)
lyGoodsId = lyGoodsId[:0:0] idsToProcess := make([]string, len(lyGoodsId))
p++ copy(idsToProcess, lyGoodsId)
go func(ctx_in *gin.Context, goodsIds_in []string, chs_in chan sync.Map) {
defer wg.Done()
lyService.LyGoodsDetail(ctx_in, goodsIds_in, chs_in)
}(ctx, idsToProcess, ch)
lyGoodsId = lyGoodsId[:0]
} }
} }
} }
...@@ -86,35 +104,55 @@ func CommonController(ctx *gin.Context) map[string]interface{} { ...@@ -86,35 +104,55 @@ func CommonController(ctx *gin.Context) map[string]interface{} {
if len(zyGoodsId) > 0 { if len(zyGoodsId) > 0 {
common.PrintDebugHtml(ctx, "zy增加协程1003:") common.PrintDebugHtml(ctx, "zy增加协程1003:")
common.PrintDebugHtml(ctx, zyGoodsId) common.PrintDebugHtml(ctx, zyGoodsId)
//wg.Add(1) //协程计数一 wg.Add(1) //协程计数一
go zyService.ZyGoodsDetail(ctx, zyGoodsId, ch)
p++ idsToProcess := make([]string, len(zyGoodsId))
copy(idsToProcess, zyGoodsId)
go func(ctx_in *gin.Context, goodsIds_in []string, chs_in chan sync.Map) {
defer wg.Done()
zyService.ZyGoodsDetail(ctx_in, goodsIds_in, chs_in)
}(ctx, zyGoodsId, ch)
} }
if len(lyGoodsId) > 0 { if len(lyGoodsId) > 0 {
common.PrintDebugHtml(ctx, "ly增加协程1004:") common.PrintDebugHtml(ctx, "ly增加协程1004:")
common.PrintDebugHtml(ctx, zyGoodsId) common.PrintDebugHtml(ctx, lyGoodsId)
go lyService.LyGoodsDetail(ctx, lyGoodsId, ch) wg.Add(1)
p++
idsToProcess := make([]string, len(lyGoodsId))
copy(idsToProcess, lyGoodsId)
go func(ctx_in *gin.Context, goodsIds_in []string, chs_in chan sync.Map) {
defer wg.Done()
lyService.LyGoodsDetail(ctx_in, goodsIds_in, chs_in)
}(ctx, idsToProcess, ch)
} }
// 开启一个协程,等待所有任务完成,然后关闭channel
go func() {
wg.Wait()
close(ch)
}()
//异步map最后转成map //异步map最后转成map
temp := make(map[string]interface{}) temp := make(map[string]interface{})
for i := 0; i < p; i++ { timeout := time.After(time.Second * 20)
for {
select { select {
case GoodsRes := <-ch: case GoodsRes, ok := <-ch:
if !ok { // channel被关闭,说明所有协程都已执行完毕
return temp
}
GoodsRes.Range(func(k, v interface{}) bool { GoodsRes.Range(func(k, v interface{}) bool {
s, _ := k.(string) s, _ := k.(string)
temp[s] = v temp[s] = v
return true return true
}) })
case <-time.After(time.Second * 20): case <-timeout:
logger.Log("协程超时", "sku", 1) logger.Log("协程整体处理超时", "sku", 1)
return temp // 超时,返回已经收到的部分数据
} }
} }
return temp
} }
func Synchronization(ctx *gin.Context) { func Synchronization(ctx *gin.Context) {
...@@ -130,7 +168,7 @@ func Hbsdata(ctx *gin.Context) { ...@@ -130,7 +168,7 @@ func Hbsdata(ctx *gin.Context) {
} }
/* /*
测试redis 测试redis
*/ */
func Testr(ctx *gin.Context) { func Testr(ctx *gin.Context) {
......
# SKU价格获取完整流程文档
## 概述
本文档详细描述了从`sku_controller.go`出发的SKU价格获取完整流程,涵盖HTTP请求处理、并发执行、价格计算、缓存策略等核心环节。
## 1. 入口层 - HTTP请求处理
### 1.1 CommonController (sku_controller.go)
**文件位置**: `/controller/sku_controller.go`
**核心功能**: 接收并处理SKU查询请求
#### 1.1.1 请求参数解析
```go
GoodsIdStr := ctx.Request.FormValue("goods_id")
```
- 支持两种传参方式:
- URL参数:`goods_id=123,456,789`
- POST表单:`goods_id[0]=123&goods_id[1]=456`
#### 1.1.2 商品分类逻辑
```go
if len(goodsId) < 19 { // 自营商品
zyGoodsId = append(zyGoodsId, goodsId)
} else { // 联营商品
lyGoodsId = append(lyGoodsId, goodsId)
}
```
#### 1.1.3 并发处理机制
- **协程数量**: 每50个商品启动一个协程
- **并发控制**: 使用`sync.WaitGroup`管理协程生命周期
- **结果收集**: 通过channel异步收集结果
- **超时保护**: 20秒整体超时机制
```go
ch := make(chan sync.Map, 50) // 结果通道
timeout := time.After(time.Second * 20) // 超时控制
```
## 2. 服务层 - 商品详情处理
### 2.1 自营商品处理 (ZiyingService)
**入口方法**: `ZyGoodsDetail`
**处理特点**: 直接获取预设价格,流程相对简单
### 2.2 联营商品处理 (LyService)
**入口方法**: `LyGoodsDetail`
**文件位置**: `/service/service_ly_common.go`
**处理特点**: 完整的价格计算流程
## 3. 价格计算核心流程
### 3.1 GetCoefficientAndPrice 方法
**文件位置**: `/service/service_ly_common.go:290-501`
#### 3.1.1 前置判断
```go
// 检查是否有阶梯价格
if len(sku.LadderPrice) == 0 {
return sku
}
```
#### 3.1.2 供应商类型区分
- **专卖供应商** (SupplierId = 17): 华云等自有供应商
- **代购供应商** (其他SupplierId): MRO、Digikey等第三方供应商
### 3.3 专卖供应商价格计算
#### 3.3.1 价格获取流程
1. **读取成本价**: 从Redis获取预设成本价
2. **折扣系数**: 调用`GetDiscountRatio`获取
3. **阶梯价格**: 调用`GenerateLadderPrice`生成
4. **最终价格**: 成本价 × 折扣系数 × 阶梯系数
### 3.4 代购供应商价格计算(完整流程)
#### 3.4.1 获取折扣系数 (`GetDiscountRatio`)
**文件位置**: `/service/service_price.go:427-522`
**数据源**: Redis中的折扣系数配置
- **Key格式**: `discount_ratio_config`
- **匹配维度**: 商品名称、品牌、分类ID、ECCN
- **优先级顺序**: 商品名称 > 品牌 > 分类ID > ECCN
**匹配逻辑**:
```
1. 商品名称匹配 (最高优先级)
2. 标准品牌ID匹配
3. 分类ID匹配
4. ECCN匹配 (最低优先级)
任一条件匹配即命中并跳出
```
#### 3.4.2 获取售价组系数 (`GetPriceRatio`)
**文件位置**: `/service/service_price.go:524-679`
**配置源**: Redis中的售价组配置
- **Key格式**: `magic_cube_price_rule_v2`
- **支持维度**:
- 供应商级别
- 商品级别
- 品牌级别
- 分类级别
#### 3.4.3 获取供应商系数
**数据源**: Redis中的供应商系数配置
- **Key格式**: `pool_supplier_ratio`
- **匹配逻辑**: 支持商品名称和品牌匹配
#### 3.4.4 价格计算公式
##### 成本价计算
```
美金成本价 = 原始美金价格 × 折扣系数
人民币成本价 = 原始人民币价格 × 汇率 × 税率 (1.13)
```
##### 售价计算
```
美金售价 = 美金成本价 × 售价组系数
人民币售价 = 人民币成本价 × 售价组系数
```
##### 特殊处理
- **MRO供应商** (1688): 支持人民币价格
- **Digikey供应商** (7): 支持人民币价格
- **实时汇率**: 从`erp_rate`键获取
- **固定税率**: 1.13
## 4. 价格服务核心方法详解
### 4.1 GenerateLadderPrice - 阶梯价格生成
**适用场景**: 专卖供应商价格计算
**文件位置**: `/service/service_price.go:20-425`
#### 4.1.1 配置获取逻辑
```go
// 根据MOQ选择配置key
if sku.Moq <= 50 {
ratioDataKey = "cost_ladder_price_egt50_lt200"
} else {
ratioDataKey = "cost_ladder_price_egt200"
}
```
#### 4.1.2 多维度匹配优先级
1. **商品名称匹配**: 精确匹配商品名称
2. **品牌匹配**: 匹配品牌名称
3. **分类匹配**: 匹配分类ID
4. **ECCN匹配**: 匹配ECCN编码
### 4.2 TransformSpecialSupplierPrice - 特殊供应商价格转换
**功能**: 处理不同供应商的币种转换和价格标准化
**文件位置**: `/service/service_price.go:681-777`
#### 4.2.1 支持的币种转换
该方法专门处理以下供应商的特殊币种问题:
- **Element(6)**: 存储的是港币,需要转换为美金
- **RS(21)**: 存储的是人民币,需要转换为美金
- **Buerklin(1676)**: 存储的是欧元,需要转换为美金
#### 4.2.2 配置数据源
**Redis配置键**: `magic_cube_supplier_currency`
**配置结构**:
```json
{
"currency": 3, // 币种ID
"has_tax": true, // 是否含税
"symbol": "€", // 货币符号
"us_to_cn": false, // 是否美金转人民币
"customize_rate_rmb": 7.2, // 自定义人民币汇率
"customize_rate_usd": 1.1 // 自定义美金汇率
}
```
#### 4.2.3 转换逻辑详解
##### 1. 汇率获取优先级
```
自定义汇率 > Redis实时汇率 > 默认汇率
```
##### 2. 币种转换流程
**情况1**: 有自定义人民币汇率
```
人民币价格 = 原始价格 × 自定义人民币汇率
如含税: 人民币价格 = 人民币价格 ÷ 1.13
```
**情况2**: 无自定义汇率,需要美金转人民币
```
人民币价格 = 原始美金价格 × 实时汇率 × 1.13
```
**情况3**: 有自定义美金汇率
```
美金价格 = 原始价格 × 自定义美金汇率
如含税: 美金价格 = 美金价格 ÷ 1.13
```
**情况4**: 无自定义美金汇率(最复杂)
```
1. 获取币种对人民币汇率
2. 获取人民币对美元汇率
3. 计算币种对美元汇率 = 币种对人民币汇率 ÷ 人民币对美元汇率
4. 美金价格 = 原始价格 × 计算出的汇率
如含税: 美金价格 = 美金价格 ÷ 1.13
```
##### 3. 实际转换示例
**示例**: Element供应商(港币→美金)
```
原始数据: price_us = 100 (实际是100港币)
配置: currency=3(港币), has_tax=true
汇率: 港币对人民币=0.9, 人民币对美元=7.2
计算: 港币对美元汇率 = 0.9 ÷ 7.2 = 0.125
最终结果: price_us = 100 × 0.125 ÷ 1.13 = 11.06美金
```
#### 4.2.4 特殊处理逻辑
- **组织ID过滤**: 仅处理OrgId=1的数据
- **税率处理**: 根据has_tax标志决定是否去除13%增值税
- **符号记录**: 记录原始货币符号用于前端展示
- **汇率缓存**: 使用Redis缓存实时汇率数据
### 4.3 GetActivityPrice - 活动价格处理
**功能**: 处理限时活动价格
**数据源**: Redis中的活动价格配置
## 5. 缓存策略与数据结构
### 5.1 Redis Key结构
| Key名称 | 用途 | 数据类型 |
|---------|------|----------|
| `magic_cube_price_rule_v2` | 售价组配置 | Hash |
| `pool_supplier_ratio` | 供应商系数 | Hash |
| `erp_rate` | 实时汇率 | Hash |
| `cost_ladder_price_*` | 阶梯价格系数 | String |
| `discount_ratio_config` | 折扣系数配置 | String |
### 5.2 缓存更新策略
- **实时读取**: 每次价格计算时从Redis获取最新配置
- **配置更新**: 通过管理后台更新Redis配置
- **异常处理**: 配置缺失时使用默认值
## 6. 并发与性能优化
### 6.1 并发处理架构
```
HTTP请求 → 商品分类 → 批次划分 → 协程处理 → 结果聚合 → 响应返回
```
### 6.2 性能优化点
- **批量处理**: 50个商品一批次,减少协程数量
- **连接复用**: Redis连接池管理
- **缓存策略**: 关键配置Redis缓存
- **超时控制**: 20秒整体超时保护
## 7. 异常处理与监控
### 7.1 异常场景处理
- **空值保护**: 各种系数缺失时的默认值处理
- **格式验证**: 数据格式异常时的容错处理
- **超时保护**: 防止长时间阻塞
### 7.2 日志与监控
- **关键节点日志**: 价格计算各阶段的状态记录
- **异常日志**: 配置缺失、计算异常等场景记录
- **性能监控**: 请求耗时、缓存命中率等指标
## 8. 数据流总结
### 8.1 完整数据流
```
用户请求 → 参数解析 → 商品分类 → 并发处理 → 价格计算 → 结果聚合 → 响应返回
Redis配置 → 折扣系数 → 售价组系数 → 供应商系数 → 汇率 → 税率
成本价计算 → 售价计算 → 币种转换 → 最终价格
```
### 8.2 关键决策点
1. **供应商类型判断**: 决定价格计算路径
2. **配置匹配优先级**: 影响最终系数选择
3. **币种转换需求**: 决定是否进行汇率转换
4. **活动价格判断**: 是否使用活动价格覆盖
## 9. 使用示例
### 9.1 请求示例
```bash
# 单个商品查询
curl "http://api.example.com/sku?goods_id=123456789"
# 多个商品查询
curl "http://api.example.com/sku" -d "goods_id[0]=123&goods_id[1]=456"
```
### 9.2 响应数据结构
```json
{
"123456789": {
"goods_name": "示例商品",
"ladder_price": [
{
"purchases": 1,
"price_us": 10.50,
"price_cn": 73.50,
"price_cost_us": 8.50,
"price_cost_cn": 59.50
}
],
"discount_ratio": {
"ratio": 0.85,
"ratio_usd": 0.90
}
}
}
```
## 10. 维护与扩展
### 10.1 配置维护
- **售价组配置**: 通过管理后台更新`magic_cube_price_rule_v2`
- **折扣系数**: 更新`discount_ratio_config`
- **供应商系数**: 更新`pool_supplier_ratio`
### 10.2 扩展点
- **新供应商支持**: 在`TransformSpecialSupplierPrice`中添加转换逻辑
- **新匹配维度**: 扩展`GetDiscountRatio``GetPriceRatio`的匹配逻辑
- **新币种支持**: 扩展汇率转换逻辑
---
*本文档基于当前代码版本整理,如有更新请及时同步文档内容。*
...@@ -42,10 +42,12 @@ type Activity struct { ...@@ -42,10 +42,12 @@ type Activity struct {
StandardBrandIdList []string StandardBrandIdList []string
ExcludeStandardBrandIds string `json:"exclude_standard_brand_ids"` ExcludeStandardBrandIds string `json:"exclude_standard_brand_ids"`
ExcludeStandardBrandIdList []string ExcludeStandardBrandIdList []string
CurrencyRmb int `json:"currency_rmb"` CurrencyRmb int `json:"currency_rmb"`
CurrencyUs int `json:"currency_us"` CurrencyUs int `json:"currency_us"`
UseType int `json:"use_type"` UseType int `json:"use_type"`
SignUrl string `json:"sign_url"` SignUrl string `json:"sign_url"`
Source string `json:"source"`
SourceList []string `json:"source_list"`
} }
type ActivityItem struct { type ActivityItem struct {
...@@ -70,4 +72,5 @@ type ActivityCheckData struct { ...@@ -70,4 +72,5 @@ type ActivityCheckData struct {
Canal string Canal string
ClassId int ClassId int
OrgId int OrgId int
Source int
} }
...@@ -243,7 +243,7 @@ func InitSkuData(sku string) (data LySku) { ...@@ -243,7 +243,7 @@ func InitSkuData(sku string) (data LySku) {
isExpire := gjson.Get(sku, "is_expire").Int() isExpire := gjson.Get(sku, "is_expire").Int()
data.IsExpire = int(isExpire) data.IsExpire = int(isExpire)
data.IsExpire = 0 //data.IsExpire = 0
hkDeliveryTime := gjson.Get(sku, "hk_delivery_time").String() hkDeliveryTime := gjson.Get(sku, "hk_delivery_time").String()
data.HkDeliveryTime = hkDeliveryTime data.HkDeliveryTime = hkDeliveryTime
......
package model
import "gopkg.in/mgo.v2/bson"
// PrevSku 对应prev_sku集合的数据结构
type PrevSku struct {
ID bson.ObjectId `bson:"_id"`
SkuId int64 `bson:"sku_id"`
SpuId int64 `bson:"spu_id"`
SupplierId int64 `bson:"supplier_id"`
}
package config package config
type MongoDbDatabase struct { type MongoDbDatabase struct {
Host string Host string
UserName string UserName string
Password string Password string
Database string Database string
MaxPoolSize string MaxPoolSize string
} }
func BuildMongoDbConfgs() map[string]MongoDbDatabase {
func BuildMongoDbConfgs () map[string]MongoDbDatabase{
return map[string]MongoDbDatabase{ return map[string]MongoDbDatabase{
"default" : { "default": {
Host:Get("mongo.host").String(), Host: Get("mongo.host").String(),
UserName:Get("mongo.username").String(), UserName: Get("mongo.username").String(),
Password:Get("mongo.password").String(), Password: Get("mongo.password").String(),
Database:Get("mongo.database").String(), Database: Get("mongo.database").String(),
MaxPoolSize:Get("mongo.maxPoolSize").String(), MaxPoolSize: Get("mongo.maxPoolSize").String(),
},
"pre_sku": {
Host: Get("pre_sku_mongo.host").String(),
UserName: Get("pre_sku_mongo.username").String(),
Password: Get("pre_sku_mongo.password").String(),
Database: Get("pre_sku_mongo.database").String(),
MaxPoolSize: Get("pre_sku_mongo.maxPoolSize").String(),
}, },
} }
} }
package config package config
type RedisDatabase struct { type RedisDatabase struct {
Password string Password string
Host string Host string
Database string Database string
MaxIdle int MaxIdle int
MaxActive int MaxActive int
IdleTimeout int
MaxAIdleTimeoutctive string MaxAIdleTimeoutctive string
Prefix string Prefix string
} }
//多数据库配置 // 多数据库配置
func BuildRedisConfigs() (RedisDatabaseMap map[string]RedisDatabase) { func BuildRedisConfigs() (RedisDatabaseMap map[string]RedisDatabase) {
redisReadMaxIdle,_ := Get("default_redis_read.max_idle").Int() redisReadMaxIdle, _ := Get("default_redis_read.max_idle").Int()
redisReadMaxActive,_ := Get("default_redis_read.max_active").Int() redisReadMaxActive, _ := Get("default_redis_read.max_active").Int()
redisWriteMaxIdle,_ := Get("default_redis_write.max_idle").Int() redisWriteMaxIdle, _ := Get("default_redis_write.max_idle").Int()
redisWriteMaxActive,_ := Get("default_redis_write.max_active").Int() redisWriteMaxActive, _ := Get("default_redis_write.max_active").Int()
redisSpuMaxIdle,_ := Get("default_redis_spu.max_idle").Int() redisSpuMaxIdle, _ := Get("default_redis_spu.max_idle").Int()
redisSpuMaxActive,_ := Get("default_redis_spu.max_active").Int() redisSpuMaxActive, _ := Get("default_redis_spu.max_active").Int()
redisIdleTimeout, _ := Get("default_redis_read.idle_timeout").Int()
return map[string]RedisDatabase{ return map[string]RedisDatabase{
"search_r": { "search_r": {
Host: Get("default_redis_read.host").String(), Host: Get("default_redis_read.host").String(),
Password: Get("default_redis_read.password").String(), Password: Get("default_redis_read.password").String(),
MaxIdle: redisReadMaxIdle, MaxIdle: redisReadMaxIdle,
MaxActive: redisReadMaxActive, MaxActive: redisReadMaxActive,
IdleTimeout: redisIdleTimeout,
}, },
"default_r": { "default_r": {
Host: Get("default_redis_read.host").String(), Host: Get("default_redis_read.host").String(),
Password: Get("default_redis_read.password").String(), Password: Get("default_redis_read.password").String(),
MaxIdle: redisReadMaxIdle, MaxIdle: redisReadMaxIdle,
MaxActive: redisReadMaxActive, MaxActive: redisReadMaxActive,
IdleTimeout: redisIdleTimeout,
}, },
"search_w": { "search_w": {
Host: Get("default_redis_write.host").String(), Host: Get("default_redis_write.host").String(),
Password: Get("default_redis_write.password").String(), Password: Get("default_redis_write.password").String(),
MaxIdle: redisWriteMaxIdle, MaxIdle: redisWriteMaxIdle,
MaxActive: redisWriteMaxActive, MaxActive: redisWriteMaxActive,
IdleTimeout: redisIdleTimeout,
}, },
"spu": { "spu": {
Host: Get("default_redis_spu.host").String(), Host: Get("default_redis_spu.host").String(),
Password: Get("default_redis_spu.password").String(), Password: Get("default_redis_spu.password").String(),
MaxIdle: redisSpuMaxIdle, MaxIdle: redisSpuMaxIdle,
MaxActive: redisSpuMaxActive, MaxActive: redisSpuMaxActive,
IdleTimeout: redisIdleTimeout,
}, },
} }
} }
...@@ -2,9 +2,10 @@ package gredis ...@@ -2,9 +2,10 @@ package gredis
import ( import (
"fmt" "fmt"
"github.com/gomodule/redigo/redis"
"go_sku_server/pkg/config" "go_sku_server/pkg/config"
"time" "time"
"github.com/gomodule/redigo/redis"
) )
type ichuntRedis struct { type ichuntRedis struct {
...@@ -32,7 +33,7 @@ func Setup() (err error) { ...@@ -32,7 +33,7 @@ func Setup() (err error) {
return nil return nil
} }
//格式化成字符串 // 格式化成字符串
func String(a interface{}, err error) (string, error) { func String(a interface{}, err error) (string, error) {
return redis.String(a, err) return redis.String(a, err)
} }
...@@ -41,10 +42,15 @@ func getConn(writeHost, password string, maxIdle, maxActive int) (pool *redis.Po ...@@ -41,10 +42,15 @@ func getConn(writeHost, password string, maxIdle, maxActive int) (pool *redis.Po
//maxIdle, _ := config.Get("redis.max_idle").Int() //maxIdle, _ := config.Get("redis.max_idle").Int()
//maxActive, _ := config.Get("redis.max_active").Int() //maxActive, _ := config.Get("redis.max_active").Int()
pool = &redis.Pool{ pool = &redis.Pool{
MaxIdle: maxIdle, MaxIdle: maxIdle,
MaxActive: maxActive, MaxActive: maxActive,
IdleTimeout: 240 * time.Second,
Dial: func() (redis.Conn, error) { Dial: func() (redis.Conn, error) {
c, err := redis.Dial("tcp", writeHost) c, err := redis.Dial("tcp", writeHost,
redis.DialConnectTimeout(2*time.Second),
redis.DialReadTimeout(2*time.Second),
redis.DialWriteTimeout(2*time.Second),
)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -70,8 +76,9 @@ func getConn(writeHost, password string, maxIdle, maxActive int) (pool *redis.Po ...@@ -70,8 +76,9 @@ func getConn(writeHost, password string, maxIdle, maxActive int) (pool *redis.Po
@param hkey string 集合键值,如sku @param hkey string 集合键值,如sku
@param targetIds string 查询的id 切片 @param targetIds string 查询的id 切片
eg: eg:
redisConn := gredis.Conn("search_r")
skuArr := gredis.HgetPi(&redisConn,"Self_SelfGoods",[]string{"1001","10005"}) redisConn := gredis.Conn("search_r")
skuArr := gredis.HgetPi(&redisConn,"Self_SelfGoods",[]string{"1001","10005"})
*/ */
func Hmget(redisCon string, hkey string, targetIds []string) map[string]string { func Hmget(redisCon string, hkey string, targetIds []string) map[string]string {
if len(targetIds) == 0 { if len(targetIds) == 0 {
...@@ -86,7 +93,8 @@ func Hmget(redisCon string, hkey string, targetIds []string) map[string]string { ...@@ -86,7 +93,8 @@ func Hmget(redisCon string, hkey string, targetIds []string) map[string]string {
goods_id := targetIds[0] goods_id := targetIds[0]
info, err := String(redisConn.Do("HGET", hkey, goods_id)) info, err := String(redisConn.Do("HGET", hkey, goods_id))
if err != nil && err != redis.ErrNil { if err != nil && err != redis.ErrNil {
fmt.Print("连接redis错误991:", err) fmt.Printf("redis HGET error for key %s, field %s: %v\n", hkey, goods_id, err)
return nil
} }
if info == "" { if info == "" {
skuArr[goods_id] = "" skuArr[goods_id] = ""
...@@ -102,9 +110,14 @@ func Hmget(redisCon string, hkey string, targetIds []string) map[string]string { ...@@ -102,9 +110,14 @@ func Hmget(redisCon string, hkey string, targetIds []string) map[string]string {
} }
res1, err1 := redisConn.Do("hmget", param...) res1, err1 := redisConn.Do("hmget", param...)
reply, _ := redis.Strings(res1, err1)
if err1 != nil { if err1 != nil {
fmt.Println(err1) fmt.Printf("redis HMGET error for key %s: %v\n", hkey, err1)
return nil
}
reply, err := redis.Strings(res1, err1)
if err != nil {
fmt.Printf("redis Strings conversion error after HMGET for key %s: %v\n", hkey, err)
return nil
} }
for k, goodsInfo := range reply { for k, goodsInfo := range reply {
...@@ -120,8 +133,9 @@ func Hmget(redisCon string, hkey string, targetIds []string) map[string]string { ...@@ -120,8 +133,9 @@ func Hmget(redisCon string, hkey string, targetIds []string) map[string]string {
@param hkey string 集合键值,如sku @param hkey string 集合键值,如sku
@param targetIds string 查询的id 切片 @param targetIds string 查询的id 切片
eg: eg:
redisConn := gredis.Conn("search_r")
skuArr := gredis.HgetPi(&redisConn,"Self_SelfGoods",[]string{"1001","10005"}) redisConn := gredis.Conn("search_r")
skuArr := gredis.HgetPi(&redisConn,"Self_SelfGoods",[]string{"1001","10005"})
*/ */
func HgetPi(redisCon string, hkey string, targetIds []string) map[string]string { func HgetPi(redisCon string, hkey string, targetIds []string) map[string]string {
redisConn := Conn(redisCon) redisConn := Conn(redisCon)
...@@ -131,8 +145,9 @@ func HgetPi(redisCon string, hkey string, targetIds []string) map[string]string ...@@ -131,8 +145,9 @@ func HgetPi(redisCon string, hkey string, targetIds []string) map[string]string
if len(targetIds) == 1 { if len(targetIds) == 1 {
oneId := targetIds[0] oneId := targetIds[0]
info, err := String(redisConn.Do("HGET", hkey, oneId)) info, err := String(redisConn.Do("HGET", hkey, oneId))
if err != nil { if err != nil && err != redis.ErrNil {
fmt.Print(err) fmt.Printf("redis HGET error for key %s, field %s: %v\n", hkey, oneId, err)
return nil
} }
if info == "" { if info == "" {
skuArr[oneId] = "" skuArr[oneId] = ""
...@@ -148,7 +163,11 @@ func HgetPi(redisCon string, hkey string, targetIds []string) map[string]string ...@@ -148,7 +163,11 @@ func HgetPi(redisCon string, hkey string, targetIds []string) map[string]string
redisConn.Flush() redisConn.Flush()
for _, goods_id := range targetIds { for _, goods_id := range targetIds {
info, _ := redisConn.Receive() info, err := redisConn.Receive()
if err != nil {
fmt.Printf("redis Receive error for key %s: %v\n", hkey, err)
return nil
}
if info == nil { if info == nil {
skuArr[goods_id] = "" skuArr[goods_id] = ""
continue continue
...@@ -164,8 +183,9 @@ func HgetPi(redisCon string, hkey string, targetIds []string) map[string]string ...@@ -164,8 +183,9 @@ func HgetPi(redisCon string, hkey string, targetIds []string) map[string]string
@param hkey string 集合键值,如sku @param hkey string 集合键值,如sku
@param targetIds string 查询的id 切片 @param targetIds string 查询的id 切片
eg: eg:
redisConn := gredis.Conn("search_r")
skuArr := gredis.HgetPi(&redisConn,"Self_SelfGoods",[]string{"1001","10005"}) redisConn := gredis.Conn("search_r")
skuArr := gredis.HgetPi(&redisConn,"Self_SelfGoods",[]string{"1001","10005"})
*/ */
func HgetPi2(redisCon string, hkey string, targetIds []string) map[string]string { func HgetPi2(redisCon string, hkey string, targetIds []string) map[string]string {
redisConn := Conn(redisCon) redisConn := Conn(redisCon)
...@@ -174,8 +194,9 @@ func HgetPi2(redisCon string, hkey string, targetIds []string) map[string]string ...@@ -174,8 +194,9 @@ func HgetPi2(redisCon string, hkey string, targetIds []string) map[string]string
skuArr := make(map[string]string, 0) skuArr := make(map[string]string, 0)
for _, goods_id := range targetIds { for _, goods_id := range targetIds {
info, err := String(redisConn.Do("HGET", hkey, goods_id)) info, err := String(redisConn.Do("HGET", hkey, goods_id))
if err != nil { if err != nil && err != redis.ErrNil {
fmt.Print("连接redis错误991:", err) fmt.Printf("redis HGET error in HgetPi2 for key %s, field %s: %v\n", hkey, goods_id, err)
return nil
} }
if info == "" { if info == "" {
skuArr[goods_id] = "" skuArr[goods_id] = ""
......
...@@ -49,74 +49,6 @@ func (as *ActivityService) GetActivityData(checkData model.ActivityCheckData) (p ...@@ -49,74 +49,6 @@ func (as *ActivityService) GetActivityData(checkData model.ActivityCheckData) (p
return return
} }
// 获取满赠活动信息
func (as *ActivityService) GetGiftActivity(checkData model.ActivityCheckData, activities []model.Activity) (giftActivity model.GiftActivity) {
var hasActivity bool
nowTimestamp := int(time.Now().Unix())
for _, activity := range activities {
if activity.Status != 1 {
continue
}
//判断时间是否过期
if activity.StartTime > nowTimestamp || activity.EndTime < nowTimestamp {
continue
}
//如果是整个供应商搞活动,则直接返回系数
if activity.EntireSupplierActivity {
hasActivity = true
goto INFO
}
//判断是否是排除的sku或者品牌,如果是的话,直接返回没活动
if as.CheckExcludeSku(checkData.GoodsId, activity) || as.CheckExcludeBrand(checkData.BrandId, activity) {
continue
}
//判断是否是搞活动的品牌
if as.CheckBrand(checkData.BrandId, activity) {
hasActivity = true
goto INFO
}
//如果是专卖,则要去判断canal,如果是自营,则去判断分类
if checkData.SupplierId == 17 {
if as.CheckCanal(checkData.Canal, activity) {
hasActivity = true
goto INFO
}
} else {
if as.CheckClass(checkData.ClassId, activity) {
hasActivity = true
goto INFO
}
}
INFO:
if hasActivity {
for key, item := range activity.ItemList {
activity.ItemList[key].Content = "订单满" + gconv.String(item.Amount) + "元赠" +
gconv.String(item.ItemName) + "X" + gconv.String(item.Num) + "" + item.Remark
}
giftActivity.ActivityName = activity.ActivityName
giftActivity.ActivityId = activity.ActivityId
giftActivity = model.GiftActivity{
CanAdminOrder: activity.CanAdminOrder,
ItemList: activity.ItemList,
ActivityCommon: model.ActivityCommon{
HasActivity: hasActivity,
ActivityId: activity.ActivityId,
ActivityName: activity.ActivityName,
AllowCoupon: activity.AllowCoupon,
UserScope: activity.UserScope,
},
}
break
}
}
return
}
func (as *ActivityService) GetPriceActivity(checkData model.ActivityCheckData, activities []model.Activity) (priceActivity model.PriceActivity) { func (as *ActivityService) GetPriceActivity(checkData model.ActivityCheckData, activities []model.Activity) (priceActivity model.PriceActivity) {
redisConn := gredis.Conn("default_r") redisConn := gredis.Conn("default_r")
defer redisConn.Close() defer redisConn.Close()
...@@ -140,6 +72,10 @@ func (as *ActivityService) GetPriceActivity(checkData model.ActivityCheckData, a ...@@ -140,6 +72,10 @@ func (as *ActivityService) GetPriceActivity(checkData model.ActivityCheckData, a
if as.CheckExcludeSku(checkData.GoodsId, activity) || as.CheckExcludeStandardBrand(checkData.StandardBrandId, activity) { if as.CheckExcludeSku(checkData.GoodsId, activity) || as.CheckExcludeStandardBrand(checkData.StandardBrandId, activity) {
continue continue
} }
//checkSource
if !as.CheckSource(checkData.Source, activity) {
continue
}
//如果是专卖,则要去判断canal,如果是自营,则去判断分类 //如果是专卖,则要去判断canal,如果是自营,则去判断分类
if checkData.SupplierId == 17 { if checkData.SupplierId == 17 {
...@@ -175,8 +111,6 @@ func (as *ActivityService) GetPriceActivity(checkData model.ActivityCheckData, a ...@@ -175,8 +111,6 @@ func (as *ActivityService) GetPriceActivity(checkData model.ActivityCheckData, a
} else if checkData.SupplierId == 10000 { } else if checkData.SupplierId == 10000 {
//自营活动特殊判断 //自营活动特殊判断
//fmt.Println(activity.ClassIds)
//fmt.Println(activity.UseType)
if activity.ClassIds != "" { if activity.ClassIds != "" {
if !as.CheckClass(checkData.ClassId, activity) { if !as.CheckClass(checkData.ClassId, activity) {
continue continue
...@@ -275,10 +209,7 @@ func (as *ActivityService) CheckExcludeBrand(brandId int, activity model.Activit ...@@ -275,10 +209,7 @@ func (as *ActivityService) CheckExcludeBrand(brandId int, activity model.Activit
activity.ExcludeBrandIdList = strings.Split(activity.ExcludeBrandIds, ",") activity.ExcludeBrandIdList = strings.Split(activity.ExcludeBrandIds, ",")
brandIdStr := gconv.String(brandId) brandIdStr := gconv.String(brandId)
//如果存在于有活动价的品牌,就是有折扣活动了 //如果存在于有活动价的品牌,就是有折扣活动了
if php2go.InArray(brandIdStr, activity.ExcludeBrandIdList) { return php2go.InArray(brandIdStr, activity.ExcludeBrandIdList)
return true
}
return false
} }
// 检查是否属于被排除的标准品牌 // 检查是否属于被排除的标准品牌
...@@ -290,10 +221,7 @@ func (as *ActivityService) CheckExcludeStandardBrand(standardBrandId int, activi ...@@ -290,10 +221,7 @@ func (as *ActivityService) CheckExcludeStandardBrand(standardBrandId int, activi
activity.ExcludeStandardBrandIdList = strings.Split(activity.ExcludeStandardBrandIds, ",") activity.ExcludeStandardBrandIdList = strings.Split(activity.ExcludeStandardBrandIds, ",")
standardBrandIdStr := gconv.String(standardBrandId) standardBrandIdStr := gconv.String(standardBrandId)
//如果存在于有活动价的品牌,就是有折扣活动了 //如果存在于有活动价的品牌,就是有折扣活动了
if php2go.InArray(standardBrandIdStr, activity.ExcludeStandardBrandIdList) { return php2go.InArray(standardBrandIdStr, activity.ExcludeStandardBrandIdList)
return true
}
return false
} }
// 检查是否属于被排除的sku // 检查是否属于被排除的sku
...@@ -304,10 +232,7 @@ func (as *ActivityService) CheckExcludeSku(skuId string, activity model.Activity ...@@ -304,10 +232,7 @@ func (as *ActivityService) CheckExcludeSku(skuId string, activity model.Activity
//先去判断品牌 //先去判断品牌
activity.ExcludeSkuIdList = strings.Split(activity.ExcludeSkuIds, ",") activity.ExcludeSkuIdList = strings.Split(activity.ExcludeSkuIds, ",")
//如果存在于有活动价的品牌,就是有折扣活动了 //如果存在于有活动价的品牌,就是有折扣活动了
if php2go.InArray(skuId, activity.ExcludeSkuIdList) { return php2go.InArray(skuId, activity.ExcludeSkuIdList)
return true
}
return false
} }
// 检查是否属于活动分类(只有自营需要判断) // 检查是否属于活动分类(只有自营需要判断)
...@@ -319,10 +244,7 @@ func (as *ActivityService) CheckClass(classId int, activity model.Activity) bool ...@@ -319,10 +244,7 @@ func (as *ActivityService) CheckClass(classId int, activity model.Activity) bool
activity.ClassIdList = strings.Split(activity.ClassIds, ",") activity.ClassIdList = strings.Split(activity.ClassIds, ",")
classIdStr := gconv.String(classId) classIdStr := gconv.String(classId)
//如果存在于有活动价的品牌,就是有折扣活动了 //如果存在于有活动价的品牌,就是有折扣活动了
if php2go.InArray(classIdStr, activity.ClassIdList) { return php2go.InArray(classIdStr, activity.ClassIdList)
return true
}
return false
} }
// 检查是否属于活动品牌 // 检查是否属于活动品牌
...@@ -334,10 +256,7 @@ func (as *ActivityService) CheckBrand(brandId int, activity model.Activity) bool ...@@ -334,10 +256,7 @@ func (as *ActivityService) CheckBrand(brandId int, activity model.Activity) bool
activity.BrandIdList = strings.Split(activity.BrandIds, ",") activity.BrandIdList = strings.Split(activity.BrandIds, ",")
brandIdStr := gconv.String(brandId) brandIdStr := gconv.String(brandId)
//如果存在于有活动价的品牌,就是有折扣活动了 //如果存在于有活动价的品牌,就是有折扣活动了
if php2go.InArray(brandIdStr, activity.BrandIdList) { return php2go.InArray(brandIdStr, activity.BrandIdList)
return true
}
return false
} }
// 检测是否属于活动标准品牌 // 检测是否属于活动标准品牌
...@@ -349,10 +268,7 @@ func (as *ActivityService) CheckStandardBrand(standardBrandId int, activity mode ...@@ -349,10 +268,7 @@ func (as *ActivityService) CheckStandardBrand(standardBrandId int, activity mode
activity.StandardBrandIdList = strings.Split(activity.StandardBrandIds, ",") activity.StandardBrandIdList = strings.Split(activity.StandardBrandIds, ",")
standardBrandIdStr := gconv.String(standardBrandId) standardBrandIdStr := gconv.String(standardBrandId)
//如果存在于有活动价的品牌,就是有折扣活动了 //如果存在于有活动价的品牌,就是有折扣活动了
if php2go.InArray(standardBrandIdStr, activity.StandardBrandIdList) { return php2go.InArray(standardBrandIdStr, activity.StandardBrandIdList)
return true
}
return false
} }
// 检查是否属于供应商渠道 // 检查是否属于供应商渠道
...@@ -363,8 +279,23 @@ func (as *ActivityService) CheckCanal(canal string, activity model.Activity) boo ...@@ -363,8 +279,23 @@ func (as *ActivityService) CheckCanal(canal string, activity model.Activity) boo
//先去判断品牌 //先去判断品牌
activity.CanalList = strings.Split(activity.Canals, ",") activity.CanalList = strings.Split(activity.Canals, ",")
//如果存在于有活动价的品牌,就是有折扣活动了 //如果存在于有活动价的品牌,就是有折扣活动了
if php2go.InArray(canal, activity.CanalList) { return php2go.InArray(canal, activity.CanalList)
}
// 检查来源是否有配置,有配置的话是否符合
func (as *ActivityService) CheckSource(source int, activity model.Activity) bool {
if source == 0 {
source = 1
}
//如果source为空,则默认为所有来源
if activity.Source == "" {
return true return true
} }
return false //先去判断品牌
activity.SourceList = strings.Split(activity.Source, ",")
sourceStr := gconv.String(source)
// fmt.Println(sourceStr)
// fmt.Println(activity.SourceList)
//如果存在于有活动价的品牌,就是有折扣活动了
return php2go.InArray(sourceStr, activity.SourceList)
} }
...@@ -2,15 +2,17 @@ package service ...@@ -2,15 +2,17 @@ package service
import ( import (
"encoding/json" "encoding/json"
"github.com/iancoleman/orderedmap"
"go_sku_server/pkg/logger" "go_sku_server/pkg/logger"
"go_sku_server/pkg/mongo" "go_sku_server/pkg/mongo"
"strconv"
"strings"
"github.com/iancoleman/orderedmap"
"gopkg.in/mgo.v2" "gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson" "gopkg.in/mgo.v2/bson"
"strconv"
) )
//获取Spu的属性 // 获取Spu的属性
func (ls *LyService) GetSpuAttr(spuId string) (attrsResult interface{}) { func (ls *LyService) GetSpuAttr(spuId string) (attrsResult interface{}) {
var spuAttr SpuAttr var spuAttr SpuAttr
var attrsList []interface{} var attrsList []interface{}
...@@ -26,7 +28,17 @@ func (ls *LyService) GetSpuAttr(spuId string) (attrsResult interface{}) { ...@@ -26,7 +28,17 @@ func (ls *LyService) GetSpuAttr(spuId string) (attrsResult interface{}) {
//fmt.Println(spuAttr.AttrsExtend) //fmt.Println(spuAttr.AttrsExtend)
//如果有attrs_extend,就去取attrs_extend //如果有attrs_extend,就去取attrs_extend
if len(spuAttr.AttrsExtend) != 0 { if len(spuAttr.AttrsExtend) != 0 {
return spuAttr.AttrsExtend //便利AttrsExtend的值
for _, value := range spuAttr.AttrsExtend {
data := make(map[string]interface{})
data["attr_name"] = value.AttrName
//€符号全部替换为逗号
data["attr_value"] = strings.ReplaceAll(value.AttrValue, "€", ",")
data["attr_unit"] = value.AttrUnit
attrsList = append(attrsList, data)
attrsResult = attrsList
}
return attrsResult
} else if spuAttr.Attrs != "" { } else if spuAttr.Attrs != "" {
o := orderedmap.New() o := orderedmap.New()
err := json.Unmarshal([]byte(spuAttr.Attrs), &o) err := json.Unmarshal([]byte(spuAttr.Attrs), &o)
......
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
"go_sku_server/pkg/mongo" "go_sku_server/pkg/mongo"
"go_sku_server/service/sorter" "go_sku_server/service/sorter"
"sort" "sort"
"strconv"
"sync" "sync"
"gopkg.in/mgo.v2" "gopkg.in/mgo.v2"
...@@ -38,7 +39,10 @@ type Power struct { ...@@ -38,7 +39,10 @@ type Power struct {
func (ls *LyService) LyGoodsDetail(ctx *gin.Context, goodsIds []string, ch chan sync.Map) { func (ls *LyService) LyGoodsDetail(ctx *gin.Context, goodsIds []string, ch chan sync.Map) {
redisConn := gredis.Conn("search_r") redisConn := gredis.Conn("search_r")
redisConnSpu := gredis.Conn("spu") redisConnSpu := gredis.Conn("spu")
// 连接prev_sku MongoDB
prevSkuMongo := mongo.Conn("pre_sku")
defer func() { defer func() {
prevSkuMongo.Close()
redisConn.Close() redisConn.Close()
redisConnSpu.Close() redisConnSpu.Close()
}() }()
...@@ -63,14 +67,40 @@ func (ls *LyService) LyGoodsDetail(ctx *gin.Context, goodsIds []string, ch chan ...@@ -63,14 +67,40 @@ func (ls *LyService) LyGoodsDetail(ctx *gin.Context, goodsIds []string, ch chan
GoodsRes := sync.Map{} GoodsRes := sync.Map{}
for goodsId, skuStr := range skuArr { for goodsId, skuStr := range skuArr {
if skuStr == "" {
GoodsRes.Store(goodsId, false)
continue
}
//初始化有序map,拼接data数据,就是从redis取出初始数据 //初始化有序map,拼接data数据,就是从redis取出初始数据
sku := model.InitSkuData(skuStr) sku := model.InitSkuData(skuStr)
var spu string
if skuStr == "" {
// 如果redis中找不到sku数据,尝试从prev_sku MongoDB中查找
skuId, err := strconv.ParseInt(goodsId, 10, 64)
if err != nil {
GoodsRes.Store(goodsId, false)
continue
}
var prevSku model.PrevSku
err = prevSkuMongo.DB("ichunt").C("prev_sku").Find(bson.M{"sku_id": skuId}).One(&prevSku)
if err != nil {
// 如果在prev_sku中也找不到,则保持默认值
GoodsRes.Store(goodsId, false)
continue
}
// 根据找到的spu_id去spu的redis中查找
spuIdStr := strconv.FormatInt(prevSku.SpuId, 10)
spuStr, _ := redis.String(redisConnSpu.Do("HGET", "spu", spuIdStr))
if spuStr == "" {
// 如果spu缓存也没有,保持默认值
GoodsRes.Store(goodsId, false)
continue
}
sku.SupplierId = prevSku.SupplierId
sku.SpuId = spuIdStr
spu = spuStr
} else {
spu = spuList[sku.SpuId]
}
sku.GoodsId = goodsId sku.GoodsId = goodsId
spu := spuList[sku.SpuId]
//读取包装字段的缓存(分别是DGK,avnet,mro) //读取包装字段的缓存(分别是DGK,avnet,mro)
if sku.SupplierId == 7 || sku.SupplierId == 13 || sku.SupplierId == 1688 || sku.SupplierId == 17 { if sku.SupplierId == 7 || sku.SupplierId == 13 || sku.SupplierId == 1688 || sku.SupplierId == 17 {
//sku_raw_map哪里写入(成意写的) //sku_raw_map哪里写入(成意写的)
...@@ -79,12 +109,12 @@ func (ls *LyService) LyGoodsDetail(ctx *gin.Context, goodsIds []string, ch chan ...@@ -79,12 +109,12 @@ func (ls *LyService) LyGoodsDetail(ctx *gin.Context, goodsIds []string, ch chan
} }
sku = ls.GetGoodsImages(sku, spu) sku = ls.GetGoodsImages(sku, spu)
sku = ls.GetPdf(sku, spu) sku = ls.GetPdf(sku, spu)
//用spuInfo补全信息
sku = ls.CombineSup(sku, spu)
// 2023.11.20 DGK商品的包装若为“Tape & Reel (TR)”,则递增量=起订量 // 2023.11.20 DGK商品的包装若为“Tape & Reel (TR)”,则递增量=起订量
if sku.SupplierId == 7 && sku.Packing == "Tape & Reel (TR)" { if sku.SupplierId == 7 && sku.Packing == "Tape & Reel (TR)" {
sku.Multiple = sku.Moq sku.Multiple = sku.Moq
} }
//获取商品名称 //获取商品名称
//1688就是mro的sku spuName和GoodsName不是一个东西,不能公用 //1688就是mro的sku spuName和GoodsName不是一个东西,不能公用
if sku.GoodsName != "" && (sku.SupplierId == 1688 || sku.OrgId == 3) { if sku.GoodsName != "" && (sku.SupplierId == 1688 || sku.OrgId == 3) {
...@@ -182,16 +212,13 @@ func (ls *LyService) LyGoodsDetail(ctx *gin.Context, goodsIds []string, ch chan ...@@ -182,16 +212,13 @@ func (ls *LyService) LyGoodsDetail(ctx *gin.Context, goodsIds []string, ch chan
//case为0是为了兼容价格体系之前的价格 //case为0是为了兼容价格体系之前的价格
case 0: case 0:
case 1: case 1:
//如果是寄售的,也不走价格体系 //这里猎芯和寄售都是走同一套的价格体系了
if sku.Source != 12 { //获取系数和价格
//这里猎芯和华云都是走同一套的价格体系了 sku = ls.GetCoefficientAndPrice(sku)
//获取系数和价格 //获取自定义价格后的阶梯价
sku = ls.GetCoefficientAndPrice(sku) customPriceService := CustomPrice{}
//获取自定义价格后的阶梯价 sku.CustomPriceList, _ = customPriceService.getCustomPriceList(sku)
customPriceService := CustomPrice{} sku = priceService.GetActivityPrice(sku)
sku.CustomPriceList, _ = customPriceService.getCustomPriceList(sku)
sku = priceService.GetActivityPrice(sku)
}
case 3: case 3:
//如果是寄售的,不走价格体系 //如果是寄售的,不走价格体系
if sku.Source == 12 { if sku.Source == 12 {
...@@ -240,6 +267,11 @@ func (ls *LyService) LyGoodsDetail(ctx *gin.Context, goodsIds []string, ch chan ...@@ -240,6 +267,11 @@ func (ls *LyService) LyGoodsDetail(ctx *gin.Context, goodsIds []string, ch chan
sku.HkDeliveryTime = delivery["hk_delivery"] sku.HkDeliveryTime = delivery["hk_delivery"]
} }
//只要是寄售的,大陆交期都是0.5工作日
if sku.Source == 12 {
sku.CnDeliveryTime = "0.5工作日"
}
} }
//处理是否可以购买 //处理是否可以购买
...@@ -255,8 +287,8 @@ func (ls *LyService) LyGoodsDetail(ctx *gin.Context, goodsIds []string, ch chan ...@@ -255,8 +287,8 @@ func (ls *LyService) LyGoodsDetail(ctx *gin.Context, goodsIds []string, ch chan
//判断是否可以购买 //判断是否可以购买
sku.IsBuy = ls.GetIsBuy(sku) sku.IsBuy = ls.GetIsBuy(sku)
if sku.IsBuy ==0 && sku.OrgId != 1 { if sku.IsBuy == 0 && sku.OrgId != 1 {
sku.AcType = 0; sku.AcType = 0
} }
sku.Stock = ls.GetStock(sku) sku.Stock = ls.GetStock(sku)
...@@ -268,8 +300,6 @@ func (ls *LyService) LyGoodsDetail(ctx *gin.Context, goodsIds []string, ch chan ...@@ -268,8 +300,6 @@ func (ls *LyService) LyGoodsDetail(ctx *gin.Context, goodsIds []string, ch chan
//获取关税以及价格转换 //获取关税以及价格转换
sku = ls.GetTariffAndPrice(sku) sku = ls.GetTariffAndPrice(sku)
//用spuInfo补全信息
sku = ls.CombineSup(sku, spu)
//最后一步,将sku的全部信息放到有序map里面 //最后一步,将sku的全部信息放到有序map里面
GoodsRes.Store(goodsId, sku) GoodsRes.Store(goodsId, sku)
//(*goodsRes)[goodsId] = A //(*goodsRes)[goodsId] = A
...@@ -290,6 +320,7 @@ func (ls *LyService) GetActivity(sku model.LySku) model.LySku { ...@@ -290,6 +320,7 @@ func (ls *LyService) GetActivity(sku model.LySku) model.LySku {
GoodsName: sku.GoodsName, GoodsName: sku.GoodsName,
ClassId: sku.ClassID2, ClassId: sku.ClassID2,
OrgId: sku.OrgId, OrgId: sku.OrgId,
Source: sku.Source,
} }
var activityService ActivityService var activityService ActivityService
priceActivity, giftActivity := activityService.GetActivityData(checkData) priceActivity, giftActivity := activityService.GetActivityData(checkData)
......
...@@ -19,6 +19,8 @@ import ( ...@@ -19,6 +19,8 @@ import (
_ "gopkg.in/mgo.v2/bson" _ "gopkg.in/mgo.v2/bson"
) )
var Self_supplier_code []string //所有自营的编码
// 获取图片信息 // 获取图片信息
func (ls *LyService) GetGoodsImages(sku model.LySku, spu string) model.LySku { func (ls *LyService) GetGoodsImages(sku model.LySku, spu string) model.LySku {
//图片 //图片
...@@ -262,7 +264,7 @@ func (ls *LyService) GetStock(sku model.LySku) (stock int64) { ...@@ -262,7 +264,7 @@ func (ls *LyService) GetStock(sku model.LySku) (stock int64) {
} }
//这里还有一个逻辑 //这里还有一个逻辑
//如果是寄售的数据(source=12),获取的库存还要减去锁库的库存 //如果是寄售的数据(source=12),获取的库存还要减去锁库的库存
if sku.Source == 12 { if sku.Source == 12 || php2go.InArray(sku.Canal, Self_supplier_code) {
//获取锁库库存 //获取锁库库存
redisCon := gredis.Conn("search_r") redisCon := gredis.Conn("search_r")
stockStr, _ := redis.String(redisCon.Do("HGET", "sku_lock_stock", sku.GoodsId)) stockStr, _ := redis.String(redisCon.Do("HGET", "sku_lock_stock", sku.GoodsId))
......
...@@ -60,14 +60,13 @@ func (ps *PriceService) GenerateLadderPrice(sku model.LySku) model.LySku { ...@@ -60,14 +60,13 @@ func (ps *PriceService) GenerateLadderPrice(sku model.LySku) model.LySku {
//拿出里面的所有排序 //拿出里面的所有排序
priceRatioSortMap := gjson.Get(priceRatioCache, ratioDataKey).Map() priceRatioSortMap := gjson.Get(priceRatioCache, ratioDataKey).Map()
var sortNumbers []int var sortNumbers []int
for sortNumberString, _ := range priceRatioSortMap { for sortNumberString := range priceRatioSortMap {
sortNumber, _ := strconv.Atoi(sortNumberString) sortNumber, _ := strconv.Atoi(sortNumberString)
sortNumbers = append(sortNumbers, sortNumber) sortNumbers = append(sortNumbers, sortNumber)
} }
//然后确定排序 //然后确定排序
sortNumbers = sorter.IntSliceSortDesc(sortNumbers) sortNumbers = sorter.IntSliceSortDesc(sortNumbers)
//确定排序以后,就可以进行按排序(从大到小)取系数 //确定排序以后,就可以进行按排序(从大到小)取系数
outerLoop:
for _, sortNumber := range sortNumbers { for _, sortNumber := range sortNumbers {
priceRatioSort = sortNumber priceRatioSort = sortNumber
priceRatioList = nil priceRatioList = nil
...@@ -81,17 +80,17 @@ func (ps *PriceService) GenerateLadderPrice(sku model.LySku) model.LySku { ...@@ -81,17 +80,17 @@ func (ps *PriceService) GenerateLadderPrice(sku model.LySku) model.LySku {
priceRatio.Purchases = gjson.Get(value.String(), "purchases").Int() priceRatio.Purchases = gjson.Get(value.String(), "purchases").Int()
priceRatioList = append(priceRatioList, priceRatio) priceRatioList = append(priceRatioList, priceRatio)
} }
//是否满足特定条件的判断 //是否满足特定条件的判断
var hasSpecialCheck = false var hasSpecialCheck = false
conditionsMet := true
//判断是否有符合的商品名称 //判断是否有符合的商品名称
goodsNames := gjson.Get(priceRatioCache, "goods_name."+sortString).String() goodsNames := gjson.Get(priceRatioCache, "goods_name."+sortString).String()
if goodsNames != "" { if goodsNames != "" {
hasSpecialCheck = true hasSpecialCheck = true
goodsNameList := strings.Split(goodsNames, "@€@") goodsNameList := strings.Split(goodsNames, "@€@")
//找到有对应的商品名称,那么优先级肯定是最高的了 if !php2go.InArray(sku.GoodsName, goodsNameList) {
if php2go.InArray(sku.GoodsName, goodsNameList) { conditionsMet = false
foundRatio = true
break
} }
} }
...@@ -100,12 +99,20 @@ func (ps *PriceService) GenerateLadderPrice(sku model.LySku) model.LySku { ...@@ -100,12 +99,20 @@ func (ps *PriceService) GenerateLadderPrice(sku model.LySku) model.LySku {
if brandIds != "" { if brandIds != "" {
hasSpecialCheck = true hasSpecialCheck = true
standardBrandIdList := strings.Split(brandIds, ",") standardBrandIdList := strings.Split(brandIds, ",")
//fmt.Println(standardBrandIdList)
standardBrandId := strconv.Itoa(sku.StandardBrand.StandardBrandId) standardBrandId := strconv.Itoa(sku.StandardBrand.StandardBrandId)
//找到有对应的品牌,那么优先级肯定是最高的了 if !php2go.InArray(standardBrandId, standardBrandIdList) {
if php2go.InArray(standardBrandId, standardBrandIdList) { conditionsMet = false
foundRatio = true }
break }
//判断是否有符合的分类ID
classIds := gjson.Get(priceRatioCache, "class_ids."+sortString).String()
if classIds != "" {
hasSpecialCheck = true
classIdList := strings.Split(classIds, ",")
classId := strconv.Itoa(sku.ClassID2)
if !php2go.InArray(classId, classIdList) {
conditionsMet = false
} }
} }
...@@ -113,11 +120,9 @@ func (ps *PriceService) GenerateLadderPrice(sku model.LySku) model.LySku { ...@@ -113,11 +120,9 @@ func (ps *PriceService) GenerateLadderPrice(sku model.LySku) model.LySku {
eccns := gjson.Get(priceRatioCache, "eccn."+sortString).String() eccns := gjson.Get(priceRatioCache, "eccn."+sortString).String()
if eccns != "" { if eccns != "" {
hasSpecialCheck = true hasSpecialCheck = true
eccnMatched := false
eccnList := strings.Split(eccns, ",") eccnList := strings.Split(eccns, ",")
//找到有对应的eccn,那么优先级肯定是最高的了
for _, eccn := range eccnList { for _, eccn := range eccnList {
//判断是否有百分号匹配
//如果是纯%,那就是不对的,要跳过
if strings.Replace(eccn, "%", "", 10) == "" { if strings.Replace(eccn, "%", "", 10) == "" {
continue continue
} }
...@@ -127,36 +132,44 @@ func (ps *PriceService) GenerateLadderPrice(sku model.LySku) model.LySku { ...@@ -127,36 +132,44 @@ func (ps *PriceService) GenerateLadderPrice(sku model.LySku) model.LySku {
if hasPrefix && hasSuffix { if hasPrefix && hasSuffix {
eccn = strings.Replace(eccn, "%", "", 10) eccn = strings.Replace(eccn, "%", "", 10)
if strings.Contains(sku.Eccn, eccn) { if strings.Contains(sku.Eccn, eccn) {
foundRatio = true eccnMatched = true
break outerLoop break
} }
} } else if hasPrefix {
if hasPrefix && !hasSuffix {
eccn = strings.Replace(eccn, "%", "", 10) eccn = strings.Replace(eccn, "%", "", 10)
if strings.HasSuffix(sku.Eccn, eccn) { if strings.HasSuffix(sku.Eccn, eccn) {
foundRatio = true eccnMatched = true
break outerLoop break
} }
} } else if hasSuffix {
if !hasPrefix && hasSuffix {
eccn = strings.Replace(eccn, "%", "", 10) eccn = strings.Replace(eccn, "%", "", 10)
if strings.HasPrefix(sku.Eccn, eccn) { if strings.HasPrefix(sku.Eccn, eccn) {
foundRatio = true eccnMatched = true
break outerLoop break
} }
} }
} else { } else {
if sku.Eccn == eccn { if sku.Eccn == eccn {
foundRatio = true eccnMatched = true
break outerLoop break
} }
} }
} }
if !eccnMatched {
conditionsMet = false
}
} }
//如果没有设置品牌和商品,那么这个优先级高的就会覆盖下面的了,不需要再去判断品牌和型号了
if hasSpecialCheck { if hasSpecialCheck {
continue if conditionsMet {
foundRatio = true
break
} else {
continue
}
} }
// 如果没有设置任何特殊条件,则默认匹配
foundRatio = true foundRatio = true
break break
} }
...@@ -534,14 +547,13 @@ func (ps PriceService) GetPriceRatio(sku model.LySku) (model.LySku, []model.Pric ...@@ -534,14 +547,13 @@ func (ps PriceService) GetPriceRatio(sku model.LySku) (model.LySku, []model.Pric
//拿出里面的所有排序 //拿出里面的所有排序
priceRatioSortMap := gjson.Get(priceRatioCache, "ladder_price").Map() priceRatioSortMap := gjson.Get(priceRatioCache, "ladder_price").Map()
var sortNumbers []int var sortNumbers []int
for sortNumberString, _ := range priceRatioSortMap { for sortNumberString := range priceRatioSortMap {
sortNumber, _ := strconv.Atoi(sortNumberString) sortNumber, _ := strconv.Atoi(sortNumberString)
sortNumbers = append(sortNumbers, sortNumber) sortNumbers = append(sortNumbers, sortNumber)
} }
//然后确定排序 //然后确定排序
sortNumbers = sorter.IntSliceSortDesc(sortNumbers) sortNumbers = sorter.IntSliceSortDesc(sortNumbers)
//确定排序以后,就可以进行按排序(从大到小)取系数 //确定排序以后,就可以进行按排序(从大到小)取系数
outerLoop:
for _, sortNumber := range sortNumbers { for _, sortNumber := range sortNumbers {
priceRatioSort = sortNumber priceRatioSort = sortNumber
priceRatioList = nil priceRatioList = nil
...@@ -555,16 +567,15 @@ func (ps PriceService) GetPriceRatio(sku model.LySku) (model.LySku, []model.Pric ...@@ -555,16 +567,15 @@ func (ps PriceService) GetPriceRatio(sku model.LySku) (model.LySku, []model.Pric
} }
var hasSpecialCheck = false var hasSpecialCheck = false
conditionsMet := true
//判断是否有符合的商品名称 //判断是否有符合的商品名称
goodsNames := gjson.Get(priceRatioCache, "goods_name."+sortString).String() goodsNames := gjson.Get(priceRatioCache, "goods_name."+sortString).String()
if goodsNames != "" { if goodsNames != "" {
hasSpecialCheck = true hasSpecialCheck = true
goodsNameList := strings.Split(goodsNames, "@€@") goodsNameList := strings.Split(goodsNames, "@€@")
//找到有对应的商品名称,那么优先级肯定是最高的了 if !php2go.InArray(sku.GoodsName, goodsNameList) {
if php2go.InArray(sku.GoodsName, goodsNameList) { conditionsMet = false
foundRatio = true
break
} }
} }
...@@ -574,10 +585,19 @@ func (ps PriceService) GetPriceRatio(sku model.LySku) (model.LySku, []model.Pric ...@@ -574,10 +585,19 @@ func (ps PriceService) GetPriceRatio(sku model.LySku) (model.LySku, []model.Pric
hasSpecialCheck = true hasSpecialCheck = true
standardBrandIdList := strings.Split(brandIds, ",") standardBrandIdList := strings.Split(brandIds, ",")
standardBrandId := strconv.Itoa(sku.StandardBrand.StandardBrandId) standardBrandId := strconv.Itoa(sku.StandardBrand.StandardBrandId)
//找到有对应的品牌,那么优先级肯定是最高的了 if !php2go.InArray(standardBrandId, standardBrandIdList) {
if php2go.InArray(standardBrandId, standardBrandIdList) { conditionsMet = false
foundRatio = true }
break }
//判断是否有符合的分类ID
classIds := gjson.Get(priceRatioCache, "class_ids."+sortString).String()
if classIds != "" {
hasSpecialCheck = true
classIdList := strings.Split(classIds, ",")
classId := strconv.Itoa(sku.ClassID2)
if !php2go.InArray(classId, classIdList) {
conditionsMet = false
} }
} }
...@@ -585,11 +605,9 @@ func (ps PriceService) GetPriceRatio(sku model.LySku) (model.LySku, []model.Pric ...@@ -585,11 +605,9 @@ func (ps PriceService) GetPriceRatio(sku model.LySku) (model.LySku, []model.Pric
eccns := gjson.Get(priceRatioCache, "eccn."+sortString).String() eccns := gjson.Get(priceRatioCache, "eccn."+sortString).String()
if eccns != "" { if eccns != "" {
hasSpecialCheck = true hasSpecialCheck = true
eccnMatched := false
eccnList := strings.Split(eccns, ",") eccnList := strings.Split(eccns, ",")
//找到有对应的eccn,那么优先级肯定是最高的了
for _, eccn := range eccnList { for _, eccn := range eccnList {
//判断是否有百分号匹配
//如果是纯%,那就是不对的,要跳过
if strings.Replace(eccn, "%", "", 10) == "" { if strings.Replace(eccn, "%", "", 10) == "" {
continue continue
} }
...@@ -599,36 +617,44 @@ func (ps PriceService) GetPriceRatio(sku model.LySku) (model.LySku, []model.Pric ...@@ -599,36 +617,44 @@ func (ps PriceService) GetPriceRatio(sku model.LySku) (model.LySku, []model.Pric
if hasPrefix && hasSuffix { if hasPrefix && hasSuffix {
eccn = strings.Replace(eccn, "%", "", 10) eccn = strings.Replace(eccn, "%", "", 10)
if strings.Contains(sku.Eccn, eccn) { if strings.Contains(sku.Eccn, eccn) {
foundRatio = true eccnMatched = true
break outerLoop break
} }
} } else if hasPrefix {
if hasPrefix && !hasSuffix {
eccn = strings.Replace(eccn, "%", "", 10) eccn = strings.Replace(eccn, "%", "", 10)
if strings.HasSuffix(sku.Eccn, eccn) { if strings.HasSuffix(sku.Eccn, eccn) {
foundRatio = true eccnMatched = true
break outerLoop break
} }
} } else if hasSuffix {
if !hasPrefix && hasSuffix {
eccn = strings.Replace(eccn, "%", "", 10) eccn = strings.Replace(eccn, "%", "", 10)
if strings.HasPrefix(sku.Eccn, eccn) { if strings.HasPrefix(sku.Eccn, eccn) {
foundRatio = true eccnMatched = true
break outerLoop break
} }
} }
} else { } else {
if sku.Eccn == eccn { if sku.Eccn == eccn {
foundRatio = true eccnMatched = true
break outerLoop break
} }
} }
} }
if !eccnMatched {
conditionsMet = false
}
} }
//如果没有设置品牌和商品,那么这个优先级高的就会覆盖下面的了,不需要再去判断品牌和型号了
if hasSpecialCheck { if hasSpecialCheck {
continue if conditionsMet {
foundRatio = true
break
} else {
continue
}
} }
// 如果没有设置任何特殊条件,则默认匹配
foundRatio = true foundRatio = true
break break
} }
......
package service package service
import ( import (
"github.com/gomodule/redigo/redis"
"github.com/syyongx/php2go"
"github.com/tidwall/gjson"
"go_sku_server/model" "go_sku_server/model"
"go_sku_server/pkg/gredis" "go_sku_server/pkg/gredis"
"go_sku_server/pkg/vars" "go_sku_server/pkg/vars"
"github.com/gomodule/redigo/redis"
"github.com/syyongx/php2go"
"github.com/tidwall/gjson"
) )
//标签相关服务,包括goods_label //标签相关服务,包括goods_label
...@@ -14,10 +15,10 @@ import ( ...@@ -14,10 +15,10 @@ import (
type TagsService struct { type TagsService struct {
} }
//当天发货标签 // 当天发货标签
const TagZiyingSku = 4 const TagZiyingSku = 4
//获取Spu的属性 // 获取Spu的属性
func (ts *TagsService) GetTags(skuId string, selfSupplierType int64) (goodsTags model.GoodsTag) { func (ts *TagsService) GetTags(skuId string, selfSupplierType int64) (goodsTags model.GoodsTag) {
redisCon := gredis.Conn("default_r") redisCon := gredis.Conn("default_r")
defer redisCon.Close() defer redisCon.Close()
...@@ -52,13 +53,13 @@ func (ts *TagsService) GetTags(skuId string, selfSupplierType int64) (goodsTags ...@@ -52,13 +53,13 @@ func (ts *TagsService) GetTags(skuId string, selfSupplierType int64) (goodsTags
goodsTags.GoodsLabelName = vars.GoodsTags[TagZiyingSku] goodsTags.GoodsLabelName = vars.GoodsTags[TagZiyingSku]
} }
} }
goodsTags.GoodsTagNames = tagNames goodsTags.GoodsTagNames = tagNames
goodsTags.GoodsTag = tags goodsTags.GoodsTag = tags
return goodsTags return goodsTags
} }
// 获取联营tags
//获取联营tags
func (ts *TagsService) GetLyTags(sku model.LySku) (goodsTags model.GoodsTag) { func (ts *TagsService) GetLyTags(sku model.LySku) (goodsTags model.GoodsTag) {
skuId := sku.GoodsId skuId := sku.GoodsId
redisCon := gredis.Conn("default_r") redisCon := gredis.Conn("default_r")
...@@ -83,14 +84,52 @@ func (ts *TagsService) GetLyTags(sku model.LySku) (goodsTags model.GoodsTag) { ...@@ -83,14 +84,52 @@ func (ts *TagsService) GetLyTags(sku model.LySku) (goodsTags model.GoodsTag) {
for _, cname := range customerTagArr { for _, cname := range customerTagArr {
//如果是爱智的话,去掉可议价标签 //如果是爱智的话,去掉可议价标签
if sku.OrgId ==3 && cname == "可议价" { if sku.OrgId == 3 && cname == "可议价" {
continue continue
} }
tagNames = append(tagNames, cname) tagNames = append(tagNames, cname)
} }
} }
} }
if sku.Source == 12 {
if !php2go.InArray("当天发货", tagNames) {
tagNames = append(tagNames, "当天发货")
}
}
//还要判断source的标签
sourceTagsStr, _ := redis.String(redisCon.Do("HGET", "goods_source_tags", sku.Source))
if sourceTagsStr != "" {
systemTags := gjson.Get(sourceTagsStr, "system_tags").Array()
for _, tag := range systemTags {
tagNames = append(tagNames, tag.String())
}
}
//判断goods_label的标签
labelTagsStr, _ := redis.String(redisCon.Do("HGET", "goods_label_tags", sku.GoodsTag.GoodsLabel))
if labelTagsStr != "" {
labelTags := gjson.Get(labelTagsStr, "system_tags").Array()
for _, tag := range labelTags {
tagNames = append(tagNames, tag.String())
}
}
//去重tagNames
tagNames = removeDuplicateString(tagNames)
goodsTags.GoodsTagNames = tagNames goodsTags.GoodsTagNames = tagNames
goodsTags.GoodsTag = tags goodsTags.GoodsTag = tags
return goodsTags return goodsTags
} }
func removeDuplicateString(s []string) []string {
result := []string{}
temp := map[string]struct{}{}
for _, item := range s {
if _, ok := temp[item]; !ok {
temp[item] = struct{}{}
result = append(result, item)
}
}
return result
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment