Zimo před 1 týdnem
rodič
revize
9d5c9d56aa
16 změnil soubory, kde provedl 732 přidání a 97 odebrání
  1. 2 0
      yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java
  2. 6 0
      yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java
  3. 18 8
      yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/util/DingtalkUtil.java
  4. 98 0
      yudao-server/src/main/java/cn/iocoder/yudao/server/controller/admin/CrmNoticeController.java
  5. 2 1
      yudao-server/src/main/java/cn/iocoder/yudao/server/controller/admin/FlowGroupController.java
  6. 81 2
      yudao-server/src/main/java/cn/iocoder/yudao/server/controller/admin/TodoController.java
  7. 55 0
      yudao-server/src/main/java/cn/iocoder/yudao/server/controller/admin/vo/crm/CrmNoticePageReqVO.java
  8. 68 0
      yudao-server/src/main/java/cn/iocoder/yudao/server/controller/admin/vo/crm/CrmNoticeRespVO.java
  9. 47 0
      yudao-server/src/main/java/cn/iocoder/yudao/server/controller/admin/vo/crm/CrmNoticeSaveReqVO.java
  10. 27 0
      yudao-server/src/main/java/cn/iocoder/yudao/server/controller/admin/vo/crm/CrmTodoVo.java
  11. 73 0
      yudao-server/src/main/java/cn/iocoder/yudao/server/dal/dataobject/CrmNoticeDO.java
  12. 37 0
      yudao-server/src/main/java/cn/iocoder/yudao/server/dal/mysql/CrmNoticeMapper.java
  13. 90 6
      yudao-server/src/main/java/cn/iocoder/yudao/server/rest/CrmRest.java
  14. 0 80
      yudao-server/src/main/java/cn/iocoder/yudao/server/service/PortalOaFlow.java
  15. 55 0
      yudao-server/src/main/java/cn/iocoder/yudao/server/service/crm/CrmNoticeService.java
  16. 73 0
      yudao-server/src/main/java/cn/iocoder/yudao/server/service/crm/CrmNoticeServiceImpl.java

+ 2 - 0
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java

@@ -23,6 +23,8 @@ public interface AdminUserApi {
      */
     AdminUserRespDTO getUser(Long id);
 
+    AdminUserRespDTO getUserByUsername(String username);
+
     /**
      * 通过用户 ID 查询用户下属
      *

+ 6 - 0
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java

@@ -38,6 +38,12 @@ public class AdminUserApiImpl implements AdminUserApi {
         return BeanUtils.toBean(user, AdminUserRespDTO.class);
     }
 
+    @Override
+    public AdminUserRespDTO getUserByUsername(String username) {
+        AdminUserDO userByUsername = userService.getUserByUsername(username);
+        return BeanUtils.toBean(userByUsername, AdminUserRespDTO.class);
+    }
+
     @Override
     public List<AdminUserRespDTO> getUserListBySubordinate(Long id) {
         // 1.1 获取用户负责的部门

+ 18 - 8
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/util/DingtalkUtil.java

@@ -11,14 +11,8 @@ import com.aliyun.teaopenapi.models.Config;
 import com.aliyun.teautil.models.RuntimeOptions;
 import com.dingtalk.api.DefaultDingTalkClient;
 import com.dingtalk.api.DingTalkClient;
-import com.dingtalk.api.request.OapiGettokenRequest;
-import com.dingtalk.api.request.OapiUserGetbyunionidRequest;
-import com.dingtalk.api.request.OapiV2UserGetRequest;
-import com.dingtalk.api.request.OapiV2UserGetuserinfoRequest;
-import com.dingtalk.api.response.OapiGettokenResponse;
-import com.dingtalk.api.response.OapiUserGetbyunionidResponse;
-import com.dingtalk.api.response.OapiV2UserGetResponse;
-import com.dingtalk.api.response.OapiV2UserGetuserinfoResponse;
+import com.dingtalk.api.request.*;
+import com.dingtalk.api.response.*;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Value;
@@ -112,6 +106,22 @@ public class DingtalkUtil {
         return rsp.getResult().getUserid();
     }
 
+        private static String URLGETUSERINFOBYMOBILE;
+        @Value("${dingtalk.URL_GET_USERINFO_BYMOBILE}")
+        public void setURLGETUSERINFOBYMOBILE(String URLGETUSERINFOBYMOBILE) {
+            DingtalkUtil.URLGETUSERINFOBYMOBILE = URLGETUSERINFOBYMOBILE;
+        }
+
+    public static String getUserInfoByMobile(String mobile) throws Exception {
+        String accessToken = getAccessToken();
+        // 根据手机号获取钉钉userid
+        DingTalkClient dingTalkClientUser = new DefaultDingTalkClient(URLGETUSERINFOBYMOBILE);
+        OapiV2UserGetbymobileRequest phoneReq = new OapiV2UserGetbymobileRequest();
+        phoneReq.setMobile(mobile);
+        OapiV2UserGetbymobileResponse rsp = dingTalkClientUser.execute(phoneReq, accessToken);
+        String userId = rsp.getResult().getUserid();
+        return userId;
+    }
     /**
      * 根据免登授权码获取用户id
      *

+ 98 - 0
yudao-server/src/main/java/cn/iocoder/yudao/server/controller/admin/CrmNoticeController.java

@@ -0,0 +1,98 @@
+package cn.iocoder.yudao.server.controller.admin;
+
+import cn.iocoder.yudao.server.controller.admin.vo.crm.CrmNoticePageReqVO;
+import cn.iocoder.yudao.server.controller.admin.vo.crm.CrmNoticeRespVO;
+import cn.iocoder.yudao.server.controller.admin.vo.crm.CrmNoticeSaveReqVO;
+import cn.iocoder.yudao.server.dal.dataobject.CrmNoticeDO;
+import cn.iocoder.yudao.server.service.crm.CrmNoticeService;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.security.access.prepost.PreAuthorize;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.Operation;
+
+import java.util.*;
+import java.io.IOException;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+
+import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+
+import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
+
+
+@Tag(name = "管理后台 - CRM消息通知")
+@RestController
+@RequestMapping("/rq/iot-crm-notice")
+@Validated
+public class CrmNoticeController {
+
+    @Resource
+    private CrmNoticeService iotCrmNoticeService;
+
+    @PostMapping("/create")
+    @Operation(summary = "创建CRM消息通知")
+    @PreAuthorize("@ss.hasPermission('rq:iot-crm-notice:create')")
+    public CommonResult<Long> createIotCrmNotice(@Valid @RequestBody CrmNoticeSaveReqVO createReqVO) {
+        return success(iotCrmNoticeService.createIotCrmNotice(createReqVO));
+    }
+
+    @PutMapping("/update")
+    @Operation(summary = "更新CRM消息通知")
+    @PreAuthorize("@ss.hasPermission('rq:iot-crm-notice:update')")
+    public CommonResult<Boolean> updateIotCrmNotice(@Valid @RequestBody CrmNoticeSaveReqVO updateReqVO) {
+        iotCrmNoticeService.updateIotCrmNotice(updateReqVO);
+        return success(true);
+    }
+
+    @DeleteMapping("/delete")
+    @Operation(summary = "删除CRM消息通知")
+    @Parameter(name = "id", description = "编号", required = true)
+    @PreAuthorize("@ss.hasPermission('rq:iot-crm-notice:delete')")
+    public CommonResult<Boolean> deleteIotCrmNotice(@RequestParam("id") Long id) {
+        iotCrmNoticeService.deleteIotCrmNotice(id);
+        return success(true);
+    }
+
+    @GetMapping("/get")
+    @Operation(summary = "获得CRM消息通知")
+    @Parameter(name = "id", description = "编号", required = true, example = "1024")
+    @PreAuthorize("@ss.hasPermission('rq:iot-crm-notice:query')")
+    public CommonResult<CrmNoticeRespVO> getIotCrmNotice(@RequestParam("id") Long id) {
+        CrmNoticeDO iotCrmNotice = iotCrmNoticeService.getIotCrmNotice(id);
+        return success(BeanUtils.toBean(iotCrmNotice, CrmNoticeRespVO.class));
+    }
+
+    @GetMapping("/page")
+    @Operation(summary = "获得CRM消息通知分页")
+    @PreAuthorize("@ss.hasPermission('rq:iot-crm-notice:query')")
+    public CommonResult<PageResult<CrmNoticeRespVO>> getIotCrmNoticePage(@Valid CrmNoticePageReqVO pageReqVO) {
+        PageResult<CrmNoticeDO> pageResult = iotCrmNoticeService.getIotCrmNoticePage(pageReqVO);
+        return success(BeanUtils.toBean(pageResult, CrmNoticeRespVO.class));
+    }
+
+    @GetMapping("/export-excel")
+    @Operation(summary = "导出CRM消息通知 Excel")
+    @PreAuthorize("@ss.hasPermission('rq:iot-crm-notice:export')")
+    @ApiAccessLog(operateType = EXPORT)
+    public void exportIotCrmNoticeExcel(@Valid CrmNoticePageReqVO pageReqVO,
+              HttpServletResponse response) throws IOException {
+        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        List<CrmNoticeDO> list = iotCrmNoticeService.getIotCrmNoticePage(pageReqVO).getList();
+        // 导出 Excel
+        ExcelUtils.write(response, "CRM消息通知.xls", "数据", CrmNoticeRespVO.class,
+                        BeanUtils.toBean(list, CrmNoticeRespVO.class));
+    }
+
+}

+ 2 - 1
yudao-server/src/main/java/cn/iocoder/yudao/server/controller/admin/FlowGroupController.java

@@ -105,7 +105,8 @@ public class FlowGroupController {
 
     @GetMapping("/all")
     @Operation(summary = "获得门户流程分组及子项信息")
-    @PreAuthorize("@ss.hasPermission('portal:flow-group:query')")
+//    @PreAuthorize("@ss.hasPermission('portal:flow-group:query')")
+    @PermitAll
     public CommonResult<List<FlowGroupRespVO>> getFlowGroupDetails(@Valid FlowGroupPageReqVO pageReqVO) {
         pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
         List<FlowGroupDO> list = flowGroupService.getFlowGroupPage(pageReqVO).getList();

+ 81 - 2
yudao-server/src/main/java/cn/iocoder/yudao/server/controller/admin/TodoController.java

@@ -4,17 +4,28 @@ import cn.hutool.core.collection.CollUtil;
 import cn.iocoder.yudao.framework.common.exception.ErrorCode;
 import cn.iocoder.yudao.framework.common.exception.ServiceException;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
+import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
+import cn.iocoder.yudao.module.system.oa.OaFlow;
+import cn.iocoder.yudao.module.system.util.DingtalkUtil;
 import cn.iocoder.yudao.server.controller.admin.vo.IotOaPersonRespVO;
+import cn.iocoder.yudao.server.dal.dataobject.CrmNoticeDO;
+import cn.iocoder.yudao.server.dal.mysql.CrmNoticeMapper;
 import cn.iocoder.yudao.server.dal.mysql.PmsMapper;
+import cn.iocoder.yudao.server.rest.CrmRest;
 import cn.iocoder.yudao.server.service.PortalOaFlow;
 import com.google.common.collect.ImmutableMap;
 import io.swagger.v3.oas.annotations.tags.Tag;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
+import javax.annotation.security.PermitAll;
+import java.util.ArrayList;
 import java.util.List;
 
 @Tag(name = "管理后台 - 待办接口")
@@ -26,15 +37,83 @@ public class TodoController {
     private PortalOaFlow portalOaFlow;
     @Resource
     private PmsMapper pmsMapper;
+    @Resource
+    private CrmRest crmRest;
+    @Autowired
+    private AdminUserApi adminUserApi;
+    @Autowired
+    private OaFlow oaFlow;
+    @Autowired
+    private CrmNoticeMapper crmNoticeMapper;
 
     @GetMapping("/oa")
+    @PermitAll
     public CommonResult<ImmutableMap> oaTodo(String workcode) throws Exception {
         List<IotOaPersonRespVO> iotOaPersonRespVOS = pmsMapper.selectOaPersonByCode(workcode);
-        if (CollUtil.isEmpty(iotOaPersonRespVOS)) {
-            throw new ServiceException(new ErrorCode(1,"不存在OA用户"));
+         if (CollUtil.isEmpty(iotOaPersonRespVOS)) {
+            oaFlow.getPerson();
+            iotOaPersonRespVOS = pmsMapper.selectOaPersonByCode(workcode);
+            if (CollUtil.isEmpty(iotOaPersonRespVOS)) {
+                throw new ServiceException(new ErrorCode(1,"不存在OA用户"));
+            }
         }
         ImmutableMap<String, Object> oaTodo = portalOaFlow.getOaTodo(iotOaPersonRespVOS.get(0).getOaId());
         return CommonResult.success(oaTodo);
     }
 
+    @GetMapping("/crm")
+    @PermitAll
+    public CommonResult<ImmutableMap<String, Object>> crmTodo(String workcode) throws Exception {
+        ImmutableMap<String, String> stringStringImmutableMap = crmRest.refreshToken("ec301168-d9d7-4f0c-a73c-03f50e952a3a");
+        AdminUserRespDTO userByUsername = adminUserApi.getUserByUsername(workcode);
+        if (userByUsername == null) {throw new ServiceException(new ErrorCode(1,"门户系统中不存在该用户"));}
+
+        String dingUserId = DingtalkUtil.getUserInfoByMobile(userByUsername.getMobile());
+        String crmUserId = crmRest.querySqlUser(String.valueOf(stringStringImmutableMap.get("access")), dingUserId);
+        if (StringUtils.isBlank(crmUserId)) {
+            return CommonResult.success(ImmutableMap.of("todoCount",0,"todoList", new ArrayList<>()));
+        }
+        ImmutableMap<String, Object> access = crmRest.getCrmTodoList(String.valueOf(stringStringImmutableMap.get("access")), crmUserId);
+        return CommonResult.success(access);
+    }
+
+    @GetMapping("/crm/notice")
+    @PermitAll
+    public CommonResult<List> crmNotice(String workcode) throws Exception {
+        List<CrmNoticeDO> workCode = crmNoticeMapper.selectList("work_code", workcode);
+        if (CollUtil.isNotEmpty(workCode)) {
+            return CommonResult.success(workCode);
+        } else {
+            ImmutableMap<String, String> stringStringImmutableMap = crmRest.refreshToken("ec301168-d9d7-4f0c-a73c-03f50e952a3a");
+            AdminUserRespDTO userByUsername = adminUserApi.getUserByUsername(workcode);
+            if (userByUsername == null) {throw new ServiceException(new ErrorCode(1,"门户系统中不存在该用户"));}
+
+            String dingUserId = DingtalkUtil.getUserInfoByMobile(userByUsername.getMobile());
+            String crmUserId = crmRest.querySqlUser(String.valueOf(stringStringImmutableMap.get("access")), dingUserId);
+            if (StringUtils.isBlank(crmUserId)) {
+                return CommonResult.success(new ArrayList());
+            }
+            List access = crmRest.getCrmNotice(String.valueOf(stringStringImmutableMap.get("access")), crmUserId, workcode);
+            return CommonResult.success(access);
+        }
+    }
+
+    @GetMapping("/crm/notice/self")
+    @PermitAll
+    public CommonResult<List> crmNoticeSelfSystem(String workcode) throws Exception {
+        List<CrmNoticeDO> workCode = crmNoticeMapper.selectList("work_code", workcode);
+        return CommonResult.success(workCode);
+    }
+
+    @GetMapping("/crm/notice/readed")
+    @PermitAll
+    public CommonResult<String> crmNoticeReaded(String workcode) throws Exception {
+        List<CrmNoticeDO> workCode = crmNoticeMapper.selectList("work_code", workcode);
+        workCode.forEach(item -> {
+            //设置为已读
+            item.setStatus("1");
+            crmNoticeMapper.updateById(item);
+        });
+        return CommonResult.success("完成已读");
+    }
 }

+ 55 - 0
yudao-server/src/main/java/cn/iocoder/yudao/server/controller/admin/vo/crm/CrmNoticePageReqVO.java

@@ -0,0 +1,55 @@
+package cn.iocoder.yudao.server.controller.admin.vo.crm;
+
+import lombok.*;
+import io.swagger.v3.oas.annotations.media.Schema;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import org.springframework.format.annotation.DateTimeFormat;
+import java.time.LocalDateTime;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@Schema(description = "管理后台 - CRM消息通知分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class CrmNoticePageReqVO extends PageParam {
+
+    @Schema(description = "发起通知人ID", example = "1264")
+    private String sourceId;
+
+    @Schema(description = "新旧通知标识(0、null表示旧,表示是新)")
+    private String typeFlg;
+
+    @Schema(description = "接收通知ID", example = "2766")
+    private String targetId;
+
+    @Schema(description = "对象下条目ID", example = "1905")
+    private String operateId;
+
+    @Schema(description = "通知类型", example = "2")
+    private String noticeType;
+
+    @Schema(description = "列表通知条目")
+    private String content;
+
+    @Schema(description = "列表通知条目的title")
+    private String contentMajor;
+
+    @Schema(description = "创建人")
+    private String createdAt;
+
+    @Schema(description = "来自应用通知类型", example = "2")
+    private String appType;
+
+    @Schema(description = "关联业务ID", example = "5663")
+    private String belongId;
+
+    @Schema(description = "通知状态", example = "2")
+    private String status;
+
+    @Schema(description = "创建时间")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime[] createTime;
+
+    private String workCode;
+}

+ 68 - 0
yudao-server/src/main/java/cn/iocoder/yudao/server/controller/admin/vo/crm/CrmNoticeRespVO.java

@@ -0,0 +1,68 @@
+package cn.iocoder.yudao.server.controller.admin.vo.crm;
+
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.*;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - CRM消息通知 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class CrmNoticeRespVO {
+
+    @Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "14994")
+    @ExcelProperty("主键id")
+    private Long id;
+
+    @Schema(description = "发起通知人ID", example = "1264")
+    @ExcelProperty("发起通知人ID")
+    private String sourceId;
+
+    @Schema(description = "新旧通知标识(0、null表示旧,表示是新)")
+    @ExcelProperty("新旧通知标识(0、null表示旧,表示是新)")
+    private String typeFlg;
+
+    @Schema(description = "接收通知ID", example = "2766")
+    @ExcelProperty("接收通知ID")
+    private String targetId;
+
+    @Schema(description = "对象下条目ID", example = "1905")
+    @ExcelProperty("对象下条目ID")
+    private String operateId;
+
+    @Schema(description = "通知类型", example = "2")
+    @ExcelProperty("通知类型")
+    private String noticeType;
+
+    @Schema(description = "列表通知条目")
+    @ExcelProperty("列表通知条目")
+    private String content;
+
+    @Schema(description = "列表通知条目的title")
+    @ExcelProperty("列表通知条目的title")
+    private String contentMajor;
+
+    @Schema(description = "创建人")
+    @ExcelProperty("创建人")
+    private String createdAt;
+
+    @Schema(description = "来自应用通知类型", example = "2")
+    @ExcelProperty("来自应用通知类型")
+    private String appType;
+
+    @Schema(description = "关联业务ID", example = "5663")
+    @ExcelProperty("关联业务ID")
+    private String belongId;
+
+    @Schema(description = "通知状态", example = "2")
+    @ExcelProperty("通知状态")
+    private String status;
+
+    @Schema(description = "创建时间")
+    @ExcelProperty("创建时间")
+    private LocalDateTime createTime;
+
+    private String workCode;
+}

+ 47 - 0
yudao-server/src/main/java/cn/iocoder/yudao/server/controller/admin/vo/crm/CrmNoticeSaveReqVO.java

@@ -0,0 +1,47 @@
+package cn.iocoder.yudao.server.controller.admin.vo.crm;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.*;
+
+@Schema(description = "管理后台 - CRM消息通知新增/修改 Request VO")
+@Data
+public class CrmNoticeSaveReqVO {
+
+    @Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "14994")
+    private Long id;
+
+    @Schema(description = "发起通知人ID", example = "1264")
+    private String sourceId;
+
+    @Schema(description = "新旧通知标识(0、null表示旧,表示是新)")
+    private String typeFlg;
+
+    @Schema(description = "接收通知ID", example = "2766")
+    private String targetId;
+
+    @Schema(description = "对象下条目ID", example = "1905")
+    private String operateId;
+
+    @Schema(description = "通知类型", example = "2")
+    private String noticeType;
+
+    @Schema(description = "列表通知条目")
+    private String content;
+
+    @Schema(description = "列表通知条目的title")
+    private String contentMajor;
+
+    @Schema(description = "创建人")
+    private String createdAt;
+
+    @Schema(description = "来自应用通知类型", example = "2")
+    private String appType;
+
+    @Schema(description = "关联业务ID", example = "5663")
+    private String belongId;
+
+    @Schema(description = "通知状态", example = "2")
+    private String status;
+
+    private String workCode;
+}

+ 27 - 0
yudao-server/src/main/java/cn/iocoder/yudao/server/controller/admin/vo/crm/CrmTodoVo.java

@@ -0,0 +1,27 @@
+package cn.iocoder.yudao.server.controller.admin.vo.crm;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class CrmTodoVo implements Serializable {
+    private static final long serialVersionUID = 1L;
+    private Long assigneeId;
+    private Long createdAt;
+    private Long dataId;
+    private Long endAt;
+    private String entityApikey;
+    private Long entityId;
+    private Long entityTypeId;
+    private Long id;
+    private String instTitle;
+    private String priority;
+    private Long procId;
+    private Long procInstId;
+    private Long procdefId;
+    private int status;
+    private Long submitAt;
+    private Long submitterId;
+    private String usertaskInstId;
+}

+ 73 - 0
yudao-server/src/main/java/cn/iocoder/yudao/server/dal/dataobject/CrmNoticeDO.java

@@ -0,0 +1,73 @@
+package cn.iocoder.yudao.server.dal.dataobject;
+
+import lombok.*;
+import com.baomidou.mybatisplus.annotation.*;
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+
+/**
+ * CRM消息通知 DO
+ *
+ * @author 超级管理员
+ */
+@TableName("rq_iot_crm_notice")
+@KeySequence("rq_iot_crm_notice_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class CrmNoticeDO extends BaseDO {
+
+    /**
+     * 主键id
+     */
+    @TableId
+    private Long id;
+    /**
+     * 发起通知人ID
+     */
+    private String sourceId;
+    /**
+     * 新旧通知标识(0、null表示旧,表示是新)
+     */
+    private String typeFlg;
+    /**
+     * 接收通知ID
+     */
+    private String targetId;
+    /**
+     * 对象下条目ID
+     */
+    private String operateId;
+    /**
+     * 通知类型
+     */
+    private String noticeType;
+    /**
+     * 列表通知条目
+     */
+    private String content;
+    /**
+     * 列表通知条目的title
+     */
+    private String contentMajor;
+    /**
+     * 创建人
+     */
+    private String createdAt;
+    /**
+     * 来自应用通知类型
+     */
+    private String appType;
+    /**
+     * 关联业务ID
+     */
+    private String belongId;
+    /**
+     * 通知状态
+     */
+    private String status;
+
+    private String workCode;
+}

+ 37 - 0
yudao-server/src/main/java/cn/iocoder/yudao/server/dal/mysql/CrmNoticeMapper.java

@@ -0,0 +1,37 @@
+package cn.iocoder.yudao.server.dal.mysql;
+
+import java.util.*;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.server.controller.admin.vo.crm.CrmNoticePageReqVO;
+import cn.iocoder.yudao.server.dal.dataobject.CrmNoticeDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * CRM消息通知 Mapper
+ *
+ * @author 超级管理员
+ */
+@Mapper
+public interface CrmNoticeMapper extends BaseMapperX<CrmNoticeDO> {
+
+    default PageResult<CrmNoticeDO> selectPage(CrmNoticePageReqVO reqVO) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<CrmNoticeDO>()
+                .eqIfPresent(CrmNoticeDO::getSourceId, reqVO.getSourceId())
+                .eqIfPresent(CrmNoticeDO::getTypeFlg, reqVO.getTypeFlg())
+                .eqIfPresent(CrmNoticeDO::getTargetId, reqVO.getTargetId())
+                .eqIfPresent(CrmNoticeDO::getOperateId, reqVO.getOperateId())
+                .eqIfPresent(CrmNoticeDO::getNoticeType, reqVO.getNoticeType())
+                .eqIfPresent(CrmNoticeDO::getContent, reqVO.getContent())
+                .eqIfPresent(CrmNoticeDO::getContentMajor, reqVO.getContentMajor())
+                .eqIfPresent(CrmNoticeDO::getCreatedAt, reqVO.getCreatedAt())
+                .eqIfPresent(CrmNoticeDO::getAppType, reqVO.getAppType())
+                .eqIfPresent(CrmNoticeDO::getBelongId, reqVO.getBelongId())
+                .eqIfPresent(CrmNoticeDO::getStatus, reqVO.getStatus())
+                .betweenIfPresent(CrmNoticeDO::getCreateTime, reqVO.getCreateTime())
+                .orderByDesc(CrmNoticeDO::getId));
+    }
+
+}

+ 90 - 6
yudao-server/src/main/java/cn/iocoder/yudao/server/rest/CrmRest.java

@@ -1,7 +1,13 @@
 package cn.iocoder.yudao.server.rest;
 
+import cn.hutool.core.collection.CollUtil;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.system.oa.SslSkippingRestTemplate;
+import cn.iocoder.yudao.server.controller.admin.vo.crm.CrmTodoVo;
+import cn.iocoder.yudao.server.dal.dataobject.CrmNoticeDO;
+import cn.iocoder.yudao.server.dal.mysql.CrmNoticeMapper;
 import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.google.common.collect.ImmutableMap;
 import lombok.Data;
@@ -13,9 +19,9 @@ import org.springframework.stereotype.Component;
 import org.springframework.util.MultiValueMap;
 import org.springframework.web.client.RestTemplate;
 
-import javax.annotation.Resource;
+import java.util.ArrayList;
 import java.util.List;
-import java.util.Objects;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.atomic.AtomicReference;
 
 @Component
@@ -23,6 +29,11 @@ public class CrmRest {
     private static final String CLIENT_ID = "baca57533e1909447a6f1918cad00bc2";
     private static final String CLIENT_SECRET = "d38fcf6dcb0f754cece55862b1ae77b3";
     private static final String REDIRECT_URI = "https://api-tencent.xiaoshouyi.com/";
+    private final CrmNoticeMapper crmNoticeMapper;
+
+    public CrmRest(CrmNoticeMapper crmNoticeMapper) {
+        this.crmNoticeMapper = crmNoticeMapper;
+    }
 
     /**
      * 刷新token
@@ -48,26 +59,77 @@ public class CrmRest {
      * @param token
      * @return
      */
-    public String querySqlUser(String token, String workcode) {
+    public String querySqlUser(String token, String dingUserId) {
         HttpHeaders headers = new HttpHeaders();
         headers.add("Authorization", token);
         HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(headers);
         RestTemplate restTemplate = SslSkippingRestTemplate.createRestTemplate();
-        ResponseEntity<String> exchange = restTemplate.exchange("https://api-tencent.xiaoshouyi.com/rest/data/v2/query?q=select id,name,unionId,phone,personalEmail from userselect id,name,unionId,phone,personalEmail from user",
+        ResponseEntity<String> exchange = restTemplate.exchange("https://api-tencent.xiaoshouyi.com/rest/data/v2/query?" +
+                        "q=select id,name,unionId,phone,personalEmail from user where unionId is not null",
                 HttpMethod.GET, requestEntity, String.class);
         String body = exchange.getBody();
-        List<CrmUser> crmUsers = JSON.parseArray(body, CrmUser.class);
+        String result = JSON.parseObject(body).getString("result");
+        String records = JSON.parseObject(result).getJSONArray("records").toJSONString();
+
+        List<CrmUser> crmUsers = JSON.parseArray(records, CrmUser.class);
         AtomicReference<String> userId = new AtomicReference<>("");
         if (crmUsers != null) {
-            crmUsers.stream().filter(e -> e.getUnionId().equals(workcode)).findAny().ifPresent(f ->{
+            crmUsers.stream().filter(e -> e.getUnionId().equals(dingUserId)).findAny().ifPresent(f ->{
                 userId.set(f.getId());
             });
         }
         return userId.get();
     }
 
+    public ImmutableMap<String, Object> getCrmTodoList(String token, String crmUserId) {
+        HttpHeaders headers = new HttpHeaders();
+        headers.add("Authorization", token);
+        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(headers);
+        RestTemplate restTemplate = SslSkippingRestTemplate.createRestTemplate();
+        ResponseEntity<String> exchange = restTemplate.exchange("https://api-tencent.xiaoshouyi.com/rest/data/v2.0/creekflow/task/filter?assigneeIds="+crmUserId+"&status=pending&pageNo=1&pageSize=1000",
+                HttpMethod.GET, requestEntity, String.class);
+        String body = exchange.getBody();
+        String data = JSON.parseObject(body).getString("data");
+        String records = JSON.parseObject(data).getJSONArray("records").toJSONString();
+        List<CrmTodoVo> crmTodoVos = JSON.parseArray(records, CrmTodoVo.class);
+        Integer dataCount = JSON.parseObject(data).getInteger("dataCount");
+
+        return ImmutableMap.of("todoCount", dataCount,"todoList", crmTodoVos);
+    }
+
+    public List getCrmNotice(String token, String crmUserId, String workcode) {
+        HttpHeaders headers = new HttpHeaders();
+        headers.add("Authorization", token);
+        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(headers);
+        RestTemplate restTemplate = SslSkippingRestTemplate.createRestTemplate();
+        ResponseEntity<String> exchange = restTemplate.exchange("https://api-tencent.xiaoshouyi.com/rest/notice/v2.0/notice/actions/list?userId="+crmUserId+"&pageNo=1&pageSize=1000",
+                HttpMethod.GET, requestEntity, String.class);
+        String body = exchange.getBody();
+        String data = JSON.parseObject(body).getString("result");
+        JSONArray objects = JSON.parseArray(data);
+        if (CollUtil.isEmpty(objects)) {return new ArrayList<>();}
+        String data1 = JSON.parseObject(objects.get(0).toString()).getString("data");
+        String records = JSON.parseObject(data1).getJSONArray("records").toJSONString();
+        List<CrmNotice> crmNotices = JSON.parseArray(records, CrmNotice.class);
 
+        //todo 异步逻辑处理
+//        CompletableFuture.runAsync(()->{
+            //先删除
+           crmNoticeMapper.deleteByMap(ImmutableMap.of("work_code",workcode));
+           //再添加到消息表里面
+           crmNotices.forEach(e ->{
+               CrmNoticeDO crmNoticeDO = new CrmNoticeDO();
+               CrmNoticeDetail notice = e.getNotice();
+               BeanUtils.copyProperties(notice,crmNoticeDO);
+               crmNoticeDO.setContentMajor(e.getContent());
+               crmNoticeDO.setDeleted(false);
+               crmNoticeDO.setWorkCode(workcode);
+               crmNoticeMapper.insert(crmNoticeDO);
+           });
+//        });
 
+        return crmNotices;
+    }
 
     @Data
     static class CrmUser{
@@ -77,4 +139,26 @@ public class CrmRest {
         private String phone;
         private String personalEmail;
     }
+
+    @Data
+    static class CrmNotice{
+        private String content;
+        private CrmNoticeDetail notice;
+    }
+    @Data
+    static class CrmNoticeDetail {
+        private Long sourceId;
+        private int typeFlg;
+        private String systemId;
+        private Long targetId;
+        private Long operateId;
+        private int noticeType;
+        private String content;
+        private Long createdAt;
+        private int appType;
+        private Long tenantId;
+        private Long beLongId;
+        private Long id;
+        private int status;
+    }
 }

+ 0 - 80
yudao-server/src/main/java/cn/iocoder/yudao/server/service/PortalOaFlow.java

@@ -115,84 +115,4 @@ public class PortalOaFlow {
         return todo;
     }
 
-//    public void createOutRepairFlow(IotMaintainDO iotMaintainDO) throws Exception {
-//        String token = getToken();
-//        HttpHeaders headersOut = new HttpHeaders();
-//        headersOut.add("token", token);
-//        headersOut.add("appid", appid);
-//        String person = E9ApiTokenUtil.encryptString(spk, iotMaintainDO.getApplyPersonId());
-//        headersOut.add("userid", person);
-//        headersOut.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
-//
-//        OutRepairFlow flow = new OutRepairFlow().setFieldName("xmjl").setFieldValue(iotMaintainDO.getProjectManager());
-//        OutRepairFlow flow1 = new OutRepairFlow().setFieldName("sqr").setFieldValue(iotMaintainDO.getApplyPersonId());
-//        List<IotOaPersonDO> dos = iotOaPersonMapper.selectList("oa_id", iotMaintainDO.getApplyPersonId());
-//        if (CollUtil.isEmpty(dos)) {
-//            throw new ServiceException(new ErrorCode(111, "不存在oa部门"));
-//        }
-//        OutRepairFlow flow2 = new OutRepairFlow().setFieldName("sqbm").setFieldValue(dos.get(0).getDepartmentid());
-//        OutRepairFlow flow3 = new OutRepairFlow().setFieldName("sqrq").setFieldValue(DateUtil.format(new Date(), DatePattern.NORM_DATE_PATTERN));
-//        OutRepairFlow flow4 = new OutRepairFlow().setFieldName("clxh").setFieldValue(iotMaintainDO.getDeviceName());
-//        OutRepairFlow flow5 = new OutRepairFlow().setFieldName("cph").setFieldValue(iotMaintainDO.getDeviceName());
-//        OutRepairFlow flow6 = new OutRepairFlow().setFieldName("wxyy").setFieldValue(iotMaintainDO.getMaintainDescription());
-//        OutRepairFlow flow7 = new OutRepairFlow().setFieldName("ygjey").setFieldValue(String.valueOf(iotMaintainDO.getMaintainFee()));
-//        OutRepairFlow flow8 = new OutRepairFlow().setFieldName("wxdd").setFieldValue(Objects.isNull(iotMaintainDO.getAddress())?"": iotMaintainDO.getAddress());
-//        OutRepairFlow flow9 = new OutRepairFlow().setFieldName("ggxh").setFieldValue(String.valueOf(iotMaintainDO.getModel()));
-//        OutRepairFlow flow10 = new OutRepairFlow().setFieldName("qyrq").setFieldValue(StringUtils.substring(iotMaintainDO.getEnableDate(), 0,10));
-//        OutRepairFlow flow11 = new OutRepairFlow().setFieldName("wxlb").setFieldValue(String.valueOf(iotMaintainDO.getMaintainClassify()));
-//        OutRepairFlow flow12 = new OutRepairFlow().setFieldName("yzglxs").setFieldValue(Objects.isNull(iotMaintainDO.getKmHour())?"": iotMaintainDO.getKmHour());
-//        OutRepairFlow flow13 = new OutRepairFlow().setFieldName("wxcj").setFieldValue(String.valueOf(iotMaintainDO.getSupplier()));
-//        OutRepairFlow flow14 = new OutRepairFlow().setFieldName("gzms").setFieldValue(String.valueOf(iotMaintainDO.getDescription()));
-//        OutRepairFlow flow15 = new OutRepairFlow().setFieldName("wxxm").setFieldValue(String.valueOf(iotMaintainDO.getMaintainItem()));
-//        List<String> strings = JSON.parseArray(iotMaintainDO.getOutFile(), String.class);
-//        List<ImmutableMap> files = new ArrayList<>();
-//        strings.forEach(e ->{
-//            String fileName = FileUtils.getFileNameByUrlParse(e);
-//            String s1 = FileUtils.encodePathSegment(fileName);
-//            String s = StringUtils.substringBeforeLast(e, "/");
-//            files.add(ImmutableMap.of("filePath", s+"/"+s1,"fileName", fileName));
-//        });
-//
-//        OutRepairFlow flow16 = new OutRepairFlow().setFieldName("fjsc").setFieldValue(JSON.toJSONString(files));
-//        OutRepairFlow flow17 = new OutRepairFlow().setFieldName("sfdy").setFieldValue("1");
-//        ImmutableList<OutRepairFlow> outRepairFlows = ImmutableList.of(flow16,flow12, flow3, flow4, flow5, flow6, flow7, flow8, flow9, flow10, flow11, flow2, flow, flow14, flow1, flow15, flow13,flow17);
-//
-//
-//
-//        // 创建表单数据
-//        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
-//        params.add("workflowId", workflowId);
-//        params.add("requestName", requestName);
-//        params.add("mainData", JSON.toJSONString(outRepairFlows));
-//        Map<String, String> other = new HashMap<>();
-//        other.put("isnextflow", "1");
-//        params.add("otherParams", JSON.toJSONString(other));
-//        System.out.println("------------"+JSON.toJSONString(params));
-//        System.out.println(headersOut);
-//
-//        // 3. 组合请求头和请求体
-//        HttpEntity<MultiValueMap<String, Object>> requestEntityOut = new HttpEntity<>(params, headersOut);
-////        RestTemplate restTemplate = SslSkippingRestTemplate.createRestTemplate();
-//        String out = restTemplate.postForObject(outMaintainUrl, requestEntityOut, String.class);
-//        JSONObject outInfo = JSON.parseObject(out);
-//        //请求成功
-//        if (Objects.isNull(outInfo) || !"success".equalsIgnoreCase(String.valueOf(outInfo.get("code")))) {
-//            throw new ServiceException(new ErrorCode(777, String.valueOf(outInfo.get("msg"))));
-//        }
-//        JSONObject jsonObject = JSON.parseObject(outInfo.get("data").toString());
-//        String requestid = String.valueOf(jsonObject.get("requestid"));
-//        iotMaintainDO.setRequestId(requestid);
-//        iotMaintainMapper.updateById(iotMaintainDO);
-//
-//    }
-//
-//    @Data
-//    @Builder
-//    @NoArgsConstructor
-//    @AllArgsConstructor
-//    public static class OutRepairFlow {
-//        private String fieldName;
-//        private String fieldValue;
-//    }
-
 }

+ 55 - 0
yudao-server/src/main/java/cn/iocoder/yudao/server/service/crm/CrmNoticeService.java

@@ -0,0 +1,55 @@
+package cn.iocoder.yudao.server.service.crm;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.server.controller.admin.vo.crm.CrmNoticePageReqVO;
+import cn.iocoder.yudao.server.controller.admin.vo.crm.CrmNoticeSaveReqVO;
+import cn.iocoder.yudao.server.dal.dataobject.CrmNoticeDO;
+
+import javax.validation.Valid;
+
+/**
+ * CRM消息通知 Service 接口
+ *
+ * @author 超级管理员
+ */
+public interface CrmNoticeService {
+
+    /**
+     * 创建CRM消息通知
+     *
+     * @param createReqVO 创建信息
+     * @return 编号
+     */
+    Long createIotCrmNotice(@Valid CrmNoticeSaveReqVO createReqVO);
+
+    /**
+     * 更新CRM消息通知
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateIotCrmNotice(@Valid CrmNoticeSaveReqVO updateReqVO);
+
+    /**
+     * 删除CRM消息通知
+     *
+     * @param id 编号
+     */
+    void deleteIotCrmNotice(Long id);
+
+    /**
+     * 获得CRM消息通知
+     *
+     * @param id 编号
+     * @return CRM消息通知
+     */
+    CrmNoticeDO getIotCrmNotice(Long id);
+
+    /**
+     * 获得CRM消息通知分页
+     *
+     * @param pageReqVO 分页查询
+     * @return CRM消息通知分页
+     */
+    PageResult<CrmNoticeDO> getIotCrmNoticePage(CrmNoticePageReqVO pageReqVO);
+
+}

+ 73 - 0
yudao-server/src/main/java/cn/iocoder/yudao/server/service/crm/CrmNoticeServiceImpl.java

@@ -0,0 +1,73 @@
+package cn.iocoder.yudao.server.service.crm;
+
+import cn.iocoder.yudao.framework.common.exception.ErrorCode;
+import cn.iocoder.yudao.server.controller.admin.vo.crm.CrmNoticePageReqVO;
+import cn.iocoder.yudao.server.controller.admin.vo.crm.CrmNoticeSaveReqVO;
+import cn.iocoder.yudao.server.dal.dataobject.CrmNoticeDO;
+import cn.iocoder.yudao.server.dal.mysql.CrmNoticeMapper;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+
+
+import javax.annotation.Resource;
+
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+
+/**
+ * CRM消息通知 Service 实现类
+ *
+ * @author 超级管理员
+ */
+@Service
+@Validated
+public class CrmNoticeServiceImpl implements CrmNoticeService {
+
+    @Resource
+    private CrmNoticeMapper crmNoticeMapper;
+
+    @Override
+    public Long createIotCrmNotice(CrmNoticeSaveReqVO createReqVO) {
+        // 插入
+        CrmNoticeDO iotCrmNotice = BeanUtils.toBean(createReqVO, CrmNoticeDO.class);
+        crmNoticeMapper.insert(iotCrmNotice);
+        // 返回
+        return iotCrmNotice.getId();
+    }
+
+    @Override
+    public void updateIotCrmNotice(CrmNoticeSaveReqVO updateReqVO) {
+        // 校验存在
+        validateIotCrmNoticeExists(updateReqVO.getId());
+        // 更新
+        CrmNoticeDO updateObj = BeanUtils.toBean(updateReqVO, CrmNoticeDO.class);
+        crmNoticeMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void deleteIotCrmNotice(Long id) {
+        // 校验存在
+        validateIotCrmNoticeExists(id);
+        // 删除
+        crmNoticeMapper.deleteById(id);
+    }
+
+    private void validateIotCrmNoticeExists(Long id) {
+        if (crmNoticeMapper.selectById(id) == null) {
+            throw exception(new ErrorCode(2,"不存咋"));
+        }
+    }
+
+    @Override
+    public CrmNoticeDO getIotCrmNotice(Long id) {
+        return crmNoticeMapper.selectById(id);
+    }
+
+    @Override
+    public PageResult<CrmNoticeDO> getIotCrmNoticePage(CrmNoticePageReqVO pageReqVO) {
+        return crmNoticeMapper.selectPage(pageReqVO);
+    }
+
+}