**简要描述：** 

- 消息发送接口，支持发送im，云桥，短信，邮件

**维护人**
  
  - 周健健

**添加jar包依赖** 
-  查看 [消息中心接口调用说明](https://im.weaver.com.cn/web/#/26/2062 "消息中心接口调用说明")
  
**请求方法：**
```
  @Autowired
   private AsyncSystemMessageRest asyncSystemMessageRest;

   com.weaver.mc.api.async.AsyncSystemMessageRest.sendMsg(SendMessageEntity smg)
```

**参数：** 
```
参数对象： com.weaver.mc.api.entity.SendMessageEntity

    @ApiModelProperty("发送人,必填，无实际发送人是， 可以使用 UserEntity.SYSTEM_USER 静态对象")
	private UserEntity sender;

	@ApiModelProperty("业务模块，必填")
	private MessageModule module;
	//与module参数等价，主要用于二开时自定义模块没有MessageModule枚举的情况
	private int moduleId;

	@ApiModelProperty("业务事件，必填，比如提醒，新建，完成等等")
	private MessageEvent event;
	//与module参数等价，主要用于二开时自定义模块没有MessageEvent枚举的情况
	private int eventId;

	@ApiModelProperty("业务标识，非必填，用于匹配规则数据范围，模块未对接规则数据范围时忽略")
	private String businessId;
	
	@ApiModelProperty("消息内容，非必填，针对短信，邮件时忽略")
	private String text = "";

	@ApiModelProperty("消息发送渠道，非必填，不传递时，使用规则配置的消息渠道")
	private Set<MessageChannelEnum> channels;

	@ApiModelProperty("消息@用户，非必填，针对im消息包含@人员")
	private List<AtUserEntity> atUsers;

	@ApiModelProperty("国际化，非必填，针对im消息国际化")
	private I18nEntity i18n;

	@ApiModelProperty("事项,非必填，如果发送的消息包含流程相关信息等")
	private Entity entity;

	@ApiModelProperty("非必填，im消息默认显示消息模块，可以通过此参数修改显示的模块信息，例如 流程模块中部分消息显示 流程提交，值未国际化的labId,注意labId对应的模块未IM")
	private String optType;

    //消息接受人  receivers和userAllType 二选一必填，消息发送必选包含消息接受人
	private List<UserEntity> receivers;

	@ApiModelProperty("接受人用户所有类型，替换receivers,支持传递业务共享对性，支持设置团队所有人，部门等信息")
    private UserAllType userAllType;

    @ApiModelProperty("正对消息渠道的动态参数，比如短信，邮箱支持动态参数")
    private Map<String, String> dynamicParams;

    //非必填 短信内容，用于非模版短信， 注意非模版短信只有部分短信渠道支持，标准功能不提供非模版短信，使用时需要查看系统配置的第三方消息渠道是否支持非模版短信
    private String smsContent;

    @ApiModelProperty("第三方id，非必填，针对第三方无法记录消息id做的特殊处理，等价于第三方传递过来的消息id")
    private String thirdId;

    //是否为外部消息，非必填。  短信，邮件，云桥支持发送消息给非OA人员。 注意使用外部消息时，sender一定要使用真实的发送人，否则无法正确使用
    private boolean outMessage;

    //是否为待办消息,非必填， 对于im，云桥（企业微信，钉钉）支持待办消息的请求。 注意设置未待办消息之后，处理完成，需要调用对应的标记处理接口将待办转已办。
    //另外，云桥配置模版时，需要将消息类型配置为待办， 发送到企业微信，钉钉中才会是待办消息。
    private boolean todo;

    @ApiModelProperty("针对子模块添加的数据id参数，非必填")
    private String dataId;

    //非必填,针对邮件消息，发送非模版邮件时，支持调用时传递邮件内容
    private EmailEntity emailInfo;

    //消息标题,非必填， 默认情况下，im，云桥都会将事项名称作为标题，如果业务方需要调整默认的标题，可以传递title字段覆盖默认。
    //标题的优先级时 title> entity.name > text
    private String title;

    //企业消息内容，非必填，默认情况下，云桥会使用text字段作为内容（与im公用一个字段），可以通过传递content自定义消息在企业微信，钉钉中的消息内容.
    private String content;

    @ApiModelProperty("app打开云桥地址url，非必填，针对钉钉，企业微信在移动端打开消息时的地址，默认情况下会使用im的h5打开地址，可以通过此参数自定义").
    private String appUrl;

    @ApiModelProperty("pp打开云桥地址url，非必填，针对钉钉，企业微信在pc打开消息时的地址，默认情况下会使用im的h5打开地址，可以通过此参数自定义")
    private String pcUrl;

    @ApiModelProperty("图片地址，非必填，企业微信，钉钉支持图文消息格式，此参数对应图文地址，注意图片地址需要支持免登录访问")
    private String picUrl;

   // im离线推送内容,非必填，默认会根据消息内容构建处理离线推送消息，可以通过此字段自定义
    private String pushMsg;

   // im离线推送标题,非必填。，默认会根据消息内容构建处理离线推送消息，可以通过此字段自定义
    private String pushTitle;
    
    //非必填，发送消息时设置消息按钮.
    private List<ImComponentEntity> buttons;
    //非必填，与buttons配合使用，1代表个人按钮，处理独立，2代表单个按钮处理时，所有接受人都处理了
    // 针对场景， 会议回执，单个用户填写的回执只包含自己的.此时msgShareType=1
    //针对 加入申请，只要有一个管理员同意，所有管理员都认为已经处理了。此时msgShareType=2
     private int msgShareType = 1;


```
UserEntity
```
//人员id,必填，发送给非OA用户邮件，短信消息是，可以设置未>0的任意值
    private long employeeId;
    //@ApiModelProperty("人员tenantKey，必填，发送给非OA用户时，使用发送人团队的tenantKey")
    private String tenantKey;
    //	@ApiModelProperty("用户名称，非必填")
    private String name;
    //	@ApiModelProperty("用户语言，非必填")
    private int language;
    //	@ApiModelProperty("手机号码，非必填，设置手机号会提升发送短信性能")
    private String phone;
    //	@ApiModelProperty("邮箱地址,非必填，设置邮件会提升发送邮件性能")
    private String email;

    //国际化key 非必填，用于系统默认帐号。
    private String i18nKey;
    //角色 ，非必填，用于部分模块过滤参与角色的需求。
    private Set<Integer> roles;

     // 非必填 第三方appId，用于给非OA用户发送公众号消息。
    private String thirdAppId;

```

AtUserEntity

```
    //	@ApiModelProperty("@的id,必填")
    private String id;
    //	@ApiModelProperty("团队标识,必填")
    private String tenantKey;
    //	@ApiModelProperty("@人员名称，必填")
    private String name;
    //	@ApiModelProperty("类型，1为人员，2为群组，3为部门，4为事项成员，必填")
    private int type;

```

I18nEntity

```

    //国际化labelId ,labelId所属模块必须为im
    private String i18nKey;
    //国际化动态参数,key未占位符，value为替换占位符的值
    private Map<String, String> i18nParams;
```
UserAllType
```
    private List<UserEntity> users;
    // 必填 tenantKey
    private String tenantKey;

    @ApiModelProperty("共享对象")
    private List<PermissionShareBean> permissionShareBeanList;
    /**
     * 排除的共享对象
     */
    @ApiModelProperty("排除的共享对象")
    private List<PermissionShareBean> excludePermissionShareBeanList;
    /**
     * 人员类型，key代表类型，value对应类型的id数组,
     */
    @ApiModelProperty("人员类型，key代表类型，value对应类型的id数组")
    private Map<Integer, List<Long>> userTypeIds;
    /**
     * 排除的类型
     */
    @ApiModelProperty("类型")
    private Map<Integer, List<Long>> excludeUserTypeIds;
    /**
     * 排除的人员
     */
    @ApiModelProperty("排除的人员")
    private List<UserEntity> excludeUsers;
    /**
     * 是否发送所有人，如果为true，users,userTypeIds参数直接被忽略
     */
    @ApiModelProperty("是否发送所有人，如果为true，users,userTypeIds参数直接被忽略")
    private boolean allUser;
```
EmailEntity

```
、、
//非必填，邮件内容，针对非模版邮件
    private String emailContent;
    //非必填,邮件主题，针对非模版邮件
    private String emailSubject;
    //非必填,邮件cc用户邮箱地址，多个用户用,隔开
    private String ccList;
    //非必填，邮件bcc用户邮箱地址，多个用户用,隔开
    private String bccList;
    //非必填，邮件发送人帐号，针对多个默认邮箱发送人帐号的情况。
    private long mailUserAccountId;
	//附件id多个用逗号隔开
private String fileIds;
```

ImComponentEntity

```
    @ApiModelProperty("必填，按钮标识，由业务模块决定按钮的类型,对于存在多个按钮时，可以使用buttonFlag区分不同的按钮")
    private String buttonFlag;

    @ApiModelProperty("必填,按鈕处理类型 1点击按钮直接调用http地址，2 点击时，根据moduleFlag,commponmentName调用页面组件")
    private int type;

    @ApiModelProperty("必填,按钮名称国际化id")
    private long i18nId;
    /**
     * 背景颜色
     */
    @ApiModelProperty("非必填，按钮背景颜色，为空时采用主题色")
    private String bgColor;
    @ApiModelProperty("非必填,按钮字体颜色,为空时采用主题色")
    private String fontColor;

    @ApiModelProperty("非必填，按钮自定义参数，用于点击按钮时处理逻辑使用, 调用Http地址时，消息中心通过dubbo接口将此参数传递给业务模块；使用组件时，此参数将传递到组件")
    private Map<String, String> param;

    @ApiModelProperty("非必填，模块标识，type=2时使用，组件的模块标示")
    private String moduleFlag;

    @ApiModelProperty("非必填,组件名称,type=2时使用")
    private String componmentName;

    @ApiModelProperty("非必填, 是否支持云桥按钮, 只有type=1才有效")
    private boolean supportCloudBridge;
```

 **请求参数说明** 
 
 |参数名|必填|类型|说明|
|:-----  |:-----|-----                           |
|module|是|enum|模块|
|event|是|enum|事件|
|sender |是|Object   |发送人  |
|sender.employeeId |是|long   |发送人id  |
|sender.name |是|string   |发送人名称  |
|sender.tenantKey |是|string   |发送人团队标识  |
|text |是|string   |消息内容  |
|channels|否|枚举对象|消息渠道，不传递时，推送所有渠道|
|opType |否|String   |消息操作title的国际化key  |
|atUsers |否|Object[]   |@用户  |
|atUsers.id |是|long   |@的id，如果是人员为employee，群组为群id，如果是部门为部门id，事项成员为99  |
|atUsers.name |是|string   |是否成功  |
|atUsers.type |是|int   |类型，1人员 ，2群组，3部门，4 事项成员|  
|receivers |是|List<Object>   |消息接收人id列表  |
|receivers.employeeId |是|long   |发送人id  |
|receivers.tenantKey |是|string   |发送人团队tenantKey  |
|receivers.role |否|int   |事项接受人角色,40创建人，30负责人，20参与人，10共享人|
|i18n |否|Object   |国际化  |
|i18n.i18nKey |是|long   |国际化的Key  |
|i18n.i18nParams |否|Map<String,String>   |国际化动态参数  |
|entity|否|object|事项|
|entity.id|是|string|事项id,主要用于默认打开详情页(消息不传递实际打开地址时,会根据模块找到模块的默认地址,将id参数传递过去)以及标记已读,标记已处理接口|
|entity.name|是|string|事项名称|
|entity.module|是|string|事项模块|
|entity.pcUrl|是|string|事项模块浏览器地址|
|entity.h5Url|是|string|事项模块h5地址|
|entity.pcLinkeType|是|string|事项模块浏览器打开方式1为内部打开，2为新tab页打开,0不打开,默认为1|
|entity.h5LinkeType|是|string|事项模块h5打开方式1为内部打开，2为打开新的tab页打开,0 不打开,默认为1|
|entity.urlParams|否|Map<String,String>|打开事项时的url参数|
|appUrl|是|string|事项模块企业微信h5打开地址|
|pcUrl|是|string|事项模块 企业微信客户端打开地址|
|applyHandle|否|object|申请类消息的处理情况|
|applyHandle.type|是|int|1同意，2拒绝，3取消|
|applyHandle.employeeId|是|long|处理人id|
|applyHandle.name|是|string|处理人名称|

 **返回示例**



``` 
  {
    "code": 200,
    "msg":"成功"，
	“status”:true,
	"data":"123456"
  }
```

 **返回参数说明** 

|参数名|类型|说明|
|:-----  |:-----|-----                           |
|code |int   |状态码，200为成功  |
|msg |string   |状态描述  |
|status |bool   |是否成功  |
|data |long   |消息中心消息Id  |

**在java代码中添加spring依赖** 

```
	@Autowired
	private AsyncSystemMessageRest systemMessageRest;
	
	各模块根据业务需要应用对应的消息中心接口
	
	
**发送消息接口demo** 

	@Autowired
	private AsyncSystemMessageRest asyncSystemMessageRest;
	
	private static final long EMPLOYEE_ID = 3905800511444409505L;
	private static final String TENANT_KEY = "ty0tu018gk";

	private static final UserEntity DEFAULT_RECIVER = new UserEntity(EMPLOYEE_ID).setTenantKey(TENANT_KEY);

	private static final Entity getEntity() {
		Entity e = new Entity();
		e.setId("1565729750462339802");
		e.setModule("task");
		e.setName("测试任务未读提醒");
//		e.setH5Url("/mobile/task/123456789");
//		e.setH5LinkeType(1);
//		e.setPcUrl("/detailspage/:targetId:/:module:");
//		e.setPcLinkeType(1);

		return e;
	}

	/**
	 * 基本消息
	 * 
	 * @returnxit
	 */
	private SendMessageEntity getBaseMsg() {
		SendMessageEntity smg = new SendMessageEntity();
//		smg.setMessageSource(MessageSource.TIMECARD_NOTIFY);
		smg.setModule(MessageModule.TASK);
		smg.setEvent(MessageEvent.NOTIFY);
		smg.setSender(UserEntity.SYSTEM_USER);
		smg.setReceivers(Collections.singletonList(DEFAULT_RECIVER));
		smg.setText("任务提醒");
		smg.setPcUrl(" 云桥pc打开事项地址");//可以为空
		smg.setAppUrl("云桥app打开事项地址");//可以为空
		smg.setTitle("云桥任务提醒标题");
		smg.setContent("云桥消息内容");
		return smg;
	}

	/**
	 * 国际化消息
	 * 
	 * @return
	 */
	private SendMessageEntity getI18nMsg() {
		SendMessageEntity smg = new SendMessageEntity();
		smg.setSender(UserEntity.SYSTEM_USER);
		smg.setReceivers(Collections.singletonList(DEFAULT_RECIVER));
		smg.setModule(MessageModule.WORK_REPORT);
		smg.setEvent(MessageEvent.NOTIFY);
		smg.setText("请记得提交2021年第9周工作报告");
		I18nEntity i18n = new I18nEntity();
		i18n.setI18nId("r12345678");  //12345678= 请记得提交%Y%年第%W%周工作报告
		Map<String, String> i18nParam = new HashMap<>();
		i18nParam.put("%Y%", "2021");
		i18nParam.put("%W%", "9");
		i18n.setI18nParams(i18nParam);
		smg.setI18n(i18n);
		
		setOptType("12345"); //修改默认模块名称.
		return smg;
	}

	/**
	 * 事项消息
	 * 
	 * @return
	 */
	private SendMessageEntity getEnityMsg() {
		SendMessageEntity smg = new SendMessageEntity();
		// 任务未读事项
		smg.setModule(MessageModule.TASK);
		smg.setEvent(MessageEvent.CREATE);
		smg.setSender(UserEntity.SYSTEM_USER);
		smg.setReceivers(Collections.singletonList(DEFAULT_RECIVER));
		smg.setText("你有一条任务未读事项");
		smg.setEntity(getEntity());
		smg.setPcUrl(" 云桥pc打开事项地址");//可以为空
		smg.setAppUrl("云桥app打开事项地址");//可以为空
		smg.setTitle("云桥任务提醒标题");
		smg.setContent("云桥消息内容");
		return smg;
	}

	/**
	 * 获取@ 消息
	 * 
	 * @return
	 */
	private SendMessageEntity getAtMsg() {
		SendMessageEntity smg = new SendMessageEntity();
		// 任务 @ 新反馈
		smg.setModule(MessageModule.TASK);
		smg.setEvent(MessageEvent.AT);
		smg.setSender(UserEntity.SYSTEM_USER);
		smg.setReceivers(Collections.singletonList(DEFAULT_RECIVER));
		smg.setText(":@3905800511444409505;  测试@消息:@3905800511444409505; "); // @格式 :@{id};{空格}
		AtUserEntity at = new AtUserEntity();
		at.setId("3905800511444409505");
		at.setName("陈二");
		smg.setTpl(0);// 0是现实事项反馈，1用于未读事项，完成事项
		smg.setEntity(getEntity());// 事项
		smg.setAtUsers(Collections.singletonList(at));
		smg.setPcUrl(" 云桥pc打开事项地址");//可以为空
		smg.setAppUrl("云桥app打开事项地址");//可以为空
		smg.setTitle("云桥任务提醒标题");
		smg.setContent("云桥消息内容");
		return smg;
	}

	private SendMessageEntity getApplyMsg() {
		SendMessageEntity smg = new SendMessageEntity();
		// 任务共享申请

		smg.setModule(MessageModule.TASK);
		smg.setEvent(MessageEvent.SHARE_APPLY);
		smg.setSender(UserEntity.SYSTEM_USER);
		smg.setReceivers(Collections.singletonList(DEFAULT_RECIVER));
		smg.setText("你有一条任务共享申请");
		smg.setEntity(getEntity());
		smg.setPcUrl(" 云桥pc打开事项地址");//可以为空
		smg.setAppUrl("云桥app打开事项地址");//可以为空
		smg.setTitle("云桥任务提醒标题");
		smg.setContent("云桥消息内容");
		return smg;
	}

	/**
	 * 短信消息
	 * 
	 * @returnxit
	 */
	private SendMessageEntity getSmsMsg() {
		SendMessageEntity smg = new SendMessageEntity();
		smg.setModule(MessageModule.INVOICE_CLOUD);
		smg.setEvent(MessageEvent.WARN_NOTIFY);
		smg.setSender(UserEntity.SYSTEM_USER);
		//  发送短信时的模块，事件以及模板常量参数，请找李晓龙 沟通
		Map<String, String> params = new HashMap<>();
		params.put("content", "发票云提醒短信"); //短信模板常量
		smg.setDynamicParams(params);
		smg.setReceivers(Collections
				.singletonList(new UserEntity().setPhone("18621746291").setTenantKey('xxxx').setEmployeeId(12345).setEmail("lkclkc88@sina.com").setLanguage(6)));
		Set<MessageChannelEnum> set = new HashSet<>();
		set.add(MessageChannelEnum.SMS);
		smg.setChannels(set);
		return smg;
	}

	
	@GetMapping("/sendBaseMsg")
	@ApiOperation("发送基本的文本消息")
	public WeaResult<Long> sendBaseMsg() {
		SendMessageEntity smg = getBaseMsg();
		WeaResult<Long> result = systemMessageRest.sendMsg(smg);
		return result;
	}
	
```

 **备注** 

- 更多返回错误代码请看首页的错误代码描述
