refactor(ConnectServiceImpl): 优化第三方API集成代码结构

- 提取DingTalk/WeChat API字段名为常量
- 统一语言代码为常量LANGUAGE_ZH_CN
- 优化JSON字段访问方式避免硬编码
- 重构企业微信配置获取逻辑
- 增强代码可读性与维护性
This commit is contained in:
PIGCLOUD committed 2025-11-18 09:38:28 +08:00
1 parent b7c4132765
commit 646859625b
1 file changed
+257 -225
@@ -62,274 +62,306 @@ import java.util.List;
@RequiredArgsConstructor
public class ConnectServiceImpl implements ConnectService {
private final SysSocialDetailsMapper sysSocialDetailsMapper;
private final SysSocialDetailsMapper sysSocialDetailsMapper;
private final SysDeptService sysDeptService;
private final SysDeptService sysDeptService;
private final SysUserService sysUserService;
private final SysUserService sysUserService;
/**
* 同步钉钉部门
* @return Boolean
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean syncDingDept() {
OapiV2DepartmentListsubRequest req = new OapiV2DepartmentListsubRequest();
req.setDeptId(1L);
req.setLanguage("zh_CN");
// JSON field name constants for DingTalk/WeChat API
private static final String FIELD_MOBILE = "mobile";
// 数据库中现有的部门
List<SysDept> deptList = sysDeptService.list(Wrappers.emptyWrapper());
private static final String FIELD_AVATAR = "avatar";
// 查询根部门下的所有部门
List<SysDept> insertDept = queryChildDept(req, getDingAccessToken(), deptList);
private static final String FIELD_NICKNAME = "nickname";
// 去重
private static final String FIELD_NAME = "name";
private static final String FIELD_EMAIL = "email";
private static final String FIELD_DEPT_ID = "dept_id";
private static final String FIELD_PARENT_ID = "parent_id";
private static final String FIELD_DEPT_ORDER_LIST = "dept_order_list";
private static final String FIELD_USERID_LIST = "userid_list";
private static final String FIELD_RESULT = "result";
// WeChat Enterprise config field name constants
private static final String FIELD_AGENT_ID = "agentId";
private static final String FIELD_TOKEN = "token";
private static final String FIELD_AES_KEY = "aesKey";
// Language code constant
private static final String LANGUAGE_ZH_CN = "zh_CN";
/**
* 同步钉钉部门
*
* @return Boolean
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean syncDingDept() {
OapiV2DepartmentListsubRequest req = new OapiV2DepartmentListsubRequest();
req.setDeptId(1L);
req.setLanguage(LANGUAGE_ZH_CN);
// 数据库中现有的部门
List<SysDept> deptList = sysDeptService.list(Wrappers.emptyWrapper());
// 查询根部门下的所有部门
List<SysDept> insertDept = queryChildDept(req, getDingAccessToken(), deptList);
// 去重
List<SysDept> syncDept = insertDept.stream().distinct().toList();
// 保存部门以及部门关系
if (CollectionUtils.isNotEmpty(syncDept)) {
syncDept.forEach(sysDeptService::save);
}
// 保存部门以及部门关系
if (CollectionUtils.isNotEmpty(syncDept)) {
syncDept.forEach(sysDeptService::save);
}
return Boolean.TRUE;
}
return Boolean.TRUE;
}
/**
* 同步部门下的钉钉用户
* @param deptId 部门ID
* @return R
*/
@SneakyThrows
@Override
@Transactional(rollbackFor = Exception.class)
public R syncDingUser(Long deptId) {
// 数据库中现有用户
List<SysUser> users = sysUserService.list(Wrappers.emptyWrapper());
/**
* 同步部门下的钉钉用户
*
* @param deptId 部门ID
* @return R
*/
@SneakyThrows
@Override
@Transactional(rollbackFor = Exception.class)
public R syncDingUser(Long deptId) {
// 数据库中现有用户
List<SysUser> users = sysUserService.list(Wrappers.emptyWrapper());
String token = getDingAccessToken();
String token = getDingAccessToken();
// 查询部门下的用户id列表
DingTalkClient client = new DefaultDingTalkClient(SecurityConstants.DING_DEPT_USERIDS_URL);
OapiUserListidRequest req = new OapiUserListidRequest();
req.setDeptId(deptId);
OapiUserListidResponse rsp = client.execute(req, token);
// 查询部门下的用户id列表
DingTalkClient client = new DefaultDingTalkClient(SecurityConstants.DING_DEPT_USERIDS_URL);
OapiUserListidRequest req = new OapiUserListidRequest();
req.setDeptId(deptId);
OapiUserListidResponse rsp = client.execute(req, token);
JSONObject jsonObject = JSONUtil.parseObj(rsp.getBody());
JSONObject result = jsonObject.getJSONObject("result");
JSONObject jsonObject = JSONUtil.parseObj(rsp.getBody());
JSONObject result = jsonObject.getJSONObject(FIELD_RESULT);
if (result == null) {
return R.ok();
}
List<String> useridList = result.get("userid_list", List.class);
if (result == null) {
return R.ok();
}
List<String> useridList = result.get(FIELD_USERID_LIST, List.class);
// 查询用户详情
for (String userid : useridList) {
DingTalkClient userClient = new DefaultDingTalkClient(SecurityConstants.DING_USER_INFO_URL);
OapiV2UserGetRequest userGetRequest = new OapiV2UserGetRequest();
userGetRequest.setUserid(userid);
OapiV2UserGetResponse userGetResponse = userClient.execute(userGetRequest, token);
JSONObject userResult = JSONUtil.parseObj(userGetResponse.getBody());
JSONObject userObj = JSONUtil.parseObj(userResult.get("result"));
// 查询用户详情
for (String userid : useridList) {
DingTalkClient userClient = new DefaultDingTalkClient(SecurityConstants.DING_USER_INFO_URL);
OapiV2UserGetRequest userGetRequest = new OapiV2UserGetRequest();
userGetRequest.setUserid(userid);
OapiV2UserGetResponse userGetResponse = userClient.execute(userGetRequest, token);
JSONObject userResult = JSONUtil.parseObj(userGetResponse.getBody());
JSONObject userObj = JSONUtil.parseObj(userResult.get(FIELD_RESULT));
boolean exist = users.stream()
.filter(user -> StrUtil.isNotBlank(user.getPhone()))
.anyMatch(user -> user.getPhone().equals(userObj.getStr("mobile")));
boolean exist = users.stream()
.filter(user -> StrUtil.isNotBlank(user.getPhone()))
.anyMatch(user -> user.getPhone().equals(userObj.getStr(FIELD_MOBILE)));
if (exist || StrUtil.isBlank(userObj.getStr("mobile"))) {
log.info("用户已存在或手机号不合法 {}", userid);
continue;
}
if (exist || StrUtil.isBlank(userObj.getStr(FIELD_MOBILE))) {
log.info("用户已存在或手机号不合法 {}", userid);
continue;
}
// 用户部门信息
JSONArray deptOrders = userObj.getJSONArray("dept_order_list");
JSONObject deptInfo = (JSONObject) deptOrders.get(0);
// 用户部门信息
JSONArray deptOrders = userObj.getJSONArray(FIELD_DEPT_ORDER_LIST);
JSONObject deptInfo = (JSONObject) deptOrders.get(0);
// 用户信息
UserDTO userDTO = new UserDTO();
userDTO.setDeptId(deptInfo.getLong("dept_id"));
userDTO.setAvatar(userObj.getStr("avatar"));
userDTO.setUsername(userObj.getStr("mobile"));
userDTO.setPhone(userObj.getStr("mobile"));
userDTO.setNickname(userObj.getStr("nickname"));
userDTO.setName(userObj.getStr("name"));
userDTO.setEmail(userObj.getStr("email"));
// 初始化密码为 手机号
userDTO.setPassword(userObj.getStr("mobile"));
userDTO.setPasswordModifyTime(LocalDateTime.now());
sysUserService.saveUser(userDTO);
}
// 用户信息
UserDTO userDTO = new UserDTO();
userDTO.setDeptId(deptInfo.getLong(FIELD_DEPT_ID));
userDTO.setAvatar(userObj.getStr(FIELD_AVATAR));
userDTO.setUsername(userObj.getStr(FIELD_MOBILE));
userDTO.setPhone(userObj.getStr(FIELD_MOBILE));
userDTO.setNickname(userObj.getStr(FIELD_NICKNAME));
userDTO.setName(userObj.getStr(FIELD_NAME));
userDTO.setEmail(userObj.getStr(FIELD_EMAIL));
// 初始化密码为 手机号
userDTO.setPassword(userObj.getStr(FIELD_MOBILE));
userDTO.setPasswordModifyTime(LocalDateTime.now());
sysUserService.saveUser(userDTO);
}
return R.ok();
}
return R.ok();
}
/**
* 同步企微部门
* @return R
*/
@Override
@Transactional(rollbackFor = Exception.class)
public R<Boolean> syncCpDept() {
WxCpService wxCpService = new WxCpServiceImpl();
wxCpService.setWxCpConfigStorage(getCpConfig());
/**
* 同步企微部门
*
* @return R
*/
@Override
@Transactional(rollbackFor = Exception.class)
public R<Boolean> syncCpDept() {
WxCpService wxCpService = new WxCpServiceImpl();
wxCpService.setWxCpConfigStorage(getCpConfig());
List<WxCpDepart> departList;
try {
departList = wxCpService.getDepartmentService().list(null);
}
catch (WxErrorException e) {
log.error("获取企业微信部门列表失败", e);
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_CONNECT_CP_DEPT_SYNC_ERROR));
}
List<WxCpDepart> departList;
try {
departList = wxCpService.getDepartmentService().list(null);
} catch (WxErrorException e) {
log.error("获取企业微信部门列表失败", e);
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_CONNECT_CP_DEPT_SYNC_ERROR));
}
if (CollUtil.isEmpty(departList)) {
return R.ok();
}
if (CollUtil.isEmpty(departList)) {
return R.ok();
}
// 数据库中现有的部门
List<SysDept> deptList = sysDeptService.list(Wrappers.emptyWrapper());
departList.stream()
.filter(depart -> deptList.stream().noneMatch(sysDept -> depart.getName().equals(sysDept.getName())))
.map(dept -> {
SysDept sysDept = new SysDept();
sysDept.setName(dept.getName());
sysDept.setDeptId(dept.getId());
sysDept.setParentId(dept.getParentId());
sysDept.setSortOrder(dept.getOrder().intValue());
return sysDept;
})
.forEach(sysDeptService::save);
return R.ok();
}
// 数据库中现有的部门
List<SysDept> deptList = sysDeptService.list(Wrappers.emptyWrapper());
departList.stream()
.filter(depart -> deptList.stream().noneMatch(sysDept -> depart.getName().equals(sysDept.getName())))
.map(dept -> {
SysDept sysDept = new SysDept();
sysDept.setName(dept.getName());
sysDept.setDeptId(dept.getId());
sysDept.setParentId(dept.getParentId());
sysDept.setSortOrder(dept.getOrder().intValue());
return sysDept;
})
.forEach(sysDeptService::save);
return R.ok();
}
/**
* 同步企微用户
* @return R
*/
@Override
public R<Boolean> syncCpUser() {
WxCpService wxCpService = new WxCpServiceImpl();
wxCpService.setWxCpConfigStorage(getCpConfig());
/**
* 同步企微用户
*
* @return R
*/
@Override
public R<Boolean> syncCpUser() {
WxCpService wxCpService = new WxCpServiceImpl();
wxCpService.setWxCpConfigStorage(getCpConfig());
List<WxCpUser> cpUserList;
try {
cpUserList = wxCpService.getUserService().listByDepartment(1L, true, 0);
}
catch (WxErrorException e) {
log.error("获取企业微信用户列表失败", e);
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_CONNECT_CP_USER_SYNC_ERROR));
}
List<WxCpUser> cpUserList;
try {
cpUserList = wxCpService.getUserService().listByDepartment(1L, true, 0);
} catch (WxErrorException e) {
log.error("获取企业微信用户列表失败", e);
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_CONNECT_CP_USER_SYNC_ERROR));
}
if (CollUtil.isEmpty(cpUserList)) {
return R.ok();
}
if (CollUtil.isEmpty(cpUserList)) {
return R.ok();
}
// 系统原有用户
List<SysUser> userList = sysUserService.list(Wrappers.emptyWrapper());
// 系统原有用户
List<SysUser> userList = sysUserService.list(Wrappers.emptyWrapper());
for (WxCpUser cpUser : cpUserList) {
boolean exist = userList.stream()
.filter(user -> StrUtil.isNotBlank(user.getPhone()))
.anyMatch(user -> user.getPhone().equals(cpUser.getMobile()));
if (exist || StrUtil.isBlank(cpUser.getMobile())) {
log.info("用户已存在或手机号不合法跳过 {}", cpUser);
continue;
}
for (WxCpUser cpUser : cpUserList) {
boolean exist = userList.stream()
.filter(user -> StrUtil.isNotBlank(user.getPhone()))
.anyMatch(user -> user.getPhone().equals(cpUser.getMobile()));
if (exist || StrUtil.isBlank(cpUser.getMobile())) {
log.info("用户已存在或手机号不合法跳过 {}", cpUser);
continue;
}
UserDTO user = new UserDTO();
user.setUsername(cpUser.getMobile());
user.setName(cpUser.getName());
user.setDeptId(cpUser.getDepartIds()[0]);
user.setEmail(cpUser.getEmail());
user.setPhone(cpUser.getMobile());
user.setAvatar(cpUser.getAvatar());
// 初始化密码为 手机号
user.setPassword(cpUser.getMobile());
sysUserService.saveUser(user);
}
UserDTO user = new UserDTO();
user.setUsername(cpUser.getMobile());
user.setName(cpUser.getName());
user.setDeptId(cpUser.getDepartIds()[0]);
user.setEmail(cpUser.getEmail());
user.setPhone(cpUser.getMobile());
user.setAvatar(cpUser.getAvatar());
// 初始化密码为 手机号
user.setPassword(cpUser.getMobile());
sysUserService.saveUser(user);
}
return R.ok();
}
return R.ok();
}
private String getDingAccessToken() {
SysSocialDetails dingTalk = sysSocialDetailsMapper.selectOne(Wrappers.<SysSocialDetails>lambdaQuery()
.eq(SysSocialDetails::getType, LoginTypeEnum.DINGTALK.getType()));
private String getDingAccessToken() {
SysSocialDetails dingTalk = sysSocialDetailsMapper.selectOne(Wrappers.<SysSocialDetails>lambdaQuery()
.eq(SysSocialDetails::getType, LoginTypeEnum.DINGTALK.getType()));
DingTalkClient client = new DefaultDingTalkClient(SecurityConstants.DING_OLD_GET_TOKEN);
OapiGettokenRequest request = new OapiGettokenRequest();
request.setAppkey(dingTalk.getAppId());
request.setAppsecret(dingTalk.getAppSecret());
request.setHttpMethod(HttpMethod.GET.name());
try {
OapiGettokenResponse response = client.execute(request);
return response.getAccessToken();
}
catch (Exception e) {
log.error("调用钉钉异常", e);
}
return null;
}
DingTalkClient client = new DefaultDingTalkClient(SecurityConstants.DING_OLD_GET_TOKEN);
OapiGettokenRequest request = new OapiGettokenRequest();
request.setAppkey(dingTalk.getAppId());
request.setAppsecret(dingTalk.getAppSecret());
request.setHttpMethod(HttpMethod.GET.name());
try {
OapiGettokenResponse response = client.execute(request);
return response.getAccessToken();
} catch (Exception e) {
log.error("调用钉钉异常", e);
}
return null;
}
public WxCpDefaultConfigImpl getCpConfig() {
SysSocialDetails cp = sysSocialDetailsMapper.selectOne(Wrappers.<SysSocialDetails>lambdaQuery()
.eq(SysSocialDetails::getType, LoginTypeEnum.WEIXIN_CP.getType()));
public WxCpDefaultConfigImpl getCpConfig() {
SysSocialDetails cp = sysSocialDetailsMapper.selectOne(Wrappers.<SysSocialDetails>lambdaQuery()
.eq(SysSocialDetails::getType, LoginTypeEnum.WEIXIN_CP.getType()));
WxCpDefaultConfigImpl config = new WxCpDefaultConfigImpl();
config.setCorpId(cp.getAppId()); // 设置微信企业号的appid
config.setCorpSecret(cp.getAppSecret()); // 设置微信企业号的app
// corpSecret
JSONObject ext = JSONUtil.parseObj(cp.getExt());
config.setAgentId(ext.getInt("agentId")); // 设置微信企业号应用ID
config.setToken(ext.getStr("token")); // 设置微信企业号应用的token
config.setAesKey(ext.getStr("aesKey")); // 设置微信企业号应用的EncodingAESKey
WxCpDefaultConfigImpl config = new WxCpDefaultConfigImpl();
config.setCorpId(cp.getAppId()); // 设置微信企业号的appid
config.setCorpSecret(cp.getAppSecret()); // 设置微信企业号的app
// corpSecret
JSONObject ext = JSONUtil.parseObj(cp.getExt());
config.setAgentId(ext.getInt(FIELD_AGENT_ID)); // 设置微信企业号应用ID
config.setToken(ext.getStr(FIELD_TOKEN)); // 设置微信企业号应用的token
config.setAesKey(ext.getStr(FIELD_AES_KEY)); // 设置微信企业号应用的EncodingAESKey
return config;
}
return config;
}
/**
* 查询当前部门下的所有部门
*/
@SneakyThrows
private List<SysDept> queryChildDept(OapiV2DepartmentListsubRequest req, String token, List<SysDept> deptList) {
List<SysDept> sysDepts = new LinkedList<>();
/**
* 查询当前部门下的所有部门
*/
@SneakyThrows
private List<SysDept> queryChildDept(OapiV2DepartmentListsubRequest req, String token, List<SysDept> deptList) {
List<SysDept> sysDepts = new LinkedList<>();
// 调用Api查询
DingTalkClient client = new DefaultDingTalkClient(SecurityConstants.DING_OLD_DEPT_URL);
OapiV2DepartmentListsubResponse rsp = client.execute(req, token);
// 调用Api查询
DingTalkClient client = new DefaultDingTalkClient(SecurityConstants.DING_OLD_DEPT_URL);
OapiV2DepartmentListsubResponse rsp = client.execute(req, token);
JSONObject result = JSONUtil.parseObj(rsp.getBody());
List<JSONObject> resultList = result.get("result", List.class);
JSONObject result = JSONUtil.parseObj(rsp.getBody());
List<JSONObject> resultList = result.get(FIELD_RESULT, List.class);
if (CollUtil.isEmpty(resultList)) {
return sysDepts;
}
if (CollUtil.isEmpty(resultList)) {
return sysDepts;
}
// 过滤出数据库存在的部门
List<SysDept> depts = resultList.stream()
.filter(dept -> deptList.stream().noneMatch(sysDept -> sysDept.getName().equals(dept.get("name"))))
.map(dept -> {
SysDept sysDept = new SysDept();
sysDept.setName(Convert.toStr(dept.get("name")));
sysDept.setDeptId(Convert.toLong(dept.get("dept_id")));
sysDept.setParentId(Convert.toLong(dept.get("parent_id")));
return sysDept;
})
// 过滤出数据库存在的部门
List<SysDept> depts = resultList.stream()
.filter(dept -> deptList.stream().noneMatch(sysDept -> sysDept.getName().equals(dept.get(FIELD_NAME))))
.map(dept -> {
SysDept sysDept = new SysDept();
sysDept.setName(Convert.toStr(dept.get(FIELD_NAME)));
sysDept.setDeptId(Convert.toLong(dept.get(FIELD_DEPT_ID)));
sysDept.setParentId(Convert.toLong(dept.get(FIELD_PARENT_ID)));
return sysDept;
})
.toList();
// 递归查询下一级
if (CollectionUtils.isNotEmpty(depts)) {
sysDepts.addAll(depts);
depts.forEach(dept -> {
OapiV2DepartmentListsubRequest request = new OapiV2DepartmentListsubRequest();
request.setDeptId(dept.getDeptId());
request.setLanguage("zh_CN");
List<SysDept> childDept = queryChildDept(request, token, deptList);
sysDepts.addAll(childDept);
});
}
// 递归查询下一级
if (CollectionUtils.isNotEmpty(depts)) {
sysDepts.addAll(depts);
depts.forEach(dept -> {
OapiV2DepartmentListsubRequest request = new OapiV2DepartmentListsubRequest();
request.setDeptId(dept.getDeptId());
request.setLanguage(LANGUAGE_ZH_CN);
List<SysDept> childDept = queryChildDept(request, token, deptList);
sysDepts.addAll(childDept);
});
}
return sysDepts;
}
return sysDepts;
}
}