@@ -5,7 +5,9 @@ import java.util.ArrayList; | |||
import java.util.List; | |||
import lombok.AllArgsConstructor; | |||
import lombok.Builder; | |||
import lombok.Data; | |||
import lombok.NoArgsConstructor; | |||
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | |||
/** | |||
@@ -34,6 +36,14 @@ public class WxCpUser implements Serializable { | |||
private String telephone; | |||
private String qrCode; | |||
private Boolean toInvite; | |||
/** | |||
* 成员对外信息. | |||
*/ | |||
private List<ExternalAttr> externalAttrs = new ArrayList<>(); | |||
public void addExternalAttr(ExternalAttr externalAttr) { | |||
this.externalAttrs.add(externalAttr); | |||
} | |||
public void addExtAttr(String name, String value) { | |||
this.extAttrs.add(new Attr(name, value)); | |||
@@ -54,4 +64,40 @@ public class WxCpUser implements Serializable { | |||
private String value; | |||
} | |||
@Data | |||
@Builder | |||
@NoArgsConstructor | |||
@AllArgsConstructor | |||
public static class ExternalAttr { | |||
/** | |||
* 属性类型: 0-本文 1-网页 2-小程序. | |||
*/ | |||
private int type; | |||
/** | |||
* 属性名称: 需要先确保在管理端有创建改属性,否则会忽略. | |||
*/ | |||
private String name; | |||
/** | |||
* 文本属性内容,长度限制12个UTF8字符. | |||
*/ | |||
private String value; | |||
/** | |||
* 网页的url,必须包含http或者https头. | |||
*/ | |||
private String url; | |||
/** | |||
* 小程序的展示标题,长度限制12个UTF8字符. | |||
* 或者 网页的展示标题,长度限制12个UTF8字符 | |||
*/ | |||
private String title; | |||
/** | |||
* 小程序appid,必须是有在本企业安装授权的小程序,否则会被忽略. | |||
*/ | |||
private String appid; | |||
/** | |||
* 小程序的页面路径. | |||
*/ | |||
private String pagePath; | |||
} | |||
} |
@@ -10,6 +10,9 @@ import me.chanjar.weixin.cp.bean.WxCpMessage; | |||
import me.chanjar.weixin.cp.bean.WxCpTag; | |||
import me.chanjar.weixin.cp.bean.WxCpUser; | |||
/** | |||
* @author Daniel Qian | |||
*/ | |||
public class WxCpGsonBuilder { | |||
public static final GsonBuilder INSTANCE = new GsonBuilder(); | |||
@@ -27,10 +27,11 @@ import me.chanjar.weixin.cp.bean.WxCpUser; | |||
* @author Daniel Qian | |||
*/ | |||
public class WxCpUserGsonAdapter implements JsonDeserializer<WxCpUser>, JsonSerializer<WxCpUser> { | |||
private static final String EXTERNAL_PROFILE = "external_profile"; | |||
private static final String EXTERNAL_ATTR = "external_attr"; | |||
@Override | |||
public WxCpUser deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) | |||
throws JsonParseException { | |||
public WxCpUser deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { | |||
JsonObject o = json.getAsJsonObject(); | |||
WxCpUser user = new WxCpUser(); | |||
@@ -71,6 +72,53 @@ public class WxCpUserGsonAdapter implements JsonDeserializer<WxCpUser>, JsonSeri | |||
user.getExtAttrs().add(attr); | |||
} | |||
} | |||
if (GsonHelper.isNotNull(o.get(EXTERNAL_PROFILE))) { | |||
JsonArray attrJsonElements = o.get(EXTERNAL_PROFILE).getAsJsonObject().get(EXTERNAL_ATTR).getAsJsonArray(); | |||
for (JsonElement element : attrJsonElements) { | |||
final Integer type = GsonHelper.getInteger(element.getAsJsonObject(), "type"); | |||
final String name = GsonHelper.getString(element.getAsJsonObject(), "name"); | |||
switch (type) { | |||
case 0: { | |||
user.getExternalAttrs() | |||
.add(WxCpUser.ExternalAttr.builder() | |||
.type(type) | |||
.name(name) | |||
.value(GsonHelper.getString(element.getAsJsonObject().get("text").getAsJsonObject(), "value")) | |||
.build() | |||
); | |||
break; | |||
} | |||
case 1: { | |||
final JsonObject web = element.getAsJsonObject().get("web").getAsJsonObject(); | |||
user.getExternalAttrs() | |||
.add(WxCpUser.ExternalAttr.builder() | |||
.type(type) | |||
.name(name) | |||
.url(GsonHelper.getString(web, "url")) | |||
.title(GsonHelper.getString(web, "title")) | |||
.build() | |||
); | |||
break; | |||
} | |||
case 2: { | |||
final JsonObject miniprogram = element.getAsJsonObject().get("miniprogram").getAsJsonObject(); | |||
user.getExternalAttrs() | |||
.add(WxCpUser.ExternalAttr.builder() | |||
.type(type) | |||
.name(name) | |||
.appid(GsonHelper.getString(miniprogram, "appid")) | |||
.pagePath(GsonHelper.getString(miniprogram, "pagepath")) | |||
.title(GsonHelper.getString(miniprogram, "title")) | |||
.build() | |||
); | |||
break; | |||
} | |||
default://ignored | |||
} | |||
} | |||
} | |||
return user; | |||
} | |||
@@ -145,6 +193,45 @@ public class WxCpUserGsonAdapter implements JsonDeserializer<WxCpUser>, JsonSeri | |||
attrsJson.add("attrs", attrsJsonArray); | |||
o.add("extattr", attrsJson); | |||
} | |||
if (user.getExternalAttrs().size() > 0) { | |||
JsonArray attrsJsonArray = new JsonArray(); | |||
for (WxCpUser.ExternalAttr attr : user.getExternalAttrs()) { | |||
JsonObject attrJson = new JsonObject(); | |||
attrJson.addProperty("type",attr.getType()); | |||
attrJson.addProperty("name", attr.getName()); | |||
switch (attr.getType()) { | |||
case 0: { | |||
JsonObject text = new JsonObject(); | |||
text.addProperty("value", attr.getValue()); | |||
attrJson.add("text", text); | |||
break; | |||
} | |||
case 1: { | |||
JsonObject web = new JsonObject(); | |||
web.addProperty("url", attr.getUrl()); | |||
web.addProperty("title", attr.getTitle()); | |||
attrJson.add("web", web); | |||
break; | |||
} | |||
case 2: { | |||
JsonObject miniprogram = new JsonObject(); | |||
miniprogram.addProperty("appid", attr.getAppid()); | |||
miniprogram.addProperty("pagepath", attr.getPagePath()); | |||
miniprogram.addProperty("title", attr.getTitle()); | |||
attrJson.add("miniprogram", miniprogram); | |||
break; | |||
} | |||
default://忽略 | |||
} | |||
attrsJsonArray.add(attrJson); | |||
} | |||
JsonObject attrsJson = new JsonObject(); | |||
attrsJson.add(EXTERNAL_ATTR, attrsJsonArray); | |||
o.add(EXTERNAL_PROFILE, attrsJson); | |||
} | |||
return o; | |||
} | |||
@@ -0,0 +1,124 @@ | |||
package me.chanjar.weixin.cp.util.json; | |||
import org.testng.annotations.*; | |||
import me.chanjar.weixin.cp.bean.WxCpUser; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
/** | |||
* <pre> | |||
* | |||
* Created by Binary Wang on 2018/9/16. | |||
* </pre> | |||
* | |||
* @author BinaryWang | |||
*/ | |||
public class WxCpUserGsonAdapterTest { | |||
@Test | |||
public void testDeserialize() { | |||
final String userJson = "{\n" + | |||
" \"errcode\": 0,\n" + | |||
" \"errmsg\": \"ok\",\n" + | |||
" \"userid\": \"zhangsan\",\n" + | |||
" \"name\": \"李四\",\n" + | |||
" \"department\": [1, 2],\n" + | |||
" \"order\": [1, 2],\n" + | |||
" \"position\": \"后台工程师\",\n" + | |||
" \"mobile\": \"15913215421\",\n" + | |||
" \"gender\": \"1\",\n" + | |||
" \"email\": \"zhangsan@gzdev.com\",\n" + | |||
" \"isleader\": 1,\n" + | |||
" \"avatar\": \"http://wx.qlogo.cn/mmopen/ajNVdqHZLLA3WJ6DSZUfiakYe37PKnQhBIeOQBO4czqrnZDS79FH5Wm5m4X69TBicnHFlhiafvDwklOpZeXYQQ2icg/0\",\n" + | |||
" \"telephone\": \"020-123456\",\n" + | |||
" \"enable\": 1,\n" + | |||
" \"alias\": \"jackzhang\",\n" + | |||
" \"extattr\": {\n" + | |||
" \"attrs\": [{\n" + | |||
" \"name\": \"爱好\",\n" + | |||
" \"value\": \"旅游\"\n" + | |||
" }, {\n" + | |||
" \"name\": \"卡号\",\n" + | |||
" \"value\": \"1234567234\"\n" + | |||
" }]\n" + | |||
" },\n" + | |||
" \"status\": 1,\n" + | |||
" \"qr_code\": \"https://open.work.weixin.qq.com/wwopen/userQRCode?vcode=xxx\",\n" + | |||
" \"external_profile\": {\n" + | |||
" \"external_attr\": [{\n" + | |||
" \"type\": 0,\n" + | |||
" \"name\": \"文本名称\",\n" + | |||
" \"text\": {\n" + | |||
" \"value\": \"文本\"\n" + | |||
" }\n" + | |||
" },\n" + | |||
" {\n" + | |||
" \"type\": 1,\n" + | |||
" \"name\": \"网页名称\",\n" + | |||
" \"web\": {\n" + | |||
" \"url\": \"http://www.test.com\",\n" + | |||
" \"title\": \"标题\"\n" + | |||
" }\n" + | |||
" },\n" + | |||
" {\n" + | |||
" \"type\": 2,\n" + | |||
" \"name\": \"测试app\",\n" + | |||
" \"miniprogram\": {\n" + | |||
" \"appid\": \"wx8bd80126147df384\",\n" + | |||
" \"pagepath\": \"/index\",\n" + | |||
" \"title\": \"my miniprogram\"\n" + | |||
" }\n" + | |||
" }\n" + | |||
" ]\n" + | |||
" }\n" + | |||
"}"; | |||
final WxCpUser user = WxCpUser.fromJson(userJson); | |||
assertThat(user).isNotNull(); | |||
assertThat(user.getExternalAttrs()).isNotEmpty(); | |||
final WxCpUser.ExternalAttr externalAttr1 = user.getExternalAttrs().get(0); | |||
assertThat(externalAttr1.getType()).isEqualTo(0); | |||
assertThat(externalAttr1.getName()).isEqualTo("文本名称"); | |||
assertThat(externalAttr1.getValue()).isEqualTo("文本"); | |||
final WxCpUser.ExternalAttr externalAttr2 = user.getExternalAttrs().get(1); | |||
assertThat(externalAttr2.getType()).isEqualTo(1); | |||
assertThat(externalAttr2.getName()).isEqualTo("网页名称"); | |||
assertThat(externalAttr2.getUrl()).isEqualTo("http://www.test.com"); | |||
assertThat(externalAttr2.getTitle()).isEqualTo("标题"); | |||
final WxCpUser.ExternalAttr externalAttr3 = user.getExternalAttrs().get(2); | |||
assertThat(externalAttr3.getType()).isEqualTo(2); | |||
assertThat(externalAttr3.getName()).isEqualTo("测试app"); | |||
assertThat(externalAttr3.getAppid()).isEqualTo("wx8bd80126147df384"); | |||
assertThat(externalAttr3.getPagePath()).isEqualTo("/index"); | |||
assertThat(externalAttr3.getTitle()).isEqualTo("my miniprogram"); | |||
} | |||
@Test | |||
public void testSerialize() { | |||
WxCpUser user = new WxCpUser(); | |||
user.addExternalAttr(WxCpUser.ExternalAttr.builder() | |||
.type(0) | |||
.name("文本名称") | |||
.value("文本") | |||
.build()); | |||
user.addExternalAttr(WxCpUser.ExternalAttr.builder() | |||
.type(1) | |||
.name("网页名称") | |||
.url("http://www.test.com") | |||
.title("标题") | |||
.build()); | |||
user.addExternalAttr(WxCpUser.ExternalAttr.builder() | |||
.type(2) | |||
.name("测试app") | |||
.appid("wx8bd80126147df384") | |||
.pagePath("/index") | |||
.title("my miniprogram") | |||
.build()); | |||
assertThat(user.toJson()).isEqualTo("{\"external_profile\":{\"external_attr\":[{\"type\":0,\"name\":\"文本名称\",\"text\":{\"value\":\"文本\"}},{\"type\":1,\"name\":\"网页名称\",\"web\":{\"url\":\"http://www.test.com\",\"title\":\"标题\"}},{\"type\":2,\"name\":\"测试app\",\"miniprogram\":{\"appid\":\"wx8bd80126147df384\",\"pagepath\":\"/index\",\"title\":\"my miniprogram\"}}]}}"); | |||
} | |||
} |