Files
jx-callback/business/partner/purchase/tiktok_store/warehouse.go
2023-07-12 13:56:48 +08:00

373 lines
15 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package tiktok_store
import (
"errors"
"fmt"
"strconv"
"strings"
address_create_request "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/address_create/request"
address_list_request "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/address_list/request"
address_list_response "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/address_list/response"
warehouse_bindFencesByStore_request "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/warehouse_bindFencesByStore/request"
warehouse_bindStore_request "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/warehouse_bindStore/request"
warehouse_create_request "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/warehouse_create/request"
warehouse_createBatch_request "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/warehouse_createBatch/request"
warehouse_createFence_request "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/warehouse_createFence/request"
warehouse_getFences_response "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/warehouse_getFences/response"
warehouse_getWarehouseByStore_response "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/warehouse_getWarehouseByStore/response"
warehouse_setFence_request "git.rosy.net.cn/baseapi/platformapi/tiktok_shop/sdk-golang/api/warehouse_setFence/request"
"git.rosy.net.cn/baseapi/platformapi/tiktok_shop/tiktok_api"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/baseapi/utils/errlist"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/model/dao"
"git.rosy.net.cn/jx-callback/globals"
)
const (
//京西平台的电子围栏形状
LocalShapeCircular = 3 //圆
LocalShapePolygon = 2 //普通多边形
)
// /warehouse/create 创建单个区域仓
func CreateWarehouse(appOrgCode string, storeID int64) (warehouseID int64, err error) {
storeDetail, err := dao.GetStoreDetail(dao.GetDB(), int(storeID), 0, "")
if err != nil {
return 0, fmt.Errorf("获取门店本地信息失败:%v", err)
}
resp, err := getAPI(appOrgCode, 0, "").CreateWarehouse(&warehouse_create_request.WarehouseCreateParam{
OutWarehouseId: utils.Int64ToStr(storeID), //本地storeID绑定
Name: "京西菜市_" + storeDetail.Name + "_" + utils.Int64ToStr(storeID) + "_区域仓",
Intro: "",
Warehouse: &warehouse_create_request.Warehouse{
WarehouseLocation: &warehouse_create_request.WarehouseLocation{
AddressId1: utils.Str2Int64(utils.Int2Str(storeDetail.ProvinceCode)[:2]),
AddressId2: int64(storeDetail.CityCode),
AddressId3: int64(storeDetail.DistrictCode),
AddressId4: 0,
},
AddressDetail: storeDetail.Address,
},
})
if err != nil {
return 0, fmt.Errorf("创建单个区域仓失败:%v", err)
}
return resp.WarehouseId, nil
}
// /warehouse/createBatch 批量创建区域仓 暂时不使用
func (P *PurchaseHandler) BatchCreateWarehouse(param warehouse_createBatch_request.WarehouseCreateBatchParam, appOrgCode string) error {
req := &warehouse_createBatch_request.WarehouseCreateBatchParam{
OutWarehouseList: []warehouse_createBatch_request.OutWarehouseListItem{
{
OutWarehouseId: param.OutWarehouseList[0].OutWarehouseId,
Name: param.OutWarehouseList[0].Name,
Intro: param.OutWarehouseList[0].Intro,
AddressDetail: param.OutWarehouseList[0].AddressDetail,
WarehouseLocation: param.OutWarehouseList[0].WarehouseLocation,
},
},
}
resp, err := getAPI(appOrgCode, 0, "").BatchCreateWarehouse(req)
if err != nil {
return err
}
if resp.Data["outWarehouseId"] == false {
return fmt.Errorf("outWarehouseId:%v 出错", resp.Data["outWarehouseId"])
}
return nil
}
// /warehouse/bindStore 仓库绑定门店
func BindStoreWarehouse(VendorOrgCode, outWarehouseID string, storeIDs int64) error {
if _, err := getAPI(VendorOrgCode, 0, "").StoreBindWarehouse(&warehouse_bindStore_request.WarehouseBindStoreParam{
StoreIds: []int64{storeIDs},
OutWarehouseId: outWarehouseID,
}); err != nil {
return err
}
return nil
}
// /warehouse/getWarehouseByStore 门店id获取绑定仓库详情包括电子围栏
func GetWarehouseByStore(appOrgCode string, storeID int64) (map[string][]*warehouse_getWarehouseByStore_response.WarehouseInfoMapItem, error) {
if resp, err := getAPI(appOrgCode, 0, "").GetWarehouseByStore(storeID); err != nil {
return nil, err
} else {
return resp.WarehouseInfoMap, nil
}
}
type LocalStore struct {
Lng int `json:"-"` // 乘了10的6次方
Lat int `json:"-"` // 乘了10的6次方
DeliveryRangeType int8 `json:"deliveryRangeType"` // 参见相关常量定义
DeliveryRange string `json:"deliveryRange"` // 如果DeliveryRangeType为DeliveryRangeTypePolygon则为逗号分隔坐标分号分隔的坐标点坐标与Lng和Lat一样都是整数比如 121361504,31189308;121420555,31150238。否则为半径单位为米
VendorStoreID string `json:"vendorStoreID"` // 平台上门店id
}
// /warehouse/createFence 以门店方式创建电子围栏
func CreateFenceByStore(appOrgCode string, storeID int64) (fenceID string, err error) {
var (
db *dao.DaoDB
localStore *LocalStore
vertex []warehouse_createFence_request.VerticesItem
param = &warehouse_createFence_request.WarehouseCreateFenceParam{}
sqlParam = []interface{}{}
)
sqlStr := `SELECT t.lng,t.lat,t.delivery_range_type,t.delivery_range FROM store t`
if storeID != 0 {
sqlStr += " WHERE t.id = ? "
sqlParam = append(sqlParam, storeID)
} else {
return "", fmt.Errorf("storeID必填")
}
if err = dao.GetRow(db, &localStore, sqlStr, sqlParam); err == nil {
if localStore.DeliveryRangeType == LocalShapeCircular {
param = &warehouse_createFence_request.WarehouseCreateFenceParam{
FenceInfo: &warehouse_createFence_request.FenceInfo{
OutFenceId: utils.Int64ToStr(storeID),
Shape: tiktok_api.ShapeCircular,
Circular: &warehouse_createFence_request.Circular{
Center: &warehouse_createFence_request.Center{
Longitude: float64(localStore.Lng) / float64(1000000),
Latitude: float64(localStore.Lat) / float64(1000000),
},
Radius: utils.Str2Float64(localStore.DeliveryRange),
},
},
}
} else if localStore.DeliveryRangeType == LocalShapePolygon {
tempStr := strings.Split(localStore.DeliveryRange, ";")
for v := len(tempStr) - 1; v > 0; v-- {
s2 := strings.Split(tempStr[v], ",")
tLng, _ := strconv.ParseFloat(s2[0], 64)
tLat, _ := strconv.ParseFloat(s2[1], 64)
vertices := warehouse_createFence_request.VerticesItem{
Longitude: tLng,
Latitude: tLat,
}
vertex = append(vertex, vertices)
}
param = &warehouse_createFence_request.WarehouseCreateFenceParam{
FenceInfo: &warehouse_createFence_request.FenceInfo{
OutFenceId: utils.Int64ToStr(storeID),
Shape: tiktok_api.ShapePolygon,
Polygon: &warehouse_createFence_request.Polygon{
Vertices: vertex,
},
},
}
globals.SugarLogger.Debug("多边形:vertex", param.FenceInfo.Polygon.Vertices)
}
resp, err := getAPI(appOrgCode, 0, "").CreateFence(param)
if err != nil {
return "", err
} else {
return resp.FenceId, err
}
} else {
return "", err
}
}
// 通过围栏id更新电子围栏
func UpdateFenceByStore(appOrgCode, outFenceID, storeID string) error {
var (
db *dao.DaoDB
localStore *LocalStore
vertex []warehouse_setFence_request.VerticesItem
param = &warehouse_setFence_request.WarehouseSetFenceParam{}
)
localID, err := dao.GetStoreDetail(db, utils.Str2Int(storeID), 0, "")
if err != nil {
return errors.New("获取门店id失败")
}
sqlParam := []interface{}{}
sqlStr := `SELECT t.lng,t.lat,t.delivery_range_type,t.delivery_range FROM store t`
if localID.Store.ID != 0 {
sqlStr += " WHERE t.id = ? "
sqlParam = append(sqlParam, localID.Store.ID)
} else {
return fmt.Errorf("storeID必填")
}
if err := dao.GetRow(db, &localStore, sqlStr, sqlParam); err == nil {
if localStore.DeliveryRangeType == LocalShapeCircular {
param = &warehouse_setFence_request.WarehouseSetFenceParam{
FenceInfo: &warehouse_setFence_request.FenceInfo{
OutFenceId: outFenceID,
Shape: tiktok_api.ShapeCircular,
Circular: &warehouse_setFence_request.Circular{
Center: &warehouse_setFence_request.Center{
Longitude: float64(localStore.Lng) / float64(1000000),
Latitude: float64(localStore.Lat) / float64(1000000),
},
Radius: utils.Str2Float64(localStore.DeliveryRange),
},
},
}
} else if localStore.DeliveryRangeType == LocalShapePolygon {
tempStr := strings.Split(localStore.DeliveryRange, ";")
for v := len(tempStr) - 1; v >= 0; v-- {
s2 := strings.Split(tempStr[v], ",")
vertices := warehouse_setFence_request.VerticesItem{
Longitude: utils.Str2Float64(s2[0]),
Latitude: utils.Str2Float64(s2[1]),
}
vertex = append(vertex, vertices)
}
param = &warehouse_setFence_request.WarehouseSetFenceParam{
FenceInfo: &warehouse_setFence_request.FenceInfo{
OutFenceId: outFenceID,
Shape: tiktok_api.ShapePolygon,
Polygon: &warehouse_setFence_request.Polygon{
Vertices: vertex,
},
},
}
}
if err := getAPI(appOrgCode, 0, "").SetFence(param); err != nil {
return err
}
} else {
return err
}
return nil
}
//门店直接绑定围栏
func BindFenceByStore(appOrgCode string, storeID int64, addOutFenceIDs []string) error {
if _, err := getAPI(appOrgCode, 0, "").BindFenceByStore(&warehouse_bindFencesByStore_request.WarehouseBindFencesByStoreParam{
StoreId: storeID,
AddOutFenceIds: addOutFenceIDs,
}); err != nil {
return err
}
return nil
}
//获取电子围栏信息
func GetFence(appOrgCode string, outFenceID []string) ([]warehouse_getFences_response.FencesItem, error) {
emptyResp := []warehouse_getFences_response.FencesItem{}
if resp, err := getAPI(appOrgCode, 0, "").GetFence(outFenceID); err != nil {
return emptyResp, err
} else {
return resp.Fences, nil
}
}
//特殊处理
func SpecialTreat(vendorOrgCode string, vendorStoreID, storeID, deliveryFeeDeductionFee, deliveryFeeDeductionSill, minPrice int64, autoCall string) error {
var (
errList = errlist.New()
FreightTemplate = &model.FreightTemplate{
VendorStoreID: utils.Int64ToStr(vendorStoreID),
StoreID: int(storeID),
}
)
//1.运费模板
bindFreightIDs, err := GetStoreFreight(vendorOrgCode, vendorStoreID)
if err != nil {
globals.SugarLogger.Debug("获取门店(%d) 绑定运费模板出错:", vendorStoreID, err)
//errList.AddErr(fmt.Errorf("获取门店(%d) 绑定运费模板出错:%v", vendorStoreID, err))
}
if bindFreightIDs == 0 { //1未查询到绑定信息不算错误
if freightTemplateID, err := CreateFreightTemplate(int(storeID), int(deliveryFeeDeductionSill)); err != nil || freightTemplateID == 0 {
errList.AddErr(fmt.Errorf("创建运费模板失败:%v", err))
} else { //绑定
if err = ShopBindStoreFreight(vendorOrgCode, vendorStoreID, freightTemplateID); err != nil {
errList.AddErr(fmt.Errorf("京西菜市门店:%d 平台门店:%d 绑定运费模板:%d 失败:%v", storeID, vendorStoreID, freightTemplateID, err))
} else {
FreightTemplate.TemplateID = freightTemplateID
}
}
} else {
if err := UpdateFreightTemplate(int(storeID)); err != nil {
globals.SugarLogger.Debug("更新运费模板失败:", err)
errList.AddErr(fmt.Errorf("更新运费模板失败:%v", err))
}
}
//2.设置门店打包费 默认为0
if err := SetStorePackageFee(vendorOrgCode, vendorStoreID, deliveryFeeDeductionFee); err != nil {
errList.AddErr(fmt.Errorf("设置门店打包费失败:%v", err))
}
//3.设置门店起送价 默认为0
if bindSaleLimitID, err := GetStoreSaleLimit(vendorOrgCode, vendorStoreID); err != nil {
globals.SugarLogger.Debugf("获取门店限售模板失败:%v", err)
} else {
if bindSaleLimitID == 0 || utils.IsNil(bindSaleLimitID) { //创建
if createSaleLimitID, err := CreateAndBindMinPriceTemplate(vendorOrgCode, vendorStoreID, minPrice); err != nil {
errList.AddErr(fmt.Errorf("设置门店起送价限售模板失败:%v", err))
} else {
FreightTemplate.TradeLimitID = createSaleLimitID
}
} else { //更新为起送价模板
if updateSaleLimitID, err := UpdateTradeLimitTemplate(vendorOrgCode, bindSaleLimitID, minPrice); err != nil {
errList.AddErr(fmt.Errorf("更新门店起送价限售模板失败:%v", err))
} else {
FreightTemplate.TradeLimitID = updateSaleLimitID
}
}
}
//4.设置自动运力
if autoCall == tiktok_api.AutoCallRiderOpen {
if err := SetStoreAutoCallRider(vendorOrgCode, tiktok_api.AutoCallRiderOpen, vendorStoreID); err != nil {
errList.AddErr(fmt.Errorf("开启门店自动运力失败:%v", err))
}
} else {
if err := SetStoreAutoCallRider(vendorOrgCode, tiktok_api.AutoCallRiderClose, vendorStoreID); err != nil {
errList.AddErr(fmt.Errorf("关闭门店自动运力失败:%v", err))
}
}
//多次同步数据库,兜底处理
if err := dao.ReplaceInsertFreight(FreightTemplate); err != nil {
if err1 := dao.InsertItemFreight(FreightTemplate); err1 != nil {
globals.SugarLogger.Debug("同步数据库错误信息:%v", err1)
}
}
//if err := dao.CreateEntity(db, FreightTemplate); dao.IsDuplicateError(err) || err != nil {
// _, err1 := dao.UpdateEntity(db, FreightTemplate, "TemplateID", "TradeLimitID")
// if err1 != nil {
// globals.SugarLogger.Debugf("更新起送价限售模板,更新进数据库错误信息:%v", err1)
// } else {
// globals.SugarLogger.Debugf("更新起送价限售模板,创建进数据库错误信息:%v", err)
// }
//}
endErr := errList.GetErrListAsOne()
return endErr
}
// /address/create 创建店铺地址库(新建即绑定)
func (P *PurchaseHandler) CreateAddress(appOrgCode string, addressInfo address_create_request.AddressCreateParam) (addressID int64, err error) {
if resp, err := getAPI(appOrgCode, 0, utils.Int64ToStr(addressInfo.StoreId)).AddressCreate(&address_create_request.AddressCreateParam{
Address: addressInfo.Address,
StoreId: addressInfo.StoreId,
}); err != nil {
return 0, err
} else {
return resp.AddressId, nil
}
}
// /address/list 获取售后地址列表接口
//分页获取商家地址列表
func (P *PurchaseHandler) GetAddressList(appOrgCode string, param *address_list_request.AddressListParam) (*address_list_response.AddressListData, error) {
//不传入ID则是获取所有门店售后地址列表
info := &address_list_request.AddressListParam{
PageSize: 10,
PageNo: 1,
OrderBy: param.OrderBy,
OrderField: param.OrderField,
}
if param.StoreId != 0 {
info.StoreId = param.StoreId
}
if listInfo, err := getAPI(appOrgCode, 0, utils.Int64ToStr(info.StoreId)).GetAddressList(info); err != nil {
return nil, err
} else {
return listInfo, nil
}
}