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 } }