feat:机器人消息模板管理

This commit is contained in:
zuoqinbo 2023-10-13 16:37:28 +08:00
parent 28c0f10625
commit 1331935477
11 changed files with 186 additions and 45 deletions

View File

@ -33,6 +33,7 @@ public class UserAccountReq {
/**
* 用户昵称
*/
@NotNull(message = "注册用户昵称不能为空")
private String nickName;
/**

View File

@ -2,6 +2,7 @@ package cn.axzo.im.channel;
import cn.axzo.im.channel.netease.dto.RegisterRequest;
import cn.axzo.im.channel.netease.dto.RegisterResponse;
import cn.axzo.im.channel.netease.dto.RegisterUpdateRequest;
import javax.validation.Valid;
@ -46,4 +47,9 @@ public interface IMChannelProvider {
* @return
*/
String getProviderAppSecret();
/**
* 更新用户IM账户信息
*/
RegisterResponse updateAccountProfile(RegisterUpdateRequest updateProfile);
}

View File

@ -90,7 +90,7 @@ public class NimChannelService implements IMChannelProvider {
paramMap.put("accid", register.getAccid());
paramMap.put("icon", register.getIcon());
paramMap.put("name", register.getName());
Map<String, String> authHeaderMap = buildAuthHeader(register.getAppKey(), AppKeyUtil.getAppSecret());
Map<String, String> authHeaderMap = buildAuthHeader(getProviderAppKey(), getProviderAppKey());
HttpResponse response = HttpRequest.post(NIM_ACCOUNT_CREATE_URL).addHeaders(authHeaderMap)
.form(paramMap).timeout(5000).execute();
String result = response.body();
@ -119,12 +119,40 @@ public class NimChannelService implements IMChannelProvider {
}
}
}
return registerResponse;
} else {
log.error("im-center请求网易云信Server:{},异常:{}", NIM_ACCOUNT_CREATE_URL, result);
}
return RegisterResponse.builder().desc("请求网易云信Server异常,请联系管理员").build();
return RegisterResponse.builder().desc("请求网易云信Server异常,请联系管理员!").build();
}
@Override
public RegisterResponse updateAccountProfile(@Valid RegisterUpdateRequest updateRequest) {
HashMap<String, Object> paramMap = new HashMap<>();
paramMap.put("accid", updateRequest.getAccid());
if (StringUtils.isNotBlank(updateRequest.getIcon())) {
paramMap.put("icon", updateRequest.getIcon());
}
if (StringUtils.isNotBlank(updateRequest.getName())) {
paramMap.put("name", updateRequest.getName());
}
if (StringUtils.isNotBlank(updateRequest.getExtJson())) {
paramMap.put("ex", updateRequest.getExtJson());
}
Map<String, String> authHeaderMap = buildAuthHeader(getProviderAppKey(), getProviderAppKey());
HttpResponse response = HttpRequest.post(NIM_ACCOUNT_CREATE_URL).addHeaders(authHeaderMap)
.form(paramMap).timeout(5000).execute();
String result = response.body();
if (response.getStatus() == SUCCESS_CODE) {
RegisterResponse registerResponse = JSONUtil.toBean(result, RegisterResponse.class);
if (registerResponse.getCode() != SUCCESS_CODE) {
log.warn("im-center请求网易云信Server:{},返回异常:{}", NIM_ACCOUNT_CREATE_URL, result);
}
return registerResponse;
} else {
log.error("im-center请求网易云信Server:{},异常:{}", NIM_ACCOUNT_CREATE_URL, result);
}
return RegisterResponse.builder().desc("请求网易云信Server异常,请联系管理员!").build();
}
/**

View File

@ -13,12 +13,6 @@ import javax.validation.constraints.NotNull;
*/
@Data
public class RegisterRequest {
/**
* AppKey 唯一标识
*/
@NotNull
private String appKey;
/**
* 云信账号必须保证唯一性若涉及字母传参时请一律小写处理只允许字母数字半角下划线_@半角点以及半角-请注意以此接口返回结果中的accid为准
*/
@ -28,6 +22,7 @@ public class RegisterRequest {
/**
* 用户昵称
*/
@NotNull
private String name;
/**

View File

@ -0,0 +1,65 @@
package cn.axzo.im.channel.netease.dto;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* 云信账户更新其他字段暂时不需要
* 文档地址:https://doc.yunxin.163.com/messaging/docs/zI0NzYyMDQ?platform=server
*
* @author zuoqinbo
* @version V1.0
* @date 2023/10/10 18:41
*/
@Data
public class RegisterUpdateRequest {
/**
* 云信账号必须保证唯一性若涉及字母传参时请一律小写处理只允许字母数字半角下划线_@半角点以及半角-请注意以此接口返回结果中的accid为准
*/
@NotNull
private String accid;
/**
* 用户昵称
*/
@NotNull
private String name;
/**
* 用户头像 URL
*/
private String icon;
/**
* 采用JSON格式存储,直接存放IM中心 机器人所有信息JSON数据结构
* {
* "robotId": "a90284cc-aa72-491c-a30b-5cc97c3305e2",
* "nickName": "机器人15",
* "robotTagList": [
* {
* "id": 2,
* "tagName": "机器人Tag2",
* "weight": 999,
* "status": 1,
* "color": "GREEN-B",
* "useCount": 3
* }
* ],
* "headImageUrl": "223",
* "imAccount": "3124513213",
* "status": "enabled",
* "msgTemplateValid": null,
* "msgTemplateTotal": null,
* "msgTemplateList": [
* {
* "templateId": 21,
* "templateContent": "机器人消息模板示例$name$",
* }
* ]
* }
*/
private String extJson;
}

View File

@ -1,16 +1,12 @@
package cn.axzo.im.controller;
import cn.axzo.framework.domain.page.PageResp;
import cn.axzo.framework.domain.web.result.ApiPageResult;
import cn.axzo.framework.domain.web.result.ApiResult;
import cn.axzo.im.center.api.feign.AccountApi;
import cn.axzo.im.center.api.feign.RobotInfoApi;
import cn.axzo.im.center.api.vo.req.*;
import cn.axzo.im.center.api.vo.resp.RobotInfoResp;
import cn.axzo.im.center.api.vo.resp.RobotMsgTemplateResp;
import cn.axzo.im.center.api.vo.req.AccountQuery;
import cn.axzo.im.center.api.vo.req.RobotAccountReq;
import cn.axzo.im.center.api.vo.req.UserAccountReq;
import cn.axzo.im.center.api.vo.resp.UserAccountResp;
import cn.axzo.im.service.AccountService;
import cn.axzo.im.service.RobotInfoService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RestController;

View File

@ -8,7 +8,6 @@ import cn.axzo.im.center.api.vo.req.RobotInfoReq;
import cn.axzo.im.center.api.vo.req.RobotPageQuery;
import cn.axzo.im.center.api.vo.req.UpdateRobotInfoReq;
import cn.axzo.im.center.api.vo.resp.RobotInfoResp;
import cn.axzo.im.center.api.vo.resp.RobotMsgTemplateResp;
import cn.axzo.im.service.RobotInfoService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

View File

@ -90,7 +90,7 @@ public class AccountService {
}
if (StringUtils.isBlank(accountRegister.getImAccount())) {
//2.重新注册账户,如果已注册就查询该账户信息
UserAccountResp accountResp = createNimAccount(userIdWrapper, headImageUrl, nickName, appKey);
UserAccountResp accountResp = createNimAccount(userIdWrapper, headImageUrl, nickName);
if (accountResp != null && StringUtils.isNotBlank(accountResp.getImAccount())) {
accountRegister.setImAccount(accountResp.getImAccount());
accountRegister.setToken(accountResp.getToken());
@ -122,12 +122,11 @@ public class AccountService {
}
private UserAccountResp createNimAccount(String userId, String headImageUrl, String name, String appKey) {
private UserAccountResp createNimAccount(String userId, String headImageUrl, String name) {
RegisterRequest register = new RegisterRequest();
register.setAccid(userId);
register.setIcon(headImageUrl);
register.setName(name);
register.setAppKey(appKey);
//3.调用公共的网易云信IM接口创建账户 网易云信只是一种IM实现
RegisterResponse registerResponse = imChannelProvider.registerAccount(register);
if (registerResponse.getInfo() != null) {

View File

@ -0,0 +1,59 @@
package cn.axzo.im.service;
import cn.axzo.im.center.api.vo.resp.RobotInfoResp;
import cn.axzo.im.center.api.vo.resp.RobotMsgTemplateResp;
import cn.axzo.im.channel.IMChannelProvider;
import cn.axzo.im.channel.netease.dto.RegisterUpdateRequest;
import cn.axzo.im.dao.repository.RobotInfoDao;
import cn.axzo.im.entity.RobotInfo;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* im-center
*
* @author zuoqinbo
* @version V1.0
* @date 2023/10/13 16:14
*/
@Slf4j
@Service
public class NotifyChannelService {
@Resource
private IMChannelProvider channelProvider;
@Resource
private RobotInfoDao robotInfoDao;
@Resource
private RobotInfoService robotInfoService;
@Resource
private RobotMsgTemplateService templateService;
public void notifyAccountChange(String robotId) {
RegisterUpdateRequest updateProfile = new RegisterUpdateRequest();
RobotInfo robotInfo = robotInfoDao.lambdaQuery().eq(RobotInfo::getIsDelete, 0)
.eq(RobotInfo::getRobotId, robotId).one();
if (robotInfo == null) {
return;
}
RobotInfoResp robotInfoResp = robotInfoService.findRobotInfoById(robotInfo.getId());
RobotMsgTemplateResp robotMsgTemplate = templateService.queryRobotMsgTemplateList(robotInfoResp.getRobotId());
robotInfoResp.setMsgTemplateList(robotMsgTemplate.getMsgTemplateList());
String extJson = JSONUtil.toJsonStr(robotInfoResp);
updateProfile.setExtJson(extJson);
updateProfile.setAccid(robotInfoResp.getImAccount());
updateProfile.setIcon(robotInfoResp.getHeadImageUrl());
updateProfile.setName(robotInfoResp.getNickName());
log.info("更新机器人:{},网易云信账户信息", JSONUtil.toJsonStr(updateProfile));
channelProvider.updateAccountProfile(updateProfile);
}
}

View File

@ -13,7 +13,6 @@ import cn.axzo.im.center.common.enums.RobotStatusEnum;
import cn.axzo.im.dao.repository.RobotInfoDao;
import cn.axzo.im.dao.repository.RobotTagDao;
import cn.axzo.im.entity.RobotInfo;
import cn.axzo.im.entity.RobotMsgTemplate;
import cn.axzo.im.entity.RobotTag;
import cn.axzo.im.utils.BeanConvertUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
@ -21,7 +20,6 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.units.qual.C;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RestController;
@ -30,8 +28,6 @@ import javax.validation.Valid;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
@ -58,6 +54,9 @@ public class RobotInfoService {
@Resource
private RobotTagService robotTagService;
@Resource
private NotifyChannelService notifyChannelService;
@Transactional(rollbackFor = Exception.class)
public RobotInfoResp saveRobotInfo(@Valid RobotInfoReq robotInfoRequest) {
verifyRobotName(robotInfoRequest.getNickName(), null);
@ -75,7 +74,6 @@ public class RobotInfoService {
@Transactional(rollbackFor = Exception.class)
public RobotInfoResp updateRobotInfo(@Valid UpdateRobotInfoReq updateRobotInfoReq) {
String status = updateRobotInfoReq.getStatus();
Long primaryId = updateRobotInfoReq.getId();
RobotInfo robotTag = robotInfoDao.lambdaQuery().eq(RobotInfo::getIsDelete, 0)
.eq(RobotInfo::getId, primaryId).one();
@ -88,10 +86,8 @@ public class RobotInfoService {
RobotInfo robotInfo = BeanConvertUtils.copyBean(updateRobotInfoReq, RobotInfo.class);
robotInfo.setUpdateAt(new Date());
robotInfo = robotInfoDao.saveOrUpdateRobotInfo(robotInfo);
if (robotInfo != null) {
return findRobotInfoById(robotInfo.getId());
}
return null;
notifyChannelService.notifyAccountChange(robotInfo.getRobotId());
return findRobotInfoById(robotInfo.getId());
}
private void verifyRobotStatus(String status, Long primaryId) {
@ -117,13 +113,13 @@ public class RobotInfoService {
}
}
private RobotInfoResp findRobotInfoById(Long id) {
public RobotInfoResp findRobotInfoById(Long id) {
RobotInfo robotInfo = robotInfoDao.getById(id);
List<Long> tagIdList = robotInfo.getTagNameList();
RobotInfoResp robotInfoResp = BeanMapper.map(robotInfo, RobotInfoResp.class);
List<RobotTag> robotTags = robotTagDao.queryRobotTagValidList(tagIdList);
List<RobotTagResp> robotTagsResp = BeanMapper.copyList(robotTags, RobotTagResp.class);
robotTagsResp.stream().forEach(robotTag -> {
robotTagsResp.forEach(robotTag -> {
int useCount = robotTagService.findTagUseCount(Integer.parseInt(String.valueOf(robotTag.getId())));
robotTag.setUseCount(useCount);
});
@ -140,7 +136,7 @@ public class RobotInfoService {
List<RobotInfoResp> list = BeanMapper.copyList(robotInfoIPage.getRecords(), RobotInfoResp.class);
PageResp<RobotInfoResp> pageOfRobotInfoResp = PageResp.list(robotInfoIPage.getCurrent(), robotInfoIPage.getSize(),
robotInfoIPage.getTotal(), list);
list.stream().forEach(robotInfoResp -> {
list.forEach(robotInfoResp -> {
RobotMsgTemplateResp robotMsgTemplate = templateService.queryRobotMsgTemplateList(robotInfoResp.getRobotId());
if (robotMsgTemplate != null) {
robotInfoResp.setMsgTemplateList(robotMsgTemplate.getMsgTemplateList());
@ -154,16 +150,12 @@ public class RobotInfoService {
if (CollectionUtils.isEmpty(runningRobots)) {
throw new ServiceException("当前无可用的机器人[状态为已启用]!");
}
List<RobotInfoResp> robotInfoRespList = runningRobots.stream().map(new Function<RobotInfo, RobotInfoResp>() {
@Override
public RobotInfoResp apply(RobotInfo robotInfo) {
RobotInfoResp robotInfoResp = findRobotInfoById(robotInfo.getId());
RobotMsgTemplateResp robotMsgTemplate = templateService.queryRobotMsgTemplateList(robotInfoResp.getRobotId());
robotInfoResp.setMsgTemplateList(robotMsgTemplate.getMsgTemplateList());
return robotInfoResp;
}
return runningRobots.stream().map(robotInfo -> {
RobotInfoResp robotInfoResp = findRobotInfoById(robotInfo.getId());
RobotMsgTemplateResp robotMsgTemplate = templateService.queryRobotMsgTemplateList(robotInfoResp.getRobotId());
robotInfoResp.setMsgTemplateList(robotMsgTemplate.getMsgTemplateList());
return robotInfoResp;
}).collect(Collectors.toList());
return robotInfoRespList;
}
public void updateRobotStatus(String robotId, String imAccount) {

View File

@ -4,22 +4,19 @@ import cn.axzo.basics.common.BeanMapper;
import cn.axzo.basics.common.exception.ServiceException;
import cn.axzo.im.center.api.vo.req.RobotMsgTemplateReq;
import cn.axzo.im.center.api.vo.resp.RobotMsgTemplateResp;
import cn.axzo.im.center.api.vo.resp.RobotTagResp;
import cn.axzo.im.dao.repository.RobotInfoDao;
import cn.axzo.im.dao.repository.RobotMsgTemplateDao;
import cn.axzo.im.entity.RobotInfo;
import cn.axzo.im.entity.RobotMsgTemplate;
import cn.axzo.im.entity.RobotTag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
/**
* im-center
* 机器人消息模板服务
*
* @author zuoqinbo
* @version V1.0
@ -36,6 +33,9 @@ public class RobotMsgTemplateService {
@Resource
private RobotInfoDao robotInfoDao;
@Resource
private NotifyChannelService notifyChannelService;
public RobotMsgTemplateResp queryRobotMsgTemplateList(String robotId) {
RobotMsgTemplate robotMsgTemplate = robotMsgTemplateDao.lambdaQuery().eq(RobotMsgTemplate::getIsDelete, 0)
.eq(RobotMsgTemplate::getRobotId, robotId).one();
@ -64,6 +64,7 @@ public class RobotMsgTemplateService {
robotMsgTemplate.setUpdateAt(new Date());
robotMsgTemplate.setMsgTemplateList(robotMsgTemplateReq.getMsgTemplateList());
robotMsgTemplateDao.saveOrUpdate(robotMsgTemplate);
notifyChannelService.notifyAccountChange(robotId);
return BeanMapper.map(robotMsgTemplate, RobotMsgTemplateResp.class);
}
}