package cn.stylefeng.rest.modular.im.controller; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; import cn.stylefeng.guns.modular.business.dto.CustomerImInfoDTO; import cn.stylefeng.guns.modular.business.dto.ImEffectiveInfoDTO; import cn.stylefeng.guns.modular.business.dto.ImGroupUserDto; import cn.stylefeng.guns.modular.business.dto.ImPushDataDTO; import cn.stylefeng.guns.modular.business.dto.request.ImGroupUpdateRequest; import cn.stylefeng.guns.modular.business.dto.request.ImTestMessageSendRequest; import cn.stylefeng.guns.modular.business.entity.*; import cn.stylefeng.guns.modular.business.service.*; import cn.stylefeng.guns.modular.business.service.impl.ImBizService; import cn.stylefeng.roses.kernel.auth.api.context.LoginContext; import cn.stylefeng.roses.kernel.auth.api.pojo.login.LoginUser; import cn.stylefeng.roses.kernel.customer.api.pojo.CustomerInfo; import cn.stylefeng.roses.kernel.customer.modular.entity.Customer; import cn.stylefeng.roses.kernel.customer.modular.service.CustomerService; import cn.stylefeng.roses.kernel.im.api.ImServerApi; import cn.stylefeng.roses.kernel.rule.enums.CustomerWorkStatusEnum; import cn.stylefeng.roses.kernel.rule.enums.ImPushTypeEnum; import cn.stylefeng.roses.kernel.rule.enums.ImUserTypeEnum; import cn.stylefeng.roses.kernel.rule.enums.PostIdEnum; import cn.stylefeng.roses.kernel.rule.pojo.response.ErrorResponseData; import cn.stylefeng.roses.kernel.rule.pojo.response.ResponseData; import cn.stylefeng.roses.kernel.rule.pojo.response.SuccessResponseData; import cn.stylefeng.roses.kernel.scanner.api.annotation.ApiResource; import cn.stylefeng.roses.kernel.scanner.api.annotation.GetResource; import cn.stylefeng.roses.kernel.scanner.api.annotation.PostResource; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.Assert; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import io.rong.messages.TxtMessage; import io.rong.models.Result; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.util.Date; import java.util.List; import java.util.stream.Collectors; @Slf4j @Api(tags = "IM接口") @RestController @ApiResource(name = "IM接口") @RequestMapping("/im") public class ImController { @Resource ImBizService imBizService; @Resource ImServerApi imServerApi; @Resource CustomerService customerService; @Resource IImGroupService imGroupService; @Resource IImNoticeService imNoticeService; @Resource private ICourseOrderService courseOrderService; @Resource private ICounsellingUserService counsellingUserService; @Resource private IImGroupUserService imGroupUserService; @ApiOperation(value = "测试发送IM消息") @PostResource(name = "测试发送IM消息", path = "/testMessageSend") public ResponseData testMessageSend(@RequestBody ImTestMessageSendRequest req) { // IM推送数据json ImPushDataDTO pushData = req.getPushData(); Result messageSendResult; if (req.getSendTpe() == null || req.getSendTpe() == 0) { messageSendResult = imBizService.messageSendSystem( req.getFromUserId(), new String[]{req.getToId()}, pushData, ImUserTypeEnum.USER, null, false ); } else if (req.getSendTpe() == 1) { messageSendResult = imServerApi.messageSendPrivate(req.getFromUserId(), new String[]{req.getToId()}, new TxtMessage(JSONUtil.toJsonStr(pushData), pushData.getExtra())); } else { messageSendResult = imBizService.messageSendGroup(req.getFromUserId(), new String[]{req.getToId()}, pushData); } log.error("发送消息结果:{}", messageSendResult); return new SuccessResponseData(messageSendResult); } @ApiOperation(value = "即时咨询销售顾问", notes = "即时咨询,获取用户销售顾问,没有绑定随机分配一位当前在上班的咨询顾问") @GetResource(name = "即时咨询销售顾问", path = "/realTimeConsult") public ResponseData realTimeConsult() { // 获取当前登录用户信息 LoginUser loginUser = LoginContext.me().getLoginUser(); Long userId = loginUser.getUserId(); // 获取C端用户的详细信息 CustomerInfo customerInfo = customerService.getCustomerInfoById(userId); Assert.notNull(customerInfo, "获取用户信息失败!"); Long consultWorkerId = customerInfo.getConsultWorkerId(); if (consultWorkerId == null) { // 获取销售顾问 consultWorkerId = customerService.randomWorkerIdByLineStatusAndPost(null, null, PostIdEnum.PO_21.getCode(), CustomerWorkStatusEnum.ON_WORK.getCode()); if (consultWorkerId != null) { // 设置用户信息销售顾问 Customer customer = new Customer(); customer.setCustomerId(userId); customer.setConsultWorkerId(consultWorkerId); customerService.updateCustomerRemoveCache(customer); } } if (consultWorkerId != null) { return new SuccessResponseData(consultWorkerId); } else { return new ErrorResponseData("获取销售顾问失败!"); } } @ApiOperation(value = "即时课程销售顾问", notes = "即时咨询,获取用户销售顾问,没有绑定随机分配一位当前在上班的咨询顾问") @GetResource(name = "即时课程销售顾问", path = "/realTimeClass") public ResponseData realTimeClass() { // 获取当前登录用户信息 LoginUser loginUser = LoginContext.me().getLoginUser(); Long userId = loginUser.getUserId(); // 获取C端用户的详细信息 CustomerInfo customerInfo = customerService.getCustomerInfoById(userId); Assert.notNull(customerInfo, "获取用户信息失败!"); Long classWorkerId = customerInfo.getClassWorkerId(); if (classWorkerId == null) { // 获取销售顾问 classWorkerId = customerService.randomWorkerIdByLineStatusAndPost(null, null, PostIdEnum.PO_11.getCode(), CustomerWorkStatusEnum.ON_WORK.getCode()); if (classWorkerId != null) { // 设置用户信息销售顾问 Customer customer = new Customer(); customer.setCustomerId(userId); customer.setClassWorkerId(classWorkerId); customerService.updateCustomerRemoveCache(customer); } } if (classWorkerId != null) { return new SuccessResponseData(classWorkerId); } else { return new ErrorResponseData("获取销售顾问失败!"); } } @ApiOperation(value = "获取IM通讯token", notes = "获取指定用户IM通讯token,没有则注册IM") @GetResource(name = "获取IM通讯token", path = "/getImToken") public ResponseData getImToken(Long userId) { Assert.notNull(userId, "用户ID不能为空!"); // 获取用户IM通讯token return new SuccessResponseData(imBizService.getImToken(userId)); } @ApiOperation(value = "获取用户IM信息") @GetResource(name = "获取用户IM信息", path = "/userListByIds") @ApiImplicitParams({ @ApiImplicitParam(name = "ids", value = "用户ID串,逗号拼接") }) public ResponseData> userListByIds(String ids) { List list = customerService.list( Wrappers.lambdaQuery() .select( Customer::getCustomerId, Customer::getNickName, Customer::getRealName, Customer::getAvatar, Customer::getImToken, Customer::getPostIds ) .in(Customer::getCustomerId, ids.split(",")) ).stream().map(o -> BeanUtil.toBean(o, CustomerImInfoDTO.class)).collect(Collectors.toList()); return new SuccessResponseData(list); } @ApiOperation(value = "我的群聊") @GetResource(name = "我的群聊", path = "/myGroup") @ApiImplicitParams({ @ApiImplicitParam(name = "userId", value = "用户ID", dataTypeClass = Long.class), @ApiImplicitParam(name = "groupName", value = "群名", dataTypeClass = String.class), @ApiImplicitParam(name = "statusFlag", value = "状态:1正常,2冻结(解散)", dataTypeClass = Integer.class), @ApiImplicitParam(name = "nickName", value = "用户姓名", dataTypeClass = String.class), @ApiImplicitParam(name = "groupType", value = "群类型:1课程,2咨询", dataTypeClass = Integer.class), @ApiImplicitParam(name = "orderId", value = "订单ID", dataTypeClass = Long.class), }) public ResponseData> myGroup(Long userId, String groupName, Integer statusFlag, String nickName, Integer groupType, String orderId) { userId = userId == null ? LoginContext.me().getLoginUser().getUserId() : userId; return new SuccessResponseData(imGroupService.getMyGroup(userId, groupName, statusFlag, nickName, groupType, orderId)); } @ApiOperation(value = "群聊详情") @GetResource(name = "群聊详情", path = "/groupDetail") public ResponseData groupDetail(Long groupId) { // 获取用户IM通讯token return new SuccessResponseData(imGroupService.getById(groupId)); } @ApiOperation(value = "编辑群聊信息") @PostResource(name = "编辑群聊信息", path = "/updateGroup") public ResponseData updateGroup(@RequestBody ImGroupUpdateRequest req) { ImGroup group = BeanUtil.toBean(req, ImGroup.class); // 编辑群聊信息 boolean update = imGroupService.updateById(group); if (update && StrUtil.isNotBlank(group.getName())) { imServerApi.groupUpdate(group.getId().toString(), group.getName(), new String[]{}); } return new SuccessResponseData(update); } @ApiOperation(value = "群聊用户列表") @GetResource(name = "群聊用户列表", path = "/groupUser") public ResponseData> groupUser(Long groupId) { // 获取用户IM通讯token return new SuccessResponseData(imGroupService.groupUser(groupId)); } @ApiOperation(value = "通知列表") @GetResource(name = "通知列表", path = "/imNotice") @ApiImplicitParams({ @ApiImplicitParam(name = "userId", value = "用户ID", dataTypeClass = Long.class), @ApiImplicitParam(name = "postId", value = "岗位ID", dataTypeClass = Integer.class), }) public ResponseData> imNotice(Long userId, Integer postId) { List list = imNoticeService.list( Wrappers.lambdaQuery() .eq(userId != null, ImNotice::getUserId, userId) .eq(postId != null, ImNotice::getPostId, postId) .orderByDesc(ImNotice::getCreateTime) ); return new SuccessResponseData(list); } @ApiOperation(value = "已读通知") @GetResource(name = "已读通知", path = "/readNotice") public ResponseData> readNotice(Long id) { boolean update = imNoticeService.update( Wrappers.lambdaUpdate() .set(ImNotice::getReadFlag, 1) .eq(ImNotice::getId, id) ); return new SuccessResponseData(update); } @ApiOperation(value = "全部已读通知") @GetResource(name = "全部已读通知", path = "/allReadNotice") public ResponseData> allReadNotice(Long userId) { boolean update = imNoticeService.update( Wrappers.lambdaUpdate() .set(ImNotice::getReadFlag, 1) .eq(ImNotice::getUserId, userId) ); return new SuccessResponseData(update); } @ApiOperation(value = "群聊禁用和启用") @ApiImplicitParams({ @ApiImplicitParam(name = "groupId", value = "群聊id", dataTypeClass = Long.class), @ApiImplicitParam(name = "statusFlag", value = "状态:1正常,2冻结", dataTypeClass = Long.class), }) @PostResource(name = "群聊禁用和启用", path = "/updateImGroupState") public ResponseData updateImGroupState(Long groupId,Integer statusFlag) { LambdaUpdateWrapper imGroupLambdaUpdateWrapper = Wrappers.lambdaUpdate() .set(ImGroup::getStatusFlag, statusFlag) .eq(ImGroup::getId, groupId); if (statusFlag.intValue() == 2 ){ imGroupLambdaUpdateWrapper.set(ImGroup::getDisbandDate,new Date()); } ImGroup imGroup = this.imGroupService.getById(groupId); Result result = imServerApi.groupDismiss(groupId.toString(),LoginContext.me().getLoginUser().getUserId().toString()); log.info("解散群聊:"+JSONUtil.toJsonStr(result)); if (result.getCode().intValue() == 200){ boolean update = imGroupService.update(imGroupLambdaUpdateWrapper); //发送群聊消息解散消息 List imGroupUsers = this.imGroupUserService.list(new LambdaQueryWrapper().select(ImGroupUser::getUserId,ImGroupUser::getGroupId).eq(ImGroupUser::getGroupId,groupId).eq(ImGroupUser::getIsDelete,0)); if (CollectionUtil.isNotEmpty(imGroupUsers)){ List userIds = imGroupUsers.stream().map(ImGroupUser::getUserId).map(String::valueOf).collect(Collectors.toList()); String pushContent = imGroup.getName()+".该群聊被解散"; // IM推送数据json ImPushDataDTO pushData = ImPushDataDTO.builder() .type(ImPushTypeEnum.S_TO_C_TIP_GROUP_CANCEL_INFO.getCode()) .objId(ObjUtil.toString(imGroup.getId())) .title("通知") .content(pushContent) // .extra("发起聊天") .data1(ObjUtil.toString(LoginContext.me().getLoginUser().getUserId())) .build(); // 发送 imBizService.messageSendSystem(LoginContext.me().getLoginUser().getUserId() + "", userIds.toArray(new String[userIds.size()]), pushData, ImUserTypeEnum.USER,null, true); } return new SuccessResponseData(update); } return new ErrorResponseData<>("解散群聊失败!"); } @ApiOperation(value = "根据分组id查询业务过期时间") @GetResource(name = "根据分组id查询业务过期时间", path = "/getGroupEffectiveInfo") public ResponseData getGroupEffectiveInfo(Long groupId) { ImGroup imGroup = this.imGroupService.getById(groupId); if (imGroup == null){ return new ErrorResponseData<>("没有对应群聊"); } ImEffectiveInfoDTO imEffectiveInfoDTO = new ImEffectiveInfoDTO(); imEffectiveInfoDTO.setGroupType(imGroup.getGroupType()); imEffectiveInfoDTO.setOrderId(imGroup.getOrderId()); if (imGroup.getGroupType().intValue() ==1){ CourseOrder courseOrder = this.courseOrderService.getById(imGroup.getOrderId()); if (courseOrder != null){ imEffectiveInfoDTO.setUserId(courseOrder.getUserId()); imEffectiveInfoDTO.setEffectiveEndTime(courseOrder.getEffectiveEndTime()); imEffectiveInfoDTO.setEffectiveBeginTime(courseOrder.getEffectiveBeginTime()); Customer customer = this.customerService.getById(imEffectiveInfoDTO.getUserId()); imEffectiveInfoDTO.setPhone(customer.getTelephone()); } }else{ ImGroupUser imGroupUser = this.imGroupUserService.getOne(new LambdaQueryWrapper().eq(ImGroupUser::getGroupId,imGroup.getId()) .isNull(ImGroupUser::getUserPost).last(" limit 1 ")); if (imGroupUser != null){ CounsellingUser counsellingUser = this.counsellingUserService.getOne(new LambdaQueryWrapper().eq(CounsellingUser::getUserId,imGroupUser.getUserId()) .eq(CounsellingUser::getCounsellingInfoId,imGroup.getOrderId()).eq(CounsellingUser::getIsDelete,0)); if (counsellingUser != null){ imEffectiveInfoDTO.setEffectiveEndTime(counsellingUser.getEffectiveEndTime()); imEffectiveInfoDTO.setEffectiveBeginTime(counsellingUser.getEffectiveBeginTime()); imEffectiveInfoDTO.setPhone(counsellingUser.getPhone()); imEffectiveInfoDTO.setClassHours(counsellingUser.getClassHours()); imEffectiveInfoDTO.setResidueClassHours(counsellingUser.getResidueClassHours()); } imEffectiveInfoDTO.setUserId(imGroupUser.getUserId()); } } if (imEffectiveInfoDTO.getUserId() != null){ Customer customer = this.customerService.getById(imEffectiveInfoDTO.getUserId()); if (customer != null){ imEffectiveInfoDTO.setNickName(customer.getNickName()); } } return new SuccessResponseData(imEffectiveInfoDTO); } }