MrShi
2026-01-13 3a154bdb0a5aaa2c0ac3eac95a6ba747068bd454
server/visits/dmvisit_service/src/main/java/com/doumee/core/dingTalk/DingTalk.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,792 @@
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.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.ResponseStatus;
import com.doumee.core.exception.BusinessException;
import com.doumee.core.utils.Constants;
import com.doumee.core.utils.DateUtil;
import com.doumee.dao.business.dao.CompanyMapper;
import com.doumee.dao.business.model.CarUseBook;
import com.doumee.dao.business.model.Company;
import com.doumee.dao.business.model.HiddenDanger;
import com.doumee.dao.business.model.Visits;
import com.doumee.dao.system.model.SystemDictData;
import com.doumee.service.business.CompanyService;
import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
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.stereotype.Service;
import java.text.DateFormat;
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;
    @Autowired
    private CompanyMapper companyMapper;
    /**
     * ä½¿ç”¨ 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);
    }
    public void updTokenInfo() throws Exception {
        String appKey  =  systemDictDataBiz.queryByCode(Constants.DD_TALK,Constants.APP_KEY).getCode();
        String appSecret  = systemDictDataBiz.queryByCode(Constants.DD_TALK,Constants.APP_SECRET).getCode();
        Client client = DingTalk.createClient();
        GetAccessTokenRequest getAccessTokenRequest = new GetAccessTokenRequest()
                .setAppKey(appKey)
                .setAppSecret(appSecret);
        try {
            GetAccessTokenResponse getAccessTokenResponse = client.getAccessToken(getAccessTokenRequest);
            //返参描述 ä¾‹ï¼š{"body":{"accessToken":"76a248ea72ba3f359b39c9e70073d642","expireIn":7200},"headers":{"access-control-allow-origin":"*","date":"Wed, 24 Sep 2025 08:39:36 GMT","server":"DingTalk/1.0.0","transfer-encoding":"chunked","x-acs-request-id":"9E8AF053-04DD-7031-9766-14DFFB087A79","access-control-allow-headers":"X-Requested-With, X-Sequence, _aop_secret, _aop_signature, x-acs-dingtalk-access-token","connection":"keep-alive","content-type":"application/json;charset=utf-8","access-control-expose-headers":"*","x-acs-trace-id":"96e7cf1f3c0e059779a6d581d4b5fca7"},"statusCode":200}
            if(Constants.equalsInteger(getAccessTokenResponse.statusCode,Constants.DD_STATUS_SUCCESS_CODE)){
                //解析token信息 å­˜å‚¨
                String accessToken = getAccessTokenResponse.getBody().getAccessToken();
                //更新token信息存储
                SystemDictData systemDictData = systemDictDataBiz.queryByCode(Constants.DD_TALK,Constants.ACCESS_TOKEN);
                systemDictData.setCode(accessToken);
                systemDictData.setUpdateTime(new Date());
                systemDictDataBiz.updateByIdNew(systemDictData);
            }
            //更新Token信息
            System.out.println(JSONObject.toJSONString(getAccessTokenResponse));
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err ä¸­å«æœ‰ code å’Œ message å±žæ€§ï¼Œå¯å¸®åŠ©å¼€å‘å®šä½é—®é¢˜
                log.error("更新钉钉Token失败:{}" + err.message);
            }
        } 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("更新钉钉Token失败:{}" + err.message);
            }
        }
    }
    /**
     * èŽ·å–é’‰é’‰Token
     * @return
     */
    public String getToken(){
        String accessToken  =  systemDictDataBiz.queryByCode(Constants.DD_TALK,Constants.ACCESS_TOKEN).getCode();
        return accessToken;
    }
    public OapiV2UserGetuserinfoResponse.UserGetByCodeResponse  getDDUserByCode(String code) throws ApiException {
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/getuserinfo");
        OapiV2UserGetuserinfoRequest req = new OapiV2UserGetuserinfoRequest();
        req.setCode(code);
        OapiV2UserGetuserinfoResponse rsp = client.execute(req, getToken());
        if(rsp.getErrcode().equals(Constants.DD_ERR_CODE)){
           return  rsp.getResult();
        }else{
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),rsp.getMessage());
        }
    }
    /**
     * å…¨é‡åŒæ­¥ éƒ¨é—¨ä¿¡æ¯
     * æŽ¥å£æ–‡æ¡£åœ°å€ https://open.dingtalk.com/document/orgapp/obtain-the-department-list-v2
     * æœ¬æŽ¥å£åªæ”¯æŒèŽ·å–å½“å‰éƒ¨é—¨çš„ä¸‹ä¸€çº§éƒ¨é—¨åŸºç¡€ä¿¡æ¯ï¼Œä¸æ”¯æŒèŽ·å–å½“å‰éƒ¨é—¨ä¸‹æ‰€æœ‰å±‚çº§å­éƒ¨é—¨
     * @throws ApiException
     */
    public List<OapiV2DepartmentGetResponse.DeptGetResponse>  syncAllDDDepartmentList() throws ApiException {
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsub");
        List<Long> headList = new ArrayList<>();
        headList.add(1L);
        List<OapiV2DepartmentListsubResponse.DeptBaseResponse> deptBaseResponseList = new ArrayList<>();
        List<OapiV2DepartmentListsubResponse.DeptBaseResponse> thisLevelList = getDepartmentList(client,headList);
        deptBaseResponseList.addAll(thisLevelList);
        while (CollectionUtils.isNotEmpty(thisLevelList)){
            headList = thisLevelList.stream().map(i->i.getDeptId()).collect(Collectors.toList());
            thisLevelList = getDepartmentList(client,headList);
            if(CollectionUtils.isNotEmpty(thisLevelList)){
                deptBaseResponseList.addAll(thisLevelList);
            }
        }
        List<OapiV2DepartmentGetResponse.DeptGetResponse> getResponseList = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(deptBaseResponseList)){
            for (OapiV2DepartmentListsubResponse.DeptBaseResponse deptBaseResponse:deptBaseResponseList) {
                OapiV2DepartmentGetResponse.DeptGetResponse deptGetResponse = syncDepartmentInfo(deptBaseResponse.getDeptId());
                getResponseList.add(deptGetResponse);
            }
        }
        return getResponseList;
    }
    /**
     * èŽ·å–éƒ¨é—¨ä¸‹çº§æ•°æ®
     * @param client
     * @param deptIdList
     * @return
     * @throws ApiException
     */
    public List<OapiV2DepartmentListsubResponse.DeptBaseResponse> getDepartmentList
            (DingTalkClient client, List<Long> deptIdList) throws ApiException{
        List<OapiV2DepartmentListsubResponse.DeptBaseResponse> thisLevelList = new ArrayList<>();
        for (Long deptId:deptIdList) {
            OapiV2DepartmentListsubRequest req = new OapiV2DepartmentListsubRequest();
            req.setDeptId(deptId);
            req.setLanguage("zh_CN");
            OapiV2DepartmentListsubResponse rsp = client.execute(req, this.getToken());
            if(rsp.getErrcode().equals(Constants.DD_ERR_CODE)){
                if(CollectionUtils.isNotEmpty(rsp.getResult())){
                    thisLevelList.addAll(rsp.getResult());
                }
            }else{
                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),rsp.getMessage());
            }
        }
        return thisLevelList;
    }
    /**
     * åˆ›å»ºç»„织部门 æš‚不使用
     * æŽ¥å£æ–‡æ¡£åœ°å€ï¼šhttps://open.dingtalk.com/document/orgapp/create-a-department-v2
     * @param ddParentId é’‰é’‰ä¸Šçº§éƒ¨é—¨ä¸»é”® å¦‚果没有则入null
     * @param name éƒ¨é—¨åç§°
     * @param sn åºå·
     * @param id ç³»ç»Ÿéƒ¨é—¨ä¸»é”®
     * @throws ApiException
     */
    public void pushCreatDepartment(Integer ddParentId,String name,Long sn,Integer id) throws ApiException {
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/create");
        OapiV2DepartmentCreateRequest req = new OapiV2DepartmentCreateRequest();
        //必入参数
        //如果无父级 åˆ™é»˜è®¤è·Ÿç»„织 1L
        req.setParentId(Objects.isNull(ddParentId)?1L:ddParentId);
        req.setName(name);
        req.setOrder(sn);
        //外部部门字段
        req.setSourceIdentifier(id.toString());
        //默认参数
        req.setHideDept(false);
        req.setOuterDept(false);
        req.setCreateDeptGroup(false);
        OapiV2DepartmentCreateResponse rsp = client.execute(req, getToken());
        if(rsp.getErrcode().equals(Constants.DD_ERR_CODE)){
        }else{
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),rsp.getMessage());
        }
        System.out.println(rsp.getBody());
    }
    /**
     * æ›´æ–°ç»„织部门 æš‚不使用
     * æŽ¥å£æ–‡æ¡£åœ°å€ï¼šhttps://open.dingtalk.com/document/orgapp/update-a-department-v2
     * @param deptId é’‰é’‰éƒ¨é—¨ä¸»é”®
     * @param name éƒ¨é—¨åç§°
     * @param parentId çˆ¶çº§é’‰é’‰éƒ¨é—¨ä¸»é”®
     * @param sn åºå·
     * @throws ApiException
     */
    public void pushUpdDepartment(Integer deptId,String name,Integer parentId,Long sn) throws ApiException {
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/update");
        OapiV2DepartmentUpdateRequest req = new OapiV2DepartmentUpdateRequest();
        req.setDeptId(deptId.longValue());
        //如果无父级 åˆ™é»˜è®¤è·Ÿç»„织 1L
        req.setParentId(Objects.isNull(parentId)?1L:parentId.longValue());
        req.setOrder(sn);
        req.setName(name);
        OapiV2DepartmentUpdateResponse rsp = client.execute(req, getToken());
        if(rsp.getErrcode().equals(Constants.DD_ERR_CODE)){
        }else{
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),rsp.getMessage());
        }
    }
    /**
     * åˆ é™¤ç»„织部门 æš‚不使用
     * æŽ¥å£æ–‡æ¡£åœ°å€ï¼šhttps://open.dingtalk.com/document/orgapp/delete-a-department-v2
     * @param deptId é’‰é’‰éƒ¨é—¨ä¸»é”®
     * @throws ApiException
     */
    public void pushDelDepartment(Integer deptId) throws ApiException {
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/delete");
        OapiV2DepartmentDeleteRequest req = new OapiV2DepartmentDeleteRequest();
        req.setDeptId(deptId.longValue());
        OapiV2DepartmentDeleteResponse rsp = client.execute(req, getToken());
        System.out.println(rsp.getBody());
        if(rsp.getErrcode().equals(Constants.DD_ERR_CODE)){
        }else{
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),rsp.getMessage());
        }
    }
    /**
     * èŽ·å–é’‰é’‰éƒ¨é—¨è¯¦æƒ…
     * @param deptId
     * @return
     * @throws ApiException
     */
    public OapiV2DepartmentGetResponse.DeptGetResponse syncDepartmentInfo(Long deptId) throws ApiException {
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/get");
        OapiV2DepartmentGetRequest req = new OapiV2DepartmentGetRequest();
        req.setDeptId(deptId);
        req.setLanguage("zh_CN");
        OapiV2DepartmentGetResponse rsp = client.execute(req, getToken());
        System.out.println(rsp.getBody());
        if(rsp.getErrcode().equals(Constants.DD_ERR_CODE)){
            return rsp.getResult();
        }else{
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),rsp.getMessage());
        }
    }
    public List<OapiV2UserGetResponse.UserGetResponse>  syncAllUserInfo() throws ApiException {
        List<Company> deptList = companyMapper.selectList(new QueryWrapper<Company>().lambda()
                .eq(Company::getIsdeleted,Constants.ZERO)
                .eq(Company::getType,Constants.ONE)
                .isNotNull(Company::getErpId)
        );
        if(CollectionUtils.isEmpty(deptList)){
            return null;
        }
        List<String> allUserIdList = new ArrayList<>();
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/user/listid");
        OapiUserListidRequest req = new OapiUserListidRequest();
        for (Company company:deptList) {
            req.setDeptId(Long.valueOf(company.getErpId()));
            OapiUserListidResponse rsp = client.execute(req, getToken());
            if(rsp.getErrcode().equals(Constants.DD_ERR_CODE)){
                if(CollectionUtils.isNotEmpty(rsp.getResult().getUseridList())){
                    allUserIdList.addAll(rsp.getResult().getUseridList());
                }
            }else{
                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),rsp.getMessage());
            }
        }
        if(CollectionUtils.isEmpty(allUserIdList)){
            return null;
        }
        Set<String> setUserIdList = new HashSet<>(allUserIdList);
        return syncUserInfoList(setUserIdList);
    }
    public List<OapiV2UserGetResponse.UserGetResponse>  syncUserInfoList(Set<String> setUserIdList) throws ApiException {
        List<OapiV2UserGetResponse.UserGetResponse> userList = new ArrayList<>();
        DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
        OapiV2UserGetRequest req = new OapiV2UserGetRequest();
        for (String userId:setUserIdList) {
            req.setUserid(userId);
            req.setLanguage("zh_CN");
            OapiV2UserGetResponse rsp = client.execute(req, getToken());
            if(rsp.getErrcode().equals(Constants.DD_ERR_CODE)){
                OapiV2UserGetResponse.UserGetResponse userGetResponse = rsp.getResult();
                userList.add(userGetResponse);
            }else{
                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),rsp.getMessage());
            }
        }
        return userList;
    }
    public OapiV2UserGetResponse.UserGetResponse syncUserInfo(String userId)throws ApiException {
        DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
        OapiV2UserGetRequest req = new OapiV2UserGetRequest();
        req.setUserid(userId);
        req.setLanguage("zh_CN");
        OapiV2UserGetResponse rsp = client.execute(req, getToken());
        if(rsp.getErrcode().equals(Constants.DD_ERR_CODE)){
            OapiV2UserGetResponse.UserGetResponse userGetResponse = rsp.getResult();
            return userGetResponse;
        }else{
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),rsp.getMessage());
        }
    }
    /**
     * å‘送 å·¥ä½œé€šçŸ¥
     * @param agentId
     * @param userIds
     * @param msg
     * api åœ°å€ https://open.dingtalk.com/document/orgapp/asynchronous-sending-of-enterprise-session-messages
     * @throws ApiException
     */
    public Boolean workInfoOANotice(Long agentId,String userIds,OapiMessageCorpconversationAsyncsendV2Request.Msg msg){
        try{
            if(CollectionUtils.isEmpty(msg)){
                return null;
            }
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2");
            OapiMessageCorpconversationAsyncsendV2Request request = new OapiMessageCorpconversationAsyncsendV2Request();
            request.setAgentId(agentId);
            request.setUseridList(userIds);
            request.setToAllUser(false);
            request.setMsg(msg);
            OapiMessageCorpconversationAsyncsendV2Response rsp = client.execute(request, getToken());
            if(rsp.getErrcode().equals(Constants.DD_ERR_CODE)){
                return true;
            }else{
                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),rsp.getMessage());
            }
        }catch (ApiException apiException){
        }
        return false;
    }
    /**
     * è®¿å®¢ç”³è¯·/报备 OA å·¥ä½œé€šçŸ¥ å†…容
     * @param visits
     * @param title
     * @return
     */
    public OapiMessageCorpconversationAsyncsendV2Request.Msg getVisitNoticeMsg(Visits visits,String title){
        OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
        msg.setMsgtype("oa");
        OapiMessageCorpconversationAsyncsendV2Request.OA oa = new OapiMessageCorpconversationAsyncsendV2Request.OA();
        oa.setMessageUrl("");
        OapiMessageCorpconversationAsyncsendV2Request.Head head = new OapiMessageCorpconversationAsyncsendV2Request.Head();
        head.setText(title);
        head.setBgcolor("#279BAA");
        oa.setHead(head);
        OapiMessageCorpconversationAsyncsendV2Request.Body body = new OapiMessageCorpconversationAsyncsendV2Request.Body();
        body.setTitle(!Constants.equalsInteger(visits.getType(),Constants.TWO)?visits.getName()+"的访客申请":"的访客报备");
        List<OapiMessageCorpconversationAsyncsendV2Request.Form> formList = new ArrayList<>();
        OapiMessageCorpconversationAsyncsendV2Request.Form visitUser = new OapiMessageCorpconversationAsyncsendV2Request.Form();
        visitUser.setKey("来访人:");
        visitUser.setValue(visits.getName());
        formList.add(visitUser);
        OapiMessageCorpconversationAsyncsendV2Request.Form inDate = new OapiMessageCorpconversationAsyncsendV2Request.Form();
        inDate.setKey("入园时间:");
        inDate.setValue(DateUtil.formatDate(visits.getStarttime(),"MM-dd HH:mm"));
        formList.add(inDate);
        OapiMessageCorpconversationAsyncsendV2Request.Form outDate = new OapiMessageCorpconversationAsyncsendV2Request.Form();
        outDate.setKey("离园时间:");
        outDate.setValue(DateUtil.formatDate(visits.getEndtime(),"MM-dd HH:mm"));
        formList.add(outDate);
        OapiMessageCorpconversationAsyncsendV2Request.Form inReason = new OapiMessageCorpconversationAsyncsendV2Request.Form();
        inReason.setKey("来访事由:");
        inReason.setValue(visits.getReason());
        formList.add(inReason);
        if(StringUtils.isNotBlank(visits.getCarNos())){
            OapiMessageCorpconversationAsyncsendV2Request.Form carNos = new OapiMessageCorpconversationAsyncsendV2Request.Form();
            carNos.setKey("随访车辆:");
            carNos.setValue(visits.getCarNos());
            formList.add(visitUser);
        }
        body.setForm(formList);
        oa.setBody(body);
        msg.setOa(oa);
        return msg;
    }
    /**
     * ç”¨è½¦ä¿¡æ¯ é’‰é’‰é€šçŸ¥æ•°æ®ç»„合
     * @param carUseBook
     * @param title
     * @return
     */
    public OapiMessageCorpconversationAsyncsendV2Request.Msg getCarUseNoticeMsg(CarUseBook carUseBook,String title){
        OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
        msg.setMsgtype("oa");
        OapiMessageCorpconversationAsyncsendV2Request.OA oa = new OapiMessageCorpconversationAsyncsendV2Request.OA();
        oa.setMessageUrl("");
        OapiMessageCorpconversationAsyncsendV2Request.Head head = new OapiMessageCorpconversationAsyncsendV2Request.Head();
        head.setText(title);
        head.setBgcolor("#279BAA");
        oa.setHead(head);
        OapiMessageCorpconversationAsyncsendV2Request.Body body = new OapiMessageCorpconversationAsyncsendV2Request.Body();
        body.setTitle("公务用车");
        List<OapiMessageCorpconversationAsyncsendV2Request.Form> formList = new ArrayList<>();
        OapiMessageCorpconversationAsyncsendV2Request.Form startDate = new OapiMessageCorpconversationAsyncsendV2Request.Form();
        startDate.setKey("开始时间:");
        startDate.setValue(DateUtil.formatDate(carUseBook.getStartTime(),"MM-dd HH:mm"));
        formList.add(startDate);
        OapiMessageCorpconversationAsyncsendV2Request.Form endDate = new OapiMessageCorpconversationAsyncsendV2Request.Form();
        endDate.setKey("结束时间:");
        endDate.setValue(DateUtil.formatDate(carUseBook.getEndTime(),"MM-dd HH:mm"));
        formList.add(endDate);
        OapiMessageCorpconversationAsyncsendV2Request.Form userNum = new OapiMessageCorpconversationAsyncsendV2Request.Form();
        userNum.setKey("乘车人数:");
        userNum.setValue(StringUtils.isBlank(carUseBook.getMemberNames())?"0人": (carUseBook.getMemberNames().split(",").length+"人"));
        formList.add(userNum);
        OapiMessageCorpconversationAsyncsendV2Request.Form inReason = new OapiMessageCorpconversationAsyncsendV2Request.Form();
        inReason.setKey("用车地点:");
        inReason.setValue(Constants.equalsInteger(carUseBook.getType(),Constants.ZERO)?"市内":"市外");
        formList.add(inReason);
        body.setForm(formList);
        oa.setBody(body);
        msg.setOa(oa);
        return msg;
    }
    /**
     * å¤©æ°” markdown
     * @param title
     * @param text
     * @return
     */
    public OapiMessageCorpconversationAsyncsendV2Request.Msg getWeatherNoticeMsg(String title,String text){
        OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
        msg.setMsgtype("markdown");
        OapiMessageCorpconversationAsyncsendV2Request.Markdown markdown = new OapiMessageCorpconversationAsyncsendV2Request.Markdown();
        markdown.setTitle(title);
        markdown.setText(text);
        msg.setMarkdown(markdown);
        return msg;
    }
    /**
     * å®‰é˜²/消防 markdown
     * @return
     */
    public OapiMessageCorpconversationAsyncsendV2Request.Msg getAlarmNoticeMsg(String areaName,String submitTime,String infoType){
        OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
        msg.setMsgtype("markdown");
        OapiMessageCorpconversationAsyncsendV2Request.Markdown markdown = new OapiMessageCorpconversationAsyncsendV2Request.Markdown();
        markdown.setTitle("园区存在安防/消防隐患");
        markdown.setText(areaName+"在"+submitTime+"发生"+infoType+",请及时前往安防中心/消防中心进行处理");
        msg.setMarkdown(markdown);
        return msg;
    }
    /**
     * é’‰é’‰å¾…办事件
     * api地址 https://open.dingtalk.com/document/orgapp/add-dingtalk-to-do-task
     * unionId é€šçŸ¥æ‰€å±žç”¨æˆ·
     * title æ ‡é¢˜
     * unionIdList å¾…办通知人员集合
     * @throws Exception
     */
    public String toDoNotice(String title,List<String> unionIdList,List<CreateTodoTaskRequest.CreateTodoTaskRequestContentFieldList> fieldList,String url) {
        try{
            if(CollectionUtils.isEmpty(fieldList)){
                return null;
            }
            com.aliyun.dingtalktodo_1_0.Client client = DingTalk.createV1Client();
            CreateTodoTaskHeaders createTodoTaskHeaders = new CreateTodoTaskHeaders();
            createTodoTaskHeaders.xAcsDingtalkAccessToken = getToken();
            //待办截止前的提醒
            CreateTodoTaskRequest.CreateTodoTaskRequestRemindNotifyConfigs remindNotifyConfigs = new CreateTodoTaskRequest.CreateTodoTaskRequestRemindNotifyConfigs()
                    .setDingNotify("1")
                    .setSendTodoApn("true");
            //待办通知配置
            CreateTodoTaskRequest.CreateTodoTaskRequestNotifyConfigs notifyConfigs = new CreateTodoTaskRequest.CreateTodoTaskRequestNotifyConfigs()
                    .setDingNotify("1")
                    .setSendTodoApn("true")
                    .setSendAssistantChat("true");
            //按钮事件
            CreateTodoTaskRequest.CreateTodoTaskRequestActionListParam actionList0Param = new CreateTodoTaskRequest.CreateTodoTaskRequestActionListParam()
                    .setBody("");
            CreateTodoTaskRequest.CreateTodoTaskRequestActionList actionList0 = new CreateTodoTaskRequest.CreateTodoTaskRequestActionList()
                    .setTitle("去处理")
                    .setActionType(2)
                    .setParam(actionList0Param)
                    .setUrl(url) //TODO è¯¦æƒ…地址
                    .setActionKey("ak-1-1");
            //详情页url跳转地址
            CreateTodoTaskRequest.CreateTodoTaskRequestDetailUrl detailUrl = new CreateTodoTaskRequest.CreateTodoTaskRequestDetailUrl()
                    .setAppUrl("https://www.baidu.com")
                    .setPcUrl("https://www.baidu.com");
            CreateTodoTaskRequest createTodoTaskRequest = new CreateTodoTaskRequest()
                    .setSubject(title)
                    .setCreatorId(unionIdList.get(Constants.ZERO))
                    .setDescription(title)
                    .setExecutorIds(unionIdList)
                    .setDetailUrl(detailUrl)
                    .setContentFieldList(fieldList)
                    .setIsOnlyShowExecutor(true)
                    .setPriority(20)
                    .setNotifyConfigs(notifyConfigs)
                    .setActionList(java.util.Arrays.asList(actionList0))
                    .setTodoType("TODO")
                    .setRemindNotifyConfigs(remindNotifyConfigs);
            try {
                CreateTodoTaskResponse response = client.createTodoTaskWithOptions(unionIdList.get(Constants.ZERO), createTodoTaskRequest, createTodoTaskHeaders, new com.aliyun.teautil.models.RuntimeOptions());
                log.error("待办通知发送成功,发送内容:{}"+JSONObject.toJSONString(response));
                return response.getBody().getId();
            } catch (TeaException err) {
                if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                    log.error("待办通知发送失败,失败原因:{}"+err.message);
                }
            } 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("待办通知发送失败,失败原因:{}"+err.message);
                }
            }
            return null;
        }catch (Exception e){
            throw  new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"钉钉待办任务通知发送失败");
        }
    }
    /**
     * å¤„理全部人的待办信息 ï¼ˆæµç¨‹å®¡æ‰¹å®Œæˆã€æœ¬çº§å®¡æ‰¹å®Œæˆ ä½¿ç”¨ï¼‰
     * @param unionId
     * @param taskId
     * api地址 https://open.dingtalk.com/document/orgapp/updates-dingtalk-to-do-tasks
     * @throws Exception
     */
    public void updToDoNoticeInfoStatus(String unionId,String taskId){
        try {
            com.aliyun.dingtalktodo_1_0.Client client = DingTalk.createV1Client();
            UpdateTodoTaskHeaders updateTodoTaskHeaders = new UpdateTodoTaskHeaders();
            updateTodoTaskHeaders.xAcsDingtalkAccessToken = getToken();
            UpdateTodoTaskRequest updateTodoTaskRequest = new UpdateTodoTaskRequest()
                    .setOperatorId(unionId)
                    .setDone(true);
            UpdateTodoTaskResponse response = client.updateTodoTaskWithOptions(unionId, taskId, updateTodoTaskRequest, updateTodoTaskHeaders, new RuntimeOptions());
            log.error("待办通知发送成功,发送内容:{}"+JSONObject.toJSONString(response));
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err ä¸­å«æœ‰ code å’Œ message å±žæ€§ï¼Œå¯å¸®åŠ©å¼€å‘å®šä½é—®é¢˜
                log.error("待办通知发送失败,失败原因:{}"+err.message);
            }
        } 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("待办通知发送失败,失败原因:{}"+err.message);
            }
        }
    }
    /**
     * å¤„理对应人员的待办信息
     * @param unionId åˆ›å»ºäººunionId
     * @param taskId  é’‰é’‰ä»»åС䏻键
     * @param dealUnionId
     * api åœ°å€ https://open.dingtalk.com/document/orgapp/update-dingtalk-to-do-status
     * @throws Exception
     */
    public void updUserToDoNoticeInfoStatus(String unionId,String taskId,String dealUnionId){
        try {
            com.aliyun.dingtalktodo_1_0.Client client = DingTalk.createV1Client();
            UpdateTodoTaskExecutorStatusHeaders updateTodoTaskExecutorStatusHeaders = new UpdateTodoTaskExecutorStatusHeaders();
            updateTodoTaskExecutorStatusHeaders.xAcsDingtalkAccessToken = getToken();
            UpdateTodoTaskExecutorStatusRequest.UpdateTodoTaskExecutorStatusRequestExecutorStatusList executorStatusList0 = new UpdateTodoTaskExecutorStatusRequest.UpdateTodoTaskExecutorStatusRequestExecutorStatusList()
                    .setId(dealUnionId)
                    .setIsDone(true);
            UpdateTodoTaskExecutorStatusRequest updateTodoTaskExecutorStatusRequest = new UpdateTodoTaskExecutorStatusRequest()
                    .setExecutorStatusList(java.util.Arrays.asList(
                            executorStatusList0
                    ));
            UpdateTodoTaskExecutorStatusResponse response = client.updateTodoTaskExecutorStatusWithOptions(unionId, taskId, updateTodoTaskExecutorStatusRequest, updateTodoTaskExecutorStatusHeaders, new RuntimeOptions());
            log.error("待办通知发送成功,发送内容:{}"+JSONObject.toJSONString(response));
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err ä¸­å«æœ‰ code å’Œ message å±žæ€§ï¼Œå¯å¸®åŠ©å¼€å‘å®šä½é—®é¢˜
                log.error("待办通知发送失败,失败原因:{}"+err.message);
            }
        } 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("待办通知发送失败,失败原因:{}"+err.message);
            }
        }
    }
    /**
     * è®¿å®¢æŠ¥å¤‡ä¸Žè®¿å®¢ç”³è¯· é’‰é’‰å¾…办
     * @param visits
     * @return
     */
    public List<CreateTodoTaskRequest.CreateTodoTaskRequestContentFieldList> getToDoVisitFiledInfo(Visits visits){
        List<CreateTodoTaskRequest.CreateTodoTaskRequestContentFieldList> list = new ArrayList<>();
        CreateTodoTaskRequest.CreateTodoTaskRequestContentFieldList contentFieldList0 = new CreateTodoTaskRequest.CreateTodoTaskRequestContentFieldList()
                .setFieldKey("来访人")
                .setFieldValue(visits.getName());
        list.add(contentFieldList0);
        CreateTodoTaskRequest.CreateTodoTaskRequestContentFieldList contentFieldList1 = new CreateTodoTaskRequest.CreateTodoTaskRequestContentFieldList()
                .setFieldKey("入园时间")
                .setFieldValue(DateUtil.getFomartDate(visits.getStarttime(),"MM-dd HH:mm"));
        list.add(contentFieldList1);
        CreateTodoTaskRequest.CreateTodoTaskRequestContentFieldList contentFieldList2 = new CreateTodoTaskRequest.CreateTodoTaskRequestContentFieldList()
                .setFieldKey("离园时间")
                .setFieldValue(DateUtil.getFomartDate(visits.getEndtime(),"MM-dd HH:mm"));
        list.add(contentFieldList2);
        CreateTodoTaskRequest.CreateTodoTaskRequestContentFieldList contentFieldList3 = new CreateTodoTaskRequest.CreateTodoTaskRequestContentFieldList()
                .setFieldKey("来访事由")
                .setFieldValue(visits.getReason());
        list.add(contentFieldList3);
        if(StringUtils.isNotBlank(visits.getCarNos())){
            CreateTodoTaskRequest.CreateTodoTaskRequestContentFieldList contentFieldList4 = new CreateTodoTaskRequest.CreateTodoTaskRequestContentFieldList()
                    .setFieldKey("随访车辆")
                    .setFieldValue(visits.getCarNos());
            list.add(contentFieldList4);
        }
        return list;
    }
    /**
     * ç”¨è½¦ç”³è¯·çš„ é’‰é’‰å¾…办
     * @param carUseBook
     * @return
     */
    public List<CreateTodoTaskRequest.CreateTodoTaskRequestContentFieldList> getToDoCarUseBookFiledInfo(CarUseBook carUseBook){
        List<CreateTodoTaskRequest.CreateTodoTaskRequestContentFieldList> list = new ArrayList<>();
        CreateTodoTaskRequest.CreateTodoTaskRequestContentFieldList contentFieldList1 = new CreateTodoTaskRequest.CreateTodoTaskRequestContentFieldList()
                .setFieldKey("开始时间")
                .setFieldValue(DateUtil.getFomartDate(carUseBook.getStartTime(),"MM-dd HH:mm"));
        list.add(contentFieldList1);
        CreateTodoTaskRequest.CreateTodoTaskRequestContentFieldList contentFieldList2 = new CreateTodoTaskRequest.CreateTodoTaskRequestContentFieldList()
                .setFieldKey("结束时间")
                .setFieldValue(DateUtil.getFomartDate(carUseBook.getEndTime(),"MM-dd HH:mm"));
        list.add(contentFieldList2);
        CreateTodoTaskRequest.CreateTodoTaskRequestContentFieldList contentFieldList3 = new CreateTodoTaskRequest.CreateTodoTaskRequestContentFieldList()
                .setFieldKey("乘车人数")
                .setFieldValue(StringUtils.isBlank(carUseBook.getMemberNames())?"0人": (carUseBook.getMemberNames().split(",").length+"人"));
        list.add(contentFieldList3);
        CreateTodoTaskRequest.CreateTodoTaskRequestContentFieldList contentFieldList4 = new CreateTodoTaskRequest.CreateTodoTaskRequestContentFieldList()
                .setFieldKey("用车地点")
                .setFieldValue(Constants.equalsInteger(carUseBook.getType(),Constants.ZERO)?"市内":"市外");
        list.add(contentFieldList4);
        return list;
    }
    public static void main(String[] args) throws Exception {
        DingTalk dingTalk = new DingTalk();
//        Visits visits = new Visits();
//        visits.setName("小豆丁");
//        visits.setStarttime(new Date());
//        visits.setEndtime(new Date());
//        visits.setReason("参观");
//        visits.setCarNos("皖A00001");
//        dingTalk.toDoNotice("visit_01","小豆丁的访客申请",java.util.Arrays.asList("iPsP86axviPHiSP4nm5YgQNCQiEiE") ,dingTalk.getToDoVisitFiledInfo(visits));
        CarUseBook carUseBook = new CarUseBook();
        carUseBook.setStartTime(new Date());
        carUseBook.setEndTime(new Date());
        carUseBook.setMemberNames("张三,李四,王五");
        carUseBook.setType(Constants.ZERO);
//        dingTalk.workInfoOANotice(4015267031L,"1568490244651036",dingTalk.getCarUseNoticeMsg(carUseBook,"用车申请"));
        dingTalk.toDoNotice("小豆丁提交的公务车用车",java.util.Arrays.asList("iPsP86axviPHiSP4nm5YgQNCQiEiE","XiPYJKRAv9eCoO4UPM20HQQiEiE","eWbHiSp3uRtrMtiiOX5LXamgiEiE") ,dingTalk.getToDoCarUseBookFiledInfo(carUseBook),"");
//
//        dingTalk.updUserToDoNoticeInfoStatus("iPsP86axviPHiSP4nm5YgQNCQiEiE",
//                "taska2d004da1f8e84847c895d14e8695102",
//                "XiPYJKRAv9eCoO4UPM20HQQiEiE");
        ;
//        String appKey  = "dingkfglaktqmfd2dmo2";//systemDictDataBiz.queryByCode("","").getCode();
//        String appSecret  = "0e22TT2s794Yj49Exgvq8nU2ulpXmxlw9ThBh5s-vDv5Cfspv-f8HPmta4cg2evk";//systemDictDataBiz.queryByCode("","").getCode();
//        Client client = DingTalk.createClient();
//        GetAccessTokenRequest getAccessTokenRequest = new GetAccessTokenRequest()
//                .setAppKey(appKey)
//                .setAppSecret(appSecret);
//        try {
//            GetAccessTokenResponse getAccessTokenResponse = client.getAccessToken(getAccessTokenRequest);
//
//            //更新Token信息
//            System.out.println(JSONObject.toJSONString(getAccessTokenResponse));
//
//        } catch (TeaException err) {
//            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
//                // err ä¸­å«æœ‰ code å’Œ message å±žæ€§ï¼Œå¯å¸®åŠ©å¼€å‘å®šä½é—®é¢˜
//                log.error("更新钉钉Token失败:{}" + err.message);
//            }
//
//        } 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("更新钉钉Token失败:{}" + err.message);
//            }
//        }
    }
}