@@ -133,46 +133,47 @@ public interface WxCpService { | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 分组管理接口 - 创建分组 | |||||
* 最多支持创建500个分组 | |||||
* 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=分组管理接口 | |||||
* 部门管理接口 - 创建部门 | |||||
* 最多支持创建500个部门 | |||||
* 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=部门管理接口 | |||||
* </pre> | * </pre> | ||||
* @param name 分组名字(30个字符以内) | |||||
* @param depart 部门 | |||||
* @return 部门id | |||||
* @throws WxErrorException | * @throws WxErrorException | ||||
*/ | */ | ||||
public WxCpDepart departmentCreate(String name) throws WxErrorException; | |||||
public Integer departCreate(WxCpDepart depart) throws WxErrorException; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 分组管理接口 - 查询所有分组 | |||||
* 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=分组管理接口 | |||||
* 部门管理接口 - 查询所有部门 | |||||
* 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=部门管理接口 | |||||
* </pre> | * </pre> | ||||
* @return | * @return | ||||
* @throws WxErrorException | * @throws WxErrorException | ||||
*/ | */ | ||||
public List<WxCpDepart> departmentGet() throws WxErrorException; | |||||
public List<WxCpDepart> departGet() throws WxErrorException; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 分组管理接口 - 修改分组名 | |||||
* 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=分组管理接口 | |||||
* 部门管理接口 - 修改部门名 | |||||
* 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=部门管理接口 | |||||
* | * | ||||
* 如果id为0(未分组),1(黑名单),2(星标组),或者不存在的id,微信会返回系统繁忙的错误 | |||||
* 如果id为0(未部门),1(黑名单),2(星标组),或者不存在的id,微信会返回系统繁忙的错误 | |||||
* </pre> | * </pre> | ||||
* @param group 要更新的group,group的id,name必须设置 | * @param group 要更新的group,group的id,name必须设置 | ||||
* @throws WxErrorException | * @throws WxErrorException | ||||
*/ | */ | ||||
public void departmentUpdate(WxCpDepart group) throws WxErrorException; | |||||
public void departUpdate(WxCpDepart group) throws WxErrorException; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 部门管理接口 - 删除部门 | * 部门管理接口 - 删除部门 | ||||
* | * | ||||
* </pre> | * </pre> | ||||
* @param department | |||||
* @param departId | |||||
* @throws WxErrorException | * @throws WxErrorException | ||||
*/ | */ | ||||
public void departmentDelete(WxCpDepart department) throws WxErrorException; | |||||
public void departDelete(Integer departId) throws WxErrorException; | |||||
public void userCreate(WxUser user) throws WxErrorException; | public void userCreate(WxUser user) throws WxErrorException; | ||||
@@ -9,6 +9,7 @@ import java.util.UUID; | |||||
import java.util.concurrent.atomic.AtomicBoolean; | import java.util.concurrent.atomic.AtomicBoolean; | ||||
import me.chanjar.weixin.common.bean.WxAccessToken; | import me.chanjar.weixin.common.bean.WxAccessToken; | ||||
import me.chanjar.weixin.common.util.GsonHelper; | |||||
import me.chanjar.weixin.enterprise.bean.*; | import me.chanjar.weixin.enterprise.bean.*; | ||||
import me.chanjar.weixin.enterprise.util.http.SimpleGetRequestExecutor; | import me.chanjar.weixin.enterprise.util.http.SimpleGetRequestExecutor; | ||||
import me.chanjar.weixin.enterprise.util.crypto.SHA1; | import me.chanjar.weixin.enterprise.util.crypto.SHA1; | ||||
@@ -147,30 +148,28 @@ public class WxCpServiceImpl implements WxCpService { | |||||
} | } | ||||
public WxCpDepart departmentCreate(String name) throws WxErrorException { | |||||
// TODO | |||||
String url = "https://api.weixin.qq.com/cgi-bin/groups/create"; | |||||
JsonObject json = new JsonObject(); | |||||
JsonObject groupJson = new JsonObject(); | |||||
json.add("group", groupJson); | |||||
groupJson.addProperty("name", name); | |||||
public Integer departCreate(WxCpDepart depart) throws WxErrorException { | |||||
String url = "https://qyapi.weixin.qq.com/cgi-bin/department/create"; | |||||
String responseContent = execute( | String responseContent = execute( | ||||
new SimplePostRequestExecutor(), | new SimplePostRequestExecutor(), | ||||
url, | url, | ||||
json.toString()); | |||||
return WxCpDepart.fromJson(responseContent); | |||||
depart.toJson()); | |||||
JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); | |||||
return GsonHelper.getAsInteger(tmpJsonElement.getAsJsonObject().get("id")); | |||||
} | } | ||||
public void departmentUpdate(WxCpDepart group) throws WxErrorException { | |||||
// TODO | |||||
String url = "https://api.weixin.qq.com/cgi-bin/groups/update"; | |||||
public void departUpdate(WxCpDepart group) throws WxErrorException { | |||||
String url = "https://qyapi.weixin.qq.com/cgi-bin/department/update"; | |||||
execute(new SimplePostRequestExecutor(), url, group.toJson()); | execute(new SimplePostRequestExecutor(), url, group.toJson()); | ||||
} | } | ||||
public List<WxCpDepart> departmentGet() throws WxErrorException { | |||||
// TODO | |||||
String url = "https://api.weixin.qq.com/cgi-bin/groups/get"; | |||||
public void departDelete(Integer departId) throws WxErrorException { | |||||
String url = "https://qyapi.weixin.qq.com/cgi-bin/department/delete?id=" + departId; | |||||
String responseContent = execute(new SimpleGetRequestExecutor(), url, null); | |||||
} | |||||
public List<WxCpDepart> departGet() throws WxErrorException { | |||||
String url = "https://qyapi.weixin.qq.com/cgi-bin/department/list"; | |||||
String responseContent = execute(new SimpleGetRequestExecutor(), url, null); | String responseContent = execute(new SimpleGetRequestExecutor(), url, null); | ||||
/* | /* | ||||
* 操蛋的微信API,创建时返回的是 { group : { id : ..., name : ...} } | * 操蛋的微信API,创建时返回的是 { group : { id : ..., name : ...} } | ||||
@@ -178,13 +177,10 @@ public class WxCpServiceImpl implements WxCpService { | |||||
*/ | */ | ||||
JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); | JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); | ||||
return WxCpGsonBuilder.INSTANCE.create() | return WxCpGsonBuilder.INSTANCE.create() | ||||
.fromJson(tmpJsonElement.getAsJsonObject().get("groups"), new TypeToken<List<WxCpDepart>>() { | |||||
}.getType()); | |||||
} | |||||
public void departmentDelete(WxCpDepart department) throws WxErrorException { | |||||
// TODO | |||||
.fromJson( | |||||
tmpJsonElement.getAsJsonObject().get("department"), | |||||
new TypeToken<List<WxCpDepart>>() { }.getType() | |||||
); | |||||
} | } | ||||
@Override | @Override | ||||
@@ -4,33 +4,52 @@ import me.chanjar.weixin.enterprise.util.json.WxCpGsonBuilder; | |||||
/** | /** | ||||
* 微信部门 | * 微信部门 | ||||
* @author Daniel Qian | |||||
* | * | ||||
* @author Daniel Qian | |||||
*/ | */ | ||||
public class WxCpDepart { | public class WxCpDepart { | ||||
private long id = -1; | |||||
private Integer id; | |||||
private String name; | private String name; | ||||
private long parentId; | |||||
private long order; | |||||
private Integer parentId; | |||||
private Integer order; | |||||
public long getId() { | |||||
public Integer getId() { | |||||
return id; | return id; | ||||
} | } | ||||
public void setId(long id) { | |||||
public void setId(Integer id) { | |||||
this.id = id; | this.id = id; | ||||
} | } | ||||
public String getName() { | public String getName() { | ||||
return name; | return name; | ||||
} | } | ||||
public void setName(String name) { | public void setName(String name) { | ||||
this.name = name; | this.name = name; | ||||
} | } | ||||
public Integer getParentId() { | |||||
return parentId; | |||||
} | |||||
public void setParentId(Integer parentId) { | |||||
this.parentId = parentId; | |||||
} | |||||
public Integer getOrder() { | |||||
return order; | |||||
} | |||||
public void setOrder(Integer order) { | |||||
this.order = order; | |||||
} | |||||
public static WxCpDepart fromJson(String json) { | public static WxCpDepart fromJson(String json) { | ||||
return WxCpGsonBuilder.create().fromJson(json, WxCpDepart.class); | return WxCpGsonBuilder.create().fromJson(json, WxCpDepart.class); | ||||
} | } | ||||
public String toJson() { | public String toJson() { | ||||
return WxCpGsonBuilder.create().toJson(this); | return WxCpGsonBuilder.create().toJson(this); | ||||
} | } | ||||
@@ -13,93 +13,6 @@ import me.chanjar.weixin.enterprise.util.json.WxCpGsonBuilder; | |||||
*/ | */ | ||||
public class WxError { | public class WxError { | ||||
protected static final Map<Integer, String> errMap = new HashMap<Integer, String>(); | |||||
static { | |||||
errMap.put(-1, "系统繁忙"); | |||||
errMap.put(0, "请求成功"); | |||||
errMap.put(40001, "获取access_token时AppSecret错误,或者access_token无效"); | |||||
errMap.put(40002, "不合法的凭证类型"); | |||||
errMap.put(40003, "不合法的OpenID"); | |||||
errMap.put(40004, "不合法的媒体文件类型"); | |||||
errMap.put(40005, "不合法的文件类型"); | |||||
errMap.put(40006, "不合法的文件大小"); | |||||
errMap.put(40007, "不合法的媒体文件id"); | |||||
errMap.put(40008, "不合法的消息类型"); | |||||
errMap.put(40009, "不合法的图片文件大小"); | |||||
errMap.put(40010, "不合法的语音文件大小"); | |||||
errMap.put(40011, "不合法的视频文件大小"); | |||||
errMap.put(40012, "不合法的缩略图文件大小"); | |||||
errMap.put(40013, "不合法的APPID"); | |||||
errMap.put(40014, "不合法的access_token"); | |||||
errMap.put(40015, "不合法的菜单类型"); | |||||
errMap.put(40016, "不合法的按钮个数"); | |||||
errMap.put(40017, "不合法的按钮个数"); | |||||
errMap.put(40018, "不合法的按钮名字长度"); | |||||
errMap.put(40019, "不合法的按钮KEY长度"); | |||||
errMap.put(40020, "不合法的按钮URL长度"); | |||||
errMap.put(40021, "不合法的菜单版本号"); | |||||
errMap.put(40022, "不合法的子菜单级数"); | |||||
errMap.put(40023, "不合法的子菜单按钮个数"); | |||||
errMap.put(40024, "不合法的子菜单按钮类型"); | |||||
errMap.put(40025, "不合法的子菜单按钮名字长度"); | |||||
errMap.put(40026, "不合法的子菜单按钮KEY长度"); | |||||
errMap.put(40027, "不合法的子菜单按钮URL长度"); | |||||
errMap.put(40028, "不合法的自定义菜单使用用户"); | |||||
errMap.put(40029, "不合法的oauth_code"); | |||||
errMap.put(40030, "不合法的refresh_token"); | |||||
errMap.put(40031, "不合法的openid列表"); | |||||
errMap.put(40032, "不合法的openid列表长度"); | |||||
errMap.put(40033, "不合法的请求字符,不能包含\\uxxxx格式的字符"); | |||||
errMap.put(40035, "不合法的参数"); | |||||
errMap.put(40038, "不合法的请求格式"); | |||||
errMap.put(40039, "不合法的URL长度"); | |||||
errMap.put(40050, "不合法的分组id"); | |||||
errMap.put(40051, "分组名字不合法"); | |||||
errMap.put(41001, "缺少access_token参数"); | |||||
errMap.put(41002, "缺少appid参数"); | |||||
errMap.put(41003, "缺少refresh_token参数"); | |||||
errMap.put(41004, "缺少secret参数"); | |||||
errMap.put(41005, "缺少多媒体文件数据"); | |||||
errMap.put(41006, "缺少media_id参数"); | |||||
errMap.put(41007, "缺少子菜单数据"); | |||||
errMap.put(41008, "缺少oauth code"); | |||||
errMap.put(41009, "缺少openid"); | |||||
errMap.put(42001, "access_token超时"); | |||||
errMap.put(42002, "refresh_token超时"); | |||||
errMap.put(42003, "oauth_code超时"); | |||||
errMap.put(43001, "需要GET请求"); | |||||
errMap.put(43002, "需要POST请求"); | |||||
errMap.put(43003, "需要HTTPS请求"); | |||||
errMap.put(43004, "需要接收者关注"); | |||||
errMap.put(43005, "需要好友关系"); | |||||
errMap.put(44001, "多媒体文件为空"); | |||||
errMap.put(44002, "POST的数据包为空"); | |||||
errMap.put(44003, "图文消息内容为空"); | |||||
errMap.put(44004, "文本消息内容为空"); | |||||
errMap.put(45001, "多媒体文件大小超过限制"); | |||||
errMap.put(45002, "消息内容超过限制"); | |||||
errMap.put(45003, "标题字段超过限制"); | |||||
errMap.put(45004, "描述字段超过限制"); | |||||
errMap.put(45005, "链接字段超过限制"); | |||||
errMap.put(45006, "图片链接字段超过限制"); | |||||
errMap.put(45007, "语音播放时间超过限制"); | |||||
errMap.put(45008, "图文消息超过限制"); | |||||
errMap.put(45009, "接口调用超过限制"); | |||||
errMap.put(45010, "创建菜单个数超过限制"); | |||||
errMap.put(45015, "回复时间超过限制"); | |||||
errMap.put(45016, "系统分组,不允许修改"); | |||||
errMap.put(45017, "分组名字过长"); | |||||
errMap.put(45018, "分组数量超过上限"); | |||||
errMap.put(46001, "不存在媒体数据"); | |||||
errMap.put(46002, "不存在的菜单版本"); | |||||
errMap.put(46003, "不存在的菜单数据"); | |||||
errMap.put(46004, "不存在的用户"); | |||||
errMap.put(47001, "解析JSON/XML内容错误"); | |||||
errMap.put(48001, "api功能未授权"); | |||||
errMap.put(50001, "用户未授权该api"); | |||||
} | |||||
protected int errorCode; | protected int errorCode; | ||||
protected String errorMsg; | protected String errorMsg; | ||||
@@ -120,17 +33,13 @@ public class WxError { | |||||
this.errorMsg = errorMsg; | this.errorMsg = errorMsg; | ||||
} | } | ||||
public String getDescription() { | |||||
return errMap.get(errorCode); | |||||
} | |||||
public static WxError fromJson(String json) { | public static WxError fromJson(String json) { | ||||
return WxCpGsonBuilder.create().fromJson(json, WxError.class); | return WxCpGsonBuilder.create().fromJson(json, WxError.class); | ||||
} | } | ||||
@Override | @Override | ||||
public String toString() { | public String toString() { | ||||
return "微信错误 errcode=" + errorCode + ", errmsg=" + errorMsg + ", description=" + getDescription(); | |||||
return "微信错误 errcode=" + errorCode + ", errmsg=" + errorMsg; | |||||
} | } | ||||
} | } |
@@ -22,38 +22,44 @@ import com.google.gson.JsonSerializationContext; | |||||
import com.google.gson.JsonSerializer; | import com.google.gson.JsonSerializer; | ||||
/** | /** | ||||
* | |||||
* @author Daniel Qian | * @author Daniel Qian | ||||
* | |||||
*/ | */ | ||||
public class WxCpDepartGsonAdapter implements JsonSerializer<WxCpDepart>, JsonDeserializer<WxCpDepart> { | public class WxCpDepartGsonAdapter implements JsonSerializer<WxCpDepart>, JsonDeserializer<WxCpDepart> { | ||||
public JsonElement serialize(WxCpDepart group, Type typeOfSrc, JsonSerializationContext context) { | public JsonElement serialize(WxCpDepart group, Type typeOfSrc, JsonSerializationContext context) { | ||||
JsonObject json = new JsonObject(); | JsonObject json = new JsonObject(); | ||||
JsonObject groupJson = new JsonObject(); | |||||
groupJson.addProperty("name", group.getName()); | |||||
groupJson.addProperty("id", group.getId()); | |||||
groupJson.addProperty("count", group.getCount()); | |||||
json.add("group", groupJson); | |||||
if (group.getId() != null) { | |||||
json.addProperty("id", group.getId()); | |||||
} | |||||
if (group.getName() != null) { | |||||
json.addProperty("name", group.getName()); | |||||
} | |||||
if (group.getParentId() != null) { | |||||
json.addProperty("parentid", group.getParentId()); | |||||
} | |||||
if (group.getOrder() != null) { | |||||
json.addProperty("order", String.valueOf(group.getOrder())); | |||||
} | |||||
return json; | return json; | ||||
} | } | ||||
public WxCpDepart deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { | |||||
WxCpDepart group = new WxCpDepart(); | |||||
JsonObject groupJson = json.getAsJsonObject(); | |||||
if (json.getAsJsonObject().get("group") != null) { | |||||
groupJson = json.getAsJsonObject().get("group").getAsJsonObject(); | |||||
public WxCpDepart deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) | |||||
throws JsonParseException { | |||||
WxCpDepart depart = new WxCpDepart(); | |||||
JsonObject departJson = json.getAsJsonObject(); | |||||
if (departJson.get("id") != null && !departJson.get("id").isJsonNull()) { | |||||
depart.setId(GsonHelper.getAsInteger(departJson.get("id"))); | |||||
} | } | ||||
if (groupJson.get("name") != null && !groupJson.get("name").isJsonNull()) { | |||||
group.setName(GsonHelper.getAsString(groupJson.get("name"))); | |||||
if (departJson.get("name") != null && !departJson.get("name").isJsonNull()) { | |||||
depart.setName(GsonHelper.getAsString(departJson.get("name"))); | |||||
} | } | ||||
if (groupJson.get("id") != null && !groupJson.get("id").isJsonNull()) { | |||||
group.setId(GsonHelper.getAsPrimitiveLong(groupJson.get("id"))); | |||||
if (departJson.get("order") != null && !departJson.get("order").isJsonNull()) { | |||||
depart.setOrder(GsonHelper.getAsInteger(departJson.get("order"))); | |||||
} | } | ||||
if (groupJson.get("count") != null && !groupJson.get("count").isJsonNull()) { | |||||
group.setCount(GsonHelper.getAsPrimitiveLong(groupJson.get("count"))); | |||||
if (departJson.get("parentid") != null && !departJson.get("parentid").isJsonNull()) { | |||||
depart.setParentId(GsonHelper.getAsInteger(departJson.get("parentid"))); | |||||
} | } | ||||
return group; | |||||
return depart; | |||||
} | } | ||||
} | } |
@@ -12,11 +12,11 @@ import me.chanjar.weixin.enterprise.exception.WxErrorException; | |||||
import com.google.inject.Inject; | import com.google.inject.Inject; | ||||
/** | /** | ||||
* 测试分组接口 | |||||
* | |||||
* 测试部门接口 | |||||
* | |||||
* @author Daniel Qian | * @author Daniel Qian | ||||
*/ | */ | ||||
@Test(groups = "groupAPI", dependsOnGroups = "baseAPI") | |||||
@Test(groups = "departAPI", dependsOnGroups = "baseAPI") | |||||
@Guice(modules = ApiTestModule.class) | @Guice(modules = ApiTestModule.class) | ||||
public class WxCpDepartAPITest { | public class WxCpDepartAPITest { | ||||
@@ -24,27 +24,35 @@ public class WxCpDepartAPITest { | |||||
protected WxCpServiceImpl wxService; | protected WxCpServiceImpl wxService; | ||||
protected WxCpDepart depart; | protected WxCpDepart depart; | ||||
public void testGroupCreate() throws WxErrorException { | |||||
WxCpDepart res = wxService.departmentCreate("测试分组1"); | |||||
Assert.assertEquals(res.getName(), "测试分组1"); | |||||
public void testDepartCreate() throws WxErrorException { | |||||
WxCpDepart depart = new WxCpDepart(); | |||||
depart.setName("测试部门"); | |||||
depart.setParentId(1); | |||||
depart.setOrder(1); | |||||
Integer departId = wxService.departCreate(depart); | |||||
} | } | ||||
@Test(dependsOnMethods="testGroupCreate") | |||||
public void testGroupGet() throws WxErrorException { | |||||
List<WxCpDepart> groupList = wxService.departmentGet(); | |||||
Assert.assertNotNull(groupList); | |||||
Assert.assertTrue(groupList.size() > 0); | |||||
for (WxCpDepart g : groupList) { | |||||
@Test(dependsOnMethods = "testDepartCreate") | |||||
public void testDepartGet() throws WxErrorException { | |||||
List<WxCpDepart> departList = wxService.departGet(); | |||||
Assert.assertNotNull(departList); | |||||
Assert.assertTrue(departList.size() > 0); | |||||
for (WxCpDepart g : departList) { | |||||
depart = g; | depart = g; | ||||
Assert.assertNotNull(g.getName()); | Assert.assertNotNull(g.getName()); | ||||
} | } | ||||
} | } | ||||
@Test(dependsOnMethods={"testGroupGet", "testGroupCreate"}) | |||||
public void getGroupUpdate() throws WxErrorException { | |||||
depart.setName("分组改名"); | |||||
wxService.departmentUpdate(depart); | |||||
@Test(dependsOnMethods = { "testDepartGet", "testDepartCreate" }) | |||||
public void testDepartUpdate() throws WxErrorException { | |||||
depart.setName("部门改名"); | |||||
wxService.departUpdate(depart); | |||||
} | |||||
@Test(dependsOnMethods = "testDepartUpdate") | |||||
public void testDepartDelete() throws WxErrorException { | |||||
wxService.departDelete(depart.getId()); | |||||
} | } | ||||
} | } |