server/services/pom.xml
@@ -24,6 +24,21 @@ <artifactId>hutool-all</artifactId> <version>5.8.40</version> </dependency> <dependency> <groupId>com.aliyun</groupId> <artifactId>dingtalk</artifactId> <version>2.2.25</version> </dependency> <dependency> <groupId>com.dingtalk.open</groupId> <artifactId>app-stream-client</artifactId> <version>1.3.7</version> </dependency> <dependency> <groupId>com.aliyun</groupId> <artifactId>alibaba-dingtalk-service-sdk</artifactId> <version>2.0.0</version> </dependency> </dependencies> <properties> <maven.compiler.source>8</maven.compiler.source> server/services/src/main/java/com/doumee/core/constants/Constants.java
@@ -76,6 +76,8 @@ public static final Integer FOUR = 4; public static final Integer SIX = 6; public static final Integer FIVE = 5; public static final Integer DD_STATUS_SUCCESS_CODE = 200 ; public static final Long DD_ERR_CODE = 0L ; public static final String INENTITY_FILES = "INENTITY_FILES"; public static final String MEMBER_FILES = "MEMBER_FILES"; public static final String CATEGORY_FILES = "CATEGORY_FILES"; @@ -85,6 +87,10 @@ public static final String ZBOM_TICKET_LOGIN_URL ="ZBOM_TICKET_LOGIN_URL" ; public static final String OBJCET_STORAGE = "OBJCET_STORAGE"; public static final Object OBJECT_TYPE_CASES = "OBJECT_TYPE_CASES"; public static final String DD_TALK = "DD_TALK" ; public static final String APP_KEY = "APP_KEY"; public static final String APP_SECRET = "APP_SECRET"; public static final String DD_USER_TYPE = "DD_USER"; public static boolean WORKORDER_SHE_EMAIL_SENDING = false; public static boolean DEALING_COMPANY_SYNC = false ; public static boolean DEALING_MEMBER_SYNC = false ; server/services/src/main/java/com/doumee/core/dingTalk/DingTalk.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,128 @@ package com.doumee.core.dingTalk; import com.alibaba.fastjson.JSONObject; import com.aliyun.dingtalkoauth2_1_0.Client; import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest; import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenResponse; import com.aliyun.dingtalkoauth2_1_0.models.GetTokenResponse; import com.aliyun.dingtalktodo_1_0.models.*; import com.aliyun.tea.TeaException; import com.aliyun.teautil.models.RuntimeOptions; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.dingtalk.api.DefaultDingTalkClient; import com.dingtalk.api.DingTalkClient; import com.dingtalk.api.request.*; import com.dingtalk.api.response.*; import com.doumee.biz.system.SystemDictDataBiz; import com.doumee.core.constants.Constants; import com.doumee.core.constants.ResponseStatus; import com.doumee.core.exception.BusinessException; import com.doumee.dao.system.dto.DingLoginDTO; import com.doumee.dao.system.model.SystemDictData; import com.taobao.api.ApiException; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.util.*; import java.util.stream.Collectors; /** * Created by IntelliJ IDEA. * * @Author : Rk * @create 2025/9/24 16:25 */ @Slf4j @Service public class DingTalk { @Autowired private SystemDictDataBiz systemDictDataBiz; @Value("${dingtalk.clientId}") private String clientId; @Value("${dingtalk.clientSecret}") private String clientSecret; /** * ä½¿ç¨ Token åå§åè´¦å·Client æ°æ®åæ¥ç±» * @return Client com.aliyun.dingtalkoauth2_1_0. * @throws Exception */ public static Client createClient() throws Exception { com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config(); config.protocol = "https"; config.regionId = "central"; return new Client(config); } /** * å¾ åéç¥ç±» 龿¥æ± * @return * @throws Exception */ public static com.aliyun.dingtalktodo_1_0.Client createV1Client() throws Exception { com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config(); config.protocol = "https"; config.regionId = "central"; return new com.aliyun.dingtalktodo_1_0.Client(config); } /** * è·åééToken * @return */ public String getToken(){ String accessToken = systemDictDataBiz.queryByCode(Constants.DD_TALK,Constants.ACCESS_TOKEN).getCode(); return accessToken; } private String getAccessToken(String corpId) { com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config(); config.protocol = "https"; config.regionId = "central"; try { com.aliyun.dingtalkoauth2_1_0.Client client = new com.aliyun.dingtalkoauth2_1_0.Client(config); com.aliyun.dingtalkoauth2_1_0.models.GetTokenRequest getTokenRequest = new com.aliyun.dingtalkoauth2_1_0.models.GetTokenRequest() .setClientId(clientId) .setClientSecret(clientSecret) .setGrantType("client_credentials"); GetTokenResponse response = client.getToken(corpId, getTokenRequest); return response.getBody().accessToken; } catch (TeaException err) { if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) { // err ä¸å«æ code å message 屿§ï¼å¯å¸®å©å¼åå®ä½é®é¢ log.error("Error getting access token: {}", err.getMessage()); } } catch (Exception _err) { TeaException err = new TeaException(_err.getMessage(), _err); if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) { // err ä¸å«æ code å message 屿§ï¼å¯å¸®å©å¼åå®ä½é®é¢ log.error("Error getting access token: {}", err.getMessage()); } } return null; } public OapiV2UserGetuserinfoResponse.UserGetByCodeResponse getDDUserByCode(DingLoginDTO dto) throws ApiException { DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/getuserinfo"); OapiV2UserGetuserinfoRequest req = new OapiV2UserGetuserinfoRequest(); req.setCode(dto.getCode()); OapiV2UserGetuserinfoResponse rsp = client.execute(req, getAccessToken(dto.getCorpId())); if(rsp.getErrcode().equals(Constants.DD_ERR_CODE)){ return rsp.getResult(); }else{ throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),rsp.getMessage()); } } } server/services/src/main/java/com/doumee/core/dingTalk/DingTalkStream.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,71 @@ package com.doumee.core.dingTalk; import com.dingtalk.open.app.api.GenericEventListener; import com.dingtalk.open.app.api.OpenDingTalkStreamClientBuilder; import com.dingtalk.open.app.api.message.GenericOpenDingTalkEvent; import com.dingtalk.open.app.api.security.AuthClientCredential; import com.dingtalk.open.app.stream.protocol.event.EventAckStatus; import com.doumee.biz.system.SystemDictDataBiz; import com.doumee.core.constants.Constants; import com.doumee.service.business.MemberService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import shade.com.alibaba.fastjson2.JSONObject; /** * éé 订é äºä»¶éç¥ * * @Author : Rk * @create 2025/9/24 17:14 */ @Slf4j @Configuration public class DingTalkStream { @Autowired private SystemDictDataBiz systemDictDataBiz; @Bean public void DingTalkStreamRun() throws Exception { String appKey = systemDictDataBiz.queryByCode(Constants.DD_TALK,Constants.APP_KEY).getCode(); String appSecret = systemDictDataBiz.queryByCode(Constants.DD_TALK,Constants.APP_SECRET).getCode(); OpenDingTalkStreamClientBuilder .custom() .credential(new AuthClientCredential(appKey, appSecret)) //注åäºä»¶çå¬ .registerAllEventListener(new GenericEventListener() { @Override public EventAckStatus onEvent(GenericOpenDingTalkEvent event) { try { //äºä»¶å¯ä¸Id String eventId = event.getEventId(); log.error("é鿍éäºä»¶Id:{}"+eventId); //äºä»¶ç±»å String eventType = event.getEventType(); log.error("é鿍éäºä»¶ç±»å:{}"+eventType); //äºä»¶äº§çæ¶é´ Long bornTime = event.getEventBornTime(); log.error("é鿍éäºä»¶äº§çæ¶é´:{}"+bornTime); //è·åäºä»¶ä½ JSONObject bizData = event.getData(); log.error("é鿍éäºä»¶è¯¦æ :{}"+bizData); //å¤çäºä»¶ // process(bizData); //æ¶è´¹æå return EventAckStatus.SUCCESS; } catch (Exception e) { //æ¶è´¹å¤±è´¥ return EventAckStatus.LATER; } } }) .build().start(); } } server/services/src/main/java/com/doumee/dao/system/dto/DingLoginDTO.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,26 @@ package com.doumee.dao.system.dto; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.NotBlank; import java.io.Serializable; /** * @author dm * @since 2025/03/31 16:44 */ @Data @ApiModel("ç»å½åæ°") public class DingLoginDTO implements Serializable { @NotBlank(message = "codeä¸è½ä¸ºç©º") @ApiModelProperty(value = "code") private String code; @NotBlank(message = "corpIdä¸è½ä¸ºç©º") @ApiModelProperty(value = "corpId") private String corpId; } server/services/src/main/java/com/doumee/dao/vo/WebLoginUserVO.java
@@ -19,10 +19,12 @@ @ApiModelProperty(value = "ç¨æ·ä¸»é®") private String id; @ApiModelProperty(value = "ç¨æ·è§è²ï¼") @ApiModelProperty(value = "ç¨æ·è§è²ï¼ (dUser:æ 记为ééç¨æ·)") private String roleType; @ApiModelProperty(value = "æåºç¼ç ") private String zhanqu; @ApiModelProperty(value = "token") private String token; } server/services/src/main/java/com/doumee/service/business/impl/CategoryServiceImpl.java
@@ -283,8 +283,8 @@ .orderByAsc(Category::getSortnum) ); if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(categoryList)){ String path = systemDictDataBiz.queryByCode(Constants.SYSTEM,Constants.RESOURCE_PATH).getCode() +systemDictDataBiz.queryByCode(Constants.SYSTEM,Constants.CATEGORY_FILES).getCode(); String path = systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE,Constants.RESOURCE_PATH).getCode() +systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE,Constants.CATEGORY_FILES).getCode(); for (Category category:categoryList) { if(StringUtils.isNotBlank(category.getIcon())){ category.setIconFull(path + category.getIcon()); server/services/src/main/java/com/doumee/service/business/impl/MemberServiceImpl.java
@@ -236,11 +236,13 @@ if(Constants.equalsInteger(pageWrap.getModel().getQueryFlag(),Constants.ONE)){ queryWrapper.select("(select count(c.id) from cases c where c.deleted=0 and c.member_id=t.id)",Member::getCaseNum); } if(StringUtils.isNotBlank(model.getFieldIds())){ String [] fieldIds = model.getFieldIds().split(","); for (String s:fieldIds) { queryWrapper.apply("find_in_set( '["+s+"]' , t.FIELD_IDS )"); if(CollectionUtils.isNotEmpty(model.getFieldIdList())){ String sql = ""; for (Integer s:model.getFieldIdList() ) { sql = sql + (StringUtils.isNotBlank(sql)?" or ":"") + " find_in_set( '["+s+"]' , t.FIELD_IDS ) "; } queryWrapper.apply(sql); } if (StringUtils.isNotBlank(model.getQueryZQCode())) { Category zhanqu = categoryMapper.selectOne(new QueryWrapper<Category>().lambda() @@ -262,19 +264,12 @@ ); String path = systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE, Constants.RESOURCE_PATH).getCode() + systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE, Constants.MEMBER_FILES).getCode(); String roleConfig = systemDictDataBiz.queryByCode(Constants.SYSTEM, Constants.ROLE_CONFIG).getCode(); for (Member member:memberIPage.getRecords()) { if(CollectionUtils.isNotEmpty(categoryList)){ dealMemberField(member,categoryList); if(Constants.equalsInteger(pageWrap.getModel().getQueryFlag(),Constants.ONE)) { dealMemberCategoryList(member, categoryList); } dealMemberCategoryList(member, categoryList,pageWrap.getModel().getQueryFlag()); } member.setFullImgurl(StringUtils.isNotBlank(member.getImgurl())?(path + member.getImgurl()):""); if(!Constants.equalsInteger(pageWrap.getModel().getQueryFlag(),Constants.ONE) && (StringUtils.isBlank(roleConfig)||StringUtils.isBlank(model.getQueryUserRole()) || !roleConfig.contains(model.getQueryUserRole()))){ member.setFee(null); } if(member.getJobYear()!=null){ member.setWorkYears(DateUtil.getCurrentYear( ) - member.getJobYear()+1); } @@ -283,36 +278,38 @@ return PageData.from(memberIPage); } private void dealMemberCategoryList(Member member, List<Category> categoryList) { member.setFieldIdList(new ArrayList<>()); member.setBustypeIdList(new ArrayList<>()); member.setZhanquIdList(new ArrayList<>()); private void dealMemberCategoryList(Member member, List<Category> categoryList, Integer queryFlag) { member.setFieldList(new ArrayList<>()); member.setTypeList(new ArrayList<>()); member.setZqList(new ArrayList<>()); member.setBustypeIdList(new ArrayList<>()); member.setZhanquIdList(new ArrayList<>()); for(Category c:categoryList){ // 0=æåº;1=åä¸å;2=æ é¿é¢å; if(Constants.equalsInteger(c.getType(),Constants.ZERO)&& StringUtils.contains(member.getZhanquIds(),"["+c.getId()+"]")){ //æåº member.getZqList().add(c); member.getZhanquIdList().add(c.getId()); } if(Constants.equalsInteger(c.getType(),Constants.ONE)&& StringUtils.contains(member.getBustypeIds(),"["+c.getId()+"]")){ //åä¸å member.getTypeList().add(c); member.getBustypeIdList().add(c.getId()); } if(Constants.equalsInteger(c.getType(),Constants.TWO) && StringUtils.contains(member.getFieldIds(),"["+c.getId()+"]")){ //æ é¿é¢å member.getFieldList().add(c); member.getFieldIdList().add(c.getId()); if(Constants.equalsInteger(queryFlag,Constants.ONE)) { // 0=æåº;1=åä¸å;2=æ é¿é¢å; if(Constants.equalsInteger(c.getType(),Constants.ZERO)&& StringUtils.contains(member.getZhanquIds(),"["+c.getId()+"]")){ //æåº member.getZqList().add(c); member.getZhanquIdList().add(c.getId()); } if(Constants.equalsInteger(c.getType(),Constants.TWO) && StringUtils.contains(member.getFieldIds(),"["+c.getId()+"]")){ //æ é¿é¢å member.getFieldList().add(c); member.getFieldIdList().add(c.getId()); } } } } @Override public Member findDetailById(Integer id,String queryUserRole) { public Member findDetailById(Integer id,String userRole) { Member member = memberMapper.selectJoinOne(Member.class, new MPJLambdaWrapper<Member>() .selectAll(Member.class) .select(" c1.NAME ", Member::getPromotionName) @@ -337,7 +334,7 @@ } String resourcePath = systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE, Constants.RESOURCE_PATH).getCode(); String path = systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE, Constants.CATEGORY_FILES).getCode(); String path = systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE, Constants.MEMBER_FILES).getCode(); String roleConfig = systemDictDataBiz.queryByCode(Constants.SYSTEM, Constants.ROLE_CONFIG).getCode(); member.setFullImgurl(StringUtils.isNotBlank(member.getImgurl())?(resourcePath + path + member.getImgurl()):""); List<Cases> casesList = casesMapper.selectList(new QueryWrapper<Cases>().lambda() @@ -346,7 +343,7 @@ .orderByDesc(Cases::getId) ); if(CollectionUtils.isNotEmpty(casesList)){ String casePath = systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE, Constants.CASES_FILES).getCode(); String casePath = systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE, Constants.CATEGORY_FILES).getCode(); for (Cases cases:casesList) { List<Multifile> multifileList = multifileMapper.selectList(new QueryWrapper<Multifile>().lambda() .eq(Multifile::getObjId,cases.getId()) @@ -357,11 +354,12 @@ multifileList.forEach(multifile -> { multifile.setUrl(StringUtils.isNotBlank(multifile.getFileurl())?(resourcePath + casePath + multifile.getFileurl()):""); }); cases.setFileList(multifileList); } member.setCasesList(casesList); } if(StringUtils.isBlank(roleConfig)||StringUtils.isBlank(queryUserRole) || !roleConfig.contains(queryUserRole)){ if(StringUtils.isBlank(roleConfig)||StringUtils.isBlank(userRole) || !(roleConfig.contains(userRole)||userRole.equals(Constants.DD_USER_TYPE) )){ member.setFee(null); } return member; @@ -391,4 +389,5 @@ } } server/services/src/main/resources/application-dev.yml
@@ -86,4 +86,9 @@ # 模å¼ï¼testingæµè¯æ¨¡å¼ mode: testing dingtalk: clientId: dingulzemj5bynjciapg clientSecret: tLnWtSmmTuqjX9a1MvJzYxI1iXVJxEwtyZZYYFQ5cLg57pzzCZ4J8VsVwvmRNtkK server/web/src/main/java/com/doumee/api/web/LoginController.java
@@ -2,6 +2,7 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.dingtalk.api.response.OapiV2UserGetuserinfoResponse; import com.doumee.api.BaseController; import com.doumee.biz.system.SystemDictDataBiz; import com.doumee.config.annotation.LoginRequired; @@ -10,6 +11,7 @@ import com.doumee.core.annotation.pr.PreventRepeat; import com.doumee.core.annotation.trace.Trace; import com.doumee.core.constants.Constants; import com.doumee.core.dingTalk.DingTalk; import com.doumee.core.model.ApiResponse; import com.doumee.core.model.LoginUserInfo; import com.doumee.core.model.PageData; @@ -18,16 +20,19 @@ import com.doumee.dao.business.dto.LoginRequestNewParam; import com.doumee.dao.business.model.Category; import com.doumee.dao.business.model.Member; import com.doumee.dao.system.dto.DingLoginDTO; import com.doumee.dao.system.model.SystemJob; import com.doumee.dao.vo.WebLoginUserVO; import com.doumee.service.business.CategoryService; import com.doumee.service.business.MemberService; import com.sun.deploy.net.HttpUtils; import com.taobao.api.ApiException; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authz.annotation.RequiresPermissions; @@ -42,6 +47,7 @@ import java.net.URLEncoder; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.UUID; /** @@ -67,14 +73,17 @@ @Autowired private MemberService memberService; @Autowired private DingTalk dingTalk; @ApiOperation("UKåç¹ç»å½") @GetMapping("/ukLogin") public void ukLogin(String tick, Object obj, HttpServletRequest request, HttpServletResponse response) throws Exception { LoginRequestNewParam requestParam = new LoginRequestNewParam(); /*// UK_ERROR_URL = "http://u.zhibang.com/sso/web/token/error"; // UK_ERROR_URL = "http://u.zhibang.com/sso/web/token/error"; String errorUrl =systemDictDataBiz.queryByCode(Constants.ZBOM_PARAM,Constants.ZBOM_UK_ERROR_URL).getCode(); try { /* try { log.error("请æ±åæ°TICKæåå§===========ï¼" + tick); JSONObject urlParams = new JSONObject(); log.info("请æ±åæ°ï¼" + JSON.toJSONString(urlParams)); @@ -106,6 +115,19 @@ response.sendRedirect(requestParam.getRediUrl()+"?token="+token); } @ApiOperation("ééç»å½") @PostMapping("/ddLogin") public ApiResponse<WebLoginUserVO> ddLogin(@Validated @RequestBody DingLoginDTO dingLoginDTO) throws ApiException { WebLoginUserVO loginUserVO = new WebLoginUserVO(); OapiV2UserGetuserinfoResponse.UserGetByCodeResponse response = dingTalk.getDDUserByCode(dingLoginDTO); if(Objects.nonNull(response)){ loginUserVO.setId(response.getUserid()); loginUserVO.setRoleType(Constants.DD_USER_TYPE); } loginUserVO.setToken(jwtTokenUtil.generateToken(loginUserVO)); return ApiResponse.success(loginUserVO); } private String enCode(String string) { // TODO Auto-generated method stub @@ -129,7 +151,17 @@ WebLoginUserVO loginUserVO = this.getMemberResponse(); pageWrap.getModel().setQueryUserRole(loginUserVO.getRoleType()); pageWrap.getModel().setQueryZQCode(loginUserVO.getZhanqu()); return ApiResponse.success(memberService.findPage(pageWrap)); PageData<Member> pageData = memberService.findPage(pageWrap); if(CollectionUtils.isNotEmpty(pageData.getRecords())){ String roleConfig = systemDictDataBiz.queryByCode(Constants.SYSTEM, Constants.ROLE_CONFIG).getCode(); if(StringUtils.isBlank(roleConfig)||StringUtils.isBlank(pageWrap.getModel().getQueryUserRole()) || ! (roleConfig.contains(pageWrap.getModel().getQueryUserRole()) || pageWrap.getModel().getQueryUserRole().equals(Constants.DD_USER_TYPE) )){ pageData.getRecords().forEach(i->{ i.setFee(null); }); } } return ApiResponse.success(pageData); } @@ -158,4 +190,7 @@ }