View Javadoc
1   package com.foxinmy.weixin4j.qy;
2   
3   import java.io.InputStream;
4   import java.util.List;
5   
6   import com.alibaba.fastjson.JSONObject;
7   import com.foxinmy.weixin4j.cache.CacheStorager;
8   import com.foxinmy.weixin4j.cache.FileCacheStorager;
9   import com.foxinmy.weixin4j.exception.WeixinException;
10  import com.foxinmy.weixin4j.http.weixin.ApiResult;
11  import com.foxinmy.weixin4j.model.Button;
12  import com.foxinmy.weixin4j.model.Token;
13  import com.foxinmy.weixin4j.model.WeixinAccount;
14  import com.foxinmy.weixin4j.model.media.MediaCounter;
15  import com.foxinmy.weixin4j.model.media.MediaDownloadResult;
16  import com.foxinmy.weixin4j.model.media.MediaItem;
17  import com.foxinmy.weixin4j.model.media.MediaRecord;
18  import com.foxinmy.weixin4j.model.media.MediaUploadResult;
19  import com.foxinmy.weixin4j.model.paging.Pageable;
20  import com.foxinmy.weixin4j.qy.api.AgentApi;
21  import com.foxinmy.weixin4j.qy.api.BatchApi;
22  import com.foxinmy.weixin4j.qy.api.ChatApi;
23  import com.foxinmy.weixin4j.qy.api.HelperApi;
24  import com.foxinmy.weixin4j.qy.api.MediaApi;
25  import com.foxinmy.weixin4j.qy.api.MenuApi;
26  import com.foxinmy.weixin4j.qy.api.NotifyApi;
27  import com.foxinmy.weixin4j.qy.api.OauthApi;
28  import com.foxinmy.weixin4j.qy.api.PartyApi;
29  import com.foxinmy.weixin4j.qy.api.TagApi;
30  import com.foxinmy.weixin4j.qy.api.UserApi;
31  import com.foxinmy.weixin4j.qy.message.ChatMessage;
32  import com.foxinmy.weixin4j.qy.message.CustomeMessage;
33  import com.foxinmy.weixin4j.qy.message.NotifyMessage;
34  import com.foxinmy.weixin4j.qy.model.AgentInfo;
35  import com.foxinmy.weixin4j.qy.model.AgentOverview;
36  import com.foxinmy.weixin4j.qy.model.AgentSetter;
37  import com.foxinmy.weixin4j.qy.model.BatchResult;
38  import com.foxinmy.weixin4j.qy.model.Callback;
39  import com.foxinmy.weixin4j.qy.model.ChatInfo;
40  import com.foxinmy.weixin4j.qy.model.ChatMute;
41  import com.foxinmy.weixin4j.qy.model.Contacts;
42  import com.foxinmy.weixin4j.qy.model.IdParameter;
43  import com.foxinmy.weixin4j.qy.model.OUserInfo;
44  import com.foxinmy.weixin4j.qy.model.Party;
45  import com.foxinmy.weixin4j.qy.model.Tag;
46  import com.foxinmy.weixin4j.qy.model.User;
47  import com.foxinmy.weixin4j.qy.suite.WeixinTokenSuiteCreator;
48  import com.foxinmy.weixin4j.qy.token.WeixinTicketCreator;
49  import com.foxinmy.weixin4j.qy.token.WeixinTokenCreator;
50  import com.foxinmy.weixin4j.qy.type.ChatType;
51  import com.foxinmy.weixin4j.qy.type.InviteType;
52  import com.foxinmy.weixin4j.qy.type.KfType;
53  import com.foxinmy.weixin4j.qy.type.UserStatus;
54  import com.foxinmy.weixin4j.token.PerTicketManager;
55  import com.foxinmy.weixin4j.token.TokenCreator;
56  import com.foxinmy.weixin4j.token.TokenManager;
57  import com.foxinmy.weixin4j.tuple.MpArticle;
58  import com.foxinmy.weixin4j.type.MediaType;
59  import com.foxinmy.weixin4j.type.TicketType;
60  import com.foxinmy.weixin4j.util.Consts;
61  import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
62  
63  /**
64   * 微信企业号接口实现
65   *
66   * @className WeixinProxy
67   * @author jinyu(foxinmy@gmail.com)
68   * @date 2014年11月19日
69   * @since JDK 1.6
70   * @see <a href="https://work.weixin.qq.com/api/doc">api文档</a>
71   */
72  public class WeixinProxy {
73  	/**
74  	 * 授权API
75  	 */
76  	private final OauthApi oauthApi;
77  	/**
78  	 * 媒体素材API
79  	 */
80  	private final MediaApi mediaApi;
81  	/**
82  	 * 菜单API
83  	 */
84  	private final MenuApi menuApi;
85  	/**
86  	 * 消息服务API
87  	 */
88  	private final NotifyApi notifyApi;
89  	/**
90  	 * 部门API
91  	 */
92  	private final PartyApi partyApi;
93  	/**
94  	 * 成员API
95  	 */
96  	private final UserApi userApi;
97  	/**
98  	 * 标签API
99  	 */
100 	private final TagApi tagApi;
101 	/**
102 	 * 辅助API
103 	 */
104 	private final HelperApi helperApi;
105 	/**
106 	 * 应用API
107 	 */
108 	private final AgentApi agentApi;
109 	/**
110 	 * 批量操作API
111 	 */
112 	private final BatchApi batchApi;
113 	/**
114 	 * 聊天服务API
115 	 */
116 	private final ChatApi chatApi;
117 	/**
118 	 * token管理
119 	 */
120 	private final TokenManager tokenManager;
121 	/**
122 	 * 账号信息
123 	 */
124 	private final WeixinAccount weixinAccount;
125 	/**
126 	 * token存储
127 	 */
128 	private final CacheStorager<Token> cacheStorager;
129 
130 	/**
131 	 * 微信接口实现(使用weixin4j.properties配置的account账号信息,
132 	 * 使用FileCacheStorager文件方式缓存TOKEN)
133 	 */
134 	public WeixinProxy() {
135 		this(new FileCacheStorager<Token>());
136 	}
137 
138 	/**
139 	 * 微信接口实现(使用weixin4j.properties配置的account账号信息)
140 	 *
141 	 * @param cacheStorager
142 	 *            token管理
143 	 */
144 	public WeixinProxy(CacheStorager<Token> cacheStorager) {
145 		this(Weixin4jConfigUtil.getWeixinAccount(), cacheStorager);
146 	}
147 
148 	/**
149 	 * 微信接口实现
150 	 *
151 	 * @param weixinAccount
152 	 *            账号信息
153 	 * @param cacheStorager
154 	 *            token管理
155 	 */
156 	public WeixinProxy(WeixinAccount weixinAccount,
157 			CacheStorager<Token> cacheStorager) {
158 		this(weixinAccount, new WeixinTokenCreator(weixinAccount.getId(),
159 				weixinAccount.getSecret()), cacheStorager);
160 	}
161 
162 	/**
163 	 * 第三方套件(永久授权码机制)
164 	 *
165 	 * @param perTicketManager
166 	 *            第三方套件永久授权码
167 	 *            {@link com.foxinmy.weixin4j.qy.api.SuiteApi#getPerCodeManager(String)}
168 	 * @param suiteTokenManager
169 	 *            第三方套件凭证token
170 	 *            {@link com.foxinmy.weixin4j.qy.api.SuiteApi#getTokenManager}
171 	 * @see com.foxinmy.weixin4j.qy.api.SuiteApi
172 	 * @see WeixinSuiteProxy#getWeixinProxy(String, String)
173 	 */
174 	public WeixinProxy(PerTicketManager perTicketManager,
175 			TokenManager suiteTokenManager) {
176 		this(
177 				new WeixinAccount(perTicketManager.getThirdId(),
178 						perTicketManager.getThirdSecret()),
179 				new WeixinTokenSuiteCreator(perTicketManager, suiteTokenManager),
180 				perTicketManager.getCacheStorager());
181 	}
182 
183 	/**
184 	 * 微信接口实现
185 	 *
186 	 * @param settings
187 	 *            配置信息
188 	 * @param tokenManager
189 	 *            token管理
190 	 */
191 	private WeixinProxy(WeixinAccount weixinAccount, TokenCreator tokenCreator,
192 			CacheStorager<Token> cacheStorager) {
193 		if (weixinAccount == null) {
194 			throw new IllegalArgumentException(
195 					"weixinAccount must not be empty");
196 		}
197 		if (tokenCreator == null) {
198 			throw new IllegalArgumentException("tokenCreator must not be empty");
199 		}
200 		if (cacheStorager == null) {
201 			throw new IllegalArgumentException(
202 					"cacheStorager must not be empty");
203 		}
204 		this.tokenManager = new TokenManager(tokenCreator, cacheStorager);
205 		this.weixinAccount = weixinAccount;
206 		this.cacheStorager = cacheStorager;
207 		this.oauthApi = new OauthApi(weixinAccount);
208 		this.partyApi = new PartyApi(tokenManager);
209 		this.userApi = new UserApi(tokenManager);
210 		this.tagApi = new TagApi(tokenManager);
211 		this.helperApi = new HelperApi(tokenManager);
212 		this.agentApi = new AgentApi(tokenManager);
213 		this.batchApi = new BatchApi(tokenManager);
214 		this.notifyApi = new NotifyApi(tokenManager);
215 		this.menuApi = new MenuApi(tokenManager);
216 		this.mediaApi = new MediaApi(tokenManager);
217 		this.chatApi = new ChatApi(tokenManager);
218 	}
219 
220 	/**
221 	 * token获取
222 	 *
223 	 * @return
224 	 */
225 	public TokenManager getTokenManager() {
226 		return this.tokenManager;
227 	}
228 
229 	/**
230 	 * 获取oauth授权API
231 	 *
232 	 * @see com.foxinmy.weixin4j.qy.api.OauthApi
233 	 * @return
234 	 */
235 	public OauthApi getOauthApi() {
236 		return oauthApi;
237 	}
238 
239 	/**
240 	 * 获取微信账号信息
241 	 *
242 	 * @return
243 	 */
244 	public WeixinAccount getWeixinAccount() {
245 		return weixinAccount;
246 	}
247 
248 	/**
249 	 * 获取JSSDK Ticket的tokenManager
250 	 *
251 	 * @param ticketType
252 	 *            票据类型
253 	 * @return
254 	 */
255 	public TokenManager getTicketManager(TicketType ticketType) {
256 		return new TokenManager(new WeixinTicketCreator(ticketType,
257 				this.tokenManager), cacheStorager);
258 	}
259 
260 	/**
261 	 * 发送消息提醒(需要管理员对应用有使用权限,对收件人touser、toparty、totag有查看权限,否则本次调用失败)
262 	 * <p>
263 	 * 1) 发送人员列表存在错误的userid:执行发送,开发者需注意返回结果说明</br>
264 	 * 2)发送人员不在通讯录权限范围内:不执行发送任务,返回首个出错的userid</br>
265 	 * 3)发送人员不在应用可见范围内:不执行发送任务,返回首个出错的userid</br>
266 	 * </p>
267 	 *
268 	 * @param message
269 	 *            消息对象
270 	 * @return 如果对应用或收件人、部门、标签任何一个无权限,则本次发送失败;如果收件人、部门或标签不存在,发送仍然执行,但返回无效的部分
271 	 *         </br> { "errcode": 0, "errmsg": "ok", "invaliduser": "UserID1",
272 	 *         "invalidparty":"PartyID1", "invalidtag":"TagID1" }
273 	 * @throws WeixinException
274 	 * @see com.foxinmy.weixin4j.qy.api.NotifyApi
275 	 * @see <a href="https://work.weixin.qq.com/api/doc#10167">发送接口说明</a>
276 	 * @see com.foxinmy.weixin4j.tuple.Text
277 	 * @see com.foxinmy.weixin4j.tuple.Image
278 	 * @see com.foxinmy.weixin4j.tuple.Voice
279 	 * @see com.foxinmy.weixin4j.tuple.Video
280 	 * @see com.foxinmy.weixin4j.tuple.File
281 	 * @see com.foxinmy.weixin4j.tuple.News
282 	 * @see com.foxinmy.weixin4j.tuple.MpNews
283 	 * @see com.foxinmy.weixin4j.qy.model.IdParameter
284 	 */
285 	public IdParameter sendNotifyMessage(NotifyMessage message)
286 			throws WeixinException {
287 		return notifyApi.sendNotifyMessage(message);
288 	}
289 
290 	/**
291 	 * 发送客服消息
292 	 *
293 	 * @param message
294 	 *            消息对象
295 	 * @return 发送结果
296 	 * @see <a href=
297 	 *      "http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BC%81%E4%B8%9A%E5%AE%A2%E6%9C%8D%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E">
298 	 *      客服接口说明</a>
299 	 * @see com.foxinmy.weixin4j.qy.api.NotifyApi
300 	 * @see com.foxinmy.weixin4j.tuple.Text
301 	 * @see com.foxinmy.weixin4j.tuple.Image
302 	 * @see com.foxinmy.weixin4j.tuple.Voice
303 	 * @see com.foxinmy.weixin4j.tuple.Video
304 	 * @see com.foxinmy.weixin4j.tuple.File
305 	 * @see com.foxinmy.weixin4j.qy.message.CustomeMessage
306 	 * @throws WeixinException
307 	 */
308 	public ApiResult sendCustomeMessage(CustomeMessage message)
309 			throws WeixinException {
310 		return notifyApi.sendCustomeMessage(message);
311 	}
312 
313 	/**
314 	 * 获取客服列表
315 	 *
316 	 * @param kfType
317 	 *            客服类型 为空时返回全部类型的客服
318 	 * @return 第一个元素为内部客服(internal),第二个参数为外部客服(external)
319 	 * @see com.foxinmy.weixin4j.qy.api.NotifyApi
320 	 * @see com.foxinmy.weixin4j.qy.model.IdParameter
321 	 * @see <a href=
322 	 *      "http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BC%81%E4%B8%9A%E5%AE%A2%E6%9C%8D%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E">
323 	 *      客服列表</a>
324 	 * @throws WeixinException
325 	 */
326 	public IdParameter[] getKfList(KfType kfType) throws WeixinException {
327 		return notifyApi.getKfList(kfType);
328 	}
329 
330 	/**
331 	 * 自定义菜单(管理员须拥有应用的管理权限 并且应用必须设置在回调模式)
332 	 *
333 	 * @param agentid
334 	 *            应用ID
335 	 *
336 	 * @param buttons
337 	 *            菜单列表
338 	 * @throws WeixinException
339 	 * @see com.foxinmy.weixin4j.qy.api.MenuApi
340 	 * @see <a href= "https://work.weixin.qq.com/api/doc#10786"> 创建自定义菜单</a>
341 	 * @see com.foxinmy.weixin4j.model.Button
342 	 */
343 	public ApiResult createMenu(int agentid, List<Button> buttons)
344 			throws WeixinException {
345 		return menuApi.createMenu(agentid, buttons);
346 	}
347 
348 	/**
349 	 * 查询菜单(管理员须拥有应用的管理权限 并且应用必须设置在回调模式。)
350 	 *
351 	 * @param agentid
352 	 *            应用ID
353 	 * @return 菜单集合
354 	 * @throws WeixinException
355 	 * @see com.foxinmy.weixin4j.qy.api.MenuApi
356 	 * @see <a href= "https://work.weixin.qq.com/api/doc#10787"> 查询菜单</a>
357 	 * @see com.foxinmy.weixin4j.model.Button
358 	 */
359 	public List<Button> getMenu(int agentid) throws WeixinException {
360 		return menuApi.getMenu(agentid);
361 	}
362 
363 	/**
364 	 * 删除菜单(管理员须拥有应用的管理权限 并且应用必须设置在回调模式)
365 	 *
366 	 * @param agentid
367 	 *            应用ID
368 	 * @throws WeixinException
369 	 * @see com.foxinmy.weixin4j.qy.api.MenuApi
370 	 * @see <a href= "https://work.weixin.qq.com/api/doc#10788"> 删除菜单</a>
371 	 * @return 处理结果
372 	 */
373 	public ApiResult deleteMenu(int agentid) throws WeixinException {
374 		return menuApi.deleteMenu(agentid);
375 	}
376 
377 	/**
378 	 * 上传图文消息内的图片:用于上传图片到企业号服务端,接口返回图片url,请注意,该url仅可用于图文消息的发送,
379 	 * 且每个企业每天最多只能上传100张图片。
380 	 *
381 	 * @param is
382 	 *            图片数据
383 	 * @param fileName
384 	 *            文件名
385 	 * @see <a href=
386 	 *      "http://qydev.weixin.qq.com/wiki/index.php?title=%E4%B8%8A%E4%BC%A0%E5%9B%BE%E6%96%87%E6%B6%88%E6%81%AF%E5%86%85%E7%9A%84%E5%9B%BE%E7%89%87">
387 	 *      上传图文消息内的图片</a>
388 	 * @return 图片url
389 	 * @see com.foxinmy.weixin4j.qy.api.MediaApi
390 	 * @throws WeixinException
391 	 */
392 	public String uploadImage(InputStream is, String fileName)
393 			throws WeixinException {
394 		return mediaApi.uploadImage(is, fileName);
395 	}
396 
397 	/**
398 	 * 上传媒体文件
399 	 * <p>
400 	 * 正常情况下返回{"type":"TYPE","media_id":"MEDIA_ID","created_at":123456789},
401 	 * 否则抛出异常.
402 	 * </p>
403 	 *
404 	 * @param agentid
405 	 *            企业应用ID(<font color="red">大于0时视为上传永久媒体文件</font>)
406 	 * @param is
407 	 *            媒体数据流
408 	 * @param fileName
409 	 *            文件名
410 	 * @return 上传到微信服务器返回的媒体标识
411 	 * @see com.foxinmy.weixin4j.qy.api.MediaApi
412 	 * @see com.foxinmy.weixin4j.model.media.MediaUploadResult
413 	 * @see <a href= "https://work.weixin.qq.com/api/doc#10112"> 上传临时素材文件说明</a>
414 	 * @see <a href=
415 	 *      "http://http://qydev.weixin.qq.com/wiki/index.php?title=%E4%B8%8A%E4%BC%A0%E6%B0%B8%E4%B9%85%E7%B4%A0%E6%9D%90">
416 	 *      上传永久素材文件说明</a>
417 	 * @throws WeixinException
418 	 */
419 	public MediaUploadResult uploadMedia(int agentid, InputStream is,
420 			String fileName) throws WeixinException {
421 		return mediaApi.uploadMedia(agentid, is, fileName);
422 	}
423 
424 	/**
425 	 * 下载媒体文件
426 	 *
427 	 * @param agentid
428 	 *            企业应用Id(<font color="red">大于0时视为获取永久媒体文件</font>)
429 	 * @param mediaId
430 	 *            媒体ID
431 	 * @return 媒体下载结果
432 	 * @see com.foxinmy.weixin4j.model.media.MediaDownloadResult
433 	 * @see com.foxinmy.weixin4j.qy.api.MediaApi
434 	 * @see <a href= "https://work.weixin.qq.com/api/doc#10115"> 获取临时媒体说明</a>
435 	 * @see <a href=
436 	 *      "http://qydev.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E6%B0%B8%E4%B9%85%E7%B4%A0%E6%9D%90">
437 	 *      获取永久媒体说明</a>
438 	 * @throws WeixinException
439 	 */
440 	public MediaDownloadResult downloadMedia(int agentid, String mediaId)
441 			throws WeixinException {
442 		return mediaApi.downloadMedia(agentid, mediaId);
443 	}
444 
445 	/**
446 	 * 上传永久图文素材
447 	 * <p>
448 	 * 、新增的永久素材也可以在公众平台官网素材管理模块中看到,永久素材的数量是有上限的,请谨慎新增。图文消息素材和图片素材的上限为5000,
449 	 * 其他类型为1000
450 	 * </P>
451 	 *
452 	 * @param agentid
453 	 *            企业应用的id
454 	 * @param articles
455 	 *            图文列表
456 	 * @return 上传到微信服务器返回的媒体标识
457 	 * @throws WeixinException
458 	 * @see com.foxinmy.weixin4j.qy.api.MediaApi
459 	 * @see <a href=
460 	 *      "http://qydev.weixin.qq.com/wiki/index.php?title=%E4%B8%8A%E4%BC%A0%E6%B0%B8%E4%B9%85%E7%B4%A0%E6%9D%90">
461 	 *      上传永久媒体素材</a>
462 	 * @see com.foxinmy.weixin4j.tuple.MpArticle
463 	 */
464 	public String uploadMaterialArticle(int agentid, List<MpArticle> articles)
465 			throws WeixinException {
466 		return mediaApi.uploadMaterialArticle(agentid, articles);
467 	}
468 
469 	/**
470 	 * 删除永久媒体素材
471 	 *
472 	 * @param agentid
473 	 *            企业应用ID
474 	 * @param mediaId
475 	 *            媒体素材的media_id
476 	 * @return 处理结果
477 	 * @throws WeixinException
478 	 * @see com.foxinmy.weixin4j.qy.api.MediaApi
479 	 * @see <a href=
480 	 *      "http://qydev.weixin.qq.com/wiki/index.php?title=%E5%88%A0%E9%99%A4%E6%B0%B8%E4%B9%85%E7%B4%A0%E6%9D%90">
481 	 *      删除永久媒体素材</a>
482 	 */
483 	public ApiResult deleteMaterialMedia(int agentid, String mediaId)
484 			throws WeixinException {
485 		return mediaApi.deleteMaterialMedia(agentid, mediaId);
486 	}
487 
488 	/**
489 	 * 下载永久图文素材
490 	 *
491 	 * @param agentid
492 	 *            企业应用ID
493 	 * @param mediaId
494 	 *            媒体素材的media_id
495 	 * @return 图文列表
496 	 * @throws WeixinException
497 	 * @see {@link #downloadMedia(int, String)}
498 	 * @see com.foxinmy.weixin4j.qy.api.MediaApi
499 	 * @see com.foxinmy.weixin4j.tuple.MpArticle
500 	 */
501 	public List<MpArticle> downloadArticle(int agentid, String mediaId)
502 			throws WeixinException {
503 		return mediaApi.downloadArticle(agentid, mediaId);
504 	}
505 
506 	/**
507 	 * 修改永久图文素材
508 	 *
509 	 * @param agentid
510 	 *            企业应用的id
511 	 * @param mediaId
512 	 *            上传后的media_id
513 	 * @param articles
514 	 *            图文列表
515 	 * @return 操作结果
516 	 * @throws WeixinException
517 	 * @see com.foxinmy.weixin4j.qy.api.MediaApi
518 	 * @see <a href=
519 	 *      "http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BF%AE%E6%94%B9%E6%B0%B8%E4%B9%85%E5%9B%BE%E6%96%87%E7%B4%A0%E6%9D%90">
520 	 *      修改永久媒体素材</a>
521 	 * @see com.foxinmy.weixin4j.tuple.MpArticle
522 	 */
523 	public String updateMaterialArticle(int agentid, String mediaId,
524 			List<MpArticle> articles) throws WeixinException {
525 		return mediaApi.updateMaterialArticle(agentid, mediaId, articles);
526 	}
527 
528 	/**
529 	 * 获取永久媒体素材的总数
530 	 *
531 	 * @param agentid
532 	 *            企业应用id
533 	 * @return 总数对象
534 	 * @throws WeixinException
535 	 * @see com.foxinmy.weixin4j.qy.api.MediaApi
536 	 * @see com.foxinmy.weixin4j.model.media.MediaCounter
537 	 * @see <a href=
538 	 *      "http://qydev.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E7%B4%A0%E6%9D%90%E6%80%BB%E6%95%B0">
539 	 *      获取素材总数</a>
540 	 */
541 	public MediaCounter countMaterialMedia(int agentid) throws WeixinException {
542 		return mediaApi.countMaterialMedia(agentid);
543 	}
544 
545 	/**
546 	 * 获取媒体素材记录列表
547 	 *
548 	 * @param agentid
549 	 *            企业应用ID
550 	 * @param mediaType
551 	 *            素材的类型,图片(image)、视频(video)、语音 (voice)、图文(news)、文件(file)
552 	 * @param pageable
553 	 *            分页数据
554 	 * @return 媒体素材的记录对象
555 	 * @throws WeixinException
556 	 * @see com.foxinmy.weixin4j.qy.api.MediaApi
557 	 * @see com.foxinmy.weixin4j.model.media.MediaRecord
558 	 * @see com.foxinmy.weixin4j.type.MediaType
559 	 * @see com.foxinmy.weixin4j.model.media.MediaItem
560 	 * @see com.foxinmy.weixin4j.model.paging.Pageable
561 	 * @see com.foxinmy.weixin4j.model.paging.Pagedata
562 	 * @see <a href=
563 	 *      "http://qydev.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E7%B4%A0%E6%9D%90%E5%88%97%E8%A1%A8">
564 	 *      获取素材列表</a>
565 	 */
566 	public MediaRecord listMaterialMedia(int agentid, MediaType mediaType,
567 			Pageable pageable) throws WeixinException {
568 		return mediaApi.listMaterialMedia(agentid, mediaType, pageable);
569 	}
570 
571 	/**
572 	 * 获取全部的媒体素材
573 	 *
574 	 * @param agentid
575 	 *            企业应用id
576 	 * @param mediaType
577 	 *            媒体类型
578 	 * @return 素材列表
579 	 * @see com.foxinmy.weixin4j.qy.api.MediaApi
580 	 * @see {@link #listMaterialMedia(int,MediaType, Pageable)}
581 	 * @throws WeixinException
582 	 */
583 	public List<MediaItem> listAllMaterialMedia(int agentid, MediaType mediaType)
584 			throws WeixinException {
585 		return mediaApi.listAllMaterialMedia(agentid, mediaType);
586 	}
587 
588 	/**
589 	 * 创建部门(根部门的parentid为1)
590 	 *
591 	 * @param party
592 	 *            部门对象
593 	 * @see com.foxinmy.weixin4j.qy.model.Party
594 	 * @see <a href= "https://work.weixin.qq.com/api/doc#10076"> 创建部门说明</a>
595 	 * @see com.foxinmy.weixin4j.qy.api.PartyApi
596 	 * @return 部门ID
597 	 * @throws WeixinException
598 	 */
599 	public int createParty(Party party) throws WeixinException {
600 		return partyApi.createParty(party);
601 	}
602 
603 	/**
604 	 * 更新部门(如果非必须的字段未指定 则不更新该字段之前的设置值)
605 	 *
606 	 * @param party
607 	 *            部门对象
608 	 * @see com.foxinmy.weixin4j.qy.model.Party
609 	 * @see <a href= "https://work.weixin.qq.com/api/doc#10077"> 更新部门说明</a>
610 	 * @see com.foxinmy.weixin4j.qy.api.PartyApi
611 	 * @return 处理结果
612 	 * @throws WeixinException
613 	 */
614 	public ApiResult updateParty(Party party) throws WeixinException {
615 		return partyApi.updateParty(party);
616 	}
617 
618 	/**
619 	 * 查询部门列表(以部门的order字段从小到大排列)
620 	 *
621 	 * @param partyId
622 	 *            部门ID。获取指定部门ID下的子部门 传入0表示获取全部子部门
623 	 * @see com.foxinmy.weixin4j.qy.model.Party
624 	 * @see <a href= "https://work.weixin.qq.com/api/doc#10093"> 获取部门列表</a>
625 	 * @see com.foxinmy.weixin4j.qy.api.PartyApi
626 	 * @return 部门列表
627 	 * @throws WeixinException
628 	 */
629 	public List<Party> listParty(int partyId) throws WeixinException {
630 		return partyApi.listParty(partyId);
631 	}
632 
633 	/**
634 	 * 删除部门(不能删除根部门;不能删除含有子部门、成员的部门)
635 	 *
636 	 * @param partyId
637 	 *            部门ID
638 	 * @see <a href= "https://work.weixin.qq.com/api/doc#10079"> 删除部门说明</a>
639 	 * @see com.foxinmy.weixin4j.qy.api.PartyApi
640 	 * @return 处理结果
641 	 * @throws WeixinException
642 	 */
643 	public ApiResult deleteParty(int partyId) throws WeixinException {
644 		return partyApi.deleteParty(partyId);
645 	}
646 
647 	/**
648 	 * 批量上传部门
649 	 *
650 	 * @param parties
651 	 *            部门列表
652 	 * @see com.foxinmy.weixin4j.qy.api.MediaApi
653 	 * @see com.foxinmy.weixin4j.qy.api.BatchApi
654 	 * @see {@link #batchReplaceParty(String,Callback)}
655 	 * @see <a href= "https://work.weixin.qq.com/api/doc#10138"> 批量任务</a>
656 	 * @return 上传后的mediaId
657 	 * @throws WeixinException
658 	 */
659 	public String batchUploadParties(List<Party> parties)
660 			throws WeixinException {
661 		return mediaApi.batchUploadParties(parties);
662 	}
663 
664 	/**
665 	 * 创建成员
666 	 *
667 	 * @param user
668 	 *            成员对象
669 	 * @see com.foxinmy.weixin4j.qy.model.User
670 	 * @see <a href= "http://work.weixin.qq.com/api/doc#10018"> 创建成员说明</a>
671 	 * @see com.foxinmy.weixin4j.qy.api.UserApi
672 	 * @return 处理结果
673 	 * @throws WeixinException
674 	 */
675 	public ApiResult createUser(User user) throws WeixinException {
676 		return userApi.createUser(user);
677 	}
678 
679 	/**
680 	 * 创建成员
681 	 *
682 	 * @param user
683 	 *            成员对象
684 	 * @param avatar
685 	 *            头像文件 可为空
686 	 * @see com.foxinmy.weixin4j.qy.model.User
687 	 * @see <a href= "http://work.weixin.qq.com/api/doc#10018"> 创建成员说明</a>
688 	 * @see com.foxinmy.weixin4j.qy.api.UserApi
689 	 * @return 处理结果
690 	 * @throws WeixinException
691 	 */
692 	public ApiResult createUser(User user, InputStream avatar)
693 			throws WeixinException {
694 		return userApi.createUser(user, avatar);
695 	}
696 
697 	/**
698 	 * 更新用户(如果非必须的字段未指定 则不更新该字段之前的设置值)
699 	 *
700 	 * @param user
701 	 *            成员对象
702 	 * @see com.foxinmy.weixin4j.qy.model.User
703 	 * @see <a href= "http://work.weixin.qq.com/api/doc#10020"> 更新成员说明</a>
704 	 * @see com.foxinmy.weixin4j.qy.api.UserApi
705 	 * @return 处理结果
706 	 * @throws WeixinException
707 	 */
708 	public ApiResult updateUser(User user) throws WeixinException {
709 		return userApi.updateUser(user);
710 	}
711 
712 	/**
713 	 * 更新用户(如果非必须的字段未指定 则不更新该字段之前的设置值)
714 	 *
715 	 * @param user
716 	 *            成员对象
717 	 * @param avatar
718 	 *            头像文件
719 	 * @see com.foxinmy.weixin4j.qy.model.User
720 	 * @see <a href= "http://work.weixin.qq.com/api/doc#10020"> 更新成员说明</a>
721 	 * @see com.foxinmy.weixin4j.qy.api.UserApi
722 	 * @return 处理结果
723 	 * @throws WeixinException
724 	 */
725 	public ApiResult updateUser(User user, InputStream avatar)
726 			throws WeixinException {
727 		return userApi.updateUser(user, avatar);
728 	}
729 
730 	/**
731 	 * 获取成员信息
732 	 *
733 	 * @param userid
734 	 *            成员唯一ID
735 	 * @see com.foxinmy.weixin4j.qy.model.User
736 	 * @see <a href= "http://work.weixin.qq.com/api/doc#10019"> 获取成员说明</a>
737 	 * @see com.foxinmy.weixin4j.qy.api.UserApi
738 	 * @return 成员对象
739 	 * @throws WeixinException
740 	 */
741 	public User getUser(String userid) throws WeixinException {
742 		return userApi.getUser(userid);
743 	}
744 
745 	/**
746 	 * code获取userid(管理员须拥有agent的使用权限;agentid必须和跳转链接时所在的企业应用ID相同。)
747 	 *
748 	 * @param code
749 	 *            通过员工授权获取到的code,每次员工授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期
750 	 * @see com.foxinmy.weixin4j.qy.model.User
751 	 * @see com.foxinmy.weixin4j.qy.api.UserApi
752 	 * @return 成员对象
753 	 * @see {@link #getUser(String)}
754 	 * @see {@link #getUserIdByCode(String)}
755 	 * @see <a href= "http://work.weixin.qq.com/api/doc#10028/根据code获取成员信息">
756 	 *      企业获取code</a>
757 	 * @see <a href= "http://work.weixin.qq.com/api/doc#10028/根据code获取成员信息">
758 	 *      根据code获取成员信息</a>
759 	 * @throws WeixinException
760 	 */
761 	public User getUserByCode(String code) throws WeixinException {
762 		return userApi.getUserByCode(code);
763 	}
764 
765 	/**
766 	 * 获取企业号管理员登录信息
767 	 *
768 	 * @param authCode
769 	 *            oauth2.0授权企业号管理员登录产生的code
770 	 * @return 登陆信息
771 	 * @see <a href=
772 	 *      "http://qydev.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E4%BC%81%E4%B8%9A%E7%AE%A1%E7%90%86%E5%91%98%E7%99%BB%E5%BD%95%E4%BF%A1%E6%81%AF">
773 	 *      授权获取企业号管理员登录信息</a>
774 	 * @see com.foxinmy.weixin4j.qy.model.OUserInfo
775 	 * @throws WeixinException
776 	 */
777 	public OUserInfo getOUserInfoByCode(String authCode) throws WeixinException {
778 		return userApi.getOUserInfoByCode(authCode);
779 	}
780 
781 	/**
782 	 * 根据code获取成员ID信息
783 	 *
784 	 * @param code
785 	 *            通过员工授权获取到的code,每次员工授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期
786 	 * @return 换取结果
787 	 * @see com.foxinmy.weixin4j.qy.api.UserApi
788 	 * @see <a href= "https://work.weixin.qq.com/api/doc#10028">
789 	 *      oauth授权获取用户信息</a>
790 	 * @throws WeixinException
791 	 */
792 	public JSONObject getUserIdByCode(String code) throws WeixinException {
793 		return userApi.getUserIdByCode(code);
794 	}
795 
796 	/**
797 	 * 获取部门成员
798 	 *
799 	 * @param partyId
800 	 *            部门ID
801 	 * @param fetchChild
802 	 *            是否递归获取子部门下面的成员
803 	 * @param userStatus
804 	 *            成员状态 status可叠加 未填写则默认为未关注(4)
805 	 * @param findDetail
806 	 *            是否获取详细信息
807 	 * @see com.foxinmy.weixin4j.qy.model.User
808 	 * @see <a href= "https://work.weixin.qq.com/api/doc#10061"> 获取部门成员说明</a>
809 	 * @see com.foxinmy.weixin4j.qy.api.UserApi
810 	 * @return 成员列表
811 	 * @throws WeixinException
812 	 */
813 	public List<User> listUser(int partyId, boolean fetchChild,
814 			UserStatus userStatus, boolean findDetail) throws WeixinException {
815 		return userApi.listUser(partyId, fetchChild, userStatus, findDetail);
816 	}
817 
818 	/**
819 	 * 获取权限范围内的所有成员列表
820 	 *
821 	 * @param userStatus
822 	 *            成员状态 未填写则默认为全部状态下的成员
823 	 * @return 成员列表
824 	 * @see com.foxinmy.weixin4j.qy.api.UserApi
825 	 * @see {@link #listUser(int, boolean, UserStatus,boolean)}
826 	 * @see {@link PartyApi#listParty(int)}
827 	 * @throws WeixinException
828 	 */
829 	public List<User> listAllUser(UserStatus userStatus) throws WeixinException {
830 		return userApi.listAllUser(userStatus);
831 	}
832 
833 	/**
834 	 * 获取部门下所有状态成员(不进行递归)
835 	 *
836 	 * @param partyId
837 	 *            部门ID
838 	 * @see {@link #listUser(int, boolean, UserStatus, boolean)}
839 	 * @see com.foxinmy.weixin4j.qy.api.UserApi
840 	 * @return 成员列表
841 	 * @throws WeixinException
842 	 */
843 	public List<User> listUser(int partyId) throws WeixinException {
844 		return userApi.listUser(partyId);
845 	}
846 
847 	/**
848 	 * 删除成员
849 	 *
850 	 * @param userid
851 	 *            成员ID
852 	 * @see <a href= "https://work.weixin.qq.com/api/doc#10030"> 删除成员说明</a>
853 	 * @see com.foxinmy.weixin4j.qy.api.UserApi
854 	 * @return 处理结果
855 	 * @throws WeixinException
856 	 */
857 	public ApiResult deleteUser(String userid) throws WeixinException {
858 		return userApi.deleteUser(userid);
859 	}
860 
861 	/**
862 	 * 批量删除成员
863 	 *
864 	 * @param userIds
865 	 *            成员列表
866 	 * @see <a href= "https://work.weixin.qq.com/api/doc#10060" >批量删除成员说明</a
867 	 * @see com.foxinmy.weixin4j.qy.api.UserApi
868 	 * @return 处理结果
869 	 * @throws WeixinException
870 	 */
871 	public ApiResult batchDeleteUser(List<String> userIds)
872 			throws WeixinException {
873 		return userApi.batchDeleteUser(userIds);
874 	}
875 
876 	/**
877 	 * 邀请成员关注(管理员须拥有该成员的查看权限)
878 	 *
879 	 * @param userId
880 	 *            成员ID
881 	 * @param tips
882 	 *            推送到微信上的提示语(只有认证号可以使用)。当使用微信推送时,该字段默认为“请关注XXX企业号”,邮件邀请时,该字段无效。
883 	 * @see com.foxinmy.weixin4j.qy.api.UserApi
884 	 * @return 调用结果
885 	 * @see <a href=
886 	 *      "http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E6%88%90%E5%91%98#.E9.82.80.E8.AF.B7.E6.88.90.E5.91.98.E5.85.B3.E6.B3.A8">
887 	 *      邀请成员关注说明</a>
888 	 * @throws WeixinException
889 	 */
890 	public InviteType inviteUser(String userId, String tips)
891 			throws WeixinException {
892 		return userApi.inviteUser(userId, tips);
893 	}
894 
895 	/**
896 	 * 开启二次验证成功时调用(管理员须拥有userid对应员工的管理权限)
897 	 *
898 	 * @param userid
899 	 *            成员ID
900 	 * @return 调用结果
901 	 * @see com.foxinmy.weixin4j.qy.api.UserApi
902 	 * @see <a href= "https://work.weixin.qq.com/api/doc#11378"> 二次验证说明</a>
903 	 * @throws WeixinException
904 	 */
905 	public ApiResult userAuthsucc(String userId) throws WeixinException {
906 		return userApi.authsucc(userId);
907 	}
908 
909 	/**
910 	 * 创建标签(创建的标签属于管理组;默认为未加锁状态)
911 	 *
912 	 * @param tag
913 	 *            标签对象;</br> 标签名称,长度为1~64个字节,标签名不可与其他标签重名;</br> 标签id,整型,
914 	 *            指定此参数时新增的标签会生成对应的标签id,不指定时则以目前最大的id自增。
915 	 * @see <a href= "https://work.weixin.qq.com/api/doc#10915"> 创建标签说明</a>
916 	 * @see com.foxinmy.weixin4j.qy.api.TagApi
917 	 * @return 标签ID
918 	 * @throws WeixinException
919 	 */
920 	public int createTag(Tag tag) throws WeixinException {
921 		return tagApi.createTag(tag);
922 	}
923 
924 	/**
925 	 * 更新标签(管理组必须是指定标签的创建者)
926 	 *
927 	 * @param tag
928 	 *            标签信息
929 	 * @see <a href= "https://work.weixin.qq.com/api/doc#10919" >更新标签说明</a>
930 	 * @see com.foxinmy.weixin4j.qy.model.Tag
931 	 * @see com.foxinmy.weixin4j.qy.api.TagApi
932 	 * @return 处理结果
933 	 * @throws WeixinException
934 	 */
935 	public ApiResult updateTag(Tag tag) throws WeixinException {
936 		return tagApi.updateTag(tag);
937 	}
938 
939 	/**
940 	 * 删除标签(管理组必须是指定标签的创建者 并且标签的成员列表为空)
941 	 *
942 	 * @param tagId
943 	 *            标签ID
944 	 * @return 处理结果
945 	 * @see <a href= "https://work.weixin.qq.com/api/doc#10920"> 删除标签说明</a>
946 	 * @see com.foxinmy.weixin4j.qy.api.TagApi
947 	 * @throws WeixinException
948 	 */
949 	public ApiResult deleteTag(int tagId) throws WeixinException {
950 		return tagApi.deleteTag(tagId);
951 	}
952 
953 	/**
954 	 * 获取标签列表
955 	 *
956 	 * @see <a href= "https://work.weixin.qq.com/api/doc#10926"> 获取标签列表说明</a>
957 	 * @see com.foxinmy.weixin4j.qy.model.Tag
958 	 * @see com.foxinmy.weixin4j.qy.api.TagApi
959 	 * @return 标签列表
960 	 * @throws WeixinException
961 	 */
962 	public List<Tag> listTag() throws WeixinException {
963 		return tagApi.listTag();
964 	}
965 
966 	/**
967 	 * 获取标签成员(管理组须拥有“获取标签成员”的接口权限,标签须对管理组可见;返回列表仅包含管理组管辖范围的成员)
968 	 *
969 	 * @param tagId
970 	 *            标签ID
971 	 * @see com.foxinmy.weixin4j.qy.model.User
972 	 * @see <a href= "https://work.weixin.qq.com/api/doc#10921"> 获取标签成员说明</a>
973 	 * @see com.foxinmy.weixin4j.qy.api.TagApi
974 	 * @return 成员列表<font color="red">Contacts#getUsers</font>和部门列表 <font
975 	 *         color="red">Contacts#getPartyIds</font>
976 	 * @throws WeixinException
977 	 */
978 	public Contacts getTagUsers(int tagId) throws WeixinException {
979 		return tagApi.getTagUsers(tagId);
980 	}
981 
982 	/**
983 	 * 新增标签成员(标签对管理组可见且未加锁,成员属于管理组管辖范围)
984 	 *
985 	 * @param tagId
986 	 *            标签ID
987 	 * @param userIds
988 	 *            企业成员ID列表,注意:userlist、partylist不能同时为空
989 	 * @param partyIds
990 	 *            企业部门ID列表,注意:userlist、partylist不能同时为空
991 	 * @see <a href= "https://work.weixin.qq.com/api/doc#10923"> 新增标签成员说明</a>
992 	 * @see com.foxinmy.weixin4j.qy.api.TagApi
993 	 * @see com.foxinmy.weixin4j.qy.model.IdParameter
994 	 * @return 非法的userIds和partyIds
995 	 * @throws WeixinException
996 	 */
997 	public IdParameter addTagUsers(int tagId, List<String> userIds,
998 			List<Integer> partyIds) throws WeixinException {
999 		return tagApi.addTagUsers(tagId, userIds, partyIds);
1000 	}
1001 
1002 	/**
1003 	 * 删除标签成员(标签对管理组可见且未加锁,成员属于管理组管辖范围)
1004 	 *
1005 	 * @param tagId
1006 	 *            标签ID
1007 	 * @param userIds
1008 	 *            企业成员ID列表,注意:userlist、partylist不能同时为空
1009 	 * @param partyIds
1010 	 *            企业部门ID列表,注意:userlist、partylist不能同时为空
1011 	 * @see <a href= "https://work.weixin.qq.com/api/doc#10925"> 删除标签成员说明</a>
1012 	 * @see com.foxinmy.weixin4j.qy.api.TagApi
1013 	 * @see com.foxinmy.weixin4j.qy.model.IdParameter
1014 	 * @return 非法的userIds和partyIds
1015 	 * @throws WeixinException
1016 	 */
1017 	public IdParameter deleteTagUsers(int tagId, List<String> userIds,
1018 			List<Integer> partyIds) throws WeixinException {
1019 		return tagApi.deleteTagUsers(tagId, userIds, partyIds);
1020 	}
1021 
1022 	/**
1023 	 * 获取微信服务器IP地址
1024 	 *
1025 	 * @return IP地址
1026 	 * @see com.foxinmy.weixin4j.qy.api.HelperApi
1027 	 * @see <a href=
1028 	 *      "http://qydev.weixin.qq.com/wiki/index.php?title=%E5%9B%9E%E8%B0%83%E6%A8%A1%E5%BC%8F#.E8.8E.B7.E5.8F.96.E5.BE.AE.E4.BF.A1.E6.9C.8D.E5.8A.A1.E5.99.A8.E7.9A.84ip.E6.AE.B5">
1029 	 *      获取IP地址</a>
1030 	 * @throws WeixinException
1031 	 */
1032 	public List<String> getWechatServerIp() throws WeixinException {
1033 		return helperApi.getWechatServerIp();
1034 	}
1035 
1036 	/**
1037 	 * 获取企业号某个应用的基本信息,包括头像、昵称、帐号类型、认证类型、可见范围等信息
1038 	 *
1039 	 * @param agentid
1040 	 *            授权方应用id
1041 	 * @return 应用信息
1042 	 * @see com.foxinmy.weixin4j.qy.model.AgentInfo
1043 	 * @see com.foxinmy.weixin4j.qy.api.AgentApi
1044 	 * @see <a href= "https://work.weixin.qq.com/api/doc#10087"> 企业号应用的信息</a>
1045 	 * @throws WeixinException
1046 	 */
1047 	public AgentInfo getAgent(int agentid) throws WeixinException {
1048 		return agentApi.getAgent(agentid);
1049 	}
1050 
1051 	/**
1052 	 * 设置企业应用的选项设置信息,如:地理位置上报等
1053 	 *
1054 	 * @param agentSet
1055 	 *            设置参数
1056 	 * @see com.foxinmy.weixin4j.qy.model.AgentSetter
1057 	 * @see com.foxinmy.weixin4j.qy.api.AgentApi
1058 	 * @see <a href= "https://work.weixin.qq.com/api/doc#10088"> 设置企业号信息</a>
1059 	 * @return 处理结果
1060 	 * @throws WeixinException
1061 	 */
1062 	public ApiResult setAgent(AgentSetter agentSet) throws WeixinException {
1063 		return agentApi.setAgent(agentSet);
1064 	}
1065 
1066 	/**
1067 	 * 获取应用概况列表
1068 	 *
1069 	 * @see com.foxinmy.weixin4j.qy.model.AgentOverview
1070 	 * @see com.foxinmy.weixin4j.qy.api.AgentApi
1071 	 * @see <a href= "https://work.weixin.qq.com/api/doc#11214"> 获取应用概况</a>
1072 	 * @return 应用概况列表
1073 	 * @throws WeixinException
1074 	 */
1075 	public List<AgentOverview> listAgentOverview() throws WeixinException {
1076 		return agentApi.listAgentOverview();
1077 	}
1078 
1079 	/**
1080 	 * 批量邀请成员关注
1081 	 *
1082 	 * @param parameter
1083 	 *            成员ID,标签ID,部门ID
1084 	 * @param callback
1085 	 *            接收任务执行结果的回调地址等信息
1086 	 * @param tips
1087 	 *            推送到微信上的提示语(只有认证号可以使用)。当使用微信推送时,该字段默认为“请关注XXX企业号”,邮件邀请时,该字段无效。
1088 	 * @return 异步任务id,最大长度为64字符
1089 	 * @see com.foxinmy.weixin4j.qy.model.IdParameter
1090 	 * @see com.foxinmy.weixin4j.qy.model.Callback
1091 	 * @see com.foxinmy.weixin4j.qy.api.BatchApi
1092 	 * @see <a href=
1093 	 *      "http://qydev.weixin.qq.com/wiki/index.php?title=%E5%BC%82%E6%AD%A5%E4%BB%BB%E5%8A%A1%E6%8E%A5%E5%8F%A3#.E9.82.80.E8.AF.B7.E6.88.90.E5.91.98.E5.85.B3.E6.B3.A8">
1094 	 *      邀请成员关注</a>
1095 	 * @throws WeixinException
1096 	 */
1097 	public String batchInviteUser(IdParameter parameter, Callback callback,
1098 			String tips) throws WeixinException {
1099 		return batchApi.inviteUser(parameter, callback, tips);
1100 	}
1101 
1102 	/**
1103 	 * 批量更新成员,本接口以userid为主键,增量更新企业号通讯录成员。
1104 	 * <p>
1105 	 * 1.模板中的部门需填写部门ID,多个部门用分号分隔,部门ID必须为数字</br>
1106 	 * 2.文件中存在、通讯录中也存在的成员,更新成员在文件中指定的字段值 </br> 3.文件中存在、通讯录中不存在的成员,执行添加操作</br>
1107 	 * 4.通讯录中存在、文件中不存在的成员,保持不变</br>
1108 	 * </p>
1109 	 *
1110 	 * @param mediaId
1111 	 *            带user信息的cvs文件上传后的media_id
1112 	 * @param callback
1113 	 *            接收任务执行结果的回调地址等信息
1114 	 * @return 异步任务id,最大长度为64字符
1115 	 * @see com.foxinmy.weixin4j.qy.model.Callback
1116 	 * @see com.foxinmy.weixin4j.qy.api.BatchApi
1117 	 * @see <a href= "https://work.weixin.qq.com/api/doc#10138/增量更新成员">
1118 	 *      批量更新成员</a>
1119 	 * @throws WeixinException
1120 	 */
1121 	public String batchSyncUser(String mediaId, Callback callback)
1122 			throws WeixinException {
1123 		return batchApi.syncUser(mediaId, callback);
1124 	}
1125 
1126 	/**
1127 	 * 批量覆盖成员,本接口以userid为主键,全量覆盖企业号通讯录成员,任务完成后企业号通讯录成员与提交的文件完全保持一致。
1128 	 * <p>
1129 	 * 1.模板中的部门需填写部门ID,多个部门用分号分隔,部门ID必须为数字</br> 2.文件中存在、通讯录中也存在的成员,完全以文件为准</br>
1130 	 * 3.文件中存在、通讯录中不存在的成员,执行添加操作</br>
1131 	 * 4.通讯录中存在、文件中不存在的成员,执行删除操作。出于安全考虑,如果需要删除的成员多于50人,
1132 	 * 且多于现有人数的20%以上,系统将中止导入并返回相应的错误码
1133 	 * </p>
1134 	 *
1135 	 * @param mediaId
1136 	 *            带userid信息的cvs文件上传后的media_id
1137 	 * @param callback
1138 	 *            接收任务执行结果的回调地址等信息
1139 	 * @return 异步任务id,最大长度为64字符
1140 	 * @see com.foxinmy.weixin4j.qy.model.Callback
1141 	 * @see com.foxinmy.weixin4j.qy.api.BatchApi
1142 	 * @see <a href= "https://work.weixin.qq.com/api/doc#10138/全量覆盖成员">
1143 	 *      批量覆盖成员</a>
1144 	 * @throws WeixinException
1145 	 */
1146 	public String batchReplaceUser(String mediaId, Callback callback)
1147 			throws WeixinException {
1148 		return batchApi.replaceUser(mediaId, callback);
1149 	}
1150 
1151 	/**
1152 	 * 批量上传成员
1153 	 *
1154 	 * @param users
1155 	 *            成员列表
1156 	 * @see com.foxinmy.weixin4j.qy.api.MediaApi
1157 	 * @see com.foxinmy.weixin4j.qy.api.BatchApi
1158 	 * @see {@link #batchSyncUser(String,Callback)}
1159 	 * @see {@link #batchReplaceUser(String,Callback)}
1160 	 * @see <a href= "https://work.weixin.qq.com/api/doc#10138"> 批量任务</a>
1161 	 * @return 上传后的mediaId
1162 	 * @throws WeixinException
1163 	 */
1164 	public String batchUploadUsers(List<User> users) throws WeixinException {
1165 		return mediaApi.batchUploadUsers(users);
1166 	}
1167 
1168 	/**
1169 	 * 批量覆盖部门,本接口以partyid为键,全量覆盖企业号通讯录组织架构,任务完成后企业号通讯录组织架构与提交的文件完全保持一致。
1170 	 * <p>
1171 	 * 1.文件中存在、通讯录中也存在的部门,执行修改操作</br> 2.文件中存在、通讯录中不存在的部门,执行添加操作</br>
1172 	 * 3.文件中不存在、通讯录中存在的部门,当部门为空时,执行删除操作</br>
1173 	 * 4.CSV文件中,部门名称、部门ID、父部门ID为必填字段,部门ID必须为数字;排序为可选字段,置空或填0不修改排序
1174 	 * </p>
1175 	 *
1176 	 * @param mediaId
1177 	 *            带partyid信息的cvs文件上传后的media_id
1178 	 * @param callback
1179 	 *            接收任务执行结果的回调地址等信息
1180 	 * @return 异步任务id,最大长度为64字符
1181 	 * @see com.foxinmy.weixin4j.qy.model.Callback
1182 	 * @see com.foxinmy.weixin4j.qy.api.BatchApi
1183 	 * @see <a href= "https://work.weixin.qq.com/api/doc#10138/全量覆盖部门">
1184 	 *      批量覆盖部门</a>
1185 	 * @throws WeixinException
1186 	 */
1187 	public String batchReplaceParty(String mediaId, Callback callback)
1188 			throws WeixinException {
1189 		return batchApi.replaceParty(mediaId, callback);
1190 	}
1191 
1192 	/**
1193 	 * 获取异步任务执行的结果
1194 	 *
1195 	 * @param jobId
1196 	 *            任务ID
1197 	 * @return 效果信息
1198 	 * @see com.foxinmy.weixin4j.qy.model.BatchResult
1199 	 * @see com.foxinmy.weixin4j.qy.api.BatchApi
1200 	 * @see <a href=
1201 	 *      "http://qydev.weixin.qq.com/wiki/index.php?title=%E5%BC%82%E6%AD%A5%E4%BB%BB%E5%8A%A1%E6%8E%A5%E5%8F%A3#.E8.8E.B7.E5.8F.96.E5.BC.82.E6.AD.A5.E4.BB.BB.E5.8A.A1.E7.BB.93.E6.9E.9C">
1202 	 *      获取异步任务执行结果</a>
1203 	 * @throws WeixinException
1204 	 */
1205 	public BatchResult getBatchResult(String jobId) throws WeixinException {
1206 		return batchApi.getBatchResult(jobId);
1207 	}
1208 
1209 	/**
1210 	 * userid转换成openid:该接口使用场景为微信支付、微信红包和企业转账,企业号用户在使用微信支付的功能时,
1211 	 * 需要自行将企业号的userid转成openid。 在使用微信红包功能时,需要将应用id和userid转成appid和openid才能使用。
1212 	 *
1213 	 * @param userid
1214 	 *            企业号内的成员id 必填
1215 	 * @param agentid
1216 	 *            需要发送红包的应用ID,若只是使用微信支付和企业转账,则无需该参数 传入0或负数则忽略
1217 	 * @return 结果数组 第一个元素为对应的openid 第二个元素则为应用的appid(如果有)
1218 	 * @throws WeixinException
1219 	 * @see com.foxinmy.weixin4j.qy.api.UserApi
1220 	 * @see <a href= "https://work.weixin.qq.com/api/doc#11279">
1221 	 *      userid与openid互换</a>
1222 	 */
1223 	public String[] userid2openid(String userid, int agentid)
1224 			throws WeixinException {
1225 		return userApi.userid2openid(userid, agentid);
1226 	}
1227 
1228 	/**
1229 	 * openid转换成userid:该接口主要应用于使用微信支付、微信红包和企业转账之后的结果查询,
1230 	 * 开发者需要知道某个结果事件的openid对应企业号内成员的信息时,可以通过调用该接口进行转换查询。
1231 	 *
1232 	 * @param openid
1233 	 *            在使用微信支付、微信红包和企业转账之后,返回结果的openid
1234 	 * @return 该openid在企业号中对应的成员userid
1235 	 * @throws WeixinException
1236 	 * @see com.foxinmy.weixin4j.qy.api.UserApi
1237 	 * @see <a href= "https://work.weixin.qq.com/api/doc#11279">
1238 	 *      userid与openid互换</a>
1239 	 */
1240 	public String openid2userid(String openid) throws WeixinException {
1241 		return userApi.openid2userid(openid);
1242 	}
1243 
1244 	/**
1245 	 * 创建会话 <font color="red">如果会话id为空,程序会自动生成一个唯一ID</font>
1246 	 *
1247 	 * @param chatInfo
1248 	 *            会话信息
1249 	 * @return 会话ID
1250 	 * @see com.foxinmy.weixin4j.qy.api.ChatApi
1251 	 * @see com.foxinmy.weixin4j.qy.model.ChatInfo
1252 	 * @see <a href=
1253 	 *      "http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BC%81%E4%B8%9A%E5%8F%B7%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E#.E5.88.9B.E5.BB.BA.E4.BC.9A.E8.AF.9D">
1254 	 *      创建会话</a>
1255 	 * @throws WeixinException
1256 	 */
1257 	public String createChat(ChatInfo chatInfo) throws WeixinException {
1258 		return chatApi.createChat(chatInfo);
1259 	}
1260 
1261 	/**
1262 	 * 获取会话
1263 	 *
1264 	 * @param chatId
1265 	 *            会话ID
1266 	 * @return 会话信息
1267 	 * @see com.foxinmy.weixin4j.qy.api.ChatApi
1268 	 * @see com.foxinmy.weixin4j.qy.model.ChatInfo
1269 	 * @see <a href=
1270 	 *      "http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BC%81%E4%B8%9A%E5%8F%B7%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E#.E8.8E.B7.E5.8F.96.E4.BC.9A.E8.AF.9D">
1271 	 *      获取会话</a>
1272 	 * @throws WeixinException
1273 	 */
1274 	public ChatInfo getChat(String chatId) throws WeixinException {
1275 		return chatApi.getChat(chatId);
1276 	}
1277 
1278 	/**
1279 	 * 更新会话
1280 	 *
1281 	 * @param chatInfo
1282 	 *            会话信息 至少保持会话ID不能为空
1283 	 * @param operator
1284 	 *            操作人userid
1285 	 * @param addUsers
1286 	 *            会话新增成员列表
1287 	 * @param deleteUsers
1288 	 *            会话退出成员列表
1289 	 * @return 处理结果
1290 	 * @see com.foxinmy.weixin4j.qy.api.ChatApi
1291 	 * @see com.foxinmy.weixin4j.qy.model.ChatInfo
1292 	 * @see <a href=
1293 	 *      "http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BC%81%E4%B8%9A%E5%8F%B7%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E#.E4.BF.AE.E6.94.B9.E4.BC.9A.E8.AF.9D.E4.BF.A1.E6.81.AF">
1294 	 *      修改会话信息</a>
1295 	 * @throws WeixinException
1296 	 */
1297 	public ApiResult updateChat(ChatInfo chatInfo, String operator,
1298 			List<String> addUsers, List<String> deleteUsers)
1299 			throws WeixinException {
1300 		return chatApi.updateChat(chatInfo, operator, addUsers, deleteUsers);
1301 	}
1302 
1303 	/**
1304 	 * 退出会话
1305 	 *
1306 	 * @param chatId
1307 	 *            会话ID
1308 	 * @param operator
1309 	 *            操作人userid
1310 	 * @return 处理结果
1311 	 * @see com.foxinmy.weixin4j.qy.api.ChatApi
1312 	 * @see <a href=
1313 	 *      "http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BC%81%E4%B8%9A%E5%8F%B7%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E#.E9.80.80.E5.87.BA.E4.BC.9A.E8.AF.9D">
1314 	 *      退出会话</a>
1315 	 * @throws WeixinException
1316 	 */
1317 	public ApiResult quitChat(String chatId, String operator)
1318 			throws WeixinException {
1319 		return chatApi.quitChat(chatId, operator);
1320 	}
1321 
1322 	/**
1323 	 * 清除会话未读状态
1324 	 *
1325 	 * @param targetId
1326 	 *            会话值,为userid|chatid,分别表示:成员id|会话id
1327 	 * @param owner
1328 	 *            会话所有者的userid
1329 	 * @param chatType
1330 	 *            会话类型:single|group,分别表示:群聊|单聊
1331 	 * @return 处理结果
1332 	 * @see com.foxinmy.weixin4j.qy.api.ChatApi
1333 	 * @see <a href=
1334 	 *      "http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BC%81%E4%B8%9A%E5%8F%B7%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E#.E6.B8.85.E9.99.A4.E4.BC.9A.E8.AF.9D.E6.9C.AA.E8.AF.BB.E7.8A.B6.E6.80.81">
1335 	 *      清除会话未读状态</a>
1336 	 * @throws WeixinException
1337 	 */
1338 	public ApiResult clearChatNotify(String targetId, String owner,
1339 			ChatType chatType) throws WeixinException {
1340 		return chatApi.clearChatNotify(targetId, owner, chatType);
1341 	}
1342 
1343 	/**
1344 	 * 设置成员接收到的消息是否提醒。主要场景是用于对接企业im的在线状态,如成员处于在线状态时,可以设置该成员的消息免打扰。当成员离线时,关闭免打扰状态
1345 	 * ,对微信端进行提醒。
1346 	 *
1347 	 * @param chatMutes
1348 	 *            提醒参数
1349 	 * @see com.foxinmy.weixin4j.qy.api.ChatApi
1350 	 * @see com.foxinmy.weixin4j.qy.model.ChatMute
1351 	 * @see <a href=
1352 	 *      "http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BC%81%E4%B8%9A%E5%8F%B7%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E#.E8.AE.BE.E7.BD.AE.E6.88.90.E5.91.98.E6.96.B0.E6.B6.88.E6.81.AF.E5.85.8D.E6.89.93.E6.89.B0"
1353 	 *      >设置成员新消息免打扰</a>
1354 	 * @return 列表中不存在的成员,剩余合法成员会继续执行。
1355 	 * @throws WeixinException
1356 	 */
1357 	public List<String> setChatMute(List<ChatMute> chatMutes)
1358 			throws WeixinException {
1359 		return chatApi.setChatMute(chatMutes);
1360 	}
1361 
1362 	/**
1363 	 * 发送会话消息
1364 	 *
1365 	 * @param message
1366 	 *            消息对象
1367 	 * @return 处理结果
1368 	 * @see com.foxinmy.weixin4j.qy.api.ChatApi
1369 	 * @see com.foxinmy.weixin4j.qy.message.ChatMessage
1370 	 * @see <a href=
1371 	 *      "http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BC%81%E4%B8%9A%E5%8F%B7%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E#.E5.8F.91.E6.B6.88.E6.81.AF">
1372 	 *      发送消息</a>
1373 	 * @throws WeixinException
1374 	 */
1375 	public ApiResult sendChatMessage(ChatMessage message)
1376 			throws WeixinException {
1377 		return chatApi.sendChatMessage(message);
1378 	}
1379 
1380 	public final static String VERSION = Consts.VERSION;
1381 }