package com.xy.service;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xy.dto.SysSceneDto;
import com.xy.entity.SysScene;
import com.xy.mapper.SysSceneMapper;
import com.xy.utils.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static com.xy.utils.Beans.copy;
/**
*
* 场景服务实现类
*
*
* @author hechunping
* @since 2023/2/1
*/
@Slf4j
@Service
@Api(tags = "场景")
public class SysSceneServiceImpl extends ServiceImpl implements SysSceneService {
/**
* 每层code长度
*/
static final int CODE_LENGTH = 3;
/**
* code最大值
*/
static final int CODE_MAX = 999;
@ApiOperation("场景树")
@Override
public R>> tree(SysSceneDto.SceneListDto pater) {
Long parentId = Emptys.check(pater.getPaterId()) ? pater.getPaterId() : 0L;
List list = copy(SysSceneDto.Vo.class, list(null));
List> collect = list.stream()
.filter(item -> !item.getId().equals(item.getPaterId()))
.sorted(Comparator.comparingInt(SysSceneDto.Vo::getWeigh))
.map(item -> {
TreeNode treeNode = new TreeNode();
treeNode.setId(item.getId());
treeNode.setParentId(item.getPaterId());
treeNode.setName(item.getName());
treeNode.setWeight(item.getWeigh());
Map extra = new HashMap<>(1);
extra.put(LambdaUtils.getProperty(SysScene::getSceneCode), item.getSceneCode());
if (Emptys.check(pater.getAllColumn()) && pater.getAllColumn()) {
extra.put(LambdaUtils.getProperty(SysScene::getLevel), item.getLevel());
extra.put(LambdaUtils.getProperty(SysScene::getWeigh), item.getWeigh());
extra.put(LambdaUtils.getProperty(SysScene::getStatus), item.getStatus());
extra.put(LambdaUtils.getProperty(SysScene::getCreateTime), item.getCreateTime());
}
treeNode.setExtra(extra);
return treeNode;
})
.collect(Collectors.toList());
return R.ok(TreeUtil.build(collect, parentId));
}
@Override
@ApiOperation("查询下一级列表")
public R> nextList(@RequestBody @Validated SysSceneDto.SceneListDto pater) {
Long parentId = Emptys.check(pater.getPaterId()) ? pater.getPaterId() : 0L;
LambdaQueryWrapper lqw = new LambdaQueryWrapper<>();
lqw.eq(SysScene::getPaterId, parentId);
if (!Emptys.check(pater.getAllColumn()) || !pater.getAllColumn()) {
lqw.select(SysScene::getId, SysScene::getSceneCode, SysScene::getName);
}
return R.ok(copy(SysSceneDto.Vo.class, list(lqw)));
}
@ApiOperation(value = "删除", notes = "有子类不能删除")
@PostMapping("del")
public R deleteById(@RequestBody @Validated SysSceneDto.IdListDto idListDto) {
List idList = idListDto.getIdList();
//判断是否有子类
LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery().in(SysScene::getPaterId, idList).last("limit 1");
List list = list(lambdaQueryWrapper);
if (CollUtil.isNotEmpty(list)) {
return R.fail("有子类不能删除!");
}
return R.ok(removeBatchByIds(idList));
}
@ApiOperation("对象查询")
@Override
public R obj(SysSceneDto.Vo vo) {
LambdaQueryWrapper lambdaQueryWrapper = new MybatisPlusQuery().eqWrapper(vo, SysScene.class).build()
.last("limit 1");
SysScene sysScene = baseMapper.selectOne(lambdaQueryWrapper);
if (Emptys.check(sysScene)) {
return R.ok(copy(SysSceneDto.Vo.class, sysScene));
} else {
return R.ok();
}
}
@ApiOperation(value = "新增、更新场景", notes = "不传id为新增,传id为修改")
@PostMapping("saveOrUpdate")
public R saveOrUpdate(@Validated @RequestBody SysSceneDto.Save saveDto) {
Long id = saveDto.getId();
boolean isAdd = id == null || id == 0;
LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery();
lambdaQueryWrapper.eq(SysScene::getName, saveDto.getName()).last("limit 1").select(SysScene::getId);
SysScene existsSysScene = getOne(lambdaQueryWrapper);
if (existsSysScene != null) {
if (isAdd) {
return R.fail("场景已存在");
} else {
if (existsSysScene.getId().longValue() != saveDto.getId().longValue()) {
return R.fail("场景已存在");
}
}
}
SysScene paterSysScene = null;
if (saveDto.getPaterId() != null && saveDto.getPaterId() > 0) {
//查找父类
paterSysScene = baseMapper.selectById(saveDto.getPaterId());
if (paterSysScene == null) {
return R.fail("父节点错误");
}
} else {
saveDto.setPaterId(0L);
}
SysScene sysSceneSave = PlusBeans.copy(SysScene.class, saveDto);
if (isAdd) {
if (paterSysScene != null) {
sysSceneSave.setLevel(paterSysScene.getLevel() + 1);
} else {
sysSceneSave.setLevel(1);
}
sysSceneSave.setSceneCode(maxCode(paterSysScene));
sysSceneSave.createId().createUserTime(AuthorizeUtils.getLoginId(Long.class));
baseMapper.insert(sysSceneSave);
} else {
//查询一下自己
SysScene selfSysScene = getById(saveDto.getId());
//判断是否更改了父类
if (saveDto.getPaterId() != null && saveDto.getPaterId().longValue() != selfSysScene.getPaterId().longValue()) {
//更改了父类,重新生成code
sysSceneSave.setSceneCode(maxCode(paterSysScene));
}
sysSceneSave.updateUserTime(AuthorizeUtils.getLoginId(Long.class));
baseMapper.updateById(sysSceneSave);
}
return R.ok();
}
/**
* 生成级联CODE
*
* @param pater 父类实例
* @return
*/
private String maxCode(SysScene pater) {
int level = 1;
//父类目ID
Long parentId = 0L;
//父类目CODE,拼接用
String parentCode = "";
if (Emptys.check(pater)) {
level = pater.getLevel().intValue() + 1;
parentId = pater.getId();
parentCode = pater.getSceneCode();
}
//查询最大code
String maxCode = baseMapper.getMaxCode(parentId);
Integer subCode = level == 1 ? 101 : 001;
String code = level == 1 ? subCode.toString() : String.format("%0" + CODE_LENGTH + "d", subCode);
if (Emptys.check(maxCode)) {
subCode = Integer.parseInt(maxCode.substring(maxCode.length() - CODE_LENGTH)) + 1;
//超过最大数量会有异常,直接返回NULL
if (level > 1 && subCode > CODE_MAX) {
return null;
}
//补0
code = String.format("%0" + CODE_LENGTH + "d", subCode);
}
//拼接
code = parentCode + code;
return code;
}
}