316 lines
7.9 KiB
Go
316 lines
7.9 KiB
Go
package jxutils
|
||
|
||
import (
|
||
"crypto/md5"
|
||
"fmt"
|
||
"io/ioutil"
|
||
"math"
|
||
"net/http"
|
||
"reflect"
|
||
"regexp"
|
||
"strings"
|
||
"time"
|
||
|
||
"git.rosy.net.cn/baseapi/platformapi"
|
||
"git.rosy.net.cn/baseapi/utils"
|
||
"git.rosy.net.cn/jx-callback/business/model"
|
||
)
|
||
|
||
var (
|
||
storeNamePat = regexp.MustCompile(`([^(\[(【)\])】\-\s]*)[(\[(【\-\s]+([^(\[(【)\])】\-]*)[)\])】]*`)
|
||
)
|
||
|
||
// 合并得到最终的门店状态
|
||
func MergeStoreStatus(status int, vendorStatus int) int {
|
||
if status < vendorStatus {
|
||
return status
|
||
}
|
||
return vendorStatus
|
||
}
|
||
|
||
func MergeSkuStatus(skuStatus int, storeSkuStatus int) int {
|
||
if skuStatus < storeSkuStatus {
|
||
return skuStatus
|
||
}
|
||
return storeSkuStatus
|
||
}
|
||
|
||
func SplitSlice(list interface{}, batchCount int) (listInList [][]interface{}) {
|
||
typeInfo := reflect.TypeOf(list)
|
||
if typeInfo.Kind() != reflect.Slice {
|
||
panic("list must be slice")
|
||
}
|
||
valueInfo := reflect.ValueOf(list)
|
||
len := valueInfo.Len()
|
||
if len > 0 {
|
||
listInListLen := (len-1)/batchCount + 1
|
||
listInList = make([][]interface{}, listInListLen)
|
||
index := 0
|
||
for i := 0; i < len; i++ {
|
||
if i%batchCount == 0 {
|
||
index = i / batchCount
|
||
arrLen := len - i
|
||
if arrLen > batchCount {
|
||
arrLen = batchCount
|
||
}
|
||
listInList[index] = make([]interface{}, arrLen)
|
||
}
|
||
listInList[index][i%batchCount] = valueInfo.Index(i).Interface()
|
||
}
|
||
}
|
||
return listInList
|
||
}
|
||
|
||
func SplitStoreName(fullName, separator, defaultPrefix string) (prefix, bareName string) {
|
||
names := strings.Split(fullName, separator)
|
||
if len(names) == 2 {
|
||
prefix = names[0]
|
||
bareName = names[1]
|
||
} else {
|
||
searchResult := storeNamePat.FindStringSubmatch(fullName)
|
||
if searchResult != nil {
|
||
prefix = searchResult[1]
|
||
bareName = strings.Trim(strings.Trim(searchResult[2], defaultPrefix), separator)
|
||
} else {
|
||
prefix = defaultPrefix
|
||
bareName = strings.Trim(strings.Trim(fullName, defaultPrefix), separator)
|
||
}
|
||
}
|
||
return TrimDecorationChar(prefix), TrimDecorationChar(bareName)
|
||
}
|
||
|
||
func ComposeStoreName(bareName string, vendorID int) (fullName string) {
|
||
bareName = TrimDecorationChar(strings.Trim(bareName, "-"))
|
||
if vendorID == model.VendorIDJD {
|
||
fullName = "京西菜市-" + bareName
|
||
} else {
|
||
fullName = "京西菜市(" + bareName + ")"
|
||
}
|
||
return fullName
|
||
}
|
||
|
||
func StrTime2JxOperationTime(strTime string, defValue int16) int16 {
|
||
if timeValue, err := time.Parse("15:04:05", strTime); err == nil {
|
||
return int16(timeValue.Hour()*100 + timeValue.Minute())
|
||
}
|
||
return defValue
|
||
}
|
||
|
||
func JxOperationTime2StrTime(value int16) string {
|
||
return fmt.Sprintf("%02d:%02d", value/100, value%100)
|
||
}
|
||
|
||
func GetPolygonFromCircle(lng, lat, distance float64, pointCount int) (points [][2]float64) {
|
||
points = make([][2]float64, pointCount)
|
||
for k := range points {
|
||
angle := float64(k) * 360 / float64(pointCount)
|
||
points[k][0], points[k][1] = ConvertDistanceToLogLat(lng, lat, float64(distance), angle)
|
||
}
|
||
return points
|
||
}
|
||
|
||
func GetPolygonFromCircleStr(lng, lat, distance float64, pointCount int) string {
|
||
return CoordinatePoints2Str(GetPolygonFromCircle(lng, lat, distance, pointCount))
|
||
}
|
||
|
||
func CoordinatePoints2Str(points [][2]float64) string {
|
||
points2 := make([]string, len(points))
|
||
for k, v := range points {
|
||
points2[k] = fmt.Sprintf("%.6f,%.6f", v[0], v[1])
|
||
}
|
||
return strings.Join(points2, ";")
|
||
}
|
||
|
||
func CoordinateStr2Points(pointsStr string) (points [][2]float64) {
|
||
strPoints := strings.Split(pointsStr, ";")
|
||
for _, v := range strPoints {
|
||
strPoint := strings.Split(v, ",")
|
||
if len(strPoint) >= 2 {
|
||
points = append(points, [2]float64{utils.Str2Float64(strPoint[0]), utils.Str2Float64(strPoint[1])})
|
||
}
|
||
}
|
||
return points
|
||
}
|
||
|
||
func IntMap2List(intMap map[int]int) []int {
|
||
retVal := make([]int, len(intMap))
|
||
index := 0
|
||
for k := range intMap {
|
||
retVal[index] = k
|
||
index++
|
||
}
|
||
return retVal
|
||
}
|
||
|
||
func Int64Map2List(int64Map map[int64]int) []int64 {
|
||
retVal := make([]int64, len(int64Map))
|
||
index := 0
|
||
for k := range int64Map {
|
||
retVal[index] = k
|
||
index++
|
||
}
|
||
return retVal
|
||
}
|
||
|
||
// 计算SKU价格,unitPrice为一斤的单价,specQuality为质量,单位为克
|
||
func CaculateSkuPrice(unitPrice int, specQuality float32, specUnit string, skuNameUnit string) int {
|
||
if skuNameUnit != "份" {
|
||
return unitPrice
|
||
}
|
||
lowerSpecUnit := strings.ToLower(specUnit)
|
||
if lowerSpecUnit == "kg" || lowerSpecUnit == "l" {
|
||
specQuality *= 1000
|
||
}
|
||
price := int(math.Round(float64(float32(unitPrice) * specQuality / 500)))
|
||
if specQuality < 250 {
|
||
price = price * 110 / 100
|
||
} else if specQuality < 500 {
|
||
price = price * 105 / 100
|
||
}
|
||
if price <= 0 {
|
||
price = 1
|
||
}
|
||
return price
|
||
}
|
||
|
||
func GetSliceLen(list interface{}) int {
|
||
return reflect.ValueOf(list).Len()
|
||
}
|
||
|
||
func CaculateSkuVendorPrice(price int, percentage int) int {
|
||
storePrice := int(math.Round(float64(price*percentage) / 100))
|
||
if storePrice < 0 {
|
||
storePrice = 0
|
||
}
|
||
return storePrice
|
||
}
|
||
|
||
// 生成一个不重复的临时ID
|
||
func genFakeID1() int64 {
|
||
return time.Now().UnixNano() / 1000000
|
||
}
|
||
|
||
func GenFakeID() int64 {
|
||
return genFakeID1() * 3
|
||
}
|
||
|
||
func IsFakeID(id int64) bool {
|
||
if id == 0 {
|
||
return true
|
||
}
|
||
multiple := id / genFakeID1()
|
||
return multiple >= 2 && multiple <= 4
|
||
}
|
||
|
||
func FormalizePageSize(pageSize int) int {
|
||
if pageSize == 0 {
|
||
return model.DefPageSize
|
||
} else if pageSize < 0 {
|
||
return model.UnlimitedPageSize
|
||
}
|
||
return pageSize
|
||
}
|
||
|
||
func FormalizeName(name string) string {
|
||
return utils.TrimBlankChar(strings.Replace(strings.Replace(name, "\t", "", -1), "\"", "", -1))
|
||
}
|
||
|
||
func Int2OneZero(value int) int {
|
||
if value != 0 {
|
||
return 1
|
||
}
|
||
return 0
|
||
}
|
||
|
||
// 判断电话号码是否是假的,比如有****号
|
||
func IsMobileFake(mobile string) bool {
|
||
return len(mobile) >= 13 || mobile == ""
|
||
}
|
||
|
||
func FormalizeMobile(mobile string) string {
|
||
mobile = TrimDecorationChar(mobile)
|
||
return strings.Replace(strings.Replace(mobile, "-", ",", -1), "_", ",", -1)
|
||
}
|
||
|
||
func IsLegalStoreID(id int) bool {
|
||
return id >= 100000 && id < 200000
|
||
}
|
||
|
||
// 将规格转为重量
|
||
func FormatSkuWeight(specQuality float32, specUnit string) int {
|
||
lowerSpecUnit := strings.ToLower(specUnit)
|
||
if lowerSpecUnit == "kg" || lowerSpecUnit == "l" {
|
||
specQuality *= 1000
|
||
}
|
||
return int(specQuality)
|
||
}
|
||
|
||
type SkuList []*model.Sku
|
||
|
||
func (s SkuList) Len() int {
|
||
return len(s)
|
||
}
|
||
|
||
func (s SkuList) Less(i, j int) bool {
|
||
if s[i].NameID == s[j].NameID {
|
||
if s[i].SpecUnit == s[j].SpecUnit {
|
||
return s[i].SpecQuality < s[j].SpecQuality
|
||
}
|
||
return s[i].SpecUnit < s[j].SpecUnit
|
||
}
|
||
return s[i].NameID < s[j].NameID
|
||
}
|
||
|
||
func (s SkuList) Swap(i, j int) {
|
||
tmp := s[i]
|
||
s[i] = s[j]
|
||
s[j] = tmp
|
||
}
|
||
|
||
func DownloadFileByURL(fileURL string) (bodyData []byte, fileMD5 string, err error) {
|
||
response, err := http.Get(fileURL)
|
||
if err == nil {
|
||
defer response.Body.Close()
|
||
if response.StatusCode == http.StatusOK {
|
||
if bodyData, err = ioutil.ReadAll(response.Body); err == nil {
|
||
fileMD5 = fmt.Sprintf("%X", md5.Sum(bodyData))
|
||
}
|
||
} else {
|
||
err = platformapi.ErrHTTPCodeIsNot200
|
||
}
|
||
}
|
||
return bodyData, fileMD5, err
|
||
}
|
||
|
||
/////
|
||
func GenPicFileName(suffix string) string {
|
||
return fmt.Sprintf("%x%s", md5.Sum([]byte(utils.GetUUID()+suffix)), suffix)
|
||
}
|
||
|
||
func GuessVendorIDFromVendorStoreID(vendorStoreID int64) (vendorID int) {
|
||
vendorID = model.VendorIDUnknown
|
||
if vendorStoreID > 10040008 && vendorStoreID < 98765432 { // 京东11733065,8位
|
||
vendorID = model.VendorIDJD
|
||
} else if vendorStoreID > 1234567 && vendorStoreID < 9876543 { // 美团外卖 2461713,7位
|
||
vendorID = model.VendorIDMTWM
|
||
} else if vendorStoreID > 1234567890 && vendorStoreID < 9987654321 { // 饿百 2167002607,10位
|
||
vendorID = model.VendorIDEBAI
|
||
} else if vendorStoreID > 123456789 && vendorStoreID < 987654321 { // 微盟微商城 132091048,9位
|
||
vendorID = model.VendorIDWSC
|
||
} else if vendorStoreID > 123456 && vendorStoreID < 654321 { // 京西门店ID,6位
|
||
vendorID = model.VendorIDJX
|
||
}
|
||
return vendorID
|
||
}
|
||
|
||
func GetVendorName(vendorID int) (vendorName string) {
|
||
return model.VendorChineseNames[vendorID]
|
||
}
|
||
|
||
func AddVendorInfo2Err(inErr error, vendorID int) (outErr error) {
|
||
if inErr != nil {
|
||
outErr = fmt.Errorf("处理平台%s, %s", model.VendorChineseNames[vendorID], inErr.Error())
|
||
}
|
||
return outErr
|
||
}
|