package com.upchina.group.service; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.hazelcast.map.IMap; import com.upchina.advisor.entity.AdvisorBasic; import com.upchina.advisor.service.AdvisorInfoService; import com.upchina.common.config.cache.CacheKey; import com.upchina.common.handler.BizException; import com.upchina.common.query.OnlyIdQuery; import com.upchina.common.result.AppPager; import com.upchina.common.result.Pager; import com.upchina.common.result.ResponseStatus; import com.upchina.common.service.AppUserService; import com.upchina.common.service.CacheService; import com.upchina.common.service.SensitiveWordService; import com.upchina.common.state.StateMachine; import com.upchina.common.vo.AuthResultVO; import com.upchina.common.vo.BackendUserVO; import com.upchina.common.vo.FrontUserVO; import com.upchina.common.vo.InsertIdVO; import com.upchina.course.service.PageService; import com.upchina.group.constant.GroupInfoStatus; import com.upchina.group.entity.GroupCollect; import com.upchina.group.entity.GroupInfo; import com.upchina.group.entity.GroupSortEntity; import com.upchina.group.mapper.GroupCollectMapper; import com.upchina.group.mapper.GroupInfoMapper; import com.upchina.group.query.*; import com.upchina.group.vo.GroupCollectVO; import com.upchina.group.vo.GroupVO; import com.upchina.rbac.entity.UserDept; import com.upchina.rbac.service.AuthService; import com.upchina.rbac.service.UserService; import com.upchina.video.constant.VideoUserType; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; @Service public class GroupInfoService { @Resource private GroupInfoMapper groupInfoMapper; @Resource private SensitiveWordService sensitiveWordService; @Resource private StateMachine groupSM; @Resource private AdvisorInfoService advisorInfoService; @Resource private UserService userService; @Resource private AuthService authService; @Resource private PageService pageService; @Resource private CacheService cacheService; @Resource private AppUserService appUserService; @Resource private IMap groupCache; @Resource private GroupCollectMapper groupCollectMapper; @Transactional(rollbackFor = Exception.class) public InsertIdVO save(SaveGroupQuery query, BackendUserVO backendUserVO) { sensitiveWordService.check(query.getName(), query.getRemark(), query.getDetail()); Integer advisorId = getAdvisorId(query.getAdvisorId(), backendUserVO); GroupInfo groupInfo = query.toPO(backendUserVO, advisorId); groupInfoMapper.insert(groupInfo); return new InsertIdVO(groupInfo.getId()); } @Transactional(rollbackFor = Exception.class) public void update(UpdateGroupQuery query, BackendUserVO backendUserVO) { sensitiveWordService.check(query.getName(), query.getRemark(), query.getDetail()); GroupInfo groupInfoInDB = groupInfoMapper.selectById(query.getId()); if (groupInfoInDB == null) { throw new BizException(ResponseStatus.ID_NOT_EXIST_ERROR); } // 状态机扭转,判断是否能够编辑 GroupInfoStatus dbStatus = GroupInfoStatus.fromValue(groupInfoInDB.getStatus()); groupSM.send(dbStatus, GroupInfoStatus.EVENT_UPDATE); GroupInfo groupInfo = query.toPO(backendUserVO, groupInfoInDB.getAdvisorId()); groupInfoMapper.updateById(groupInfo); clearCache(query.getId()); } @Transactional(rollbackFor = Exception.class) public void updateStatus(UpdateGroupStatusQuery query, BackendUserVO backendUserVO) { GroupInfo groupInfoInDB = groupInfoMapper.selectById(query.getId()); if (groupInfoInDB == null) { throw new BizException(ResponseStatus.ID_NOT_EXIST_ERROR); } // 状态机扭转 GroupInfoStatus dbStatus = GroupInfoStatus.fromValue(groupInfoInDB.getStatus()); GroupInfoStatus targetStatus = groupSM.send(dbStatus, GroupInfoStatus.fromValue(query.getEvent())); GroupInfo groupInfo = query.toPO(targetStatus, backendUserVO); groupInfoMapper.updateById(groupInfo); clearCache(query.getId()); } public Pager list(ListGroupQuery query, BackendUserVO backendUserVO) { String name = query.getName(); Integer status = query.getStatus(); Integer userType = query.getUserType(); Integer advisorId = query.getAdvisorId(); Integer isDisplay = query.getIsDisplay(); Set authSet = authService.getAuthByUserType(VideoUserType.format(userType), backendUserVO, true); if (authSet != null && authSet.isEmpty()) { return null; } LambdaQueryWrapper wrapper = Wrappers.lambdaQuery() .in(Objects.nonNull(authSet), GroupInfo::getAdvisorId, authSet) .eq(advisorId != null && advisorId != 0, GroupInfo::getAdvisorId, advisorId) .like(StrUtil.isNotEmpty(name), GroupInfo::getName, name) .eq(status != null && status != 0, GroupInfo::getStatus, status) .eq(isDisplay != null && isDisplay != 0, GroupInfo::getIsDisplay, isDisplay) .ne(!VideoUserType.MANAGER_USER.value.equals(userType), GroupInfo::getStatus, GroupInfoStatus.DELETED.value) .orderByDesc(GroupInfo::getId); Page page = groupInfoMapper.selectPage(query.toPage(), wrapper); Map advisorMap = advisorInfoService.getAdvisorMap(); Map userNameMap = userService.getUserMap().values().stream() .collect(Collectors.toMap(UserDept::getUserId, UserDept::getName)); List list = page.getRecords().stream().map(groupInfo -> new GroupVO( groupInfo, advisorMap.get(groupInfo.getAdvisorId()), userNameMap.get(groupInfo.getCreateUserId()), userNameMap.get(groupInfo.getAuditUserId()), pageService.getForApp(groupInfo.getPageId()) )).collect(Collectors.toList()); return new Pager<>(list, page.getTotal()); } public GroupVO get(OnlyIdQuery query, BackendUserVO backendUserVO) { Integer id = query.getId(); GroupInfo groupInfo = getEntity(id, backendUserVO); if (groupInfo == null) { return null; } Map advisorMap = advisorInfoService.getAdvisorMap(); Map userNameMap = userService.getUserMap().values().stream() .collect(Collectors.toMap(UserDept::getUserId, UserDept::getName)); return new GroupVO( groupInfo, advisorMap.get(groupInfo.getAdvisorId()), userNameMap.get(groupInfo.getCreateUserId()), userNameMap.get(groupInfo.getAuditUserId()), groupInfo.getPageId() == null ? null : pageService.get(new OnlyIdQuery(groupInfo.getPageId()), null) ); } public void setNotice(SetNoticeQuery query, BackendUserVO backendUserVO) { GroupInfo groupInDB = groupInfoMapper.selectById(query.getId()); if (groupInDB == null) { throw new BizException(ResponseStatus.ID_NOT_EXIST_ERROR); } GroupInfo groupInfo = query.toPO(); groupInfoMapper.updateById(groupInfo); clearCache(query.getId()); } /** * APP端查询交易圈详情 */ public GroupVO getForApp(OnlyIdQuery query, FrontUserVO frontUserVO) { GroupVO vo = cacheService.get(groupCache, CacheKey.GroupKey.GROUP_INFO + query.getId(), () -> get(query, null)); if (vo == null) { return null; } // 防止落地页修改后,未更新缓存 if (vo.getPage() != null) { vo.setPage(pageService.getForApp(vo.getPage().getId())); } if (frontUserVO != null) { AuthResultVO authResultVo = appUserService.checkAuth(vo.getAuthorityId(), frontUserVO); vo.setAuthResultVo(authResultVo); } return vo; } /** * APP端查询交易圈列表 */ public AppPager listForApp(ListGroupAppQuery query) { Integer id = query.getId(); Integer lastId = query.getLastId(); LocalDateTime lastPublishTime = query.getLastPublishTime(); Integer lastWeight = query.getLastWeight(); Integer size = query.getSize(); NavigableSet sortedSet = cacheService.get(groupCache, CacheKey.GroupKey.MAIN_GROUP_LIST + id, () -> { LambdaQueryWrapper wrapper = Wrappers.lambdaQuery() .eq(GroupInfo::getAdvisorId, id) .eq(GroupInfo::getStatus, GroupInfoStatus.AUDITED.value) // .eq(GroupInfo::getIsDisplay, IsDisplay.YES.value) .orderByDesc(GroupInfo::getIsRecommend, GroupInfo::getAuditTime); List list = groupInfoMapper.selectList(wrapper); NavigableSet set = new TreeSet<>(); list.stream().map(GroupSortEntity::new).forEach(set::add); return set; }); GroupSortEntity lastEntity = lastId == null || lastWeight == null || lastPublishTime == null ? null : new GroupSortEntity(lastId, lastWeight, lastPublishTime); if (lastEntity != null) { sortedSet = sortedSet.tailSet(lastEntity, false); } List voList = new ArrayList<>(size); Iterator iterator = sortedSet.iterator(); while (iterator.hasNext() && voList.size() < size) { GroupSortEntity entity = iterator.next(); GroupVO vo = getForApp(new OnlyIdQuery(entity.getId()), null); if (vo != null) { voList.add(vo); } } return new AppPager<>(voList, iterator.hasNext()); } private GroupInfo getEntity(Integer id, BackendUserVO backendUserVO) { GroupInfo groupInfo = groupInfoMapper.selectById(id); if (groupInfo == null) { return null; } checkAdvisorId(groupInfo.getAdvisorId(), backendUserVO); return groupInfo; } /** * 检查投顾ID * * @param advisorId 投顾ID * @param backendUserVO 后台用户 */ private void checkAdvisorId(Integer advisorId, BackendUserVO backendUserVO) { if (advisorId == null || backendUserVO == null) { return; } // 数据权限检查 if (backendUserVO.getAdvisorId() != null) { if (!backendUserVO.getAdvisorId().equals(advisorId)) { throw new BizException(ResponseStatus.DATA_PERMISSION_ERROR); } } else { Set authSet = authService.getAuthByUserType(VideoUserType.MANAGER_USER, backendUserVO, true); if (authSet != null && !authSet.contains(advisorId)) { throw new BizException(ResponseStatus.DATA_PERMISSION_ERROR); } } } /** * 获取投顾ID * * @param advisorId 投顾ID * @param backendUserVO 后台用户 * @return 投顾ID */ private Integer getAdvisorId(Integer advisorId, BackendUserVO backendUserVO) { if (backendUserVO.getAdvisorId() != null) { // 投顾老师只能用自己创建课程 advisorId = backendUserVO.getAdvisorId(); } else { // 其他角色必须指定投顾ID if (advisorId == null) { throw new BizException(ResponseStatus.PARM_ERROR, "投顾ID不能为空"); } // 其他角色指定的投顾ID必须符合数据权限 Set authSet = authService.getAuthByUserType(VideoUserType.MANAGER_USER, backendUserVO, true); if (authSet != null && !authSet.contains(advisorId)) { throw new BizException(ResponseStatus.DATA_PERMISSION_ERROR, "投顾不可选用"); } } return advisorId; } public List queryCollect(QueryGroupCollectQuery query, BackendUserVO backendUserVO) { Integer groupId = query.getGroupId(); LocalDate startDate = query.getStartDate(); LocalDate endDate = query.getEndDate(); LambdaQueryWrapper wrapper = Wrappers.lambdaQuery() .eq(groupId != null && groupId != 0, GroupCollect::getGroupId, groupId) .ge(startDate != null, GroupCollect::getDate, startDate) .le(endDate != null, GroupCollect::getDate, endDate); List list = groupCollectMapper.selectList(wrapper); return list.stream().map(GroupCollectVO::new).collect(Collectors.toList()); } public void clearCache(Integer id) { groupCache.delete(CacheKey.GroupKey.GROUP_INFO + id); } }