| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441 |
- package com.usoftchina.qywx.sdk;
- import com.usoftchina.qywx.sdk.config.Agent;
- import com.usoftchina.qywx.sdk.config.QywxProperties;
- import com.usoftchina.qywx.sdk.dto.*;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.http.ResponseEntity;
- import org.springframework.ui.ModelMap;
- import org.springframework.util.CollectionUtils;
- import org.springframework.util.StringUtils;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.concurrent.atomic.AtomicReference;
- /**
- * 通讯录管理
- *
- * @author yingp
- */
- public class AddrBookSdk extends BaseSdk {
- /**
- * 通讯录管理私钥
- * <p>使用应用secret只能进行“查询”、“邀请”等非写操作,而且只能操作应用可见范围内的通讯录</p>
- */
- public final static String ADDRESS_BOOK_AGENT_CODE = "AddressBook";
- private final Logger logger = LoggerFactory.getLogger(AddrBookSdk.class);
- public AddrBookSdk(QywxProperties properties) {
- super(properties);
- }
- /**
- * 是否启用
- *
- * @return
- */
- public boolean enabled() {
- Agent agent = getAgentMap().get(ADDRESS_BOOK_AGENT_CODE);
- return null != agent && null != agent.getSecret();
- }
- /**
- * sdk是否只有读权限
- *
- * @return
- */
- public boolean isReadonly() {
- return enabled() && getAgentMap().get(ADDRESS_BOOK_AGENT_CODE).isReadonly();
- }
- /**
- * 创建成员
- *
- * @param req
- */
- public void createUser(CreateUserReq req) {
- tryAndIgnoreSystemError(() ->
- restTemplate.postForEntity(baseUrl + "/cgi-bin/user/create?access_token={access_token}",
- req.build(), BaseResp.class,
- new ModelMap("access_token", getAccessToken(ADDRESS_BOOK_AGENT_CODE)))
- );
- }
- /**
- * 读取成员
- *
- * @param userId 成员UserID。对应管理端的帐号,企业内必须唯一。不区分大小写,长度为1~64个字节
- */
- public GetUserResp getUser(String userId) {
- ResponseEntity<GetUserResp> resp = restTemplate.getForEntity(baseUrl + "/cgi-bin/user/get?access_token={access_token}&userid={userid}",
- GetUserResp.class,
- new ModelMap("access_token", getAccessToken(ADDRESS_BOOK_AGENT_CODE)).addAttribute("userid", userId));
- assertOK(resp);
- return resp.getBody();
- }
- /**
- * 更新成员
- *
- * @param req
- */
- public void updateUser(UpdateUserReq req) {
- tryAndIgnoreSystemError(() ->
- restTemplate.postForEntity(baseUrl + "/cgi-bin/user/update?access_token={access_token}",
- req.build(), BaseResp.class,
- new ModelMap("access_token", getAccessToken(ADDRESS_BOOK_AGENT_CODE)))
- );
- }
- /**
- * 删除成员
- *
- * @param userId 成员UserID。对应管理端的帐号
- */
- public void deleteUser(String userId) {
- tryAndIgnoreSystemError(() ->
- restTemplate.getForEntity(baseUrl + "/cgi-bin/user/delete?access_token={access_token}&userid={userid}",
- BaseResp.class,
- new ModelMap("access_token", getAccessToken(ADDRESS_BOOK_AGENT_CODE)).addAttribute("userid", userId))
- );
- }
- /**
- * 批量删除成员
- *
- * @param userIdList 成员UserID列表。对应管理端的帐号。最多支持200个。若存在无效UserID,直接返回错误
- */
- public void deleteUser(List<String> userIdList) {
- tryAndIgnoreSystemError(() ->
- restTemplate.postForEntity(baseUrl + "/cgi-bin/user/batchdelete?access_token={access_token}",
- new ModelMap("useridlist", userIdList),
- BaseResp.class,
- new ModelMap("access_token", getAccessToken(ADDRESS_BOOK_AGENT_CODE)))
- );
- }
- /**
- * 获取部门成员
- *
- * @param departmentId 部门ID
- * @param fetchChild 是否递归获取子部门下面的成员:1-递归获取,0-只获取本部门
- * 企业微信升级,方法不可用
- */
- @Deprecated
- public List<GetSimpleUserListResp.User> getSimpleUserList(Integer departmentId, boolean fetchChild) {
- ResponseEntity<GetSimpleUserListResp> resp = restTemplate.getForEntity(baseUrl + "/cgi-bin/user/simplelist?access_token={access_token}&department_id={department_id}&fetch_child={fetch_child}",
- GetSimpleUserListResp.class,
- new ModelMap("access_token", getAccessToken(ADDRESS_BOOK_AGENT_CODE))
- .addAttribute("department_id", departmentId)
- .addAttribute("fetch_child", fetchChild ? 1 : 0));
- assertOK(resp);
- return resp.getBody().getUserlist();
- }
- /**
- * 获取部门成员详情
- *
- * @param departmentId 部门ID
- * @param fetchChild 是否递归获取子部门下面的成员:1-递归获取,0-只获取本部门
- * 企业微信升级,方法不可用
- * @return
- */
- @Deprecated
- public List<GetUserListResp.User> getUserList(Integer departmentId, boolean fetchChild) {
- ResponseEntity<GetUserListResp> resp = restTemplate.getForEntity(baseUrl + "/cgi-bin/user/list?access_token={access_token}&department_id={department_id}&fetch_child={fetch_child}",
- GetUserListResp.class,
- new ModelMap("access_token", getAccessToken(ADDRESS_BOOK_AGENT_CODE))
- .addAttribute("department_id", departmentId)
- .addAttribute("fetch_child", fetchChild ? 1 : 0));
- assertOK(resp);
- return resp.getBody().getUserlist();
- }
- /**
- * 获取部门成员详情
- * @param cursor 用于分页查询的游标,字符串类型,由上一次调用返回,首次调用不填
- * limit 分页,预期请求的数据量,取值范围 1 ~ 10000 默认10000
- * @return
- */
- public List<GetSimpleUserIDListResp.User> getUserIdList(List<GetSimpleUserIDListResp.User> userList,String cursor) {
- ResponseEntity<GetSimpleUserIDListResp> resp = restTemplate.getForEntity(baseUrl + "/cgi-bin/user/list_id?access_token={access_token}&cursor={cursor}&limit={limit}",
- GetSimpleUserIDListResp.class,
- new ModelMap("access_token", getAccessToken(ADDRESS_BOOK_AGENT_CODE))
- .addAttribute("cursor", cursor)
- .addAttribute("limit", 10000));
- assertOK(resp);
- if(StringUtils.hasText(resp.getBody().getNext_cursor())){
- System.out.println("Next_cursor:"+resp.getBody().getNext_cursor());
- return getUserIdList(resp.getBody().getDept_user(),resp.getBody().getNext_cursor());
- }else {
- userList.addAll(resp.getBody().getDept_user());
- return userList;
- }
- }
- /**
- * userid转openid
- * <p>该接口使用场景为企业支付,在使用企业红包和向员工付款时,需要自行将企业微信的userid转成openid。</p>
- *
- * @param userId
- * @return
- */
- public String getOpenId(String userId) {
- ResponseEntity<GetOpenIdResp> resp = restTemplate.postForEntity(baseUrl + "/cgi-bin/user/convert_to_openid?access_token={access_token}",
- new ModelMap("userid", userId),
- GetOpenIdResp.class,
- new ModelMap("access_token", getAccessToken(ADDRESS_BOOK_AGENT_CODE)));
- assertOK(resp);
- return resp.getBody().getOpenid();
- }
- /**
- * 二次验证
- * <p>
- * 企业在开启二次验证时,必须在管理端填写企业二次验证页面的url。
- * 当成员登录企业微信或关注微工作台(原企业号)加入企业时,会自动跳转到企业的验证页面。在跳转到企业的验证页面时,会带上如下参数:code=CODE。
- * 企业收到code后,使用“通讯录同步助手”调用接口“根据code获取成员信息”获取成员的userid。然后在验证成员信息成功后,调用如下接口即可让成员成功加入企业
- * </p>
- *
- * @param userId
- */
- public void authSuccess(String userId) {
- ResponseEntity<BaseResp> resp = restTemplate.getForEntity(baseUrl + "/cgi-bin/user/authsucc?access_token={access_token}&userid={userid}",
- BaseResp.class,
- new ModelMap("access_token", getAccessToken(ADDRESS_BOOK_AGENT_CODE))
- .addAttribute("userid", userId));
- assertOK(resp);
- }
- /**
- * 邀请成员
- * <p>企业可通过接口批量邀请成员使用企业微信,邀请后将通过短信或邮件下发通知</p>
- *
- * @param req
- */
- public InviteResp invite(InviteReq req) {
- ResponseEntity<InviteResp> resp = restTemplate.postForEntity(baseUrl + "/cgi-bin/batch/invite?access_token={access_token}",
- req.build(), InviteResp.class,
- new ModelMap("access_token", getAccessToken(ADDRESS_BOOK_AGENT_CODE)));
- assertOK(resp);
- return resp.getBody();
- }
- /**
- * 获取加入企业二维码
- *
- * @param type 尺寸
- * @return 二维码链接,有效期7天
- */
- public String getJoinQrCode(QrCodeType type) {
- ResponseEntity<GetJoinQrCodeResp> resp = restTemplate.getForEntity(baseUrl + "/cgi-bin/corp/get_join_qrcode?access_token={access_token}&size_type={size_type}",
- GetJoinQrCodeResp.class,
- new ModelMap("access_token", getAccessToken(ADDRESS_BOOK_AGENT_CODE))
- .addAttribute("size_type", type.code));
- assertOK(resp);
- return resp.getBody().getJoin_qrcode();
- }
- /**
- * qrcode尺寸类型
- */
- public enum QrCodeType {
- T_171_171(1),
- T_399_399(2),
- T_741_741(3),
- T_2052_2052(4);
- private final int code;
- QrCodeType(int code) {
- this.code = code;
- }
- public int getCode() {
- return code;
- }
- }
- /**
- * 创建部门
- *
- * @param req
- * @return 部门ID
- */
- public Integer createDepartment(CreateDepartmentReq req) {
- ResponseEntity<CreateDepartmentResp> resp = tryAndIgnoreSystemError(() ->
- restTemplate.postForEntity(baseUrl + "/cgi-bin/department/create?access_token={access_token}",
- req.build(), CreateDepartmentResp.class,
- new ModelMap("access_token", getAccessToken(ADDRESS_BOOK_AGENT_CODE)))
- );
- return null == resp ? null : resp.getBody().getId();
- }
- /**
- * 更新部门
- *
- * @param req
- */
- public void updateDepartment(UpdateDepartmentReq req) {
- tryAndIgnoreSystemError(() ->
- restTemplate.postForEntity(baseUrl + "/cgi-bin/department/update?access_token={access_token}",
- req.build(), BaseResp.class,
- new ModelMap("access_token", getAccessToken(ADDRESS_BOOK_AGENT_CODE)))
- );
- }
- /**
- * 删除部门
- *
- * @param departmentId
- */
- public void deleteDepartment(int departmentId) {
- tryAndIgnoreSystemError(() ->
- restTemplate.getForEntity(baseUrl + "/cgi-bin/department/delete?access_token={access_token}&id={id}",
- BaseResp.class,
- new ModelMap("access_token", getAccessToken(ADDRESS_BOOK_AGENT_CODE))
- .addAttribute("id", departmentId))
- );
- }
- /**
- * 获取部门
- * 企业微信升级,方法不可用
- * @param departmentId
- * @return
- */
- @Deprecated
- public GetDepartmentListResp.Department getDepartment(int departmentId) {
- List<GetDepartmentListResp.Department> departmentList = getDepartmentList(departmentId);
- if (!CollectionUtils.isEmpty(departmentList)) {
- for (GetDepartmentListResp.Department department : departmentList) {
- if (department.getId().equals(departmentId)) {
- return department;
- }
- }
- }
- return null;
- }
- /**
- * 获取部门,包括下级
- * 企业微信升级,方法不可用
- * @param departmentId
- * @return
- */
- @Deprecated
- public List<GetDepartmentListResp.Department> getDepartmentList(int departmentId) {
- ResponseEntity<GetDepartmentListResp> resp = restTemplate.getForEntity(baseUrl + "/cgi-bin/department/list?access_token={access_token}&id={id}",
- GetDepartmentListResp.class,
- new ModelMap("access_token", getAccessToken(ADDRESS_BOOK_AGENT_CODE))
- .addAttribute("id", departmentId));
- assertOK(resp);
- if (!CollectionUtils.isEmpty(resp.getBody().getDepartment())) {
- return resp.getBody().getDepartment();
- }
- return null;
- }
- /**
- * 获取部门列表
- * 企业微信升级,方法不可用
- * @return
- */
- @Deprecated
- public List<GetDepartmentListResp.Department> getDepartmentList() {
- ResponseEntity<GetDepartmentListResp> resp = restTemplate.getForEntity(baseUrl + "/cgi-bin/department/list?access_token={access_token}",
- GetDepartmentListResp.class,
- new ModelMap("access_token", getAccessToken(ADDRESS_BOOK_AGENT_CODE)));
- assertOK(resp);
- return resp.getBody().getDepartment();
- }
- /**
- * 获取部门列表
- *
- * @return
- */
- public List<GetDepartmentSimpleListResp.Department> getSimpleDepartmentList() {
- ResponseEntity<GetDepartmentSimpleListResp> resp = restTemplate.getForEntity(baseUrl + "/cgi-bin/department/simplelist?access_token={access_token}&id={id}",
- GetDepartmentSimpleListResp.class,
- new ModelMap("access_token", getAccessToken(ADDRESS_BOOK_AGENT_CODE))
- .addAttribute("id", 0));
- assertOK(resp);
- return resp.getBody().getDepartment_id();
- }
- /**
- * 获取部门列表
- *
- * @return
- */
- public List<GetDepartmentSimpleListResp.Department> getSimpleDepartmentList(Integer departmentId) {
- ResponseEntity<GetDepartmentSimpleListResp> resp = restTemplate.getForEntity(baseUrl + "/cgi-bin/department/simplelist?access_token={access_token}&id={id}",
- GetDepartmentSimpleListResp.class,
- new ModelMap("access_token", getAccessToken(ADDRESS_BOOK_AGENT_CODE))
- .addAttribute("id", departmentId));
- assertOK(resp);
- return resp.getBody().getDepartment_id();
- }
- /**
- * 获取访问用户身份
- *
- * @param agentCode 应用编号
- * @param code 授权码
- */
- public GetUserInfoResp getUserInfo(String agentCode, String code) {
- ResponseEntity<GetUserInfoResp> resp = restTemplate.getForEntity(baseUrl + "/cgi-bin/user/getuserinfo?access_token={access_token}&code={code}",
- GetUserInfoResp.class,
- new ModelMap("access_token", getAccessToken(agentCode))
- .addAttribute("code", code));
- assertOK(resp);
- return resp.getBody();
- }
- /**
- * 获取用户UserID
- *
- * @param mobile 手机号
- * */
- public GetUserInfoResp getUserInfoByMobile(String mobile) {
- ResponseEntity<GetUserInfoResp> resp = restTemplate.postForEntity(baseUrl + "/cgi-bin/user/getuserid?access_token={access_token}&debug=1",
- new ModelMap("mobile", mobile),
- GetUserInfoResp.class,
- new ModelMap("access_token", getAccessToken(ADDRESS_BOOK_AGENT_CODE)));
- return resp.getBody();
- }
- /**
- * 获取用户openid
- * access_token 代开发企业应用的access_token
- * */
- public GetUserOpenIDListResp convert_openUserId(List<String> userList) {
- logger.info("convert_openUserId:{}",String.join("," , userList));
- ResponseEntity<GetUserOpenIDListResp> resp = restTemplate.postForEntity(
- baseUrl + "/cgi-bin/batch/userid_to_openuserid?access_token={access_token}",
- new ModelMap("userid_list", userList),
- GetUserOpenIDListResp.class,
- new ModelMap("access_token", getAccessToken(null)));
- logger.info("convert_openUserId--:{}",resp.getBody());
- assertOK(resp);
- return resp.getBody();
- }
- /**
- * 以下接口仅能获取企业内部openuserid
- * */
- /* public List<GetUserOpenIDListResp.OpenUser> convert_openUserId(List<String> userList) {
- List<GetUserOpenIDListResp.OpenUser> openUsers = new ArrayList<>();
- for(String userId : userList) {
- try {
- GetUserOpenIDListResp.OpenUser openUser = new GetUserOpenIDListResp.OpenUser();
- openUser.setUserid(userId);
- openUser.setOpen_userid(getOpenId(userId));
- openUsers.add(openUser);
- } catch (Exception e) {
- logger.error("转换用户ID失败: {}", userId, e);
- // 失败时仍保留用户ID,但openid为null
- GetUserOpenIDListResp.OpenUser openUser = new GetUserOpenIDListResp.OpenUser();
- openUser.setUserid(userId);
- openUsers.add(openUser);
- }
- }
- return openUsers;
- }*/
- }
|