feat:账户注册接口、账户查询接口实现

This commit is contained in:
zuoqinbo 2023-10-12 11:22:23 +08:00
parent c55af63439
commit 9fcbd3bda5
39 changed files with 485 additions and 609 deletions

View File

@ -1,6 +1,7 @@
package cn.axzo.im.center.api.feign;
import cn.axzo.framework.domain.web.result.ApiResult;
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;
@ -9,32 +10,45 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;
/**
* 机器人管理API
*
* @version V1.0
* @author zuoqinbo
* @version V1.0
* @date 2023/10/9 16:01
*/
@FeignClient(name = "im", url = "${axzo.service.im:http://im:8080}")
@FeignClient(name = "im-center", url = "${axzo.service.im-center:http://im:8080}")
public interface AccountApi {
/**
* 普通用户生成网易云信IM账户
* 因多终端场景同一个普通用户会申请多个云信账户用于不同的app终端
* 例如工人端一个IM账户企业端一个IM账户,根据不同的appType来区分
* @param userAccountReq 生成云信账户参数
*
* @param userAccountReq 生成云信账户参数
* @return 返回云信IM账户
*/
@PostMapping("api/im/account/user/generate")
ApiResult<UserAccountResp> generateAccount(@RequestBody @Validated UserAccountReq userAccountReq);
/**
* 查询注册账户信息
*
* @param accountQuery 账户查询条件
* @return 返回云信IM账户
*/
@PostMapping("api/im/account/register/query")
ApiResult<List<UserAccountResp>> queryRegisterAccountInfo(@RequestBody @Validated AccountQuery accountQuery);
/**
* 机器人生成网易云信IM账户
* 机器人通过PC端创建IM账户不需要appType来区分
*
* @param robotAccountReq 生成云信账户参数
* @param robotAccountReq 生成云信账户参数
* @return 返回云信IM账户
*/
@PostMapping("api/im/account/robot/generate")

View File

@ -0,0 +1,39 @@
package cn.axzo.im.center.api.vo.req;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.Map;
/**
* 查询账户信息
*
* @author zuoqinbo
* @version V1.0
* @date 2023/10/9 16:01
*/
@Data
public class AccountQuery {
/**
* 消息应用端
* 工人端企业端服务器
* WORKERENTERPRISESYSTEM
*/
@NotNull(message = "消息应用端不能为空")
private String appType;
/**
* 注册用户ID唯一
* 普通用户userId机器人robotId
*/
@NotNull(message = "注册ID不能为空")
private String accountId;
/**
* 注册用户ID唯一
*/
private String imAccount;
}

View File

@ -1,5 +1,6 @@
package cn.axzo.im.center.api.vo.req;
import cn.axzo.im.center.common.enums.RobotStatusEnum;
import lombok.Data;
import javax.validation.constraints.NotNull;
@ -36,7 +37,7 @@ public class RobotInfoReq {
/**
* 机器人状态
* @see cn.axzo.maokai.common.enums.RobotStatusEnum
* @see RobotStatusEnum
*/
private String status = "creating";

View File

@ -22,14 +22,16 @@ public class RobotTagQuery extends PageRequest {
/**
* 机器人Tag名称
* 支持模糊查询
*/
private String tagName;
/**
* 机器人状态
* 机器人Tag状态
* 0:下架 1:上架
*/
private String status;
private Integer status;
}

View File

@ -16,18 +16,18 @@ import java.util.Map;
public class UserAccountReq {
/**
* 发送消息到
* 工人端企业端ALL
* WORKERENTERPRISEALL
* 消息应用
* 工人端企业端服务器
* WORKERENTERPRISESYSTEM
*/
@NotNull(message = "消息接收端类型")
@NotNull(message = "消息应用端不能为空")
private String appType;
/**
* 用户userId 唯一
* 注册用户ID唯一
*/
@NotNull(message = "userId不能为空")
@NotNull(message = "注册用户ID不能为空")
private String userId;
/**

View File

@ -29,4 +29,10 @@ public class UserAccountResp {
private String token;
/**
* 注册不成功返回网易云信描述信息
*/
private String desc;
}

View File

@ -1,2 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.axzo.im.center.api.config.MaoKaiApiAutoConfiguration
#org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
#cn.axzo.im.center.api.config.MaoKaiApiAutoConfiguration

View File

@ -1,2 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.axzo.im.center.api.config.MaoKaiApiAutoConfiguration
#org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
#cn.axzo.im.center.api.config.MaoKaiApiAutoConfiguration

View File

@ -1,22 +1,22 @@
cn\axzo\im\center\api\feign\RobotTagApi.class
cn\axzo\im\center\api\vo\req\RobotTagQuery.class
cn\axzo\im\center\api\vo\req\RobotInfoReq.class
cn\axzo\im\center\api\vo\req\UpdateRobotInfoReq.class
cn\axzo\im\center\api\vo\req\UserAccountReq.class
cn\axzo\im\center\api\vo\req\UpdateRobotTagReq$UpdateRobotTagReqBuilder.class
cn\axzo\im\center\api\vo\resp\RobotInfoResp.class
cn\axzo\im\center\api\vo\req\RobotTagReq$RobotTagReqBuilder.class
cn\axzo\im\center\api\vo\req\RobotTagQuery$RobotTagQueryBuilder.class
cn\axzo\im\center\api\vo\req\MessageInfo.class
cn\axzo\im\center\api\vo\req\RobotPageQuery.class
cn\axzo\im\center\api\vo\resp\UserAccountResp.class
cn\axzo\im\center\api\vo\resp\MessageTemplateResp.class
cn\axzo\im\center\api\vo\resp\MessageResp.class
cn\axzo\im\center\api\vo\req\RobotTagQuery.class
cn\axzo\im\center\api\vo\req\RobotAccountReq.class
cn\axzo\im\center\api\vo\resp\RobotMsgTemplateResp.class
cn\axzo\im\center\api\feign\AccountApi.class
cn\axzo\im\center\api\vo\req\UpdateRobotTagReq.class
cn\axzo\im\center\api\vo\req\UpdateRobotTagReq$UpdateRobotTagReqBuilder.class
cn\axzo\im\center\api\vo\resp\RobotTagResp.class
cn\axzo\im\center\api\vo\resp\RobotInfoResp.class
cn\axzo\im\center\api\vo\req\RobotTagReq$RobotTagReqBuilder.class
cn\axzo\im\center\api\vo\req\RobotTagReq.class
cn\axzo\im\center\api\vo\req\RobotTagQuery$RobotTagQueryBuilder.class
cn\axzo\im\center\api\feign\RobotInfoApi.class
cn\axzo\im\center\api\vo\req\MessageInfo.class
cn\axzo\im\center\api\vo\req\RobotPageQuery.class
cn\axzo\im\center\api\vo\resp\UserAccountResp.class
cn\axzo\im\center\api\feign\MessageApi.class
cn\axzo\im\center\api\vo\resp\MessageTemplateResp.class
cn\axzo\im\center\api\vo\resp\MessageResp.class

View File

@ -1,4 +1,4 @@
package cn.axzo.maokai.common.enums;
package cn.axzo.im.center.common.enums;
import lombok.Getter;

View File

@ -0,0 +1,43 @@
package cn.axzo.im.center.common.enums;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
/**
* App消息应用终端类型
*
* @author zuoqinbo
* @version V1.0
* @date 2023/10/9 16:01
*/
@Getter
public enum AppTypeEnum {
WORKER("worker", "工人端"),
ENTERPRISE("enterprise", "企业端"),
SYSTEM("system", "服务器");
private String code;
private String message;
AppTypeEnum(String code, String message) {
this.code = code;
}
public static AppTypeEnum isValidAppType(String appType) {
if (StringUtils.isBlank(appType)) {
return null;
}
AppTypeEnum[] appTypeEnums = AppTypeEnum.values();
for (AppTypeEnum appTypeEnum : appTypeEnums) {
if (appTypeEnum.getCode().equals(appType.toLowerCase())) {
return appTypeEnum;
}
}
return null;
}
}

View File

@ -1,4 +1,4 @@
package cn.axzo.maokai.common.enums;
package cn.axzo.im.center.common.enums;
import lombok.Getter;

View File

@ -3,4 +3,4 @@
* @author tanjie@axzo.cn
* @date 2023/6/25 18:30
*/
package cn.axzo.maokai.common;
package cn.axzo.im.center.common;

View File

@ -1,29 +0,0 @@
package cn.axzo.maokai.common.enums;
import lombok.Getter;
/**
* App终端类型
*
* @version V1.0
* @author zuoqinbo
* @date 2023/10/9 16:01
*/
@Getter
public enum AppTypeEnum {
WORKER("worker", "工人端"),
ENTERPRISE("enterprise", "企业端"),
SYSTEM("system", "服务器");
private String code;
private String message;
AppTypeEnum(String code, String message) {
this.code = code;
}
}

View File

@ -1,3 +0,0 @@
cn\axzo\maokai\common\enums\AccountTypeEnum.class
cn\axzo\maokai\common\enums\AppTypeEnum.class
cn\axzo\maokai\common\enums\RobotStatusEnum.class

View File

@ -113,7 +113,7 @@
</dependencies>
<build>
<finalName>maokai</finalName>
<finalName>im-center</finalName>
<resources>
<resource>
<directory>src/main/java</directory>

View File

@ -1,15 +1,25 @@
package cn.axzo.im;
import cn.axzo.framework.data.mybatisplus.config.MybatisPlusAutoConfiguration;
import cn.axzo.trade.theadpool.annotation.EnableTradeTaskExecutor;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import;
import org.springframework.core.env.Environment;
import org.springframework.scheduling.annotation.EnableAsync;
@Slf4j
@MapperScan(value = {"cn.axzo.im.repository.mapper"})
@SpringBootApplication(scanBasePackages = "cn.axzo")
@SpringBootApplication(scanBasePackages = "cn.axzo", exclude = MybatisPlusAutoConfiguration.class)
@EnableFeignClients(basePackages = {
"cn.axzo.im.center.api",
})
@MapperScan(value = {"cn.axzo.im.dao.mapper"})
@EnableDiscoveryClient
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(Application.class, args);

View File

@ -39,6 +39,12 @@ public class AccountController implements AccountApi {
return ApiResult.ok(userAccountResp);
}
@Override
public ApiResult<List<UserAccountResp>> queryRegisterAccountInfo(AccountQuery accountQuery) {
List<UserAccountResp> userAccountList = accountService.queryAccountInfo(accountQuery);
return ApiResult.ok(userAccountList);
}
@Override
public ApiResult<UserAccountResp> generateRobotAccount(RobotAccountReq robotAccountReq) {
UserAccountResp userAccountResp = accountService.generateRobotAccount(robotAccountReq);

View File

@ -9,18 +9,19 @@ import cn.axzo.im.enums.RobotStatus;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* im
* 账户服务Dao
*
* @author zuoqinbo
* @version V1.0
* @date 2023/10/10 10:06
*/
@Service
@Repository("accountRegisterDao")
public class AccountRegisterDao extends ServiceImpl<AccountRegisterMapper, AccountRegister> {
}

View File

@ -7,18 +7,19 @@ import cn.axzo.im.enums.RobotStatus;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* im
* 机器人服务Dao
*
* @author zuoqinbo
* @version V1.0
* @date 2023/10/10 10:06
*/
@Service
@Repository("robotInfoDao")
public class RobotInfoDao extends ServiceImpl<RobotInfoMapper, RobotInfo> {
/**
* 查询机器人标签列表,支持分页查询

View File

@ -30,8 +30,7 @@ public class RobotTagDao extends ServiceImpl<RobotTagMapper, RobotTag> {
.like(StringUtils.isNoneBlank(robotTagQuery.getTagName()),
RobotTag::getTagName,
robotTagQuery.getTagName())
.eq(StringUtils.isNoneBlank(robotTagQuery.getStatus()),
RobotTag::getStatus, robotTagQuery.getStatus())
.eq(RobotTag::getStatus, robotTagQuery.getStatus())
.orderByDesc(RobotTag::getWeight)
.page(robotTagQuery.toPage());
return pageOfRobotTag;

View File

@ -1,24 +1,27 @@
package cn.axzo.im.entity;
import cn.axzo.framework.data.mybatisplus.model.BaseEntity;
import cn.axzo.im.center.common.enums.AppTypeEnum;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Getter;
import lombok.Setter;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.List;
import java.io.Serializable;
/**
* im
* IM账户表
*
* @version V1.0
* @author zuoqinbo
* @version V1.0
* @date 2023/10/9 16:01
*/
@Getter
@Setter
@TableName("im_account_register")
public class AccountRegister extends BaseEntity<AccountRegister> {
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class AccountRegister extends BaseEntity<AccountRegister> implements Serializable {
private static final long serialVersionUID = 1L;
@ -29,7 +32,7 @@ public class AccountRegister extends BaseEntity<AccountRegister> {
private String accountId;
/**
* 普通用户账户需要根据不同appType来进行包装
* 普通用户通过appType包装
* 包装以后进行账户注册
*/
@TableField("account_wrapper")
@ -43,7 +46,8 @@ public class AccountRegister extends BaseEntity<AccountRegister> {
/**
* 终端类型
* @see cn.axzo.maokai.common.enums.AppTypeEnum
*
* @see AppTypeEnum
*/
@TableField("app_type")
private String appType;
@ -55,7 +59,7 @@ public class AccountRegister extends BaseEntity<AccountRegister> {
@TableField("app_key")
private String appKey;
/**
* 账户类型 机器人普通用户
* 账户类型:机器人普通用户
*/
@TableField("account_type")
private String accountType;

View File

@ -3,9 +3,13 @@ package cn.axzo.im.entity;
import cn.axzo.framework.data.mybatisplus.model.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.List;
/**
@ -15,10 +19,11 @@ import java.util.List;
* @author zuoqinbo
* @date 2023/10/9 16:01
*/
@Getter
@Setter
@TableName("im_robot_info")
public class RobotInfo extends BaseEntity<RobotInfo> {
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class RobotInfo extends BaseEntity<RobotInfo> implements Serializable {
private static final long serialVersionUID = 1L;

View File

@ -0,0 +1,51 @@
package cn.axzo.im.exception;
import cn.axzo.basics.common.exception.ServiceException;
import cn.azxo.framework.common.model.CommonResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.List;
/**
* Controller异常
* @author zuoqinbo
* @version V1.0
* @date 2023/10/11 9:44
*/
@Order(value = 0)
@RestControllerAdvice
@Slf4j
public class ExceptionAdviceHandler {
@ExceptionHandler(ServiceException.class)
public CommonResponse<Void> basicsServiceExceptionHandler(ServiceException e) {
log.warn("业务异常", e);
return CommonResponse.fail(e.getMessage());
}
@ExceptionHandler(cn.axzo.core.service.ServiceException.class)
public CommonResponse<Void> coreServiceExceptionHandler(cn.axzo.core.service.ServiceException e) {
log.warn("业务异常", e);
return CommonResponse.fail(e.getMessage());
}
@ExceptionHandler(BindException.class)
public CommonResponse<Void> bindExceptionHandler(BindException e) {
log.warn("业务异常", e);
List<ObjectError> allErrors = e.getBindingResult().getAllErrors();
if (CollectionUtils.isEmpty(allErrors)) {
return CommonResponse.fail("操作失败 请联系系统管理员");
}
ObjectError objectError = allErrors.get(0);
String objectErrorDefaultMessage = objectError.getDefaultMessage();
return CommonResponse.fail(objectErrorDefaultMessage);
}
}

View File

@ -1,12 +1,9 @@
package cn.axzo.im.nim;
import cn.axzo.im.nim.dto.UserAccount;
import cn.axzo.maokai.common.enums.AppTypeEnum;
import javax.annotation.Resource;
/**
* IM证书管理
* 网易云信IM证书管理
* 引入配置中心
*
* @author zuoqinbo
@ -17,8 +14,12 @@ import javax.annotation.Resource;
public class AppKeyUtil {
private static final String APP_KEY = "70c18b713812ae6e8038142f24c99f48";
private static final String APP_SECRET = "784adefc4be7";
public static String getAppKey() {
return APP_KEY;
}
public static String getAppSecret() {
return APP_SECRET;
}
}

View File

@ -1,11 +1,16 @@
package cn.axzo.im.nim;
import cn.axzo.im.nim.dto.AccountRegisterResponse;
import cn.axzo.im.nim.dto.RegisterResponse;
import cn.axzo.im.nim.dto.QueryAccountResp;
import cn.axzo.im.nim.dto.RegisterRequest;
import cn.axzo.im.nim.dto.UserAccount;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.validation.Valid;
@ -24,12 +29,16 @@ import java.util.UUID;
@Slf4j
public class NimService {
private static final String NIM_ACCOUNT_CREATE_URL = " https://api.netease.im/nimserver/user/create.action";
private static final String NIM_ACCOUNT_CREATE_URL = "https://api.netease.im/nimserver/user/create.action";
private static final String NIM_ACCOUNT_QUERY_URL = "https://api.netease.im/nimserver/user/getUinfos.action";
private static final String NIM_MESSAGE_DISPATCH_URL = "https://api.netease.im/nimserver/msg/sendMsg.action";
private static final int SUCCESS_CODE = 200;
private static final String NIM_ACCOUNT_ALREADY_REGISTER = "already register";
// public static String sendMessage(@Valid NimMessage messageInfo) {
// if(messageInfo == null){
//
@ -58,27 +67,46 @@ public class NimService {
* @param register
* @return
*/
public static UserAccount registerAccount(@Valid Register register) {
public static RegisterResponse registerAccount(@Valid RegisterRequest register) {
HashMap<String, Object> paramMap = new HashMap<>();
paramMap.put("accid", register.getAccid());
paramMap.put("icon", register.getIcon());
paramMap.put("name", register.getName());
Map<String, String> authHeaderMap = buildAuthHeader(register.getAppKey());
Map<String, String> authHeaderMap = buildAuthHeader(register.getAppKey(), AppKeyUtil.getAppSecret());
HttpResponse response = HttpRequest.post(NIM_ACCOUNT_CREATE_URL).addHeaders(authHeaderMap)
.form(paramMap).timeout(5000).execute();
String result = response.body();
if (response.getStatus() == SUCCESS_CODE) {
AccountRegisterResponse userAccount = JSONUtil.toBean(result, AccountRegisterResponse.class);
if (userAccount.getCode() == SUCCESS_CODE) {
return userAccount.getInfo();
} else {
log.error("请求网易云信Server:{},异常desc:{}", NIM_ACCOUNT_CREATE_URL, userAccount.getDesc());
RegisterResponse registerResponse = JSONUtil.toBean(result, RegisterResponse.class);
if (registerResponse.getCode() != SUCCESS_CODE) {
log.warn("im-center请求网易云信Server:{},返回异常:{}", NIM_ACCOUNT_CREATE_URL, result);
if (StringUtils.isNotBlank(registerResponse.getDesc()) &&
registerResponse.getDesc().equals(NIM_ACCOUNT_ALREADY_REGISTER)) {
HashMap<String, Object> queryParamMap = new HashMap<>();
JSONArray jsonArray = new JSONArray();
jsonArray.add(register.getAccid());
jsonArray.toArray();
queryParamMap.put("accids", jsonArray.toString());
HttpResponse queryAccountResponse = HttpRequest.post(NIM_ACCOUNT_QUERY_URL).addHeaders(authHeaderMap)
.form(queryParamMap).timeout(5000).execute();
if (queryAccountResponse.getStatus() == SUCCESS_CODE) {
QueryAccountResp queryInfoResp = JSONUtil.toBean(queryAccountResponse.body(), QueryAccountResp.class);
if (CollectionUtils.isNotEmpty(queryInfoResp.getUinfos())) {
QueryAccountResp.AccountInfo accountInfo = queryInfoResp.getUinfos().get(0);
UserAccount userAccount = new UserAccount();
userAccount.setAccid(accountInfo.getAccid());
registerResponse.setInfo(userAccount);
}
}
}
}
return registerResponse;
} else {
log.error("请求网易云信Server:{},异常:{}", NIM_ACCOUNT_CREATE_URL, result);
;
log.error("im-center请求网易云信Server:{},异常:{}", NIM_ACCOUNT_CREATE_URL, result);
}
return new UserAccount();
return RegisterResponse.builder().desc("请求网易云信Server异常,请联系管理员").build();
}
/**
@ -87,10 +115,10 @@ public class NimService {
*
* @return
*/
private static Map<String, String> buildAuthHeader(String appKey) {
private static Map<String, String> buildAuthHeader(String appKey, String secret) {
String nonce = UUID.randomUUID().toString();
String curTime = String.valueOf(System.currentTimeMillis() / 1000);
String checkSum = CheckSumUtil.getCheckSum(appKey, nonce, curTime);
String checkSum = CheckSumUtil.getCheckSum(secret, nonce, curTime);
HashMap<String, String> commonAuthMap = new HashMap<>();
commonAuthMap.put("AppKey", appKey);
commonAuthMap.put("Nonce", nonce);

View File

@ -0,0 +1,52 @@
package cn.axzo.im.nim.dto;
import lombok.Builder;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
/**
* 查询网易云信IM注册用户信息
*
* @author zuoqinbo
* @version V1.0
* @date 2023/10/11 17:14
*/
@Data
@Builder
public class QueryAccountResp {
private int code;
private List<AccountInfo> uinfos;
@Getter
@Setter
public class AccountInfo {
/**
* 性别
*/
private boolean valid;
/**
* 性别
*/
private int gender;
/**
* IM账户信息
*/
private String accid;
/**
* mute
*/
private boolean mute;
}
}

View File

@ -1,4 +1,4 @@
package cn.axzo.im.nim;
package cn.axzo.im.nim.dto;
import lombok.Data;
@ -12,7 +12,7 @@ import javax.validation.constraints.NotNull;
* @date 2023/10/10 18:41
*/
@Data
public class Register {
public class RegisterRequest {
/**
* AppKey 唯一标识

View File

@ -1,5 +1,6 @@
package cn.axzo.im.nim.dto;
import lombok.Builder;
import lombok.Data;
/**
@ -10,7 +11,8 @@ import lombok.Data;
* @date 2023/10/11 17:14
*/
@Data
public class AccountRegisterResponse {
@Builder
public class RegisterResponse {
private int code;
private UserAccount info;
private String desc;

View File

@ -27,4 +27,10 @@ public class UserAccount {
private String token;
/**
* 注册不成功返回网易云信描述信息
*/
private String desc;
}

View File

@ -1,32 +1,33 @@
package cn.axzo.im.service;
import cn.axzo.basics.common.BeanMapper;
import cn.axzo.framework.domain.page.PageResp;
import cn.axzo.basics.common.exception.ServiceException;
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.resp.RobotTagResp;
import cn.axzo.im.center.api.vo.resp.UserAccountResp;
import cn.axzo.im.dao.repository.AccountRegisterDao;
import cn.axzo.im.dao.repository.RobotInfoDao;
import cn.axzo.im.entity.AccountRegister;
import cn.axzo.im.entity.RobotInfo;
import cn.axzo.im.enums.RobotStatus;
import cn.axzo.im.nim.AppKeyUtil;
import cn.axzo.im.nim.NimService;
import cn.axzo.im.nim.Register;
import cn.axzo.im.nim.dto.RegisterResponse;
import cn.axzo.im.nim.dto.RegisterRequest;
import cn.axzo.im.nim.dto.UserAccount;
import cn.axzo.im.utils.BeanConvertUtils;
import cn.axzo.maokai.common.enums.AccountTypeEnum;
import cn.axzo.maokai.common.enums.AppTypeEnum;
import com.baomidou.mybatisplus.core.metadata.IPage;
import cn.axzo.im.center.common.enums.AccountTypeEnum;
import cn.axzo.im.center.common.enums.AppTypeEnum;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Date;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* IM账户服务
@ -44,19 +45,19 @@ public class AccountService {
private AccountRegisterDao accountRegisterDao;
/**
* 普通用户创建IM账户
* 1.检查账户是否已经创建
* 1.1 如果已经创建直接返回
* 2.appType 校验重新拼接注册账户
* 3.调用公共的网易云信IM接口创建
* 创建IM账户
*
* @param userAccountReq
*/
@Transactional(rollbackFor = Exception.class)
public UserAccountResp generateAccount(@Valid UserAccountReq userAccountReq) {
String appType = userAccountReq.getAppType();
String userIdWrapper = userAccountReq.getUserId() + "_" + appType;
AppTypeEnum appTypeEnum = AppTypeEnum.isValidAppType(appType);
if (appTypeEnum == null) {
throw new ServiceException("当前appType,服务器不支持该类型!!");
}
String userIdWrapper = userAccountReq.getUserId() + "_" + appTypeEnum.getCode();
//后续AppKey可能会更换普通用户通过userIdappTypeappKey维度来保证唯一性
//机器人通过robotIdappKey维度来保证唯一性
UserAccountResp userAccountResp = createAccountRegister(userAccountReq.getUserId(),
userIdWrapper, appType, AccountTypeEnum.USER.getCode(),
userAccountReq.getHeadImageUrl(), userAccountReq.getNickName());
@ -65,49 +66,94 @@ public class AccountService {
public UserAccountResp generateRobotAccount(@Valid RobotAccountReq robotAccountReq) {
//机器人通过robotIdappKey维度来保证唯一性
//后续AppKey可能会更换机器人通过robotIdappKey维度来保证唯一性
String robotId = robotAccountReq.getRobotId();
UserAccountResp userAccountResp = createAccountRegister(robotId, robotId, AppTypeEnum.SYSTEM.getCode(),
AccountTypeEnum.USER.getCode(), robotAccountReq.getHeadImageUrl(), robotAccountReq.getNickName());
AccountTypeEnum.ROBOT.getCode(), robotAccountReq.getHeadImageUrl(), robotAccountReq.getNickName());
return userAccountResp;
}
public UserAccountResp createAccountRegister(String userId, String userIdWrapper, String appType,
String accountType, String headImageUrl, String nickName) {
//1.检查账户是否已经创建
AccountRegister accountRegister = accountRegisterDao.lambdaQuery().eq(AccountRegister::getIsDelete, 0)
.eq(AccountRegister::getAccountWrapper, userIdWrapper)
.eq(AccountRegister::getAppKey, AppKeyUtil.getAppKey()).getEntity();
.eq(AccountRegister::getAppKey, AppKeyUtil.getAppKey()).one();
if (accountRegister == null) {
accountRegister = new AccountRegister();
}
if (StringUtils.isBlank(accountRegister.getImAccount())) {
UserAccountResp accountResp = createNimAccount(userIdWrapper, headImageUrl,
nickName, AppKeyUtil.getAppKey());
accountRegister.setImAccount(accountResp.getImAccount());
accountRegister.setToken(accountResp.getToken());
accountRegister.setAppKey(AppKeyUtil.getAppKey());
accountRegister.setAccountId(userId);
accountRegister.setAccountWrapper(userIdWrapper);
accountRegister.setAccountType(accountType);
accountRegister.setAppType(appType);
accountRegisterDao.saveOrUpdate(accountRegister);
//2.重新注册账户,如果已注册就查询该账户信息
UserAccountResp accountResp = createNimAccount(userIdWrapper, headImageUrl, nickName, AppKeyUtil.getAppKey());
if (accountResp != null && StringUtils.isNotBlank(accountResp.getImAccount())) {
accountRegister.setImAccount(accountResp.getImAccount());
accountRegister.setToken(accountResp.getToken());
accountRegister.setAppKey(AppKeyUtil.getAppKey());
accountRegister.setAccountId(userId);
accountRegister.setAccountWrapper(userIdWrapper);
accountRegister.setAccountType(accountType);
accountRegister.setAppType(appType);
accountRegister.setCreateAt(new Date());
accountRegister.setUpdateAt(new Date());
accountRegisterDao.saveOrUpdate(accountRegister);
} else {
//2.1注册出现异常
UserAccountResp userAccountResp = UserAccountResp.builder()
.desc(accountResp.getDesc())
.build();
return userAccountResp;
}
return accountResp;
}
//1.1 如果已经创建直接返回
UserAccountResp userAccountResp = UserAccountResp.builder()
.imAccount(accountRegister.getImAccount())
.userId(userIdWrapper)
.token(accountRegister.getToken())
.build();
return userAccountResp;
}
private UserAccountResp createNimAccount(String userId, String headImageUrl, String name, String appKey) {
Register register = new Register();
RegisterRequest register = new RegisterRequest();
register.setAccid(userId);
register.setIcon(headImageUrl);
register.setName(name);
register.setAppKey(appKey);
UserAccount userAccount = NimService.registerAccount(register);
UserAccountResp userAccountResp = BeanMapper.map(userAccount, UserAccountResp.class);
return userAccountResp;
//3.调用公共的网易云信IM接口创建账户 网易云信只是一种IM实现
RegisterResponse registerResponse = NimService.registerAccount(register);
if (registerResponse.getInfo() != null) {
UserAccount userAccount = BeanMapper.map(registerResponse.getInfo(), UserAccount.class);
UserAccountResp userAccsountResp = UserAccountResp.builder()
.imAccount(userAccount.getAccid())
.userId(userId)
.token(userAccount.getToken())
.build();
return userAccsountResp;
}
return UserAccountResp.builder().desc(registerResponse.getDesc()).build();
}
public List<UserAccountResp> queryAccountInfo(@Valid AccountQuery accountQuery) {
//如果存在多个appKey一个账户会有多条数据分别对应不同的appKey
List<AccountRegister> accountRegisterList = accountRegisterDao.lambdaQuery().eq(AccountRegister::getIsDelete, 0)
.eq(StringUtils.isNoneBlank(accountQuery.getImAccount()), AccountRegister::getImAccount,
accountQuery.getImAccount())
.eq(StringUtils.isNoneBlank(accountQuery.getAccountId()), AccountRegister::getAccountId,
accountQuery.getAccountId())
.eq(StringUtils.isNoneBlank(accountQuery.getAppType()), AccountRegister::getAppType,
accountQuery.getAppType())
.list();
if (CollectionUtils.isNotEmpty(accountRegisterList)) {
List<UserAccountResp> accountRespList = accountRegisterList.stream().map(accountRegister -> {
UserAccountResp userAccountResp = UserAccountResp.builder()
.userId(accountRegister.getAccountWrapper())
.imAccount(accountRegister.getImAccount()).build();
return userAccountResp;
}).collect(Collectors.toList());
return accountRespList;
}
return null;
}
}

View File

@ -15,6 +15,7 @@ import cn.azxo.framework.common.model.CommonResponse;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@ -36,7 +37,7 @@ public class RobotInfoService {
@Resource
private RobotInfoDao robotInfoDao;
@Transactional(rollbackFor = Exception.class)
public RobotInfoResp saveRobotInfo(@Valid RobotInfoReq robotInfoRequest) {
RobotInfo robotInfo = BeanConvertUtils.copyBean(robotInfoRequest, RobotInfo.class);
robotInfo = robotInfoDao.saveOrUpdateRobotInfo(robotInfo);
@ -46,7 +47,7 @@ public class RobotInfoService {
}
return null;
}
@Transactional(rollbackFor = Exception.class)
public RobotInfoResp updateRobotInfo(@Valid UpdateRobotInfoReq updateRobotInfoReq) {
RobotInfo robotInfo = BeanConvertUtils.copyBean(updateRobotInfoReq, RobotInfo.class);
robotInfo = robotInfoDao.saveOrUpdateRobotInfo(robotInfo);

View File

@ -13,6 +13,7 @@ import cn.axzo.im.utils.BeanConvertUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@ -38,7 +39,7 @@ public class RobotTagService {
@Resource
private RobotInfoDao robotInfoDao;
@Transactional(rollbackFor = Exception.class)
public RobotTagResp saveRobotTag(@Valid RobotTagReq robotTagRequest) {
RobotTag robotTag = BeanConvertUtils.copyBean(robotTagRequest, RobotTag.class);
robotTag = robotTagDao.saveOrUpdateRobotTag(robotTag);
@ -49,6 +50,7 @@ public class RobotTagService {
return null;
}
@Transactional(rollbackFor = Exception.class)
public RobotTagResp updateRobotTag(@Valid UpdateRobotTagReq updateRobotTagReq) {
RobotTag robotTag = BeanConvertUtils.copyBean(updateRobotTagReq, RobotTag.class);
robotTag = robotTagDao.saveOrUpdateRobotTag(robotTag);

View File

@ -12,7 +12,7 @@ spring:
read-unknown-enum-values-as-null: true
mybatis-plus:
#枚举扫描多个package用逗号或者分号分隔
typeEnumsPackage: cn.axzo.maokai.server.common.enums,cn.axzo.basics.common.constant.enums,cn.axzo.pudge.server.common.enums;cn.axzo.pudge.api.enums;cn.axzo.basics.profiles.common.enums;cn.axzo.basics.auth.enums;cn.axzo.basics.common.constant.enums
typeEnumsPackage: cn.axzo.im.center.common.enums,cn.axzo.basics.common.constant.enums,cn.axzo.pudge.server.common.enums;cn.axzo.pudge.api.enums;cn.axzo.basics.profiles.common.enums;cn.axzo.basics.auth.enums;cn.axzo.basics.common.constant.enums
configuration:
auto-mapping-behavior: full
map-underscore-to-camel-case: true

View File

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.axzo.maokai.dao.mapper.OrganizationalJobMapper">
<select id="listUnitJobByType"
resultType="cn.axzo.maokai.dao.entity.dto.UnitJobDto">
select t2.id unitId, t2.type unitType, t1.name jobName, t1.source_code jobSourceCode
from organizational_job t1
right join organizational_unit t2
on t1.organizational_unit_id = t2.id and t1.is_delete = 0 and t2.is_delete = 0
where t2.type = #{type}
</select>
</mapper>

View File

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.axzo.maokai.dao.mapper.OrganizationalNodeMapper">
<select id="listNodeByOuIdsAndNodeIds"
resultType="cn.axzo.maokai.dto.dto.OrganizationNodeUserCountPersonDto">
select
id nodeId,
parent_id parentNodeId,
organizational_unit_id ouId,
node_name nodeName,
node_type nodeTypeEnum,
0 personCount,
`path`
from organizational_node
<where>
is_delete=0 and
(id,organizational_unit_id) in
<foreach collection="queryNodes" item="item" separator="," open="(" close=")">
(#{item.nodeId},#{item.ouId})
</foreach>
</where>
</select>
</mapper>

View File

@ -1,238 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.axzo.maokai.dao.mapper.OrganizationalNodeUserMapper">
<select id="findNodeUserCountByNode"
resultType="cn.axzo.maokai.dto.dto.OrganizationNodeUserCountPersonDto">
SELECT
t3.id ouId,
t3.`name` ouName,
t3.type organizationalUnitTypeEnum,
t2.id nodeId,
t2.node_name nodeName,
t2.node_type nodeTypeEnum,
count(t1.identity_id) personCount,
if(
EXISTS
(SELECT id from organizational_node WHERE parent_id = t2.id and parent_id != id limit 1)
, true,false) hasChild
FROM `organizational_node_user` t1
inner join organizational_node t2 on t1.organizational_node_id = t2.id
inner join organizational_unit t3 on t1.organizational_unit_id = t3.id
<where>
<foreach collection="req" open=" ( " item="query" separator=") or (" close=" )">
t1.organizational_unit_id = #{query.ouId} and t1.organizational_node_id = #{query.nodeId}
<if test="query.identityType !=null">
and t1.identity_type= #{query.identityType}
</if>
</foreach>
</where>
GROUP BY t1.organizational_unit_id ,t1.organizational_node_id
</select>
<select id="findNodeUserCountByParentCount" resultType="cn.axzo.maokai.dto.dto.OrganizationNodeUserCountPersonDto">
SELECT
t3.id ouId,
t3.`name` ouName,
t3.type organizationalUnitTypeEnum,
t2.id nodeId,
t2.node_name nodeName,
t2.node_type nodeTypeEnum,
count(t1.identity_id) personCount,
if(
EXISTS
(SELECT id from organizational_node WHERE parent_id = t2.id and parent_id != id limit 1)
, true,false) hasChild
FROM `organizational_node_user` t1
inner join organizational_node t2 on t1.organizational_node_id = t2.id
inner join organizational_unit t3 on t1.organizational_unit_id = t3.id
<where>
and t1.organizational_unit_id= #{ouId}
and t2.parent_id = #{parentNodeId}
<if test="identityType !=null">
and t1.identity_type= #{identityType}
</if>
</where>
GROUP BY t1.organizational_unit_id ,t1.organizational_node_id
</select>
<select id="listUserCountByNodeIds"
resultType="cn.axzo.maokai.dto.dto.NodePersonCountDTO">
select organizational_node_id nodeId,count(organizational_node_id) `count` from
organizational_node_user
where is_delete=0
<if test="nodeIds!=null and nodeIds.size()>0">
and organizational_node_id in
<foreach collection="nodeIds" item="nodeId" open="(" close=" )" separator=",">
#{nodeId}
</foreach>
</if>
<if test="identityType!=null">
and identity_type=#{identityType}
</if>
group by organizational_unit_id,organizational_node_id
</select>
<select id="listUserCountByNodeIdsAndIdentityTypes"
resultType="cn.axzo.maokai.dto.dto.NodePersonCountDTO">
select organizational_node_id nodeId,count(organizational_node_id) `count` from
organizational_node_user
where is_delete=0
<if test="nodeIds!=null and nodeIds.size()>0">
and organizational_node_id in
<foreach collection="nodeIds" item="nodeId" open="(" close=" )" separator=",">
#{nodeId}
</foreach>
</if>
<if test="identityTypes!=null and identityTypes.size()>0">
and identity_type in
<foreach collection="identityTypes" item="identityType" open="(" close=" )" separator=",">
#{identityType}
</foreach>
</if>
group by organizational_unit_id,organizational_node_id
</select>
<select id="pageOrganizationalUserByKeyword"
resultType="cn.axzo.maokai.dto.dto.OrganizationalNodeUserDTO">
SELECT
nodeUser.id, nodeUser.identity_id, nodeUser.identity_type,
nodeUser.phone, nodeUser.real_name, nodeUser.id_number,
nodeUser.organizational_unit_id,
nodeUser.organizational_node_id,
nodeUser.organizational_job_id, job.`name` as organizational_job_name,
nodeUser.is_allowed, nodeUser.join_at, nodeUser.leave_at,
nodeUser.create_at
FROM organizational_node_user nodeUser
LEFT JOIN organizational_job job ON nodeUser.organizational_job_id = job.id AND job.is_delete = 0
LEFT JOIN organizational_unit unit ON nodeUser.organizational_unit_id = unit.id AND unit.is_delete = 0
<where>
nodeUser.is_delete = 0
and nodeUser.organizational_unit_id = #{query.unitId}
and unit.type = #{query.unitType}
<if test="query.nodeId != null">
and nodeUser.organizational_node_id = #{query.nodeId}
</if>
<if test="query.keyWordType == 1">
and person.real_name like CONCAT('%',#{query.keyWord},'%')
</if>
<if test="query.keyWordType == 2">
and job.`name` like CONCAT('%',#{query.keyWord},'%')
</if>
</where>
group by nodeUser.identity_id, nodeUser.identity_type, nodeUser.organizational_job_id
</select>
<select id="pageUsersByUnitIdAndIdentityType" resultType="cn.axzo.maokai.dto.dto.OrganizationalNodeUserDTO">
SELECT
nodeUser.id, nodeUser.identity_id, nodeUser.identity_type,
nodeUser.phone, nodeUser.real_name, nodeUser.id_number,
nodeUser.organizational_unit_id,
nodeUser.organizational_node_id,
nodeUser.organizational_job_id, job.`name` as organizational_job_name,
nodeUser.is_allowed, nodeUser.join_at, nodeUser.leave_at,
nodeUser.create_at
FROM organizational_node_user nodeUser
LEFT JOIN organizational_job job ON nodeUser.organizational_job_id = job.id AND job.is_delete = 0
LEFT JOIN organizational_unit unit ON nodeUser.organizational_unit_id = unit.id AND unit.is_delete = 0
<where>
nodeUser.is_delete = 0
and nodeUser.organizational_unit_id = #{query.unitId}
and nodeUser.identity_type in
<foreach collection="query.identityTypes" open="(" separator="," close=")" item="identityType">
#{identityType}
</foreach>
<if test="query.nodeId != null">
and nodeUser.organizational_node_id = #{query.nodeId}
</if>
<if test="query.identityId != null">
and nodeUser.identity_id = #{query.identityId}
</if>
</where>
group by nodeUser.identity_id, nodeUser.identity_type, nodeUser.organizational_job_id
</select>
<select id="findNodeUserByTopPathAndIdentityIdAndIdentityType"
resultType="cn.axzo.maokai.dto.dto.OrganizationalNodeUserDTO">
select
nodeUser.id, nodeUser.identity_id, nodeUser.identity_type,
nodeUser.phone, nodeUser.real_name, nodeUser.id_number,
person.avatar_url,
nodeUser.organizational_unit_id,
nodeUser.organizational_node_id, node.node_name as organizational_node_name,
nodeUser.organizational_job_id, job.`name` as organizational_job_name,
nodeUser.is_allowed, nodeUser.join_at, nodeUser.leave_at,
nodeUser.create_at
from organizational_node node
left join organizational_node_user nodeUser
on node.organizational_unit_id = nodeUser.organizational_unit_id and node.id = nodeUser.organizational_node_id
left join organizational_job job on nodeUser.organizational_job_id = job.id and job.is_delete = 0
where node.is_delete = 0 and nodeUser.is_delete = 0
and FIND_IN_SET(#{path}, node.path)
<if test="query.unitId != null">
and node.organizational_unit_id = #{query.unitId}
</if>
and nodeUser.identity_id = #{query.identityId}
and nodeUser.identity_type in
<foreach collection="query.identityTypes" open="(" separator="," close=")" item="identityType">
#{identityType}
</foreach>
</select>
<select id="pageWorkspaceAllNodeUsersByKeyword"
resultType="cn.axzo.maokai.dto.dto.OrganizationalNodeUserDTO">
select
nodeUser.id, nodeUser.identity_id, nodeUser.identity_type,
nodeUser.phone, nodeUser.real_name, nodeUser.id_number,
nodeUser.organizational_unit_id,
nodeUser.organizational_node_id, node.node_name as organizational_node_name,
nodeUser.organizational_job_id, job.`name` as organizational_job_name,
nodeUser.is_allowed, nodeUser.join_at, nodeUser.leave_at,
nodeUser.create_at
FROM organizational_node_user nodeUser
LEFT JOIN organizational_node node on nodeUser.organizational_node_id = node.id
LEFT JOIN organizational_job job ON nodeUser.organizational_job_id = job.id AND job.is_delete = 0
<where>
nodeUser.is_delete = 0
and nodeUser.organizational_unit_id = #{query.unitId}
and FIND_IN_SET(#{query.topNodeId}, node.path)
<if test="query.keyword != '' and query.keyword != null">
and person.real_name like CONCAT('%',#{query.keyword},'%')
</if>
</where>
order by nodeUser.create_at
</select>
<select id="getUserByIdentityIdAndTopNodeIds"
resultType="cn.axzo.maokai.dto.dto.OrganizationalNodeUserDTO">
select
nodeUser.id, nodeUser.identity_id, nodeUser.identity_type,
nodeUser.phone, nodeUser.real_name, nodeUser.id_number,
nodeUser.organizational_unit_id,
nodeUser.organizational_node_id, node.node_name as organizational_node_name,
nodeUser.organizational_job_id, job.`name` as organizational_job_name,
nodeUser.is_allowed, nodeUser.join_at, nodeUser.leave_at,
nodeUser.create_at
FROM organizational_node_user nodeUser
LEFT JOIN organizational_node node on nodeUser.organizational_node_id = node.id
LEFT JOIN organizational_job job ON nodeUser.organizational_job_id = job.id AND job.is_delete = 0
<where>
nodeUser.is_delete = 0
and nodeUser.identity_id = #{query.identityId}
<foreach collection="query.topNodeIds" open="and (" item="topNodeId" separator=" or " close=")">
FIND_IN_SET(#{topNodeId}, node.path)
</foreach>
and nodeUser.identity_type = #{identityType}
</where>
</select>
</mapper>

View File

@ -1,149 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.axzo.maokai.dao.mapper.OrganizationalUnitRegisterMapper">
<select id="pageQueryRegisterHistory" parameterType="cn.axzo.im.center.api.vo.request.OURegisterHistoryPageQueryReq"
resultType="cn.axzo.maokai.dao.entity.OrganizationUnitQualificationApply">
SELECT * FROM
(
SELECT
r.id,
r.`name`,
r.main_body_type AS mainBodyType,
1 AS registerType,
r.submission_time AS submissionTime,
r.approval_status AS approvalStatus,
r.approval_msg AS approvalMsg,
r.contact_name AS contactName,
r.contact_phone AS contactPhone
FROM
organizational_unit_register r
WHERE
r.is_delete = 0
<if test="params.phone != null and params.phone != ''">
AND r.contact_phone = #{params.phone}
</if>
<if test="params.mainBodyType != null and params.mainBodyType != ''">
AND r.main_body_type = #{params.mainBodyType}
</if>
<if test="params.approvalStatus != null">
AND r.approval_status IN
<foreach collection="params.approvalStatus" open="(" close=")" separator="," item="status" index="i">
#{status}
</foreach>
</if>
UNION ALL
SELECT
q.id,
q.ou_name AS `name`,
q.main_body_type AS mainBodyType,
2 AS registerType,
q.create_at AS submissionTime,
q.approval_status AS approvalStatus,
q.approval_msg AS approvalMsg,
q.presenter_name AS contactName,
q.presenter_phone AS contactPhone
FROM
qualifications_apply q
WHERE q.is_delete = 0 AND q.ou_register_id IS NULL
<if test="params.phone != null and params.phone != ''">
AND q.presenter_phone = #{params.phone}
</if>
<if test="params.mainBodyType != null and params.mainBodyType != ''">
AND q.main_body_type = #{params.mainBodyType}
</if>
<if test="params.approvalStatus != null">
AND q.approval_status IN
<foreach collection="params.approvalStatus" open="(" close=")" separator="," item="status" index="i">
#{status}
</foreach>
</if>
) AS t
<where>
<if test="params.nameEquals != null and params.nameEquals != ''">
AND t.`name` = #{params.nameEquals}
</if>
<if test="params.nameLike != null and params.nameLike != ''">
AND t.`name` LIKE CONCAT('%', #{params.nameLike}, '%')
</if>
</where>
ORDER BY t.submissionTime DESC
</select>
<select id="pageQueryRegisterOUHistory" parameterType="cn.axzo.im.center.api.vo.request.OURegisterHistoryPageQueryReq"
resultType="cn.axzo.maokai.dao.entity.OrganizationUnitQualificationApply">
SELECT
r.id,
r.`name`,
r.main_body_type AS mainBodyType,
1 AS registerType,
r.submission_time AS submissionTime,
r.approval_status AS approvalStatus,
r.approval_msg AS approvalMsg,
r.contact_name AS contactName,
r.contact_phone AS contactPhone
FROM
organizational_unit_register r
WHERE
r.is_delete = 0
<if test="params.phone != null and params.phone != ''">
AND r.contact_phone = #{params.phone}
</if>
<if test="params.mainBodyType != null and params.mainBodyType != ''">
AND r.main_body_type = #{params.mainBodyType}
</if>
<if test="params.approvalStatus != null">
AND r.approval_status IN
<foreach collection="params.approvalStatus" open="(" close=")" separator="," item="status" index="i">
#{status}
</foreach>
</if>
<if test="params.nameEquals != null and params.nameEquals != ''">
AND r.`name` = #{params.nameEquals}
</if>
<if test="params.nameLike != null and params.nameLike != ''">
AND r.`name` LIKE CONCAT('%', #{params.nameLike}, '%')
</if>
ORDER BY r.submission_time DESC
</select>
<select id="pageQueryRegisterQFHistory" parameterType="cn.axzo.im.center.api.vo.request.OURegisterHistoryPageQueryReq"
resultType="cn.axzo.maokai.dao.entity.OrganizationUnitQualificationApply">
SELECT
q.id,
q.ou_name AS `name`,
q.main_body_type AS mainBodyType,
2 AS registerType,
q.create_at AS submissionTime,
q.approval_status AS approvalStatus,
q.approval_msg AS approvalMsg,
q.presenter_name AS contactName,
q.presenter_phone AS contactPhone
FROM
qualifications_apply q
WHERE q.is_delete = 0 AND q.ou_register_id IS NULL
<if test="params.phone != null and params.phone != ''">
AND q.presenter_phone = #{params.phone}
</if>
<if test="params.mainBodyType != null and params.mainBodyType != ''">
AND q.main_body_type = #{params.mainBodyType}
</if>
<if test="params.approvalStatus != null">
AND q.approval_status IN
<foreach collection="params.approvalStatus" open="(" close=")" separator="," item="status" index="i">
#{status}
</foreach>
</if>
<if test="params.nameEquals != null and params.nameEquals != ''">
AND q.`ou_name` = #{params.nameEquals}
</if>
<if test="params.nameLike != null and params.nameLike != ''">
AND q.`ou_name` LIKE CONCAT('%', #{params.nameLike}, '%')
</if>
ORDER BY q.create_at DESC
</select>
</mapper>

View File

@ -1,45 +1,59 @@
CREATE TABLE IF NOT EXISTS im_robot_tag(
id bigint auto_increment comment '主键' ,
tag_name varchar(100) not null comment '机器人Tag名称' unique,
weight int default 1 not null comment '机器人Tag排序权重,最小值是1',
status tinyint default 1 not null comment '机器人Tag状态 1、开启、0关闭',
color varchar(10) default '' not null comment '机器人Tag颜色',
is_delete tinyint default 0 not null comment '未删除0,删除id',
create_at datetime default CURRENT_TIMESTAMP not null comment '创建时间',
update_at datetime default CURRENT_TIMESTAMP not null comment '更新时间',
PRIMARY KEY ( `id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8 comment '机器人Tag表';
CREATE TABLE IF NOT EXISTS im_robot_tag
(
id bigint auto_increment comment '主键',
tag_name varchar(100) not null comment '机器人Tag名称' unique,
weight int default 1 not null comment '机器人Tag排序权重,最小值是1',
status tinyint default 1 not null comment '机器人Tag状态 1、开启、0关闭',
color varchar(10) default '' not null comment '机器人Tag颜色',
is_delete tinyint default 0 not null comment '未删除0,删除id',
create_at datetime default CURRENT_TIMESTAMP not null comment '创建时间',
update_at datetime default CURRENT_TIMESTAMP not null comment '更新时间',
PRIMARY KEY (`id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8 comment '机器人Tag表';
create index idx_im_robot_tag
on im_robot_tag (tag_name, status);
CREATE TABLE IF NOT EXISTS im_robot_info(
id bigint auto_increment comment '主键' ,
robot_id varchar(100) not null comment '机器人ID' unique,
nick_name varchar(100) not null comment '机器人名称' unique,
status varchar(50) default '' not null comment '机器人状态',
head_image_url varchar(512) default '' not null comment '机器人头像url',
im_account varchar(100) default '' not null comment '机器人IM账号',
is_delete tinyint default 0 not null comment '未删除0,删除id',
create_at datetime default CURRENT_TIMESTAMP not null comment '创建时间',
update_at datetime default CURRENT_TIMESTAMP not null comment '更新时间',
PRIMARY KEY ( `id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8 comment '机器人信息表';
CREATE TABLE IF NOT EXISTS im_robot_info
(
id bigint auto_increment comment '主键',
robot_id varchar(100) not null comment '机器人ID' unique,
nick_name varchar(100) not null comment '机器人名称' unique,
status varchar(50) default '' not null comment '机器人状态',
head_image_url varchar(512) default '' not null comment '机器人头像url',
im_account varchar(100) default '' not null comment '机器人IM账号',
is_delete tinyint default 0 not null comment '未删除0,删除id',
create_at datetime default CURRENT_TIMESTAMP not null comment '创建时间',
update_at datetime default CURRENT_TIMESTAMP not null comment '更新时间',
PRIMARY KEY (`id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8 comment '机器人信息表';
create index idx_im_robot_info
on im_robot_info (nick_name,im_account,status);
on im_robot_info (nick_name, im_account, status);
create index idx_im_robot_id
on im_robot_info (robot_id);
CREATE TABLE IF NOT EXISTS im_account_register
(
id bigint auto_increment comment '主键',
account_id varchar(100) not null comment '用户账户:机器人robotId、普通用户userId',
account_wrapper varchar(100) not null comment '普通用户,通过appType包装',
app_key varchar(100) not null comment '网易云信app_key',
im_account varchar(100) default '' not null comment '机器人IM账号',
account_type varchar(20) default '' not null comment '账户类型:机器人、普通用户',
app_type varchar(20) default '' not null comment 'App终端类型:WORKER、ENTERPRISE、SYSTEM',
token varchar(100) default '' not null comment '网易云信token',
CREATE TABLE IF NOT EXISTS im_account_info(
id bigint auto_increment comment '主键' ,
user_id varchar(100) not null comment '用户ID、机器人ID' unique,
app_type varchar(512) default '' not null comment 'App终端类型',
im_account varchar(100) default '' not null comment '机器人IM账号',
is_delete tinyint default 0 not null comment '未删除0,删除id',
create_at datetime default CURRENT_TIMESTAMP not null comment '创建时间',
update_at datetime default CURRENT_TIMESTAMP not null comment '更新时间',
PRIMARY KEY ( `id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8 comment '机器人信息表';
is_delete tinyint default 0 not null comment '未删除0,删除id',
create_at datetime default CURRENT_TIMESTAMP not null comment '创建时间',
update_at datetime default CURRENT_TIMESTAMP not null comment '更新时间',
PRIMARY KEY (`id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8 comment 'IM注册账户表';
create index idx_im_account_info
on im_account_info (user_id,im_account);
create index idx_im_account_id
on im_account_register (account_id);
create index idx_im_account_register_id
on im_account_register (im_account);