16 changed files with 519 additions and 0 deletions
@ -0,0 +1,28 @@ |
|||||
|
package com.epmet.sdt; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
|
||||
|
/** |
||||
|
* 山东通返回结果封装 |
||||
|
*/ |
||||
|
@Data |
||||
|
public class SdtBaseResult { |
||||
|
|
||||
|
/** |
||||
|
* 成功状态码 |
||||
|
*/ |
||||
|
public static final Integer SUCCESS_CODE = 0; |
||||
|
|
||||
|
private Integer errcode; |
||||
|
private String errmsg; |
||||
|
|
||||
|
/** |
||||
|
* 请求是否成功 |
||||
|
* @author wxz |
||||
|
* @date 2022/11/2 22:43 |
||||
|
* @return boolean |
||||
|
*/ |
||||
|
public boolean success() { |
||||
|
return (errcode != null && errcode == SUCCESS_CODE) ? true : false; |
||||
|
} |
||||
|
} |
@ -0,0 +1,12 @@ |
|||||
|
package com.epmet.sdt; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
|
||||
|
/** |
||||
|
* 获取山东通AccessToken接口的返回Result |
||||
|
*/ |
||||
|
@Data |
||||
|
public class SdtGetAccessTokenResult extends SdtBaseResult { |
||||
|
private String access_token; |
||||
|
private Long expires_in; |
||||
|
} |
@ -0,0 +1,17 @@ |
|||||
|
package com.epmet.sdt; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
|
||||
|
/** |
||||
|
* 返回了挺多属性,但是我只取手机号 |
||||
|
* @ClassName SdtStaffInfoResult |
||||
|
* @Description TODO |
||||
|
* @Author wangxianzhang |
||||
|
* @Date 2022/11/3 10:58 |
||||
|
*/ |
||||
|
@Data |
||||
|
public class SdtStaffDetailResult extends SdtBaseResult { |
||||
|
private String userid; |
||||
|
private String name; |
||||
|
private String mobile; |
||||
|
} |
@ -0,0 +1,17 @@ |
|||||
|
package com.epmet.sdt; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
|
||||
|
/** |
||||
|
* @ClassName SdtStaffInfoResult |
||||
|
* @Description TODO |
||||
|
* @Author wangxianzhang |
||||
|
* @Date 2022/11/3 10:58 |
||||
|
*/ |
||||
|
@Data |
||||
|
public class SdtStaffInfoResult extends SdtBaseResult { |
||||
|
private String UserId; |
||||
|
private String DeviceId; |
||||
|
private String user_ticket; |
||||
|
private String expires_in; |
||||
|
} |
@ -0,0 +1,47 @@ |
|||||
|
package com.epmet.controller; |
||||
|
|
||||
|
import com.epmet.commons.tools.utils.EpmetRequestHolder; |
||||
|
import com.epmet.commons.tools.utils.Result; |
||||
|
import com.epmet.service.SdtService; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.web.bind.annotation.GetMapping; |
||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||
|
import org.springframework.web.bind.annotation.RequestParam; |
||||
|
import org.springframework.web.bind.annotation.RestController; |
||||
|
|
||||
|
/** |
||||
|
* 山东通controller |
||||
|
*/ |
||||
|
@RestController |
||||
|
@RequestMapping("sdt") |
||||
|
public class SdtController { |
||||
|
|
||||
|
@Autowired |
||||
|
private SdtService sdtService; |
||||
|
|
||||
|
/** |
||||
|
* 刷新山东通token |
||||
|
* @author wxz |
||||
|
* @date 2022/11/2 22:11 |
||||
|
* @return Result |
||||
|
*/ |
||||
|
@GetMapping("refreshAccessToken") |
||||
|
public Result refreshAccessToken() { |
||||
|
sdtService.refreshAccessToken(null); |
||||
|
return new Result(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 查询山东通AccesToken |
||||
|
* @author wxz |
||||
|
* @date 2022/11/3 10:12 |
||||
|
* |
||||
|
* * @return Result<String> |
||||
|
*/ |
||||
|
@GetMapping("getCachedAccessToken") |
||||
|
public Result<String> getCachedAccessToken(@RequestParam("customerId") String customerId) { |
||||
|
String cachedAccessToken = sdtService.getCachedAccessToken(EpmetRequestHolder.getLoginUserCustomerId()); |
||||
|
return new Result<String>().ok(cachedAccessToken); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,16 @@ |
|||||
|
package com.epmet.dao; |
||||
|
|
||||
|
import com.epmet.commons.mybatis.dao.BaseDao; |
||||
|
import com.epmet.entity.SdtAppInfoEntity; |
||||
|
import org.apache.ibatis.annotations.Mapper; |
||||
|
|
||||
|
/** |
||||
|
* 接入山东通app信息 |
||||
|
* |
||||
|
* @author generator generator@elink-cn.com |
||||
|
* @since v1.0.0 2022-11-02 |
||||
|
*/ |
||||
|
@Mapper |
||||
|
public interface SdtAppInfoDao extends BaseDao<SdtAppInfoEntity> { |
||||
|
|
||||
|
} |
@ -0,0 +1,54 @@ |
|||||
|
package com.epmet.entity; |
||||
|
|
||||
|
import com.baomidou.mybatisplus.annotation.TableName; |
||||
|
|
||||
|
import com.epmet.commons.mybatis.entity.BaseEpmetEntity; |
||||
|
import lombok.Data; |
||||
|
import lombok.EqualsAndHashCode; |
||||
|
|
||||
|
import java.util.Date; |
||||
|
|
||||
|
/** |
||||
|
* 接入山东通app信息 |
||||
|
* |
||||
|
* @author generator generator@elink-cn.com |
||||
|
* @since v1.0.0 2022-11-02 |
||||
|
*/ |
||||
|
@Data |
||||
|
@EqualsAndHashCode(callSuper=false) |
||||
|
@TableName("sdt_app_info") |
||||
|
public class SdtAppInfoEntity extends BaseEpmetEntity { |
||||
|
|
||||
|
private static final long serialVersionUID = 1L; |
||||
|
|
||||
|
/** |
||||
|
* 客户ID |
||||
|
*/ |
||||
|
private String customerId; |
||||
|
|
||||
|
/** |
||||
|
* 组织ID |
||||
|
*/ |
||||
|
private String corpId; |
||||
|
|
||||
|
/** |
||||
|
* 秘钥 |
||||
|
*/ |
||||
|
private String corpSecret; |
||||
|
|
||||
|
/** |
||||
|
* api地址 |
||||
|
*/ |
||||
|
private String apiAddress; |
||||
|
|
||||
|
/** |
||||
|
* 接口调用凭证 |
||||
|
*/ |
||||
|
private String accessToken; |
||||
|
|
||||
|
/** |
||||
|
* 何时过期 |
||||
|
*/ |
||||
|
private Date expiresAt; |
||||
|
|
||||
|
} |
@ -0,0 +1,35 @@ |
|||||
|
package com.epmet.service; |
||||
|
|
||||
|
import com.zaxxer.hikari.util.FastList; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
/** |
||||
|
* @ClassName SdtService |
||||
|
* @Description 山东通相关service |
||||
|
* @Author wangxianzhang |
||||
|
* @Date 2022/11/2 22:02 |
||||
|
*/ |
||||
|
public interface SdtService { |
||||
|
|
||||
|
/** |
||||
|
* 获取accessToken的url地址 |
||||
|
* /cgi-bin/gettoken?corpid=id&corpsecret=secrect |
||||
|
*/ |
||||
|
String API_GET_ACCESS_TOKEN_URL = "/cgi-bin/gettoken"; |
||||
|
|
||||
|
/** |
||||
|
* 刷新token |
||||
|
* @author wxz |
||||
|
* @date 2022/11/2 22:50 |
||||
|
*/ |
||||
|
void refreshAccessToken(String customerId); |
||||
|
|
||||
|
/** |
||||
|
* 获取缓存的AccessToken |
||||
|
* @author wxz |
||||
|
* @date 2022/11/2 22:56 |
||||
|
* |
||||
|
* * @return String |
||||
|
*/ |
||||
|
String getCachedAccessToken(String customerId); |
||||
|
} |
@ -0,0 +1,156 @@ |
|||||
|
package com.epmet.service.impl; |
||||
|
|
||||
|
import com.alibaba.fastjson.JSON; |
||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
||||
|
import com.epmet.commons.tools.redis.RedisKeys; |
||||
|
import com.epmet.commons.tools.redis.RedisUtils; |
||||
|
import com.epmet.commons.tools.utils.HttpClientManager; |
||||
|
import com.epmet.commons.tools.utils.Result; |
||||
|
import com.epmet.dao.SdtAppInfoDao; |
||||
|
import com.epmet.entity.SdtAppInfoEntity; |
||||
|
import com.epmet.sdt.SdtGetAccessTokenResult; |
||||
|
import com.epmet.service.SdtService; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.apache.commons.lang3.StringUtils; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
|
||||
|
import java.util.*; |
||||
|
|
||||
|
/** |
||||
|
* @ClassName SdtServiceImpl |
||||
|
* @Description 山东通相关service |
||||
|
* @Author wangxianzhang |
||||
|
* @Date 2022/11/2 22:03 |
||||
|
*/ |
||||
|
@Service |
||||
|
@Slf4j |
||||
|
public class SdtServiceImpl implements SdtService { |
||||
|
|
||||
|
@Autowired |
||||
|
private SdtAppInfoDao sdtAppInfoDao; |
||||
|
|
||||
|
@Autowired |
||||
|
private RedisUtils redisUtils; |
||||
|
|
||||
|
/** |
||||
|
* 刷新accessToken |
||||
|
* @author wxz |
||||
|
* @date 2022/11/2 22:53 |
||||
|
*/ |
||||
|
@Override |
||||
|
public void refreshAccessToken(String customerId) { |
||||
|
List<SdtAppInfoEntity> appInfos; |
||||
|
|
||||
|
if (StringUtils.isBlank(customerId)) { |
||||
|
// 没传递customerId,刷新所有
|
||||
|
appInfos = sdtAppInfoDao.selectList(new QueryWrapper<>()); |
||||
|
} else { |
||||
|
// 传递了customerId,只刷新该客户的
|
||||
|
LambdaQueryWrapper<SdtAppInfoEntity> query = new LambdaQueryWrapper<>(); |
||||
|
query.eq(SdtAppInfoEntity::getCustomerId, customerId); |
||||
|
appInfos = sdtAppInfoDao.selectList(query); |
||||
|
} |
||||
|
|
||||
|
appInfos.stream().forEach(app -> { |
||||
|
Date now = new Date(); |
||||
|
String apiAddress = app.getApiAddress(); |
||||
|
String customerIdInner = app.getCustomerId(); |
||||
|
|
||||
|
HashMap<String, Object> params = new HashMap<>(); |
||||
|
params.put("corpid", app.getCorpId()); |
||||
|
params.put("corpsecret", app.getCorpSecret()); |
||||
|
Result<String> stringResult = HttpClientManager.getInstance().sendGet(apiAddress + API_GET_ACCESS_TOKEN_URL, params); |
||||
|
if (!stringResult.success()) { |
||||
|
// 请求有问题
|
||||
|
log.error("【山东通】刷新accessToken出现异常:{}", stringResult.getMsg()); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
SdtGetAccessTokenResult sdtResult = JSON.parseObject(stringResult.getMsg(), SdtGetAccessTokenResult.class); |
||||
|
if (!sdtResult.success()) { |
||||
|
log.error("【山东通】刷新accessToken失败:{}", sdtResult.getErrmsg()); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
String access_token = sdtResult.getAccess_token(); |
||||
|
Long expires_in = sdtResult.getExpires_in(); |
||||
|
|
||||
|
SdtAppInfoEntity updateEntity = new SdtAppInfoEntity(); |
||||
|
updateEntity.setId(app.getId()); |
||||
|
updateEntity.setAccessToken(access_token); |
||||
|
updateEntity.setExpiresAt(getExpireAt(now, expires_in)); |
||||
|
sdtAppInfoDao.updateById(updateEntity); |
||||
|
|
||||
|
// token刷新了以后,要刷新缓存中的token,这样下次才能获取到最新的token
|
||||
|
String key = RedisKeys.getOpenApiAccessTokenKey(customerIdInner); |
||||
|
|
||||
|
redisUtils.set(key, access_token, expires_in); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 计算过期时间 |
||||
|
* @author wxz |
||||
|
* @date 2022/11/2 23:22 |
||||
|
* * @param startTime |
||||
|
* @param expires_in |
||||
|
* * @return Date |
||||
|
*/ |
||||
|
private Date getExpireAt(Date startTime, Long expires_in) { |
||||
|
Calendar calendar = Calendar.getInstance(); |
||||
|
calendar.setTime(startTime); |
||||
|
calendar.add(Calendar.SECOND, expires_in.intValue()); |
||||
|
return calendar.getTime(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 还有多少秒过期 |
||||
|
* @author wxz |
||||
|
* @date 2022/11/3 10:08 |
||||
|
* * @param expireAt |
||||
|
* * @return Long |
||||
|
*/ |
||||
|
private Long getExpireIn(Date expireAt) { |
||||
|
return expireAt.getTime() - System.currentTimeMillis(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取缓存的AccessToken |
||||
|
* @author wxz |
||||
|
* @date 2022/11/2 22:56 |
||||
|
* |
||||
|
* * @return String |
||||
|
*/ |
||||
|
@Override |
||||
|
public String getCachedAccessToken(String customerId) { |
||||
|
String key = RedisKeys.getOpenApiAccessTokenKey(customerId); |
||||
|
String accessToken = redisUtils.getString(key); |
||||
|
if (StringUtils.isNotBlank(accessToken)) { |
||||
|
return accessToken; |
||||
|
} |
||||
|
|
||||
|
// db中查询
|
||||
|
LambdaQueryWrapper<SdtAppInfoEntity> query = new LambdaQueryWrapper<>(); |
||||
|
query.eq(SdtAppInfoEntity::getCustomerId, customerId); |
||||
|
SdtAppInfoEntity sdtAppInfoEntity = sdtAppInfoDao.selectOne(query); |
||||
|
|
||||
|
if (sdtAppInfoEntity == null) { |
||||
|
log.error("【查询山东通AccessToken】失败,原因:该客户id没有配置山东通相关信息"); |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
accessToken = sdtAppInfoEntity.getAccessToken(); |
||||
|
Date expiresAt = sdtAppInfoEntity.getExpiresAt(); |
||||
|
|
||||
|
if (StringUtils.isNotBlank(accessToken)) { |
||||
|
redisUtils.set(key, accessToken, getExpireIn(expiresAt)); |
||||
|
return accessToken; |
||||
|
} else { |
||||
|
// 配置了appInfo,但是没有accessToken,刷新token,刷新缓存,然后重新从缓存中取
|
||||
|
refreshAccessToken(customerId); |
||||
|
return redisUtils.getString(key); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,19 @@ |
|||||
|
create table sdt_app_info |
||||
|
( |
||||
|
`ID` varchar(64) NOT NULL COMMENT '主键', |
||||
|
`CUSTOMER_ID` varchar(64) NOT NULL COMMENT '客户ID', |
||||
|
`CORPID` varchar(32) not null comment '组织ID', |
||||
|
`CORPSECRET` varchar(64) not null comment '秘钥', |
||||
|
`ACCESS_TOKEN` varchar(512) not null comment '接口调用凭证', |
||||
|
`API_ADDRESS` varchar(128) not null comment 'api地址', |
||||
|
`EXPIRES_AT` datetime not null comment '何时过期', |
||||
|
`DEL_FLAG` int(11) NOT NULL COMMENT '删除标识:0.未删除 1.已删除', |
||||
|
`REVISION` int(11) NOT NULL COMMENT '乐观锁', |
||||
|
`CREATED_BY` varchar(64) NOT NULL COMMENT '创建人', |
||||
|
`CREATED_TIME` datetime NOT NULL COMMENT '创建时间', |
||||
|
`UPDATED_BY` varchar(64) NOT NULL COMMENT '更新人', |
||||
|
`UPDATED_TIME` datetime NOT NULL COMMENT '更新时间', |
||||
|
PRIMARY KEY (`ID`) |
||||
|
) ENGINE = InnoDB |
||||
|
DEFAULT CHARSET = utf8mb4 COMMENT ='接入山东通app信息'; |
||||
|
|
@ -0,0 +1,22 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
||||
|
|
||||
|
<mapper namespace="com.epmet.dao.SdtAppInfoDao"> |
||||
|
|
||||
|
<resultMap type="com.epmet.entity.SdtAppInfoEntity" id="sdtAppInfoMap"> |
||||
|
<result property="id" column="ID"/> |
||||
|
<result property="customerId" column="CUSTOMER_ID"/> |
||||
|
<result property="corpId" column="CORP_ID"/> |
||||
|
<result property="corpSecret" column="CORP_SECRET"/> |
||||
|
<result property="accessToken" column="ACCESS_TOKEN"/> |
||||
|
<result property="expiresAt" column="EXPIRES_AT"/> |
||||
|
<result property="delFlag" column="DEL_FLAG"/> |
||||
|
<result property="revision" column="REVISION"/> |
||||
|
<result property="createdBy" column="CREATED_BY"/> |
||||
|
<result property="createdTime" column="CREATED_TIME"/> |
||||
|
<result property="updatedBy" column="UPDATED_BY"/> |
||||
|
<result property="updatedTime" column="UPDATED_TIME"/> |
||||
|
</resultMap> |
||||
|
|
||||
|
|
||||
|
</mapper> |
Loading…
Reference in new issue