一、枚举
/**
* 地块获得方式
*/
@AllArgsConstructor
@Getter
public enum LandObtainWayEnum {
/** 系统赠送 **/
FREE,
/** 分享获取 **/
SHARE,
/** 购买获取 **/
BUY,
/** 替换获取 **/
REPLACE,
/** 好友赠送 **/
GIVE
}
二、事务 锁
@Transactional(rollbackFor = Exception.class)
@Override
public LandMinVo freeLand(String areaCode) {
Long curUserId = SecurityUtils.getUserId();
RLock lock = LockUtil.lock(String.valueOf(curUserId));
LandMinVo freeLand;
try {
TbUserExt userExt = userExtMapper.selectById(curUserId);
if (null == userExt) {
throw new ServiceException("用户不存在");
}
if (userExt.getFreeNum() < 1) {
throw new ServiceException("免费获取次数已用完");
}
CityInfo cityInfo = cityInfoService.getCityInfo(areaCode);
freeLand = randomLandV2(cityInfo.getCityCode(), curUserId);
TbLand land = new TbLand();
land.setAreaCode(freeLand.getAreaCode());
land.setLandNumber(freeLand.getLandCode());
land.setLandHash(freeLand.getLandHash());
land.setLandLat(freeLand.getLandLat());
land.setLandLng(freeLand.getLandLng());
land.setUserId(curUserId);
if (userExt.getFreeNum() - userExt.getShareNum() > 0) {
land.setObtainWay(LandObtainWayEnum.FREE.ordinal());
} else {
land.setObtainWay(LandObtainWayEnum.SHARE.ordinal());
}
baseMapper.insert(land);
//土地数增加
userExtMapper.incNum(curUserId, "land_num");
//免费数减少
userExtMapper.decNum(curUserId, "free_num");
//粉丝收到消息
msgService.sendGetLandMsg(curUserId, land.getId(), freeLand.getProvName() + freeLand.getCityName());
} finally {
if (lock.isLocked() && lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
return freeLand;
}
三、弃用的方法
/***
* 获取随机地块(根据城市中心点坐标)
* @param areaCode
* @param userId
* @return
*/
@Deprecated
private LandMinVo randomLand(String areaCode, Long userId) {
List<TbCityInfo> cityInfos = cityInfoService.list(new LambdaQueryWrapper<TbCityInfo>().ne(TbCityInfo::getAreaCode, areaCode).eq(TbCityInfo::getLevel, CityLevelEnum.CITY.ordinal()));
int index = RandomUtil.getRandom().nextInt(cityInfos.size());
TbCityInfo cityInfo = cityInfos.get(index);
TbCityInfo parentInfo = cityInfoService.getById(cityInfo.getParentCode());
Integer cityMax = Convert.toInt(configService.selectConfigByKey(CacheConstants.CITY_LAND_LIMIT), -1);
double lat;
double lng;
String geoHash;
do {
int[] geo = RandomUtil.getRandom().ints(0, 1000).limit(2).toArray();
String latPre = BigDecimal.valueOf(cityInfo.getCenterLat()).setScale(1, RoundingMode.DOWN).toPlainString();
String lngPre = BigDecimal.valueOf(cityInfo.getCenterLng()).setScale(1, RoundingMode.DOWN).toPlainString();
lat = Double.valueOf(latPre + (10 > geo[0] ? "00" + geo[0] : 100 > geo[0] ? "0" + geo[0] : geo[0]));
lng = Double.valueOf(lngPre + (10 > geo[1] ? "00" + geo[1] : 100 > geo[1] ? "0" + geo[1] : geo[1]));
geoHash = GeoHashUtils.encode(lat, lng);
} while (0 < baseMapper.selectCount(new LambdaQueryWrapper<TbLand>().eq(TbLand::getLandNumber, geoHash))
|| (-1 < cityMax && cityMax <= baseMapper.selectCount(new LambdaQueryWrapper<TbLand>().eq(TbLand::getUserId, userId).eq(TbLand::getAreaCode, areaCode))));
LandMinVo minVo = new LandMinVo();
minVo.setLandCode(geoHash);
minVo.setLandLat(lat);
minVo.setLandLng(lng);
minVo.setAreaCode(cityInfo.getAreaCode());
minVo.setCityName(cityInfo.getAreaName());
minVo.setProvName(parentInfo.getAreaName());
return minVo;
}