358 lines
14 KiB
Go
358 lines
14 KiB
Go
package tiktok_store
|
||
|
||
import (
|
||
"fmt"
|
||
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"
|
||
"strconv"
|
||
"strings"
|
||
)
|
||
|
||
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
|
||
}
|
||
}
|
||
|
||
// 通过门店更新电子围栏
|
||
func UpdateFenceByStore(appOrgCode, outFenceID string, storeID int) error {
|
||
var (
|
||
db *dao.DaoDB
|
||
localStore *LocalStore
|
||
vertex []warehouse_setFence_request.VerticesItem
|
||
param = &warehouse_setFence_request.WarehouseSetFenceParam{}
|
||
)
|
||
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_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, minPrice int64, userName string) error {
|
||
var (
|
||
db *dao.DaoDB
|
||
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)); err != nil || freightTemplateID == 0 || utils.IsNil(freightTemplateID) {
|
||
globals.SugarLogger.Debug("创建运费模板失败:", err)
|
||
errList.AddErr(fmt.Errorf("创建运费模板失败:%v", err))
|
||
} else { //绑定
|
||
if err = ShopBindStoreFreight(vendorOrgCode, vendorStoreID, freightTemplateID); err != nil {
|
||
globals.SugarLogger.Debugf("京西菜市门店:%d 平台门店:%d 绑定运费模板:%d 失败:%v", storeID, vendorStoreID, freightTemplateID, err)
|
||
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 {
|
||
errList.AddErr(fmt.Errorf("获取门店限售模板失败:%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
|
||
}
|
||
}
|
||
}
|
||
//多次同步数据库,兜底处理
|
||
if err := dao.CreateEntity(db, FreightTemplate); err != nil {
|
||
_, err1 := dao.UpdateEntity(db, FreightTemplate, "TemplateID", "TradeLimitID")
|
||
if err1 != nil {
|
||
errList.AddErr(fmt.Errorf("同步进数据库错误信息:%v", err1))
|
||
} else {
|
||
errList.AddErr(fmt.Errorf("同步进数据库错误信息:%v", err))
|
||
}
|
||
} else {
|
||
dao.WrapAddIDCULDEntity(FreightTemplate, userName)
|
||
}
|
||
endErr := errList.GetErrListAsOne()
|
||
globals.SugarLogger.Debugf("SpecialTreat wrong information endErr: %s", endErr)
|
||
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
|
||
}
|
||
}
|