Ver Fonte

集成飞书 卡片模板消息推送

yurk há 2 anos atrás
pai
commit
1d866002d9

+ 0 - 94
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/AuthRedirectController.java

@@ -156,100 +156,6 @@ public class AuthRedirectController {
     }
 
 
-    @RequestMapping("/corpFeishuAuth")
-    public ModelAndView corpFeishuAuth(String code, String appId) {
-        Map<String,Object> reqParam = new HashMap<String,Object>(16);
-        String userAgent = request.getHeader("User-Agent");
-        //获取设备类型
-        FeishuInfo feishuInfo = feishuInfoService.getOne(new QueryWrapper<FeishuInfo>().eq("app_id", appId));
-        String deviceType = UserAgentUtils.getDeviceType(userAgent);
-        boolean isMobile = "MOBILE".equals(deviceType);
-        String url = FeishuInfoServiceImpl.GET_USER_ACCESS_TOKEN;
-        HttpHeaders headers = new HttpHeaders();
-        RestTemplate restTemplate = new RestTemplate();
-        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
-        headers.setContentType(type);
-        headers.add("Authorization","Bearer "+feishuInfoService.getAppAccessToken(feishuInfo));
-        JSONObject ob = new JSONObject();
-        ob.put("grant_type", "authorization_code");
-        ob.put("code", code);
-        HttpEntity<JSONObject> Entity = new HttpEntity<>(ob, headers);
-        ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, Entity, String.class);
-        String redirecUrl = null;
-        String openUserId=null;
-        String fsUserId=null;
-        String corpId=null;
-        if (responseEntity.getStatusCode() == HttpStatus.OK) {
-            String resp = responseEntity.getBody();
-            System.err.println(resp);
-            JSONObject obj = JSONObject.parseObject(resp);
-            if (obj.getIntValue("code") == 0) {
-                System.out.println(obj.toString());
-                JSONObject data = obj.getJSONObject("data");
-                fsUserId = data.getString("user_id");
-                openUserId = data.getString("open_id");
-                corpId = data.getString("tenant_key");
-            }
-        }
-        List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("feishu_userid", openUserId));
-        Integer companyId = 0;
-        if (userList.size() > 0) {
-            //该用户已存在
-            User curUser = userList.get(0);
-            System.out.println("找到用户corpwxUserid=="+curUser.getFeishuUserid());
-            companyId = curUser.getCompanyId();
-            if (curUser.getIsActive() == 1) {
-                reqParam.put("userId", curUser.getId());
-            } else {
-                //提示账号已停用
-                //reqParam.put("errorMsg", "您的账号已停用,无法登录");
-                reqParam.put("errorMsg", MessageUtils.message("user.inactive"));
-            }
-        } else {
-            //使用UserId比对,之前有的老用户存的是UserId
-            if (feishuInfo == null) {
-                reqParam.put("errorMsg", MessageUtils.message("user.accountNoExist"));
-            } else {
-                User curUser = userMapper.selectOne(new QueryWrapper<User>().eq("company_id", feishuInfo.getCompanyId()).eq("feishu_userid", openUserId));
-                if (curUser != null) {
-                    if (curUser.getIsActive() == 1) {
-                        companyId = curUser.getCompanyId();
-                        reqParam.put("userId", curUser.getId());
-                    } else {
-                        //提示账号已停用
-                        //reqParam.put("errorMsg", "您的账号已停用,无法登录");
-                        reqParam.put("errorMsg", MessageUtils.message("user.inactive"));
-                    }
-                } else {
-                    System.err.println("==生成飞书User失败==");
-                    reqParam.put("errorMsg", "尚未绑定飞书,请使用账号密码登录。");
-                }
-
-            }
-        }
-        reqParam.put("hasTriedAutoLogin", 1);
-        String router = "index";
-        if (companyId > 0) {
-            HashMap compExpireInfo = getCompExpireInfo(companyId);
-            if (compExpireInfo != null) {
-                //过期了
-                router = "expire";
-                reqParam.put("expDate", compExpireInfo.get("expDate"));
-                reqParam.put("version", compExpireInfo.get("version"));
-            }
-        }
-        if (isMobile) {
-            redirecUrl = "http://47.101.180.183:9097/#/" + router;
-        } else {
-            redirecUrl = "http://47.101.180.183:9097/#/" + router;
-        }
-        ModelAndView modelAndView = new ModelAndView(
-                new RedirectView(redirecUrl), reqParam);
-
-        return modelAndView;
-    }
-
-
     @RequestMapping("/corpWXScanningAuth")
     public ModelAndView scanningAuth(String auth_code, String state)throws Exception {
         Map<String,Object> reqParam = new HashMap<String,Object>(16);

+ 296 - 4
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/FeishuInfoController.java

@@ -6,24 +6,28 @@ import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.management.platform.constant.Constant;
 import com.management.platform.entity.*;
+import com.management.platform.entity.vo.UserVO;
 import com.management.platform.mapper.*;
 import com.management.platform.service.FeishuInfoService;
 import com.management.platform.service.SysRoleService;
 import com.management.platform.service.UserService;
+import com.management.platform.service.impl.FeishuInfoServiceImpl;
 import com.management.platform.util.*;
 import com.taobao.api.ApiException;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Value;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.MediaType;
-import org.springframework.http.ResponseEntity;
+import org.springframework.http.*;
+import org.springframework.util.StringUtils;
 import org.springframework.web.bind.annotation.RequestMapping;
 
 import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.client.RestTemplate;
 
 import javax.annotation.Resource;
 import java.time.LocalDateTime;
+import java.time.ZoneOffset;
 import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * <p>
@@ -59,6 +63,22 @@ public class FeishuInfoController {
     private SysRoleMapper sysRoleMapper;
     @Resource
     private UserService userService;
+    @Resource
+    private UserMapper userMapper;
+    @Resource
+    private AuditWorkflowTimeSettingMapper auditWorkflowTimeSettingMapper;
+    @Resource
+    private SysFunctionMapper sysFunctionMapper;
+    @Resource
+    private SysRoleFunctionMapper sysRoleFunctionMapper;
+    @Resource
+    private SysRoleModuleMapper sysRoleModuleMapper;
+    @Resource
+    private SysModuleMapper sysModuleMapper;
+    @Resource
+    private TaskGroupMapper taskGroupMapper;
+    @Resource
+    private ProjectAuditorMapper projectAuditorMapper;
 
 
     /**
@@ -234,5 +254,277 @@ public class FeishuInfoController {
         return allList.stream().filter(all->all.getDepartmentId().intValue() == id).findFirst().get();
     }
 
+
+
+
+    @RequestMapping("/loginByFeishu")
+    public HttpRespMsg loginByFeishu(String code,String appId){
+        HttpRespMsg httpRespMsg=new HttpRespMsg();
+        FeishuInfo feishuInfo = feishuInfoService.getOne(new QueryWrapper<FeishuInfo>().eq("app_id", appId));
+        String url = FeishuInfoServiceImpl.GET_USER_ACCESS_TOKEN;
+        HttpHeaders headers = new HttpHeaders();
+        RestTemplate restTemplate = new RestTemplate();
+        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
+        headers.setContentType(type);
+        headers.add("Authorization","Bearer "+feishuInfoService.getAppAccessToken(feishuInfo));
+        JSONObject ob = new JSONObject();
+        ob.put("grant_type", "authorization_code");
+        ob.put("code", code);
+        HttpEntity<JSONObject> Entity = new HttpEntity<>(ob, headers);
+        ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, Entity, String.class);
+        String redirecUrl = null;
+        String openUserId=null;
+        String fsUserId=null;
+        String corpId=null;
+        if (responseEntity.getStatusCode() == HttpStatus.OK) {
+            String resp = responseEntity.getBody();
+            System.err.println(resp);
+            JSONObject obj = JSONObject.parseObject(resp);
+            if (obj.getIntValue("code") == 0) {
+                System.out.println(obj.toString());
+                JSONObject data = obj.getJSONObject("data");
+                fsUserId = data.getString("user_id");
+                openUserId = data.getString("open_id");
+                corpId = data.getString("tenant_key");
+            }
+        }
+        List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("feishu_userid", openUserId));
+        Integer companyId = 0;
+        if (userList.size() > 0) {
+            //该用户已存在
+            User curUser = userList.get(0);
+            System.out.println("找到用户corpFeishuUserid=="+curUser.getFeishuUserid());
+            companyId = curUser.getCompanyId();
+            String userId = curUser.getId();
+            if (StringUtils.isEmpty(userId) || userId.length() > 50) {
+                //httpRespMsg.setError("账号不存在");
+                httpRespMsg.setError(MessageUtils.message("user.accountNoExist"));
+                return httpRespMsg;
+            }
+            User user = userMapper.selectById(userId);
+            if (user == null) {
+                //httpRespMsg.setError("账号不存在");
+                httpRespMsg.setError(MessageUtils.message("user.accountNoExist"));
+                return httpRespMsg;
+            }
+            if (user.getIsActive() == 0) {
+                //httpRespMsg.setError("该账号已停用");
+                httpRespMsg.setError(MessageUtils.message("user.accountDeactivation"));
+                return httpRespMsg;
+            }
+            //查看该公司非会员公司,只能允许试用三天,超时不可登录
+            Company company = companyMapper.selectOne(new QueryWrapper<Company>().eq("id", user.getCompanyId()));
+            //公司未办理会员
+            if (null != company.getExpirationDate()) {
+                if (0 == company.getSetMeal()) {
+                    //未办理会员
+                    if (company.getExpirationDate().isBefore(LocalDateTime.now())) {
+                        //httpRespMsg.setError("账号试用已到期,请联系客服。");
+                        httpRespMsg.setError(MessageUtils.message("user.accountExpired"));
+                        return httpRespMsg;
+                    }
+                } else {
+                    if (company.getExpirationDate().isBefore(LocalDateTime.now())) {
+                        //httpRespMsg.setError("账号会员已到期,请联系客服。");
+                        httpRespMsg.setError(MessageUtils.message("user.memberExpired"));
+                        return httpRespMsg;
+                    }
+                }
+            }
+            UserVO userVO = new UserVO().setCompanyName(company.getCompanyName());
+            userVO.setCompany(company);
+            BeanUtils.copyProperties(user, userVO);
+            //还要多返回一个公司名字
+            userVO.setPassword("");
+            LocalDateTime remainingTime = company.getExpirationDate() == null ? LocalDateTime.now() : company.getExpirationDate();
+            userVO.setRemainingTime(remainingTime.toInstant(ZoneOffset.of("+8")).toEpochMilli() -
+                    LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli());
+            //检测是否是项目经理,项目经理有审核功能权限
+            userVO.setLeader(judgeIsLeader(userVO.getId()));
+            userVO.setTimeType(timeTypeMapper.selectById(company.getId()));
+            List<Department> manageDeptList = departmentMapper.selectList(new QueryWrapper<Department>().eq("manager_id", userVO.getId()));
+            List<Integer> deptIds = manageDeptList.stream().map(Department::getDepartmentId).collect(Collectors.toList());
+            int num = 0;
+            if (deptIds.size() > 0) {
+                num = auditWorkflowTimeSettingMapper.selectCount(new QueryWrapper<AuditWorkflowTimeSetting>().in("audit_dept_id", deptIds));
+            }
+            userVO.setHasAuditDept(num>0);
+            //获取当前角色的权限菜单
+            setUserRoleMenu(userVO);
+            httpRespMsg.data = userVO;
+            return httpRespMsg;
+        }else httpRespMsg.setError("飞书用户未开通");
+        return httpRespMsg;
+    }
+
+    private boolean judgeIsLeader(String userId) {
+        int cnt = projectAuditorMapper.selectCount(new QueryWrapper<ProjectAuditor>().eq("auditor_id", userId));
+        return cnt>0;
+    }
+
+    public void setUserRoleMenu(UserVO user) {
+        Integer roleId = user.getRoleId();
+        //获取公司的套餐
+        Company company = companyMapper.selectById(user.getCompanyId());
+        TimeType timeType = timeTypeMapper.selectById(company.getId());
+        //按照公司开通的模块进行匹配
+        QueryWrapper<SysModule> queryWrapper = new QueryWrapper<SysModule>().eq("package_time", 1);
+        if (company.getPackageProject() == 1) {
+            queryWrapper.or().eq("package_project", 1);
+        }
+        if (company.getPackageOa() == 1) {
+            queryWrapper.or().eq("package_oa", 1);
+        }
+        if (company.getPackageExpense() == 1) {
+            queryWrapper.or().eq("package_expense", 1);
+        }
+        if (company.getPackageCustomer() == 1) {
+            queryWrapper.or().eq("package_customer", 1);
+        }
+        if (company.getPackageEngineering() == 1) {
+            queryWrapper.or().eq("package_engineering", 1);
+        }
+        if (company.getPackageContract() == 1) {
+            queryWrapper.or().eq("package_contract", 1);
+        }
+        if (company.getPackageEtimecard()== 1) {
+            queryWrapper.or().eq("package_etimecard", 1);
+        }
+        if (company.getPackageFinance() == 1) {
+            queryWrapper.or().eq("package_finance", 1);
+        }
+        if (company.getPackageProvider() == 1) {
+            queryWrapper.or().eq("package_provider", 1);
+        }
+        if (timeType.getReportWorkflow() == 1) {
+            queryWrapper.or().eq("report_workflow", 1);
+        }
+        if (timeType.getNeedDeptAudit() == 1) {
+            queryWrapper.or().eq("need_dept_audit", 1);
+        }
+
+        queryWrapper.orderByAsc("orderitem");
+
+        //返回菜单
+        List<SysRoleModule> rModules = sysRoleModuleMapper.selectList(new QueryWrapper<SysRoleModule>().eq("role_id", roleId));
+        List<Integer> ids = rModules.stream().map(SysRoleModule::getModuleId).collect(Collectors.toList());
+        //项目报告审核模块,如果参与日报的审核,需要自动加上, 或者担任任务分组负责人
+        if (user.isLeader() || user.isHasAuditDept() || (company.getPackageProject() == 1 && taskGroupMapper.selectCount(new QueryWrapper<TaskGroup>().eq("incharger_id", user.getId())) > 0)) {
+            SysModule projectAuditModule = sysModuleMapper.selectOne(new QueryWrapper<SysModule>().eq("name", "项目报告审核"));
+            if (!ids.contains(projectAuditModule.getId())) {
+                ids.add(projectAuditModule.getId());
+            }
+        }
+
+        List<SysModule> moduleList = sysModuleMapper.selectList(queryWrapper);
+
+        //过滤一下,这个角色选中的模块
+        moduleList = moduleList.stream().filter(m->ids.contains(m.getId())).collect(Collectors.toList());
+        if (company.getPackageEngineering() == 1) {
+            //生成虚拟的两个审核放进去
+            SysModule proModule = new SysModule();
+            proModule.setName("专业审核");
+            proModule.setPath("/reviewProfession");
+            proModule.setId(0);
+            moduleList.add(1,proModule);
+            SysModule deptModule = new SysModule();
+            deptModule.setName("部门审核");
+            deptModule.setPath("/reviewDepartment");
+            deptModule.setId(0);
+            moduleList.add(2,deptModule);
+        }
+        //开启了自定义日报列表的情况下,需要菜单上有
+        if (timeType.getCustomDegreeActive() == 1 && moduleList.stream().anyMatch(mod->mod.getName().equals("系统基础设置"))) {
+            SysModule centerManageModule = new SysModule();
+            //centerManageModule.setName(timeType.getCustomDegreeName()+"管理");
+            centerManageModule.setName(timeType.getCustomDegreeName()+MessageUtils.message("project.manage"));
+            centerManageModule.setPath("/centerManage");
+            centerManageModule.setId(0);
+            //加到组织架构前面
+            int findIndex = 0;
+            for (int i=0;i<moduleList.size(); i++) {
+                if (moduleList.get(i).getName().equals("组织架构") || moduleList.get(i).getName().equals("基础数据管理")) {
+                    findIndex = i;
+                    break;
+                }
+            }
+            moduleList.add(findIndex,centerManageModule);
+        }
+        //组装层级关系,默认只有两级
+        List<SysModule> menuList = new ArrayList<>();
+        for (SysModule module : moduleList) {
+            if (module.getParentId() == null) {
+                menuList.add(module);
+            }
+        }
+        for (SysModule mainMenu : menuList) {
+            List<SysModule> list = moduleList.stream().filter(mod -> mainMenu.getId().equals(mod.getParentId())).collect(Collectors.toList());
+            mainMenu.setChildren(list);
+        }
+
+        user.setModuleList(menuList);
+        //此处返回权限集合
+        List<Integer> functionIdList = new ArrayList<>();
+        //获取角色所有的功能id
+        List<SysRoleFunction> funList = sysRoleFunctionMapper.selectList(new QueryWrapper<SysRoleFunction>()
+                .eq("role_id", roleId));
+        for (SysRoleFunction sysRoleFunction : funList) {
+            functionIdList.add(sysRoleFunction.getFunctionId());
+        }
+        //获取当前公司开启了得报表
+        List<CompanyReport> companyReportList = companyReportMapper.selectList(new QueryWrapper<CompanyReport>().eq("company_id", company.getId()));
+        List<Integer> formIds = companyReportList.stream().map(CompanyReport::getReportFormId).collect(Collectors.toList());
+        if (functionIdList.size() > 0) {
+            //根据功能id获取可用的操作代码
+            if (formIds.size() == 0) {
+                formIds.add(-1);
+            }
+            QueryWrapper<SysFunction> functionQueryWrapper = new QueryWrapper<SysFunction>().and(wrapper1->wrapper1.isNull("report_form_id").or().in("report_form_id",formIds)).and(wrapper->{
+                wrapper.eq("package_time", 1);
+                if (company.getPackageProject() == 1) {
+                    wrapper.or().eq("package_project", 1);
+                }
+                if (company.getPackageOa() == 1) {
+                    wrapper.or().eq("package_oa", 1);
+                }
+                if (company.getPackageExpense() == 1) {
+                    wrapper.or().eq("package_expense", 1);
+                }
+                if (company.getPackageCustomer() == 1) {
+                    wrapper.or().eq("package_customer", 1);
+                }
+                if (company.getPackageEngineering() == 1) {
+                    wrapper.or().eq("package_engineering", 1);
+                }
+                if (company.getPackageContract() == 1) {
+                    wrapper.or().eq("package_contract", 1);
+                }
+                if (company.getPackageEtimecard()== 1) {
+                    wrapper.or().eq("package_etimecard", 1);
+                }
+                if (company.getPackageFinance() == 1) {
+                    wrapper.or().eq("package_finance", 1);
+                }
+//            if (company.getPackageProvider() == 1) {
+//                wrapper.or().eq("package_provider", 1);
+//            }
+                if (timeType.getSyncCorpwxTime() == 1) {
+                    wrapper.or().eq("sync_corpwx_time", 1);
+                }
+                //开通财务审核功能的
+                if (timeType.getFinanceAudit() == 1) {
+                    wrapper.or().eq("finance_audit", 1);
+                }
+                return wrapper;
+            });
+            functionQueryWrapper.orderByAsc("seq");
+            List<SysFunction> functionList = sysFunctionMapper.selectList(functionQueryWrapper);
+            functionList = functionList.stream().filter(f->functionIdList.contains(f.getId())).collect(Collectors.toList());
+            user.setFunctionList(functionList);
+        } else {
+            user.setFunctionList(new ArrayList<>());
+        }
+    }
+
 }
 

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/FeishuSendController.java

@@ -0,0 +1,21 @@
+package com.management.platform.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2023-03-02
+ */
+@RestController
+@RequestMapping("/feishu-send")
+public class FeishuSendController {
+
+}
+

+ 23 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/UserController.java

@@ -1,7 +1,9 @@
 package com.management.platform.controller;
 
 
+import com.management.platform.entity.FeishuInfo;
 import com.management.platform.entity.User;
+import com.management.platform.service.FeishuInfoService;
 import com.management.platform.service.UserService;
 import com.management.platform.util.HttpRespMsg;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -12,6 +14,8 @@ import org.springframework.web.multipart.MultipartFile;
 
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * <p>
@@ -30,6 +34,9 @@ public class UserController {
     @Resource
     private HttpServletRequest request;
 
+    @Resource
+    private FeishuInfoService feishuInfoService;
+
     /**
      * 登录网页端
      * username 用户名
@@ -242,5 +249,21 @@ public class UserController {
         return userService.moveUserData(sourceId,targetId,request);
     }
 
+
+    @RequestMapping("/send")
+    public HttpRespMsg send() throws Exception {
+        HttpRespMsg httpRespMsg=new HttpRespMsg();
+        FeishuInfo feishuInfo = feishuInfoService.getById("F171770056");
+        List<String> userIds=new ArrayList<>();
+        userIds.add("ou_8b2f204be465c53024a4687a88b7ece8");
+        List<String> templateVariableDetail=new ArrayList<>();
+        templateVariableDetail.add("通过");
+        templateVariableDetail.add("测试项目");
+        templateVariableDetail.add("闵元凯");
+        templateVariableDetail.add("2023-03-02");
+        feishuInfoService.batchSendCardMessage(feishuInfo,userIds,"项目报告审核通知",templateVariableDetail);
+        return httpRespMsg;
+    }
+
 }
 

+ 54 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/FeishuSend.java

@@ -0,0 +1,54 @@
+package com.management.platform.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableField;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author Seyason
+ * @since 2023-03-02
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class FeishuSend extends Model<FeishuSend> {
+
+    private static final long serialVersionUID=1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 模板名称
+     */
+    @TableField("template_name")
+    private String templateName;
+
+    /**
+     * 飞书卡片消息模板Id
+     */
+    @TableField("template_id")
+    private String templateId;
+
+    /**
+     * 卡片相关变量  发送消息需要注意按照变量赋值
+     */
+    @TableField("template_variable")
+    private String templateVariable;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 16 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/FeishuSendMapper.java

@@ -0,0 +1,16 @@
+package com.management.platform.mapper;
+
+import com.management.platform.entity.FeishuSend;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author Seyason
+ * @since 2023-03-02
+ */
+public interface FeishuSendMapper extends BaseMapper<FeishuSend> {
+
+}

+ 6 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/FeishuInfoService.java

@@ -6,6 +6,8 @@ import com.management.platform.entity.FeishuInfo;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.management.platform.util.HttpRespMsg;
 
+import java.util.List;
+
 /**
  * <p>
  *  服务类
@@ -17,6 +19,8 @@ import com.management.platform.util.HttpRespMsg;
 public interface FeishuInfoService extends IService<FeishuInfo> {
 
 
+    String getAppAccessToken(FeishuInfo feishuInfo);
+
     JSONObject getCorpInfo(FeishuInfo feishuInfo);
 
     JSONArray getAvailableRange(FeishuInfo feishuInfo,String pageToken);
@@ -26,4 +30,6 @@ public interface FeishuInfoService extends IService<FeishuInfo> {
     JSONArray getDepartmentInfo(FeishuInfo feishuInfo, String departmentId);
 
     JSONArray getUserInfoWithDepartment(FeishuInfo feishuInfo, String feishuDeptid, String pageToken);
+
+    void batchSendCardMessage(FeishuInfo feishuInfo, List<String> userIds, String sendTypeName, List<String> templateVariableDetail) throws Exception;
 }

+ 16 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/FeishuSendService.java

@@ -0,0 +1,16 @@
+package com.management.platform.service;
+
+import com.management.platform.entity.FeishuSend;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2023-03-02
+ */
+public interface FeishuSendService extends IService<FeishuSend> {
+
+}

+ 57 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/FeishuInfoServiceImpl.java

@@ -6,15 +6,23 @@ import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.google.gson.JsonObject;
 import com.management.platform.entity.FeishuInfo;
+import com.management.platform.entity.FeishuSend;
+import com.management.platform.entity.User;
 import com.management.platform.mapper.FeishuInfoMapper;
+import com.management.platform.mapper.FeishuSendMapper;
 import com.management.platform.service.FeishuInfoService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.MessageUtils;
+import com.management.platform.util.UserAgentUtils;
 import org.apache.http.client.methods.HttpGet;
 import org.springframework.http.*;
 import org.springframework.stereotype.Service;
 import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.client.RestTemplate;
+import org.springframework.web.servlet.ModelAndView;
+import org.springframework.web.servlet.view.RedirectView;
 
 import javax.annotation.Resource;
 import java.time.LocalDateTime;
@@ -48,12 +56,17 @@ public class FeishuInfoServiceImpl extends ServiceImpl<FeishuInfoMapper, FeishuI
         public static final String GET_USER_LIST="https://open.feishu.cn/open-apis/contact/v3/users/find_by_department";
         /*获取单个部门信息*/
         public static final String GET_DEPARTMENT_INFO="https://open.feishu.cn/open-apis/contact/v3/departments/:department_id";
+        /*批量发送消息*/
+        public static final String BATCH_SEND_MESSAGE="https://open.feishu.cn/open-apis/message/v4/batch_send/";
 
 
         @Resource
         FeishuInfoMapper feishuInfoMapper;
+        @Resource
+        FeishuSendMapper feishuSendMapper;
 
-        public String getAppAccessToken(FeishuInfo feishuInfo){
+        @Override
+        public String getAppAccessToken(FeishuInfo feishuInfo) {
                 String result="";
                 String url = GET_APP_ACCESS_TOKEN;
                 HttpHeaders headers = new HttpHeaders();
@@ -274,4 +287,47 @@ public class FeishuInfoServiceImpl extends ServiceImpl<FeishuInfoMapper, FeishuI
                 return result;
         }
 
+        @Override
+        public void batchSendCardMessage(FeishuInfo feishuInfo,List<String> userIds,String sendTypeName,List<String> templateVariableDetail) throws Exception {
+                if(feishuInfo.getExpireTime().isBefore(LocalDateTime.now())){
+                        String tenantAccessToken = getTenantAccessToken(feishuInfo.getAppId());
+                        feishuInfo.setAccessToken(tenantAccessToken);
+                }
+                FeishuSend feishuSend = feishuSendMapper.selectOne(new QueryWrapper<FeishuSend>().eq("template_name", sendTypeName));
+                if(feishuSend==null){
+                   throw new Exception(sendTypeName+"==========发送模板不存在");
+                }
+                String url = BATCH_SEND_MESSAGE;
+                HttpHeaders headers = new HttpHeaders();
+                RestTemplate restTemplate = new RestTemplate();
+                MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
+                headers.setContentType(type);
+                headers.add("Authorization","Bearer "+feishuInfo.getAccessToken());
+                JSONObject requestMap=new JSONObject();
+                JSONObject card=new JSONObject();
+                card.put("type","template");
+                JSONObject data=new JSONObject();
+                data.put("template_id",feishuSend.getTemplateId());
+                JSONObject templateVariable=new JSONObject();
+                List<String> list = Arrays.asList(feishuSend.getTemplateVariable().split(","));
+                if(list.size()!=templateVariableDetail.size()){
+                        throw new Exception("模板与实际数据不符合");
+                }else {
+                        for (int i = 0; i < list.size(); i++) {
+                                templateVariable.put(list.get(i),templateVariableDetail.get(i));
+                        }
+                        data.put("template_variable",templateVariable);
+                }
+                card.put("data",data);
+                requestMap.put("card",card);
+                requestMap.put("open_ids",userIds);
+                requestMap.put("msg_type","interactive");
+                HttpEntity<JSONObject> httpEntity = new HttpEntity<>(requestMap, headers);
+                ResponseEntity<String> ResponseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class);
+                if (ResponseEntity.getStatusCode() == HttpStatus.OK) {
+                        String resp = ResponseEntity.getBody();
+                        System.out.println(resp);
+                }
+        }
+
 }

+ 20 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/FeishuSendServiceImpl.java

@@ -0,0 +1,20 @@
+package com.management.platform.service.impl;
+
+import com.management.platform.entity.FeishuSend;
+import com.management.platform.mapper.FeishuSendMapper;
+import com.management.platform.service.FeishuSendService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2023-03-02
+ */
+@Service
+public class FeishuSendServiceImpl extends ServiceImpl<FeishuSendMapper, FeishuSend> implements FeishuSendService {
+
+}

+ 18 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/FeishuSendMapper.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.management.platform.mapper.FeishuSendMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.FeishuSend">
+        <id column="id" property="id" />
+        <result column="template_name" property="templateName" />
+        <result column="template_id" property="templateId" />
+        <result column="template_variable" property="templateVariable" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, template_name, template_id, template_variable
+    </sql>
+
+</mapper>