|
|
@@ -0,0 +1,307 @@
|
|
|
+package com.kym.service.admin.impl;
|
|
|
+
|
|
|
+import cn.dev33.satoken.stp.StpUtil;
|
|
|
+import com.baomidou.dynamic.datasource.annotation.DS;
|
|
|
+import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
|
|
|
+import com.github.pagehelper.PageHelper;
|
|
|
+import com.github.yulichang.base.MPJBaseServiceImpl;
|
|
|
+import com.kym.common.exception.BusinessException;
|
|
|
+import com.kym.common.utils.CommUtil;
|
|
|
+import com.kym.common.utils.IDGenerator;
|
|
|
+import com.kym.entity.admin.Station;
|
|
|
+import com.kym.entity.admin.StationWhitelist;
|
|
|
+import com.kym.entity.admin.StationWhitelistLog;
|
|
|
+import com.kym.entity.admin.dto.BatchAddWhitelistDto;
|
|
|
+import com.kym.entity.admin.queryParams.StationWhitelistQueryParam;
|
|
|
+import com.kym.entity.admin.vo.StationWhitelistVo;
|
|
|
+import com.kym.entity.common.PageBean;
|
|
|
+import com.kym.entity.common.RedisKeys;
|
|
|
+import com.kym.entity.miniapp.User;
|
|
|
+import com.kym.mapper.admin.StationWhitelistMapper;
|
|
|
+import com.kym.service.admin.StationService;
|
|
|
+import com.kym.service.admin.StationWhitelistLogService;
|
|
|
+import com.kym.service.admin.StationWhitelistService;
|
|
|
+import com.kym.service.miniapp.UserService;
|
|
|
+import jakarta.annotation.PostConstruct;
|
|
|
+import org.springframework.data.redis.core.StringRedisTemplate;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+
|
|
|
+import java.util.*;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+@Service
|
|
|
+@DS("db-admin")
|
|
|
+public class StationWhitelistServiceImpl extends MPJBaseServiceImpl<StationWhitelistMapper, StationWhitelist> implements StationWhitelistService {
|
|
|
+
|
|
|
+ private static final long CACHE_EXPIRE_HOURS = 24;
|
|
|
+ private final IDGenerator idGenerator = new IDGenerator();
|
|
|
+ private final StationWhitelistMapper stationWhitelistMapper;
|
|
|
+ private final StationService stationService;
|
|
|
+ private final UserService userService;
|
|
|
+ private final StationWhitelistLogService stationWhitelistLogService;
|
|
|
+ private final StringRedisTemplate redisTemplate;
|
|
|
+
|
|
|
+ public StationWhitelistServiceImpl(StationWhitelistMapper stationWhitelistMapper,
|
|
|
+ StationService stationService,
|
|
|
+ UserService userService,
|
|
|
+ StationWhitelistLogService stationWhitelistLogService,
|
|
|
+ StringRedisTemplate redisTemplate) {
|
|
|
+ this.stationWhitelistMapper = stationWhitelistMapper;
|
|
|
+ this.stationService = stationService;
|
|
|
+ this.userService = userService;
|
|
|
+ this.stationWhitelistLogService = stationWhitelistLogService;
|
|
|
+ this.redisTemplate = redisTemplate;
|
|
|
+ }
|
|
|
+
|
|
|
+ @PostConstruct
|
|
|
+ public void init() {
|
|
|
+ DynamicDataSourceContextHolder.push("db-admin");
|
|
|
+ refreshAllCache();
|
|
|
+ DynamicDataSourceContextHolder.poll();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public PageBean<StationWhitelistVo> listWhitelist(StationWhitelistQueryParam param) {
|
|
|
+ PageHelper.startPage(param.getPageNum(), param.getPageSize());
|
|
|
+ List<StationWhitelistVo> list = stationWhitelistMapper.selectJoinList(StationWhitelistVo.class,
|
|
|
+ new com.github.yulichang.wrapper.MPJLambdaWrapper<StationWhitelist>()
|
|
|
+ .selectAll(StationWhitelist.class)
|
|
|
+ .select(User::getMobilePhone, User::getNickname)
|
|
|
+ .leftJoin(User.class, User::getId, StationWhitelist::getUserId)
|
|
|
+ .eq(!CommUtil.isEmptyOrNull(param.getStationId()), StationWhitelist::getStationId, param.getStationId())
|
|
|
+ .like(!CommUtil.isEmptyOrNull(param.getUserPhone()), User::getMobilePhone, param.getUserPhone())
|
|
|
+ .like(!CommUtil.isEmptyOrNull(param.getUserNickname()), User::getNickname, param.getUserNickname())
|
|
|
+ .eq(!CommUtil.isEmptyOrNull(param.getStatus()), StationWhitelist::getStatus, param.getStatus())
|
|
|
+ .orderByDesc(StationWhitelist::getCreateTime)
|
|
|
+ );
|
|
|
+ return new PageBean<>(list);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void addWhitelist(StationWhitelist whitelist) {
|
|
|
+ CommUtil.assertsNonNull(whitelist.getStationId(), "站点ID不能为空");
|
|
|
+ CommUtil.asserts(whitelist.getUserId() != null && whitelist.getUserId() > 0, "用户ID不能为空");
|
|
|
+
|
|
|
+ Station station = stationService.lambdaQuery()
|
|
|
+ .eq(Station::getStationId, whitelist.getStationId())
|
|
|
+ .one();
|
|
|
+ CommUtil.assertsNonNull(station, "站点不存在");
|
|
|
+
|
|
|
+ User user = userService.getById(whitelist.getUserId());
|
|
|
+ CommUtil.assertsNonNull(user, "用户不存在");
|
|
|
+
|
|
|
+ StationWhitelist exists = lambdaQuery()
|
|
|
+ .eq(StationWhitelist::getStationId, whitelist.getStationId())
|
|
|
+ .eq(StationWhitelist::getUserId, whitelist.getUserId())
|
|
|
+ .one();
|
|
|
+ if (exists != null) {
|
|
|
+ throw new BusinessException("用户已在该站点白名单中");
|
|
|
+ }
|
|
|
+
|
|
|
+ whitelist.setId(idGenerator.nextId());
|
|
|
+ whitelist.setStationName(station.getStationName());
|
|
|
+ whitelist.setUserPhone(user.getMobilePhone());
|
|
|
+ whitelist.setUserNickname(user.getNickname());
|
|
|
+ whitelist.setStatus(StationWhitelist.STATUS_启用);
|
|
|
+ whitelist.setCreateBy(StpUtil.getLoginIdAsLong());
|
|
|
+
|
|
|
+ save(whitelist);
|
|
|
+
|
|
|
+ refreshCache(whitelist.getStationId());
|
|
|
+
|
|
|
+ stationWhitelistLogService.logAdd(whitelist.getStationId(), whitelist.getStationName(),
|
|
|
+ whitelist.getUserId(), whitelist.getUserPhone(),
|
|
|
+ StpUtil.getLoginIdAsLong(), StpUtil.getSession().getString("mobilePhone"));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void batchAddWhitelist(BatchAddWhitelistDto dto) {
|
|
|
+ CommUtil.assertsNonNull(dto.getStationId(), "站点ID不能为空");
|
|
|
+ CommUtil.asserts(dto.getUserIds() != null && !dto.getUserIds().isEmpty(), "用户ID列表不能为空");
|
|
|
+
|
|
|
+ Station station = stationService.lambdaQuery()
|
|
|
+ .eq(Station::getStationId, dto.getStationId())
|
|
|
+ .one();
|
|
|
+ CommUtil.assertsNonNull(station, "站点不存在");
|
|
|
+
|
|
|
+ List<StationWhitelist> existingList = lambdaQuery()
|
|
|
+ .eq(StationWhitelist::getStationId, dto.getStationId())
|
|
|
+ .in(StationWhitelist::getUserId, dto.getUserIds())
|
|
|
+ .list();
|
|
|
+ Set<Long> existingUserIds = existingList.stream()
|
|
|
+ .map(StationWhitelist::getUserId)
|
|
|
+ .collect(Collectors.toSet());
|
|
|
+
|
|
|
+ List<User> users = userService.listByIds(dto.getUserIds());
|
|
|
+ Map<Long, User> userMap = users.stream()
|
|
|
+ .collect(Collectors.toMap(User::getId, u -> u));
|
|
|
+
|
|
|
+ Long operatorId = StpUtil.getLoginIdAsLong();
|
|
|
+ String operatorName = StpUtil.getSession().getString("mobilePhone");
|
|
|
+
|
|
|
+ List<StationWhitelist> toSave = new ArrayList<>();
|
|
|
+ for (Long userId : dto.getUserIds()) {
|
|
|
+ if (existingUserIds.contains(userId)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ User user = userMap.get(userId);
|
|
|
+ if (user == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ StationWhitelist whitelist = new StationWhitelist();
|
|
|
+ whitelist.setId(idGenerator.nextId());
|
|
|
+ whitelist.setStationId(dto.getStationId());
|
|
|
+ whitelist.setStationName(station.getStationName());
|
|
|
+ whitelist.setUserId(userId);
|
|
|
+ whitelist.setUserPhone(user.getMobilePhone());
|
|
|
+ whitelist.setUserNickname(user.getNickname());
|
|
|
+ whitelist.setStatus(StationWhitelist.STATUS_启用);
|
|
|
+ whitelist.setRemark(dto.getRemark());
|
|
|
+ whitelist.setCreateBy(operatorId);
|
|
|
+ toSave.add(whitelist);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!toSave.isEmpty()) {
|
|
|
+ saveBatch(toSave);
|
|
|
+ refreshCache(dto.getStationId());
|
|
|
+ stationWhitelistLogService.logBatchAdd(dto.getStationId(), station.getStationName(),
|
|
|
+ toSave.size(), operatorId, operatorName);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void removeWhitelist(Long id) {
|
|
|
+ StationWhitelist whitelist = getById(id);
|
|
|
+ CommUtil.assertsNonNull(whitelist, "白名单记录不存在");
|
|
|
+
|
|
|
+ removeById(id);
|
|
|
+ refreshCache(whitelist.getStationId());
|
|
|
+
|
|
|
+ stationWhitelistLogService.logRemove(whitelist.getStationId(), whitelist.getStationName(),
|
|
|
+ whitelist.getUserId(), whitelist.getUserPhone(),
|
|
|
+ StpUtil.getLoginIdAsLong(), StpUtil.getSession().getString("mobilePhone"));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void batchRemoveWhitelist(List<Long> ids) {
|
|
|
+ if (ids == null || ids.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ List<StationWhitelist> list = listByIds(ids);
|
|
|
+ if (list.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ removeByIds(ids);
|
|
|
+
|
|
|
+ Map<String, List<StationWhitelist>> groupByStation = list.stream()
|
|
|
+ .collect(Collectors.groupingBy(StationWhitelist::getStationId));
|
|
|
+ for (String stationId : groupByStation.keySet()) {
|
|
|
+ refreshCache(stationId);
|
|
|
+ }
|
|
|
+
|
|
|
+ stationWhitelistLogService.logBatchRemove(list.get(0).getStationId(), list.get(0).getStationName(),
|
|
|
+ list.size(), StpUtil.getLoginIdAsLong(), StpUtil.getSession().getString("mobilePhone"));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void updateStatus(Long id, Integer status) {
|
|
|
+ StationWhitelist whitelist = getById(id);
|
|
|
+ CommUtil.assertsNonNull(whitelist, "白名单记录不存在");
|
|
|
+
|
|
|
+ lambdaUpdate()
|
|
|
+ .set(StationWhitelist::getStatus, status)
|
|
|
+ .eq(StationWhitelist::getId, id)
|
|
|
+ .update();
|
|
|
+
|
|
|
+ refreshCache(whitelist.getStationId());
|
|
|
+
|
|
|
+ stationWhitelistLogService.logStatusChange(whitelist.getStationId(), whitelist.getStationName(),
|
|
|
+ whitelist.getUserId(), whitelist.getUserPhone(), status,
|
|
|
+ StpUtil.getLoginIdAsLong(), StpUtil.getSession().getString("mobilePhone"));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean isInWhitelist(String stationId, Long userId) {
|
|
|
+ String key = RedisKeys.STATION_WHITELIST_USERS + stationId;
|
|
|
+ if (Boolean.TRUE.equals(redisTemplate.hasKey(key))) {
|
|
|
+ return Boolean.TRUE.equals(redisTemplate.opsForSet().isMember(key, String.valueOf(userId)));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 缓存不存在,重建缓存
|
|
|
+ refreshCache(stationId);
|
|
|
+
|
|
|
+ // 再次检查缓存
|
|
|
+ if (Boolean.TRUE.equals(redisTemplate.hasKey(key))) {
|
|
|
+ return Boolean.TRUE.equals(redisTemplate.opsForSet().isMember(key, String.valueOf(userId)));
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<Long> getWhitelistUserIds(String stationId) {
|
|
|
+ String key = RedisKeys.STATION_WHITELIST_USERS + stationId;
|
|
|
+ Set<String> members = redisTemplate.opsForSet().members(key);
|
|
|
+ if (members != null && !members.isEmpty()) {
|
|
|
+ return members.stream()
|
|
|
+ .map(Long::valueOf)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ }
|
|
|
+ List<StationWhitelist> list = lambdaQuery()
|
|
|
+ .eq(StationWhitelist::getStationId, stationId)
|
|
|
+ .eq(StationWhitelist::getStatus, StationWhitelist.STATUS_启用)
|
|
|
+ .list();
|
|
|
+ return list.stream()
|
|
|
+ .map(StationWhitelist::getUserId)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void refreshCache(String stationId) {
|
|
|
+ String key = RedisKeys.STATION_WHITELIST_USERS + stationId;
|
|
|
+ redisTemplate.delete(key);
|
|
|
+
|
|
|
+ List<StationWhitelist> list = lambdaQuery()
|
|
|
+ .eq(StationWhitelist::getStationId, stationId)
|
|
|
+ .eq(StationWhitelist::getStatus, StationWhitelist.STATUS_启用)
|
|
|
+ .list();
|
|
|
+
|
|
|
+ if (!list.isEmpty()) {
|
|
|
+ String[] userIds = list.stream()
|
|
|
+ .map(w -> String.valueOf(w.getUserId()))
|
|
|
+ .toArray(String[]::new);
|
|
|
+ redisTemplate.opsForSet().add(key, userIds);
|
|
|
+ redisTemplate.expire(key, CACHE_EXPIRE_HOURS, TimeUnit.HOURS);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void refreshAllCache() {
|
|
|
+ List<StationWhitelist> allList = lambdaQuery()
|
|
|
+ .eq(StationWhitelist::getStatus, StationWhitelist.STATUS_启用)
|
|
|
+ .list();
|
|
|
+
|
|
|
+ Map<String, List<StationWhitelist>> groupByStation = allList.stream()
|
|
|
+ .collect(Collectors.groupingBy(StationWhitelist::getStationId));
|
|
|
+
|
|
|
+ for (Map.Entry<String, List<StationWhitelist>> entry : groupByStation.entrySet()) {
|
|
|
+ String stationId = entry.getKey();
|
|
|
+ List<StationWhitelist> list = entry.getValue();
|
|
|
+ String key = RedisKeys.STATION_WHITELIST_USERS + stationId;
|
|
|
+ redisTemplate.delete(key);
|
|
|
+ String[] userIds = list.stream()
|
|
|
+ .map(w -> String.valueOf(w.getUserId()))
|
|
|
+ .toArray(String[]::new);
|
|
|
+ redisTemplate.opsForSet().add(key, userIds);
|
|
|
+ redisTemplate.expire(key, CACHE_EXPIRE_HOURS, TimeUnit.HOURS);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|