package com.fdkankan.scene.service.impl; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.fdkankan.common.constant.CommonStatus; import com.fdkankan.common.constant.UploadFilePath; import com.fdkankan.redis.constant.RedisKey; import com.fdkankan.redis.util.RedisClient; import com.fdkankan.scene.bean.TagBean; import com.fdkankan.scene.entity.Scene; import com.fdkankan.scene.entity.SceneEditInfoExt; import com.fdkankan.scene.service.*; import com.fdkankan.scene.vo.BaseJsonArrayParamVO; import com.fdkankan.scene.vo.DeleteSidListParamVO; import com.google.common.collect.Lists; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.io.IOException; import java.util.*; import java.util.stream.Collectors; @Service public class SceneDrawServiceImpl implements ISceneDrawService { private final String SCENE_DRAW_JSON_NAME = "sceneDraw.json"; @Autowired private SceneService sceneService; @Autowired private RedisClient redisClient; @Autowired private SceneEditInfoExtService sceneEditInfoExtService; @Autowired private SceneEditInfoService sceneEditInfoService; @Resource private FYunFileService fYunFileService; @Autowired private SceneFileMappingService sceneFileMappingService; @Override public void saveSceneDraw(BaseJsonArrayParamVO param) throws Exception { Scene scenePlus = sceneService.getByNum(param.getNum(), param.getSubgroup()); this.addOrUpdate(param.getNum(), param.getSubgroup(), param.getData()); //保存数据库 SceneEditInfoExt sceneEditInfoExt = sceneEditInfoExtService.getByScenePlusId(scenePlus.getId()); this.updateDb(param.getNum(), param.getSubgroup(), scenePlus.getId()); sceneEditInfoService.upgradeVersionById(sceneEditInfoExt.getEditInfoId()); this.publicSceneDraw(param.getNum(), param.getSubgroup()); } private void updateDb(String num, Integer subgroup, Long scenePlusId){ //查询缓存是否包含热点数据 String key = String.format(RedisKey.SCENE_DRAW, RedisKey.getNumStr(num, subgroup)); Map map = redisClient.hmget(key); boolean hasSceneDraw= false; for (Map.Entry tagMap : map.entrySet()) { if(StrUtil.isEmpty(tagMap.getValue())){ continue; } hasSceneDraw = true; break; } //更改热点状态 sceneEditInfoExtService.update( new LambdaUpdateWrapper() .set(SceneEditInfoExt::getSceneDraw, hasSceneDraw ? CommonStatus.YES.code().intValue() : CommonStatus.NO.code().intValue()) .eq(SceneEditInfoExt::getScenePlusId,scenePlusId)); } private void addOrUpdate(String num, Integer subgroup, List data) throws Exception{ Map addOrUpdateMap = new HashMap<>(); int i = 0; for (JSONObject jsonObject : data) { jsonObject.put("createTime", Calendar.getInstance().getTimeInMillis() + i++); addOrUpdateMap.put(jsonObject.getString("sid"), JSON.toJSONString(jsonObject)); } // this.syncFileToRedis(num); //处理新增和修改数据 this.addOrUpdateHandler(num, subgroup, addOrUpdateMap); } private void addOrUpdateHandler(String num, Integer subgroup, Map addOrUpdateMap){ if(CollUtil.isEmpty(addOrUpdateMap)) return; //批量写入缓存 String key = String.format(RedisKey.SCENE_DRAW, RedisKey.getNumStr(num, subgroup)); redisClient.hmset(key, addOrUpdateMap); //写入本地文件,作为备份 // this.writeFile(num); } // private void writeFile(String num){ // String lockKey = String.format(RedisLockKey.LOCK_SCENE_DRAW, num); // String lockVal = cn.hutool.core.lang.UUID.randomUUID().toString(); // boolean lock = redisLockUtil.lock(lockKey, lockVal, RedisKey.EXPIRE_TIME_1_MINUTE); // if(!lock){ // return; // } // try{ // String dataKey = String.format(RedisKey.SCENE_DRAW, num); // String sceneDrawJsonPath = String.format(ConstantFilePath.SCENE_USER_PATH_V4, num) + SCENE_DRAW_JSON_NAME; // if(!redisUtil.hasKey(dataKey)){ // FileUtil.del(sceneDrawJsonPath); // return; // } // Map map = redisUtil.hmget(dataKey); // List list = map.entrySet().stream().map(entry->JSON.parseObject(entry.getValue())).collect(Collectors.toList()); // FileUtil.writeUtf8String(JSON.toJSONString(list), sceneDrawJsonPath); // }finally { // redisLockUtil.unlockLua(lockKey, lockVal); // } // } // private void syncFileToRedis(String num) throws Exception{ // // String key = String.format(RedisKey.SCENE_DRAW, num); // boolean exist = redisUtil.hasKey(key); // if(exist){ // return; // } // String lockKey = String.format(RedisLockKey.LOCK_SCENE_DRAW, num); // String lockVal = cn.hutool.core.lang.UUID.randomUUID().toString(); // boolean lock = redisLockUtil.lock(lockKey, lockVal, RedisKey.EXPIRE_TIME_1_MINUTE); // if(!lock){ // throw new BusinessException(ErrorCode.SYSTEM_BUSY); // } // try{ // exist = redisUtil.hasKey(key); // if(exist){ // return; // } // String sceneDrawFilePath = String.format(ConstantFilePath.SCENE_USER_PATH_V4, num) + SCENE_DRAW_JSON_NAME; // String sceneDrawData = FileUtils.readUtf8String(sceneDrawFilePath); // if(StrUtil.isEmpty(sceneDrawData)){ // return; // } // JSONArray tagsArr = JSON.parseArray(sceneDrawData); // if(CollUtil.isEmpty(tagsArr)){ // return; // } // Map map = new HashMap<>(); // for (Object o : tagsArr) { // JSONObject jo = (JSONObject)o; // map.put(jo.getString("sid"), jo.toJSONString()); // } // redisUtil.hmset(key, map); // }finally { // redisLockUtil.unlockLua(lockKey, lockVal); // } // } @Override public List listSceneDraw(String num, Integer subgroup) throws Exception { List tags = new ArrayList<>(); // this.syncFileToRedis(num); //获取裁剪模型数据 String key = String.format(RedisKey.SCENE_DRAW, RedisKey.getNumStr(num, subgroup)); List list = redisClient.hgetValues(key); if(CollUtil.isNotEmpty(list)){ List sortList = list.stream().map(str -> { JSONObject jsonObject = JSON.parseObject(str); TagBean tagBean = new TagBean(); tagBean.setCreateTime(jsonObject.getLong("createTime")); jsonObject.remove("createTime"); tagBean.setTag(jsonObject); return tagBean; }).collect(Collectors.toList()); sortList.sort(Comparator.comparingLong(TagBean::getCreateTime).reversed()); tags = sortList.stream().map(item -> item.getTag()).collect(Collectors.toList()); } return tags; } @Override public void deleteSceneDraw(DeleteSidListParamVO param) throws Exception { Scene scenePlus = sceneService.getByNum(param.getNum(), param.getSubgroup()); List deleteSidList = param.getSidList(); // this.syncFileToRedis(param.getNum()); //处理删除状态数据 this.deleteCache(param.getNum(), param.getSubgroup(), deleteSidList); //写入本地文件,作为备份 // this.writeFile(param.getNum()); //保存数据库 SceneEditInfoExt sceneEditInfoExt = sceneEditInfoExtService.getByScenePlusId(scenePlus.getId()); this.updateDb(param.getNum(), param.getSubgroup(), scenePlus.getId()); sceneEditInfoService.upgradeVersionById(sceneEditInfoExt.getEditInfoId()); this.publicSceneDraw(param.getNum(), param.getSubgroup()); } private List deleteCache(String num, Integer subgroup, List deleteSidList) { if(CollUtil.isEmpty(deleteSidList)){ return null; } //从redis中加载热点数据 String key = String.format(RedisKey.SCENE_DRAW, RedisKey.getNumStr(num, subgroup)); List deletDataList = redisClient.hMultiGet(key, deleteSidList); if(CollUtil.isNotEmpty(deletDataList)){ redisClient.hdel(key, deleteSidList); } return deletDataList; } @Override public void publicSceneDraw(String sceneNum, Integer subgroup) throws IOException { String Key = String.format(RedisKey.SCENE_DRAW, RedisKey.getNumStr(sceneNum, subgroup)); String userEditPath = String.format(UploadFilePath.USER_VIEW_PATH, sceneNum) + SCENE_DRAW_JSON_NAME; List list = redisClient.hgetValues(Key); if(CollUtil.isEmpty(list)){ fYunFileService.deleteFile(sceneNum, subgroup, userEditPath); return; } List collect = list.stream().map(str -> JSON.parseObject(str)).collect(Collectors.toList()); fYunFileService.uploadFile(sceneNum, subgroup, JSON.toJSONString(collect).getBytes(), userEditPath); } }