package tiktok_store import ( "fmt" 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 string, err error) { storeDetail, err := dao.GetStoreDetail(dao.GetDB(), int(storeID), 0, "") if err != nil { return "", fmt.Errorf("获取门店本地信息失败:%v", err) } param := &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, }, } resp, err := getAPI(appOrgCode, 0, "").CreateWarehouse(param) if err != nil { return "", fmt.Errorf("创建单个区域仓失败:%v", err) } return resp.WarehouseId, nil } // /warehouse/createBatch 批量创建区域仓 func (P *PurchaseHandler) BatchCreateWarehouse(param warehouse_createBatch_request.WarehouseCreateBatchParam, appOrgCode string) error { infos := []warehouse_createBatch_request.OutWarehouseListItem{} for _, v := range param.OutWarehouseList { info := warehouse_createBatch_request.OutWarehouseListItem{ OutWarehouseId: v.OutWarehouseId, Name: v.Name, Intro: v.Intro, AddressDetail: v.AddressDetail, WarehouseLocation: v.WarehouseLocation, } infos = append(infos, info) } req := &warehouse_createBatch_request.WarehouseCreateBatchParam{ OutWarehouseList: infos, } 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 { param := &warehouse_bindStore_request.WarehouseBindStoreParam{ StoreIds: []int64{storeIDs}, OutWarehouseId: outWarehouseID, } if _, err := getAPI(VendorOrgCode, 0, "").StoreBindWarehouse(param); err != nil { return err } return nil } // /warehouse/getWarehouseByStore 门店id获取绑定仓库详情包括电子围栏 func GetWarehouseByStore(appOrgCode string, storeID int64) (map[int64][]warehouse_getWarehouseByStore_response.WarehouseInfoMapItem, error) { info, err := getAPI(appOrgCode, 0, "").GetWarehouseByStore(storeID) if err != nil { return nil, err } return info, 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 CreateFenceDirectly(param warehouse_createFence_request.WarehouseCreateFenceParam) (fenceID string, err error) { info := &warehouse_createFence_request.WarehouseCreateFenceParam{ FenceInfo: param.FenceInfo, } resp, err := getAPI("", 0, "").CreateFence(info) if err != nil { return "", err } return resp.FenceId, err } // 通过门店更新电子围栏 func UpdateFenceByStore(appOrgCode, outFenceID string, storeID int) error { var ( db *dao.DaoDB localStore *LocalStore vertex []warehouse_setFence_request.VerticesItem ) sqlParam := []interface{}{ model.VendorIDDD, } 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 { param := &warehouse_setFence_request.WarehouseSetFenceParam{ FenceInfo: &warehouse_setFence_request.FenceInfo{ OutFenceId: outFenceID, Shape: int32(localStore.DeliveryRangeType), }, } if localStore.DeliveryRangeType == 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), } param.FenceInfo.Circular = circular } else if localStore.DeliveryRangeType == tiktok_api.ShapePolygon { 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.FenceInfo.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 { param := &warehouse_bindFencesByStore_request.WarehouseBindFencesByStoreParam{ StoreId: storeID, AddOutFenceIds: addOutFenceIDs, } if _, err := getAPI(appOrgCode, 0, "").BindFenceByStore(param); err != nil { return err } return nil } //获取电子围栏信息 func GetFence(appOrgCode, outFenceID string) (warehouse_getFences_response.FencesItem, error) { data := warehouse_getFences_response.FencesItem{} resp, err := getAPI(appOrgCode, 0, "").GetFence(outFenceID) if err != nil { return data, err } return resp.Fences[0], nil } //特殊处理 func SpecialTreat(vendorOrgCode string, vendorStoreID, storeID, deliveryFeeDeductionFee, minPrice int64) error { var ( errList = errlist.New() FreightTemplate = &model.FreightTemplate{} db *dao.DaoDB ) //首先获取绑定信息 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)) } } //设置门店打包费 默认为0 if err := SetStorePackageFee(vendorOrgCode, vendorStoreID, deliveryFeeDeductionFee); err != nil { errList.AddErr(fmt.Errorf("设置门店打包费失败:%v", err)) } //设置门店起送价 默认为0 bindSaleLimitID, err := GetStoreSaleLimit(vendorOrgCode, vendorStoreID) if 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 } } } err1 := dao.CreateEntity(db, FreightTemplate) if err1 != nil { _, err2 := dao.UpdateEntity(db, FreightTemplate, "TemplateID") if err2 != nil { errList.AddErr(fmt.Errorf("同步进数据库错误信息:%v", err1)) } } endErr := errList.GetErrListAsOne() globals.SugarLogger.Debugf("endErr===============%s", endErr) return endErr }