package com.nb.im.controller; import cn.dev33.satoken.stp.StpLogic; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.mapper.Mapper; import java.util.*; import java.util.concurrent.atomic.AtomicLong; import com.nb.auth.utils.SecurityUtil; import com.nb.common.crud.BaseService; import com.nb.common.crud.controller.BaseSaveController; import com.nb.core.exception.CustomException; import com.nb.core.result.R; import com.nb.im.controller.vo.RemarkReadVo; import com.nb.im.controller.vo.UnreadVo; import com.nb.im.entity.ImMsgEntity; import com.nb.im.entity.ImRoomEntity; import com.nb.im.room.ImRoomOperator; import com.nb.im.room.ImRoomOperatorManager; import com.nb.im.service.LocalImMsgService; import com.nb.im.service.dto.ImRoomDetailDto; import com.nb.im.service.dto.ImRoomDto; import com.nb.im.enums.ImStatusEnum; import com.nb.im.enums.SponsorEnum; import com.nb.im.service.LocalImRoomService; import com.nb.im.service.dto.ImRoomQuery; import com.nb.im.service.dto.ImRoomResult; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.AllArgsConstructor; import org.springframework.context.annotation.Bean; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; /** * @author lifang * @version 1.0.0 * @ClassName ChatRoomController.java * @Description * @createTime 2022年08月16日 09:42:00 */ @RestController @AllArgsConstructor @RequestMapping("/im/room") @Api(tags = "聊天室") public class ImRoomController implements BaseSaveController { private final LocalImRoomService imRoomService; private final ImRoomOperatorManager roomOperatorManager; private final LocalImMsgService msgService; @Override public BaseService, ImRoomEntity, String> getService() { return imRoomService; } @ApiOperation(value = "查询并自动创建与病人看护人的聊天室",notes = "若存在,则返回聊天室信息,若不存在,则返回空") @PostMapping("/look") public R getChatRoom(@RequestBody@Validated ImRoomDto source){ if(Boolean.TRUE.equals(source.isAutoCreate())&&StrUtil.isEmpty(source.getDoctorNickname())){ throw new CustomException("医生昵称不可为空"); } ImRoomEntity chatRoom = imRoomService.getOne(new QueryWrapper() .lambda() .eq(ImRoomEntity::getAssistId, source.getAssistId()) .eq(ImRoomEntity::getDoctorId, source.getDoctorId()) .eq(ImRoomEntity::getPatientId, source.getPatientId()) .nested(i->i.eq(ImRoomEntity::getStatus, ImStatusEnum.WAITING) .or() .eq(ImRoomEntity::getStatus,ImStatusEnum.SUCCESS)) .last("limit 1")); if(chatRoom==null&&source.isAutoCreate()){ source.setTotalCount(0); source.setSponsorType(SponsorEnum.doctor); source.setStatus(ImStatusEnum.SUCCESS); imRoomService.createChatRoom(source); }else if(chatRoom!=null&&ImStatusEnum.WAITING.equals(chatRoom.getStatus())&&source.isAutoCreate()){ imRoomService.successChatRoom(chatRoom.getId(),source.getDoctorId()); } return R.success(chatRoom); } @PostMapping("/finished/{roomId}") @ApiOperation(value = "结束咨询") public R finished(@PathVariable String roomId){ return R.success(imRoomService.finished(roomId)); } @PostMapping("/no_page") @ApiOperation(value = "聊天室列表查询",notes = "走非条件查询,条件查询请于安卓端自行实现") public R> list(@RequestBody @Validated ImRoomQuery query){ List result= imRoomService.getBaseMapper().queryPageNoneMsgBlurry(query); String userId = String.valueOf(SecurityUtil.getId()); result.forEach(room-> room.setUnreadCount( roomOperatorManager.getRoomOperator(room.getId()) .unReadCount(userId)) ); return R.success(result); } @GetMapping("/view/{id}") @ApiOperation(value = "根据id查询聊天室") public R getById(@PathVariable("id") String id){ ImRoomDetailDto result= BeanUtil.toBean(imRoomService.getById(id),ImRoomDetailDto.class); if(result!=null){ result.setUnreadCount( roomOperatorManager.getRoomOperator(result.getId()) .unReadCount( String.valueOf(SecurityUtil.getId()))); } return R.success(result); } @PostMapping("/no_page/unread/{roomId}") @ApiOperation(value = "获取所有未读消息(需手动调用接口设置为已读)") public R> unReadMsg(@PathVariable("roomId") String roomId){ String userId = String.valueOf(SecurityUtil.getId()); ImRoomOperator roomOperator = roomOperatorManager.getRoomOperator(roomId); Set keySet = roomOperator.allUnreadMsgKey(userId); if(CollectionUtil.isEmpty(keySet)){ return R.success(new ArrayList<>()); } List result = msgService.list(new QueryWrapper() .lambda() .eq(ImMsgEntity::getRoomId,roomId) .in(ImMsgEntity::getKey,keySet)); return R.success(result); } @PostMapping("/read") @ApiOperation("标记信息为已读信息") public R readMsg(@RequestBody RemarkReadVo vo){ roomOperatorManager.getRoomOperator(vo.getRoomId()) .readUnreadMsg(vo.getUerId(),vo.getKey()); return R.success(true); } @PostMapping("/read/all") @ApiOperation("标记所有信息为已读信息") public R readAll(@RequestBody RemarkReadVo vo){ roomOperatorManager.getRoomOperator(vo.getRoomId()) .readUnreadMsgAll(vo.getUerId()); return R.success(true); } @PostMapping("/read/unread") @ApiOperation("获取未读消息总数量") public R unReadCount(@RequestBody UnreadVo vo){ if (StrUtil.isEmpty(vo.getAssistId()) && StrUtil.isEmpty(vo.getDoctorId())) { throw new CustomException("看护人id和医生id不能同时为空"); } String userId=StrUtil.isEmpty(vo.getAssistId())?vo.getDoctorId():vo.getAssistId(); AtomicLong result=new AtomicLong(0); List rooms = imRoomService.list(new QueryWrapper() .lambda() .select(ImRoomEntity::getId) .eq(StrUtil.isNotEmpty(vo.getAssistId()), ImRoomEntity::getAssistId, vo.getAssistId()) .eq(StrUtil.isNotEmpty(vo.getDoctorId()), ImRoomEntity::getDoctorId, vo.getDoctorId()) .eq(ImRoomEntity::getStatus,ImStatusEnum.SUCCESS) ); if(CollectionUtil.isNotEmpty(rooms)){ rooms.stream() .map(ImRoomEntity::getId).map(roomOperatorManager::getRoomOperator) .forEach(operator->{ result.addAndGet(operator.unReadCount(userId)); }); } return R.success(result.get()); } @Override public boolean isAuth() { return false; } @Override public String getPermissionPrefix() { return null; } @Override public StpLogic getStpLogin() { return SecurityUtil.getStpLogic(); } }