企业微信推送 文字/图文/卡片 消息 实操案例

企业微信推送应用应用消息的记录

企业微信官方文档 :https://developer.work.weixin.qq.com/document/path/90664

本文写于2022/11/10号,官网文档中有些字段可能会进行更新,实体类的创建根据官方文档为准,本文仅提供参考

如果想要使用企业微信相关的api功能,我们需要先获取企业微信相关应用的token

请求方式: GET(HTTPS
请求地址: https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ID&corpsecret=SECRET

参数说明:

参数必须说明
corpid企业ID
corpsecret应用的凭证密钥,注意应用需要是启用状态

注意:获取的token有应用和应用区分,A应用的token只能用于A应用,B应用的token只能用于B应用,corpsecret是区分应用的一种途径,每个应用的corpsecret是不同的,且同一个应用的token在两个小时内重复获取,获取的token不会改变,并且token的访问次数是有限制的

在这里插入图片描述

1、案例准备

1>定义一个异常类

public class EnterpriseWeChatException extends RuntimeException {

	public EnterpriseWeChatException(String msg) {
		super(msg);

	}

	public EnterpriseWeChatException() {
		super();
	}
}

2>定义一个guavaCache的缓存类

            <dependency>
                <groupId>com.google.guava</groupId>
                <artifactId>guava</artifactId>
                <version>22.0</version>
            </dependency>
/**
 * 企业微信应用token缓存
 *
 * @Author liuxk
 * @date: 2022/10/31
 */
public class EnterpriseWeChatAgentTokenGuavaCache {
    /**
     * 缓存过期时间为 2 小时
     */
    public static Cache<Integer, String> cache = CacheBuilder.newBuilder().expireAfterAccess(2, TimeUnit.HOURS).build();

    /**
     * 添加缓存数据
     *
     * @param key
     * @param value
     */
    public static void put(Integer key, String value) {
        cache.put(key, value);
    }

    /**
     * 获取缓存数据
     *
     * @param key
     * @return
     */
    public static String get(Integer key) {
        return cache.getIfPresent(key);
    }
}

3>定义一个常量类

/**
 * 微信公众平台常量类
 * <p>
 * User:  liuxk
 * Date:  2022/10/27
 */
public class EnterpriseWeChatConstant {

    /**
     * 企业id
     */
    public static final String CORPID = "填写自己的企业id";

    /**
     * 应用的凭证密钥
     * 注意:应用需要是启用状态
     */
    // 一开始进行设计开发时,使用的想法时直接在常量类中将每个应用的密钥设置到常量中,后来感觉不可取,就把密钥设置到数据库中,使用的时候从数据库中进行获取
    public static final String CORPSECRET = "填写自己的企业应用密钥";

    /**
     * 获取访问权限码(access_token)URL  GET请求
     */
    public static final String ACCESS_TOKEN_URL = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=%s&corpsecret=%s";

    /**
     * 发送消息URL POST请求
     */
    public static final String CREATE_SESSION_URL = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=";

    /**
     * 获取企业微信用户userid POST请求
     */
    public static final String GET_USER_ID = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserid?access_token=";
}

4> 数据库准备

(也可以不使用数据库,用什么方法见仁见智)
在这里插入图片描述

--更改相关字段为你所需要的
CREATE TABLE `table_name` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '企业微信应用表id',
  `appName` varchar(20) NOT NULL COMMENT '企业微信下应用名称',
  `agentId` int NOT NULL COMMENT '企业微信下应用id',
  `appSecret` varchar(255) NOT NULL COMMENT '企业微信下应用的私钥',
  `createTime` datetime NOT NULL COMMENT '创建时间',
  `updateTime` datetime DEFAULT NULL COMMENT '修改时间',
  `deleted` int unsigned NOT NULL DEFAULT '0' COMMENT '逻辑删除',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='企业微信下应用的相关信息';

5>定义mapper

public interface EnterpriseWeChatAppMapper {

    EnterpriseWeChatAppDto queryByAgentId(Integer agentId);

    List<EnterpriseWeChatAppDto> list();
}

相关的mapper.xml自行书写

6>发送网络请求使用restTemplate

定义一个restTemplate配置类

@Configuration
public class RestTemplateConfig {

    @Bean
    RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

7>定义获取token的返回值的对象

@Getter
@Setter
public class EnterpriseAccessTokenDto {
    /**
     * 出错返回码,为0表示成功,非0表示调用失败
     */
    private Integer errcode;
    /**
     * 返回码提示语
     */
    private String errmsg;
    /**
     * 获取到的凭证,最长为512字节
     */
    private String access_token;
    /**
     * 凭证的有效时间(秒)
     */
    private String expires_in;
}

8>定义一个字典

(本案例中不定义也可以)

public enum EnterpriseWeixinErrorCodeDict {
    // 存放的为微信的一些常用的错误码
    Not_OK(-1,"系统繁忙"),
    Ok(0, "请求成功");

    public final int code;
    public final String name;

    EnterpriseWeixinErrorCodeDict(int code, String name) {
        this.code = code;
        this.name = name;
    }
}

9>定义一个类用于接受推送消息返回结果

@Getter
@Setter
public class EnterpriseAppMessageDto {

    /**
     * 返回码
     */
    private Integer errcode;
    /**
     * 对返回码的文本描述内容
     */
    private String errmsg;
    /**
     * 不合法的userid,不区分大小写,统一转为小写
     */
    private String invaliduser;
    /**
     * 不合法的partyid
     */
    private String invalidparty;
    /**
     * 不合法的标签id
     */
    private String invalidtag;
    /**
     * 没有基础接口许可(包含已过期)的userid
     */
    private String unlicenseduser;
    /**
     * 消息id,用于撤回应用消息
     */
    private String msgid;
    /**
     * 仅消息类型为“按钮交互型”,“投票选择型”和“多项选择型”的模板卡片消息返回,应用可使用response_code调用更新模版卡片消息接口,72小时内有效,且只能使用一次
     */
    private String response_code;
}

2、获取token

因为知道

1、每个应用的token都不同且不通用

2、token在两个小时内获取到的是一样的

3、固定时间内获取token的次数是固定的

为了解决这些问题,要考虑把token放在缓存中(redis缓存,guavaCache等多种缓存,本案例使用guavaCache进行缓存)

先按照步骤3 定义一个接口及其实现类,将获取token的方法写在其实现类中

public String getAccessToken(Integer agentId) {
    // 获取缓存中的token,有则返回token,没有则获取token
        String token = EnterpriseWeChatAgentTokenGuavaCache.get(agentId);
        if (StringUtils.isNotEmpty(token)) {
            return token;
        }
    // 从数据库中获取到的相关信息
        EnterpriseWeChatAppDto enterpriseWeChatAppDto = enterpriseWeChatAppMapper.queryByAgentId(agentId);
        if (enterpriseWeChatAppDto == null) {
            throw new EnterpriseWeChatException("获取应用密钥失败,请检查应用id是否正确");
        }

        String appSecret = enterpriseWeChatAppDto.getAppSecret();

        // 拼接获取token 的url
    	// 常量类中的属性
        String getTokenUrl = String.format(EnterpriseWeChatConstant.ACCESS_TOKEN_URL,
                EnterpriseWeChatConstant.CORPID,
                appSecret);
    	// 通过url发送请求,获取返回的对象
        ResponseEntity<EnterpriseAccessTokenDto> entity =
                restTemplate.getForEntity(getTokenUrl, EnterpriseAccessTokenDto.class);
        if (entity.getStatusCode() != HttpStatus.OK) {
            throw new EnterpriseWeChatException("获取token请求发送失败,错误信息:" + entity);
        }
        EnterpriseAccessTokenDto body = entity.getBody();
    	// 如果没有定义字典,也可以直接使用 0 代替 EnterpriseWeixinErrorCodeDict.Ok.code
        if (body.getErrcode() != EnterpriseWeixinErrorCodeDict.Ok.code) {
            throw new EnterpriseWeChatException("获取token失败,错误码:" + body.getErrcode() + "错误信息:" + body.getErrmsg());
        }
    	// 获取到了token之后存档在guavaCache缓存中
        EnterpriseWeChatAgentTokenGuavaCache.put(agentId, body.getAccess_token());
        return body.getAccess_token();
    }

3、发送文字消息

定义一个参数实体类

实体类内容要和企业微信官网文档中的对应

@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class EnterpriseWeChatTextMessageParam {

    // touser、toparty、totag不能同时为空

    /**
     * 指定接收消息的成员,成员ID列表(多个接收者用‘|’分隔,最多支持1000个)。特殊情况:指定为"@all",则向该企业应用的全部成员发送
     */
    private String touser;

    /**
     * 指定接收消息的部门,部门ID列表,多个接收者用‘|’分隔,最多支持100个。当touser为"@all"时忽略本参数
     */
    private String toparty;
    /**
     * 指定接收消息的标签,标签ID列表,多个接收者用‘|’分隔,最多支持100个。 当touser为"@all"时忽略本参数
     */
    private String totag;
    /**
     * 消息类型
     */
    private String msgtype;
    /**
     * 企业应用的id
     */
    private Integer agentid;
    /**
     * 消息内容
     */
    private EnterpriseWeChatTextMessage text;

    /**
     * 表示是否是保密消息,0表示可对外分享,1表示不能分享且内容显示水印,默认为0
     */
    private Integer safe = 0;
    /**
     * 表示是否开启id转译,0表示否,1表示是,默认0。仅第三方应用需要用到,企业自建应用可以忽略。
     */
    private Integer enable_id_trans = 0 ;
    /**
     * 表示是否开启重复消息检查,0表示否,1表示是,默认0
     */
    private Integer enable_duplicate_check = 0 ;
    /**
     * 表示是否重复消息检查的时间间隔,默认1800s,最大不超过4小时
     */
    private Integer duplicate_check_interval = 1800;
}

定义一个接口

@Service
public interface EnterpriseWeChatService {

    /**
     * 应用消息-文字消息
     *
     * @param appTextMessage
     * @return
     */
    Result sendTextMessage(EnterpriseWeChatTextMessageParam appTextMessage);
}

接口实现类

(获取token的方法写在此处)

@Slf4j
@Service
public class EnterpriseWeChatServiceImpl implements EnterpriseWeChatService {
     @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private EnterpriseWeChatAppMapper enterpriseWeChatAppMapper;
    
        @Override
    public Result sendTextMessage(EnterpriseWeChatTextMessageParam appTextMessage) {
        log.info("应用文本消息参数: {} ", appTextMessage.toString());
        EnterpriseAppMessageDto enterpriseAppMessageDto =
                sendMessage(appTextMessage.getAgentid(), appTextMessage);
        log.info("应用文本消息响应:{}", enterpriseAppMessageDto.toString());

        return Result.success();
    }
    
     /**
     * 发送微信消息
     *
     * @param agentId 企业应用id
     * @param request 请求体参数对象
     * @return 推送应用消息返回值
     */
    public EnterpriseAppMessageDto sendMessage(Integer agentId, Object request) {
        String token = getAccessToken(agentId);
        //请求链接
        String action = EnterpriseWeChatConstant.CREATE_SESSION_URL + token;
        ResponseEntity<EnterpriseAppMessageDto> responseEntity =
                restTemplate.postForEntity(action, request, EnterpriseAppMessageDto.class);
        if (responseEntity.getStatusCode() != HttpStatus.OK) {
            throw new EnterpriseWeChatException("应用消息请求发送失败{}" + request);
        }

        EnterpriseAppMessageDto body = responseEntity.getBody();
        if (body.getErrcode() != EnterpriseWeixinErrorCodeDict.Ok.code) {
            throw new EnterpriseWeChatException("发送应用消息失败,错误码:" + body.getErrcode() + "错误信息:" + body.getErrmsg());
        }

        return body;
    }
}

4、发送文字消息

定义参数实体类

/**
 * 企业微信应用消息推送图文消息
 * (两种图文消息,此实体类对应msgtype = ”mpnews“)
 */

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class EnterpriseWeChatPictureNewsPushParam {

    /**
     * 否
     * 成员ID列表(消息接收者,多个接收者用‘|’分隔,最多支持1000个)。特殊情况:指定为@all,则向关注该企业应用的全部成员发送
     */
    private String touser;
    /**
     * 否
     * 部门ID列表,多个接收者用‘|’分隔,最多支持100个。当touser为@all时忽略本参数
     */
    private String toparty;
    /**
     * 否
     * 标签ID列表,多个接收者用‘|’分隔,最多支持100个。当touser为@all时忽略本参数
     */
    private String totag;
    /**
     * 是
     * 消息类型,此时固定为:mpnews
     */
    private String msgtype;
    /**
     * 是
     * 企业应用的id,整型。企业内部开发,可在应用的设置页面查看;第三方服务商,可通过接口 获取企业授权信息 获取该参数值
     */
    private Integer agentid;

    /**
     * 消息主体
     */
    private EnterpriseWeChatPictureNewsParam mpnews;

    /**
     * 否
     * 表示是否是保密消息,0表示可对外分享,1表示不能分享且内容显示水印,2表示仅限在企业内分享,默认为0;注意仅mpnews类型的消息支持safe值为2,其他消息类型不支持
     */
    private Integer safe;
    /**
     * 否
     * 表示是否开启id转译,0表示否,1表示是,默认0
     */
    private Integer enable_id_trans;
    /**
     * 否
     * 表示是否开启重复消息检查,0表示否,1表示是,默认0
     */
    private Integer enable_duplicate_check;
    /**
     * 否
     * 表示是否重复消息检查的时间间隔,默认1800s,最大不超过4小时
     */
    private Integer duplicate_check_interval;


}
@Getter
@Setter
public class EnterpriseWeChatPictureNewsParam {
    /**
     * 图文消息-消息主体内容
     */
    private List<EnterPriseWeChatPictureWordContentParam> articles;
}

@Getter
@Setter
public class EnterPriseWeChatPictureWordContentParam {
    /**
     * 是否必填 :是
     * 标题
     */
    private String title;
    /**
     * 是
     * 图文消息缩略图的media_id, 可以通过素材管理接口获得。此处thumb_media_id即上传接口返回的media_id
     */
    private String thumb_media_id;
    /**
     * 否
     * 图文消息的作者,不超过64个字节
     */
    private String author;
    /**
     * 否
     * 图文消息点击“阅读原文”之后的页面链接
     */
    private String content_source_url;
    /**
     * 是
     * 图文消息的内容,支持html标签,不超过666 K个字节(支持id转译)
     */
    private String content;
    /**
     * 否
     * 图文消息的描述,不超过512个字节,超过会自动截断(支持id转译)
     */
    private String digest;
}

定义三个实体类而不是定义一个,原因是为了符合微信官方文档的消息体格式

{
   "touser" : "UserID1|UserID2|UserID3",
   "toparty" : "PartyID1 | PartyID2",
   "totag": "TagID1 | TagID2",
   "msgtype" : "mpnews",
   "agentid" : 1,
   "mpnews" : {
       "articles":[
           {
               "title": "Title", 
               "thumb_media_id": "MEDIA_ID",
               "author": "Author",
               "content_source_url": "URL",
               "content": "Content",
               "digest": "Digest description"
            }
       ]
   },
   "safe":0,
   "enable_id_trans": 0,
   "enable_duplicate_check": 0,
   "duplicate_check_interval": 1800
}


在接口中添加方法

    /**
     * 应用消息-图文消息
     *
     * @param picture
     * @return
     */
    Result sendImageTextMessage(EnterpriseWeChatPictureNewsPushParam picture);

接口实现类中也增加相应的方法

    @Override
    public Result sendImageTextMessage(EnterpriseWeChatPictureNewsPushParam picture) {
        log.info("图文消息参数: {} ", picture.toString());
        EnterpriseAppMessageDto enterpriseAppMessageDto = sendMessage(picture.getAgentid(), picture);
        log.info("图文消息响应: {}", enterpriseAppMessageDto.toString());
        return Result.success();
    }


5、发送卡片信息

定义参数实体类

@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class EnterpriseWeChatCardMessageParam {
    /**
     * 是否必填:否
     * 成员ID列表(消息接收者,多个接收者用‘|’分隔,最多支持1000个)。特殊情况:指定为@all,则向关注该企业应用的全部成员发送
     */
    private String touser;
    /**
     * 是否必填:否
     * 部门ID列表,多个接收者用‘|’分隔,最多支持100个。当touser为@all时忽略本参数
     */
    private String toparty;
    /**
     * 是否必填:否
     * 标签ID列表,多个接收者用‘|’分隔,最多支持100个。当touser为@all时忽略本参数
     */
    private String totag;
    /**
     * 是否必填:是
     * 消息类型,此时固定为:template_card
     */
    private String msgtype = "template_card";
    /**
     * 是否必填:是
     * 企业应用的id,整型。企业内部开发,可在应用的设置页面查看;第三方服务商,可通过接口 获取企业授权信息 获取该参数值
     */
    private Integer agentid;
    /**
     * 是否必填:是
     * 模板卡片类型,文本通知型卡片填写 "text_notice"
     */
    private String card_type;
    /**
     * 是否必填:否
     * 卡片来源样式信息,不需要来源样式可不填写
     */
    private EnterpriseWeChatCardSourceparam source;

    /**
     * 是否必填:否
     * 卡片右上角更多操作按钮
     */
    private EnterpriseWeChatCardActionMenuParam action_menu;

    /**
     * 是否必填:
     * 一级标题,建议不超过36个字,文本通知型卡片本字段非必填
     * 但不可以本字段和sub_title_text都不填
     */
    private EnterpriseWeChatCardMainTitleParam main_title;

    /**
     * 是否必填:否
     * 引用文献样式
     */
    private EnterpriseWeChatCardQuoteAreaParam quote_area;

    /**
     * 是否必填:否
     * 关键数据样式
     */
    private EnterpriseWeChatCardEmphasisContentParam emphasis_content;

    /**
     * 是否必填:否
     * 二级普通文本,建议不超过160个字,(支持id转译)
     */
    private String sub_title_text;
    /**
     * 是否必填:否
     * 二级标题+文本列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过6
     */
    private List<EnterpriseWeChatCardHorizontalContentListParam> horizontal_content_list;

    /**
     * 是否必填:否
     * 跳转指引样式的列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过3
     */
    private List<EnterpriseWeChatCardJumpListParam> jump_list;

    /**
     * 是否必填:是
     * 整体卡片的点击跳转事件,text_notice必填本字段
     */
    private EnterpriseWeChatCardCardActionParam card_action;

    /**
     * 是否必填:否
     * 任务id,同一个应用任务id不能重复,只能由数字、字母和“_-@”组成,最长128字节,填了action_menu字段的话本字段必填
     */
    private String task_id;
    /**
     * 是否必填:否
     * 表示是否开启id转译,0表示否,1表示是,默认0
     */
    private Integer enable_id_trans = 0;
    /**
     * 是否必填:否
     * 表示是否开启重复消息检查,0表示否,1表示是,默认0
     */
    private Integer enable_duplicate_check = 0;
    /**
     * 是否必填:否
     * 表示是否重复消息检查的时间间隔,默认1800s,最大不超过4小时
     */
    private Integer duplicate_check_interval = 1800;
}

@Getter
@Setter
public class EnterpriseWeChatCardSourceparam {

    /**
     * 是否必填:否
     * 来源图片的url,来源图片的尺寸建议为72*72
     */
    private String icon_url;
    /**
     * 是否必填:否
     * 来源图片的描述,建议不超过20个字,(支持id转译)
     */
    private String desc	;
    /**
     * 是否必填:否
     * 来源文字的颜色,目前支持:0(默认) 灰色,1 黑色,2 红色,3 绿色
     */
    private Integer desc_color;
}

@Getter
@Setter
public class EnterpriseWeChatCardActionMenuParam {

    /**
     * 是否必填: 否
     * 更多操作界面的描述
     */
    private String  desc;
    /**
     * 是否必填:是
     * 操作列表,列表长度取值范围为 [1, 3]
     */        
    private EnterpriseWeChatCardActionListParam  action_list;


}

@Getter
@Setter
public class EnterpriseWeChatCardMainTitleParam {
    /**
     * 是否必填:否
     * 一级标题,建议不超过36个字,文本通知型卡片本字段非必填,但不可本字段和sub_title_text都不填,(支持id转译)
     */
    private String title;
    /**
     * 是否必填:否
     * 标题辅助信息,建议不超过44个字,(支持id转译)
     */
    private String desc;
}


@Getter
@Setter
public class EnterpriseWeChatCardQuoteAreaParam {

    /**
     * 是否必填:否
     * 引用文献样式区域点击事件,0或不填代表没有点击事件,1 代表跳转url,2 代表跳转小程序
     */
    private Integer type;
    /**
     * 是否必填:否
     * 点击跳转的url,  type是1时必填
     */
    private String url;
    /**
     * 是否必填:否
     * 点击跳转的小程序的appid,必须是与当前应用关联的小程序,  type是2时必填
     */
    private String appid;
    /**
     * 是否必填:否
     * 点击跳转的小程序的pagepath,  type是2时选填
     */
    private String pagepath;
    /**
     * 是否必填:否
     * 引用文献样式的标题
     */
    private String title;
    /**
     * 是否必填:否
     * 引用文献样式的引用文案
     */
    private String quote_text;
}

@Getter
@Setter
public class EnterpriseWeChatCardEmphasisContentParam {
    /**
     * 是否必填:否
     * 关键数据样式的数据内容,建议不超过14个字
     */
    private String title;
    /**
     * 是否必填:否
     * 关键数据样式的数据描述内容,建议不超过22个字
     */
    private String desc;
}


@Getter
@Setter
public class EnterpriseWeChatCardHorizontalContentListParam {
    /**
     * 是否必填:否
     * 链接类型,0或不填代表不是链接,1 代表跳转url,2 代表下载附件,3 代表点击跳转成员详情
     */
    private Integer type;
    /**
     * 是否必填:是
     * 二级标题,建议不超过5个字
     */
    private String keyname;
    /**
     * 根据type的值判断是否必填
     * 二级文本,如果  type是2,该字段代表文件名称(要包含文件类型),建议不超过30个字,(支持id转译)
     */
    private String value;
    /**
     * 根据type的值判断是否必填
     * 链接跳转的url,  type是1时必填
     */
    private String url;
    /**
     * 根据type的值判断是否必填
     * 附件的media_id,  type是2时必填
     */
    private String media_id;
    /**
     * 根据type的值判断是否必填
     * 成员详情的userid,  type是3时必填
     */
    private String userid;
}

@Getter
@Setter
public class EnterpriseWeChatCardJumpListParam {

    /**
     * 是否必填:否
     * 跳转链接类型,0或不填代表不是链接,1代表跳转url,2代表跳转小程序
     */
    private Integer type;

    /**
     * 根据type的值判断是否必填
     * 跳转链接样式的文案内容,建议不超过18个字
     */
    private String title;

    /**
     * 根据type的值判断是否必填
     * 跳转链接的url, type是1时必填
     */
    private String url;

    /**
     * 根据type的值判断是否必填
     * 跳转链接的小程序的appid,必须是与当前应用关联的小程序,  type是2时必填
     */
    private String appid;

    /**
     * 是根据type的值判断是否必填
     * 跳转链接的小程序的pagepath,  type是2时选填
     */
    private String pagepath;
}

@Getter
@Setter
public class EnterpriseWeChatCardCardActionParam {
    /**
     * 是否必填:是
     * 跳转事件类型,1代表跳转url,2代表打开小程序。text_notice卡片模版中该字段取值范围为[1,2]
     */
    private Integer type;

    /**
     * 根据type的值判断是否必填
     * 跳转事件的url,  type是1时必填
     */
    private String url;

    /**
     * 根据type的值判断是否必填
     * 跳转事件的小程序的appid,必须是与当前应用关联的小程序,  type是2时必填
     */
    private String appid;
    /**
     * 根据type的值判断是否必填
     * 跳转事件的小程序的pagepath,  type是2时选填
     */
    private String pagepath;
}

接口中新增方法

   /**
    * 应用消息-卡片消息
    *
    * @param cardMessage
    * @return
    */
   Result sendCardMessage(EnterpriseWeChatCardMessageParam cardMessage);

接口实现类中也增加相应的方法

    @Override
    public Result sendCardMessage(EnterpriseWeChatCardMessageParam cardMessage) {
        log.info("卡片消息参数: {} ", cardMessage.toString());
        EnterpriseAppMessageDto enterpriseAppMessageDto = sendMessage(cardMessage.getAgentid(), cardMessage);
        log.info("卡片消息响应: {}", enterpriseAppMessageDto.toString());
        return Result.success();
    }

Result 实体包装类 (上文返回值),

public class Result<E> implements Serializable {

    /**
     * 请求响应状态,参考字典ResultStatus
     * @mock 200
     */
    private Integer status;
    /**
     * 消息提示
     * @mock 请求成功
     */
    private String msg;
    /**
     * 返回结果
     */
    private E data;

    public Result(Integer status, String msg, E data) {
        this.status = status;
        this.msg = msg;
        this.data = data;
    }

    public Result() {
    }

    public E getData() {
        return data;
    }

    public void setData(E data) {
        this.data = data;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    /**
     * 请求结果成功
     */
    public boolean succeeded() {
        return status == ResultStatus.Success.code;
    }

    /**
     * 请求结果失败
     */
    public boolean failed() {
        return status != ResultStatus.Success.code;
    }

    /**
     * 业务处理成功
     */
    public static <T> Result<T> success(String msg) {
        return success(msg, null);
    }

    public static <T> Result<T> success() {
        return success(null, null);
    }

    public static <T> Result<T> success(T data) {
        return success(null, data);
    }

    public static <T> Result<T> success(String msg, T data) {
        return new Result(ResultStatus.Success.code, msg, data);
    }

    /**
     * 业务处理失败
     */
    public static <T> Result<T> failure(String msg) {
        return failure(msg, null);
    }

    public static <T> Result<T> failure(String msg, T data) {
        return new Result(ResultStatus.Failure.code, msg, data);
    }

    public static <T> Result<T> failure(ResultStatus statusCode) {
        return new Result(statusCode.code, statusCode.name, null);
    }

    /**
     * 系统异常
     */
    public static <T> Result<T> error(String msg) {
        return new Result(ResultStatus.Internal_Server_Error.code, msg, null);
    }

//    /**
//     * 系统异常,计划删除的方法
//     */
//    @Deprecated
//    public static <T> Result<T> error(String msg, Throwable throwable) {
//        return new Result(ResultStatus.Internal_Server_Error.code, msg, null);
//    }

    public static <T> Result<T> set(ResultStatus status) {
        return set(status, status.name, null);
    }

    public static <T> Result<T> set(ResultStatus status, String msg) {
        return set(status, msg, null);
    }

    public static <T> Result<T> set(ResultStatus status, String msg, T data) {
        return new Result(status.code, msg, data);
    }

    public static <T> Result<T> valueOf(Result resp) {
        return new Result(resp.getStatus(), resp.getMsg(), null);
    }

    public static <T> Result page(T data) {
        return new Result(ResultStatus.Success.code, null, new Page<>(data));
    }

    @Override
    public String toString() {
        return "Result{" +
                "status=" + status +
                ", msg='" + msg + '\'' +
                ", data=" + data +
                '}';
    }

}


Http内部接口交互状态码

public enum ResultStatus {

    /**
     * 业务处理成功,付款与退款结果表示处理完成
     */
    Success(200, "业务处理成功"),
    Accepted(202, "业务处理成功,等待服务器通知处理"),
    /**
     * 提示message消息内容
     */
    Failure(400, "业务处理失败"),
    /**
     * 用户身份验证不通过,拉起登录窗口
     */
    Unauthorized(401, "会话过期请重新登录"),
    Forbidden(403, "无权限访问"),
    Not_Found(404, "无效指令,或接口不存在"),
    Method_Not_Allowed(405, "请求方法不支持"),
    Precondition_Failed(412, "前提条件失败"),
    Payload_Too_Large(413, "请求方法不支持"),
    Upgrade_Required(426, "需要升级版本"),
    Precondition_Required(428, "需要条件验证"),
    /**
     * 显示系统异常占位图
      */
    Internal_Server_Error(500, "服务器内部异常");

    public final int code;
    public final String name;

    ResultStatus(int code, String name) {
        this.code = code;
        this.name = name;
    }

    public short shortCode() {
        return (short) code;
    }

}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值