Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
杨树贤
/
bom_server
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
2b9184b3
authored
Jun 28, 2020
by
mushishixian
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
品牌映射
parent
5a658fa0
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
160 additions
and
62 deletions
internal/common/bom.go
internal/logic/attr.go
internal/logic/bom_matching.go
internal/logic/brand_map.go
internal/logic/goods.go
internal/logic/match.go
internal/model/bom_item.go
internal/common/bom.go
0 → 100644
View file @
2b9184b3
package
common
import
(
"bom_server/internal/model"
"strings"
)
//去除两端空格
func
TrimBomItemSpace
(
bomItems
[]
model
.
BomItem
)
(
result
[]
model
.
BomItem
)
{
for
key
,
item
:=
range
bomItems
{
bomItems
[
key
]
.
BrandName
=
strings
.
TrimSpace
(
item
.
BrandName
)
bomItems
[
key
]
.
GoodsName
=
strings
.
TrimSpace
(
item
.
GoodsName
)
bomItems
[
key
]
.
Attrs
=
strings
.
TrimSpace
(
item
.
Attrs
)
bomItems
[
key
]
.
Encap
=
strings
.
TrimSpace
(
item
.
Encap
)
}
return
bomItems
}
internal/logic/attr.go
View file @
2b9184b3
...
...
@@ -9,6 +9,7 @@ import (
"context"
"fmt"
"github.com/gomodule/redigo/redis"
"github.com/syyongx/php2go"
"github.com/tidwall/gjson"
es
"gopkg.in/olivere/elastic.v5"
"regexp"
...
...
@@ -17,7 +18,6 @@ import (
)
//根据参数去匹配商品
func
MatchGoodsNameByAttrs
(
bomItems
[]
model
.
BomItem
)
(
result
[]
model
.
BomItem
,
err
error
)
{
client
,
err
:=
es
.
NewClient
(
es
.
SetURL
(
configs
.
ESSetting
.
Url
))
if
err
!=
nil
{
...
...
@@ -31,12 +31,12 @@ func MatchGoodsNameByAttrs(bomItems []model.BomItem) (result []model.BomItem, er
for
_
,
item
:=
range
bomItems
{
//如果有型号,但是型号有可能是参数,所以先去匹配下参数,有的话转成对应的型号
if
item
.
GoodsName
!=
""
&&
item
.
Attrs
==
""
{
search
=
searchAttr
(
item
.
GoodsName
,
item
.
BrandName
,
item
.
Encap
,
search
)
search
=
searchAttr
(
item
,
search
)
searchFlag
=
true
}
//如果没有型号,但是有参数(参数有可能是型号),那就去匹配参数
if
item
.
GoodsName
==
""
&&
item
.
Attrs
!=
""
{
search
=
searchAttr
(
item
.
Attrs
,
item
.
BrandName
,
item
.
Encap
,
search
)
search
=
searchAttr
(
item
,
search
)
searchFlag
=
true
}
}
...
...
@@ -56,7 +56,6 @@ func MatchGoodsNameByAttrs(bomItems []model.BomItem) (result []model.BomItem, er
if
responses
.
Hits
!=
nil
{
for
_
,
hit
:=
range
responses
.
Hits
.
Hits
{
res
,
_
:=
hit
.
Source
.
MarshalJSON
()
//CS0805KKX7R9BB105
if
bomItems
[
key
]
.
GoodsName
==
""
{
bomItems
[
key
]
.
GoodsName
=
gjson
.
Get
(
string
(
res
),
"goods_name"
)
.
String
()
}
...
...
@@ -67,9 +66,9 @@ func MatchGoodsNameByAttrs(bomItems []model.BomItem) (result []model.BomItem, er
return
}
func
searchAttr
(
attrOrigin
,
brandName
,
encap
string
,
search
*
es
.
MultiSearchService
)
(
result
*
es
.
MultiSearchService
)
{
func
searchAttr
(
bomItem
model
.
BomItem
,
search
*
es
.
MultiSearchService
)
(
result
*
es
.
MultiSearchService
)
{
//先去切割参数得到参数列表
attrs
:=
splitAttrs
(
attrOrigin
)
attrs
:=
splitAttrs
(
bomItem
.
Attrs
)
//当切割出来的参数大于1个的时候,就要去针对每个参数进行里面再一次提纯
if
len
(
attrs
)
>
1
{
for
key
,
attr
:=
range
attrs
{
...
...
@@ -96,37 +95,45 @@ func searchAttr(attrOrigin, brandName, encap string, search *es.MultiSearchServi
}
}
//单独针对封装进行转换
if
e
ncap
!=
""
{
if
bomItem
.
E
ncap
!=
""
{
//先提取出纯数字
numberR
,
_
:=
regexp
.
Compile
(
mapping
.
PureNumberRegular
)
pureNumber
:=
numberR
.
FindString
(
e
ncap
)
pureNumber
:=
numberR
.
FindString
(
bomItem
.
E
ncap
)
//再去找对应属性
attrName
,
_
:=
redis
.
String
(
gredis
.
HGet
(
"sku_map2"
,
pureNumber
))
if
attrName
!=
""
{
attrValue
:=
attrName
+
"€"
+
pureNumber
attrsSlice
=
append
(
attrsSlice
,
attrValue
)
if
!
php2go
.
InArray
(
attrValue
,
attrsSlice
)
{
attrsSlice
=
append
(
attrsSlice
,
attrValue
)
}
}
}
query
:=
getQuery
(
attrsSlice
)
if
brandName
!=
""
&&
len
(
attrsSlice
)
>
0
{
//提取全英文,转成大写
if
strings
.
Contains
(
brandName
,
" "
)
{
//有空格隔开只取第一个
brandName
=
strings
.
Split
(
brandName
,
" "
)[
0
]
//如果ZyBrandId不为空,则代表匹配到了映射id,可以直接用must去查询
if
bomItem
.
ZyBrandId
!=
""
&&
len
(
attrsSlice
)
>
0
{
query
.
Should
(
es
.
NewTermQuery
(
"brand_name"
,
bomItem
.
ZyBrandName
))
}
else
{
if
bomItem
.
BrandName
!=
""
&&
len
(
attrsSlice
)
>
0
{
brandName
:=
bomItem
.
BrandName
//提取全英文,转成大写
if
strings
.
Contains
(
brandName
,
" "
)
{
//有空格隔开只取第一个
brandName
=
strings
.
Split
(
brandName
,
" "
)[
0
]
}
//转成全大写,因为ES存的是大写
brandName
=
strings
.
ToUpper
(
brandName
)
//去除特殊符号和中文等等
r1
,
_
:=
regexp
.
Compile
(
`/[^A-Za-z0-9]+/`
)
brandName
=
r1
.
ReplaceAllString
(
brandName
,
""
)
query
.
Should
(
es
.
NewTermQuery
(
"brand_name"
,
brandName
))
}
//转成全大写,因为ES存的是大写
brandName
=
strings
.
ToUpper
(
brandName
)
//去除特殊符号和中文等等
r1
,
_
:=
regexp
.
Compile
(
`/[^A-Za-z0-9]+/`
)
brandName
=
r1
.
ReplaceAllString
(
brandName
,
""
)
query
.
Should
(
es
.
NewTermQuery
(
"brand_name"
,
brandName
))
}
source
:=
es
.
NewSearchSource
()
.
Query
(
query
)
source
.
Sort
(
"_score"
,
false
)
source
.
Sort
(
"brand_sort"
,
true
)
source
=
source
.
From
(
0
)
.
Size
(
1
)
searchRequest
:=
es
.
NewSearchRequest
()
.
Source
(
source
)
//fmt.Println(searchRequest.Body())
return
search
.
Add
(
searchRequest
)
}
...
...
@@ -152,7 +159,6 @@ func splitAttrs(attrs string) (result []string) {
if
len
(
result
)
>
1
{
return
}
//按照分隔符切完了,再去每个去正则提取
return
}
...
...
internal/logic/bom_matching.go
View file @
2b9184b3
...
...
@@ -50,17 +50,10 @@ func BatchSaveMatchings(bomId int, matchingList []model.BomItemMatching) (err er
}
now
:=
time
.
Now
()
.
Unix
()
var
itemStatus
int
//if matching.IsBuy == 1 && matching.Price != 0 && matching.Stock != 0 {
// itemStatus = 2
// //库存为0或者价格为0,要放到待确认
//
//} else if matching.Price == 0 || matching.Stock == 0 {
// itemStatus = 4
//}
if
matching
.
IsBuy
==
1
{
itemStatus
=
2
}
else
{
itemStatus
=
3
}
else
{
itemStatus
=
3
}
err
=
model
.
Db
.
Table
(
"lie_bom_item_"
+
tableEnd
)
.
Where
(
"bom_item_id = ?"
,
matching
.
BomItemID
)
.
Updates
(
map
[
string
]
interface
{}{
"item_status"
:
itemStatus
,
"update_time"
:
now
})
.
Error
...
...
internal/logic/brand_map.go
View file @
2b9184b3
package
logic
import
"bom_server/internal/model"
import
(
"bom_server/configs"
"bom_server/internal/model"
"context"
"github.com/tidwall/gjson"
es
"gopkg.in/olivere/elastic.v5"
"regexp"
"strings"
)
//和品牌映射有关的逻辑
func
GetBrandMap
(
bomItems
[]
model
.
BomItem
)
(
result
[]
model
.
BomItem
,
err
error
)
{
client
,
err
:=
es
.
NewClient
(
es
.
SetURL
(
configs
.
ESSetting
.
Url
))
if
err
!=
nil
{
return
}
index
:=
"stand_brand"
search
:=
client
.
MultiSearch
()
.
Index
(
index
)
for
_
,
bomItem
:=
range
bomItems
{
search
=
searchBrandMap
(
bomItem
,
search
)
}
res
,
err
:=
search
.
Do
(
context
.
Background
())
if
err
!=
nil
{
return
}
if
len
(
res
.
Responses
)
==
0
{
return
}
//因为是多重查询,所以会有多套结果
for
key
,
responses
:=
range
res
.
Responses
{
//有数据进行转换
if
responses
.
Hits
!=
nil
{
var
lyBrandIds
[]
string
for
_
,
hit
:=
range
responses
.
Hits
.
Hits
{
res
,
_
:=
hit
.
Source
.
MarshalJSON
()
lyIdArray
:=
gjson
.
Get
(
string
(
res
),
"attrs.#.attr_brand_id"
)
.
Array
()
for
_
,
id
:=
range
lyIdArray
{
idSlice
:=
strings
.
Split
(
id
.
String
(),
","
)
lyBrandIds
=
append
(
lyBrandIds
,
idSlice
...
)
}
bomItems
[
key
]
.
ZyBrandId
=
hit
.
Id
bomItems
[
key
]
.
ZyBrandName
=
gjson
.
Get
(
string
(
res
),
"stand_zy_brand_name"
)
.
String
()
}
bomItems
[
key
]
.
LyBrandIds
=
lyBrandIds
}
}
result
=
bomItems
return
}
//根据用户输入的品牌获取映射后的品牌,没有映射的话不变,有的话变
func
getBrandMap
(
bomItems
[]
model
.
BomItem
)
{
func
searchBrandMap
(
bomItem
model
.
BomItem
,
search
*
es
.
MultiSearchService
)
(
result
*
es
.
MultiSearchService
)
{
query
:=
getBrandMapQuery
(
bomItem
)
source
:=
es
.
NewSearchSource
()
.
Query
(
query
)
source
=
source
.
From
(
0
)
.
Size
(
1
)
searchRequest
:=
es
.
NewSearchRequest
()
.
Source
(
source
)
search
.
Add
(
searchRequest
)
return
search
}
//获取品牌映射搜索的查询条件
func
getBrandMapQuery
(
bomItem
model
.
BomItem
)
(
query
*
es
.
BoolQuery
)
{
var
subQuery
*
es
.
TermQuery
var
nestedQuery
*
es
.
NestedQuery
query
=
es
.
NewBoolQuery
()
brandName
:=
bomItem
.
BrandName
brandName
=
strings
.
ToUpper
(
brandName
)
//提取出纯中文
r
,
_
:=
regexp
.
Compile
(
"[
\u4e00
-
\u9fa5
]+"
)
chineseBrandName
:=
r
.
FindString
(
brandName
)
if
chineseBrandName
!=
""
{
query
.
Should
(
es
.
NewMatchQuery
(
"brand_name_cn"
,
chineseBrandName
))
}
//提取出纯英文
re
,
_
:=
regexp
.
Compile
(
"[A-Za-z0-9]+"
)
englishBrandName
:=
re
.
FindString
(
brandName
)
subQuery
=
es
.
NewTermQuery
(
"attrs.attr_brand_name"
,
englishBrandName
)
nestedQuery
=
es
.
NewNestedQuery
(
"attrs"
,
subQuery
)
query
.
Should
(
nestedQuery
)
query
.
MinimumNumberShouldMatch
(
1
)
return
query
}
//
internal/logic/goods.go
View file @
2b9184b3
...
...
@@ -4,6 +4,7 @@ import (
"bom_server/configs"
"bom_server/internal/model"
"encoding/json"
"fmt"
"github.com/imroc/req"
"github.com/tidwall/gjson"
"strings"
...
...
@@ -29,7 +30,7 @@ func UpdateGoodsData(goodsMapList []GoodsMap) (err error) {
goodsIds
=
append
(
goodsIds
,
goodsMap
.
GoodsId
)
}
goodsIdsStr
:=
strings
.
Join
(
goodsIds
,
","
)
//
fmt.Println(goodsIdsStr)
fmt
.
Println
(
goodsIdsStr
)
goodsList
,
err
:=
GetGoodsInfo
(
goodsIdsStr
)
if
len
(
goodsMapList
)
!=
0
{
bomId
=
goodsMapList
[
0
]
.
BomId
...
...
@@ -59,6 +60,7 @@ func UpdateGoodsData(goodsMapList []GoodsMap) (err error) {
}
}
}
err
=
BatchSaveMatchings
(
bomId
,
bomMatchingList
)
if
err
!=
nil
{
return
...
...
@@ -167,7 +169,7 @@ func MatchGoodsInfo(goods model.ApiGoods, goodsMap GoodsMap) (bomMatching model.
Mpl
:
goods
.
Mpl
,
Mpq
:
goods
.
Mpq
,
Encap
:
goods
.
Encap
,
Status
:
goods
.
Status
,
Status
:
1
,
AddTime
:
int
(
time
.
Now
()
.
Unix
()),
}
/**
...
...
internal/logic/match.go
View file @
2b9184b3
...
...
@@ -7,6 +7,7 @@ import (
"context"
"encoding/json"
"errors"
"fmt"
"math"
"regexp"
"strings"
...
...
@@ -76,11 +77,15 @@ func SearchGoods(bomId int, bomItems []model.BomItem, deliveryType, sort int, wg
if
len
(
bomItems
)
==
0
{
return
}
//去除首尾空格
bomItems
=
common
.
TrimBomItemSpace
(
bomItems
)
client
,
err
:=
es
.
NewClient
(
es
.
SetURL
(
configs
.
ESSetting
.
Url
))
if
err
!=
nil
{
panic
(
err
)
}
defer
client
.
Stop
()
//先去查询品牌映射,有映射关系的,就用映射关系得到的brand_id进行查询
bomItems
,
err
=
GetBrandMap
(
bomItems
)
//匹配之前,去遍历bom_item,把没有型号名称但是有参数的bom_item进行型号补充
bomItems
,
err
=
MatchGoodsNameByAttrs
(
bomItems
)
//第一次先去精确匹配
...
...
@@ -236,7 +241,7 @@ func search(index string, bomId int, bomItems []model.BomItem, deliveryType, sor
bom
.
GoodsName
=
bom
.
Attrs
}
//构建一个goods_name对应的bomItems列表
searchRequest
:=
getSearchParams
(
index
,
bom
.
GoodsName
,
bom
.
BrandName
,
sort
,
bom
.
Number
,
rawSearch
)
searchRequest
:=
getSearchParams
(
bom
,
sort
,
rawSearch
)
searchFlag
=
true
search
.
Add
(
searchRequest
)
}
...
...
@@ -281,48 +286,57 @@ func search(index string, bomId int, bomItems []model.BomItem, deliveryType, sor
}
//构建请求参数
func
getSearchParams
(
index
,
goodsName
,
brandName
string
,
sort
,
number
int
,
flag
bool
)
(
searchRequest
*
es
.
SearchRequest
)
{
query
:=
getTermQuery
(
goodsName
,
brandName
,
sort
,
number
,
flag
)
func
getSearchParams
(
bomItem
model
.
BomItem
,
sort
int
,
flag
bool
)
(
searchRequest
*
es
.
SearchRequest
)
{
query
:=
getTermQuery
(
bomItem
,
sort
,
flag
)
source
:=
es
.
NewSearchSource
()
.
Query
(
query
)
if
sort
==
1
{
source
.
Sort
(
"_score"
,
false
)
source
.
Sort
(
"sort"
,
false
)
source
.
Sort
(
"stock"
,
false
)
source
.
Sort
(
"single_price"
,
true
)
}
//要去判断sort,sort=2是按照价格排序
if
sort
==
2
{
source
.
Sort
(
"_score"
,
false
)
source
.
Sort
(
"single_price"
,
true
)
//sort=3是按照库存排序
}
else
if
sort
==
3
{
source
.
Sort
(
"
stock_sort
"
,
false
)
source
.
Sort
(
"
_score
"
,
false
)
source
.
Sort
(
"stock"
,
false
)
}
source
.
Sort
(
"_score"
,
false
)
source
=
source
.
From
(
0
)
.
Size
(
1
)
searchRequest
=
es
.
NewSearchRequest
()
.
Source
(
source
)
fmt
.
Println
(
searchRequest
.
Body
())
return
searchRequest
}
//构建term条件
func
getTermQuery
(
goodsName
,
brandName
string
,
sort
,
number
int
,
flag
bool
)
(
query
*
es
.
BoolQuery
)
{
func
getTermQuery
(
bomItem
model
.
BomItem
,
sort
int
,
flag
bool
)
(
query
*
es
.
BoolQuery
)
{
query
=
es
.
NewBoolQuery
()
if
flag
{
field
:=
"auto_goods_name.raw"
replace
,
_
:=
regexp
.
Compile
(
"[^A-Za-z0-9]+"
)
goodsName
:=
replace
.
ReplaceAllString
(
g
oodsName
,
""
)
goodsName
:=
replace
.
ReplaceAllString
(
bomItem
.
G
oodsName
,
""
)
goodsName
=
strings
.
ToUpper
(
goodsName
)
//搜索商品名称
query
=
query
.
Filter
(
es
.
NewTermQuery
(
field
,
goodsName
))
//判断是否存在brandName
,存在就去搜索brandName
if
brandName
!=
""
{
b
randName
=
strings
.
ToUpper
(
b
randName
)
query
=
query
.
Should
(
es
.
NewConstantScoreQuery
(
es
.
NewTermQuery
(
"brand_name"
,
brandName
))
.
Boost
(
2
))
//判断是否存在brandName
并且匹配不到对应的标准品牌
if
b
omItem
.
B
randName
!=
""
{
b
omItem
.
BrandName
=
strings
.
ToUpper
(
bomItem
.
B
randName
)
query
=
query
.
Should
(
es
.
NewConstantScoreQuery
(
es
.
NewTermQuery
(
"brand_name"
,
b
omItem
.
B
randName
))
.
Boost
(
2
))
}
//搜索库存
query
=
query
.
Should
(
es
.
NewConstantScoreQuery
(
es
.
NewRangeQuery
(
"stock"
)
.
Gte
(
n
umber
)))
query
=
query
.
Should
(
es
.
NewConstantScoreQuery
(
es
.
NewRangeQuery
(
"stock"
)
.
Gte
(
bomItem
.
N
umber
)))
}
else
{
field
:=
"auto_goods_name"
query
=
query
.
Must
(
es
.
NewTermQuery
(
field
,
goodsName
))
query
=
query
.
Must
(
es
.
NewTermQuery
(
field
,
bomItem
.
GoodsName
))
}
//对品牌进行判断搜索,如果能匹配到对应的自营标准品牌(那么同时也有对应的联营品牌)
if
bomItem
.
ZyBrandId
!=
""
{
query
.
Should
(
es
.
NewTermQuery
(
"brand_id"
,
bomItem
.
ZyBrandId
))
for
_
,
id
:=
range
bomItem
.
LyBrandIds
{
query
.
Should
(
es
.
NewTermQuery
(
"brand_id"
,
id
))
}
}
//按价格排序
if
sort
==
2
{
...
...
@@ -332,20 +346,8 @@ func getTermQuery(goodsName, brandName string, sort, number int, flag bool) (que
if
sort
==
3
{
query
=
query
.
Filter
(
es
.
NewRangeQuery
(
"stock"
)
.
Gt
(
0
))
}
//query = query.Filter(es.NewRangeQuery("single_price").Gt(0))
//query = query.Filter(es.NewRangeQuery("stock").Gt(0))
if
configs
.
ApiSetting
.
Mode
!=
"debug"
{
query
=
query
.
Filter
(
es
.
NewTermQuery
(
"status"
,
1
))
}
//query = query.Filter(es.NewRangeQuery("single_price").Gt(0))
//src, err := query.Source()
//if err != nil {
// panic(err)
//}
//data, err := json.MarshalIndent(src, "", " ")
//if err != nil {
// panic(err)
//}
//fmt.Println(string(data))
return
query
}
internal/model/bom_item.go
View file @
2b9184b3
...
...
@@ -23,9 +23,11 @@ type BomItem struct {
UpdateTime
int
`json:"update_time"`
//映射后的自营品牌id
ZyBrandId
int
`json:"-"`
ZyBrandId
string
`json:"-"`
//映射后的联营品牌id
LyBrandId
int
`json:"-"`
LyBrandIds
[]
string
`json:"-"`
//映射后的品牌名称(自营品牌名称)
ZyBrandName
string
`json:"-"`
Matching
BomItemMatching
`json:"matching"`
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment