package com.sinata.appointment.service;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.sinata.appointment.constants.CacheNames;
|
import com.sinata.appointment.constants.BizErrorCode;
|
import com.sinata.appointment.dto.PassAreaCreateRequest;
|
import com.sinata.appointment.dto.PassAreaDetailVo;
|
import com.sinata.appointment.dto.PassAreaListVo;
|
import com.sinata.appointment.dto.PassAreaUpdateRequest;
|
import com.sinata.appointment.entity.MpPassAccessArea;
|
import com.sinata.appointment.exception.BizException;
|
import com.sinata.appointment.mapper.MpPassAccessAreaMapper;
|
import com.sinata.appointment.util.UuidAssert;
|
import java.util.Map;
|
import org.springframework.cache.Cache;
|
import org.springframework.cache.CacheManager;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.util.StringUtils;
|
|
@Service
|
public class PassAreaManageApplicationService {
|
|
private final MpPassAccessAreaMapper mpPassAccessAreaMapper;
|
private final CacheManager cacheManager;
|
|
public PassAreaManageApplicationService(
|
MpPassAccessAreaMapper mpPassAccessAreaMapper, CacheManager cacheManager) {
|
this.mpPassAccessAreaMapper = mpPassAccessAreaMapper;
|
this.cacheManager = cacheManager;
|
}
|
|
public IPage<PassAreaListVo> page(long page, long size, Long pid, String areaName) {
|
long p = pid == null ? 0L : pid;
|
LambdaQueryWrapper<MpPassAccessArea> q =
|
new LambdaQueryWrapper<MpPassAccessArea>()
|
.eq(MpPassAccessArea::getDelFlag, 0)
|
.eq(MpPassAccessArea::getPid, p)
|
.like(StringUtils.hasText(areaName), MpPassAccessArea::getAreaName, trim(areaName))
|
.orderByAsc(MpPassAccessArea::getAreaName)
|
.orderByAsc(MpPassAccessArea::getId);
|
Page<MpPassAccessArea> pg = mpPassAccessAreaMapper.selectPage(new Page<>(page, size), q);
|
return pg.convert(this::toListVo);
|
}
|
|
public PassAreaDetailVo detail(Long id, String uuid) {
|
MpPassAccessArea e = loadActive(id, uuid);
|
PassAreaDetailVo vo = new PassAreaDetailVo();
|
vo.setId(e.getId());
|
vo.setUuid(e.getUuid());
|
vo.setPid(e.getPid());
|
vo.setAreaName(e.getAreaName());
|
vo.setRemark(e.getRemark());
|
vo.setAreaDesc(e.getAreaDesc());
|
if (e.getPid() != null && e.getPid() > 0) {
|
MpPassAccessArea parent = mpPassAccessAreaMapper.selectById(e.getPid());
|
if (parent != null
|
&& (parent.getDelFlag() == null || parent.getDelFlag() == 0)
|
&& StringUtils.hasText(parent.getAreaName())) {
|
vo.setParentAreaName(parent.getAreaName());
|
}
|
}
|
return vo;
|
}
|
|
@Transactional(rollbackFor = Exception.class)
|
public Map<String, Object> create(PassAreaCreateRequest req) {
|
long pid = req.getPid() == null ? 0L : req.getPid();
|
validateParentPid(pid);
|
String name = req.getAreaName().trim();
|
assertNameUniqueUnderPid(pid, name, null);
|
MpPassAccessArea e = new MpPassAccessArea();
|
e.setPid(pid);
|
e.setAreaName(name);
|
e.setRemark(trimToEmpty(req.getRemark()));
|
e.setAreaDesc(trimToEmpty(req.getAreaDesc()));
|
mpPassAccessAreaMapper.insert(e);
|
MpPassAccessArea fresh = mpPassAccessAreaMapper.selectById(e.getId());
|
if (fresh == null || !StringUtils.hasText(fresh.getUuid())) {
|
throw new BizException(BizErrorCode.AUTH_FORBIDDEN, "创建后读取失败");
|
}
|
evictMiniPassAccessAreaTreeCache();
|
return Map.of("id", fresh.getId(), "uuid", fresh.getUuid());
|
}
|
|
@Transactional(rollbackFor = Exception.class)
|
public void update(Long id, PassAreaUpdateRequest req) {
|
MpPassAccessArea e = loadActive(id, req.getUuid());
|
String name = req.getAreaName().trim();
|
long targetPid;
|
if (e.getPid() == null || e.getPid() == 0) {
|
targetPid = 0L;
|
} else {
|
targetPid = req.getPid() != null ? req.getPid() : e.getPid();
|
validateParentPid(targetPid);
|
}
|
assertNameUniqueUnderPid(targetPid, name, id);
|
e.setPid(targetPid);
|
e.setAreaName(name);
|
if (req.getRemark() != null) {
|
e.setRemark(trimToEmpty(req.getRemark()));
|
}
|
e.setAreaDesc(trimToEmpty(req.getAreaDesc()));
|
mpPassAccessAreaMapper.updateById(e);
|
evictMiniPassAccessAreaTreeCache();
|
}
|
|
@Transactional(rollbackFor = Exception.class)
|
public void delete(Long id, String uuid) {
|
MpPassAccessArea e = loadActive(id, uuid);
|
long child =
|
mpPassAccessAreaMapper.selectCount(
|
new LambdaQueryWrapper<MpPassAccessArea>()
|
.eq(MpPassAccessArea::getDelFlag, 0)
|
.eq(MpPassAccessArea::getPid, e.getId()));
|
if (child > 0) {
|
throw new BizException(BizErrorCode.DEPT_HAS_CHILDREN, "请先删除子区域");
|
}
|
int affected = mpPassAccessAreaMapper.deleteById(e.getId());
|
if (affected <= 0) {
|
throw new BizException(BizErrorCode.RESOURCE_VERIFY_FAILED, "删除失败,请刷新后重试");
|
}
|
evictMiniPassAccessAreaTreeCache();
|
}
|
|
private void evictMiniPassAccessAreaTreeCache() {
|
Cache cache = cacheManager.getCache(CacheNames.MINI_LOOKUP);
|
if (cache != null) {
|
cache.evict(CacheNames.MINI_LOOKUP_PASS_ACCESS_AREA_TREE_KEY);
|
}
|
}
|
|
private void validateParentPid(long pid) {
|
if (pid == 0) {
|
return;
|
}
|
MpPassAccessArea parent = mpPassAccessAreaMapper.selectById(pid);
|
if (parent == null || (parent.getDelFlag() != null && parent.getDelFlag() == 1)) {
|
throw new BizException(BizErrorCode.RESOURCE_VERIFY_FAILED, "上级区域不存在");
|
}
|
if (parent.getPid() == null || parent.getPid() != 0) {
|
throw new BizException(BizErrorCode.AUTH_INVALID_CREDENTIALS, "仅允许两级:上级须为一级区域");
|
}
|
}
|
|
private void assertNameUniqueUnderPid(long pid, String name, Long excludeId) {
|
LambdaQueryWrapper<MpPassAccessArea> w =
|
new LambdaQueryWrapper<MpPassAccessArea>()
|
.eq(MpPassAccessArea::getDelFlag, 0)
|
.eq(MpPassAccessArea::getPid, pid)
|
.eq(MpPassAccessArea::getAreaName, name);
|
if (excludeId != null) {
|
w.ne(MpPassAccessArea::getId, excludeId);
|
}
|
if (mpPassAccessAreaMapper.selectCount(w) > 0) {
|
throw new BizException(BizErrorCode.AUTH_INVALID_CREDENTIALS, "同级下区域名称已存在");
|
}
|
}
|
|
private MpPassAccessArea loadActive(Long id, String uuid) {
|
MpPassAccessArea e = mpPassAccessAreaMapper.selectById(id);
|
if (e == null || (e.getDelFlag() != null && e.getDelFlag() == 1)) {
|
throw new BizException(BizErrorCode.RESOURCE_VERIFY_FAILED, "资源不存在或无权访问");
|
}
|
UuidAssert.match(e, uuid);
|
return e;
|
}
|
|
private PassAreaListVo toListVo(MpPassAccessArea e) {
|
PassAreaListVo vo = new PassAreaListVo();
|
vo.setId(e.getId());
|
vo.setUuid(e.getUuid());
|
vo.setPid(e.getPid());
|
vo.setAreaName(e.getAreaName());
|
vo.setAreaDesc(e.getAreaDesc());
|
vo.setCreateTime(e.getCreateTime());
|
return vo;
|
}
|
|
private static String trim(String s) {
|
return s == null ? null : s.trim();
|
}
|
|
private static String trimToNull(String s) {
|
if (!StringUtils.hasText(s)) {
|
return null;
|
}
|
String t = s.trim();
|
return t.isEmpty() ? null : t;
|
}
|
|
private static String trimToEmpty(String s) {
|
return s == null ? "" : s.trim();
|
}
|
}
|