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.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fdkankan.common.constant.CommonStatus;
import com.fdkankan.common.constant.ErrorCode;
import com.fdkankan.common.constant.UploadFilePath;
import com.fdkankan.common.exception.BusinessException;
import com.fdkankan.redis.constant.RedisKey;
import com.fdkankan.redis.util.RedisClient;
import com.fdkankan.scene.bean.ResultData;
import com.fdkankan.scene.bean.TagBean;
import com.fdkankan.scene.entity.Scene;
import com.fdkankan.scene.entity.SceneEditInfo;
import com.fdkankan.scene.entity.SceneEditInfoExt;
import com.fdkankan.scene.mapper.SceneEditInfoExtMapper;
import com.fdkankan.scene.service.FYunFileService;
import com.fdkankan.scene.service.SceneEditInfoExtService;
import com.fdkankan.scene.service.SceneEditInfoService;
import com.fdkankan.scene.service.SceneService;
import com.fdkankan.scene.vo.BaseJsonArrayParamVO;
import com.fdkankan.scene.vo.BaseSceneParamVO;
import com.fdkankan.scene.vo.DeleteSidListParamVO;
import com.fdkankan.scene.vo.DeleteStylesParamVO;
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.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
/**
*
* 服务实现类
*
*
* @author
* @since 2024-10-09
*/
@DS("vr")
@Service
public class SceneEditInfoExtServiceImpl extends ServiceImpl implements SceneEditInfoExtService {
@Autowired
private SceneService scenePlusService;
@Autowired
private SceneEditInfoService sceneEditInfoService;
@Resource
private RedisClient redisClient;
@Autowired
private FYunFileService fYunFileService;
@Override
public SceneEditInfoExt getByScenePlusId(long scenePlusId) {
return this.getOne(new LambdaQueryWrapper().eq(SceneEditInfoExt::getScenePlusId, scenePlusId));
}
@Override
public SceneEditInfoExt getByEditInfoId(long editInfoId) {
return this.getOne(new LambdaQueryWrapper().eq(SceneEditInfoExt::getEditInfoId, editInfoId));
}
@Override
public void updateToursByNum(String num, Integer subgroup, String upTime, Integer tours) {
Scene scenePlus = scenePlusService.getByNum(num, subgroup, upTime);
if(Objects.isNull(scenePlus)){
throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
}
SceneEditInfo sceneEditInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId());
sceneEditInfoService.upgradeVersionById(sceneEditInfo.getId());
SceneEditInfoExt sceneEditInfoExt = this.getByEditInfoId(sceneEditInfo.getId());
sceneEditInfoExt.setTours(tours);
this.updateById(sceneEditInfoExt);
}
@Override
public ResultData saveBillboards(BaseJsonArrayParamVO param) throws Exception {
Scene scenePlus = scenePlusService.getByNum(param.getNum(), param.getSubgroup(), param.getUpTimeKey());
this.addOrUpdateBillboards(param.getNum(), param.getSubgroup(), param.getUpTimeKey(), scenePlus.getCacheKeyHasTime(), param.getData());
this.addOrUpdateBillboardsStyles(param.getNum(), param.getSubgroup(), param.getUpTimeKey(), scenePlus.getCacheKeyHasTime(), param.getStyles());
//保存数据库
SceneEditInfoExt sceneEditInfoExt = this.getByScenePlusId(scenePlus.getId());
this.updateBillboards(param.getNum(), param.getSubgroup(), param.getUpTimeKey(), scenePlus.getCacheKeyHasTime(), sceneEditInfoExt);
this.publicBillboardData(param.getNum(), param.getSubgroup(), param.getUpTimeKey(), scenePlus.getCacheKeyHasTime());
sceneEditInfoService.upgradeVersionById(sceneEditInfoExt.getEditInfoId());
return ResultData.ok();
}
private void addOrUpdateBillboardsStyles(String num, Integer subgroup, String upTime, Integer cacheKeyHasTime, List styles) throws Exception{
if(CollUtil.isEmpty(styles)){
return;
}
long time = Calendar.getInstance().getTimeInMillis();
Map styleMap = new HashMap<>();
AtomicInteger index = new AtomicInteger();
styles.stream().forEach(style->{
String id = style.getString("sid");
style.put("createTime", time + index.getAndIncrement());
styleMap.put(id, style.toJSONString());
});
String key = String.format(RedisKey.SCENE_BILLBOARDS_STYLES, RedisKey.getNumStr(num, subgroup, upTime, cacheKeyHasTime));
redisClient.hmset(key, styleMap);
}
@Override
public ResultData deleteBillboards(DeleteSidListParamVO param) throws Exception {
Scene scenePlus = scenePlusService.getByNum(param.getNum(), param.getSubgroup(), param.getUpTimeKey());
List deleteSidList = param.getSidList();
//处理删除状态数据
this.deleteBillboardsHandler(param.getNum(), param.getSubgroup(), param.getUpTimeKey(), scenePlus.getCacheKeyHasTime(), deleteSidList);
this.publicBillboardData(param.getNum(), param.getSubgroup(), param.getUpTimeKey(), scenePlus.getCacheKeyHasTime());
//保存数据库
SceneEditInfoExt sceneEditInfoExt = this.getByScenePlusId(scenePlus.getId());
this.updateBillboards(param.getNum(), param.getSubgroup(), param.getUpTimeKey(), scenePlus.getCacheKeyHasTime(), sceneEditInfoExt);
sceneEditInfoService.upgradeVersionById(sceneEditInfoExt.getEditInfoId());
return ResultData.ok();
}
@Override
public JSONObject listBillboards(BaseSceneParamVO param) throws Exception {
JSONObject result = new JSONObject();
List tags = new ArrayList<>();
List styles = new ArrayList<>();
Scene scenePlus = scenePlusService.getByNum(param.getNum(), param.getSubgroup(), param.getUpTimeKey());
//获取指示牌数据
String key = String.format(RedisKey.SCENE_BILLBOARDS, RedisKey.getNumStr(param.getNum(), param.getSubgroup(), param.getUpTimeKey(), scenePlus.getCacheKeyHasTime()));
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());
}
result.put("tags", tags);
//获取图标数据
key = String.format(RedisKey.SCENE_BILLBOARDS_STYLES, RedisKey.getNumStr(param.getNum(), param.getSubgroup(), param.getUpTimeKey(), scenePlus.getCacheKeyHasTime()));
List sytlelist = redisClient.hgetValues(key);
if(CollUtil.isNotEmpty(sytlelist)){
List stileSortList = sytlelist.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());
stileSortList.sort(Comparator.comparingLong(TagBean::getCreateTime).reversed());
styles = stileSortList.stream().map(item -> item.getTag()).collect(Collectors.toList());
}
result.put("styles", styles);
return result;
}
private void deleteBillboardsHandler(String num, Integer subgroup, String upTime, Integer cacheKeyHasTime, List deleteSidList) throws Exception {
if(CollUtil.isEmpty(deleteSidList)){
return;
}
//从redis中加载热点数据
String key = String.format(RedisKey.SCENE_BILLBOARDS, RedisKey.getNumStr(num, subgroup, upTime, cacheKeyHasTime));
List deletDataList = redisClient.hMultiGet(key, deleteSidList);
if(CollUtil.isEmpty(deletDataList))
return;
//从redis中移除热点数据
redisClient.hdel(key, deleteSidList);
}
private void addOrUpdateBillboards(String num, Integer subgroup, String upTime, Integer cacheKeyHasTime, 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.addOrUpdateBillboardsHandler(num, subgroup, upTime, cacheKeyHasTime, addOrUpdateMap);
}
private void addOrUpdateBillboardsHandler(String num, Integer subgroup, String upTime, Integer cacheKeyHasTime, Map addOrUpdateMap){
if(CollUtil.isEmpty(addOrUpdateMap))
return;
//批量写入缓存
String key = String.format(RedisKey.SCENE_BILLBOARDS, RedisKey.getNumStr(num, subgroup, upTime, cacheKeyHasTime));
redisClient.hmset(key, addOrUpdateMap);
}
private void updateBillboards(String num, Integer subgroup, String upTime, Integer cacheKeyHasTime, SceneEditInfoExt sceneEditInfoExt){
//查询缓存是否包含热点数据
String key = String.format(RedisKey.SCENE_BILLBOARDS, RedisKey.getNumStr(num, subgroup, upTime, cacheKeyHasTime));
Map billboardsMap = redisClient.hmget(key);
boolean hashBillboards= false;
for (Map.Entry tagMap : billboardsMap.entrySet()) {
if(StrUtil.isEmpty(tagMap.getValue())){
continue;
}
hashBillboards = true;
break;
}
//更改热点状态
sceneEditInfoExt.setBillboards(hashBillboards ? CommonStatus.YES.code().intValue() : CommonStatus.NO.code().intValue());
this.updateById(sceneEditInfoExt);
}
private void publicBillboardData(String sceneNum, Integer subgroup, String upTime, Integer cacheKeyHasTime) throws IOException {
String Key = String.format(RedisKey.SCENE_BILLBOARDS, RedisKey.getNumStr(sceneNum, subgroup, upTime, cacheKeyHasTime));
String userEditPath = String.format(UploadFilePath.USER_VIEW_PATH, sceneNum) + "billboards.json";
List list = redisClient.hgetValues(Key);
if(CollUtil.isEmpty(list)){
fYunFileService.deleteFile(sceneNum, subgroup, upTime, userEditPath);
return;
}
List collect = list.stream().map(str -> JSON.parseObject(str)).collect(Collectors.toList());
fYunFileService.uploadFile(sceneNum, subgroup, upTime, JSON.toJSONString(collect).getBytes(), userEditPath);
}
@Override
public ResultData deleteBillboardsStyles(DeleteStylesParamVO param) throws Exception {
Scene scenePlus = scenePlusService.getByNum(param.getNum(), param.getSubgroup(), param.getUpTimeKey());
if (scenePlus == null)
throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
List sidList = param.getSidList();
String key = String.format(RedisKey.SCENE_BILLBOARDS_STYLES, RedisKey.getNumStr(param.getNum(), param.getSubgroup(), param.getUpTimeKey(), scenePlus.getCacheKeyHasTime()));
List deleteList = redisClient.hMultiGet(key, sidList);
redisClient.hdel(key, sidList);
//删除oss文件
List deleteFileList = deleteList.stream().map(str -> {
JSONObject parse = JSON.parseObject(str);
return parse.getString("url");
}).collect(Collectors.toList());
deleteFileList.stream().forEach(v->{
String fileKey = String.format(UploadFilePath.USER_VIEW_PATH, param.getNum()) + v;
fYunFileService.deleteFile(param.getNum(), param.getSubgroup(), param.getUpTimeKey(), fileKey);
});
return ResultData.ok();
}
}