mirror of
https://github.com/jeecgboot/JeecgBoot.git
synced 2025-12-31 17:15:29 +08:00
JeecgBoot低代码平台 2.4.5 版本发布,钉钉与企业微信集成版本
This commit is contained in:
@ -1,18 +1,14 @@
|
||||
package org.jeecg.modules.quartz.controller;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.util.ImportExcelUtil;
|
||||
import org.jeecg.modules.quartz.entity.QuartzJob;
|
||||
@ -22,28 +18,21 @@ import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||
import org.quartz.JobKey;
|
||||
import org.quartz.Scheduler;
|
||||
import org.quartz.SchedulerException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Description: 定时任务在线管理
|
||||
@ -89,10 +78,6 @@ public class QuartzJobController {
|
||||
//@RequiresRoles("admin")
|
||||
@RequestMapping(value = "/add", method = RequestMethod.POST)
|
||||
public Result<?> add(@RequestBody QuartzJob quartzJob) {
|
||||
List<QuartzJob> list = quartzJobService.findByJobClassName(quartzJob.getJobClassName());
|
||||
if (list != null && list.size() > 0) {
|
||||
return Result.error("该定时任务类名已存在");
|
||||
}
|
||||
quartzJobService.saveAndScheduleJob(quartzJob);
|
||||
return Result.ok("创建定时任务成功");
|
||||
}
|
||||
@ -155,15 +140,14 @@ public class QuartzJobController {
|
||||
/**
|
||||
* 暂停定时任务
|
||||
*
|
||||
* @param jobClassName
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
//@RequiresRoles("admin")
|
||||
@GetMapping(value = "/pause")
|
||||
@ApiOperation(value = "暂停定时任务")
|
||||
public Result<Object> pauseJob(@RequestParam(name = "jobClassName", required = true) String jobClassName) {
|
||||
QuartzJob job = null;
|
||||
job = quartzJobService.getOne(new LambdaQueryWrapper<QuartzJob>().eq(QuartzJob::getJobClassName, jobClassName));
|
||||
public Result<Object> pauseJob(@RequestParam(name = "id") String id) {
|
||||
QuartzJob job = quartzJobService.getById(id);
|
||||
if (job == null) {
|
||||
return Result.error("定时任务不存在!");
|
||||
}
|
||||
@ -174,14 +158,14 @@ public class QuartzJobController {
|
||||
/**
|
||||
* 启动定时任务
|
||||
*
|
||||
* @param jobClassName
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
//@RequiresRoles("admin")
|
||||
@GetMapping(value = "/resume")
|
||||
@ApiOperation(value = "恢复定时任务")
|
||||
public Result<Object> resumeJob(@RequestParam(name = "jobClassName", required = true) String jobClassName) {
|
||||
QuartzJob job = quartzJobService.getOne(new LambdaQueryWrapper<QuartzJob>().eq(QuartzJob::getJobClassName, jobClassName));
|
||||
public Result<Object> resumeJob(@RequestParam(name = "id") String id) {
|
||||
QuartzJob job = quartzJobService.getById(id);
|
||||
if (job == null) {
|
||||
return Result.error("定时任务不存在!");
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ public class SampleParamJob implements Job {
|
||||
|
||||
@Override
|
||||
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
|
||||
|
||||
log.info(String.format("welcome %s! Jeecg-Boot 带参数定时任务 SampleParamJob ! 时间:" + DateUtils.now(), this.parameter));
|
||||
log.info(" Job Execution key:"+jobExecutionContext.getJobDetail().getKey());
|
||||
log.info( String.format("welcome %s! Jeecg-Boot 带参数定时任务 SampleParamJob ! 时间:" + DateUtils.now(), this.parameter));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
package org.jeecg.modules.quartz.service.impl;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
import org.jeecg.common.util.DateUtils;
|
||||
@ -13,9 +12,8 @@ import org.quartz.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description: 定时任务在线管理
|
||||
@ -46,13 +44,16 @@ public class QuartzJobServiceImpl extends ServiceImpl<QuartzJobMapper, QuartzJob
|
||||
*/
|
||||
@Override
|
||||
public boolean saveAndScheduleJob(QuartzJob quartzJob) {
|
||||
if (CommonConstant.STATUS_NORMAL.equals(quartzJob.getStatus())) {
|
||||
// 定时器添加
|
||||
this.schedulerAdd(quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
|
||||
}
|
||||
// DB设置修改
|
||||
quartzJob.setDelFlag(CommonConstant.DEL_FLAG_0);
|
||||
return this.save(quartzJob);
|
||||
boolean success = this.save(quartzJob);
|
||||
if (success) {
|
||||
if (CommonConstant.STATUS_NORMAL.equals(quartzJob.getStatus())) {
|
||||
// 定时器添加
|
||||
this.schedulerAdd(quartzJob.getId(), quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -60,8 +61,8 @@ public class QuartzJobServiceImpl extends ServiceImpl<QuartzJobMapper, QuartzJob
|
||||
*/
|
||||
@Override
|
||||
public boolean resumeJob(QuartzJob quartzJob) {
|
||||
schedulerDelete(quartzJob.getJobClassName().trim());
|
||||
schedulerAdd(quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
|
||||
schedulerDelete(quartzJob.getId());
|
||||
schedulerAdd(quartzJob.getId(), quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
|
||||
quartzJob.setStatus(CommonConstant.STATUS_NORMAL);
|
||||
return this.updateById(quartzJob);
|
||||
}
|
||||
@ -73,10 +74,10 @@ public class QuartzJobServiceImpl extends ServiceImpl<QuartzJobMapper, QuartzJob
|
||||
@Override
|
||||
public boolean editAndScheduleJob(QuartzJob quartzJob) throws SchedulerException {
|
||||
if (CommonConstant.STATUS_NORMAL.equals(quartzJob.getStatus())) {
|
||||
schedulerDelete(quartzJob.getJobClassName().trim());
|
||||
schedulerAdd(quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
|
||||
schedulerDelete(quartzJob.getId());
|
||||
schedulerAdd(quartzJob.getId(), quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
|
||||
}else{
|
||||
scheduler.pauseJob(JobKey.jobKey(quartzJob.getJobClassName().trim()));
|
||||
scheduler.pauseJob(JobKey.jobKey(quartzJob.getId()));
|
||||
}
|
||||
return this.updateById(quartzJob);
|
||||
}
|
||||
@ -86,7 +87,7 @@ public class QuartzJobServiceImpl extends ServiceImpl<QuartzJobMapper, QuartzJob
|
||||
*/
|
||||
@Override
|
||||
public boolean deleteAndStopJob(QuartzJob job) {
|
||||
schedulerDelete(job.getJobClassName().trim());
|
||||
schedulerDelete(job.getId());
|
||||
boolean ok = this.removeById(job.getId());
|
||||
return ok;
|
||||
}
|
||||
@ -98,7 +99,9 @@ public class QuartzJobServiceImpl extends ServiceImpl<QuartzJobMapper, QuartzJob
|
||||
String ymd = DateUtils.date2Str(startDate,DateUtils.yyyymmddhhmmss.get());
|
||||
String identity = jobName + ymd;
|
||||
//3秒后执行 只执行一次
|
||||
startDate.setTime(startDate.getTime()+3000L);
|
||||
// update-begin--author:sunjianlei ---- date:20210511--- for:定时任务立即执行,延迟3秒改成0.1秒-------
|
||||
startDate.setTime(startDate.getTime() + 100L);
|
||||
// update-end--author:sunjianlei ---- date:20210511--- for:定时任务立即执行,延迟3秒改成0.1秒-------
|
||||
// 定义一个Trigger
|
||||
SimpleTrigger trigger = (SimpleTrigger)TriggerBuilder.newTrigger()
|
||||
.withIdentity(identity, JOB_TEST_GROUP)
|
||||
@ -114,31 +117,31 @@ public class QuartzJobServiceImpl extends ServiceImpl<QuartzJobMapper, QuartzJob
|
||||
|
||||
@Override
|
||||
public void pause(QuartzJob quartzJob){
|
||||
schedulerDelete(quartzJob.getJobClassName().trim());
|
||||
schedulerDelete(quartzJob.getId());
|
||||
quartzJob.setStatus(CommonConstant.STATUS_DISABLE);
|
||||
this.updateById(quartzJob);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加定时任务
|
||||
*
|
||||
*
|
||||
* @param jobClassName
|
||||
* @param cronExpression
|
||||
* @param parameter
|
||||
*/
|
||||
private void schedulerAdd(String jobClassName, String cronExpression, String parameter) {
|
||||
private void schedulerAdd(String id, String jobClassName, String cronExpression, String parameter) {
|
||||
try {
|
||||
// 启动调度器
|
||||
scheduler.start();
|
||||
|
||||
// 构建job信息
|
||||
JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass()).withIdentity(jobClassName).usingJobData("parameter", parameter).build();
|
||||
JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass()).withIdentity(id).usingJobData("parameter", parameter).build();
|
||||
|
||||
// 表达式调度构建器(即任务执行的时间)
|
||||
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
|
||||
|
||||
// 按新的cronExpression表达式构建一个新的trigger
|
||||
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobClassName).withSchedule(scheduleBuilder).build();
|
||||
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(id).withSchedule(scheduleBuilder).build();
|
||||
|
||||
scheduler.scheduleJob(jobDetail, trigger);
|
||||
} catch (SchedulerException e) {
|
||||
@ -153,13 +156,13 @@ public class QuartzJobServiceImpl extends ServiceImpl<QuartzJobMapper, QuartzJob
|
||||
/**
|
||||
* 删除定时任务
|
||||
*
|
||||
* @param jobClassName
|
||||
* @param id
|
||||
*/
|
||||
private void schedulerDelete(String jobClassName) {
|
||||
private void schedulerDelete(String id) {
|
||||
try {
|
||||
scheduler.pauseTrigger(TriggerKey.triggerKey(jobClassName));
|
||||
scheduler.unscheduleJob(TriggerKey.triggerKey(jobClassName));
|
||||
scheduler.deleteJob(JobKey.jobKey(jobClassName));
|
||||
scheduler.pauseTrigger(TriggerKey.triggerKey(id));
|
||||
scheduler.unscheduleJob(TriggerKey.triggerKey(id));
|
||||
scheduler.deleteJob(JobKey.jobKey(id));
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
throw new JeecgBootException("删除定时任务失败");
|
||||
|
||||
@ -133,7 +133,7 @@ public class CommonController {
|
||||
String orgName = mf.getOriginalFilename();// 获取文件名
|
||||
orgName = CommonUtils.getFileName(orgName);
|
||||
if(orgName.indexOf(".")!=-1){
|
||||
fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.indexOf("."));
|
||||
fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."));
|
||||
}else{
|
||||
fileName = orgName+ "_" + System.currentTimeMillis();
|
||||
}
|
||||
|
||||
@ -1,54 +1,54 @@
|
||||
package org.jeecg.modules.system.controller;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.constant.CommonSendStatus;
|
||||
import org.jeecg.common.constant.WebsocketConst;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.system.util.JwtUtil;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.message.websocket.WebSocket;
|
||||
import org.jeecg.modules.system.entity.SysAnnouncement;
|
||||
import org.jeecg.modules.system.entity.SysAnnouncementSend;
|
||||
import org.jeecg.modules.system.service.ISysAnnouncementSendService;
|
||||
import org.jeecg.modules.system.service.ISysAnnouncementService;
|
||||
|
||||
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
|
||||
import com.jeecg.dingtalk.api.core.response.Response;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.constant.CommonSendStatus;
|
||||
import org.jeecg.common.constant.WebsocketConst;
|
||||
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||
import org.jeecg.common.system.util.JwtUtil;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.RedisUtil;
|
||||
import org.jeecg.common.util.TokenUtils;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.message.websocket.WebSocket;
|
||||
import org.jeecg.modules.system.entity.SysAnnouncement;
|
||||
import org.jeecg.modules.system.entity.SysAnnouncementSend;
|
||||
import org.jeecg.modules.system.service.ISysAnnouncementSendService;
|
||||
import org.jeecg.modules.system.service.ISysAnnouncementService;
|
||||
import org.jeecg.modules.system.service.impl.ThirdAppDingtalkServiceImpl;
|
||||
import org.jeecg.modules.system.service.impl.ThirdAppWechatEnterpriseServiceImpl;
|
||||
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jeecg.common.constant.CommonConstant.ANNOUNCEMENT_SEND_STATUS_1;
|
||||
|
||||
/**
|
||||
* @Title: Controller
|
||||
@ -67,6 +67,15 @@ public class SysAnnouncementController {
|
||||
private ISysAnnouncementSendService sysAnnouncementSendService;
|
||||
@Resource
|
||||
private WebSocket webSocket;
|
||||
@Autowired
|
||||
ThirdAppWechatEnterpriseServiceImpl wechatEnterpriseService;
|
||||
@Autowired
|
||||
ThirdAppDingtalkServiceImpl dingtalkService;
|
||||
@Autowired
|
||||
private ISysBaseAPI sysBaseAPI;
|
||||
@Autowired
|
||||
@Lazy
|
||||
private RedisUtil redisUtil;
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
@ -242,6 +251,19 @@ public class SysAnnouncementController {
|
||||
obj.put(WebsocketConst.MSG_TXT, sysAnnouncement.getTitile());
|
||||
webSocket.sendMessage(userIds, obj.toJSONString());
|
||||
}
|
||||
try {
|
||||
// 同步企业微信、钉钉的消息通知
|
||||
Response<String> dtResponse = dingtalkService.sendActionCardMessage(sysAnnouncement, true);
|
||||
wechatEnterpriseService.sendTextCardMessage(sysAnnouncement, true);
|
||||
|
||||
if (dtResponse != null && dtResponse.isSuccess()) {
|
||||
String taskId = dtResponse.getResult();
|
||||
sysAnnouncement.setDtTaskId(taskId);
|
||||
sysAnnouncementService.updateById(sysAnnouncement);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("同步发送第三方APP消息失败:", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -265,6 +287,13 @@ public class SysAnnouncementController {
|
||||
boolean ok = sysAnnouncementService.updateById(sysAnnouncement);
|
||||
if(ok) {
|
||||
result.success("该系统通知撤销成功");
|
||||
if (oConvertUtils.isNotEmpty(sysAnnouncement.getDtTaskId())) {
|
||||
try {
|
||||
dingtalkService.recallMessage(sysAnnouncement.getDtTaskId());
|
||||
} catch (Exception e) {
|
||||
log.error("第三方APP撤回消息失败:", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -423,4 +452,33 @@ public class SysAnnouncementController {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通告查看详情页面(用于第三方APP)
|
||||
* @param modelAndView
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/show/{id}")
|
||||
public ModelAndView showContent(ModelAndView modelAndView, @PathVariable("id") String id, HttpServletRequest request) {
|
||||
SysAnnouncement announcement = sysAnnouncementService.getById(id);
|
||||
if (announcement != null) {
|
||||
boolean tokenOK = false;
|
||||
try {
|
||||
// 验证Token有效性
|
||||
tokenOK = TokenUtils.verifyToken(request, sysBaseAPI, redisUtil);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
// 判断是否传递了Token,并且Token有效,如果传了就不做查看限制,直接返回
|
||||
// 如果Token无效,就做查看限制:只能查看已发布的
|
||||
if (tokenOK || ANNOUNCEMENT_SEND_STATUS_1.equals(announcement.getSendStatus())) {
|
||||
modelAndView.addObject("data", announcement);
|
||||
modelAndView.setViewName("announcement/showContent");
|
||||
return modelAndView;
|
||||
}
|
||||
}
|
||||
modelAndView.setStatus(HttpStatus.NOT_FOUND);
|
||||
return modelAndView;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -409,10 +409,11 @@ public class SysCategoryController {
|
||||
* 分类字典控件数据回显[表单页面]
|
||||
*
|
||||
* @param ids
|
||||
* @param delNotExist 是否移除不存在的项,默认为true,设为false如果某个key不存在数据库中,则直接返回key本身
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/loadDictItem", method = RequestMethod.GET)
|
||||
public Result<List<String>> loadDictItem(@RequestParam(name = "ids") String ids) {
|
||||
public Result<List<String>> loadDictItem(@RequestParam(name = "ids") String ids, @RequestParam(name = "delNotExist", required = false, defaultValue = "true") boolean delNotExist) {
|
||||
Result<List<String>> result = new Result<>();
|
||||
// 非空判断
|
||||
if (StringUtils.isBlank(ids)) {
|
||||
@ -420,13 +421,8 @@ public class SysCategoryController {
|
||||
result.setMessage("ids 不能为空");
|
||||
return result;
|
||||
}
|
||||
String[] idArray = ids.split(",");
|
||||
LambdaQueryWrapper<SysCategory> query = new LambdaQueryWrapper<>();
|
||||
query.in(SysCategory::getId, Arrays.asList(idArray));
|
||||
// 查询数据
|
||||
List<SysCategory> list = this.sysCategoryService.list(query);
|
||||
// 取出name并返回
|
||||
List<String> textList = list.stream().map(SysCategory::getName).collect(Collectors.toList());
|
||||
List<String> textList = sysCategoryService.loadDictItem(ids, delNotExist);
|
||||
result.setSuccess(true);
|
||||
result.setResult(textList);
|
||||
return result;
|
||||
|
||||
@ -1,12 +1,9 @@
|
||||
package org.jeecg.modules.system.controller;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
@ -23,28 +20,25 @@ import org.jeecg.modules.system.entity.SysUser;
|
||||
import org.jeecg.modules.system.model.DepartIdModel;
|
||||
import org.jeecg.modules.system.model.SysDepartTreeModel;
|
||||
import org.jeecg.modules.system.service.ISysDepartService;
|
||||
import org.jeecg.modules.system.service.ISysPositionService;
|
||||
import org.jeecg.modules.system.service.ISysUserDepartService;
|
||||
import org.jeecg.modules.system.service.ISysUserService;
|
||||
import org.jeecg.modules.system.util.FindsDepartsChildrenUtil;
|
||||
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@ -132,6 +126,33 @@ public class SysDepartController {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取某个部门的所有父级部门的ID
|
||||
*
|
||||
* @param departId 根据departId查
|
||||
* @param orgCode 根据orgCode查,departId和orgCode必须有一个不为空
|
||||
*/
|
||||
@GetMapping("/queryAllParentId")
|
||||
public Result queryParentIds(
|
||||
@RequestParam(name = "departId", required = false) String departId,
|
||||
@RequestParam(name = "orgCode", required = false) String orgCode
|
||||
) {
|
||||
try {
|
||||
JSONObject data;
|
||||
if (oConvertUtils.isNotEmpty(departId)) {
|
||||
data = sysDepartService.queryAllParentIdByDepartId(departId);
|
||||
} else if (oConvertUtils.isNotEmpty(orgCode)) {
|
||||
data = sysDepartService.queryAllParentIdByOrgCode(orgCode);
|
||||
} else {
|
||||
return Result.error("departId 和 orgCode 不能都为空!");
|
||||
}
|
||||
return Result.OK(data);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加新数据 添加用户新建的部门对象数据,并保存到数据库
|
||||
*
|
||||
|
||||
@ -31,7 +31,6 @@ import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||
import org.jeecgframework.poi.excel.entity.result.ExcelImportResult;
|
||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -122,44 +121,20 @@ public class SysDictController {
|
||||
public Result<List<DictModel>> getDictItems(@PathVariable String dictCode, @RequestParam(value = "sign",required = false) String sign,HttpServletRequest request) {
|
||||
log.info(" dictCode : "+ dictCode);
|
||||
Result<List<DictModel>> result = new Result<List<DictModel>>();
|
||||
List<DictModel> ls = null;
|
||||
try {
|
||||
if(dictCode.indexOf(",")!=-1) {
|
||||
//关联表字典(举例:sys_user,realname,id)
|
||||
String[] params = dictCode.split(",");
|
||||
|
||||
if(params.length<3) {
|
||||
result.error500("字典Code格式不正确!");
|
||||
return result;
|
||||
}
|
||||
//SQL注入校验(只限制非法串改数据库)
|
||||
final String[] sqlInjCheck = {params[0],params[1],params[2]};
|
||||
SqlInjectionUtil.filterContent(sqlInjCheck);
|
||||
|
||||
if(params.length==4) {
|
||||
//SQL注入校验(查询条件SQL 特殊check,此方法仅供此处使用)
|
||||
SqlInjectionUtil.specialFilterContent(params[3]);
|
||||
ls = sysDictService.queryTableDictItemsByCodeAndFilter(params[0],params[1],params[2],params[3]);
|
||||
}else if (params.length==3) {
|
||||
ls = sysDictService.queryTableDictItemsByCode(params[0],params[1],params[2]);
|
||||
}else{
|
||||
result.error500("字典Code格式不正确!");
|
||||
return result;
|
||||
}
|
||||
}else {
|
||||
//字典表
|
||||
ls = sysDictService.queryDictItemsByCode(dictCode);
|
||||
List<DictModel> ls = sysDictService.getDictItems(dictCode);
|
||||
if (ls == null) {
|
||||
result.error500("字典Code格式不正确!");
|
||||
return result;
|
||||
}
|
||||
|
||||
result.setSuccess(true);
|
||||
result.setResult(ls);
|
||||
log.debug(result.toString());
|
||||
result.setSuccess(true);
|
||||
result.setResult(ls);
|
||||
log.debug(result.toString());
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
log.error(e.getMessage(), e);
|
||||
result.error500("操作失败");
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -198,8 +173,9 @@ public class SysDictController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 【JSearchSelectTag下拉搜索组件专用接口】
|
||||
* 大数据量的字典表 走异步加载 即前端输入内容过滤数据
|
||||
* @param dictCode
|
||||
* @param dictCode 字典code格式:table,text,code
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/loadDict/{dictCode}", method = RequestMethod.GET)
|
||||
@ -209,39 +185,75 @@ public class SysDictController {
|
||||
@RequestParam(value = "pageSize", required = false) Integer pageSize) {
|
||||
log.info(" 加载字典表数据,加载关键字: "+ keyword);
|
||||
Result<List<DictModel>> result = new Result<List<DictModel>>();
|
||||
List<DictModel> ls = null;
|
||||
try {
|
||||
if(dictCode.indexOf(",")!=-1) {
|
||||
String[] params = dictCode.split(",");
|
||||
if(params.length!=3) {
|
||||
result.error500("字典Code格式不正确!");
|
||||
return result;
|
||||
}
|
||||
if(pageSize!=null){
|
||||
ls = sysDictService.queryLittleTableDictItems(params[0],params[1],params[2],keyword, pageSize);
|
||||
}else{
|
||||
ls = sysDictService.queryTableDictItems(params[0],params[1],params[2],keyword);
|
||||
}
|
||||
result.setSuccess(true);
|
||||
result.setResult(ls);
|
||||
log.info(result.toString());
|
||||
}else {
|
||||
List<DictModel> ls = sysDictService.loadDict(dictCode, keyword, pageSize);
|
||||
if (ls == null) {
|
||||
result.error500("字典Code格式不正确!");
|
||||
return result;
|
||||
}
|
||||
result.setSuccess(true);
|
||||
result.setResult(ls);
|
||||
log.info(result.toString());
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
result.error500("操作失败");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 【给表单设计器的表字典使用】下拉搜索模式,有值时动态拼接数据
|
||||
* @param dictCode
|
||||
* @param keyword 当前控件的值,可以逗号分割
|
||||
* @param sign
|
||||
* @param pageSize
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/loadDictOrderByValue/{dictCode}", method = RequestMethod.GET)
|
||||
public Result<List<DictModel>> loadDictOrderByValue(
|
||||
@PathVariable String dictCode,
|
||||
@RequestParam(name = "keyword") String keyword,
|
||||
@RequestParam(value = "sign", required = false) String sign,
|
||||
@RequestParam(value = "pageSize", required = false) Integer pageSize) {
|
||||
// 首次查询查出来用户选中的值,并且不分页
|
||||
Result<List<DictModel>> firstRes = this.loadDict(dictCode, keyword, sign, null);
|
||||
if (!firstRes.isSuccess()) {
|
||||
return firstRes;
|
||||
}
|
||||
// 然后再查询出第一页的数据
|
||||
Result<List<DictModel>> result = this.loadDict(dictCode, "", sign, pageSize);
|
||||
if (!result.isSuccess()) {
|
||||
return result;
|
||||
}
|
||||
// 合并两次查询的数据
|
||||
List<DictModel> firstList = firstRes.getResult();
|
||||
List<DictModel> list = result.getResult();
|
||||
for (DictModel firstItem : firstList) {
|
||||
// anyMatch 表示:判断的条件里,任意一个元素匹配成功,返回true
|
||||
// allMatch 表示:判断条件里的元素,所有的都匹配成功,返回true
|
||||
// noneMatch 跟 allMatch 相反,表示:判断条件里的元素,所有的都匹配失败,返回true
|
||||
boolean none = list.stream().noneMatch(item -> item.getValue().equals(firstItem.getValue()));
|
||||
// 当元素不存在时,再添加到集合里
|
||||
if (none) {
|
||||
list.add(0, firstItem);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* 根据字典code加载字典text 返回
|
||||
* @param dictCode 顺序:tableName,text,code
|
||||
* @param keys 要查询的key
|
||||
* @param sign
|
||||
* @param delNotExist 是否移除不存在的项,默认为true,设为false如果某个key不存在数据库中,则直接返回key本身
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/loadDictItem/{dictCode}", method = RequestMethod.GET)
|
||||
public Result<List<String>> loadDictItem(@PathVariable String dictCode,@RequestParam(name="key") String keys, @RequestParam(value = "sign",required = false) String sign,HttpServletRequest request) {
|
||||
public Result<List<String>> loadDictItem(@PathVariable String dictCode,@RequestParam(name="key") String keys, @RequestParam(value = "sign",required = false) String sign,@RequestParam(value = "delNotExist",required = false,defaultValue = "true") boolean delNotExist,HttpServletRequest request) {
|
||||
Result<List<String>> result = new Result<>();
|
||||
try {
|
||||
if(dictCode.indexOf(",")!=-1) {
|
||||
@ -250,7 +262,7 @@ public class SysDictController {
|
||||
result.error500("字典Code格式不正确!");
|
||||
return result;
|
||||
}
|
||||
List<String> texts = sysDictService.queryTableDictByKeys(params[0], params[1], params[2], keys);
|
||||
List<String> texts = sysDictService.queryTableDictByKeys(params[0], params[1], params[2], keys, delNotExist);
|
||||
|
||||
result.setSuccess(true);
|
||||
result.setResult(texts);
|
||||
@ -407,12 +419,14 @@ public class SysDictController {
|
||||
//清空字典缓存
|
||||
Set keys = redisTemplate.keys(CacheConstant.SYS_DICT_CACHE + "*");
|
||||
Set keys2 = redisTemplate.keys(CacheConstant.SYS_DICT_TABLE_CACHE + "*");
|
||||
Set keys21 = redisTemplate.keys(CacheConstant.SYS_DICT_TABLE_BY_KEYS_CACHE + "*");
|
||||
Set keys3 = redisTemplate.keys(CacheConstant.SYS_DEPARTS_CACHE + "*");
|
||||
Set keys4 = redisTemplate.keys(CacheConstant.SYS_DEPART_IDS_CACHE + "*");
|
||||
Set keys5 = redisTemplate.keys( "jmreport:cache:dict*");
|
||||
Set keys6 = redisTemplate.keys( "jmreport:cache:dictTable*");
|
||||
redisTemplate.delete(keys);
|
||||
redisTemplate.delete(keys2);
|
||||
redisTemplate.delete(keys21);
|
||||
redisTemplate.delete(keys3);
|
||||
redisTemplate.delete(keys4);
|
||||
redisTemplate.delete(keys5);
|
||||
|
||||
@ -145,8 +145,8 @@ public class SysUserController {
|
||||
user.setPassword(passwordEncode);
|
||||
user.setStatus(1);
|
||||
user.setDelFlag(CommonConstant.DEL_FLAG_0);
|
||||
sysUserService.addUserWithRole(user, selectedRoles);
|
||||
sysUserService.addUserWithDepart(user, selectedDeparts);
|
||||
// 保存用户走一个service 保证事务
|
||||
sysUserService.saveUser(user, selectedRoles, selectedDeparts);
|
||||
result.success("添加成功!");
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
@ -172,9 +172,8 @@ public class SysUserController {
|
||||
user.setPassword(sysUser.getPassword());
|
||||
String roles = jsonObject.getString("selectedroles");
|
||||
String departs = jsonObject.getString("selecteddeparts");
|
||||
sysUserService.editUserWithRole(user, roles);
|
||||
sysUserService.editUserWithDepart(user, departs);
|
||||
sysUserService.updateNullPhoneEmail();
|
||||
// 修改用户走一个service 保证事务
|
||||
sysUserService.editUser(user, roles, departs);
|
||||
result.success("修改成功!");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@ -279,6 +278,7 @@ public class SysUserController {
|
||||
result.setResult(true);
|
||||
try {
|
||||
//通过传入信息查询新的用户信息
|
||||
sysUser.setPassword(null);
|
||||
SysUser user = sysUserService.getOne(new QueryWrapper<SysUser>(sysUser));
|
||||
if (user != null) {
|
||||
result.setSuccess(false);
|
||||
@ -298,6 +298,7 @@ public class SysUserController {
|
||||
/**
|
||||
* 修改密码
|
||||
*/
|
||||
//@RequiresRoles({"admin"})
|
||||
@RequestMapping(value = "/changePassword", method = RequestMethod.PUT)
|
||||
public Result<?> changePassword(@RequestBody SysUser sysUser) {
|
||||
SysUser u = this.sysUserService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, sysUser.getUsername()));
|
||||
@ -388,6 +389,23 @@ public class SysUserController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户选择组件 专用 根据用户账号或部门分页查询
|
||||
* @param departId
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/queryUserComponentData", method = RequestMethod.GET)
|
||||
public Result<IPage<SysUser>> queryUserComponentData(
|
||||
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||
@RequestParam(name = "departId", required = false) String departId,
|
||||
@RequestParam(name="realname",required=false) String realname,
|
||||
@RequestParam(name="username",required=false) String username) {
|
||||
IPage<SysUser> pageList = sysUserDepartService.queryDepartUserPageList(departId, username, realname, pageSize, pageNo);
|
||||
return Result.OK(pageList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出excel
|
||||
*
|
||||
@ -521,13 +539,17 @@ public class SysUserController {
|
||||
/**
|
||||
* 首页用户重置密码
|
||||
*/
|
||||
//@RequiresRoles({"admin"})
|
||||
@RequestMapping(value = "/updatePassword", method = RequestMethod.PUT)
|
||||
public Result<?> changPassword(@RequestBody JSONObject json) {
|
||||
//@RequiresRoles({"admin"})
|
||||
@RequestMapping(value = "/updatePassword", method = RequestMethod.PUT)
|
||||
public Result<?> updatePassword(@RequestBody JSONObject json) {
|
||||
String username = json.getString("username");
|
||||
String oldpassword = json.getString("oldpassword");
|
||||
String password = json.getString("password");
|
||||
String confirmpassword = json.getString("confirmpassword");
|
||||
LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
|
||||
if(!sysUser.getUsername().equals(username)){
|
||||
return Result.error("只允许修改自己的密码!");
|
||||
}
|
||||
SysUser user = this.sysUserService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, username));
|
||||
if(user==null) {
|
||||
return Result.error("用户不存在!");
|
||||
@ -1338,4 +1360,6 @@ public class SysUserController {
|
||||
sysUserService.updateById(user);
|
||||
return Result.ok("手机号设置成功!");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,261 @@
|
||||
package org.jeecg.modules.system.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.jeecg.dingtalk.api.core.response.Response;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.dto.message.MessageDTO;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.system.util.JwtUtil;
|
||||
import org.jeecg.config.thirdapp.ThirdAppConfig;
|
||||
import org.jeecg.modules.system.service.impl.ThirdAppDingtalkServiceImpl;
|
||||
import org.jeecg.modules.system.service.impl.ThirdAppWechatEnterpriseServiceImpl;
|
||||
import org.jeecg.modules.system.vo.thirdapp.SyncInfoVo;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 第三方App对接
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController("thirdAppController")
|
||||
@RequestMapping("/sys/thirdApp")
|
||||
public class ThirdAppController {
|
||||
|
||||
@Autowired
|
||||
ThirdAppConfig thirdAppConfig;
|
||||
|
||||
@Autowired
|
||||
ThirdAppWechatEnterpriseServiceImpl wechatEnterpriseService;
|
||||
@Autowired
|
||||
ThirdAppDingtalkServiceImpl dingtalkService;
|
||||
|
||||
/**
|
||||
* 获取启用的系统
|
||||
*/
|
||||
@GetMapping("/getEnabledType")
|
||||
public Result getEnabledType() {
|
||||
Map<String, Boolean> enabledMap = new HashMap<>();
|
||||
enabledMap.put("wechatEnterprise", thirdAppConfig.isWechatEnterpriseEnabled());
|
||||
enabledMap.put("dingtalk", thirdAppConfig.isDingtalkEnabled());
|
||||
return Result.OK(enabledMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步本地[用户]到【企业微信】
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sync/wechatEnterprise/user/toApp")
|
||||
public Result syncWechatEnterpriseUserToApp(@RequestParam(value = "ids", required = false) String ids) {
|
||||
if (thirdAppConfig.isWechatEnterpriseEnabled()) {
|
||||
SyncInfoVo syncInfo = wechatEnterpriseService.syncLocalUserToThirdApp(ids);
|
||||
if (syncInfo.getFailInfo().size() == 0) {
|
||||
return Result.OK("同步成功", syncInfo);
|
||||
} else {
|
||||
return Result.error("同步失败", syncInfo);
|
||||
}
|
||||
}
|
||||
return Result.error("企业微信同步功能已禁用");
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步【企业微信】[用户]到本地
|
||||
*
|
||||
* @param ids 作废
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sync/wechatEnterprise/user/toLocal")
|
||||
public Result syncWechatEnterpriseUserToLocal(@RequestParam(value = "ids", required = false) String ids) {
|
||||
if (thirdAppConfig.isWechatEnterpriseEnabled()) {
|
||||
SyncInfoVo syncInfo = wechatEnterpriseService.syncThirdAppUserToLocal();
|
||||
if (syncInfo.getFailInfo().size() == 0) {
|
||||
return Result.OK("同步成功", syncInfo);
|
||||
} else {
|
||||
return Result.error("同步失败", syncInfo);
|
||||
}
|
||||
}
|
||||
return Result.error("企业微信同步功能已禁用");
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步本地[部门]到【企业微信】
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sync/wechatEnterprise/depart/toApp")
|
||||
public Result syncWechatEnterpriseDepartToApp(@RequestParam(value = "ids", required = false) String ids) {
|
||||
if (thirdAppConfig.isWechatEnterpriseEnabled()) {
|
||||
boolean flag = wechatEnterpriseService.syncLocalDepartmentToThirdApp(ids);
|
||||
return flag ? Result.OK("同步成功", null) : Result.error("同步失败");
|
||||
}
|
||||
return Result.error("企业微信同步功能已禁用");
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步【企业微信】[部门]到本地
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sync/wechatEnterprise/depart/toLocal")
|
||||
public Result syncWechatEnterpriseDepartToLocal(@RequestParam(value = "ids", required = false) String ids) {
|
||||
if (thirdAppConfig.isWechatEnterpriseEnabled()) {
|
||||
SyncInfoVo syncInfo = wechatEnterpriseService.syncThirdAppDepartmentToLocal(ids);
|
||||
if (syncInfo.getFailInfo().size() == 0) {
|
||||
return Result.OK("同步成功", syncInfo);
|
||||
} else {
|
||||
return Result.error("同步失败", syncInfo);
|
||||
}
|
||||
}
|
||||
return Result.error("企业微信同步功能已禁用");
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步本地[部门]到【钉钉】
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sync/dingtalk/depart/toApp")
|
||||
public Result syncDingtalkDepartToApp(@RequestParam(value = "ids", required = false) String ids) {
|
||||
if (thirdAppConfig.isDingtalkEnabled()) {
|
||||
boolean flag = dingtalkService.syncLocalDepartmentToThirdApp(ids);
|
||||
return flag ? Result.OK("同步成功", null) : Result.error("同步失败");
|
||||
}
|
||||
return Result.error("钉钉同步功能已禁用");
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步【钉钉】[部门]到本地
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sync/dingtalk/depart/toLocal")
|
||||
public Result syncDingtalkDepartToLocal(@RequestParam(value = "ids", required = false) String ids) {
|
||||
if (thirdAppConfig.isDingtalkEnabled()) {
|
||||
SyncInfoVo syncInfo = dingtalkService.syncThirdAppDepartmentToLocal(ids);
|
||||
if (syncInfo.getFailInfo().size() == 0) {
|
||||
return Result.OK("同步成功", syncInfo);
|
||||
} else {
|
||||
return Result.error("同步失败", syncInfo);
|
||||
}
|
||||
}
|
||||
return Result.error("钉钉同步功能已禁用");
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步本地[用户]到【钉钉】
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sync/dingtalk/user/toApp")
|
||||
public Result syncDingtalkUserToApp(@RequestParam(value = "ids", required = false) String ids) {
|
||||
if (thirdAppConfig.isDingtalkEnabled()) {
|
||||
SyncInfoVo syncInfo = dingtalkService.syncLocalUserToThirdApp(ids);
|
||||
if (syncInfo.getFailInfo().size() == 0) {
|
||||
return Result.OK("同步成功", syncInfo);
|
||||
} else {
|
||||
return Result.error("同步失败", syncInfo);
|
||||
}
|
||||
}
|
||||
return Result.error("钉钉同步功能已禁用");
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步【钉钉】[用户]到本地
|
||||
*
|
||||
* @param ids 作废
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sync/dingtalk/user/toLocal")
|
||||
public Result syncDingtalkUserToLocal(@RequestParam(value = "ids", required = false) String ids) {
|
||||
if (thirdAppConfig.isDingtalkEnabled()) {
|
||||
SyncInfoVo syncInfo = dingtalkService.syncThirdAppUserToLocal();
|
||||
if (syncInfo.getFailInfo().size() == 0) {
|
||||
return Result.OK("同步成功", syncInfo);
|
||||
} else {
|
||||
return Result.error("同步失败", syncInfo);
|
||||
}
|
||||
}
|
||||
return Result.error("钉钉同步功能已禁用");
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送消息测试
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/sendMessageTest")
|
||||
public Result sendMessageTest(@RequestBody JSONObject params, HttpServletRequest request) {
|
||||
/* 获取前台传递的参数 */
|
||||
// 第三方app的类型
|
||||
String app = params.getString("app");
|
||||
// 是否发送给全部人
|
||||
boolean sendAll = params.getBooleanValue("sendAll");
|
||||
// 消息接收者,传sys_user表的username字段,多个用逗号分割
|
||||
String receiver = params.getString("receiver");
|
||||
// 消息内容
|
||||
String content = params.getString("content");
|
||||
|
||||
String fromUser = JwtUtil.getUserNameByToken(request);
|
||||
String title = "第三方APP消息测试";
|
||||
MessageDTO message = new MessageDTO(fromUser, receiver, title, content);
|
||||
message.setToAll(sendAll);
|
||||
|
||||
if (ThirdAppConfig.WECHAT_ENTERPRISE.equals(app)) {
|
||||
if (thirdAppConfig.isWechatEnterpriseEnabled()) {
|
||||
JSONObject response = wechatEnterpriseService.sendMessageResponse(message, false);
|
||||
return Result.OK(response);
|
||||
}
|
||||
return Result.error("企业微信已被禁用");
|
||||
} else if (ThirdAppConfig.DINGTALK.equals(app)) {
|
||||
if (thirdAppConfig.isDingtalkEnabled()) {
|
||||
Response<String> response = dingtalkService.sendMessageResponse(message, false);
|
||||
return Result.OK(response);
|
||||
}
|
||||
return Result.error("钉钉已被禁用");
|
||||
}
|
||||
return Result.error("不识别的第三方APP");
|
||||
}
|
||||
|
||||
/**
|
||||
* 撤回消息测试
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/recallMessageTest")
|
||||
public Result recallMessageTest(@RequestBody JSONObject params) {
|
||||
/* 获取前台传递的参数 */
|
||||
// 第三方app的类型
|
||||
String app = params.getString("app");
|
||||
// 消息id
|
||||
String msg_task_id = params.getString("msg_task_id");
|
||||
|
||||
if (ThirdAppConfig.WECHAT_ENTERPRISE.equals(app)) {
|
||||
if (thirdAppConfig.isWechatEnterpriseEnabled()) {
|
||||
return Result.error("企业微信不支持撤回消息");
|
||||
}
|
||||
return Result.error("企业微信已被禁用");
|
||||
} else if (ThirdAppConfig.DINGTALK.equals(app)) {
|
||||
if (thirdAppConfig.isDingtalkEnabled()) {
|
||||
Response<JSONObject> response = dingtalkService.recallMessageResponse(msg_task_id);
|
||||
if (response.isSuccess()) {
|
||||
return Result.OK("撤回成功", response);
|
||||
} else {
|
||||
return Result.error("撤回失败:" + response.getErrcode() + "——" + response.getErrmsg(), response);
|
||||
}
|
||||
}
|
||||
return Result.error("钉钉已被禁用");
|
||||
}
|
||||
return Result.error("不识别的第三方APP");
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,17 +1,16 @@
|
||||
package org.jeecg.modules.system.entity;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
import org.jeecg.common.aspect.annotation.Dict;
|
||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @Description: 系统通告表
|
||||
* @Author: jeecg-boot
|
||||
@ -144,4 +143,8 @@ public class SysAnnouncement implements Serializable {
|
||||
* 摘要
|
||||
*/
|
||||
private java.lang.String msgAbstract;
|
||||
/**
|
||||
* 钉钉task_id,用于撤回消息
|
||||
*/
|
||||
private java.lang.String dtTaskId;
|
||||
}
|
||||
|
||||
@ -6,13 +6,11 @@ import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
import org.jeecg.common.aspect.annotation.Dict;
|
||||
import org.jeecg.modules.system.model.SysDepartTreeModel;
|
||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
@ -73,6 +71,8 @@ public class SysDepart implements Serializable {
|
||||
/**删除状态(0,正常,1已删除)*/
|
||||
@Dict(dicCode = "del_flag")
|
||||
private String delFlag;
|
||||
/**对接企业微信的ID*/
|
||||
private String qywxIdentifier;
|
||||
/**创建人*/
|
||||
private String createBy;
|
||||
/**创建日期*/
|
||||
|
||||
@ -1,18 +1,13 @@
|
||||
package org.jeecg.modules.system.entity;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||
|
||||
/**
|
||||
@ -60,4 +55,8 @@ public class SysThirdAccount {
|
||||
@Excel(name = "真实姓名", width = 15)
|
||||
@ApiModelProperty(value = "真实姓名")
|
||||
private java.lang.String thirdUserUuid;
|
||||
/**真实姓名*/
|
||||
@Excel(name = "第三方用户账号", width = 15)
|
||||
@ApiModelProperty(value = "第三方用户账号")
|
||||
private java.lang.String thirdUserId;
|
||||
}
|
||||
|
||||
@ -6,7 +6,6 @@ import java.util.Map;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.ResultType;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
import org.jeecg.common.system.vo.DictModel;
|
||||
@ -132,4 +131,26 @@ public interface SysDictMapper extends BaseMapper<SysDict> {
|
||||
*/
|
||||
@Deprecated
|
||||
public Page<DictModel> queryDictTablePageList(Page page, @Param("query") DictQuery query);
|
||||
|
||||
|
||||
/**
|
||||
* 查询 字典表数据 支持查询条件 分页
|
||||
* @param page
|
||||
* @param table
|
||||
* @param text
|
||||
* @param code
|
||||
* @param filterSql
|
||||
* @return
|
||||
*/
|
||||
IPage<DictModel> queryTableDictWithFilter(Page<DictModel> page, @Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("filterSql") String filterSql);
|
||||
|
||||
/**
|
||||
* 查询 字典表数据 支持查询条件 查询所有
|
||||
* @param table
|
||||
* @param text
|
||||
* @param code
|
||||
* @param filterSql
|
||||
* @return
|
||||
*/
|
||||
List<DictModel> queryAllTableDictItems(@Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("filterSql") String filterSql);
|
||||
}
|
||||
|
||||
@ -1,17 +1,26 @@
|
||||
package org.jeecg.modules.system.mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.jeecg.modules.system.entity.SysThirdAccount;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description: 第三方登录账号表
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2020-11-17
|
||||
* @Date: 2020-11-17
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface SysThirdAccountMapper extends BaseMapper<SysThirdAccount> {
|
||||
|
||||
/**
|
||||
* 通过 sysUsername 集合批量查询
|
||||
*
|
||||
* @param sysUsernameArr username集合
|
||||
* @param thirdType 第三方类型
|
||||
* @return
|
||||
*/
|
||||
List<SysThirdAccount> selectThirdIdsByUsername(@Param("sysUsernameArr") String[] sysUsernameArr, @Param("thirdType") String thirdType);
|
||||
|
||||
}
|
||||
|
||||
@ -1,11 +1,32 @@
|
||||
package org.jeecg.modules.system.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.jeecg.modules.system.entity.SysUser;
|
||||
import org.jeecg.modules.system.entity.SysUserDepart;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
public interface SysUserDepartMapper extends BaseMapper<SysUserDepart>{
|
||||
|
||||
List<SysUserDepart> getUserDepartByUid(@Param("userId") String userId);
|
||||
|
||||
/**
|
||||
* 查询指定部门下的用户 并且支持用户真实姓名模糊查询
|
||||
* @param orgCode
|
||||
* @param realname
|
||||
* @return
|
||||
*/
|
||||
List<SysUser> queryDepartUserList(@Param("orgCode") String orgCode, @Param("realname") String realname);
|
||||
|
||||
/**
|
||||
* 根据部门查询部门用户
|
||||
* @param page
|
||||
* @param orgCode
|
||||
* @param username
|
||||
* @param realname
|
||||
* @return
|
||||
*/
|
||||
IPage<SysUser> queryDepartUserPageList(Page<SysUser> page, @Param("orgCode") String orgCode, @Param("username") String username, @Param("realname") String realname);
|
||||
}
|
||||
|
||||
@ -106,4 +106,22 @@
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<!--通过查询指定table的 text code 获取字典数据,且支持关键字和自定义查询条件查询 分页-->
|
||||
<select id="queryTableDictWithFilter" parameterType="String" resultType="org.jeecg.common.system.vo.DictModel">
|
||||
select ${text} as "text", ${code} as "value" from ${table}
|
||||
<if test="filterSql != null and filterSql != ''">
|
||||
${filterSql}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<!--通过查询指定table的 text code 获取字典数据,且支持关键字和自定义查询条件查询 获取所有 -->
|
||||
<select id="queryAllTableDictItems" parameterType="String" resultType="org.jeecg.common.system.vo.DictModel">
|
||||
select ${text} as "text", ${code} as "value" from ${table}
|
||||
<if test="filterSql != null and filterSql != ''">
|
||||
${filterSql}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
|
||||
|
||||
</mapper>
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
|
||||
<!-- 首页访问统计 -->
|
||||
<select id="findVisitCount" resultType="java.util.HashMap">
|
||||
<if test="dbType == 'MYSQL'">
|
||||
<if test="dbType == 'MYSQL' || dbType == 'MARIADB'">
|
||||
select count(*) as visit
|
||||
,count(distinct(ip)) as ip
|
||||
,DATE_FORMAT(create_time, '%Y-%m-%d') as tian
|
||||
@ -34,7 +34,7 @@
|
||||
group by tian,type
|
||||
order by tian asc
|
||||
</if>
|
||||
<if test="dbType == 'ORACLE'">
|
||||
<if test="dbType == 'ORACLE' || dbType == 'DM'">
|
||||
select count(*) as visit
|
||||
,count(distinct(ip)) as ip
|
||||
,to_char(create_time, 'yyyy-mm-dd') as tian
|
||||
|
||||
@ -2,4 +2,13 @@
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.jeecg.modules.system.mapper.SysThirdAccountMapper">
|
||||
|
||||
<!-- 通过 sysUsername 集合批量查询 -->
|
||||
<select id="selectThirdIdsByUsername" resultType="org.jeecg.modules.system.entity.SysThirdAccount">
|
||||
SELECT third_user_id FROM sys_third_account
|
||||
INNER JOIN sys_user ON sys_user.id = sys_third_account.sys_user_id
|
||||
WHERE third_type = #{thirdType} AND
|
||||
<!-- TODO in 查询数据量大的时候可能会报错 -->
|
||||
<foreach collection="sysUsernameArr" item="item" open=" sys_user.username IN (" close=")" separator=",">#{item}</foreach>
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@ -6,4 +6,29 @@
|
||||
FROM sys_user_depart
|
||||
WHERE user_id = #{userId, jdbcType=VARCHAR}
|
||||
</select>
|
||||
|
||||
<!-- 查询指定部门下的用户 并且支持用户账号模糊查询 -->
|
||||
<select id="queryDepartUserList" resultType="org.jeecg.modules.system.entity.SysUser">
|
||||
select a.* from sys_user a
|
||||
join sys_user_depart b on b.user_id = a.id
|
||||
join sys_depart c on b.dep_id = c.id
|
||||
where a.del_flag = 0 and c.org_code like '${orgCode}%'
|
||||
<if test="realname!=null and realname!=''">
|
||||
and a.realname like '%${realname}%'
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<!-- 根据部门查询部门用户 分页 -->
|
||||
<select id="queryDepartUserPageList" resultType="org.jeecg.modules.system.entity.SysUser">
|
||||
select a.*, c.depart_name as org_code_txt from sys_user a
|
||||
join sys_user_depart b on b.user_id = a.id
|
||||
join sys_depart c on b.dep_id = c.id
|
||||
where a.del_flag = 0 and c.org_code like '${orgCode}%'
|
||||
<if test="username!=null and username!=''">
|
||||
and a.username like '%${username}%'
|
||||
</if>
|
||||
<if test="realname!=null and realname!=''">
|
||||
and a.realname like '%${realname}%'
|
||||
</if>
|
||||
</select>
|
||||
</mapper>
|
||||
@ -65,6 +65,8 @@ public class SysDepartTreeModel implements Serializable{
|
||||
|
||||
private String delFlag;
|
||||
|
||||
private String qywxIdentifier;
|
||||
|
||||
private String createBy;
|
||||
|
||||
private Date createTime;
|
||||
@ -100,6 +102,7 @@ public class SysDepartTreeModel implements Serializable{
|
||||
this.memo = sysDepart.getMemo();
|
||||
this.status = sysDepart.getStatus();
|
||||
this.delFlag = sysDepart.getDelFlag();
|
||||
this.qywxIdentifier = sysDepart.getQywxIdentifier();
|
||||
this.createBy = sysDepart.getCreateBy();
|
||||
this.createTime = sysDepart.getCreateTime();
|
||||
this.updateBy = sysDepart.getUpdateBy();
|
||||
@ -287,6 +290,14 @@ public class SysDepartTreeModel implements Serializable{
|
||||
this.delFlag = delFlag;
|
||||
}
|
||||
|
||||
public String getQywxIdentifier() {
|
||||
return qywxIdentifier;
|
||||
}
|
||||
|
||||
public void setQywxIdentifier(String qywxIdentifier) {
|
||||
this.qywxIdentifier = qywxIdentifier;
|
||||
}
|
||||
|
||||
public String getCreateBy() {
|
||||
return createBy;
|
||||
}
|
||||
@ -349,6 +360,7 @@ public class SysDepartTreeModel implements Serializable{
|
||||
Objects.equals(memo, model.memo) &&
|
||||
Objects.equals(status, model.status) &&
|
||||
Objects.equals(delFlag, model.delFlag) &&
|
||||
Objects.equals(qywxIdentifier, model.qywxIdentifier) &&
|
||||
Objects.equals(createBy, model.createBy) &&
|
||||
Objects.equals(createTime, model.createTime) &&
|
||||
Objects.equals(updateBy, model.updateBy) &&
|
||||
@ -364,7 +376,7 @@ public class SysDepartTreeModel implements Serializable{
|
||||
|
||||
return Objects.hash(id, parentId, departName, departNameEn, departNameAbbr,
|
||||
departOrder, description, orgCategory, orgType, orgCode, mobile, fax, address,
|
||||
memo, status, delFlag, createBy, createTime, updateBy, updateTime,
|
||||
memo, status, delFlag, qywxIdentifier, createBy, createTime, updateBy, updateTime,
|
||||
children);
|
||||
}
|
||||
|
||||
|
||||
@ -1,13 +1,12 @@
|
||||
package org.jeecg.modules.system.service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
import org.jeecg.modules.system.entity.SysCategory;
|
||||
import org.jeecg.modules.system.model.TreeSelectModel;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Description: 分类字典
|
||||
@ -58,5 +57,22 @@ public interface ISysCategoryService extends IService<SysCategory> {
|
||||
* @param ids
|
||||
*/
|
||||
void deleteSysCategory(String ids);
|
||||
|
||||
|
||||
/**
|
||||
* 分类字典控件数据回显[表单页面]
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
List<String> loadDictItem(String ids);
|
||||
|
||||
/**
|
||||
* 分类字典控件数据回显[表单页面]
|
||||
*
|
||||
* @param ids
|
||||
* @param delNotExist 是否移除不存在的项,设为false如果某个key不存在数据库中,则直接返回key本身
|
||||
* @return
|
||||
*/
|
||||
List<String> loadDictItem(String ids, boolean delNotExist);
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package org.jeecg.modules.system.service;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.jeecg.modules.system.entity.SysDepart;
|
||||
import org.jeecg.modules.system.model.DepartIdModel;
|
||||
@ -112,6 +113,20 @@ public interface ISysDepartService extends IService<SysDepart>{
|
||||
* @return
|
||||
*/
|
||||
List<SysDepartTreeModel> queryTreeListByPid(String parentId);
|
||||
|
||||
/**
|
||||
* 获取某个部门的所有父级部门的ID
|
||||
*
|
||||
* @param departId 根据departId查
|
||||
*/
|
||||
JSONObject queryAllParentIdByDepartId(String departId);
|
||||
|
||||
/**
|
||||
* 获取某个部门的所有父级部门的ID
|
||||
*
|
||||
* @param orgCode 根据orgCode查
|
||||
*/
|
||||
JSONObject queryAllParentIdByOrgCode(String orgCode);
|
||||
/**
|
||||
* 获取公司信息
|
||||
* @return
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
package org.jeecg.modules.system.service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.jeecg.common.system.vo.DictModel;
|
||||
import org.jeecg.common.system.vo.DictQuery;
|
||||
import org.jeecg.modules.system.entity.SysDict;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.jeecg.modules.system.entity.SysDictItem;
|
||||
import org.jeecg.modules.system.model.TreeSelectModel;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 字典表 服务类
|
||||
@ -37,6 +37,8 @@ public interface ISysDictService extends IService<SysDict> {
|
||||
|
||||
@Deprecated
|
||||
List<String> queryTableDictByKeys(String table, String text, String code, String keys);
|
||||
@Deprecated
|
||||
List<String> queryTableDictByKeys(String table, String text, String code, String keys,boolean delNotExist);
|
||||
|
||||
/**
|
||||
* 根据字典类型删除关联表中其对应的数据
|
||||
@ -50,19 +52,19 @@ public interface ISysDictService extends IService<SysDict> {
|
||||
* 添加一对多
|
||||
*/
|
||||
public Integer saveMain(SysDict sysDict, List<SysDictItem> sysDictItemList);
|
||||
|
||||
|
||||
/**
|
||||
* 查询所有部门 作为字典信息 id -->value,departName -->text
|
||||
* @return
|
||||
*/
|
||||
public List<DictModel> queryAllDepartBackDictModel();
|
||||
|
||||
|
||||
/**
|
||||
* 查询所有用户 作为字典信息 username -->value,realname -->text
|
||||
* @return
|
||||
*/
|
||||
public List<DictModel> queryAllUserBackDictModel();
|
||||
|
||||
|
||||
/**
|
||||
* 通过关键字查询字典表
|
||||
* @param table
|
||||
@ -82,7 +84,18 @@ public interface ISysDictService extends IService<SysDict> {
|
||||
* @param keyword
|
||||
* @return
|
||||
*/
|
||||
public List<DictModel> queryLittleTableDictItems(String table, String text, String code,String keyword, int pageSize);
|
||||
public List<DictModel> queryLittleTableDictItems(String table, String text, String code, String condition, String keyword, int pageSize);
|
||||
|
||||
/**
|
||||
* 查询字典表所有数据
|
||||
* @param table
|
||||
* @param text
|
||||
* @param code
|
||||
* @param condition
|
||||
* @param keyword
|
||||
* @return
|
||||
*/
|
||||
public List<DictModel> queryAllTableDictItems(String table, String text, String code, String condition, String keyword);
|
||||
/**
|
||||
* 根据表名、显示字段名、存储字段名 查询树
|
||||
* @param table
|
||||
@ -125,4 +138,21 @@ public interface ISysDictService extends IService<SysDict> {
|
||||
@Deprecated
|
||||
public List<DictModel> queryDictTablePageList(DictQuery query,int pageSize, int pageNo);
|
||||
|
||||
/**
|
||||
* 获取字典数据
|
||||
* @param dictCode 字典code
|
||||
* @param dictCode 表名,文本字段,code字段 | 举例:sys_user,realname,id
|
||||
* @return
|
||||
*/
|
||||
List<DictModel> getDictItems(String dictCode);
|
||||
|
||||
/**
|
||||
* 【JSearchSelectTag下拉搜索组件专用接口】
|
||||
* 大数据量的字典表 走异步加载 即前端输入内容过滤数据
|
||||
*
|
||||
* @param dictCode 字典code格式:table,text,code
|
||||
* @return
|
||||
*/
|
||||
List<DictModel> loadDict(String dictCode, String keyword, Integer pageSize);
|
||||
|
||||
}
|
||||
|
||||
@ -11,4 +11,9 @@ import org.jeecg.modules.system.entity.SysPosition;
|
||||
*/
|
||||
public interface ISysPositionService extends IService<SysPosition> {
|
||||
|
||||
/**
|
||||
* 通过code查询
|
||||
*/
|
||||
SysPosition getByCode(String code);
|
||||
|
||||
}
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
package org.jeecg.modules.system.service;
|
||||
|
||||
import org.jeecg.modules.system.entity.SysThirdAccount;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.jeecg.modules.system.entity.SysThirdAccount;
|
||||
import org.jeecg.modules.system.entity.SysUser;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description: 第三方登录账号表
|
||||
* @Author: jeecg-boot
|
||||
@ -15,5 +17,19 @@ public interface ISysThirdAccountService extends IService<SysThirdAccount> {
|
||||
void updateThirdUserId(SysUser sysUser,String thirdUserUuid);
|
||||
/**创建第三方用户*/
|
||||
SysUser createUser(String phone, String thirdUserUuid);
|
||||
|
||||
|
||||
/** 根据本地userId查询数据 */
|
||||
SysThirdAccount getOneBySysUserId(String sysUserId, String thirdType);
|
||||
/** 根据第三方userId查询数据 */
|
||||
SysThirdAccount getOneByThirdUserId(String thirdUserId, String thirdType);
|
||||
|
||||
/**
|
||||
* 通过 sysUsername 集合批量查询
|
||||
*
|
||||
* @param sysUsernameArr username集合
|
||||
* @param thirdType 第三方类型
|
||||
* @return
|
||||
*/
|
||||
List<SysThirdAccount> listThirdUserIdByUsername(String[] sysUsernameArr, String thirdType);
|
||||
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package org.jeecg.modules.system.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.jeecg.modules.system.entity.SysUser;
|
||||
import org.jeecg.modules.system.entity.SysUserDepart;
|
||||
import org.jeecg.modules.system.model.DepartIdModel;
|
||||
@ -37,5 +38,16 @@ public interface ISysUserDepartService extends IService<SysUserDepart> {
|
||||
/**
|
||||
* 根据部门code,查询当前部门和下级部门的用户信息
|
||||
*/
|
||||
public List<SysUser> queryUserByDepCode(String depCode,String realname);
|
||||
List<SysUser> queryUserByDepCode(String depCode,String realname);
|
||||
|
||||
/**
|
||||
* 用户组件数据查询
|
||||
* @param departId
|
||||
* @param username
|
||||
* @param pageSize
|
||||
* @param pageNo
|
||||
* @return
|
||||
*/
|
||||
IPage<SysUser> queryDepartUserPageList(String departId, String username, String realname, int pageSize, int pageNo);
|
||||
|
||||
}
|
||||
|
||||
@ -1,22 +1,21 @@
|
||||
package org.jeecg.modules.system.service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.system.vo.SysUserCacheInfo;
|
||||
import org.jeecg.modules.system.entity.SysUser;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.jeecg.modules.system.model.SysUserSysDepartModel;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户表 服务类
|
||||
@ -233,4 +232,24 @@ public interface ISysUserService extends IService<SysUser> {
|
||||
* @return
|
||||
*/
|
||||
List<SysUser> queryByDepIds(List<String> departIds, String username);
|
||||
|
||||
/**
|
||||
* 保存用户
|
||||
* @param user 用户
|
||||
* @param selectedRoles 选择的角色id,多个以逗号隔开
|
||||
* @param selectedDeparts 选择的部门id,多个以逗号隔开
|
||||
*/
|
||||
void saveUser(SysUser user, String selectedRoles, String selectedDeparts);
|
||||
|
||||
/**
|
||||
* 编辑用户
|
||||
* @param user 用户
|
||||
* @param roles 选择的角色id,多个以逗号隔开
|
||||
* @param departs 选择的部门id,多个以逗号隔开
|
||||
*/
|
||||
void editUser(SysUser user, String roles, String departs);
|
||||
|
||||
/** userId转为username */
|
||||
List<String> userIdToUsername(Collection<String> userIdList);
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,79 @@
|
||||
package org.jeecg.modules.system.service;
|
||||
|
||||
import org.jeecg.common.api.dto.message.MessageDTO;
|
||||
import org.jeecg.modules.system.vo.thirdapp.SyncInfoVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 第三方App对接
|
||||
*/
|
||||
public interface IThirdAppService {
|
||||
|
||||
String getAccessToken();
|
||||
|
||||
/**
|
||||
* 将本地部门同步到第三方App<br>
|
||||
* 同步方向:本地 --> 第三方APP
|
||||
* 同步逻辑:<br>
|
||||
* 1. 先判断是否同步过,有则修改,无则创建;<br>
|
||||
* 2. 本地没有但第三方App里有则删除第三方App里的。
|
||||
*
|
||||
* @return 成功返回true
|
||||
*/
|
||||
boolean syncLocalDepartmentToThirdApp(String ids);
|
||||
|
||||
/**
|
||||
* 将第三方App部门同步到本地<br>
|
||||
* 同步方向:第三方APP --> 本地
|
||||
* 同步逻辑:<br>
|
||||
* 1. 先判断是否同步过,有则修改,无则创建;<br>
|
||||
* 2. 本地没有但第三方App里有则删除第三方App里的。
|
||||
*
|
||||
* @return 成功返回true
|
||||
*/
|
||||
SyncInfoVo syncThirdAppDepartmentToLocal(String ids);
|
||||
|
||||
/**
|
||||
* 将本地用户同步到第三方App<br>
|
||||
* 同步方向:本地 --> 第三方APP <br>
|
||||
* 同步逻辑:先判断是否同步过,有则修改、无则创建<br>
|
||||
* 注意:同步人员的状态,比如离职、禁用、逻辑删除等。
|
||||
* (特殊点:1、目前逻辑特意做的不删除用户,防止企业微信提前上线,用户已经存在,但是平台无此用户。
|
||||
* 企业微信支持禁用账号;钉钉不支持
|
||||
* 2、企业微信里面是手机号激活,只能用户自己改,不允许通过接口改)
|
||||
*
|
||||
* @return 成功返回空数组,失败返回错误信息
|
||||
*/
|
||||
SyncInfoVo syncLocalUserToThirdApp(String ids);
|
||||
|
||||
/**
|
||||
* 将第三方App用户同步到本地<br>
|
||||
* 同步方向:第三方APP --> 本地 <br>
|
||||
* 同步逻辑:先判断是否同步过,有则修改、无则创建<br>
|
||||
* 注意:同步人员的状态,比如离职、禁用、逻辑删除等。
|
||||
*
|
||||
* @return 成功返回空数组,失败返回错误信息
|
||||
*/
|
||||
SyncInfoVo syncThirdAppUserToLocal();
|
||||
|
||||
/**
|
||||
* 根据本地用户ID,删除第三方APP的用户
|
||||
*
|
||||
* @param userIdList 本地用户ID列表
|
||||
* @return 0表示成功,其他值表示失败
|
||||
*/
|
||||
int removeThirdAppUser(List<String> userIdList);
|
||||
|
||||
/**
|
||||
* 发送消息
|
||||
*
|
||||
* @param message
|
||||
* @param verifyConfig 是否验证配置(未启用的APP会拒绝发送)
|
||||
* @return
|
||||
*/
|
||||
boolean sendMessage(MessageDTO message, boolean verifyConfig);
|
||||
|
||||
boolean sendMessage(MessageDTO message);
|
||||
|
||||
}
|
||||
@ -1,7 +1,4 @@
|
||||
package org.jeecg.modules.system.service.impl;
|
||||
import java.util.HashMap;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
@ -95,6 +92,11 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
@Autowired
|
||||
private ISysPermissionDataRuleService sysPermissionDataRuleService;
|
||||
|
||||
@Autowired
|
||||
private ThirdAppWechatEnterpriseServiceImpl wechatEnterpriseService;
|
||||
@Autowired
|
||||
private ThirdAppDingtalkServiceImpl dingtalkService;
|
||||
|
||||
@Override
|
||||
@Cacheable(cacheNames=CacheConstant.SYS_USERS_CACHE, key="#username")
|
||||
public LoginUser getUserByName(String username) {
|
||||
@ -201,6 +203,8 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
info.setSysUserCode(user.getUsername());
|
||||
info.setSysUserName(user.getRealname());
|
||||
info.setSysOrgCode(user.getOrgCode());
|
||||
}else{
|
||||
return null;
|
||||
}
|
||||
//多部门支持in查询
|
||||
List<SysDepart> list = departMapper.queryUserDeparts(user.getId());
|
||||
@ -267,7 +271,7 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(value = CacheConstant.SYS_DICT_CACHE,key = "#code")
|
||||
@Cacheable(value = CacheConstant.SYS_DICT_CACHE,key = "#code", unless = "#result == null ")
|
||||
public List<DictModel> queryDictItemsByCode(String code) {
|
||||
return sysDictService.queryDictItemsByCode(code);
|
||||
}
|
||||
@ -294,6 +298,13 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
message.getTitle(),
|
||||
message.getContent(),
|
||||
message.getCategory());
|
||||
try {
|
||||
// 同步发送第三方APP消息
|
||||
wechatEnterpriseService.sendMessage(message, true);
|
||||
dingtalkService.sendMessage(message, true);
|
||||
} catch (Exception e) {
|
||||
log.error("同步发送第三方APP消息失败!", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -305,6 +316,13 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
message.getCategory(),
|
||||
message.getBusType(),
|
||||
message.getBusId());
|
||||
try {
|
||||
// 同步发送第三方APP消息
|
||||
wechatEnterpriseService.sendMessage(message, true);
|
||||
dingtalkService.sendMessage(message, true);
|
||||
} catch (Exception e) {
|
||||
log.error("同步发送第三方APP消息失败!", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -368,6 +386,13 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
webSocket.sendMessage(sysUser.getId(), obj.toJSONString());
|
||||
}
|
||||
}
|
||||
try {
|
||||
// 同步企业微信、钉钉的消息通知
|
||||
dingtalkService.sendActionCardMessage(announcement, true);
|
||||
wechatEnterpriseService.sendTextCardMessage(announcement, true);
|
||||
} catch (Exception e) {
|
||||
log.error("同步发送第三方APP消息失败!", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -435,6 +460,14 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
webSocket.sendMessage(sysUser.getId(), obj.toJSONString());
|
||||
}
|
||||
}
|
||||
try {
|
||||
// 同步企业微信、钉钉的消息通知
|
||||
dingtalkService.sendActionCardMessage(announcement, true);
|
||||
wechatEnterpriseService.sendTextCardMessage(announcement, true);
|
||||
} catch (Exception e) {
|
||||
log.error("同步发送第三方APP消息失败!", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -492,8 +525,11 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
DB_TYPE = DataBaseConstant.DB_TYPE_SQLSERVER;
|
||||
}else if(dbType.indexOf("postgresql")>=0) {
|
||||
DB_TYPE = DataBaseConstant.DB_TYPE_POSTGRESQL;
|
||||
}else if(dbType.indexOf("mariadb")>=0) {
|
||||
DB_TYPE = DataBaseConstant.DB_TYPE_MARIADB;
|
||||
}else {
|
||||
throw new JeecgBootException("数据库类型:["+dbType+"]不识别!");
|
||||
log.error("数据库类型:[" + dbType + "]不识别!");
|
||||
//throw new JeecgBootException("数据库类型:["+dbType+"]不识别!");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
@ -848,7 +884,7 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
|
||||
/**
|
||||
* 36根据多个用户账号(逗号分隔),查询返回多个用户信息
|
||||
* @param orgCodes
|
||||
* @param usernames
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@ -867,7 +903,7 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
|
||||
/**
|
||||
* 37根据多个部门编码(逗号分隔),查询返回多个部门信息
|
||||
* @param usernames
|
||||
* @param orgCodes
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
|
||||
@ -1,27 +1,27 @@
|
||||
package org.jeecg.modules.system.service.impl;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.jeecg.common.constant.FillRuleConstant;
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
import org.jeecg.common.util.FillRuleUtil;
|
||||
import org.jeecg.common.util.YouBianCodeUtil;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.system.entity.SysCategory;
|
||||
import org.jeecg.modules.system.mapper.SysCategoryMapper;
|
||||
import org.jeecg.modules.system.model.TreeSelectModel;
|
||||
import org.jeecg.modules.system.service.ISysCategoryService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Description: 分类字典
|
||||
* @Author: jeecg-boot
|
||||
@ -204,4 +204,32 @@ public class SysCategoryServiceImpl extends ServiceImpl<SysCategoryMapper, SysCa
|
||||
return sb;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> loadDictItem(String ids) {
|
||||
return this.loadDictItem(ids, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> loadDictItem(String ids, boolean delNotExist) {
|
||||
String[] idArray = ids.split(",");
|
||||
LambdaQueryWrapper<SysCategory> query = new LambdaQueryWrapper<>();
|
||||
query.in(SysCategory::getId, Arrays.asList(idArray));
|
||||
// 查询数据
|
||||
List<SysCategory> list = super.list(query);
|
||||
// 取出name并返回
|
||||
List<String> textList;
|
||||
// update-begin--author:sunjianlei--date:20210514--for:新增delNotExist参数,设为false不删除数据库里不存在的key ----
|
||||
if (delNotExist) {
|
||||
textList = list.stream().map(SysCategory::getName).collect(Collectors.toList());
|
||||
} else {
|
||||
textList = new ArrayList<>();
|
||||
for (String id : idArray) {
|
||||
List<SysCategory> res = list.stream().filter(i -> id.equals(i.getId())).collect(Collectors.toList());
|
||||
textList.add(res.size() > 0 ? res.get(0).getName() : id);
|
||||
}
|
||||
}
|
||||
// update-end--author:sunjianlei--date:20210514--for:新增delNotExist参数,设为false不删除数据库里不存在的key ----
|
||||
return textList;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,8 +1,11 @@
|
||||
package org.jeecg.modules.system.service.impl;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.jeecg.common.constant.CacheConstant;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
@ -21,10 +24,7 @@ import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@ -468,7 +468,8 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
SysDepart depart = list.get(i);
|
||||
SysDepartTreeModel treeModel = new SysDepartTreeModel(depart);
|
||||
//TODO 异步树加载key拼接__+时间戳,以便于每次展开节点会刷新数据
|
||||
treeModel.setKey(treeModel.getKey()+"__"+System.currentTimeMillis());
|
||||
//treeModel.setKey(treeModel.getKey()+"__"+System.currentTimeMillis());
|
||||
treeModel.setKey(treeModel.getKey());
|
||||
Integer count=this.baseMapper.queryCountByPid(depart.getId());
|
||||
if(count>0){
|
||||
treeModel.setIsLeaf(false);
|
||||
@ -479,6 +480,59 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
}
|
||||
return records;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject queryAllParentIdByDepartId(String departId) {
|
||||
JSONObject result = new JSONObject();
|
||||
for (String id : departId.split(",")) {
|
||||
JSONObject all = this.queryAllParentId("id", id);
|
||||
result.put(id, all);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject queryAllParentIdByOrgCode(String orgCode) {
|
||||
JSONObject result = new JSONObject();
|
||||
for (String code : orgCode.split(",")) {
|
||||
JSONObject all = this.queryAllParentId("org_code", code);
|
||||
result.put(code, all);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询某个部门的所有父ID信息
|
||||
*
|
||||
* @param fieldName 字段名
|
||||
* @param value 值
|
||||
*/
|
||||
private JSONObject queryAllParentId(String fieldName, String value) {
|
||||
JSONObject data = new JSONObject();
|
||||
// 父ID集合,有序
|
||||
data.put("parentIds", new JSONArray());
|
||||
// 父ID的部门数据,key是id,value是数据
|
||||
data.put("parentMap", new JSONObject());
|
||||
this.queryAllParentIdRecursion(fieldName, value, data);
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归调用查询父部门接口
|
||||
*/
|
||||
private void queryAllParentIdRecursion(String fieldName, String value, JSONObject data) {
|
||||
QueryWrapper<SysDepart> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq(fieldName, value);
|
||||
SysDepart depart = super.getOne(queryWrapper);
|
||||
if (depart != null) {
|
||||
data.getJSONArray("parentIds").add(0, depart.getId());
|
||||
data.getJSONObject("parentMap").put(depart.getId(), depart);
|
||||
if (oConvertUtils.isNotEmpty(depart.getParentId())) {
|
||||
this.queryAllParentIdRecursion("id", depart.getParentId(), data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysDepart queryCompByOrgCode(String orgCode) {
|
||||
int length = YouBianCodeUtil.zhanweiLength;
|
||||
|
||||
@ -9,6 +9,7 @@ import org.jeecg.common.constant.CacheConstant;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.system.vo.DictModel;
|
||||
import org.jeecg.common.system.vo.DictQuery;
|
||||
import org.jeecg.common.util.SqlInjectionUtil;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.system.entity.SysDict;
|
||||
import org.jeecg.modules.system.entity.SysDictItem;
|
||||
@ -50,7 +51,7 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@Cacheable(value = CacheConstant.SYS_DICT_CACHE,key = "#code")
|
||||
@Cacheable(value = CacheConstant.SYS_DICT_CACHE,key = "#code", unless = "#result == null ")
|
||||
public List<DictModel> queryDictItemsByCode(String code) {
|
||||
log.debug("无缓存dictCache的时候调用这里!");
|
||||
return sysDictMapper.queryDictItemsByCode(code);
|
||||
@ -86,7 +87,7 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
*/
|
||||
|
||||
@Override
|
||||
@Cacheable(value = CacheConstant.SYS_DICT_CACHE,key = "#code+':'+#key")
|
||||
@Cacheable(value = CacheConstant.SYS_DICT_CACHE,key = "#code+':'+#key", unless = "#result == null ")
|
||||
public String queryDictTextByKey(String code, String key) {
|
||||
log.debug("无缓存dictText的时候调用这里!");
|
||||
return sysDictMapper.queryDictTextByKey(code, key);
|
||||
@ -123,12 +124,17 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@Cacheable(value = CacheConstant.SYS_DICT_TABLE_CACHE)
|
||||
@Cacheable(value = CacheConstant.SYS_DICT_TABLE_CACHE, unless = "#result == null ")
|
||||
public String queryTableDictTextByKey(String table,String text,String code, String key) {
|
||||
log.debug("无缓存dictTable的时候调用这里!");
|
||||
return sysDictMapper.queryTableDictTextByKey(table,text,code,key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> queryTableDictByKeys(String table, String text, String code, String keys) {
|
||||
return this.queryTableDictByKeys(table, text, code, keys, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过查询指定table的 text code 获取字典,包含text和value
|
||||
* dictTableCache采用redis缓存有效期10分钟
|
||||
@ -136,28 +142,33 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
* @param text
|
||||
* @param code
|
||||
* @param keys (逗号分隔)
|
||||
* @param delNotExist 是否移除不存在的项,默认为true,设为false如果某个key不存在数据库中,则直接返回key本身
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
//update-begin--Author:lvdandan Date:20201204 for:JT-36【online】树形列表bug修改后,还是显示原来值 暂时去掉缓存
|
||||
//@Cacheable(value = CacheConstant.SYS_DICT_TABLE_BY_KEYS_CACHE)
|
||||
//update-end--Author:lvdandan Date:20201204 for:JT-36【online】树形列表bug修改后,还是显示原来值 暂时去掉缓存
|
||||
public List<String> queryTableDictByKeys(String table, String text, String code, String keys) {
|
||||
public List<String> queryTableDictByKeys(String table, String text, String code, String keys, boolean delNotExist) {
|
||||
if(oConvertUtils.isEmpty(keys)){
|
||||
return null;
|
||||
}
|
||||
String[] keyArray = keys.split(",");
|
||||
List<DictModel> dicts = sysDictMapper.queryTableDictByKeys(table, text, code, keyArray);
|
||||
List<String> texts = new ArrayList<>(dicts.size());
|
||||
|
||||
// update-begin--author:sunjianlei--date:20210514--for:新增delNotExist参数,设为false不删除数据库里不存在的key ----
|
||||
// 查询出来的顺序可能是乱的,需要排个序
|
||||
for (String key : keyArray) {
|
||||
for (DictModel dict : dicts) {
|
||||
if (key.equals(dict.getValue())) {
|
||||
texts.add(dict.getText());
|
||||
break;
|
||||
}
|
||||
List<DictModel> res = dicts.stream().filter(i -> key.equals(i.getValue())).collect(Collectors.toList());
|
||||
if (res.size() > 0) {
|
||||
texts.add(res.get(0).getText());
|
||||
} else if (!delNotExist) {
|
||||
texts.add(key);
|
||||
}
|
||||
}
|
||||
// update-end--author:sunjianlei--date:20210514--for:新增delNotExist参数,设为false不删除数据库里不存在的key ----
|
||||
|
||||
return texts;
|
||||
}
|
||||
|
||||
@ -205,12 +216,49 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictModel> queryLittleTableDictItems(String table, String text, String code, String keyword, int pageSize) {
|
||||
public List<DictModel> queryLittleTableDictItems(String table, String text, String code, String condition, String keyword, int pageSize) {
|
||||
Page<DictModel> page = new Page<DictModel>(1, pageSize);
|
||||
IPage<DictModel> pageList = baseMapper.queryTableDictItems(page, table, text, code, "%"+keyword+"%");
|
||||
page.setSearchCount(false);
|
||||
String filterSql = getFilterSql(text, code, condition, keyword);
|
||||
IPage<DictModel> pageList = baseMapper.queryTableDictWithFilter(page, table, text, code, filterSql);
|
||||
return pageList.getRecords();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取条件语句
|
||||
* @param text
|
||||
* @param code
|
||||
* @param condition
|
||||
* @param keyword
|
||||
* @return
|
||||
*/
|
||||
private String getFilterSql(String text, String code, String condition, String keyword){
|
||||
String keywordSql = null, filterSql = "", sql_where = " where ";
|
||||
if(oConvertUtils.isNotEmpty(keyword)){
|
||||
// 判断是否是多选
|
||||
if (keyword.contains(",")) {
|
||||
String inKeywords = "\"" + keyword.replaceAll(",", "\",\"") + "\"";
|
||||
keywordSql = "(" + text + " in (" + inKeywords + ") or " + code + " in (" + inKeywords + "))";
|
||||
} else {
|
||||
keywordSql = "("+text + " like '%"+keyword+"%' or "+ code + " like '%"+keyword+"%')";
|
||||
}
|
||||
}
|
||||
if(oConvertUtils.isNotEmpty(condition) && oConvertUtils.isNotEmpty(keywordSql)){
|
||||
filterSql+= sql_where + condition + " and " + keywordSql;
|
||||
}else if(oConvertUtils.isNotEmpty(condition)){
|
||||
filterSql+= sql_where + condition;
|
||||
}else if(oConvertUtils.isNotEmpty(keywordSql)){
|
||||
filterSql+= sql_where + keywordSql;
|
||||
}
|
||||
return filterSql;
|
||||
}
|
||||
@Override
|
||||
public List<DictModel> queryAllTableDictItems(String table, String text, String code, String condition, String keyword) {
|
||||
String filterSql = getFilterSql(text, code, condition, keyword);
|
||||
List<DictModel> ls = baseMapper.queryAllTableDictItems(table, text, code, filterSql);
|
||||
return ls;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TreeSelectModel> queryTreeList(Map<String, String> query,String table, String text, String code, String pidField,String pid,String hasChildField) {
|
||||
return baseMapper.queryTreeList(query,table, text, code, pidField, pid,hasChildField);
|
||||
@ -238,4 +286,61 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
Page<DictModel> pageList = baseMapper.queryDictTablePageList(page, query);
|
||||
return pageList.getRecords();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictModel> getDictItems(String dictCode) {
|
||||
List<DictModel> ls;
|
||||
if (dictCode.contains(",")) {
|
||||
//关联表字典(举例:sys_user,realname,id)
|
||||
String[] params = dictCode.split(",");
|
||||
if (params.length < 3) {
|
||||
// 字典Code格式不正确
|
||||
return null;
|
||||
}
|
||||
//SQL注入校验(只限制非法串改数据库)
|
||||
final String[] sqlInjCheck = {params[0], params[1], params[2]};
|
||||
SqlInjectionUtil.filterContent(sqlInjCheck);
|
||||
if (params.length == 4) {
|
||||
// SQL注入校验(查询条件SQL 特殊check,此方法仅供此处使用)
|
||||
SqlInjectionUtil.specialFilterContent(params[3]);
|
||||
ls = this.queryTableDictItemsByCodeAndFilter(params[0], params[1], params[2], params[3]);
|
||||
} else if (params.length == 3) {
|
||||
ls = this.queryTableDictItemsByCode(params[0], params[1], params[2]);
|
||||
} else {
|
||||
// 字典Code格式不正确
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
//字典表
|
||||
ls = this.queryDictItemsByCode(dictCode);
|
||||
}
|
||||
return ls;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictModel> loadDict(String dictCode, String keyword, Integer pageSize) {
|
||||
if (dictCode.contains(",")) {
|
||||
//update-begin-author:taoyan date:20210329 for: 下拉搜索不支持表名后加查询条件
|
||||
String[] params = dictCode.split(",");
|
||||
String condition = null;
|
||||
if (params.length != 3 && params.length != 4) {
|
||||
// 字典Code格式不正确
|
||||
return null;
|
||||
} else if (params.length == 4) {
|
||||
condition = params[3];
|
||||
}
|
||||
List<DictModel> ls;
|
||||
if (pageSize != null) {
|
||||
ls = this.queryLittleTableDictItems(params[0], params[1], params[2], condition, keyword, pageSize);
|
||||
} else {
|
||||
ls = this.queryAllTableDictItems(params[0], params[1], params[2], condition, keyword);
|
||||
}
|
||||
//update-end-author:taoyan date:20210329 for: 下拉搜索不支持表名后加查询条件
|
||||
return ls;
|
||||
} else {
|
||||
// 字典Code格式不正确
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package org.jeecg.modules.system.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.jeecg.modules.system.entity.SysPosition;
|
||||
import org.jeecg.modules.system.mapper.SysPositionMapper;
|
||||
@ -15,4 +16,11 @@ import org.springframework.stereotype.Service;
|
||||
@Service
|
||||
public class SysPositionServiceImpl extends ServiceImpl<SysPositionMapper, SysPosition> implements ISysPositionService {
|
||||
|
||||
@Override
|
||||
public SysPosition getByCode(String code) {
|
||||
LambdaQueryWrapper<SysPosition> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysPosition::getCode, code);
|
||||
return super.getOne(queryWrapper);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
package org.jeecg.modules.system.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.util.DateUtils;
|
||||
import org.jeecg.common.util.PasswordUtil;
|
||||
import org.jeecg.common.util.UUIDGenerator;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
@ -14,12 +16,10 @@ import org.jeecg.modules.system.mapper.SysThirdAccountMapper;
|
||||
import org.jeecg.modules.system.mapper.SysUserMapper;
|
||||
import org.jeecg.modules.system.mapper.SysUserRoleMapper;
|
||||
import org.jeecg.modules.system.service.ISysThirdAccountService;
|
||||
import org.jeecg.modules.system.service.ISysUserService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -55,7 +55,8 @@ public class SysThirdAccountServiceImpl extends ServiceImpl<SysThirdAccountMappe
|
||||
thirdQuery.eq(SysThirdAccount::getThirdType,account.getThirdType());
|
||||
SysThirdAccount sysThirdAccounts = sysThirdAccountMapper.selectOne(thirdQuery);
|
||||
if(sysThirdAccounts!=null){
|
||||
sysThirdAccountMapper.deleteById(sysThirdAccounts.getId());
|
||||
sysThirdAccount.setThirdUserId(sysThirdAccounts.getThirdUserId());
|
||||
sysThirdAccountMapper.deleteById(sysThirdAccounts.getId());
|
||||
}
|
||||
//更新用户账户表sys_user_id
|
||||
sysThirdAccountMapper.update(sysThirdAccount,query);
|
||||
@ -67,6 +68,13 @@ public class SysThirdAccountServiceImpl extends ServiceImpl<SysThirdAccountMappe
|
||||
LambdaQueryWrapper<SysThirdAccount> query = new LambdaQueryWrapper<>();
|
||||
query.eq(SysThirdAccount::getThirdUserUuid,thirdUserUuid);
|
||||
SysThirdAccount account = sysThirdAccountMapper.selectOne(query);
|
||||
//通过用户名查询数据库是否已存在
|
||||
SysUser userByName = sysUserMapper.getUserByName(thirdUserUuid);
|
||||
if(null!=userByName){
|
||||
//如果账号存在的话,则自动加上一个时间戳
|
||||
String format = DateUtils.yyyymmddhhmmss.get().format(new Date());
|
||||
thirdUserUuid = thirdUserUuid + format;
|
||||
}
|
||||
//添加用户
|
||||
SysUser user = new SysUser();
|
||||
user.setActivitiSync(CommonConstant.ACT_SYNC_0);
|
||||
@ -103,4 +111,26 @@ public class SysThirdAccountServiceImpl extends ServiceImpl<SysThirdAccountMappe
|
||||
sysUserRoleMapper.insert(userRole);
|
||||
return userid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysThirdAccount getOneBySysUserId(String sysUserId, String thirdType) {
|
||||
LambdaQueryWrapper<SysThirdAccount> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysThirdAccount::getSysUserId, sysUserId);
|
||||
queryWrapper.eq(SysThirdAccount::getThirdType, thirdType);
|
||||
return super.getOne(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysThirdAccount getOneByThirdUserId(String thirdUserId, String thirdType) {
|
||||
LambdaQueryWrapper<SysThirdAccount> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysThirdAccount::getThirdUserId, thirdUserId);
|
||||
queryWrapper.eq(SysThirdAccount::getThirdType, thirdType);
|
||||
return super.getOne(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysThirdAccount> listThirdUserIdByUsername(String[] sysUsernameArr, String thirdType) {
|
||||
return sysThirdAccountMapper.selectThirdIdsByUsername(sysUsernameArr, thirdType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,11 +1,15 @@
|
||||
package org.jeecg.modules.system.service.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.system.entity.SysDepart;
|
||||
import org.jeecg.modules.system.entity.SysUser;
|
||||
@ -100,34 +104,58 @@ public class SysUserDepartServiceImpl extends ServiceImpl<SysUserDepartMapper, S
|
||||
*/
|
||||
@Override
|
||||
public List<SysUser> queryUserByDepCode(String depCode,String realname) {
|
||||
LambdaQueryWrapper<SysDepart> queryByDepCode = new LambdaQueryWrapper<SysDepart>();
|
||||
queryByDepCode.likeRight(SysDepart::getOrgCode,depCode);
|
||||
List<SysDepart> sysDepartList = sysDepartService.list(queryByDepCode);
|
||||
List<String> depIds = sysDepartList.stream().map(SysDepart::getId).collect(Collectors.toList());
|
||||
|
||||
LambdaQueryWrapper<SysUserDepart> queryUDep = new LambdaQueryWrapper<SysUserDepart>();
|
||||
queryUDep.in(SysUserDepart::getDepId, depIds);
|
||||
List<String> userIdList = new ArrayList<>();
|
||||
List<SysUserDepart> uDepList = this.list(queryUDep);
|
||||
if(uDepList != null && uDepList.size() > 0) {
|
||||
for(SysUserDepart uDep : uDepList) {
|
||||
userIdList.add(uDep.getUserId());
|
||||
}
|
||||
LambdaQueryWrapper<SysUser> queryUser = new LambdaQueryWrapper<SysUser>();
|
||||
queryUser.in(SysUser::getId,userIdList);
|
||||
if(oConvertUtils.isNotEmpty(realname)){
|
||||
queryUser.like(SysUser::getRealname,realname.trim());
|
||||
}
|
||||
List<SysUser> userList = (List<SysUser>) sysUserService.list(queryUser);
|
||||
//update-begin-author:taoyan date:201905047 for:接口调用查询返回结果不能返回密码相关信息
|
||||
for (SysUser sysUser : userList) {
|
||||
sysUser.setSalt("");
|
||||
sysUser.setPassword("");
|
||||
}
|
||||
//update-end-author:taoyan date:201905047 for:接口调用查询返回结果不能返回密码相关信息
|
||||
return userList;
|
||||
//update-begin-author:taoyan date:20210422 for: 根据部门选择用户接口代码优化
|
||||
if(oConvertUtils.isNotEmpty(realname)){
|
||||
realname = realname.trim();
|
||||
}
|
||||
return new ArrayList<SysUser>();
|
||||
List<SysUser> userList = this.baseMapper.queryDepartUserList(depCode, realname);
|
||||
Map<String, SysUser> map = new HashMap<String, SysUser>();
|
||||
for (SysUser sysUser : userList) {
|
||||
// 返回的用户数据去掉密码信息
|
||||
sysUser.setSalt("");
|
||||
sysUser.setPassword("");
|
||||
map.put(sysUser.getId(), sysUser);
|
||||
}
|
||||
return new ArrayList<SysUser>(map.values());
|
||||
//update-end-author:taoyan date:20210422 for: 根据部门选择用户接口代码优化
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public IPage<SysUser> queryDepartUserPageList(String departId, String username, String realname, int pageSize, int pageNo) {
|
||||
IPage<SysUser> pageList = null;
|
||||
// 部门ID不存在 直接查询用户表即可
|
||||
Page<SysUser> page = new Page<SysUser>(pageNo, pageSize);
|
||||
if(oConvertUtils.isEmpty(departId)){
|
||||
LambdaQueryWrapper<SysUser> query = new LambdaQueryWrapper<>();
|
||||
if(oConvertUtils.isNotEmpty(username)){
|
||||
query.like(SysUser::getUsername, username);
|
||||
}
|
||||
pageList = sysUserService.page(page, query);
|
||||
}else{
|
||||
// 有部门ID 需要走自定义sql
|
||||
SysDepart sysDepart = sysDepartService.getById(departId);
|
||||
pageList = this.baseMapper.queryDepartUserPageList(page, sysDepart.getOrgCode(), username, realname);
|
||||
}
|
||||
List<SysUser> userList = pageList.getRecords();
|
||||
if(userList!=null && userList.size()>0){
|
||||
List<String> userIds = userList.stream().map(SysUser::getId).collect(Collectors.toList());
|
||||
Map<String, SysUser> map = new HashMap<String, SysUser>();
|
||||
if(userIds!=null && userIds.size()>0){
|
||||
// 查部门名称
|
||||
Map<String,String> useDepNames = sysUserService.getDepNamesByUserIds(userIds);
|
||||
userList.forEach(item->{
|
||||
//TODO 临时借用这个字段用于页面展示
|
||||
item.setOrgCodeTxt(useDepNames.get(item.getId()));
|
||||
item.setSalt("");
|
||||
item.setPassword("");
|
||||
// 去重
|
||||
map.put(item.getId(), item);
|
||||
});
|
||||
}
|
||||
pageList.setRecords(new ArrayList<SysUser>(map.values()));
|
||||
}
|
||||
return pageList;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -10,12 +10,12 @@ import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.CacheConstant;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||
import org.jeecg.modules.base.service.BaseCommonService;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.system.vo.SysUserCacheInfo;
|
||||
import org.jeecg.common.util.PasswordUtil;
|
||||
import org.jeecg.common.util.UUIDGenerator;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.base.service.BaseCommonService;
|
||||
import org.jeecg.modules.system.entity.*;
|
||||
import org.jeecg.modules.system.mapper.*;
|
||||
import org.jeecg.modules.system.model.SysUserSysDepartModel;
|
||||
@ -62,6 +62,12 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
private SysDepartRoleMapper sysDepartRoleMapper;
|
||||
@Resource
|
||||
private BaseCommonService baseCommonService;
|
||||
@Autowired
|
||||
private SysThirdAccountMapper sysThirdAccountMapper;
|
||||
@Autowired
|
||||
ThirdAppWechatEnterpriseServiceImpl wechatEnterpriseService;
|
||||
@Autowired
|
||||
ThirdAppDingtalkServiceImpl dingtalkService;
|
||||
|
||||
@Override
|
||||
@CacheEvict(value = {CacheConstant.SYS_USERS_CACHE}, allEntries = true)
|
||||
@ -408,6 +414,16 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
line += sysUserDepartMapper.delete(new LambdaQueryWrapper<SysUserDepart>().in(SysUserDepart::getUserId, userIds));
|
||||
//3. 删除用户角色关系
|
||||
line += sysUserRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().in(SysUserRole::getUserId, userIds));
|
||||
//4.同步删除第三方App的用户
|
||||
try {
|
||||
dingtalkService.removeThirdAppUser(userIds);
|
||||
wechatEnterpriseService.removeThirdAppUser(userIds);
|
||||
} catch (Exception e) {
|
||||
log.error("同步删除第三方App的用户失败:", e);
|
||||
}
|
||||
//5. 删除第三方用户表(因为第4步需要用到第三方用户表,所以在他之后删)
|
||||
line += sysThirdAccountMapper.delete(new LambdaQueryWrapper<SysThirdAccount>().in(SysThirdAccount::getSysUserId, userIds));
|
||||
|
||||
return line != 0;
|
||||
}
|
||||
|
||||
@ -439,4 +455,88 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
return userMapper.queryByDepIds(departIds,username);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void saveUser(SysUser user, String selectedRoles, String selectedDeparts) {
|
||||
//step.1 保存用户
|
||||
this.save(user);
|
||||
//step.2 保存角色
|
||||
if(oConvertUtils.isNotEmpty(selectedRoles)) {
|
||||
String[] arr = selectedRoles.split(",");
|
||||
for (String roleId : arr) {
|
||||
SysUserRole userRole = new SysUserRole(user.getId(), roleId);
|
||||
sysUserRoleMapper.insert(userRole);
|
||||
}
|
||||
}
|
||||
//step.3 保存所属部门
|
||||
if(oConvertUtils.isNotEmpty(selectedDeparts)) {
|
||||
String[] arr = selectedDeparts.split(",");
|
||||
for (String deaprtId : arr) {
|
||||
SysUserDepart userDeaprt = new SysUserDepart(user.getId(), deaprtId);
|
||||
sysUserDepartMapper.insert(userDeaprt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@CacheEvict(value={CacheConstant.SYS_USERS_CACHE}, allEntries=true)
|
||||
public void editUser(SysUser user, String roles, String departs) {
|
||||
//step.1 修改用户基础信息
|
||||
this.updateById(user);
|
||||
//step.2 修改角色
|
||||
//处理用户角色 先删后加
|
||||
sysUserRoleMapper.delete(new QueryWrapper<SysUserRole>().lambda().eq(SysUserRole::getUserId, user.getId()));
|
||||
if(oConvertUtils.isNotEmpty(roles)) {
|
||||
String[] arr = roles.split(",");
|
||||
for (String roleId : arr) {
|
||||
SysUserRole userRole = new SysUserRole(user.getId(), roleId);
|
||||
sysUserRoleMapper.insert(userRole);
|
||||
}
|
||||
}
|
||||
|
||||
//step.3 修改部门
|
||||
String[] arr = {};
|
||||
if(oConvertUtils.isNotEmpty(departs)){
|
||||
arr = departs.split(",");
|
||||
}
|
||||
//查询已关联部门
|
||||
List<SysUserDepart> userDepartList = sysUserDepartMapper.selectList(new QueryWrapper<SysUserDepart>().lambda().eq(SysUserDepart::getUserId, user.getId()));
|
||||
if(userDepartList != null && userDepartList.size()>0){
|
||||
for(SysUserDepart depart : userDepartList ){
|
||||
//修改已关联部门删除部门用户角色关系
|
||||
if(!Arrays.asList(arr).contains(depart.getDepId())){
|
||||
List<SysDepartRole> sysDepartRoleList = sysDepartRoleMapper.selectList(
|
||||
new QueryWrapper<SysDepartRole>().lambda().eq(SysDepartRole::getDepartId,depart.getDepId()));
|
||||
List<String> roleIds = sysDepartRoleList.stream().map(SysDepartRole::getId).collect(Collectors.toList());
|
||||
if(roleIds != null && roleIds.size()>0){
|
||||
departRoleUserMapper.delete(new QueryWrapper<SysDepartRoleUser>().lambda().eq(SysDepartRoleUser::getUserId, user.getId())
|
||||
.in(SysDepartRoleUser::getDroleId,roleIds));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//先删后加
|
||||
sysUserDepartMapper.delete(new QueryWrapper<SysUserDepart>().lambda().eq(SysUserDepart::getUserId, user.getId()));
|
||||
if(oConvertUtils.isNotEmpty(departs)) {
|
||||
for (String departId : arr) {
|
||||
SysUserDepart userDepart = new SysUserDepart(user.getId(), departId);
|
||||
sysUserDepartMapper.insert(userDepart);
|
||||
}
|
||||
}
|
||||
//step.4 修改手机号和邮箱
|
||||
// 更新手机号、邮箱空字符串为 null
|
||||
userMapper.updateNullByEmptyString("email");
|
||||
userMapper.updateNullByEmptyString("phone");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> userIdToUsername(Collection<String> userIdList) {
|
||||
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.in(SysUser::getId, userIdList);
|
||||
List<SysUser> userList = super.list(queryWrapper);
|
||||
return userList.stream().map(SysUser::getUsername).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,769 @@
|
||||
package org.jeecg.modules.system.service.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.jeecg.dingtalk.api.base.JdtBaseAPI;
|
||||
import com.jeecg.dingtalk.api.core.response.Response;
|
||||
import com.jeecg.dingtalk.api.core.vo.AccessToken;
|
||||
import com.jeecg.dingtalk.api.core.vo.PageResult;
|
||||
import com.jeecg.dingtalk.api.department.JdtDepartmentAPI;
|
||||
import com.jeecg.dingtalk.api.department.vo.Department;
|
||||
import com.jeecg.dingtalk.api.message.JdtMessageAPI;
|
||||
import com.jeecg.dingtalk.api.message.vo.ActionCardMessage;
|
||||
import com.jeecg.dingtalk.api.message.vo.Message;
|
||||
import com.jeecg.dingtalk.api.message.vo.TextMessage;
|
||||
import com.jeecg.dingtalk.api.user.JdtUserAPI;
|
||||
import com.jeecg.dingtalk.api.user.body.GetUserListBody;
|
||||
import com.jeecg.dingtalk.api.user.vo.User;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.jeecg.common.api.dto.message.MessageDTO;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.system.util.JwtUtil;
|
||||
import org.jeecg.common.util.PasswordUtil;
|
||||
import org.jeecg.common.util.RestUtil;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.config.thirdapp.ThirdAppConfig;
|
||||
import org.jeecg.modules.system.entity.*;
|
||||
import org.jeecg.modules.system.mapper.SysAnnouncementSendMapper;
|
||||
import org.jeecg.modules.system.model.SysDepartTreeModel;
|
||||
import org.jeecg.modules.system.service.*;
|
||||
import org.jeecg.modules.system.vo.thirdapp.JdtDepartmentTreeVo;
|
||||
import org.jeecg.modules.system.vo.thirdapp.SyncInfoVo;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
/**
|
||||
* 第三方App对接:钉钉实现类
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
|
||||
|
||||
@Autowired
|
||||
ThirdAppConfig thirdAppConfig;
|
||||
|
||||
@Autowired
|
||||
private ISysDepartService sysDepartService;
|
||||
@Autowired
|
||||
private ISysUserService sysUserService;
|
||||
@Autowired
|
||||
private ISysThirdAccountService sysThirdAccountService;
|
||||
@Autowired
|
||||
private ISysUserDepartService sysUserDepartService;
|
||||
@Autowired
|
||||
private ISysPositionService sysPositionService;
|
||||
@Autowired
|
||||
private SysAnnouncementSendMapper sysAnnouncementSendMapper;
|
||||
|
||||
@Override
|
||||
public String getAccessToken() {
|
||||
String appKey = thirdAppConfig.getDingtalk().getClientId();
|
||||
String appSecret = thirdAppConfig.getDingtalk().getClientSecret();
|
||||
AccessToken accessToken = JdtBaseAPI.getAccessToken(appKey, appSecret);
|
||||
if (accessToken != null) {
|
||||
return accessToken.getAccessToken();
|
||||
}
|
||||
log.warn("获取AccessToken失败");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean syncLocalDepartmentToThirdApp(String ids) {
|
||||
String accessToken = this.getAccessToken();
|
||||
if (accessToken == null) {
|
||||
return false;
|
||||
}
|
||||
// 获取【钉钉】所有的部门
|
||||
List<Department> departments = JdtDepartmentAPI.listAll(accessToken);
|
||||
// 删除钉钉有但本地没有的部门(以本地部门数据为主)(钉钉不能创建同名部门,只能先删除)
|
||||
List<SysDepart> sysDepartList = sysDepartService.list();
|
||||
for1:
|
||||
for (Department department : departments) {
|
||||
for (SysDepart depart : sysDepartList) {
|
||||
// id相同,代表已存在,不删除
|
||||
String sourceIdentifier = department.getSource_identifier();
|
||||
if (sourceIdentifier != null && sourceIdentifier.equals(depart.getId())) {
|
||||
continue for1;
|
||||
}
|
||||
}
|
||||
// 循环到此说明本地没有,删除
|
||||
int deptId = department.getDept_id();
|
||||
// 钉钉不允许删除带有用户的部门,所以需要判断下,将有用户的部门的用户移动至根部门
|
||||
Response<List<String>> userIdRes = JdtUserAPI.getUserListIdByDeptId(deptId, accessToken);
|
||||
if (userIdRes.isSuccess() && userIdRes.getResult().size() > 0) {
|
||||
for (String userId : userIdRes.getResult()) {
|
||||
User updateUser = new User();
|
||||
updateUser.setUserid(userId);
|
||||
updateUser.setDept_id_list(1);
|
||||
JdtUserAPI.update(updateUser, accessToken);
|
||||
}
|
||||
}
|
||||
JdtDepartmentAPI.delete(deptId, accessToken);
|
||||
}
|
||||
// 获取本地所有部门树结构
|
||||
List<SysDepartTreeModel> sysDepartsTree = sysDepartService.queryTreeList();
|
||||
// -- 钉钉不能创建新的顶级部门,所以新的顶级部门的parentId就为1
|
||||
Department parent = new Department();
|
||||
parent.setDept_id(1);
|
||||
// 递归同步部门
|
||||
departments = JdtDepartmentAPI.listAll(accessToken);
|
||||
this.syncDepartmentRecursion(sysDepartsTree, departments, parent, accessToken);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 递归同步部门到本地
|
||||
public void syncDepartmentRecursion(List<SysDepartTreeModel> sysDepartsTree, List<Department> departments, Department parent, String accessToken) {
|
||||
if (sysDepartsTree != null && sysDepartsTree.size() != 0) {
|
||||
for1:
|
||||
for (SysDepartTreeModel depart : sysDepartsTree) {
|
||||
for (Department department : departments) {
|
||||
// id相同,代表已存在,执行修改操作
|
||||
String sourceIdentifier = department.getSource_identifier();
|
||||
if (sourceIdentifier != null && sourceIdentifier.equals(depart.getId())) {
|
||||
this.sysDepartToDtDepartment(depart, department, parent.getDept_id());
|
||||
JdtDepartmentAPI.update(department, accessToken);
|
||||
// 紧接着同步子级
|
||||
this.syncDepartmentRecursion(depart.getChildren(), departments, department, accessToken);
|
||||
// 跳出外部循环
|
||||
continue for1;
|
||||
}
|
||||
}
|
||||
// 循环到此说明是新部门,直接调接口创建
|
||||
Department newDepartment = this.sysDepartToDtDepartment(depart, parent.getDept_id());
|
||||
Response<Integer> response = JdtDepartmentAPI.create(newDepartment, accessToken);
|
||||
// 创建成功,将返回的id绑定到本地
|
||||
if (response.getResult() != null) {
|
||||
Department newParent = new Department();
|
||||
newParent.setDept_id(response.getResult());
|
||||
// 紧接着同步子级
|
||||
this.syncDepartmentRecursion(depart.getChildren(), departments, newParent, accessToken);
|
||||
}
|
||||
// 收集错误信息
|
||||
// this.syncUserCollectErrInfo(errCode, sysUser, errInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SyncInfoVo syncThirdAppDepartmentToLocal(String ids) {
|
||||
SyncInfoVo syncInfo = new SyncInfoVo();
|
||||
String accessToken = this.getAccessToken();
|
||||
if (accessToken == null) {
|
||||
syncInfo.addFailInfo("accessToken获取失败!");
|
||||
return syncInfo;
|
||||
}
|
||||
// 获取【钉钉】所有的部门
|
||||
List<Department> departments = JdtDepartmentAPI.listAll(accessToken);
|
||||
String username = JwtUtil.getUserNameByToken(SpringContextUtils.getHttpServletRequest());
|
||||
List<JdtDepartmentTreeVo> departmentTreeList = JdtDepartmentTreeVo.listToTree(departments);
|
||||
// 递归同步部门
|
||||
this.syncDepartmentToLocalRecursion(departmentTreeList, null, username, syncInfo, accessToken);
|
||||
return syncInfo;
|
||||
}
|
||||
|
||||
public void syncDepartmentToLocalRecursion(List<JdtDepartmentTreeVo> departmentTreeList, String sysParentId, String username, SyncInfoVo syncInfo, String accessToken) {
|
||||
|
||||
if (departmentTreeList != null && departmentTreeList.size() != 0) {
|
||||
for (JdtDepartmentTreeVo departmentTree : departmentTreeList) {
|
||||
LambdaQueryWrapper<SysDepart> queryWrapper = new LambdaQueryWrapper<>();
|
||||
// 根据 source_identifier 字段查询
|
||||
queryWrapper.eq(SysDepart::getId, departmentTree.getSource_identifier());
|
||||
SysDepart sysDepart = sysDepartService.getOne(queryWrapper);
|
||||
if (sysDepart != null) {
|
||||
// 执行更新操作
|
||||
SysDepart updateSysDepart = this.dtDepartmentToSysDepart(departmentTree, sysDepart);
|
||||
if (sysParentId != null) {
|
||||
updateSysDepart.setParentId(sysParentId);
|
||||
}
|
||||
try {
|
||||
sysDepartService.updateDepartDataById(updateSysDepart, username);
|
||||
String str = String.format("部门 %s 更新成功!", updateSysDepart.getDepartName());
|
||||
syncInfo.addSuccessInfo(str);
|
||||
} catch (Exception e) {
|
||||
this.syncDepartCollectErrInfo(e, departmentTree, syncInfo);
|
||||
}
|
||||
if (departmentTree.hasChildren()) {
|
||||
// 紧接着同步子级
|
||||
this.syncDepartmentToLocalRecursion(departmentTree.getChildren(), updateSysDepart.getId(), username, syncInfo, accessToken);
|
||||
}
|
||||
} else {
|
||||
// 执行新增操作
|
||||
SysDepart newSysDepart = this.dtDepartmentToSysDepart(departmentTree, null);
|
||||
if (sysParentId != null) {
|
||||
newSysDepart.setParentId(sysParentId);
|
||||
}
|
||||
try {
|
||||
sysDepartService.saveDepartData(newSysDepart, username);
|
||||
// 更新钉钉 source_identifier
|
||||
Department updateDtDepart = new Department();
|
||||
updateDtDepart.setDept_id(departmentTree.getDept_id());
|
||||
updateDtDepart.setSource_identifier(newSysDepart.getId());
|
||||
Response response = JdtDepartmentAPI.update(updateDtDepart, accessToken);
|
||||
if (!response.isSuccess()) {
|
||||
throw new RuntimeException(response.getErrmsg());
|
||||
}
|
||||
String str = String.format("部门 %s 创建成功!", newSysDepart.getDepartName());
|
||||
syncInfo.addSuccessInfo(str);
|
||||
} catch (Exception e) {
|
||||
this.syncDepartCollectErrInfo(e, departmentTree, syncInfo);
|
||||
}
|
||||
// 紧接着同步子级
|
||||
if (departmentTree.hasChildren()) {
|
||||
this.syncDepartmentToLocalRecursion(departmentTree.getChildren(), newSysDepart.getId(), username, syncInfo, accessToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean syncDepartCollectErrInfo(Exception e, Department department, SyncInfoVo syncInfo) {
|
||||
String msg;
|
||||
if (e instanceof DuplicateKeyException) {
|
||||
msg = e.getCause().getMessage();
|
||||
} else {
|
||||
msg = e.getMessage();
|
||||
}
|
||||
String str = String.format("部门 %s(%s) 同步失败!错误信息:%s", department.getName(), department.getDept_id(), msg);
|
||||
syncInfo.addFailInfo(str);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SyncInfoVo syncLocalUserToThirdApp(String ids) {
|
||||
SyncInfoVo syncInfo = new SyncInfoVo();
|
||||
String accessToken = this.getAccessToken();
|
||||
if (accessToken == null) {
|
||||
syncInfo.addFailInfo("accessToken获取失败!");
|
||||
return syncInfo;
|
||||
}
|
||||
List<SysUser> sysUsers;
|
||||
if (StringUtils.isNotBlank(ids)) {
|
||||
String[] idList = ids.split(",");
|
||||
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.in(SysUser::getId, (Object[]) idList);
|
||||
// 获取本地指定用户
|
||||
sysUsers = sysUserService.list(queryWrapper);
|
||||
} else {
|
||||
// 获取本地所有用户
|
||||
sysUsers = sysUserService.list();
|
||||
}
|
||||
// 查询钉钉所有的部门,用于同步用户和部门的关系
|
||||
List<Department> allDepartment = JdtDepartmentAPI.listAll(accessToken);
|
||||
|
||||
for (SysUser sysUser : sysUsers) {
|
||||
// 外部模拟登陆临时账号,不同步
|
||||
if ("_reserve_user_external".equals(sysUser.getUsername())) {
|
||||
continue;
|
||||
}
|
||||
// 钉钉用户信息,不为null代表已同步过
|
||||
Response<User> dtUserInfo;
|
||||
/*
|
||||
* 判断是否同步过的逻辑:
|
||||
* 1. 查询 sys_third_account(第三方账号表)是否有数据,如果有代表已同步
|
||||
* 2. 本地表里没有,就先用手机号判断,不通过再用username判断。
|
||||
*/
|
||||
SysThirdAccount sysThirdAccount = sysThirdAccountService.getOneBySysUserId(sysUser.getId(), ThirdAppConfig.DINGTALK.toLowerCase());
|
||||
if (sysThirdAccount != null && oConvertUtils.isNotEmpty(sysThirdAccount.getThirdUserId())) {
|
||||
// sys_third_account 表匹配成功,通过第三方userId查询出第三方userInfo
|
||||
dtUserInfo = JdtUserAPI.getUserById(sysThirdAccount.getThirdUserId(), accessToken);
|
||||
} else {
|
||||
// 手机号匹配
|
||||
Response<String> thirdUserId = JdtUserAPI.getUseridByMobile(sysUser.getPhone(), accessToken);
|
||||
// 手机号匹配成功
|
||||
if (thirdUserId.isSuccess() && oConvertUtils.isNotEmpty(thirdUserId.getResult())) {
|
||||
// 通过查询到的userId查询用户详情
|
||||
dtUserInfo = JdtUserAPI.getUserById(thirdUserId.getResult(), accessToken);
|
||||
} else {
|
||||
// 手机号匹配失败,尝试使用username匹配
|
||||
dtUserInfo = JdtUserAPI.getUserById(sysUser.getUsername(), accessToken);
|
||||
}
|
||||
}
|
||||
String dtUserId;
|
||||
// api 接口是否执行成功
|
||||
boolean apiSuccess;
|
||||
// 已同步就更新,否则就创建
|
||||
if (dtUserInfo != null && dtUserInfo.isSuccess() && dtUserInfo.getResult() != null) {
|
||||
User dtUser = dtUserInfo.getResult();
|
||||
dtUserId = dtUser.getUserid();
|
||||
User updateQwUser = this.sysUserToDtUser(sysUser, dtUser, allDepartment);
|
||||
Response<JSONObject> updateRes = JdtUserAPI.update(updateQwUser, accessToken);
|
||||
// 收集成功/失败信息
|
||||
apiSuccess = this.syncUserCollectErrInfo(updateRes, sysUser, syncInfo);
|
||||
} else {
|
||||
User newQwUser = this.sysUserToDtUser(sysUser, allDepartment);
|
||||
Response<String> createRes = JdtUserAPI.create(newQwUser, accessToken);
|
||||
dtUserId = createRes.getResult();
|
||||
// 收集成功/失败信息
|
||||
apiSuccess = this.syncUserCollectErrInfo(createRes, sysUser, syncInfo);
|
||||
}
|
||||
|
||||
// api 接口执行成功,并且 sys_third_account 表匹配失败,就向 sys_third_account 里插入一条数据
|
||||
if (apiSuccess && (sysThirdAccount == null || oConvertUtils.isEmpty(sysThirdAccount.getThirdUserId()))) {
|
||||
if (sysThirdAccount == null) {
|
||||
sysThirdAccount = new SysThirdAccount();
|
||||
sysThirdAccount.setSysUserId(sysUser.getId());
|
||||
sysThirdAccount.setStatus(1);
|
||||
sysThirdAccount.setDelFlag(0);
|
||||
sysThirdAccount.setThirdType(ThirdAppConfig.DINGTALK.toLowerCase());
|
||||
}
|
||||
// 设置第三方app用户ID
|
||||
sysThirdAccount.setThirdUserId(dtUserId);
|
||||
sysThirdAccountService.saveOrUpdate(sysThirdAccount);
|
||||
}
|
||||
}
|
||||
return syncInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SyncInfoVo syncThirdAppUserToLocal() {
|
||||
SyncInfoVo syncInfo = new SyncInfoVo();
|
||||
String accessToken = this.getAccessToken();
|
||||
if (accessToken == null) {
|
||||
syncInfo.addFailInfo("accessToken获取失败!");
|
||||
return syncInfo;
|
||||
}
|
||||
|
||||
// 获取本地用户
|
||||
List<SysUser> sysUsersList = sysUserService.list();
|
||||
|
||||
// 查询钉钉所有的部门,用于同步用户和部门的关系
|
||||
List<Department> allDepartment = JdtDepartmentAPI.listAll(accessToken);
|
||||
// 根据钉钉部门查询所有钉钉用户,用于反向同步到本地
|
||||
List<User> ddUserList = this.getDtAllUserByDepartment(allDepartment, accessToken);
|
||||
|
||||
for (User dtUserInfo : ddUserList) {
|
||||
SysThirdAccount sysThirdAccount = sysThirdAccountService.getOneByThirdUserId(dtUserInfo.getUserid(), ThirdAppConfig.DINGTALK.toLowerCase());
|
||||
List<SysUser> collect = sysUsersList.stream().filter(user -> (dtUserInfo.getMobile().equals(user.getPhone()) || dtUserInfo.getUserid().equals(user.getUsername()))
|
||||
).collect(Collectors.toList());
|
||||
if (collect != null && collect.size() > 0) {
|
||||
SysUser sysUserTemp = collect.get(0);
|
||||
// 循环到此说明用户匹配成功,进行更新操作
|
||||
SysUser updateSysUser = this.dtUserToSysUser(dtUserInfo, sysUserTemp);
|
||||
try {
|
||||
sysUserService.updateById(updateSysUser);
|
||||
String str = String.format("用户 %s(%s) 更新成功!", updateSysUser.getRealname(), updateSysUser.getUsername());
|
||||
syncInfo.addSuccessInfo(str);
|
||||
} catch (Exception e) {
|
||||
this.syncUserCollectErrInfo(e, dtUserInfo, syncInfo);
|
||||
}
|
||||
//第三方账号关系表
|
||||
this.thirdAccountSaveOrUpdate(sysThirdAccount, updateSysUser.getId(), dtUserInfo.getUserid());
|
||||
}else{
|
||||
// 如果没有匹配到用户,则走创建逻辑
|
||||
SysUser newSysUser = this.dtUserToSysUser(dtUserInfo);
|
||||
try {
|
||||
sysUserService.save(newSysUser);
|
||||
String str = String.format("用户 %s(%s) 创建成功!", newSysUser.getRealname(), newSysUser.getUsername());
|
||||
syncInfo.addSuccessInfo(str);
|
||||
} catch (Exception e) {
|
||||
this.syncUserCollectErrInfo(e, dtUserInfo, syncInfo);
|
||||
}
|
||||
//第三方账号关系表
|
||||
this.thirdAccountSaveOrUpdate(null, newSysUser.getId(), dtUserInfo.getUserid());
|
||||
}
|
||||
}
|
||||
return syncInfo;
|
||||
}
|
||||
|
||||
private List<User> getDtAllUserByDepartment(List<Department> allDepartment, String accessToken) {
|
||||
// 根据钉钉部门查询所有钉钉用户,用于反向同步到本地
|
||||
List<User> userList = new ArrayList<>();
|
||||
for (Department department : allDepartment) {
|
||||
this.getUserListByDeptIdRecursion(department.getDept_id(), 0, userList, accessToken);
|
||||
}
|
||||
return userList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归查询所有用户
|
||||
*/
|
||||
private void getUserListByDeptIdRecursion(int deptId, int cursor, List<User> userList, String accessToken) {
|
||||
// 根据钉钉部门查询所有钉钉用户,用于反向同步到本地
|
||||
GetUserListBody getUserListBody = new GetUserListBody(deptId, cursor, 100);
|
||||
Response<PageResult<User>> response = JdtUserAPI.getUserListByDeptId(getUserListBody, accessToken);
|
||||
if (response.isSuccess()) {
|
||||
PageResult<User> page = response.getResult();
|
||||
userList.addAll(page.getList());
|
||||
if (page.getHas_more()) {
|
||||
this.getUserListByDeptIdRecursion(deptId, page.getNext_cursor(), userList, accessToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存或修改第三方登录表
|
||||
*
|
||||
* @param sysThirdAccount 第三方账户表对象,为null就新增数据,否则就修改
|
||||
* @param sysUserId 本地系统用户ID
|
||||
* @param dtUserId 钉钉用户ID
|
||||
*/
|
||||
private void thirdAccountSaveOrUpdate(SysThirdAccount sysThirdAccount, String sysUserId, String dtUserId) {
|
||||
if (sysThirdAccount == null) {
|
||||
sysThirdAccount = new SysThirdAccount();
|
||||
sysThirdAccount.setSysUserId(sysUserId);
|
||||
sysThirdAccount.setStatus(1);
|
||||
sysThirdAccount.setDelFlag(0);
|
||||
sysThirdAccount.setThirdType(ThirdAppConfig.DINGTALK.toLowerCase());
|
||||
}
|
||||
sysThirdAccount.setThirdUserId(dtUserId);
|
||||
sysThirdAccountService.saveOrUpdate(sysThirdAccount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 【同步用户】收集同步过程中的错误信息
|
||||
*/
|
||||
private boolean syncUserCollectErrInfo(Response<?> response, SysUser sysUser, SyncInfoVo syncInfo) {
|
||||
if (!response.isSuccess()) {
|
||||
String str = String.format("用户 %s(%s) 同步失败!错误码:%s——%s", sysUser.getUsername(), sysUser.getRealname(), response.getErrcode(), response.getErrmsg());
|
||||
syncInfo.addFailInfo(str);
|
||||
return false;
|
||||
} else {
|
||||
String str = String.format("用户 %s(%s) 同步成功!", sysUser.getUsername(), sysUser.getRealname());
|
||||
syncInfo.addSuccessInfo(str);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 【同步用户】收集同步过程中的错误信息
|
||||
*/
|
||||
private boolean syncUserCollectErrInfo(Exception e, User dtUser, SyncInfoVo syncInfo) {
|
||||
String msg;
|
||||
if (e instanceof DuplicateKeyException) {
|
||||
msg = e.getCause().getMessage();
|
||||
} else {
|
||||
msg = e.getMessage();
|
||||
}
|
||||
String str = String.format("用户 %s(%s) 同步失败!错误信息:%s", dtUser.getUserid(), dtUser.getName(), msg);
|
||||
syncInfo.addFailInfo(str);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 【同步用户】将SysUser转为【钉钉】的User对象(创建新用户)
|
||||
*/
|
||||
private User sysUserToDtUser(SysUser sysUser, List<Department> allDepartment) {
|
||||
User user = new User();
|
||||
// 通过 username 来关联
|
||||
user.setUserid(sysUser.getUsername());
|
||||
return this.sysUserToDtUser(sysUser, user, allDepartment);
|
||||
}
|
||||
|
||||
/**
|
||||
* 【同步用户】将SysUser转为【钉钉】的User对象(更新旧用户)
|
||||
*/
|
||||
private User sysUserToDtUser(SysUser sysUser, User user, List<Department> allDepartment) {
|
||||
user.setName(sysUser.getRealname());
|
||||
user.setMobile(sysUser.getPhone());
|
||||
user.setTelephone(sysUser.getTelephone());
|
||||
user.setJob_number(sysUser.getWorkNo());
|
||||
// 职务翻译
|
||||
if (oConvertUtils.isNotEmpty(sysUser.getPost())) {
|
||||
SysPosition position = sysPositionService.getByCode(sysUser.getPost());
|
||||
if (position != null) {
|
||||
user.setTitle(position.getName());
|
||||
}
|
||||
}
|
||||
user.setEmail(sysUser.getEmail());
|
||||
// 查询并同步用户部门关系
|
||||
List<SysDepart> departList = this.getUserDepart(sysUser);
|
||||
if (departList != null) {
|
||||
List<Integer> departmentIdList = new ArrayList<>();
|
||||
for (SysDepart sysDepart : departList) {
|
||||
// 企业微信的部门id
|
||||
Department department = this.getDepartmentByDepartId(sysDepart.getId(), allDepartment);
|
||||
if (department != null) {
|
||||
departmentIdList.add(department.getDept_id());
|
||||
}
|
||||
}
|
||||
user.setDept_id_list(departmentIdList.toArray(new Integer[]{}));
|
||||
user.setDept_order_list(null);
|
||||
}
|
||||
if (oConvertUtils.isEmpty(user.getDept_id_list())) {
|
||||
// 没有找到匹配部门,同步到根部门下
|
||||
user.setDept_id_list(1);
|
||||
user.setDept_order_list(null);
|
||||
}
|
||||
// --- 钉钉没有逻辑删除功能
|
||||
// sysUser.getDelFlag()
|
||||
// --- 钉钉没有冻结、启用禁用功能
|
||||
// sysUser.getStatus()
|
||||
return user;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 【同步用户】将【钉钉】的User对象转为SysUser(创建新用户)
|
||||
*/
|
||||
private SysUser dtUserToSysUser(User dtUser) {
|
||||
SysUser sysUser = new SysUser();
|
||||
sysUser.setDelFlag(0);
|
||||
// 通过 username 来关联
|
||||
sysUser.setUsername(dtUser.getUserid());
|
||||
// 密码默认为 “123456”,随机加盐
|
||||
String password = "123456", salt = oConvertUtils.randomGen(8);
|
||||
String passwordEncode = PasswordUtil.encrypt(sysUser.getUsername(), password, salt);
|
||||
sysUser.setSalt(salt);
|
||||
sysUser.setPassword(passwordEncode);
|
||||
return this.dtUserToSysUser(dtUser, sysUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* 【同步用户】将【钉钉】的User对象转为SysUser(更新旧用户)
|
||||
*/
|
||||
private SysUser dtUserToSysUser(User dtUser, SysUser oldSysUser) {
|
||||
SysUser sysUser = new SysUser();
|
||||
BeanUtils.copyProperties(oldSysUser, sysUser);
|
||||
sysUser.setRealname(dtUser.getName());
|
||||
sysUser.setPhone(dtUser.getMobile());
|
||||
sysUser.setTelephone(dtUser.getTelephone());
|
||||
|
||||
// 因为唯一键约束的原因,如果原数据和旧数据相同,就不更新
|
||||
if (oConvertUtils.isNotEmpty(dtUser.getEmail()) && !dtUser.getEmail().equals(sysUser.getEmail())) {
|
||||
sysUser.setEmail(dtUser.getEmail());
|
||||
} else {
|
||||
sysUser.setEmail(null);
|
||||
}
|
||||
// 因为唯一键约束的原因,如果原数据和旧数据相同,就不更新
|
||||
if (oConvertUtils.isNotEmpty(dtUser.getMobile()) && !dtUser.getMobile().equals(sysUser.getPhone())) {
|
||||
sysUser.setPhone(dtUser.getMobile());
|
||||
} else {
|
||||
sysUser.setPhone(null);
|
||||
}
|
||||
sysUser.setWorkNo(null);
|
||||
// --- 钉钉没有逻辑删除功能
|
||||
// sysUser.getDelFlag()
|
||||
// --- 钉钉没有冻结、启用禁用功能
|
||||
// sysUser.getStatus()
|
||||
return sysUser;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询用户和部门的关系
|
||||
*/
|
||||
private List<SysDepart> getUserDepart(SysUser sysUser) {
|
||||
// 根据用户部门关系表查询出用户的部门
|
||||
LambdaQueryWrapper<SysUserDepart> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysUserDepart::getUserId, sysUser.getId());
|
||||
List<SysUserDepart> sysUserDepartList = sysUserDepartService.list(queryWrapper);
|
||||
if (sysUserDepartList.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
// 根据用户部门
|
||||
LambdaQueryWrapper<SysDepart> departQueryWrapper = new LambdaQueryWrapper<>();
|
||||
List<String> departIdList = sysUserDepartList.stream().map(SysUserDepart::getDepId).collect(Collectors.toList());
|
||||
departQueryWrapper.in(SysDepart::getId, departIdList);
|
||||
List<SysDepart> departList = sysDepartService.list(departQueryWrapper);
|
||||
return departList.size() == 0 ? null : departList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据sysDepartId查询钉钉的部门
|
||||
*/
|
||||
private Department getDepartmentByDepartId(String departId, List<Department> allDepartment) {
|
||||
for (Department department : allDepartment) {
|
||||
if (departId.equals(department.getSource_identifier())) {
|
||||
return department;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 【同步部门】将SysDepartTreeModel转为【钉钉】的Department对象(创建新部门)
|
||||
*/
|
||||
private Department sysDepartToDtDepartment(SysDepartTreeModel departTree, Integer parentId) {
|
||||
Department department = new Department();
|
||||
department.setSource_identifier(departTree.getId());
|
||||
return this.sysDepartToDtDepartment(departTree, department, parentId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 【同步部门】将SysDepartTreeModel转为【钉钉】的Department对象
|
||||
*/
|
||||
private Department sysDepartToDtDepartment(SysDepartTreeModel departTree, Department department, Integer parentId) {
|
||||
department.setName(departTree.getDepartName());
|
||||
department.setParent_id(parentId);
|
||||
department.setOrder(departTree.getDepartOrder());
|
||||
return department;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 【同步部门】将【钉钉】的Department对象转为SysDepartTreeModel
|
||||
*/
|
||||
private SysDepart dtDepartmentToSysDepart(Department department, SysDepart departTree) {
|
||||
SysDepart sysDepart = new SysDepart();
|
||||
if (departTree != null) {
|
||||
BeanUtils.copyProperties(departTree, sysDepart);
|
||||
}
|
||||
sysDepart.setDepartName(department.getName());
|
||||
sysDepart.setDepartOrder(department.getOrder());
|
||||
return sysDepart;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int removeThirdAppUser(List<String> userIdList) {
|
||||
// 判断启用状态
|
||||
if (!thirdAppConfig.isDingtalkEnabled()) {
|
||||
return -1;
|
||||
}
|
||||
int count = 0;
|
||||
if (userIdList != null && userIdList.size() > 0) {
|
||||
String accessToken = this.getAccessToken();
|
||||
if (accessToken == null) {
|
||||
return count;
|
||||
}
|
||||
LambdaQueryWrapper<SysThirdAccount> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysThirdAccount::getThirdType, ThirdAppConfig.DINGTALK.toLowerCase());
|
||||
queryWrapper.in(SysThirdAccount::getSysUserId, userIdList);
|
||||
// 根据userId,获取第三方用户的id
|
||||
List<SysThirdAccount> thirdAccountList = sysThirdAccountService.list(queryWrapper);
|
||||
List<String> thirdUserIdList = thirdAccountList.stream().map(SysThirdAccount::getThirdUserId).collect(Collectors.toList());
|
||||
|
||||
for (String thirdUserId : thirdUserIdList) {
|
||||
if (oConvertUtils.isNotEmpty(thirdUserId)) {
|
||||
// 没有批量删除的接口
|
||||
Response<JSONObject> response = JdtUserAPI.delete(thirdUserId, accessToken);
|
||||
if (response.getErrcode() == 0) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean sendMessage(MessageDTO message) {
|
||||
return this.sendMessage(message, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送消息
|
||||
*
|
||||
* @param message
|
||||
* @param verifyConfig
|
||||
* @return
|
||||
*/
|
||||
public boolean sendMessage(MessageDTO message, boolean verifyConfig) {
|
||||
Response<String> response = this.sendMessageResponse(message, verifyConfig);
|
||||
if (response != null) {
|
||||
return response.isSuccess();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Response<String> sendMessageResponse(MessageDTO message, boolean verifyConfig) {
|
||||
if (verifyConfig && !thirdAppConfig.isDingtalkEnabled()) {
|
||||
return null;
|
||||
}
|
||||
String accessToken = this.getAccessToken();
|
||||
if (accessToken == null) {
|
||||
return null;
|
||||
}
|
||||
// 封装钉钉消息
|
||||
String content = message.getContent();
|
||||
int agentId = thirdAppConfig.getDingtalk().getAgentIdInt();
|
||||
Message<TextMessage> textMessage = new Message<>(agentId, new TextMessage(content));
|
||||
if (message.isToAll()) {
|
||||
textMessage.setTo_all_user(true);
|
||||
} else {
|
||||
String[] toUsers = message.getToUser().split(",");
|
||||
// 通过第三方账号表查询出第三方userId
|
||||
List<SysThirdAccount> thirdAccountList = sysThirdAccountService.listThirdUserIdByUsername(toUsers, ThirdAppConfig.DINGTALK.toLowerCase());
|
||||
List<String> dtUserIds = thirdAccountList.stream().map(SysThirdAccount::getThirdUserId).collect(Collectors.toList());
|
||||
textMessage.setUserid_list(dtUserIds);
|
||||
}
|
||||
return JdtMessageAPI.sendTextMessage(textMessage, accessToken);
|
||||
}
|
||||
|
||||
public boolean recallMessage(String msg_task_id) {
|
||||
Response<JSONObject> response = this.recallMessageResponse(msg_task_id);
|
||||
if (response == null) {
|
||||
return false;
|
||||
}
|
||||
return response.isSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* 撤回消息
|
||||
*
|
||||
* @param msg_task_id
|
||||
* @return
|
||||
*/
|
||||
public Response<JSONObject> recallMessageResponse(String msg_task_id) {
|
||||
String accessToken = this.getAccessToken();
|
||||
if (accessToken == null) {
|
||||
return null;
|
||||
}
|
||||
int agentId = thirdAppConfig.getDingtalk().getAgentIdInt();
|
||||
return JdtMessageAPI.recallMessage(agentId, msg_task_id, getAccessToken());
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送卡片消息(SysAnnouncement定制)
|
||||
*
|
||||
* @param announcement
|
||||
* @param verifyConfig 是否验证配置(未启用的APP会拒绝发送)
|
||||
* @return
|
||||
*/
|
||||
public Response<String> sendActionCardMessage(SysAnnouncement announcement, boolean verifyConfig) {
|
||||
if (verifyConfig && !thirdAppConfig.isDingtalkEnabled()) {
|
||||
return null;
|
||||
}
|
||||
String accessToken = this.getAccessToken();
|
||||
if (accessToken == null) {
|
||||
return null;
|
||||
}
|
||||
int agentId = thirdAppConfig.getDingtalk().getAgentIdInt();
|
||||
String markdown = "### " + announcement.getTitile() + "\n" + oConvertUtils.getString(announcement.getMsgAbstract(),"空");
|
||||
ActionCardMessage actionCard = new ActionCardMessage(markdown);
|
||||
actionCard.setTitle(announcement.getTitile());
|
||||
actionCard.setSingle_title("详情");
|
||||
actionCard.setSingle_url(RestUtil.getBaseUrl() + "/sys/annountCement/show/" + announcement.getId());
|
||||
Message<ActionCardMessage> actionCardMessage = new Message<>(agentId, actionCard);
|
||||
if (CommonConstant.MSG_TYPE_ALL.equals(announcement.getMsgType())) {
|
||||
actionCardMessage.setTo_all_user(true);
|
||||
return JdtMessageAPI.sendActionCardMessage(actionCardMessage, accessToken);
|
||||
} else {
|
||||
// 将userId转为username
|
||||
String[] userIds = null;
|
||||
String userId = announcement.getUserIds();
|
||||
if(oConvertUtils.isNotEmpty(userId)){
|
||||
userIds = userId.substring(0, (userId.length() - 1)).split(",");
|
||||
}else{
|
||||
LambdaQueryWrapper<SysAnnouncementSend> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysAnnouncementSend::getAnntId, announcement.getId());
|
||||
SysAnnouncementSend sysAnnouncementSend = sysAnnouncementSendMapper.selectOne(queryWrapper);
|
||||
userIds = new String[] {sysAnnouncementSend.getUserId()};
|
||||
}
|
||||
|
||||
if(userIds!=null){
|
||||
String[] usernameList = sysUserService.userIdToUsername(Arrays.asList(userIds)).toArray(new String[]{});
|
||||
// 通过第三方账号表查询出第三方userId
|
||||
List<SysThirdAccount> thirdAccountList = sysThirdAccountService.listThirdUserIdByUsername(usernameList, ThirdAppConfig.DINGTALK.toLowerCase());
|
||||
List<String> dtUserIds = thirdAccountList.stream().map(SysThirdAccount::getThirdUserId).collect(Collectors.toList());
|
||||
actionCardMessage.setUserid_list(dtUserIds);
|
||||
return JdtMessageAPI.sendActionCardMessage(actionCardMessage, accessToken);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,791 @@
|
||||
package org.jeecg.modules.system.service.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.jeecg.qywx.api.base.JwAccessTokenAPI;
|
||||
import com.jeecg.qywx.api.core.common.AccessToken;
|
||||
import com.jeecg.qywx.api.department.JwDepartmentAPI;
|
||||
import com.jeecg.qywx.api.department.vo.DepartMsgResponse;
|
||||
import com.jeecg.qywx.api.department.vo.Department;
|
||||
import com.jeecg.qywx.api.message.JwMessageAPI;
|
||||
import com.jeecg.qywx.api.message.vo.Text;
|
||||
import com.jeecg.qywx.api.message.vo.TextCard;
|
||||
import com.jeecg.qywx.api.message.vo.TextCardEntity;
|
||||
import com.jeecg.qywx.api.message.vo.TextEntity;
|
||||
import com.jeecg.qywx.api.user.JwUserAPI;
|
||||
import com.jeecg.qywx.api.user.vo.User;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.jeecg.common.api.dto.message.MessageDTO;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.system.util.JwtUtil;
|
||||
import org.jeecg.common.util.PasswordUtil;
|
||||
import org.jeecg.common.util.RestUtil;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.config.thirdapp.ThirdAppConfig;
|
||||
import org.jeecg.modules.system.entity.*;
|
||||
import org.jeecg.modules.system.mapper.SysAnnouncementSendMapper;
|
||||
import org.jeecg.modules.system.model.SysDepartTreeModel;
|
||||
import org.jeecg.modules.system.service.*;
|
||||
import org.jeecg.modules.system.vo.thirdapp.JwDepartmentTreeVo;
|
||||
import org.jeecg.modules.system.vo.thirdapp.SyncInfoVo;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 第三方App对接:企业微信实现类
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
|
||||
|
||||
@Autowired
|
||||
ThirdAppConfig thirdAppConfig;
|
||||
@Autowired
|
||||
private ISysDepartService sysDepartService;
|
||||
@Autowired
|
||||
private ISysUserService sysUserService;
|
||||
@Autowired
|
||||
private ISysThirdAccountService sysThirdAccountService;
|
||||
@Autowired
|
||||
private ISysUserDepartService sysUserDepartService;
|
||||
@Autowired
|
||||
private ISysPositionService sysPositionService;
|
||||
@Autowired
|
||||
private SysAnnouncementSendMapper sysAnnouncementSendMapper;
|
||||
|
||||
@Override
|
||||
public String getAccessToken() {
|
||||
String CORP_ID = thirdAppConfig.getWechatEnterprise().getClientId();
|
||||
String SECRET = thirdAppConfig.getWechatEnterprise().getClientSecret();
|
||||
AccessToken accessToken = JwAccessTokenAPI.getAccessToken(CORP_ID, SECRET);
|
||||
if (accessToken != null) {
|
||||
return accessToken.getAccesstoken();
|
||||
}
|
||||
log.warn("获取AccessToken失败");
|
||||
return null;
|
||||
}
|
||||
|
||||
/** 获取APPToken,新版企业微信的秘钥是分开的 */
|
||||
public String getAppAccessToken() {
|
||||
String CORP_ID = thirdAppConfig.getWechatEnterprise().getClientId();
|
||||
String SECRET = thirdAppConfig.getWechatEnterprise().getAgentAppSecret();
|
||||
// 如果没有配置APP秘钥,就说明是老企业,可以通用秘钥
|
||||
if (oConvertUtils.isEmpty(SECRET)) {
|
||||
SECRET = thirdAppConfig.getWechatEnterprise().getClientSecret();
|
||||
}
|
||||
|
||||
AccessToken accessToken = JwAccessTokenAPI.getAccessToken(CORP_ID, SECRET);
|
||||
if (accessToken != null) {
|
||||
return accessToken.getAccesstoken();
|
||||
}
|
||||
log.warn("获取AccessToken失败");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean syncLocalDepartmentToThirdApp(String ids) {
|
||||
String accessToken = this.getAccessToken();
|
||||
if (accessToken == null) {
|
||||
return false;
|
||||
}
|
||||
// 获取企业微信所有的部门
|
||||
List<Department> departments = JwDepartmentAPI.getAllDepartment(accessToken);
|
||||
if (departments == null) {
|
||||
return false;
|
||||
}
|
||||
// 删除企业微信有但本地没有的部门(以本地部门数据为主)(以为企业微信不能创建同名部门,所以只能先删除)
|
||||
List<JwDepartmentTreeVo> departmentTreeList = JwDepartmentTreeVo.listToTree(departments);
|
||||
this.deleteDepartRecursion(departmentTreeList, accessToken, true);
|
||||
// 获取本地所有部门树结构
|
||||
List<SysDepartTreeModel> sysDepartsTree = sysDepartService.queryTreeList();
|
||||
// -- 企业微信不能创建新的顶级部门,所以新的顶级部门的parentId就为1
|
||||
Department parent = new Department();
|
||||
parent.setId("1");
|
||||
// 递归同步部门
|
||||
departments = JwDepartmentAPI.getAllDepartment(accessToken);
|
||||
this.syncDepartmentRecursion(sysDepartsTree, departments, parent, accessToken);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 递归删除部门以及子部门,由于企业微信不允许删除带有成员和子部门的部门,所以需要递归删除下子部门,然后把部门成员移动端根部门下
|
||||
private void deleteDepartRecursion(List<JwDepartmentTreeVo> children, String accessToken, boolean ifLocal) {
|
||||
for (JwDepartmentTreeVo departmentTree : children) {
|
||||
String depId = departmentTree.getId();
|
||||
// 过滤根部门
|
||||
if (!"1".equals(depId)) {
|
||||
// 判断本地是否有该部门
|
||||
if (ifLocal) {
|
||||
LambdaQueryWrapper<SysDepart> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysDepart::getQywxIdentifier, depId);
|
||||
SysDepart sysDepart = sysDepartService.getOne(queryWrapper);
|
||||
// 本地有该部门,不删除
|
||||
if (sysDepart != null) {
|
||||
if (departmentTree.hasChildren()) {
|
||||
this.deleteDepartRecursion(departmentTree.getChildren(), accessToken, true);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// 判断是否有成员,有就移动到根部门
|
||||
List<User> departUserList = JwUserAPI.getUsersByDepartid(depId, "1", null, accessToken);
|
||||
if (departUserList != null && departUserList.size() > 0) {
|
||||
for (User user : departUserList) {
|
||||
User updateUser = new User();
|
||||
updateUser.setUserid(user.getUserid());
|
||||
updateUser.setDepartment(new Integer[]{1});
|
||||
JwUserAPI.updateUser(updateUser, accessToken);
|
||||
}
|
||||
}
|
||||
// 有子部门优先删除子部门
|
||||
if (departmentTree.hasChildren()) {
|
||||
this.deleteDepartRecursion(departmentTree.getChildren(), accessToken, false);
|
||||
}
|
||||
// 执行删除操作
|
||||
JwDepartmentAPI.deleteDepart(depId, accessToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 递归同步部门到第三方APP
|
||||
private void syncDepartmentRecursion(List<SysDepartTreeModel> sysDepartsTree, List<Department> departments, Department parent, String accessToken) {
|
||||
if (sysDepartsTree != null && sysDepartsTree.size() != 0) {
|
||||
for1:
|
||||
for (SysDepartTreeModel depart : sysDepartsTree) {
|
||||
for (Department department : departments) {
|
||||
// id相同,代表已存在,执行修改操作
|
||||
if (department.getId().equals(depart.getQywxIdentifier())) {
|
||||
this.sysDepartToQwDepartment(depart, department, parent.getId());
|
||||
JwDepartmentAPI.updateDepart(department, accessToken);
|
||||
// 紧接着同步子级
|
||||
this.syncDepartmentRecursion(depart.getChildren(), departments, department, accessToken);
|
||||
// 跳出外部循环
|
||||
continue for1;
|
||||
}
|
||||
}
|
||||
// 循环到此说明是新部门,直接调接口创建
|
||||
Department newDepartment = this.sysDepartToQwDepartment(depart, parent.getId());
|
||||
DepartMsgResponse response = JwDepartmentAPI.createDepartment(newDepartment, accessToken);
|
||||
// 创建成功,将返回的id绑定到本地
|
||||
if (response != null && response.getId() != null) {
|
||||
SysDepart sysDepart = new SysDepart();
|
||||
sysDepart.setId(depart.getId());
|
||||
sysDepart.setQywxIdentifier(response.getId().toString());
|
||||
sysDepartService.updateById(sysDepart);
|
||||
Department newParent = new Department();
|
||||
newParent.setId(response.getId().toString());
|
||||
// 紧接着同步子级
|
||||
this.syncDepartmentRecursion(depart.getChildren(), departments, newParent, accessToken);
|
||||
}
|
||||
// 收集错误信息
|
||||
// this.syncUserCollectErrInfo(errCode, sysUser, errInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SyncInfoVo syncThirdAppDepartmentToLocal(String ids) {
|
||||
SyncInfoVo syncInfo = new SyncInfoVo();
|
||||
String accessToken = this.getAccessToken();
|
||||
if (accessToken == null) {
|
||||
syncInfo.addFailInfo("accessToken获取失败!");
|
||||
return syncInfo;
|
||||
}
|
||||
// 获取企业微信所有的部门
|
||||
List<Department> departments = JwDepartmentAPI.getAllDepartment(accessToken);
|
||||
if (departments == null) {
|
||||
syncInfo.addFailInfo("企业微信部门信息获取失败!");
|
||||
return syncInfo;
|
||||
}
|
||||
String username = JwtUtil.getUserNameByToken(SpringContextUtils.getHttpServletRequest());
|
||||
// 将list转为tree
|
||||
List<JwDepartmentTreeVo> departmentTreeList = JwDepartmentTreeVo.listToTree(departments);
|
||||
// 递归同步部门
|
||||
this.syncDepartmentToLocalRecursion(departmentTreeList, null, username, syncInfo);
|
||||
return syncInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归同步部门到本地
|
||||
*/
|
||||
private void syncDepartmentToLocalRecursion(List<JwDepartmentTreeVo> departmentTreeList, String sysParentId, String username, SyncInfoVo syncInfo) {
|
||||
if (departmentTreeList != null && departmentTreeList.size() != 0) {
|
||||
for (JwDepartmentTreeVo departmentTree : departmentTreeList) {
|
||||
String depId = departmentTree.getId();
|
||||
LambdaQueryWrapper<SysDepart> queryWrapper = new LambdaQueryWrapper<>();
|
||||
// 根据 qywxIdentifier 字段查询
|
||||
queryWrapper.eq(SysDepart::getQywxIdentifier, depId);
|
||||
SysDepart sysDepart = sysDepartService.getOne(queryWrapper);
|
||||
if (sysDepart != null) {
|
||||
// 执行更新操作
|
||||
SysDepart updateSysDepart = this.qwDepartmentToSysDepart(departmentTree, sysDepart);
|
||||
if (sysParentId != null) {
|
||||
updateSysDepart.setParentId(sysParentId);
|
||||
}
|
||||
try {
|
||||
sysDepartService.updateDepartDataById(updateSysDepart, username);
|
||||
String str = String.format("部门 %s 更新成功!", updateSysDepart.getDepartName());
|
||||
syncInfo.addSuccessInfo(str);
|
||||
} catch (Exception e) {
|
||||
this.syncDepartCollectErrInfo(e, departmentTree, syncInfo);
|
||||
}
|
||||
if (departmentTree.hasChildren()) {
|
||||
// 紧接着同步子级
|
||||
this.syncDepartmentToLocalRecursion(departmentTree.getChildren(), updateSysDepart.getId(), username, syncInfo);
|
||||
}
|
||||
} else {
|
||||
// 执行新增操作
|
||||
SysDepart newSysDepart = this.qwDepartmentToSysDepart(departmentTree, null);
|
||||
if (sysParentId != null) {
|
||||
newSysDepart.setParentId(sysParentId);
|
||||
}
|
||||
try {
|
||||
sysDepartService.saveDepartData(newSysDepart, username);
|
||||
String str = String.format("部门 %s 创建成功!", newSysDepart.getDepartName());
|
||||
syncInfo.addSuccessInfo(str);
|
||||
} catch (Exception e) {
|
||||
this.syncDepartCollectErrInfo(e, departmentTree, syncInfo);
|
||||
}
|
||||
// 紧接着同步子级
|
||||
if (departmentTree.hasChildren()) {
|
||||
this.syncDepartmentToLocalRecursion(departmentTree.getChildren(), newSysDepart.getId(), username, syncInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SyncInfoVo syncLocalUserToThirdApp(String ids) {
|
||||
SyncInfoVo syncInfo = new SyncInfoVo();
|
||||
String accessToken = this.getAccessToken();
|
||||
if (accessToken == null) {
|
||||
syncInfo.addFailInfo("accessToken获取失败!");
|
||||
return syncInfo;
|
||||
}
|
||||
// 获取企业微信所有的用户
|
||||
List<User> qwUsers = JwUserAPI.getDetailUsersByDepartid("1", null, null, accessToken);
|
||||
if (qwUsers == null) {
|
||||
syncInfo.addFailInfo("企业微信用户列表查询失败!");
|
||||
return syncInfo;
|
||||
}
|
||||
List<SysUser> sysUsers;
|
||||
if (StringUtils.isNotBlank(ids)) {
|
||||
String[] idList = ids.split(",");
|
||||
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.in(SysUser::getId, (Object[]) idList);
|
||||
// 获取本地指定用户
|
||||
sysUsers = sysUserService.list(queryWrapper);
|
||||
} else {
|
||||
// 获取本地所有用户
|
||||
sysUsers = sysUserService.list();
|
||||
}
|
||||
|
||||
// 循环判断新用户和需要更新的用户
|
||||
for1:
|
||||
for (SysUser sysUser : sysUsers) {
|
||||
// 外部模拟登陆临时账号,不同步
|
||||
if ("_reserve_user_external".equals(sysUser.getUsername())) {
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* 判断是否同步过的逻辑:
|
||||
* 1. 查询 sys_third_account(第三方账号表)是否有数据,如果有代表已同步
|
||||
* 2. 本地表里没有,就先用手机号判断,不通过再用username判断。
|
||||
*/
|
||||
User qwUser;
|
||||
SysThirdAccount sysThirdAccount = sysThirdAccountService.getOneBySysUserId(sysUser.getId(), ThirdAppConfig.WECHAT_ENTERPRISE.toLowerCase());
|
||||
for (User qwUserTemp : qwUsers) {
|
||||
if (sysThirdAccount == null || oConvertUtils.isEmpty(sysThirdAccount.getThirdUserId()) || !sysThirdAccount.getThirdUserId().equals(qwUserTemp.getUserid())) {
|
||||
// sys_third_account 表匹配失败,尝试用手机号匹配
|
||||
String phone = sysUser.getPhone();
|
||||
if (!(oConvertUtils.isEmpty(phone) || phone.equals(qwUserTemp.getMobile()))) {
|
||||
// 手机号匹配失败,再尝试用username匹配
|
||||
String username = sysUser.getUsername();
|
||||
if (!(oConvertUtils.isEmpty(username) || username.equals(qwUserTemp.getUserid()))) {
|
||||
// username 匹配失败,直接跳到下一次循环继续
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 循环到此说明用户匹配成功,进行更新操作
|
||||
qwUser = this.sysUserToQwUser(sysUser, qwUserTemp);
|
||||
int errCode = JwUserAPI.updateUser(qwUser, accessToken);
|
||||
// 收集错误信息
|
||||
this.syncUserCollectErrInfo(errCode, sysUser, syncInfo);
|
||||
this.thirdAccountSaveOrUpdate(sysThirdAccount, sysUser.getId(), qwUser.getUserid());
|
||||
// 更新完成,直接跳到下一次外部循环继续
|
||||
continue for1;
|
||||
}
|
||||
// 循环到此说明是新用户,直接调接口创建
|
||||
qwUser = this.sysUserToQwUser(sysUser);
|
||||
int errCode = JwUserAPI.createUser(qwUser, accessToken);
|
||||
// 收集错误信息
|
||||
boolean apiSuccess = this.syncUserCollectErrInfo(errCode, sysUser, syncInfo);
|
||||
if (apiSuccess) {
|
||||
this.thirdAccountSaveOrUpdate(sysThirdAccount, sysUser.getId(), qwUser.getUserid());
|
||||
}
|
||||
}
|
||||
return syncInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SyncInfoVo syncThirdAppUserToLocal() {
|
||||
SyncInfoVo syncInfo = new SyncInfoVo();
|
||||
String accessToken = this.getAccessToken();
|
||||
if (accessToken == null) {
|
||||
syncInfo.addFailInfo("accessToken获取失败!");
|
||||
return syncInfo;
|
||||
}
|
||||
// 获取企业微信所有的用户
|
||||
List<User> qwUsersList = JwUserAPI.getDetailUsersByDepartid("1", null, null, accessToken);
|
||||
if (qwUsersList == null) {
|
||||
syncInfo.addFailInfo("企业微信用户列表查询失败!");
|
||||
return syncInfo;
|
||||
}
|
||||
//查询本地用户
|
||||
List<SysUser> sysUsersList = sysUserService.list();
|
||||
// 循环判断新用户和需要更新的用户
|
||||
for (User qwUser : qwUsersList) {
|
||||
/*
|
||||
* 判断是否同步过的逻辑:
|
||||
* 1. 查询 sys_third_account(第三方账号表)是否有数据,如果有代表已同步
|
||||
* 2. 本地表里没有,就先用手机号判断,不通过再用username判断。
|
||||
*/
|
||||
SysThirdAccount sysThirdAccount = sysThirdAccountService.getOneByThirdUserId(qwUser.getUserid(), ThirdAppConfig.WECHAT_ENTERPRISE.toLowerCase());
|
||||
List<SysUser> collect = sysUsersList.stream().filter(user -> (qwUser.getMobile().equals(user.getPhone()) || qwUser.getUserid().equals(user.getUsername()))
|
||||
).collect(Collectors.toList());
|
||||
|
||||
if (collect != null && collect.size() > 0) {
|
||||
SysUser sysUserTemp = collect.get(0);
|
||||
// 循环到此说明用户匹配成功,进行更新操作
|
||||
SysUser updateSysUser = this.qwUserToSysUser(qwUser, sysUserTemp);
|
||||
try {
|
||||
sysUserService.updateById(updateSysUser);
|
||||
String str = String.format("用户 %s(%s) 更新成功!", updateSysUser.getRealname(), updateSysUser.getUsername());
|
||||
syncInfo.addSuccessInfo(str);
|
||||
} catch (Exception e) {
|
||||
this.syncUserCollectErrInfo(e, qwUser, syncInfo);
|
||||
}
|
||||
|
||||
this.thirdAccountSaveOrUpdate(sysThirdAccount, updateSysUser.getId(), qwUser.getUserid());
|
||||
// 更新完成,直接跳到下一次外部循环继续
|
||||
}else{
|
||||
// 没匹配到用户则走新增逻辑
|
||||
SysUser newSysUser = this.qwUserToSysUser(qwUser);
|
||||
try {
|
||||
sysUserService.save(newSysUser);
|
||||
String str = String.format("用户 %s(%s) 创建成功!", newSysUser.getRealname(), newSysUser.getUsername());
|
||||
syncInfo.addSuccessInfo(str);
|
||||
} catch (Exception e) {
|
||||
this.syncUserCollectErrInfo(e, qwUser, syncInfo);
|
||||
}
|
||||
this.thirdAccountSaveOrUpdate(sysThirdAccount, newSysUser.getId(), qwUser.getUserid());
|
||||
}
|
||||
}
|
||||
return syncInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存或修改第三方登录表
|
||||
*
|
||||
* @param sysThirdAccount 第三方账户表对象,为null就新增数据,否则就修改
|
||||
* @param sysUserId 本地系统用户ID
|
||||
* @param qwUserId 企业微信用户ID
|
||||
*/
|
||||
private void thirdAccountSaveOrUpdate(SysThirdAccount sysThirdAccount, String sysUserId, String qwUserId) {
|
||||
if (sysThirdAccount == null) {
|
||||
sysThirdAccount = new SysThirdAccount();
|
||||
sysThirdAccount.setSysUserId(sysUserId);
|
||||
sysThirdAccount.setStatus(1);
|
||||
sysThirdAccount.setDelFlag(0);
|
||||
sysThirdAccount.setThirdType(ThirdAppConfig.WECHAT_ENTERPRISE.toLowerCase());
|
||||
}
|
||||
sysThirdAccount.setThirdUserId(qwUserId);
|
||||
sysThirdAccountService.saveOrUpdate(sysThirdAccount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 【同步用户】收集同步过程中的错误信息
|
||||
*/
|
||||
private boolean syncUserCollectErrInfo(int errCode, SysUser sysUser, SyncInfoVo syncInfo) {
|
||||
if (errCode != 0) {
|
||||
String msg = "";
|
||||
// https://open.work.weixin.qq.com/api/doc/90000/90139/90313
|
||||
switch (errCode) {
|
||||
case 40003:
|
||||
msg = "无效的UserID";
|
||||
break;
|
||||
case 60129:
|
||||
msg = "手机和邮箱不能都为空";
|
||||
break;
|
||||
case 60102:
|
||||
msg = "UserID已存在";
|
||||
break;
|
||||
case 60103:
|
||||
msg = "手机号码不合法";
|
||||
break;
|
||||
case 60104:
|
||||
msg = "手机号码已存在";
|
||||
break;
|
||||
}
|
||||
String str = String.format("用户 %s(%s) 同步失败!错误码:%s——%s", sysUser.getUsername(), sysUser.getRealname(), errCode, msg);
|
||||
syncInfo.addFailInfo(str);
|
||||
return false;
|
||||
} else {
|
||||
String str = String.format("用户 %s(%s) 同步成功!", sysUser.getUsername(), sysUser.getRealname());
|
||||
syncInfo.addSuccessInfo(str);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean syncUserCollectErrInfo(Exception e, User qwUser, SyncInfoVo syncInfo) {
|
||||
String msg;
|
||||
if (e instanceof DuplicateKeyException) {
|
||||
msg = e.getCause().getMessage();
|
||||
} else {
|
||||
msg = e.getMessage();
|
||||
}
|
||||
String str = String.format("用户 %s(%s) 同步失败!错误信息:%s", qwUser.getUserid(), qwUser.getName(), msg);
|
||||
syncInfo.addFailInfo(str);
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean syncDepartCollectErrInfo(Exception e, Department department, SyncInfoVo syncInfo) {
|
||||
String msg;
|
||||
if (e instanceof DuplicateKeyException) {
|
||||
msg = e.getCause().getMessage();
|
||||
} else {
|
||||
msg = e.getMessage();
|
||||
}
|
||||
String str = String.format("部门 %s(%s) 同步失败!错误信息:%s", department.getName(), department.getId(), msg);
|
||||
syncInfo.addFailInfo(str);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 【同步用户】将SysUser转为企业微信的User对象(创建新用户)
|
||||
*/
|
||||
private User sysUserToQwUser(SysUser sysUser) {
|
||||
User user = new User();
|
||||
// 通过 username 来关联
|
||||
user.setUserid(sysUser.getUsername());
|
||||
return this.sysUserToQwUser(sysUser, user);
|
||||
}
|
||||
|
||||
/**
|
||||
* 【同步用户】将SysUser转为企业微信的User对象(更新旧用户)
|
||||
*/
|
||||
private User sysUserToQwUser(SysUser sysUser, User user) {
|
||||
user.setName(sysUser.getRealname());
|
||||
user.setMobile(sysUser.getPhone());
|
||||
// 查询并同步用户部门关系
|
||||
List<SysDepart> departList = this.getUserDepart(sysUser);
|
||||
if (departList != null) {
|
||||
List<Integer> departmentIdList = new ArrayList<>();
|
||||
// 企业微信 1表示为上级,0表示非上级
|
||||
List<Integer> isLeaderInDept = new ArrayList<>();
|
||||
// 当前用户管理的部门
|
||||
List<String> manageDepartIdList = new ArrayList<>();
|
||||
if (oConvertUtils.isNotEmpty(sysUser.getDepartIds())) {
|
||||
manageDepartIdList = Arrays.asList(sysUser.getDepartIds().split(","));
|
||||
}
|
||||
for (SysDepart sysDepart : departList) {
|
||||
// 企业微信的部门id
|
||||
if (oConvertUtils.isNotEmpty(sysDepart.getQywxIdentifier())) {
|
||||
try {
|
||||
departmentIdList.add(Integer.parseInt(sysDepart.getQywxIdentifier()));
|
||||
} catch (NumberFormatException ignored) {
|
||||
continue;
|
||||
}
|
||||
// 判断用户身份,是否为上级
|
||||
if (CommonConstant.USER_IDENTITY_2.equals(sysUser.getUserIdentity())) {
|
||||
// 判断当前部门是否为该用户管理的部门
|
||||
isLeaderInDept.add(manageDepartIdList.contains(sysDepart.getId()) ? 1 : 0);
|
||||
} else {
|
||||
isLeaderInDept.add(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
user.setDepartment(departmentIdList.toArray(new Integer[]{}));
|
||||
// 个数必须和参数department的个数一致,表示在所在的部门内是否为上级。1表示为上级,0表示非上级。在审批等应用里可以用来标识上级审批人
|
||||
user.setIs_leader_in_dept(isLeaderInDept.toArray(new Integer[]{}));
|
||||
}
|
||||
if (user.getDepartment() == null || user.getDepartment().length == 0) {
|
||||
// 没有找到匹配部门,同步到根部门下
|
||||
user.setDepartment(new Integer[]{1});
|
||||
user.setIs_leader_in_dept(new Integer[]{0});
|
||||
}
|
||||
// 职务翻译
|
||||
if (oConvertUtils.isNotEmpty(sysUser.getPost())) {
|
||||
SysPosition position = sysPositionService.getByCode(sysUser.getPost());
|
||||
if (position != null) {
|
||||
user.setPosition(position.getName());
|
||||
}
|
||||
}
|
||||
if (sysUser.getSex() != null) {
|
||||
user.setGender(sysUser.getSex().toString());
|
||||
}
|
||||
user.setEmail(sysUser.getEmail());
|
||||
// 启用/禁用成员(状态),规则不同,需要转换
|
||||
// 企业微信规则:1表示启用成员,0表示禁用成员
|
||||
// JEECG规则:1正常,2冻结
|
||||
if (sysUser.getStatus() != null) {
|
||||
if (sysUser.getStatus() == 1 || sysUser.getStatus() == 2) {
|
||||
user.setEnable(sysUser.getStatus() == 1 ? 1 : 0);
|
||||
} else {
|
||||
user.setEnable(1);
|
||||
}
|
||||
}
|
||||
user.setTelephone(sysUser.getTelephone());// 座机号
|
||||
// --- 企业微信没有逻辑删除的功能
|
||||
// update-begin--Author:sunjianlei Date:20210520 for:本地逻辑删除的用户,在企业微信里禁用 -----
|
||||
if (CommonConstant.DEL_FLAG_1.equals(sysUser.getDelFlag())) {
|
||||
user.setEnable(0);
|
||||
}
|
||||
// update-end--Author:sunjianlei Date:20210520 for:本地逻辑删除的用户,在企业微信里冻结 -----
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户和部门的关系
|
||||
*/
|
||||
private List<SysDepart> getUserDepart(SysUser sysUser) {
|
||||
// 根据用户部门关系表查询出用户的部门
|
||||
LambdaQueryWrapper<SysUserDepart> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysUserDepart::getUserId, sysUser.getId());
|
||||
List<SysUserDepart> sysUserDepartList = sysUserDepartService.list(queryWrapper);
|
||||
if (sysUserDepartList.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
// 根据用户部门
|
||||
LambdaQueryWrapper<SysDepart> departQueryWrapper = new LambdaQueryWrapper<>();
|
||||
List<String> departIdList = sysUserDepartList.stream().map(SysUserDepart::getDepId).collect(Collectors.toList());
|
||||
departQueryWrapper.in(SysDepart::getId, departIdList);
|
||||
List<SysDepart> departList = sysDepartService.list(departQueryWrapper);
|
||||
return departList.size() == 0 ? null : departList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 【同步用户】将企业微信的User对象转为SysUser(创建新用户)
|
||||
*/
|
||||
private SysUser qwUserToSysUser(User user) {
|
||||
SysUser sysUser = new SysUser();
|
||||
sysUser.setDelFlag(0);
|
||||
// 通过 username 来关联
|
||||
sysUser.setUsername(user.getUserid());
|
||||
// 密码默认为 “123456”,随机加盐
|
||||
String password = "123456", salt = oConvertUtils.randomGen(8);
|
||||
String passwordEncode = PasswordUtil.encrypt(sysUser.getUsername(), password, salt);
|
||||
sysUser.setSalt(salt);
|
||||
sysUser.setPassword(passwordEncode);
|
||||
return this.qwUserToSysUser(user, sysUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* 【同步用户】将企业微信的User对象转为SysUser(更新旧用户)
|
||||
*/
|
||||
private SysUser qwUserToSysUser(User qwUser, SysUser oldSysUser) {
|
||||
SysUser sysUser = new SysUser();
|
||||
BeanUtils.copyProperties(oldSysUser, sysUser);
|
||||
sysUser.setRealname(qwUser.getName());
|
||||
sysUser.setPost(qwUser.getPosition());
|
||||
try {
|
||||
sysUser.setSex(Integer.parseInt(qwUser.getGender()));
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
// 因为唯一键约束的原因,如果原数据和旧数据相同,就不更新
|
||||
if (oConvertUtils.isNotEmpty(qwUser.getEmail()) && !qwUser.getEmail().equals(sysUser.getEmail())) {
|
||||
sysUser.setEmail(qwUser.getEmail());
|
||||
} else {
|
||||
sysUser.setEmail(null);
|
||||
}
|
||||
// 因为唯一键约束的原因,如果原数据和旧数据相同,就不更新
|
||||
if (oConvertUtils.isNotEmpty(qwUser.getMobile()) && !qwUser.getMobile().equals(sysUser.getPhone())) {
|
||||
sysUser.setPhone(qwUser.getMobile());
|
||||
} else {
|
||||
sysUser.setPhone(null);
|
||||
}
|
||||
|
||||
// 启用/禁用成员(状态),规则不同,需要转换
|
||||
// 企业微信规则:1表示启用成员,0表示禁用成员
|
||||
// JEECG规则:1正常,2冻结
|
||||
if (qwUser.getEnable() != null) {
|
||||
sysUser.setStatus(qwUser.getEnable() == 1 ? 1 : 2);
|
||||
}
|
||||
sysUser.setTelephone(qwUser.getTelephone());// 座机号
|
||||
|
||||
// --- 企业微信没有逻辑删除的功能
|
||||
// sysUser.setDelFlag()
|
||||
return sysUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* 【同步部门】将SysDepartTreeModel转为企业微信的Department对象(创建新部门)
|
||||
*/
|
||||
private Department sysDepartToQwDepartment(SysDepartTreeModel departTree, String parentId) {
|
||||
Department department = new Department();
|
||||
return this.sysDepartToQwDepartment(departTree, department, parentId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 【同步部门】将SysDepartTreeModel转为企业微信的Department对象
|
||||
*/
|
||||
private Department sysDepartToQwDepartment(SysDepartTreeModel departTree, Department department, String parentId) {
|
||||
department.setName(departTree.getDepartName());
|
||||
department.setParentid(parentId);
|
||||
if (departTree.getDepartOrder() != null) {
|
||||
department.setOrder(departTree.getDepartOrder().toString());
|
||||
}
|
||||
return department;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 【同步部门】将企业微信的Department对象转为SysDepart
|
||||
*/
|
||||
private SysDepart qwDepartmentToSysDepart(Department department, SysDepart oldSysDepart) {
|
||||
SysDepart sysDepart = new SysDepart();
|
||||
if (oldSysDepart != null) {
|
||||
BeanUtils.copyProperties(oldSysDepart, sysDepart);
|
||||
}
|
||||
sysDepart.setQywxIdentifier(department.getId());
|
||||
sysDepart.setDepartName(department.getName());
|
||||
try {
|
||||
sysDepart.setDepartOrder(Integer.parseInt(department.getOrder()));
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
return sysDepart;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int removeThirdAppUser(List<String> userIdList) {
|
||||
// 判断启用状态
|
||||
if (!thirdAppConfig.isWechatEnterpriseEnabled()) {
|
||||
return -1;
|
||||
}
|
||||
int count = 0;
|
||||
if (userIdList != null && userIdList.size() > 0) {
|
||||
String accessToken = this.getAccessToken();
|
||||
if (accessToken == null) {
|
||||
return count;
|
||||
}
|
||||
LambdaQueryWrapper<SysThirdAccount> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysThirdAccount::getThirdType, ThirdAppConfig.WECHAT_ENTERPRISE.toLowerCase());
|
||||
queryWrapper.in(SysThirdAccount::getSysUserId, userIdList);
|
||||
// 根据userId,获取第三方用户的id
|
||||
List<SysThirdAccount> thirdAccountList = sysThirdAccountService.list(queryWrapper);
|
||||
List<String> thirdUserIdList = thirdAccountList.stream().map(SysThirdAccount::getThirdUserId).collect(Collectors.toList());
|
||||
|
||||
for (String thirdUserId : thirdUserIdList) {
|
||||
if (oConvertUtils.isNotEmpty(thirdUserId)) {
|
||||
// 没有批量删除的接口
|
||||
int err = JwUserAPI.deleteUser(thirdUserId, accessToken);
|
||||
if (err == 0) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean sendMessage(MessageDTO message) {
|
||||
return this.sendMessage(message, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean sendMessage(MessageDTO message, boolean verifyConfig) {
|
||||
JSONObject response = this.sendMessageResponse(message, verifyConfig);
|
||||
if (response != null) {
|
||||
return response.getIntValue("errcode") == 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public JSONObject sendMessageResponse(MessageDTO message, boolean verifyConfig) {
|
||||
if (verifyConfig && !thirdAppConfig.isWechatEnterpriseEnabled()) {
|
||||
return null;
|
||||
}
|
||||
String accessToken = this.getAppAccessToken();
|
||||
if (accessToken == null) {
|
||||
return null;
|
||||
}
|
||||
Text text = new Text();
|
||||
text.setMsgtype("text");
|
||||
text.setTouser(this.getTouser(message.getToUser(), message.isToAll()));
|
||||
TextEntity entity = new TextEntity();
|
||||
entity.setContent(message.getContent());
|
||||
text.setText(entity);
|
||||
text.setAgentid(thirdAppConfig.getWechatEnterprise().getAgentIdInt());
|
||||
return JwMessageAPI.sendTextMessage(text, accessToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送文本卡片消息(SysAnnouncement定制)
|
||||
*
|
||||
* @param announcement
|
||||
* @param verifyConfig 是否验证配置(未启用的APP会拒绝发送)
|
||||
* @return
|
||||
*/
|
||||
public JSONObject sendTextCardMessage(SysAnnouncement announcement, boolean verifyConfig) {
|
||||
if (verifyConfig && !thirdAppConfig.isWechatEnterpriseEnabled()) {
|
||||
return null;
|
||||
}
|
||||
String accessToken = this.getAppAccessToken();
|
||||
if (accessToken == null) {
|
||||
return null;
|
||||
}
|
||||
TextCard textCard = new TextCard();
|
||||
textCard.setAgentid(thirdAppConfig.getWechatEnterprise().getAgentIdInt());
|
||||
boolean isToAll = CommonConstant.MSG_TYPE_ALL.equals(announcement.getMsgType());
|
||||
String usernameString = "";
|
||||
if (!isToAll) {
|
||||
// 将userId转为username
|
||||
String userId = announcement.getUserIds();
|
||||
String[] userIds = null;
|
||||
if(oConvertUtils.isNotEmpty(userId)){
|
||||
userIds = userId.substring(0, (userId.length() - 1)).split(",");
|
||||
}else{
|
||||
LambdaQueryWrapper<SysAnnouncementSend> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysAnnouncementSend::getAnntId, announcement.getId());
|
||||
SysAnnouncementSend sysAnnouncementSend = sysAnnouncementSendMapper.selectOne(queryWrapper);
|
||||
userIds = new String[] {sysAnnouncementSend.getUserId()};
|
||||
}
|
||||
List<String> usernameList = sysUserService.userIdToUsername(Arrays.asList(userIds));
|
||||
usernameString = String.join(",", usernameList);
|
||||
}
|
||||
|
||||
textCard.setTouser(this.getTouser(usernameString, isToAll));
|
||||
TextCardEntity entity = new TextCardEntity();
|
||||
entity.setTitle(announcement.getTitile());
|
||||
entity.setDescription(oConvertUtils.getString(announcement.getMsgAbstract(),"空"));
|
||||
entity.setUrl(RestUtil.getBaseUrl() + "/sys/annountCement/show/" + announcement.getId());
|
||||
textCard.setTextcard(entity);
|
||||
return JwMessageAPI.sendTextCardMessage(textCard, accessToken);
|
||||
}
|
||||
|
||||
private String getTouser(String origin, boolean toAll) {
|
||||
if (toAll) {
|
||||
return "@all";
|
||||
} else {
|
||||
String[] toUsers = origin.split(",");
|
||||
// 通过第三方账号表查询出第三方userId
|
||||
List<SysThirdAccount> thirdAccountList = sysThirdAccountService.listThirdUserIdByUsername(toUsers, ThirdAppConfig.WECHAT_ENTERPRISE.toLowerCase());
|
||||
List<String> toUserList = thirdAccountList.stream().map(SysThirdAccount::getThirdUserId).collect(Collectors.toList());
|
||||
// 多个接收者用‘|’分隔
|
||||
return String.join("|", toUserList);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
package org.jeecg.modules.system.service.impl.desform;
|
||||
|
||||
import org.jeecg.common.api.desform.ISysTranslateAPI;
|
||||
import org.jeecg.common.system.vo.DictModel;
|
||||
import org.jeecg.modules.system.service.ISysCategoryService;
|
||||
import org.jeecg.modules.system.service.ISysDictService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 表单设计器翻译API接口(system实现类)
|
||||
*
|
||||
* @author sunjianlei
|
||||
*/
|
||||
@Component
|
||||
public class SysTranslateAPIImpl implements ISysTranslateAPI {
|
||||
|
||||
@Autowired
|
||||
ISysCategoryService sysCategoryService;
|
||||
@Autowired
|
||||
ISysDictService sysDictService;
|
||||
|
||||
@Override
|
||||
public List<String> categoryLoadDictItem(String ids) {
|
||||
return sysCategoryService.loadDictItem(ids, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> dictLoadDictItem(String dictCode, String keys) {
|
||||
String[] params = dictCode.split(",");
|
||||
return sysDictService.queryTableDictByKeys(params[0], params[1], params[2], keys, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictModel> dictGetDictItems(String dictCode) {
|
||||
List<DictModel> ls = sysDictService.getDictItems(dictCode);
|
||||
if (ls == null) {
|
||||
ls = new ArrayList<>();
|
||||
}
|
||||
return ls;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictModel> dictLoadDict(String dictCode, String keyword, Integer pageSize) {
|
||||
return sysDictService.loadDict(dictCode, keyword, pageSize);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,25 +1,25 @@
|
||||
package org.jeecg.modules.system.util;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 多租户 tenant_id存储器
|
||||
*/
|
||||
@Slf4j
|
||||
public class TenantContext {
|
||||
|
||||
private static ThreadLocal<String> currentTenant = new ThreadLocal<>();
|
||||
|
||||
public static void setTenant(String tenant) {
|
||||
log.debug(" setting tenant to " + tenant);
|
||||
currentTenant.set(tenant);
|
||||
}
|
||||
|
||||
public static String getTenant() {
|
||||
return currentTenant.get();
|
||||
}
|
||||
|
||||
public static void clear(){
|
||||
currentTenant.remove();
|
||||
}
|
||||
}
|
||||
//package org.jeecg.modules.system.util;
|
||||
//
|
||||
//import lombok.extern.slf4j.Slf4j;
|
||||
//
|
||||
///**
|
||||
// * 多租户 tenant_id存储器
|
||||
// */
|
||||
//@Slf4j
|
||||
//public class TenantContext {
|
||||
//
|
||||
// private static ThreadLocal<String> currentTenant = new ThreadLocal<>();
|
||||
//
|
||||
// public static void setTenant(String tenant) {
|
||||
// log.debug(" setting tenant to " + tenant);
|
||||
// currentTenant.set(tenant);
|
||||
// }
|
||||
//
|
||||
// public static String getTenant() {
|
||||
// return currentTenant.get();
|
||||
// }
|
||||
//
|
||||
// public static void clear(){
|
||||
// currentTenant.remove();
|
||||
// }
|
||||
//}
|
||||
|
||||
@ -0,0 +1,76 @@
|
||||
package org.jeecg.modules.system.vo.thirdapp;
|
||||
|
||||
import com.jeecg.dingtalk.api.department.vo.Department;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 钉钉树结构的部门
|
||||
*
|
||||
* @author sunjianlei
|
||||
*/
|
||||
public class JdtDepartmentTreeVo extends Department {
|
||||
|
||||
private List<JdtDepartmentTreeVo> children;
|
||||
|
||||
public List<JdtDepartmentTreeVo> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
public JdtDepartmentTreeVo setChildren(List<JdtDepartmentTreeVo> children) {
|
||||
this.children = children;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JdtDepartmentTreeVo(Department department) {
|
||||
BeanUtils.copyProperties(department, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否有子项
|
||||
*/
|
||||
public boolean hasChildren() {
|
||||
return children != null && children.size() > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JwDepartmentTree{" +
|
||||
"children=" + children +
|
||||
"} " + super.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 静态辅助方法,将list转为tree结构
|
||||
*/
|
||||
public static List<JdtDepartmentTreeVo> listToTree(List<Department> allDepartment) {
|
||||
// 先找出所有的父级
|
||||
List<JdtDepartmentTreeVo> treeList = getByParentId(1, allDepartment);
|
||||
getChildrenRecursion(treeList, allDepartment);
|
||||
return treeList;
|
||||
}
|
||||
|
||||
private static List<JdtDepartmentTreeVo> getByParentId(Integer parentId, List<Department> allDepartment) {
|
||||
List<JdtDepartmentTreeVo> list = new ArrayList<>();
|
||||
for (Department department : allDepartment) {
|
||||
if (parentId.equals(department.getParent_id())) {
|
||||
list.add(new JdtDepartmentTreeVo(department));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private static void getChildrenRecursion(List<JdtDepartmentTreeVo> treeList, List<Department> allDepartment) {
|
||||
for (JdtDepartmentTreeVo departmentTree : treeList) {
|
||||
// 递归寻找子级
|
||||
List<JdtDepartmentTreeVo> children = getByParentId(departmentTree.getDept_id(), allDepartment);
|
||||
if (children.size() > 0) {
|
||||
departmentTree.setChildren(children);
|
||||
getChildrenRecursion(children, allDepartment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,76 @@
|
||||
package org.jeecg.modules.system.vo.thirdapp;
|
||||
|
||||
import com.jeecg.qywx.api.department.vo.Department;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 企业微信树结构的部门
|
||||
*
|
||||
* @author sunjianlei
|
||||
*/
|
||||
public class JwDepartmentTreeVo extends Department {
|
||||
|
||||
private List<JwDepartmentTreeVo> children;
|
||||
|
||||
public List<JwDepartmentTreeVo> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
public JwDepartmentTreeVo setChildren(List<JwDepartmentTreeVo> children) {
|
||||
this.children = children;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JwDepartmentTreeVo(Department department) {
|
||||
BeanUtils.copyProperties(department, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否有子项
|
||||
*/
|
||||
public boolean hasChildren() {
|
||||
return children != null && children.size() > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JwDepartmentTree{" +
|
||||
"children=" + children +
|
||||
"} " + super.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 静态辅助方法,将list转为tree结构
|
||||
*/
|
||||
public static List<JwDepartmentTreeVo> listToTree(List<Department> allDepartment) {
|
||||
// 先找出所有的父级
|
||||
List<JwDepartmentTreeVo> treeList = getByParentId("1", allDepartment);
|
||||
getChildrenRecursion(treeList, allDepartment);
|
||||
return treeList;
|
||||
}
|
||||
|
||||
private static List<JwDepartmentTreeVo> getByParentId(String parentId, List<Department> allDepartment) {
|
||||
List<JwDepartmentTreeVo> list = new ArrayList<>();
|
||||
for (Department department : allDepartment) {
|
||||
if (parentId.equals(department.getParentid())) {
|
||||
list.add(new JwDepartmentTreeVo(department));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private static void getChildrenRecursion(List<JwDepartmentTreeVo> treeList, List<Department> allDepartment) {
|
||||
for (JwDepartmentTreeVo departmentTree : treeList) {
|
||||
// 递归寻找子级
|
||||
List<JwDepartmentTreeVo> children = getByParentId(departmentTree.getId(), allDepartment);
|
||||
if (children.size() > 0) {
|
||||
departmentTree.setChildren(children);
|
||||
getChildrenRecursion(children, allDepartment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
package org.jeecg.modules.system.vo.thirdapp;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 同步结果信息,包含成功的信息和失败的信息
|
||||
*
|
||||
* @author sunjianlei
|
||||
*/
|
||||
@Data
|
||||
public class SyncInfoVo {
|
||||
|
||||
/**
|
||||
* 成功的信息
|
||||
*/
|
||||
private List<String> successInfo;
|
||||
/**
|
||||
* 失败的信息
|
||||
*/
|
||||
private List<String> failInfo;
|
||||
|
||||
public SyncInfoVo() {
|
||||
this.successInfo = new ArrayList<>();
|
||||
this.failInfo = new ArrayList<>();
|
||||
}
|
||||
|
||||
public SyncInfoVo(List<String> successInfo, List<String> failInfo) {
|
||||
this.successInfo = successInfo;
|
||||
this.failInfo = failInfo;
|
||||
}
|
||||
|
||||
public SyncInfoVo addSuccessInfo(String info) {
|
||||
this.successInfo.add(info);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SyncInfoVo addFailInfo(String info) {
|
||||
this.failInfo.add(info);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user