Commit a86b8559 by mushishixian

完善请求es

parent 7ee4bf02
The file could not be displayed because it is too large.
build_pkg: "./"
watch_paths:
- ../
\ No newline at end of file
...@@ -14,8 +14,6 @@ func main() { ...@@ -14,8 +14,6 @@ func main() {
flag.Parse() flag.Parse()
configs.Setup(path) configs.Setup(path)
model.Setup() model.Setup()
logic.MatchGoods(11)
logic.SearchGoods("213")
queue.Sync() queue.Sync()
} }
...@@ -2,7 +2,6 @@ package queue ...@@ -2,7 +2,6 @@ package queue
import ( import (
"bom_server/configs" "bom_server/configs"
"bom_server/internal/logic"
"fmt" "fmt"
"github.com/ichunt2019/go-rabbitmq/utils/rabbitmq" "github.com/ichunt2019/go-rabbitmq/utils/rabbitmq"
) )
...@@ -20,7 +19,6 @@ func (t *RecvPro) FailAction(dataByte []byte) error { ...@@ -20,7 +19,6 @@ func (t *RecvPro) FailAction(dataByte []byte) error {
} }
func Sync() { func Sync() {
fmt.Println(logic.GetBomInfoWithItems(1))
t := &RecvPro{} t := &RecvPro{}
rabbitmq.Recv(rabbitmq.QueueExchange{ rabbitmq.Recv(rabbitmq.QueueExchange{
"bom_match", "bom_match",
......
...@@ -11,6 +11,7 @@ url = "amqp://huntadmin:jy2y2900@192.168.1.237:5672/" ...@@ -11,6 +11,7 @@ url = "amqp://huntadmin:jy2y2900@192.168.1.237:5672/"
[api] [api]
base = http://192.168.2.232:40001 base = http://192.168.2.232:40001
goods = http://192.168.2.232:60004
[falcon] [falcon]
push_url = http://192.168.1.237:1988/v1/push push_url = http://192.168.1.237:1988/v1/push
......
...@@ -32,18 +32,24 @@ type Redis struct { ...@@ -32,18 +32,24 @@ type Redis struct {
} }
type ES struct { type ES struct {
Url string `ini:"url"` Url string `ini:"url"`
GoodsIndexName string `ini:"goods_index_name"` GoodsIndexName string `ini:"goods_index_name"`
} }
type RabbitMQ struct { type RabbitMQ struct {
Url string `ini:"url"` Url string `ini:"url"`
}
type Api struct {
Goods string `ini:"goods"`
} }
var DatabaseSetting = &Database{} var DatabaseSetting = &Database{}
var RedisSetting = &Redis{} var RedisSetting = &Redis{}
var RabbitMQSetting = &RabbitMQ{} var RabbitMQSetting = &RabbitMQ{}
var ESSetting = &ES{} var ESSetting = &ES{}
var ApiSetting = &Api{}
var ( var (
cfg *ini.File cfg *ini.File
) )
...@@ -60,6 +66,7 @@ func Setup(filePath string) { ...@@ -60,6 +66,7 @@ func Setup(filePath string) {
mapTo("redis", RedisSetting) mapTo("redis", RedisSetting)
mapTo("rabbitmq", RabbitMQSetting) mapTo("rabbitmq", RabbitMQSetting)
mapTo("es", ESSetting) mapTo("es", ESSetting)
mapTo("api", ApiSetting)
RedisSetting.IdleTimeout = RedisSetting.IdleTimeout * time.Second RedisSetting.IdleTimeout = RedisSetting.IdleTimeout * time.Second
} }
......
...@@ -3,15 +3,18 @@ module bom_server ...@@ -3,15 +3,18 @@ module bom_server
go 1.13 go 1.13
require ( require (
github.com/beevik/etree v1.1.0 github.com/360EntSecGroup-Skylar/excelize v1.4.1
github.com/go-ini/ini v1.56.0 github.com/go-ini/ini v1.56.0
github.com/go-kratos/kratos v0.5.0 github.com/go-kratos/kratos v0.5.0
github.com/hprose/hprose-golang v2.0.5+incompatible
github.com/ichunt2019/go-rabbitmq v1.0.1 github.com/ichunt2019/go-rabbitmq v1.0.1
github.com/imroc/req v0.3.0 github.com/imroc/req v0.3.0
github.com/jinzhu/gorm v1.9.12 github.com/jinzhu/gorm v1.9.12
github.com/jmoiron/sqlx v1.2.0 github.com/jmoiron/sqlx v1.2.0
github.com/mushishixian/gosoap v1.2.0
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/smartystreets/goconvey v1.6.4 // indirect github.com/smartystreets/goconvey v1.6.4 // indirect
github.com/syyongx/php2go v0.9.4
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e
gopkg.in/ini.v1 v1.56.0 // indirect gopkg.in/ini.v1 v1.56.0 // indirect
gopkg.in/olivere/elastic.v5 v5.0.85
) )
...@@ -3,6 +3,7 @@ package common ...@@ -3,6 +3,7 @@ package common
import ( import (
"crypto/md5" "crypto/md5"
"encoding/hex" "encoding/hex"
"github.com/syyongx/php2go"
) )
// Md5 md5() // Md5 md5()
...@@ -12,7 +13,23 @@ func Md5(str string) string { ...@@ -12,7 +13,23 @@ func Md5(str string) string {
return hex.EncodeToString(hash.Sum(nil)) return hex.EncodeToString(hash.Sum(nil))
} }
//非精确匹配,字符串截取向下80%,5个字符以下不截,5-10个截一个,10-20个向下取80%,20个以上向下取70%
func SubKeyWordStr(str string) string {
strLen := len(str)
strLenFloat := float64(strLen)
if strLen < 5 {
return str
}
if strLen >= 5 && strLen <= 10 {
str = php2go.Substr(str, 0, strLen-1)
}
if strLen > 10 && strLen <= 20 {
num := php2go.Floor(strLenFloat * 0.2)
str = php2go.Substr(str, 0, strLen-int(num))
}
if strLen > 20 {
num := php2go.Floor(strLenFloat * 0.3)
str = php2go.Substr(str, 0, strLen-int(num))
}
return str
}
...@@ -2,11 +2,14 @@ package logic ...@@ -2,11 +2,14 @@ package logic
import ( import (
"bom_server/internal/model" "bom_server/internal/model"
"fmt"
) )
//根据bom_id查出bom表信息 //根据bom_id查出bom表信息
func GetBomInfo(bomId int) (bom model.Bom) { func GetBomInfo(bomId int) (bom model.Bom) {
model.Db.Where("bom_id = ?", bomId).First(&bom) if err := model.Db.Where("bom_id = ?", bomId).First(&bom).Error; err != nil {
fmt.Println(err)
}
return bom return bom
} }
......
package logic
import (
"bom_server/configs"
"bom_server/internal/model"
"encoding/json"
"fmt"
"github.com/imroc/req"
"strings"
"time"
)
type GoodsMap struct {
GoodsId string
GoodsName string
BomItemId int
BomId int
Number int
}
func UpdateGoodsData(goodsMapList []GoodsMap) () {
//根据goodsIds去商品服务获取对应的商品信息
var goodsIds []string
for _, goodsMap := range goodsMapList {
goodsIds = append(goodsIds, goodsMap.GoodsId)
}
goodsIdsStr := strings.Join(goodsIds, ",")
goodsServerUrl := configs.ApiSetting.Goods
params := req.Param{
"goods_id": goodsIdsStr,
}
//req.Debug = true
resp, err := req.Post(goodsServerUrl+"/synchronization", params)
if err != nil {
fmt.Println(err)
}
var responseData model.ApiGoodsResponse
if err := resp.ToJSON(&responseData); err != nil {
fmt.Println(err)
}
bomMatchingList := map[string]model.BomItemMatching{}
for _, goodsMap := range goodsMapList {
for _, goods := range responseData.Data {
if goodsMap.GoodsId == goods.GoodsID {
//组装需要去更新的商品信息
bomMatching := model.BomItemMatching{
BomID: goodsMap.BomId,
BomItemID: goodsMap.BomItemId,
GoodsID: goods.GoodsID,
GoodsType: goods.AcType,
SupplierID: goods.SupplierID,
SupplierName: goods.SupplierName,
CnDelivery: goods.CnDeliveryTime,
HkDelivery: goods.HkDeliveryTime,
Number: goodsMap.Number,
Stock: goods.Stock,
Moq: goods.Moq,
Mpq: goods.Mpq,
Encap: goods.Encap,
Status: goods.Status,
AddTime: int(time.Now().Unix()),
UpdateTime: 0,
}
//阶梯价处理
if len(goods.LadderPrice) > 0 {
ladderPriceStr, err := json.Marshal(goods.LadderPrice)
if err != nil {
fmt.Println(err)
}
bomMatching.LadderPrice = string(ladderPriceStr)
//获取美元和人民币的价格
bomMatching.CnPrice = 0
bomMatching.HkPrice = 0
}
bomMatchingList[bomMatching.GoodsID] = bomMatching
}
}
}
}
...@@ -2,9 +2,15 @@ package logic ...@@ -2,9 +2,15 @@ package logic
import ( import (
"bom_server/configs" "bom_server/configs"
"bom_server/internal/common"
"bom_server/internal/model" "bom_server/internal/model"
"context"
"encoding/json"
"fmt" "fmt"
"github.com/imroc/req" es "gopkg.in/olivere/elastic.v5"
"regexp"
"strconv"
"strings"
) )
//匹配商品 //匹配商品
...@@ -15,44 +21,165 @@ import ( ...@@ -15,44 +21,165 @@ import (
4.得到具体的商品数据以后,针对对应的商品进行修改 4.得到具体的商品数据以后,针对对应的商品进行修改
**/ **/
func MatchGoods(bom model.Bom) { func MatchGoods(bomId int) {
bomItems := bom.BomItems //获取bom
for _, item := range bomItems { //bom := GetBomInfoWithItems(11)
fmt.Println(item) //bomItems := bom.BomItems
bomItems := []model.BomItem{
{
BomID: 7,
BomItemID: 1,
BrandName: "ADVID",
GoodsName: "ECC15DCKNS1562",
Number: 1,
},
{
BomID: 7,
BomItemID: 2,
BrandName: "ADVID",
GoodsName: "ECC15DCKNS1562",
Number: 1,
},
{
BomID: 7,
BomItemID: 3,
BrandName: "ADVID",
GoodsName: "ECC15DCKNS15621",
Number: 1,
},
{
BomID: 7,
BomItemID: 4,
BrandName: "ADVID",
GoodsName: "ECC15DCKNS1562",
Number: 1,
},
} }
bomId = 11
SearchGoods(bomId, bomItems)
} }
//去es搜索商品 //去es搜索商品,得到对应的商品对应关系
func SearchGoods(goodsName string) (goodsId int) { func SearchGoods(bomId int, bomItems []model.BomItem) {
var ( client, err := es.NewClient(es.SetURL(configs.ESSetting.Url))
err error if err != nil {
foo []map[string]string panic(err)
url string }
resp *req.Resp defer client.Stop()
) //第一次先去精确匹配
goodsMapList, err := getUpdateGoodsData(bomId, bomItems, client, true)
url = configs.ESSetting.Url
req.Debug = true
resp, err = req.Get(url, req.BodyJSON(&foo))
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} }
fmt.Println(resp.String()) UpdateGoodsData(goodsMapList)
getSearchParams() //第二次去模糊匹配
return goodsId //todo : 先删除第一次已经精确匹配的bom
goodsMapList, err = getUpdateGoodsData(bomId, bomItems, client, true)
if err != nil {
fmt.Println(err)
}
UpdateGoodsData(goodsMapList)
}
func getUpdateGoodsData(bomId int, bomItems []model.BomItem, client *es.Client, rawSearch bool) (goodsMapList []GoodsMap, err error) {
index := configs.ESSetting.GoodsIndexName
search := client.MultiSearch().Index(index)
//多重搜索,第一次先去精确匹配
for _, bom := range bomItems {
//如果是模糊查询,还要去截取字符串
if !rawSearch {
bom.GoodsName = common.SubKeyWordStr(bom.GoodsName)
}
//构建一个goods_name对应的bomItems列表
searchRequest := getSearchParams(bom.GoodsName, bom.BrandName, bom.Number, rawSearch)
search.Add(searchRequest)
}
res, err := search.Do(context.Background())
if err != nil {
return
}
//因为是多重查询,所以会有多套结果
for key, responses := range res.Responses {
//有数据进行转换
if responses.Hits.TotalHits > 0 {
for _, hit := range responses.Hits.Hits {
var goods model.Goods
err := json.Unmarshal(*hit.Source, &goods)
if err != nil {
return nil, err
}
var goodsMap GoodsMap
goodsMap.GoodsId = strconv.FormatInt(int64(goods.GoodsID), 10)
goodsMap.GoodsName = goods.GoodsName
goodsMap.BomItemId = bomItems[key].BomItemID
goodsMap.BomId = bomId
goodsMapList = append(goodsMapList, goodsMap)
break
}
}
}
return
} }
//构建请求参数 //构建请求参数
func getSearchParams(){ func getSearchParams(goodsName, brandName string, number int, flag bool) (searchRequest *es.SearchRequest) {
//var size int
//if flag {
// size = 10
//} else {
// size = 1
//}
query := getTermQuery(goodsName, brandName, number, flag)
source := es.NewSearchSource().IndexBoost("liexin_ziying", 2).Query(query).Size(1).
Sort("_score", false).Sort("sort", false).Sort("single_price", true).
From(0)
searchRequest = es.NewSearchRequest().Source(source)
return searchRequest
}
//构建term条件
func getTermQuery(goodsName, brandName string, number int, flag bool) (query *es.BoolQuery) {
var ( var (
indexName string field string
) )
indexName = configs.ESSetting.GoodsIndexName
fmt.Println(indexName)
} if number == 0 {
number = 0
}
query = es.NewBoolQuery()
if flag {
func GetGoodsData(goodsIds []int) () { field = "auto_goods_name.raw"
replace, _ := regexp.Compile("[^A-Za-z0-9]+")
goodsName := replace.ReplaceAllString(goodsName, "")
goodsName = strings.ToUpper(goodsName)
//搜索商品名称
query = query.Filter(es.NewTermQuery(field, goodsName))
//判断是否存在brandName,存在就去搜索brandName
if brandName != "" {
brandName = strings.ToUpper(brandName)
query = query.Should(es.NewConstantScoreQuery(es.NewTermQuery("brand_name", brandName)).Boost(2))
}
//搜索库存
query = query.Should(es.NewConstantScoreQuery(es.NewRangeQuery("stock").Gte(number)))
} else {
field = "auto_goods_name"
query = query.Must(es.NewTermQuery(field, goodsName))
}
query = query.Filter(es.NewTermQuery("status", 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
} }
package model package model
type LieBomItemMatching0 struct { type BomItemMatching struct {
// MatchingID 匹配ID // MatchingID 匹配ID
MatchingID int `json:"matching_id"` MatchingID int `json:"matching_id"`
// BomID bom主表Id(为了方便逆向查找bom_item表) // BomID bom主表Id(为了方便逆向查找bom_item表)
...@@ -8,7 +8,7 @@ type LieBomItemMatching0 struct { ...@@ -8,7 +8,7 @@ type LieBomItemMatching0 struct {
// BomItemID bom详情ID // BomItemID bom详情ID
BomItemID int `json:"bom_item_id"` BomItemID int `json:"bom_item_id"`
// GoodsID 匹配到的商品ID // GoodsID 匹配到的商品ID
GoodsID int `json:"goods_id"` GoodsID string `json:"goods_id"`
// GoodsType 0:自营 1:联营 2:专卖 // GoodsType 0:自营 1:联营 2:专卖
GoodsType int `json:"goods_type"` GoodsType int `json:"goods_type"`
// SupplierID 供应商ID // SupplierID 供应商ID
...@@ -33,7 +33,7 @@ type LieBomItemMatching0 struct { ...@@ -33,7 +33,7 @@ type LieBomItemMatching0 struct {
// Encap 封装 // Encap 封装
Encap string `json:"encap"` Encap string `json:"encap"`
// Status 1:正常 2:取消匹配(被替换) // Status 1:正常 2:取消匹配(被替换)
Status uint8 `json:"status"` Status int `json:"status"`
// AddTime 创建时间 // AddTime 创建时间
AddTime int `json:"add_time"` AddTime int `json:"add_time"`
// UpdateTime 更新时间 // UpdateTime 更新时间
......
package model
type Goods struct {
GoodsID int `json:"goods_id"`
OldGoodsID int `json:"old_goods_id"`
GoodsName string `json:"goods_name"`
AutoGoodsName string `json:"auto_goods_name"`
BrandID interface{} `json:"brand_id"`
BrandName string `json:"brand_name"`
SupplierName string `json:"supplier_name"`
ClassID1 int `json:"class_id1"`
ClassID2 int `json:"class_id2"`
ClassID3 int `json:"class_id3"`
SpuID int `json:"spu_id"`
SaleTime int `json:"sale_time"`
GoodsDetails string `json:"goods_details"`
CreateTime int `json:"create_time"`
UpdateTime int `json:"update_time"`
SinglePrice float64 `json:"single_price"`
Stock int `json:"stock"`
GoodsStatus int `json:"goods_status"`
Status int `json:"status"`
Sort int `json:"sort"`
Encoded string `json:"encoded"`
Encap string `json:"encap"`
CanalNew string `json:"canal_new"`
StockSort int `json:"stock_sort"`
SinglePriceSort int `json:"single_price_sort"`
}
type ApiGoodsResponse struct {
Errcode int `json:"errcode"`
Errmsg string `json:"errmsg"`
Data Data `json:"data"`
}
type Data map[string]ApiGoods
type ApiGoods struct {
GoodsID string `json:"goods_id"`
GoodsSn string `json:"goods_sn"`
SpuID string `json:"spu_id"`
UpdateTime int `json:"update_time"`
GoodsStatus int `json:"goods_status"`
GoodsName string `json:"goods_name"`
GoodsType int `json:"goods_type"`
SupplierID int `json:"supplier_id"`
Encoded string `json:"encoded"`
BatchSn string `json:"batch_sn"`
Moq int `json:"moq"`
Mpq int `json:"mpq"`
Stock int `json:"stock"`
HkDeliveryTime string `json:"hk_delivery_time"`
CnDeliveryTime string `json:"cn_delivery_time"`
GoodsDetails string `json:"goods_details"`
LadderPrice []struct {
Purchases int `json:"purchases"`
PriceUs float64 `json:"price_us"`
PriceCn float64 `json:"price_cn"`
} `json:"ladder_price"`
GoodsImages string `json:"goods_images"`
Canal string `json:"canal"`
CpTime int `json:"cp_time"`
BrandName string `json:"brand_name"`
SupplierName string `json:"supplier_name"`
Attrs interface{} `json:"attrs"`
AcType int `json:"ac_type"`
AllowCoupon int `json:"allow_coupon"`
BrandID int `json:"brand_id"`
Coefficient struct {
Cn string `json:"cn"`
Hk string `json:"hk"`
ExtraRatio string `json:"extra_ratio"`
Ratio string `json:"ratio"`
Tax float64 `json:"tax"`
} `json:"coefficient"`
OriginalPrice []struct {
Purchases int `json:"purchases"`
PriceCn int `json:"price_cn"`
PriceUs float64 `json:"price_us"`
} `json:"original_price"`
SuppExtendFee struct {
Cn struct {
Max string `json:"max"`
Price string `json:"price"`
} `json:"cn"`
Hk struct {
Max int `json:"max"`
Price int `json:"price"`
} `json:"hk"`
} `json:"supp_extend_fee"`
IsBuy int `json:"is_buy"`
ClassID1 int `json:"class_id1"`
ClassID2 int `json:"class_id2"`
ClassID3 int `json:"class_id3"`
SpuName string `json:"spu_name"`
Status int `json:"status"`
ImagesL string `json:"images_l"`
Encap string `json:"encap"`
Pdf string `json:"pdf"`
SpuBrief string `json:"spu_brief"`
SpuDetail string `json:"spu_detail"`
ClassName string `json:"class_name"`
ErpTax bool `json:"erp_tax"`
}
package service
import (
"errors"
"github.com/beevik/etree"
"github.com/mushishixian/gosoap"
"bom_server/configs"
)
func LoginErp() (err error) {
soap, err := gosoap.SoapClient(configs.ErpLoginStatusApi)
if err != nil {
return
}
params := gosoap.ArrayParams{
{"userName", configs.ErpUserName},
{"password", configs.ErpPassword},
{"slnName", configs.ErpSlnName},
{"dcName", configs.ErpDcName},
{"language", configs.ErpLanguage},
{"dbType", configs.ErpDbType},
{"authPattern", configs.ErpAuthPattern},
}
res, err := soap.Call("login", params)
if err != nil {
return
}
doc := etree.NewDocument()
if err := doc.ReadFromBytes(res.Body); err != nil {
return err
}
root := doc.SelectElement("multiRef")
sessionId := root.SelectElement("sessionId").Text()
if sessionId != "" {
return
}
return errors.New(string(res.Body))
}
package service
import (
"fmt"
"github.com/360EntSecGroup-Skylar/excelize"
"math/rand"
"strconv"
"time"
)
func init() {
rand.Seed(time.Now().UnixNano())
}
var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
func RandStringRunes(n int) string {
b := make([]rune, n)
for i := range b {
b[i] = letterRunes[rand.Intn(len(letterRunes))]
}
return string(b)
}
//导出excel
func Export() {
t := time.Now()
f := excelize.NewFile()
// Create a new sheet.
str := RandStringRunes(10)
index := f.NewSheet("Sheet1")
for i := 1; i <= 200; i++ {
// Set value of a cell.
temp := strconv.FormatInt(int64(i), 10)
f.SetCellValue("Sheet1", "A"+temp, str)
f.SetCellValue("Sheet1", "B"+temp, str)
}
f.SetActiveSheet(index)
// Save xlsx file by the given path.
if err := f.SaveAs("Book1" + str + ".xlsx"); err != nil {
fmt.Println(err)
}
elapsed := time.Since(t)
fmt.Println(elapsed)
}
package main package main
func main() { import (
"net/http"
"github.com/hprose/hprose-golang/rpc"
)
func hello(name string) string {
return "Hello " + name + "!"
}
func main() {
service := rpc.NewHTTPService()
service.AddFunction("hello", hello, rpc.Options{})
http.ListenAndServe(":8080", service)
} }
package main
import (
"bom_server/internal/service"
"fmt"
"time"
"github.com/hprose/hprose-golang/rpc"
)
type Stub struct {
Hello func(string) (string, error)
AsyncHello func(func(string, error), string) `name:"hello"`
}
func testHprose() {
client := rpc.NewClient("http://127.0.0.1:8080/")
var stub *Stub
client.UseService(&stub)
stub.AsyncHello(func(result string, err error) {
fmt.Println(result, err)
}, "async world")
fmt.Println(stub.Hello("world"))
}
func main() {
for i:=0;i<100;i++ {
go service.Export()
}
fmt.Println(21321)
time.Sleep(100*time.Second)
}
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