diff --git a/flossom-common/flossom-common-core/src/main/java/com/flossom/common/core/domain/shuyun/AccessToken.java b/flossom-common/flossom-common-core/src/main/java/com/flossom/common/core/domain/shuyun/AccessToken.java index 6feda3d..66b99a9 100644 --- a/flossom-common/flossom-common-core/src/main/java/com/flossom/common/core/domain/shuyun/AccessToken.java +++ b/flossom-common/flossom-common-core/src/main/java/com/flossom/common/core/domain/shuyun/AccessToken.java @@ -30,7 +30,7 @@ public class AccessToken { /** * 0:代表已更新 1:代表已过期,如果是授权过期,则需要租户在页面进行手动授权,产生新accessToken */ - private String isOverDue; + private Integer isOverDue; public String getAccessToken() { return accessToken; @@ -64,11 +64,11 @@ public class AccessToken { this.authValue = authValue; } - public String getIsOverDue() { + public Integer getIsOverDue() { return isOverDue; } - public void setIsOverDue(String isOverDue) { + public void setIsOverDue(Integer isOverDue) { this.isOverDue = isOverDue; } diff --git a/flossom-common/flossom-common-core/src/main/java/com/flossom/common/core/domain/shuyun/ShuYunMember.java b/flossom-common/flossom-common-core/src/main/java/com/flossom/common/core/domain/shuyun/ShuYunMember.java new file mode 100644 index 0000000..6e0ac09 --- /dev/null +++ b/flossom-common/flossom-common-core/src/main/java/com/flossom/common/core/domain/shuyun/ShuYunMember.java @@ -0,0 +1,174 @@ +package com.flossom.common.core.domain.shuyun; + +/** + * 数云的 会员信息 + */ +public class ShuYunMember { + + /** + * 平台客户账号(必填) + */ + private String id; + + /** + * 平台编码(必填) + */ + private String platCode; + + /** + * 客户注册时使用的店铺ID,非数云店铺ID(必填) + */ + private String shopId; + + /** + * 姓名(必填) + */ + private String name; + + /** + * 手机号(必填) + */ + private String mobile; + + /** + * 生日 yyyy-MM-dd + */ + private String birthday; + + /** + * 性别:F(女); M(男) + */ + private String gender; + + /** + * 变更时间 yyyy-MM-dd HH:mm:ss + */ + private String created; + + /** + * 导购ID,非导购业务可以不填 + */ + private String guideId; + + public ShuYunMember() { + } + + /** + * 新增必填 + * @param id + * @param platCode + * @param shopId + * @param name + * @param mobile + */ + public ShuYunMember(String id, String platCode, String shopId, String name, String mobile) { + this.id = id; + this.platCode = platCode; + this.shopId = shopId; + this.name = name; + this.mobile = mobile; + } + + /** + * 查询必填 + * @param id + * @param platCode + * @param shopId + */ + public ShuYunMember(String id, String platCode, String shopId) { + this.id = id; + this.platCode = platCode; + this.shopId = shopId; + } + + public ShuYunMember(String id, String platCode, String shopId, String mobile) { + this.id = id; + this.platCode = platCode; + this.shopId = shopId; + this.mobile = mobile; + } + + public ShuYunMember(String id, String platCode, String shopId, String name, String mobile, String birthday, String gender, String created, String guideId) { + this.id = id; + this.platCode = platCode; + this.shopId = shopId; + this.name = name; + this.mobile = mobile; + this.birthday = birthday; + this.gender = gender; + this.created = created; + this.guideId = guideId; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getPlatCode() { + return platCode; + } + + public void setPlatCode(String platCode) { + this.platCode = platCode; + } + + public String getShopId() { + return shopId; + } + + public void setShopId(String shopId) { + this.shopId = shopId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getMobile() { + return mobile; + } + + public void setMobile(String mobile) { + this.mobile = mobile; + } + + public String getBirthday() { + return birthday; + } + + public void setBirthday(String birthday) { + this.birthday = birthday; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getCreated() { + return created; + } + + public void setCreated(String created) { + this.created = created; + } + + public String getGuideId() { + return guideId; + } + + public void setGuideId(String guideId) { + this.guideId = guideId; + } +} diff --git a/flossom-common/flossom-common-core/src/main/java/com/flossom/common/core/domain/shuyun/ShuYunPointChange.java b/flossom-common/flossom-common-core/src/main/java/com/flossom/common/core/domain/shuyun/ShuYunPointChange.java new file mode 100644 index 0000000..58accb1 --- /dev/null +++ b/flossom-common/flossom-common-core/src/main/java/com/flossom/common/core/domain/shuyun/ShuYunPointChange.java @@ -0,0 +1,183 @@ +package com.flossom.common.core.domain.shuyun; + +public class ShuYunPointChange { + + /** + * 平台客户账号 + */ + private String id; + + /** + * 平台编码 + */ + private String platCode; + + /** + * 客户注册时使用的店铺ID,非数云店铺ID + */ + private String shopId; + + /** + * 全局流水号 + */ + private String sequence; + + /** + * 业务来源 + * TRADE:订单赠送、 + * REFUND:退单扣减、 + * SERVICE:客服、 + * CONSUME:消费、 + * EXPIRE:过期、 + * IMPORT:导入、 + * MALL:手淘互动、 + * BRAND:会员通、 + * OTHER 其他 + */ + private String source; + + /** + * 变更积分。 正值为发放;负值为消费。 + */ + private Integer changePoint; + + + /** + * 变更时间 yyyy-MM-dd HH:mm:ss + */ + private String created; + + /** + * 过期时间 yyyy-MM-dd HH:mm:ss + */ + private String expired; + + /** + * 操作人 + */ + private String operator; + + /** + * 描述信息 + */ + private String desc; + + public ShuYunPointChange() { + } + + /** + * 必填选项 + * + * @param id + * @param platCode + * @param shopId + * @param sequence + * @param source + * @param changePoint + * @param created + * @param desc + */ + public ShuYunPointChange(String id, String platCode, String shopId, String sequence, String source, Integer changePoint, String created, String desc) { + this.id = id; + this.platCode = platCode; + this.shopId = shopId; + this.sequence = sequence; + this.source = source; + this.changePoint = changePoint; + this.created = created; + this.desc = desc; + } + + public ShuYunPointChange(String id, String platCode, String shopId, String sequence, String source, Integer changePoint, String created, String expired, String operator, String desc) { + this.id = id; + this.platCode = platCode; + this.shopId = shopId; + this.sequence = sequence; + this.source = source; + this.changePoint = changePoint; + this.created = created; + this.expired = expired; + this.operator = operator; + this.desc = desc; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getPlatCode() { + return platCode; + } + + public void setPlatCode(String platCode) { + this.platCode = platCode; + } + + public String getShopId() { + return shopId; + } + + public void setShopId(String shopId) { + this.shopId = shopId; + } + + public String getSequence() { + return sequence; + } + + public void setSequence(String sequence) { + this.sequence = sequence; + } + + public String getSource() { + return source; + } + + public void setSource(String source) { + this.source = source; + } + + public Integer getChangePoint() { + return changePoint; + } + + public void setChangePoint(Integer changePoint) { + this.changePoint = changePoint; + } + + public String getCreated() { + return created; + } + + public void setCreated(String created) { + this.created = created; + } + + public String getExpired() { + return expired; + } + + public void setExpired(String expired) { + this.expired = expired; + } + + public String getOperator() { + return operator; + } + + public void setOperator(String operator) { + this.operator = operator; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } +} diff --git a/flossom-modules/flossom-system/src/main/java/com/flossom/system/controller/ShuYunCallbackController.java b/flossom-modules/flossom-system/src/main/java/com/flossom/system/controller/ShuYunCallbackController.java index 4c3f525..0588208 100644 --- a/flossom-modules/flossom-system/src/main/java/com/flossom/system/controller/ShuYunCallbackController.java +++ b/flossom-modules/flossom-system/src/main/java/com/flossom/system/controller/ShuYunCallbackController.java @@ -46,7 +46,7 @@ public class ShuYunCallbackController { */ if (accessTokenList != null && accessTokenList.size() > 0) { for (AccessToken accessToken : accessTokenList) { - if (StringUtils.equals(accessToken.getAppId(), shuYunConfig.getAppid())) { + if (accessToken.getIsOverDue() == 0 && StringUtils.equals(accessToken.getAuthValue(), shuYunConfig.getAuthValue())) { logger.info("缓存数云accessToken:{}", accessToken); if (StringUtils.isNotBlank(accessToken.getAccessToken())) { Map map = new HashMap<>(); diff --git a/flossom-modules/flossom-system/src/main/java/com/flossom/system/utils/shuyun/ActionMethod.java b/flossom-modules/flossom-system/src/main/java/com/flossom/system/utils/shuyun/ActionMethod.java index 7d2d4d5..3368714 100644 --- a/flossom-modules/flossom-system/src/main/java/com/flossom/system/utils/shuyun/ActionMethod.java +++ b/flossom-modules/flossom-system/src/main/java/com/flossom/system/utils/shuyun/ActionMethod.java @@ -1,9 +1,45 @@ package com.flossom.system.utils.shuyun; +/** + * 数云接口方法名称 + */ public class ActionMethod { + /** + * 获取token路径标识 + */ private String accessToken; + /** + * 查询会员路径标识(单个会员) + */ + private String queryMember; + + /** + * 注册会员路径标识 + */ + private String registerMember; + + /** + * 修改会员信息路径标识 + */ + private String modifyMember; + + /** + * 修改会员手机号 + */ + private String modifyMemberMobile; + + /** + * 解绑会员 + */ + private String unbindMember; + + /** + * 积分变更 + */ + private String pointChange; + public String getAccessToken() { return accessToken; } @@ -11,4 +47,52 @@ public class ActionMethod { public void setAccessToken(String accessToken) { this.accessToken = accessToken; } + + public String getQueryMember() { + return queryMember; + } + + public void setQueryMember(String queryMember) { + this.queryMember = queryMember; + } + + public String getRegisterMember() { + return registerMember; + } + + public void setRegisterMember(String registerMember) { + this.registerMember = registerMember; + } + + public String getModifyMember() { + return modifyMember; + } + + public void setModifyMember(String modifyMember) { + this.modifyMember = modifyMember; + } + + public String getModifyMemberMobile() { + return modifyMemberMobile; + } + + public void setModifyMemberMobile(String modifyMemberMobile) { + this.modifyMemberMobile = modifyMemberMobile; + } + + public String getUnbindMember() { + return unbindMember; + } + + public void setUnbindMember(String unbindMember) { + this.unbindMember = unbindMember; + } + + public String getPointChange() { + return pointChange; + } + + public void setPointChange(String pointChange) { + this.pointChange = pointChange; + } } diff --git a/flossom-modules/flossom-system/src/main/java/com/flossom/system/utils/shuyun/ShuYunApiUtils.java b/flossom-modules/flossom-system/src/main/java/com/flossom/system/utils/shuyun/ShuYunApiUtils.java index 6cdff0d..17a61f3 100644 --- a/flossom-modules/flossom-system/src/main/java/com/flossom/system/utils/shuyun/ShuYunApiUtils.java +++ b/flossom-modules/flossom-system/src/main/java/com/flossom/system/utils/shuyun/ShuYunApiUtils.java @@ -1,8 +1,16 @@ package com.flossom.system.utils.shuyun; +import com.alibaba.fastjson.JSON; import com.flossom.common.core.constant.CacheConstants; +import com.flossom.common.core.domain.R; +import com.flossom.common.core.domain.shuyun.AccessToken; +import com.flossom.common.core.domain.shuyun.ShuYunMember; +import com.flossom.common.core.domain.shuyun.ShuYunPointChange; +import com.flossom.common.core.exception.ServiceException; import com.flossom.common.redis.service.RedisService; import com.flossom.system.utils.HttpClientUtils; +import com.shuyun.open.sdk.bean.HttpMethod; +import com.shuyun.open.sdk.core.GateWayClient; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -11,6 +19,7 @@ import org.springframework.stereotype.Component; import java.time.LocalDateTime; import java.time.ZoneId; +import java.util.Map; /** @@ -21,6 +30,9 @@ public class ShuYunApiUtils { protected final static Logger logger = LoggerFactory.getLogger(ShuYunApiUtils.class); + /** + * 数云配置类 + */ private static ShuYunConfig shuYunConfig; private static RedisService redisService; @@ -36,20 +48,147 @@ public class ShuYunApiUtils { } /** - * 获取 accessToken,缓存没有就请求数云回调接口,将accessToken传递过来 - * - * @return - * @throws Exception + * 获取 accessToken,缓存没有就请求数云回调接口,将 accessToken 传递过来 */ - public static String getAccessToken() throws Exception { - Integer expiryTime = redisService.getCacheMapValue(CacheConstants.SHUYUN_ACCESS_TOKEN_CACHE, CacheConstants.SHUYUN_ACCESS_TOKEN_CACHE_VALUE); - if (expiryTime == null || LocalDateTime.now().atZone(ZoneId.systemDefault()).toEpochSecond() > expiryTime) { + public static String getAccessToken() { + Long expiryTime = redisService.getCacheMapValue(CacheConstants.SHUYUN_ACCESS_TOKEN_CACHE, CacheConstants.SHUYUN_ACCESS_TOKEN_CACHE_EXPIRY); + if (expiryTime == null || expiryTime == 0 || LocalDateTime.now().atZone(ZoneId.systemDefault()).toEpochSecond() > expiryTime) { String accessTokenUrl = StringUtils.replace(shuYunConfig.getActionMethod().getAccessToken(), "{appid}", shuYunConfig.getAppid()); logger.info("刷新accessToken地址:{}", accessTokenUrl); - String result = HttpClientUtils.get(accessTokenUrl); - logger.info("请求刷新accessToken结果:{}", result); + try { + String result = HttpClientUtils.get(accessTokenUrl); + logger.info("请求数云接口获取accessToken结果:{}", result); + R r = JSON.parseObject(result, R.class); + if (r.getCode() != R.SUCCESS) { + logger.error("请求数云接口获取accessToken失败,将直接使用旧的accessToken,失败原因:{}", result); + } + } catch (Exception e) { + logger.error("请求数云接口获取accessToken失败,将直接使用旧的accessToken,失败原因:{}", e); + } + } + String accessTokenStr = redisService.getCacheMapValue(CacheConstants.SHUYUN_ACCESS_TOKEN_CACHE, CacheConstants.SHUYUN_ACCESS_TOKEN_CACHE_VALUE); + if (StringUtils.isNotBlank(accessTokenStr)) { + AccessToken accessToken = JSON.parseObject(accessTokenStr, AccessToken.class); + return accessToken.getAccessToken(); + } + /** + * 第一次获取会失败,因为回调是异步的,如果还没回调回来,我们就从redis获取缓存了 + */ + logger.error("从redis获取数云accessToken失败,缓存中没有accessToken,有可能是第一次调用"); + throw new ServiceException("从redis获取数云accessToken失败,缓存中没有accessToken,有可能是第一次调用"); + } + + /** + * 请求基础封装方法 + * + * @param httpMethod 请求方式 + * @param requestParams get请求时,url地址后的参数 + * @param requestBody post、put 请求时,请求体的数据 + * @param actionMethod 请求方法地址 + */ + public static R shuYunHttpRequest(HttpMethod httpMethod, Map requestParams, String requestBody, String actionMethod) throws ServiceException { + logger.info("数云接口请求地址:{},参数:requestParams = {}、requestBody = {}", actionMethod, requestParams, requestBody); + String result = GateWayClient.askGateWay( + httpMethod, + shuYunConfig.getUrl(), + requestParams, + requestBody, + shuYunConfig.getAppid(), + shuYunConfig.getSecurity(), + getAccessToken(), + actionMethod); + logger.info("返回响应:{}", result); + R r = JSON.parseObject(result, R.class); + if (r.getCode() == 10000 || r.getCode() == 14000) { + return r; + } else { + logger.error("调用数云接口发生未知错误:{}", result); + throw new ServiceException("调用数云接口发生未知错误"); + } + } + + + /** + * 会员注册 + */ + public static void registerMember(ShuYunMember member) { + try { + shuYunHttpRequest(HttpMethod.POST, null, JSON.toJSONString(member), + shuYunConfig.getActionMethod().getRegisterMember()); + } catch (Exception e) { + logger.error("请求数云接口注册会员失败:{}", e); + throw new ServiceException("请求数云接口注册会员失败"); + } + } + + /** + * 会员查询(单查询) + */ + public static ShuYunMember queryMember(ShuYunMember member) { + try { + R r = shuYunHttpRequest(HttpMethod.POST, null, JSON.toJSONString(member), + shuYunConfig.getActionMethod().getQueryMember()); + if (r.getCode() == 10000) { + return JSON.parseObject(r.getData().toString(), ShuYunMember.class); + } + return null; + } catch (Exception e) { + logger.error("请求数云接口-查询会员信息失败:{}", e); + throw new ServiceException("请求数云接口-查询会员信息失败"); + } + } + + /** + * 修改会员信息 + * 手机号不能修改 + */ + public static void modifyMember(ShuYunMember member) { + try { + shuYunHttpRequest(HttpMethod.PUT, null, JSON.toJSONString(member), + shuYunConfig.getActionMethod().getModifyMember()); + } catch (Exception e) { + logger.error("请求数云接口-修改会员信息(除手机号)失败:{}", e); + throw new ServiceException("请求数云接口-修改会员信息(除手机号)失败"); + } + } + + /** + * 修改会员手机号 + */ + public static void modifyMemberMobile(ShuYunMember member) { + try { + shuYunHttpRequest(HttpMethod.PUT, null, JSON.toJSONString(member), + shuYunConfig.getActionMethod().getModifyMemberMobile()); + } catch (Exception e) { + logger.error("请求数云接口-修改会员手机号失败:{}", e); + throw new ServiceException("请求数云接口-修改会员手机号失败"); + } + } + + /** + * 解绑会员 + */ + public static void unbindMember(ShuYunMember member) { + try { + shuYunHttpRequest(HttpMethod.POST, null, JSON.toJSONString(member), + shuYunConfig.getActionMethod().getUnbindMember()); + } catch (Exception e) { + logger.error("请求数云接口-解绑会员失败:{}", e); + throw new ServiceException("请求数云接口-解绑会员失败"); + } + } + + /** + * 积分变更 + */ + public static void pointChange(ShuYunPointChange shuYunPointChange) { + try { + shuYunHttpRequest(HttpMethod.POST, null, JSON.toJSONString(shuYunPointChange), + shuYunConfig.getActionMethod().getPointChange()); + } catch (Exception e) { + logger.error("请求数云接口-会员积分变更失败:{}", e); + throw new ServiceException("请求数云接口-会员积分变更失败"); } - return redisService.getCacheMapValue(CacheConstants.SHUYUN_ACCESS_TOKEN_CACHE, CacheConstants.SHUYUN_ACCESS_TOKEN_CACHE_VALUE); } } diff --git a/flossom-modules/flossom-system/src/main/java/com/flossom/system/utils/shuyun/ShuYunConfig.java b/flossom-modules/flossom-system/src/main/java/com/flossom/system/utils/shuyun/ShuYunConfig.java index 81da0a0..d7d6c0a 100644 --- a/flossom-modules/flossom-system/src/main/java/com/flossom/system/utils/shuyun/ShuYunConfig.java +++ b/flossom-modules/flossom-system/src/main/java/com/flossom/system/utils/shuyun/ShuYunConfig.java @@ -29,6 +29,15 @@ public class ShuYunConfig { */ private String security; + /** + * 租户名 + */ + private String authValue; + + private String platCode; + + private String shopId; + private ActionMethod actionMethod; @@ -63,4 +72,28 @@ public class ShuYunConfig { public void setActionMethod(ActionMethod actionMethod) { this.actionMethod = actionMethod; } + + public String getPlatCode() { + return platCode; + } + + public void setPlatCode(String platCode) { + this.platCode = platCode; + } + + public String getShopId() { + return shopId; + } + + public void setShopId(String shopId) { + this.shopId = shopId; + } + + public String getAuthValue() { + return authValue; + } + + public void setAuthValue(String authValue) { + this.authValue = authValue; + } }