package cms import ( "errors" "strconv" "strings" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/business/model" "git.rosy.net.cn/jx-callback/business/model/dao" "git.rosy.net.cn/jx-callback/business/model/legacymodel" "git.rosy.net.cn/jx-callback/business/partner" "git.rosy.net.cn/jx-callback/globals" ) const ( GET_BAD_COMMENTS_TYPE = 0 //获取差评的标志 GET_ALL_COMMENTS_TYPE = 1 //获取所有评论的标志 ) type StoreExt struct { model.Store FloatLng float64 `json:"lng"` FloatLat float64 `json:"lat"` CityName string `json:"cityName"` DistrictName string `json:"districtName"` JdID string `orm:"column(jd_id)" json:"jdID"` ElmID string `orm:"column(elm_id)" json:"elmID"` EbaiID string `orm:"column(ebai_id)" json:"ebaiID"` } type StoresInfo struct { TotalCount int `json:"totalCount"` Stores []*StoreExt `json:"stores"` } var ( ErrMissingInput = errors.New("没有有效的输入参数") ErrCanNotFindVendor = errors.New("vendorID参数不合法") ) // todo 门店绑定信息可以考虑以数组形式返回,而不是现在这样 func GetStores(keyword string, params map[string]interface{}, offset, pageSize int) (retVal *StoresInfo, err error) { sqlFrom := ` FROM store t1 LEFT JOIN place city ON t1.city_code = city.code AND city.level = 2 LEFT JOIN place district ON t1.district_code = district.code AND district.level = 3 LEFT JOIN store_map jdm ON t1.id = jdm.store_id AND jdm.vendor_id = 0 AND jdm.deleted_at = '1970-01-01 00:00:00' LEFT JOIN store_map elmm ON t1.id = elmm.store_id AND elmm.vendor_id = 2 AND elmm.deleted_at = '1970-01-01 00:00:00' LEFT JOIN store_map ebaim ON t1.id = ebaim.store_id AND ebaim.vendor_id = 3 AND ebaim.deleted_at = '1970-01-01 00:00:00' ` sqlWhere := ` WHERE t1.deleted_at = '1970-01-01 00:00:00' ` sqlParams := make([]interface{}, 0) if keyword != "" { keywordLike := "%" + keyword + "%" sqlWhere += " AND (t1.name LIKE ? OR t1.address LIKE ? OR t1.tel1 LIKE ? OR t1.tel2 LIKE ? OR t1.last_operator LIKE ? OR city.name LIKE ?" sqlParams = append(sqlParams, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike) if keywordInt64, err2 := strconv.ParseInt(keyword, 10, 64); err2 == nil { sqlWhere += " OR t1.id = ? OR t1.city_code = ? OR t1.district_code = ? OR t1.lng = ? OR t1.lat = ?" sqlParams = append(sqlParams, keywordInt64, keywordInt64, keywordInt64, keywordInt64, keywordInt64) } sqlWhere += ")" } if params["storeID"] != nil { sqlWhere += " AND t1.id = ?" sqlParams = append(sqlParams, params["storeID"].(int)) } if params["name"] != nil { sqlWhere += " AND t1.name LIKE ?" sqlParams = append(sqlParams, "%"+params["name"].(string)+"%") } if params["placeID"] != nil { level := 2 if params["placeLevel"] != nil { level = params["placeLevel"].(int) } if level == 2 { sqlWhere += " AND t1.city_code = ?" } else { sqlWhere += " AND t1.district_code = ?" } sqlParams = append(sqlParams, params["placeID"].(int)) } if params["address"] != nil { sqlWhere += " AND t1.address LIKE ?" sqlParams = append(sqlParams, "%"+params["address"].(string)+"%") } if params["tel"] != nil { sqlWhere += " AND (t1.tel1 LIKE ? OR t1.tel2 LIKE ?)" sqlParams = append(sqlParams, "%"+params["tel"].(string)+"%") sqlParams = append(sqlParams, "%"+params["tel"].(string)+"%") } if params["fromStatus"] != nil { fromStatus := params["fromStatus"].(int) toStatus := fromStatus if params["toStatus"] != nil { toStatus = params["toStatus"].(int) } sqlWhere += " AND t1.status >= ? AND t1.status <= ?" sqlParams = append(sqlParams, fromStatus, toStatus) } if vendorStoreCond := strings.ToUpper(utils.Interface2String(params["vendorStoreCond"])); vendorStoreCond == "AND" || vendorStoreCond == "OR" { sqlVendorStoreCond := "" if vendorStoreCond == "AND" { sqlVendorStoreCond += " AND ( 1 = 1" } else { sqlVendorStoreCond += " AND ( 1 = 0" } condMap := map[string]int{ "jdm": utils.Interface2DirectIntWithDefault(params["jdCond"], 0), "elmm": utils.Interface2DirectIntWithDefault(params["elmCond"], 0), "ebaim": utils.Interface2DirectIntWithDefault(params["ebaiCond"], 0), } for tableName, cond := range condMap { if cond != 0 { sqlVendorStoreCond += " " + vendorStoreCond + " " + tableName } if cond == -1 { sqlVendorStoreCond += ".vendor_store_id IS NULL" } else if cond == 1 { sqlVendorStoreCond += ".vendor_store_id IS NOT NULL" } } if sqlVendorStoreCond != " AND ( 1 = 0" { sqlWhere += sqlVendorStoreCond + ")" } } sql := "SELECT SQL_CALC_FOUND_ROWS CAST(t1.lng AS DECIMAL(15,6))/1000000 float_lng,CAST(t1.lat AS DECIMAL(15,6))/1000000 float_lat, t1.*, city.name city_name, district.name district_name, jdm.vendor_store_id jd_id, elmm.vendor_store_id elm_id, ebaim.vendor_store_id ebai_id\n" + sqlFrom + sqlWhere + ` ORDER BY t1.id LIMIT ? OFFSET ?` pageSize = jxutils.FormalizePageSize(pageSize) if offset < 0 { offset = 0 } sqlParams = append(sqlParams, pageSize, offset) retVal = &StoresInfo{} db := dao.GetDB() dao.Begin(db) defer func() { if r := recover(); r != nil { dao.Rollback(db) panic(r) } }() if err = dao.GetRows(db, &retVal.Stores, sql, sqlParams...); err == nil { countInfo := &struct{ Ct int }{} if err = dao.GetRow(db, countInfo, "SELECT FOUND_ROWS() ct"); err == nil { retVal.TotalCount = countInfo.Ct } } dao.Commit(db) return retVal, err } func GetVendorStore(vendorStoreID string, vendorID int) (retVal *StoreExt, err error) { if handler := CurVendorSync.GetStoreHandler(vendorID); handler != nil { result, err2 := handler.ReadStore(vendorStoreID) if err = err2; err == nil { retVal = &StoreExt{ Store: *result, } db := dao.GetDB() if city, err2 := dao.GetPlaceByCode(db, result.CityCode); err2 == nil { retVal.CityName = city.Name } if district, err2 := dao.GetPlaceByCode(db, result.DistrictCode); err2 == nil { retVal.DistrictName = district.Name } return retVal, nil } return nil, err } return nil, ErrCanNotFindVendor } func UpdateStore(storeID int, payload map[string]interface{}, userName string) (num int64, err error) { store := &model.Store{} store.ID = storeID valid := dao.NormalMakeMapByStructObject(payload, store, userName) if payload["lng"] != nil { valid["lng"] = jxutils.StandardCoordinate2Int(utils.Interface2FloatWithDefault(payload["lng"], 0.0)) valid["lat"] = jxutils.StandardCoordinate2Int(utils.Interface2FloatWithDefault(payload["lat"], 0.0)) } if len(valid) > 0 { db := dao.GetDB() dao.Begin(db) defer func() { if r := recover(); r != nil { dao.Rollback(db) panic(r) } }() if num, err = dao.UpdateEntityLogically(db, store, valid, userName, nil); err == nil && num == 1 { dummy := &model.StoreMap{} _, err2 := dao.UpdateEntityLogicallyAndUpdateSyncStatus(db, dummy, nil, userName, map[string]interface{}{ model.FieldStoreID: store.ID, }, model.FieldSyncStatus) if err = err2; err == nil { dao.Commit(db) _, err = CurVendorSync.SyncStore(db, -1, store.ID, false, userName) } } if err != nil { dao.Rollback(db) } } return num, err } func CreateStore(store *model.Store, userName string) (id int, err error) { existingID := store.ID dao.WrapAddIDCULDEntity(store, userName) store.ID = existingID if err = dao.CreateEntity(nil, store); err == nil { return store.ID, err } return 0, err } func GetStoreVendorMaps(db *dao.DaoDB, storeID int, vendorID int) (storeMaps []*model.StoreMap, err error) { cond := map[string]interface{}{ model.FieldStoreID: storeID, } if vendorID != -1 { cond[model.FieldVendorID] = vendorID } return storeMaps, dao.GetEntitiesByKV(db, &storeMaps, cond, false) } func AddStoreVendorMap(db *dao.DaoDB, storeID, vendorID int, storeMap *model.StoreMap, userName string) (outStoreMap *model.StoreMap, err error) { if handler := CurVendorSync.GetMultiStoreHandler(vendorID); handler != nil { store, err2 := handler.ReadStore(storeMap.VendorStoreID) if err = err2; err == nil { dao.WrapAddIDCULDEntity(storeMap, userName) storeMap.StoreID = storeID storeMap.VendorID = vendorID storeMap.DeliveryType = store.DeliveryType storeMap.Status = store.Status storeMap.SyncStatus = model.SyncFlagModifiedMask // 新增绑定门店是修改的概念 if db == nil { db = dao.GetDB() } dao.Begin(db) defer func() { if r := recover(); r != nil { dao.Rollback(db) panic(r) } }() if err = dao.CreateEntity(db, storeMap); err == nil { dao.Commit(db) outStoreMap = storeMap _, err = CurVendorSync.SyncStore(db, storeMap.VendorID, storeID, false, userName) } if err != nil { dao.Rollback(db) } } } else { err = ErrCanNotFindVendor } return outStoreMap, err } func DeleteStoreVendorMap(db *dao.DaoDB, storeID, vendorID int, userName string) (num int64, err error) { if db == nil { db = dao.GetDB() } storeMap := &model.StoreMap{} if num, err = dao.DeleteEntityLogically(db, storeMap, map[string]interface{}{ model.FieldSyncStatus: model.SyncFlagDeletedMask, model.FieldStatus: model.StoreStatusDisabled, }, userName, map[string]interface{}{ model.FieldStoreID: storeID, model.FieldVendorID: vendorID, }); err == nil && num > 0 { _, err = CurVendorSync.SyncStore(db, vendorID, storeID, false, userName) } return num, err } func UpdateStoreVendorMap(db *dao.DaoDB, storeID, vendorID int, payload map[string]interface{}, userName string) (num int64, err error) { if db == nil { db = dao.GetDB() } if vendorStoreID := utils.Interface2String(payload["vendorStoreID"]); vendorStoreID != "" { if handler := CurVendorSync.GetMultiStoreHandler(vendorID); handler != nil { jdStore, err2 := handler.ReadStore(vendorStoreID) if err = err2; err == nil { payload["deliveryType"] = jdStore.DeliveryType } } else { err = ErrCanNotFindVendor } } if err == nil { dummyStoreMap := &model.StoreMap{} valid := dao.NormalMakeMapByStructObject(payload, dummyStoreMap, userName) if len(valid) > 0 { if valid["status"] != nil { // 对于store vendor map,只有Status改变才需要同步到厂商 num, err = dao.UpdateEntityLogicallyAndUpdateSyncStatus(db, dummyStoreMap, valid, userName, map[string]interface{}{ model.FieldStoreID: storeID, model.FieldVendorID: vendorID, }, model.FieldSyncStatus) } else { num, err = dao.UpdateEntityLogically(db, dummyStoreMap, valid, userName, map[string]interface{}{ model.FieldStoreID: storeID, model.FieldVendorID: vendorID, }) } if err == nil && num > 0 { if valid["status"] != nil { _, err = CurVendorSync.SyncStore(db, vendorID, storeID, false, userName) } } } } return num, err } func DeleteStore(db *dao.DaoDB, storeID int, userName string) (num int64, err error) { return 0, err } func TmpGetJxBadCommentsNo(storeID int) (count int, err error) { db := dao.GetDB() var ctInfo struct { Ct int } if err = dao.GetRow(db, &ctInfo, "SELECT COUNT(*) ct FROM jx_bad_comments WHERE status = 0 AND jxstoreid = ?", utils.Int2Str(storeID)); err == nil { count = ctInfo.Ct } return count, err } func TmpGetJxBadCommentsByStoreId(storeID, page, size, commentType int) (retVal map[string]interface{}, err error) { db := dao.GetDB() sql := ` SELECT SQL_CALC_FOUND_ROWS * FROM jx_bad_comments WHERE jxstoreid = ? ` if commentType == GET_BAD_COMMENTS_TYPE { sql += " AND status = 0" } sql += " ORDER BY createtime DESC LIMIT ? OFFSET ?" var commentList []*legacymodel.JxBadComments dao.Begin(db) defer func() { dao.Rollback(db) }() globals.SugarLogger.Debug(sql) if err = dao.GetRows(db, &commentList, sql, utils.Int2Str(storeID), size, (page-1)*size); err == nil { countInfo := &struct{ Ct int }{} if err = dao.GetRow(db, countInfo, "SELECT FOUND_ROWS() ct"); err == nil { dao.Commit(db) retVal = map[string]interface{}{ "total": countInfo.Ct, "list": commentList, } } } return retVal, err } func GetStoreCourierMaps(db *dao.DaoDB, storeID int, vendorID int) (storeCourierMaps []*model.StoreCourierMap, err error) { cond := map[string]interface{}{ model.FieldStoreID: storeID, } if vendorID != -1 { cond[model.FieldVendorID] = vendorID } return storeCourierMaps, dao.GetEntitiesByKV(db, &storeCourierMaps, cond, false) } func AddStoreCourierMap(db *dao.DaoDB, storeID, vendorID int, storeCourierMap *model.StoreCourierMap, userName string) (outStoreCourierMap *model.StoreCourierMap, err error) { if handler := partner.GetDeliveryPlatformFromVendorID(vendorID); handler != nil { dao.WrapAddIDCULDEntity(storeCourierMap, userName) storeCourierMap.StoreID = storeID storeCourierMap.VendorID = vendorID if db == nil { db = dao.GetDB() } dao.Begin(db) defer func() { if r := recover(); r != nil { dao.Rollback(db) panic(r) } }() if err = dao.CreateEntity(db, storeCourierMap); err == nil { dao.Commit(db) outStoreCourierMap = storeCourierMap _, err = CurVendorSync.SyncStore(db, storeCourierMap.VendorID, storeID, false, userName) } if err != nil { dao.Rollback(db) } } else { err = ErrCanNotFindVendor } return outStoreCourierMap, err } func DeleteStoreCourierMap(db *dao.DaoDB, storeID, vendorID int, userName string) (num int64, err error) { if db == nil { db = dao.GetDB() } storeCourierMap := &model.StoreCourierMap{} if num, err = dao.DeleteEntityLogically(db, storeCourierMap, map[string]interface{}{ model.FieldStatus: model.StoreStatusDisabled, }, userName, map[string]interface{}{ model.FieldStoreID: storeID, model.FieldVendorID: vendorID, }); err == nil && num > 0 { _, err = CurVendorSync.SyncStore(db, vendorID, storeID, false, userName) } return num, err } func UpdateStoreCourierMap(db *dao.DaoDB, storeID, vendorID int, payload map[string]interface{}, userName string) (num int64, err error) { if db == nil { db = dao.GetDB() } dummyStoreCourierMap := &model.StoreCourierMap{} valid := dao.NormalMakeMapByStructObject(payload, dummyStoreCourierMap, userName) if len(valid) > 0 { num, err = dao.UpdateEntityLogically(db, dummyStoreCourierMap, valid, userName, map[string]interface{}{ model.FieldStoreID: storeID, model.FieldVendorID: vendorID, }) } return num, err }