Commit 8d22d6e1 by lijinqi

Merge branch 'api' into develop

# Conflicts:
#	computility-module-apihub/src/main/java/com/luhu/computility/module/apihub/dal/mysql/apicalllog/ApiCallLogMapper.java
#	computility-module-apihub/src/main/java/com/luhu/computility/module/apihub/dal/mysql/apiorder/ApiOrderMapper.java
#	computility-module-apihub/src/main/java/com/luhu/computility/module/apihub/service/apicalllog/ApiCallLogServiceImpl.java
#	computility-module-apihub/src/main/java/com/luhu/computility/module/apihub/service/apiorder/ApiOrderServiceImpl.java
parents 134aedb9 da36632f
......@@ -42,6 +42,19 @@
<artifactId>computility-spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.luhu</groupId>-->
<!-- <artifactId>computility-module-external</artifactId>-->
<!-- <version>${revision}</version>-->
<!-- </dependency>-->
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-module-apihub-biz</artifactId>
<version>${revision}</version>
</dependency>
</dependencies>
</project>
package com.luhu.computility.framework.signature.core.aop;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.alibaba.fastjson.JSON;
import com.luhu.computility.framework.common.exception.ServiceException;
import com.luhu.computility.framework.common.exception.enums.GlobalErrorCodeConstants;
import com.luhu.computility.framework.common.pojo.CommonResult;
import com.luhu.computility.framework.common.util.servlet.ServletUtils;
import com.luhu.computility.framework.signature.core.annotation.ApiSignature;
import com.luhu.computility.framework.signature.core.redis.ApiSignatureRedisDAO;
import com.luhu.computility.module.apihub.controller.admin.apicalllog.vo.ApiCallLogSaveReqVO;
import com.luhu.computility.module.apihub.controller.admin.userapiusage.vo.JoinUserApiUsageResult;
import com.luhu.computility.module.apihub.dal.dataobject.apiendpoint.ApiEndpointDO;
import com.luhu.computility.module.apihub.dal.dataobject.appcredential.AppCredentialDO;
import com.luhu.computility.module.apihub.service.apicalllog.ApiCallLogService;
import com.luhu.computility.module.apihub.service.apiendpoint.ApiEndpointService;
import com.luhu.computility.module.apihub.service.appcredential.AppCredentialService;
import com.luhu.computility.module.apihub.service.userapiusage.UserApiUsageService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.SortedMap;
import java.util.TreeMap;
import static com.luhu.computility.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
import static com.luhu.computility.module.apihub.enums.ErrorCodeConstants.API_ENDPOINT_EXPIRED;
import static com.luhu.computility.module.apihub.enums.ErrorCodeConstants.API_ENDPOINT_NOT_AVAILABLE;
import static com.luhu.computility.module.apihub.enums.ErrorCodeConstants.API_ENDPOINT_NOT_EXISTS;
import static com.luhu.computility.module.apihub.enums.ErrorCodeConstants.INVALID_APPID;
import static com.luhu.computility.module.apihub.enums.ErrorCodeConstants.TIMESTAMP_EXCEPTION;
/**
* 拦截声明了 {@link ApiSignature} 注解的方法,实现签名
......@@ -37,51 +54,152 @@ public class ApiSignatureAspect {
private final ApiSignatureRedisDAO signatureRedisDAO;
@Before("@annotation(signature)")
public void beforePointCut(JoinPoint joinPoint, ApiSignature signature) {
// 1. 验证通过,直接结束
if (verifySignature(signature, Objects.requireNonNull(ServletUtils.getRequest()))) {
return;
@Resource
private AppCredentialService appCredentialService;
@Resource
private ApiEndpointService appEndpointService;
@Resource
private ApiCallLogService apiCallLogService;
@Resource
private UserApiUsageService userApiUsageService;
public ApiSignatureAspect(ApiSignatureRedisDAO signatureRedisDAO) {
this.signatureRedisDAO = signatureRedisDAO;
}
@Around("@annotation(signature)")
public Object aroundPointCut(ProceedingJoinPoint joinPoint, ApiSignature signature) throws Throwable {
HttpServletRequest request = Objects.requireNonNull(ServletUtils.getRequest());
// 1.校验 Header
/* if (!verifyHeaders(signature, request)) {
throw new ServiceException(HEAD_EXCEPTION);
}*/
//查询appId对应的Secret
String appId = request.getHeader(signature.appId());
AppCredentialDO appCredentialDO = appCredentialService.getAppSecretByAppid(appId);
if (!ObjectUtil.isEmpty(appCredentialDO)) {
Assert.notNull(appCredentialDO.getAppId(), "[appId({})] 找不到对应的 appSecret", appId);
} else {
throw new ServiceException(INVALID_APPID);
}
// 2. 签名校验
/*if (!verifySignature(signature, request, appCredentialDO)) {
log.error("[aroundPointCut][方法 {} 参数({}) 签名失败]", joinPoint.getSignature(), joinPoint.getArgs());
throw new ServiceException(BAD_REQUEST.getCode(),
StrUtil.blankToDefault(signature.message(), BAD_REQUEST.getMsg()));
}*/
// 2. 应用-接口绑定校验
String path = request.getRequestURI();
String method = request.getMethod();
//2.1是否有该接口
ApiEndpointDO apiEndpoint = appEndpointService.getApiEndpointByPathAndMethod(path, method);
if (Objects.isNull(apiEndpoint)) {
throw new ServiceException(API_ENDPOINT_NOT_EXISTS);
}
//2.2该接口是否订阅过
List<JoinUserApiUsageResult> joinUserApiUsageResults = userApiUsageService.selectJoinUserApiUsageResult(appCredentialDO.getUserId(), apiEndpoint.getId());
if (CollectionUtil.isEmpty(joinUserApiUsageResults)){
throw new ServiceException(API_ENDPOINT_NOT_AVAILABLE);
}
//3. 用户套餐校验(只校验,不扣减)如果有一个套餐符合条件,则继续往下走
JoinUserApiUsageResult joinUserApiUsageResult = null;
LocalDateTime now = LocalDateTime.now();
for (JoinUserApiUsageResult j : joinUserApiUsageResults) {
// 未过期且有剩余额度
if (j.getExpireTime().isAfter(now) && j.getUsedTimes() < j.getPackageTimes()) {
if (joinUserApiUsageResult == null || j.getExpireTime().isBefore(joinUserApiUsageResult.getExpireTime())) {
joinUserApiUsageResult = j;
}
}
}
if (Objects.isNull(joinUserApiUsageResult)) {
throw new ServiceException(API_ENDPOINT_EXPIRED);
}
// 4. 执行目标方法
Object result = joinPoint.proceed();
// 2. 验证不通过,抛出异常
log.error("[beforePointCut][方法{} 参数({}) 签名失败]", joinPoint.getSignature().toString(),
joinPoint.getArgs());
throw new ServiceException(BAD_REQUEST.getCode(),
StrUtil.blankToDefault(signature.message(), BAD_REQUEST.getMsg()));
// 5. 只有当接口执行成功才扣减额度
ApiCallLogSaveReqVO apiCallLogSaveReqVO = new ApiCallLogSaveReqVO();
if (result instanceof CommonResult) {
if (((CommonResult<?>) result).isSuccess()){
consumeUsage(joinUserApiUsageResults, apiEndpoint.getConsumptionPoints());
apiCallLogSaveReqVO.setResponseStatus(((CommonResult<?>) result).getCode().toString());
}
String requestBody = ServletUtils.isJsonRequest(request) ? ServletUtils.getBody(request) : null;
apiCallLogService.createApiCallLog(
apiCallLogSaveReqVO
.setUserId(appCredentialDO.getUserId())
.setCallTime(LocalDateTime.now())
.setMethod(method)
.setPath(path)
.setApiEndpointName(apiEndpoint.getName())
.setRequestParams(requestBody)
.setResponseParams(JSON.toJSONString(result))
);
}
return result;
}
public boolean verifySignature(ApiSignature signature, HttpServletRequest request) {
// 1.1 校验 Header
if (!verifyHeaders(signature, request)) {
return false;
/** 扣减一次额度(优先扣最近过期的套餐,用 Redis 保证并发安全) */
private void consumeUsage(List<JoinUserApiUsageResult> joinUserApiUsageResults, Integer consumptionPoints) {
JoinUserApiUsageResult target = null;
LocalDateTime now = LocalDateTime.now();
// 找到过期时间最早且可用的套餐
for (JoinUserApiUsageResult j : joinUserApiUsageResults) {
if (!ObjectUtil.isEmpty(j.getExpireTime()) && j.getExpireTime().isAfter(now)
&& j.getUsedTimes() < j.getPackageTimes()) {
if (ObjectUtil.isEmpty(target) || j.getExpireTime().isBefore(target.getExpireTime())) {
target = j;
}
}
}
// Redis key:USAGE_KEY + apiEndpointId + userId
String key = ApiSignatureRedisDAO.USAGE_KEY + target.getApiEndPointId() + target.getUserId();
// 自增使用次数
Integer used = signatureRedisDAO.incrementUsageWithExpire(key, consumptionPoints.longValue());
if (!ObjectUtil.isEmpty(used) && used <= target.getPackageTimes()) {
// 异步回写 DB
userApiUsageService.asyncUpdateUsage(target.getId(), used);
}
}
public boolean verifySignature(ApiSignature signature, HttpServletRequest request, AppCredentialDO appCredentialDO) {
// 1.2 校验 appId 是否能获取到对应的 appSecret
String appId = request.getHeader(signature.appId());
String appSecret = signatureRedisDAO.getAppSecret(appId);
Assert.notNull(appSecret, "[appId({})] 找不到对应的 appSecret", appId);
// 2. 校验签名【重要!】
String clientSignature = request.getHeader(signature.sign()); // 客户端签名
String serverSignatureString = buildSignatureString(signature, request, appSecret); // 服务端签名字符串
String serverSignatureString = buildSignatureString(signature, request, appCredentialDO.getAppSecret()); // 服务端签名字符串
String serverSignature = DigestUtil.sha256Hex(serverSignatureString); // 服务端签名
log.error(DigestUtil.sha256Hex(serverSignatureString));
if (ObjUtil.notEqual(clientSignature, serverSignature)) {
return false;
}
// 3. 将 nonce 记入缓存,防止重复使用(重点二:此处需要将 ttl 设定为允许 timestamp 时间差的值 x 2 )
String nonce = request.getHeader(signature.nonce());
if (BooleanUtil.isFalse(signatureRedisDAO.setNonce(appId, nonce, signature.timeout() * 2, signature.timeUnit()))) {
String timestamp = request.getHeader(signature.timestamp());
log.info("[verifySignature][appId({}) timestamp({}) nonce({}) sign({}) 存在重复请求]", appId, timestamp, nonce, clientSignature);
throw new ServiceException(GlobalErrorCodeConstants.REPEATED_REQUESTS.getCode(), "存在重复请求");
}
signatureRedisDAO.setNonce(appId, nonce, signature.timeout() * 2, signature.timeUnit());
return true;
}
/**
* 校验请求头加签参数
* <p>
*
* 1. appId 是否为空
* 2. timestamp 是否为空,请求是否已经超时,默认 10 分钟
* 3. nonce 是否为空,随机数是否 10 位以上,是否在规定时间内已经访问过了
......@@ -113,18 +231,21 @@ public class ApiSignatureAspect {
// 2. 检查 timestamp 是否超出允许的范围 (重点一:此处需要取绝对值)
long expireTime = signature.timeUnit().toMillis(signature.timeout());
long requestTimestamp = Long.parseLong(timestamp);
log.error("当前时间:"+System.currentTimeMillis()+"");;
long timestampDisparity = Math.abs(System.currentTimeMillis() - requestTimestamp);
if (timestampDisparity > expireTime) {
return false;
throw new ServiceException(TIMESTAMP_EXCEPTION);
}
// 3. 检查 nonce 是否存在,有且仅能使用一次
return signatureRedisDAO.getNonce(appId, nonce) == null;
}
/**
* 构建签名字符串
* <p>
*
* 格式为 = 请求参数 + 请求体 + 请求头 + 密钥
*
* @param signature signature
......@@ -133,19 +254,17 @@ public class ApiSignatureAspect {
* @return 签名字符串
*/
private String buildSignatureString(ApiSignature signature, HttpServletRequest request, String appSecret) {
SortedMap<String, String> parameterMap = getRequestParameterMap(request); // 请求头
SortedMap<String, String> headerMap = getRequestHeaderMap(signature, request); // 请求参数
String requestBody = StrUtil.nullToDefault(ServletUtils.getBody(request), ""); // 请求体
return MapUtil.join(parameterMap, "&", "=")
+ requestBody
+ MapUtil.join(headerMap, "&", "=")
+ appSecret;
log.error(MapUtil.join(headerMap, "&", "=")
+ "&appSecret=" + appSecret);
return MapUtil.join(headerMap, "&", "=")
+ "&appSecret=" + appSecret;
}
/**
* 获取请求头加签参数 Map
*
* @param request 请求
* @param request 请求
* @param signature 签名注解
* @return signature params
*/
......
package com.luhu.computility.framework.signature.core.redis;
import cn.hutool.core.util.BooleanUtil;
import lombok.AllArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
......@@ -25,6 +26,11 @@ public class ApiSignatureRedisDAO {
private static final String SIGNATURE_NONCE = "api_signature_nonce:%s:%s";
/**
* 用户套餐使用次数 Key 前缀
*/
public static final String USAGE_KEY = "api_usage:";
/**
* 签名密钥
* <p>
* HASH 结构
......@@ -54,4 +60,54 @@ public class ApiSignatureRedisDAO {
return (String) stringRedisTemplate.opsForHash().get(SIGNATURE_APPID, appId);
}
// ========== 用户套餐使用次数 ==========
/**
* 原子自增用户套餐使用次数
*
* @param key Redis key(USAGE_KEY + apiEndpointId + userId)
* @return 当前使用次数
*/
public Long incrementUsage(String key) {
return stringRedisTemplate.opsForValue().increment(key, 1);
}
/**
* 获取用户套餐已使用次数
*
* @param key Redis key
* @return 使用次数
*/
public Long getUsage(String key) {
String value = stringRedisTemplate.opsForValue().get(key);
if (value == null) {
return 0L;
}
try {
return Long.parseLong(value);
} catch (NumberFormatException e) {
return 0L;
}
}
/**
* 重置用户套餐使用次数(可选,用于测试或套餐刷新)
*/
public void resetUsage(String key) {
stringRedisTemplate.opsForValue().set(key, "0");
}
/**
* 增加用户套餐使用次数,并设置过期时间
*
* @param key Redis key
* @return 当前使用次数
*/
public Integer incrementUsageWithExpire(String key, Long consumptionPoints) {
Integer used = stringRedisTemplate.opsForValue().increment(key, consumptionPoints).intValue();
return used;
}
}
......@@ -66,9 +66,9 @@ public class ApiSignatureTest {
when(signatureRedisDAO.setNonce(eq(appId), eq(nonce), eq(120), eq(TimeUnit.SECONDS))).thenReturn(true);
// 调用
boolean result = apiSignatureAspect.verifySignature(apiSignature, request);
//boolean result = apiSignatureAspect.verifySignature(apiSignature, request);
// 断言结果
assertTrue(result);
// assertTrue(result);
}
}
\ No newline at end of file
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.luhu</groupId>
<artifactId>computility-module-apihub</artifactId>
<version>${revision}</version>
</parent>
<artifactId>computility-module-apihub-api</artifactId>
<packaging>jar</packaging>
<name>computility-module-apihub-api</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-common</artifactId>
</dependency>
<!-- 参数校验 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>
package com.luhu.computility.module.apihub.api.apicalllog;
import com.luhu.computility.module.apihub.api.apicalllog.dto.ApiCallLogPageReqDTO;
import com.luhu.computility.module.apihub.api.apicalllog.dto.ApiCallLogRespDTO;
import java.util.List;
/**
* @version 1.0
* @Author ljq
* @Date 2025/9/13
* @注释
*/
public interface ApiCallLogApi {
/**
* 获得API 调用日志列表
* @param apiCallLogPageReqDTO
* @return
*/
List<ApiCallLogRespDTO> getApiCallLogList(ApiCallLogPageReqDTO apiCallLogPageReqDTO);
}
package com.luhu.computility.module.apihub.api.apicalllog.dto;
import com.luhu.computility.framework.common.pojo.PageParam;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static com.luhu.computility.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Data
public class ApiCallLogPageReqDTO extends PageParam {
private String userMobile;
private Long userId;
private String apiEndpointName;
private String responseStatus;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] callTime;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.api.apicalllog.dto;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
@Data
public class ApiCallLogRespDTO {
private Long id;
private Long userId;
private String userMobile;
private String apiEndpointName;
private String method;
private String path;
private String requestParams;
private String responseParams;
private String responseStatus;
private LocalDateTime callTime;
private String remark;
private LocalDateTime createTime;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.api.apicalllog.dto;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
@Data
public class ApiCallLogSaveReqDTO {
private Long id;
private Long userId;
private String apiEndpointName;
private String method;
private String path;
private String requestParams;
private String responseStatus;
private String responseParams;
private LocalDateTime callTime;
private String remark;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.api.apiorder;
import com.luhu.computility.module.apihub.api.apiorder.dto.ApiOrderPageReqDTO;
import com.luhu.computility.module.apihub.api.apiorder.dto.ApiOrderRespDTO;
import java.util.List;
/**
* @version 1.0
* @Author ljq
* @Date 2025/9/13
* @注释
*/
public interface ApiOrderApi {
List<ApiOrderRespDTO> getOrderList(ApiOrderPageReqDTO apiOrderPageReqDTO);
}
package com.luhu.computility.module.apihub.api.apiorder.dto;
import com.luhu.computility.framework.common.pojo.PageParam;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static com.luhu.computility.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Data
public class ApiOrderPageReqDTO extends PageParam {
private Long userId;
private Long apiId;
private Long packageId;
private String orderNo;
private Integer status;
private Long payOrderId;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] payTime;
private String payChannelCode;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.api.apiorder.dto;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class ApiOrderRespDTO {
private Long id;
private Long userId;
private String userMobile;
private Long apiId;
private String apiName;
private Long packageId;
private String packageName;
private Integer packageTimes;
private Integer packagePrice;
private Integer packageValidDays;
private String orderNo;
private Integer costPrice;
private Integer status;
private String statusName;
private Integer payStatus;
private String payStatusName;
private Long payOrderId;
private LocalDateTime payTime;
private String payChannelCode;
private LocalDateTime finishTime;
private LocalDateTime cancelTime;
private String remark;
private LocalDateTime createTime;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.api.apiorder.dto;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
@Data
public class ApiOrderSaveReqDTO {
private Long id;
@NotNull(message = "下单用户ID不能为空")
private Long userId;
@NotNull(message = "购买的API ID不能为空")
private Long apiId;
@NotNull(message = "购买的套餐ID不能为空")
private Long packageId;
@NotEmpty(message = "订单编号不能为空")
private String orderNo;
@NotNull(message = "订单实际支付金额(分)不能为空")
private Integer costPrice;
private Integer status;
private Long payOrderId;
private LocalDateTime payTime;
private String payChannelCode;
private LocalDateTime finishTime;
private LocalDateTime cancelTime;
private Integer payStatus;
private String remark;
}
\ No newline at end of file
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.luhu</groupId>
<artifactId>computility-module-apihub</artifactId>
<version>${revision}</version>
</parent>
<artifactId>computility-module-apihub-biz</artifactId>
<packaging>jar</packaging>
<name>computility-module-apihub-biz</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-module-apihub-api</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-module-pay</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-module-member</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-module-system</artifactId>
<version>${revision}</version>
</dependency>
<!-- 业务组件 -->
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-spring-boot-starter-biz-tenant</artifactId>
</dependency>
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-spring-boot-starter-biz-ip</artifactId>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-spring-boot-starter-security</artifactId>
</dependency>
<!-- DB 相关 -->
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-spring-boot-starter-mybatis</artifactId>
</dependency>
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-spring-boot-starter-redis</artifactId>
</dependency>
<!-- Test 测试相关 -->
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-spring-boot-starter-test</artifactId>
</dependency>
<!-- 工具类相关 -->
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-spring-boot-starter-excel</artifactId>
</dependency>
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-module-biz</artifactId>
<version>${revision}</version>
</dependency>
</dependencies>
</project>
package com.luhu.computility.module.apihub.api;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.common.util.object.BeanUtils;
import com.luhu.computility.module.apihub.api.apicalllog.ApiCallLogApi;
import com.luhu.computility.module.apihub.api.apicalllog.dto.ApiCallLogPageReqDTO;
import com.luhu.computility.module.apihub.api.apicalllog.dto.ApiCallLogRespDTO;
import com.luhu.computility.module.apihub.controller.admin.apicalllog.vo.ApiCallLogPageReqVO;
import com.luhu.computility.module.apihub.controller.admin.apicalllog.vo.ApiCallLogRespVO;
import com.luhu.computility.module.apihub.controller.admin.apicalllog.vo.ApiCallLogSaveReqVO;
import com.luhu.computility.module.apihub.controller.app.apicalllog.vo.AppApiCallLogPageReqVO;
import com.luhu.computility.module.apihub.dal.dataobject.apicalllog.ApiCallLogDO;
import com.luhu.computility.module.apihub.dal.mysql.apicalllog.ApiCallLogMapper;
import com.luhu.computility.module.apihub.service.apicalllog.ApiCallLogService;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import static com.luhu.computility.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.luhu.computility.module.apihub.enums.ErrorCodeConstants.API_CALL_LOG_NOT_EXISTS;
/**
* API 调用日志 Service 实现类
*
* @author ljq
*/
@Service
@Validated
public class ApiCallLogApiServiceImpl implements ApiCallLogApi {
@Resource
private ApiCallLogMapper apiCallLogMapper;
@Override
public List<ApiCallLogRespDTO> getApiCallLogList(ApiCallLogPageReqDTO apiCallLogPageReqDTO) {
return apiCallLogMapper.selectList(apiCallLogPageReqDTO);
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.api;
import com.luhu.computility.module.apihub.api.apicalllog.ApiCallLogApi;
import com.luhu.computility.module.apihub.api.apicalllog.dto.ApiCallLogPageReqDTO;
import com.luhu.computility.module.apihub.api.apicalllog.dto.ApiCallLogRespDTO;
import com.luhu.computility.module.apihub.api.apiorder.ApiOrderApi;
import com.luhu.computility.module.apihub.api.apiorder.dto.ApiOrderPageReqDTO;
import com.luhu.computility.module.apihub.api.apiorder.dto.ApiOrderRespDTO;
import com.luhu.computility.module.apihub.dal.mysql.apicalllog.ApiCallLogMapper;
import com.luhu.computility.module.apihub.dal.mysql.apiorder.ApiOrderMapper;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.List;
/**
* API 调用日志 Service 实现类
*
* @author ljq
*/
@Service
@Validated
public class ApiOrderApiServiceImpl implements ApiOrderApi {
@Resource
private ApiOrderMapper apiOrderMapper;
@Override
public List<ApiOrderRespDTO> getOrderList(ApiOrderPageReqDTO apiOrderPageReqDTO) {
return apiOrderMapper.selectList(apiOrderPageReqDTO);
}
}
\ No newline at end of file
......@@ -11,8 +11,10 @@ import com.luhu.computility.module.apihub.controller.admin.apipackage.vo.ApiPack
import com.luhu.computility.module.apihub.dal.dataobject.apiendpointrel.ApiEndpointRelDO;
import com.luhu.computility.module.apihub.dal.dataobject.apipackage.ApiPackageDO;
import com.luhu.computility.module.apihub.service.apiendpoint.ApiEndpointService;
import com.luhu.computility.module.apihub.service.apiendpointapplicationrel.ApiEndpointApplicationRelService;
import com.luhu.computility.module.apihub.service.apiendpointrel.ApiEndpointRelService;
import com.luhu.computility.module.apihub.service.apipackage.ApiPackageService;
import com.luhu.computility.module.biz.controller.admin.industryapplication.vo.IndustryApplicationRespVO;
import org.checkerframework.checker.units.qual.A;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
......@@ -60,6 +62,10 @@ public class ApiController {
private ApiPackageService apiPackageService;
@Resource
private ApiEndpointApplicationRelService apiEndpointApplicationRelService;
@PostMapping("/create")
@Operation(summary = "创建API信息")
@Transactional(rollbackFor = Exception.class)
......@@ -119,6 +125,7 @@ public class ApiController {
@PreAuthorize("@ss.hasPermission('apihub:api:delete')")
public CommonResult<Boolean> deleteApi(@RequestParam("id") Long id) {
apiService.deleteApi(id);
apiEndpointRelService.deleteByApiId(id);
return success(true);
}
......@@ -128,6 +135,9 @@ public class ApiController {
@PreAuthorize("@ss.hasPermission('apihub:api:delete')")
public CommonResult<Boolean> deleteApiList(@RequestParam("ids") List<Long> ids) {
apiService.deleteApiListByIds(ids);
for (Long id : ids) {
apiEndpointRelService.deleteByApiId(id);
}
return success(true);
}
......@@ -142,6 +152,11 @@ public class ApiController {
apiRespVO.setApiPackages(BeanUtils.toBean(apiPackageDOS, ApiPackageRespVO.class));
List<ApiEndpointRespVO> apiEndpointRespVOS = apiEndpointRelService.getApiEndpointByApiId(id);
/*
for (ApiEndpointRespVO apiEndpointRespVO : apiEndpointRespVOS) {
List<IndustryApplicationRespVO> industryApplicationRespVOS = apiEndpointApplicationRelService.getApplicationByApiEndpointId(apiEndpointRespVO.getId());
apiEndpointRespVO.setIndustryApplications(industryApplicationRespVOS);
}*/
apiRespVO.setApiEndPoints(apiEndpointRespVOS);
return success(apiRespVO);
......
......@@ -84,8 +84,8 @@ public class ApiCallLogController {
@Operation(summary = "获得API 调用日志分页")
@PreAuthorize("@ss.hasPermission('apihub:api-call-log:query')")
public CommonResult<PageResult<ApiCallLogRespVO>> getApiCallLogPage(@Valid ApiCallLogPageReqVO pageReqVO) {
PageResult<ApiCallLogDO> pageResult = apiCallLogService.getApiCallLogPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, ApiCallLogRespVO.class));
PageResult<ApiCallLogRespVO> pageResult = apiCallLogService.getApiCallLogPage(pageReqVO);
return success(pageResult);
}
@GetMapping("/export-excel")
......@@ -95,10 +95,9 @@ public class ApiCallLogController {
public void exportApiCallLogExcel(@Valid ApiCallLogPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<ApiCallLogDO> list = apiCallLogService.getApiCallLogPage(pageReqVO).getList();
List<ApiCallLogRespVO> list = apiCallLogService.getApiCallLogPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "API 调用日志.xls", "数据", ApiCallLogRespVO.class,
BeanUtils.toBean(list, ApiCallLogRespVO.class));
ExcelUtils.write(response, "API 调用日志.xls", "数据", ApiCallLogRespVO.class, list);
}
}
\ No newline at end of file
......@@ -5,6 +5,8 @@ import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import com.luhu.computility.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import static com.luhu.computility.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
......@@ -13,11 +15,15 @@ import static com.luhu.computility.framework.common.util.date.DateUtils.FORMAT_Y
@Data
public class ApiCallLogPageReqVO extends PageParam {
@Schema(description = "调用用户ID", example = "25965")
@Schema(description = "调用用户手机号", example = "25965")
private String userMobile;
@Schema(description = "调用用户id", example = "25965")
private Long userId;
@Schema(description = "调用的API ID", example = "11672")
private Long apiId;
@Schema(description = "接口名称", example = "11672")
private String apiEndpointName;
@Schema(description = "响应状态(如200, 500等)", example = "2")
private String responseStatus;
......
......@@ -7,6 +7,8 @@ import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
import javax.validation.constraints.NotNull;
@Schema(description = "管理后台 - API 调用日志 Response VO")
@Data
@ExcelIgnoreUnannotated
......@@ -20,14 +22,32 @@ public class ApiCallLogRespVO {
@ExcelProperty("调用用户ID")
private Long userId;
@Schema(description = "调用的API ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "11672")
@ExcelProperty("调用的API ID")
private Long apiId;
@Schema(description = "用户手机号", requiredMode = Schema.RequiredMode.REQUIRED, example = "25965")
@ExcelProperty("用户手机号")
private String userMobile;
@Schema(description = "接口名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "11672")
@NotNull(message = "接口名称不能为空")
private String apiEndpointName;
@Schema(description = "请求方法", requiredMode = Schema.RequiredMode.REQUIRED, example = "11672")
@NotNull(message = "请求方法不能为空")
private String method;
@Schema(description = "请求地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "11672")
@NotNull(message = "请求地址不能为空")
private String path;
@Schema(description = "请求参数")
@ExcelProperty("请求参数")
private String requestParams;
@Schema(description = "返回结果")
@ExcelProperty("返回结果")
private String responseParams;
@Schema(description = "响应状态(如200, 500等)", example = "2")
@ExcelProperty("响应状态(如200, 500等)")
private String responseStatus;
......
......@@ -2,9 +2,8 @@ package com.luhu.computility.module.apihub.controller.admin.apicalllog.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - API 调用日志新增/修改 Request VO")
......@@ -18,9 +17,17 @@ public class ApiCallLogSaveReqVO {
@NotNull(message = "调用用户ID不能为空")
private Long userId;
@Schema(description = "调用的API ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "11672")
@NotNull(message = "调用的API ID不能为空")
private Long apiId;
@Schema(description = "接口名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "11672")
@NotNull(message = "接口名称不能为空")
private String apiEndpointName;
@Schema(description = "请求方法", requiredMode = Schema.RequiredMode.REQUIRED, example = "11672")
@NotNull(message = "请求方法不能为空")
private String method;
@Schema(description = "请求地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "11672")
@NotNull(message = "请求地址不能为空")
private String path;
@Schema(description = "请求参数")
private String requestParams;
......@@ -28,6 +35,9 @@ public class ApiCallLogSaveReqVO {
@Schema(description = "响应状态(如200, 500等)", example = "2")
private String responseStatus;
@Schema(description = "请求参数")
private String responseParams;
@Schema(description = "调用时间")
private LocalDateTime callTime;
......
package com.luhu.computility.module.apihub.controller.admin.apiendpoint;
import com.luhu.computility.module.apihub.controller.admin.apiendpointapplicationrel.vo.ApiEndpointApplicationRelSaveReqVO;
import com.luhu.computility.module.apihub.service.apiendpointapplicationrel.ApiEndpointApplicationRelService;
import com.luhu.computility.module.biz.controller.admin.industryapplication.vo.IndustryApplicationRespVO;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
......@@ -38,11 +42,23 @@ public class ApiEndpointController {
@Resource
private ApiEndpointService apiEndpointService;
@Resource
private ApiEndpointApplicationRelService apiEndpointApplicationRelService;
@PostMapping("/create")
@Operation(summary = "创建API 接口")
@PreAuthorize("@ss.hasPermission('apihub:api-endpoint:create')")
@Transactional(rollbackFor = Exception.class)
public CommonResult<Long> createApiEndpoint(@Valid @RequestBody ApiEndpointSaveReqVO createReqVO) {
return success(apiEndpointService.createApiEndpoint(createReqVO));
Long apiEndpointId = apiEndpointService.createApiEndpoint(createReqVO);
for (IndustryApplicationRespVO industryApplicationRespVO : createReqVO.getIndustryApplications()) {
apiEndpointApplicationRelService.createApiEndpointApplicationRel(
new ApiEndpointApplicationRelSaveReqVO()
.setIndustryApplicationId(industryApplicationRespVO.getId())
.setApiEndpointId(apiEndpointId));
}
return success(apiEndpointId);
}
@PutMapping("/update")
......@@ -50,6 +66,15 @@ public class ApiEndpointController {
@PreAuthorize("@ss.hasPermission('apihub:api-endpoint:update')")
public CommonResult<Boolean> updateApiEndpoint(@Valid @RequestBody ApiEndpointSaveReqVO updateReqVO) {
apiEndpointService.updateApiEndpoint(updateReqVO);
//删除以前的
apiEndpointApplicationRelService.deleteApiEndpointApplicationRelByApiEndpointId(updateReqVO.getId());
//插入新数据
for (IndustryApplicationRespVO industryApplicationRespVO : updateReqVO.getIndustryApplications()) {
apiEndpointApplicationRelService.createApiEndpointApplicationRel(
new ApiEndpointApplicationRelSaveReqVO()
.setIndustryApplicationId(industryApplicationRespVO.getId())
.setApiEndpointId(updateReqVO.getId()));
}
return success(true);
}
......@@ -59,6 +84,7 @@ public class ApiEndpointController {
@PreAuthorize("@ss.hasPermission('apihub:api-endpoint:delete')")
public CommonResult<Boolean> deleteApiEndpoint(@RequestParam("id") Long id) {
apiEndpointService.deleteApiEndpoint(id);
apiEndpointApplicationRelService.deleteApiEndpointApplicationRelByApiEndpointId(id);
return success(true);
}
......@@ -68,6 +94,10 @@ public class ApiEndpointController {
@PreAuthorize("@ss.hasPermission('apihub:api-endpoint:delete')")
public CommonResult<Boolean> deleteApiEndpointList(@RequestParam("ids") List<Long> ids) {
apiEndpointService.deleteApiEndpointListByIds(ids);
//不常用,先偷懒循环delete
for(Long id : ids){
apiEndpointApplicationRelService.deleteApiEndpointApplicationRelByApiEndpointId(id);
}
return success(true);
}
......@@ -77,7 +107,10 @@ public class ApiEndpointController {
@PreAuthorize("@ss.hasPermission('apihub:api-endpoint:query')")
public CommonResult<ApiEndpointRespVO> getApiEndpoint(@RequestParam("id") Long id) {
ApiEndpointDO apiEndpoint = apiEndpointService.getApiEndpoint(id);
return success(BeanUtils.toBean(apiEndpoint, ApiEndpointRespVO.class));
ApiEndpointRespVO apiEndpointRespVO = BeanUtils.toBean(apiEndpoint, ApiEndpointRespVO.class);
List<IndustryApplicationRespVO> industryApplicationRespVOS = apiEndpointApplicationRelService.getApplicationByApiEndpointId(id);
apiEndpointRespVO.setIndustryApplications(industryApplicationRespVOS);
return success(apiEndpointRespVO);
}
@GetMapping("/page")
......@@ -93,8 +126,13 @@ public class ApiEndpointController {
@Operation(summary = "获得API 接口")
@PreAuthorize("@ss.hasPermission('apihub:api-endpoint:query')")
public CommonResult<List<ApiEndpointRespVO>> getApiEndpointPage() {
List<ApiEndpointDO> pageResult = apiEndpointService.getApiEndpointList();
return success(BeanUtils.toBean(pageResult, ApiEndpointRespVO.class));
List<ApiEndpointDO> apiEndpointDOS = apiEndpointService.getApiEndpointList();
List<ApiEndpointRespVO> apiEndpointRespVOS = BeanUtils.toBean(apiEndpointDOS, ApiEndpointRespVO.class);
for (ApiEndpointRespVO apiEndpointRespVO : apiEndpointRespVOS) {
List<IndustryApplicationRespVO> industryApplicationRespVOS = apiEndpointApplicationRelService.getApplicationByApiEndpointId(apiEndpointRespVO.getId());
apiEndpointRespVO.setIndustryApplications(industryApplicationRespVOS);
}
return success(apiEndpointRespVOS);
}
......
package com.luhu.computility.module.apihub.controller.admin.apiendpoint.vo;
import com.luhu.computility.module.biz.controller.admin.industryapplication.vo.IndustryApplicationRespVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
......@@ -7,6 +8,8 @@ import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
import javax.validation.constraints.NotEmpty;
@Schema(description = "管理后台 - API 接口 Response VO")
@Data
@ExcelIgnoreUnannotated
......@@ -24,6 +27,11 @@ public class ApiEndpointRespVO {
@ExcelProperty("接口路径,全路径例如 https://phsl.lijinqi.com/openn_ip/xxx")
private String path;
@Schema(description = "消费点数", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
@ExcelProperty("消费点数")
private Integer consumptionPoints;
@Schema(description = "请求方式: GET/POST/PUT/DELETE", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("请求方式: GET/POST/PUT/DELETE")
private String method;
......@@ -52,4 +60,9 @@ public class ApiEndpointRespVO {
@ExcelProperty("创建时间")
private LocalDateTime createTime;
@Schema(description = "关联行业应用", example = "[{}]")
@ExcelProperty("关联行业应用")
private List<IndustryApplicationRespVO> industryApplications;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.admin.apiendpoint.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import com.luhu.computility.module.biz.controller.admin.industryapplication.vo.IndustryApplicationRespVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
......@@ -20,6 +22,11 @@ public class ApiEndpointSaveReqVO {
@NotEmpty(message = "接口路径,全路径例如 https://phsl.lijinqi.com/openn_ip/xxx不能为空")
private String path;
@Schema(description = "消费点数", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
@ExcelProperty("消费点数")
private Integer consumptionPoints;
@Schema(description = "请求方式: GET/POST/PUT/DELETE", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "请求方式: GET/POST/PUT/DELETE不能为空")
private String method;
......@@ -39,4 +46,10 @@ public class ApiEndpointSaveReqVO {
@Schema(description = "备注", example = "你说的对")
private String remark;
@Schema(description = "关联行业应用", example = "[{}]")
@NotEmpty(message = "行业应用至少填写一个")
private List<IndustryApplicationRespVO> industryApplications;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.admin.apiendpointapplicationrel;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import com.luhu.computility.framework.common.pojo.PageParam;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.common.pojo.CommonResult;
import com.luhu.computility.framework.common.util.object.BeanUtils;
import static com.luhu.computility.framework.common.pojo.CommonResult.success;
import com.luhu.computility.framework.excel.core.util.ExcelUtils;
import com.luhu.computility.framework.apilog.core.annotation.ApiAccessLog;
import static com.luhu.computility.framework.apilog.core.enums.OperateTypeEnum.*;
import com.luhu.computility.module.apihub.controller.admin.apiendpointapplicationrel.vo.*;
import com.luhu.computility.module.apihub.dal.dataobject.apiendpointapplicationrel.ApiEndpointApplicationRelDO;
import com.luhu.computility.module.apihub.service.apiendpointapplicationrel.ApiEndpointApplicationRelService;
@Tag(name = "管理后台 - 行业应用与接口关联")
@RestController
@RequestMapping("/apihub/api-endpoint-application-rel")
@Validated
public class ApiEndpointApplicationRelController {
@Resource
private ApiEndpointApplicationRelService apiEndpointApplicationRelService;
@PostMapping("/create")
@Operation(summary = "创建行业应用与接口关联")
@PreAuthorize("@ss.hasPermission('apihub:api-endpoint-application-rel:create')")
public CommonResult<Long> createApiEndpointApplicationRel(@Valid @RequestBody ApiEndpointApplicationRelSaveReqVO createReqVO) {
return success(apiEndpointApplicationRelService.createApiEndpointApplicationRel(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新行业应用与接口关联")
@PreAuthorize("@ss.hasPermission('apihub:api-endpoint-application-rel:update')")
public CommonResult<Boolean> updateApiEndpointApplicationRel(@Valid @RequestBody ApiEndpointApplicationRelSaveReqVO updateReqVO) {
apiEndpointApplicationRelService.updateApiEndpointApplicationRel(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除行业应用与接口关联")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('apihub:api-endpoint-application-rel:delete')")
public CommonResult<Boolean> deleteApiEndpointApplicationRel(@RequestParam("id") Long id) {
apiEndpointApplicationRelService.deleteApiEndpointApplicationRel(id);
return success(true);
}
@DeleteMapping("/delete-list")
@Parameter(name = "ids", description = "编号", required = true)
@Operation(summary = "批量删除行业应用与接口关联")
@PreAuthorize("@ss.hasPermission('apihub:api-endpoint-application-rel:delete')")
public CommonResult<Boolean> deleteApiEndpointApplicationRelList(@RequestParam("ids") List<Long> ids) {
apiEndpointApplicationRelService.deleteApiEndpointApplicationRelListByIds(ids);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得行业应用与接口关联")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('apihub:api-endpoint-application-rel:query')")
public CommonResult<ApiEndpointApplicationRelRespVO> getApiEndpointApplicationRel(@RequestParam("id") Long id) {
ApiEndpointApplicationRelDO apiEndpointApplicationRel = apiEndpointApplicationRelService.getApiEndpointApplicationRel(id);
return success(BeanUtils.toBean(apiEndpointApplicationRel, ApiEndpointApplicationRelRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得行业应用与接口关联分页")
@PreAuthorize("@ss.hasPermission('apihub:api-endpoint-application-rel:query')")
public CommonResult<PageResult<ApiEndpointApplicationRelRespVO>> getApiEndpointApplicationRelPage(@Valid ApiEndpointApplicationRelPageReqVO pageReqVO) {
PageResult<ApiEndpointApplicationRelDO> pageResult = apiEndpointApplicationRelService.getApiEndpointApplicationRelPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, ApiEndpointApplicationRelRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出行业应用与接口关联 Excel")
@PreAuthorize("@ss.hasPermission('apihub:api-endpoint-application-rel:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportApiEndpointApplicationRelExcel(@Valid ApiEndpointApplicationRelPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<ApiEndpointApplicationRelDO> list = apiEndpointApplicationRelService.getApiEndpointApplicationRelPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "行业应用与接口关联.xls", "数据", ApiEndpointApplicationRelRespVO.class,
BeanUtils.toBean(list, ApiEndpointApplicationRelRespVO.class));
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.admin.apiendpointapplicationrel.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import com.luhu.computility.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static com.luhu.computility.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 行业应用与接口关联分页 Request VO")
@Data
public class ApiEndpointApplicationRelPageReqVO extends PageParam {
@Schema(description = "行业应用ID,关联 industry_application.id", example = "3247")
private Long industryApplicationId;
@Schema(description = "接口ID,关联 apihub_api_endpoint.id", example = "18744")
private Long apiEndpointId;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.admin.apiendpointapplicationrel.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - 行业应用与接口关联 Response VO")
@Data
@ExcelIgnoreUnannotated
public class ApiEndpointApplicationRelRespVO {
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "25217")
@ExcelProperty("主键")
private Long id;
@Schema(description = "行业应用ID,关联 industry_application.id", requiredMode = Schema.RequiredMode.REQUIRED, example = "3247")
@ExcelProperty("行业应用ID,关联 industry_application.id")
private Long industryApplicationId;
@Schema(description = "接口ID,关联 apihub_api_endpoint.id", requiredMode = Schema.RequiredMode.REQUIRED, example = "18744")
@ExcelProperty("接口ID,关联 apihub_api_endpoint.id")
private Long apiEndpointId;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.admin.apiendpointapplicationrel.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - 行业应用与接口关联新增/修改 Request VO")
@Data
public class ApiEndpointApplicationRelSaveReqVO {
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "25217")
private Long id;
@Schema(description = "行业应用ID,关联 industry_application.id", requiredMode = Schema.RequiredMode.REQUIRED, example = "3247")
@NotNull(message = "行业应用ID,关联 industry_application.id不能为空")
private Long industryApplicationId;
@Schema(description = "接口ID,关联 apihub_api_endpoint.id", requiredMode = Schema.RequiredMode.REQUIRED, example = "18744")
@NotNull(message = "接口ID,关联 apihub_api_endpoint.id不能为空")
private Long apiEndpointId;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.admin.apiorder;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.luhu.computility.module.apihub.controller.admin.userapiusage.vo.UserApiUsageSaveReqVO;
import com.luhu.computility.module.apihub.enums.ApiOrderPayStatus;
import com.luhu.computility.module.apihub.enums.ApiOrderStatus;
import com.luhu.computility.module.apihub.service.userapiusage.UserApiUsageService;
import com.luhu.computility.module.pay.api.notify.dto.PayOrderNotifyReqDTO;
import lombok.extern.slf4j.Slf4j;
......@@ -95,8 +98,16 @@ public class ApiOrderController {
@Operation(summary = "获得api订单分页")
@PreAuthorize("@ss.hasPermission('apihub:api-order:query')")
public CommonResult<PageResult<ApiOrderRespVO>> getApiOrderPage(@Valid ApiOrderPageReqVO pageReqVO) {
PageResult<ApiOrderDO> pageResult = apiOrderService.getApiOrderPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, ApiOrderRespVO.class));
PageResult<ApiOrderRespVO> pageResult = apiOrderService.getApiOrderPage(pageReqVO);
for (ApiOrderRespVO apiOrderRespVO : pageResult.getList()) {
apiOrderRespVO.setStatusName(ApiOrderStatus.getByValue(apiOrderRespVO.getStatus()).getRemark());
if (!ObjectUtil.isEmpty(apiOrderRespVO.getPayStatus())) {
apiOrderRespVO.setPayStatusName(ApiOrderPayStatus.getByValue(apiOrderRespVO.getPayStatus()).getRemark());
}
}
return success(pageResult);
}
@GetMapping("/export-excel")
......@@ -106,10 +117,9 @@ public class ApiOrderController {
public void exportApiOrderExcel(@Valid ApiOrderPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<ApiOrderDO> list = apiOrderService.getApiOrderPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "api订单.xls", "数据", ApiOrderRespVO.class,
BeanUtils.toBean(list, ApiOrderRespVO.class));
apiOrderService.getApiOrderPage(pageReqVO).getList());
}
/**
......
......@@ -21,6 +21,10 @@ public class ApiOrderRespVO {
@ExcelProperty("下单用户ID")
private Long userId;
@Schema(description = "下单用户手机号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3895")
@ExcelProperty("下单用户手机号")
private String userMobile;
@Schema(description = "购买的API ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "10347")
@ExcelProperty("购买的API ID")
private Long apiId;
......@@ -56,6 +60,15 @@ public class ApiOrderRespVO {
@ExcelProperty("订单状态:0=待支付,1=已支付,2=已取消")
private Integer status;
@Schema(description = "订单状态值:0=待支付,1=已支付,2=已取消", example = "2")
private String statusName;
@Schema(description = "支付状态", example = "2")
private Integer payStatus;
@Schema(description = "支付状态值", example = "2")
private String payStatusName;
@Schema(description = "支付订单编号", example = "14961")
@ExcelProperty("支付订单编号")
private Long payOrderId;
......
......@@ -53,6 +53,9 @@ public class ApiOrderSaveReqVO {
@Schema(description = "订单取消时间")
private LocalDateTime cancelTime;
@Schema(description = "支付状态", example = "2")
private Integer payStatus;
@Schema(description = "备注", example = "你说的对")
private String remark;
......
package com.luhu.computility.module.apihub.controller.admin.userapiusage.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(description = "用户对应接口 ")
@Data
@ExcelIgnoreUnannotated
public class JoinUserApiUsageResult {
@Schema(description = "记录ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "2826")
@ExcelProperty("记录ID")
private Long id;
@Schema(description = "用户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "2826")
@ExcelProperty("用户ID")
private Long userId;
@Schema(description = "接口ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "2826")
@ExcelProperty("接口ID")
private Long apiEndPointId;
@Schema(description = "接口名", requiredMode = Schema.RequiredMode.REQUIRED, example = "26592")
@ExcelProperty("接口名")
private String apiEndPintName;
@Schema(description = "购买的API应用名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "10347")
private String apiName;
@Schema(description = "购买的套餐名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "8957")
private String packageName;
@Schema(description = "套餐最大可用次数", requiredMode = Schema.RequiredMode.REQUIRED, example = "8957")
private Integer packageTimes;
@Schema(description = "套餐价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "8957")
private Integer packagePrice;
@Schema(description = "套餐有效期", requiredMode = Schema.RequiredMode.REQUIRED, example = "8957")
private Integer packageValidDays;
@Schema(description = "已使用次数", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("已使用次数")
private Integer usedTimes;
@Schema(description = "过期时间")
@ExcelProperty("过期时间")
private LocalDateTime expireTime;
@Schema(description = "备注", example = "随便")
@ExcelProperty("备注")
private String remark;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}
\ No newline at end of file
......@@ -8,6 +8,7 @@ import com.luhu.computility.framework.common.util.object.BeanUtils;
import com.luhu.computility.framework.excel.core.util.ExcelUtils;
import com.luhu.computility.module.apihub.controller.admin.api.vo.ApiPageReqVO;
import com.luhu.computility.module.apihub.controller.admin.api.vo.ApiRespVO;
import com.luhu.computility.module.apihub.controller.admin.apiendpoint.vo.ApiEndpointRespVO;
import com.luhu.computility.module.apihub.controller.admin.apipackage.vo.ApiPackageRespVO;
import com.luhu.computility.module.apihub.controller.app.api.vo.AppApiPackageRespVO;
import com.luhu.computility.module.apihub.controller.app.api.vo.AppApiRespVO;
......@@ -16,7 +17,10 @@ import com.luhu.computility.module.apihub.dal.dataobject.apicategory.ApiCategory
import com.luhu.computility.module.apihub.dal.dataobject.apipackage.ApiPackageDO;
import com.luhu.computility.module.apihub.service.api.ApiService;
import com.luhu.computility.module.apihub.service.apicategory.ApiCategoryService;
import com.luhu.computility.module.apihub.service.apiendpointapplicationrel.ApiEndpointApplicationRelService;
import com.luhu.computility.module.apihub.service.apiendpointrel.ApiEndpointRelService;
import com.luhu.computility.module.apihub.service.apipackage.ApiPackageService;
import com.luhu.computility.module.biz.controller.admin.industryapplication.vo.IndustryApplicationRespVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
......@@ -53,6 +57,14 @@ public class AppApiController {
@Resource
private ApiPackageService apiPackageService;
@Resource
private ApiEndpointRelService apiEndpointRelService;
@Resource
private ApiEndpointApplicationRelService apiEndpointApplicationRelService;
@GetMapping("/get")
@Operation(summary = "获得API信息")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
......@@ -64,6 +76,16 @@ public class AppApiController {
apiRespVO.setCategoryName(apiCategory.getName());
List<ApiPackageDO> apiPackageDOS = apiPackageService.selectByApiId(id);
apiRespVO.setApiPackages(BeanUtils.toBean(apiPackageDOS, AppApiPackageRespVO.class));
List<ApiEndpointRespVO> apiEndpointRespVOS = apiEndpointRelService.getApiEndpointByApiId(id);
for (ApiEndpointRespVO apiEndpointRespVO : apiEndpointRespVOS) {
List<IndustryApplicationRespVO> industryApplicationRespVOS = apiEndpointApplicationRelService.getApplicationByApiEndpointId(apiEndpointRespVO.getId());
apiEndpointRespVO.setIndustryApplications(industryApplicationRespVOS);
}
apiRespVO.setApiEndPoints(apiEndpointRespVOS);
return success(apiRespVO);
}
......
......@@ -2,6 +2,8 @@ package com.luhu.computility.module.apihub.controller.app.api.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.luhu.computility.module.apihub.controller.admin.apiendpoint.vo.ApiEndpointRespVO;
import com.luhu.computility.module.apihub.controller.admin.apiendpoint.vo.ApiEndpointSaveReqVO;
import com.luhu.computility.module.apihub.controller.admin.apipackage.vo.ApiPackageRespVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
......@@ -54,6 +56,9 @@ public class AppApiRespVO {
@Schema(description = "套餐包", example = "[{}]")
private List<AppApiPackageRespVO> apiPackages;
@Schema(description = "", example = "[{}]")
private List<ApiEndpointRespVO> apiEndPoints;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
......
package com.luhu.computility.module.apihub.controller.app.apicalllog;
import com.luhu.computility.framework.apilog.core.annotation.ApiAccessLog;
import com.luhu.computility.framework.common.pojo.CommonResult;
import com.luhu.computility.framework.common.pojo.PageParam;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.common.util.object.BeanUtils;
import com.luhu.computility.framework.excel.core.util.ExcelUtils;
import com.luhu.computility.framework.security.core.util.SecurityFrameworkUtils;
import com.luhu.computility.module.apihub.controller.admin.apicalllog.vo.ApiCallLogSaveReqVO;
import com.luhu.computility.module.apihub.controller.app.apicalllog.vo.AppApiCallLogPageReqVO;
import com.luhu.computility.module.apihub.controller.app.apicalllog.vo.AppApiCallLogRespVO;
import com.luhu.computility.module.apihub.dal.dataobject.apicalllog.ApiCallLogDO;
import com.luhu.computility.module.apihub.service.apicalllog.ApiCallLogService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import static com.luhu.computility.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static com.luhu.computility.framework.common.pojo.CommonResult.success;
@Tag(name = "用户端 - API 调用日志")
@RestController
@RequestMapping("/apihub/api-call-log")
@Validated
public class AppApiCallLogController {
@Resource
private ApiCallLogService apiCallLogService;
@GetMapping("/get")
@Operation(summary = "获得API 调用日志")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('apihub:api-call-log:query')")
public CommonResult<AppApiCallLogRespVO> getApiCallLog(@RequestParam("id") Long id) {
ApiCallLogDO apiCallLog = apiCallLogService.getApiCallLog(id);
return success(BeanUtils.toBean(apiCallLog, AppApiCallLogRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得API 调用日志分页")
public CommonResult<PageResult<AppApiCallLogRespVO>> getApiCallLogPage(@Valid AppApiCallLogPageReqVO pageReqVO) {
pageReqVO.setUserId(SecurityFrameworkUtils.getLoginUserId());
PageResult<ApiCallLogDO> pageResult = apiCallLogService.getAppApiCallLogPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, AppApiCallLogRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出API 调用日志 Excel")
@PreAuthorize("@ss.hasPermission('apihub:api-call-log:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportApiCallLogExcel(@Valid AppApiCallLogPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<ApiCallLogDO> list = apiCallLogService.getAppApiCallLogPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "API 调用日志.xls", "数据", AppApiCallLogRespVO.class,
BeanUtils.toBean(list, AppApiCallLogRespVO.class));
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.app.apicalllog.vo;
import com.luhu.computility.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static com.luhu.computility.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "用户端 - API 调用日志分页 Request VO")
@Data
public class AppApiCallLogPageReqVO extends PageParam {
@Schema(description = "用户id", example = "25965")
private Long userId;
@Schema(description = "调用用户手机号", example = "25965")
private String userMobile;
@Schema(description = "接口名称", example = "11672")
private String apiEndpointName;
@Schema(description = "响应状态(如200, 500等)", example = "2")
private String responseStatus;
@Schema(description = "调用时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] callTime;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.app.apicalllog.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
@Schema(description = "用户端- API 调用日志 Response VO")
@Data
@ExcelIgnoreUnannotated
public class AppApiCallLogRespVO {
@Schema(description = "调用日志ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "8682")
@ExcelProperty("调用日志ID")
private Long id;
@Schema(description = "用户手机号", requiredMode = Schema.RequiredMode.REQUIRED, example = "25965")
@ExcelProperty("用户手机号")
private String userMobile;
@Schema(description = "接口名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "11672")
@NotNull(message = "接口名称不能为空")
private String apiEndpointName;
@Schema(description = "请求方法", requiredMode = Schema.RequiredMode.REQUIRED, example = "11672")
@NotNull(message = "请求方法不能为空")
private String method;
@Schema(description = "请求地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "11672")
@NotNull(message = "请求地址不能为空")
private String path;
@Schema(description = "请求参数")
@ExcelProperty("请求参数")
private String requestParams;
@Schema(description = "返回结果")
@ExcelProperty("返回结果")
private String responseParams;
@Schema(description = "响应状态(如200, 500等)", example = "2")
@ExcelProperty("响应状态(如200, 500等)")
private String responseStatus;
@Schema(description = "调用时间")
@ExcelProperty("调用时间")
private LocalDateTime callTime;
@Schema(description = "备注", example = "你猜")
@ExcelProperty("备注")
private String remark;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.app.userapiusage;
import com.luhu.computility.framework.apilog.core.annotation.ApiAccessLog;
import com.luhu.computility.framework.common.pojo.CommonResult;
import com.luhu.computility.framework.common.pojo.PageParam;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.common.util.object.BeanUtils;
import com.luhu.computility.framework.excel.core.util.ExcelUtils;
import com.luhu.computility.framework.security.core.util.SecurityFrameworkUtils;
import com.luhu.computility.module.apihub.controller.admin.userapiusage.vo.UserApiUsagePageReqVO;
import com.luhu.computility.module.apihub.controller.admin.userapiusage.vo.UserApiUsageRespVO;
import com.luhu.computility.module.apihub.controller.app.userapiusage.vo.AppUserApiUsageRespVO;
import com.luhu.computility.module.apihub.dal.dataobject.userapiusage.UserApiUsageDO;
import com.luhu.computility.module.apihub.service.userapiusage.UserApiUsageService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
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;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import static com.luhu.computility.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static com.luhu.computility.framework.common.pojo.CommonResult.success;
@Tag(name = "用户端 - 我的资源")
@RestController
@RequestMapping("/apihub/user-api-usage")
@Validated
public class AppUserApiUsageController {
@Resource
private UserApiUsageService userApiUsageService;
@GetMapping("/get")
@Operation(summary = "获得资源管理")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
public CommonResult<AppUserApiUsageRespVO> getUserApiUsage(@RequestParam("id") Long id) {
UserApiUsageDO userApiUsage = userApiUsageService.getUserApiUsage(id);
return success(BeanUtils.toBean(userApiUsage, AppUserApiUsageRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得资源管理分页")
public CommonResult<PageResult<AppUserApiUsageRespVO>> getUserApiUsagePage(@Valid UserApiUsagePageReqVO pageReqVO) {
pageReqVO.setUserId(SecurityFrameworkUtils.getLoginUserId());
return success(userApiUsageService.getAppUserApiUsagePage(pageReqVO));
}
@GetMapping("/export-excel")
@Operation(summary = "导出用户API管理 Excel")
@PreAuthorize("@ss.hasPermission('apihub:user-api-usage:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportUserApiUsageExcel(@Valid UserApiUsagePageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
// 导出 Excel
ExcelUtils.write(response, "用户API管理.xls", "数据", AppUserApiUsageRespVO.class,
userApiUsageService.getAppUserApiUsagePage(pageReqVO).getList());
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.app.userapiusage.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(description = "用户端 - 用户 API 使用统计 Response VO")
@Data
@ExcelIgnoreUnannotated
public class AppUserApiUsageRespVO {
@Schema(description = "记录ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "2826")
@ExcelProperty("记录ID")
private Long id;
@Schema(description = "用户手机号", requiredMode = Schema.RequiredMode.REQUIRED, example = "26592")
@ExcelProperty("用户手机号")
private String userMobile;
@Schema(description = "购买的API 名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "10347")
private String apiName;
@Schema(description = "购买的套餐名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "8957")
private String packageName;
@Schema(description = "套餐最大可用次数", requiredMode = Schema.RequiredMode.REQUIRED, example = "8957")
private Integer packageTimes;
@Schema(description = "套餐价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "8957")
private Integer packagePrice;
@Schema(description = "套餐有效期", requiredMode = Schema.RequiredMode.REQUIRED, example = "8957")
private Integer packageValidDays;
@Schema(description = "已使用次数", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("已使用次数")
private Integer usedTimes;
@Schema(description = "过期时间")
@ExcelProperty("过期时间")
private LocalDateTime expireTime;
@Schema(description = "备注", example = "随便")
@ExcelProperty("备注")
private String remark;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.app.userapiusage.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 用户 API 使用统计新增/修改 Request VO")
@Data
public class UserApiUsageSaveReqVO {
@Schema(description = "记录ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "2826")
private Long id;
@Schema(description = "用户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "26592")
@NotNull(message = "用户ID不能为空")
private Long userId;
@Schema(description = "API ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "8522")
@NotNull(message = "API ID不能为空")
private Long apiId;
@Schema(description = "购买的API 名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "10347")
private String apiName;
@Schema(description = "购买的套餐ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "8957")
@ExcelProperty("购买的套餐ID")
private Long packageId;
@Schema(description = "购买的套餐名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "8957")
private String packageName;
@Schema(description = "套餐可用次数", requiredMode = Schema.RequiredMode.REQUIRED, example = "8957")
private Integer packageTimes;
@Schema(description = "套餐价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "8957")
private Integer packagePrice;
@Schema(description = "套餐有效期", requiredMode = Schema.RequiredMode.REQUIRED, example = "8957")
private Integer packageValidDays;
@Schema(description = "已使用次数", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "已使用次数不能为空")
private Integer usedTimes;
@Schema(description = "过期时间")
private LocalDateTime expireTime;
@Schema(description = "备注", example = "随便")
private String remark;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.dal.dataobject.apicalllog;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
......@@ -8,6 +10,8 @@ import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import com.luhu.computility.framework.mybatis.core.dataobject.BaseDO;
import javax.validation.constraints.NotNull;
/**
* API 调用日志 DO
*
......@@ -33,9 +37,21 @@ public class ApiCallLogDO extends BaseDO {
*/
private Long userId;
/**
* 调用的API ID
* 请求方法
*/
private String method;
/**
* 接口名称
*/
private String apiEndpointName;
/**
* 请求路径
*/
private String path;
/**
* 返回结果
*/
private Long apiId;
private String responseParams;
/**
* 请求参数
*/
......
......@@ -31,8 +31,13 @@ public class ApiEndpointDO extends BaseDO {
* 接口名称
*/
private String name;
/**
* 接口消费点数
*/
private Integer consumptionPoints;
/**
* 接口路径,全路径例如 https://phsl.lijinqi.com/openn_ip/xxx
* 接口路径,全路径例如 https://phsl.lijinqi.com/open-ip/xxx
*/
private String path;
/**
......
package com.luhu.computility.module.apihub.dal.dataobject.apiendpointapplicationrel;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import com.luhu.computility.framework.mybatis.core.dataobject.BaseDO;
/**
* 行业应用与接口关联 DO
*
* @author ljq
*/
@TableName("apihub_api_endpoint_application_rel")
@KeySequence("apihub_api_endpoint_application_rel_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ApiEndpointApplicationRelDO extends BaseDO {
/**
* 主键
*/
@TableId
private Long id;
/**
* 行业应用ID,关联 industry_application.id
*/
private Long industryApplicationId;
/**
* 接口ID,关联 apihub_api_endpoint.id
*/
private Long apiEndpointId;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.dal.mysql.apicalllog;
import java.util.*;
import java.util.stream.Collectors;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.common.util.object.BeanUtils;
import com.luhu.computility.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.luhu.computility.framework.mybatis.core.mapper.BaseMapperX;
import com.luhu.computility.framework.mybatis.core.query.MPJLambdaWrapperX;
import com.luhu.computility.module.apihub.api.apicalllog.dto.ApiCallLogPageReqDTO;
import com.luhu.computility.module.apihub.api.apicalllog.dto.ApiCallLogRespDTO;
import com.luhu.computility.module.apihub.controller.app.apicalllog.vo.AppApiCallLogPageReqVO;
import com.luhu.computility.module.apihub.dal.dataobject.apicalllog.ApiCallLogDO;
import com.luhu.computility.module.member.dal.dataobject.user.MemberUserDO;
import org.apache.ibatis.annotations.Mapper;
import com.luhu.computility.module.apihub.controller.admin.apicalllog.vo.*;
......@@ -17,24 +24,37 @@ import com.luhu.computility.module.apihub.controller.admin.apicalllog.vo.*;
@Mapper
public interface ApiCallLogMapper extends BaseMapperX<ApiCallLogDO> {
default PageResult<ApiCallLogDO> selectPage(ApiCallLogPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<ApiCallLogDO>()
.eqIfPresent(ApiCallLogDO::getUserId, reqVO.getUserId())
.eqIfPresent(ApiCallLogDO::getApiId, reqVO.getApiId())
.eqIfPresent(ApiCallLogDO::getResponseStatus, reqVO.getResponseStatus())
.betweenIfPresent(ApiCallLogDO::getCallTime, reqVO.getCallTime())
default PageResult<ApiCallLogRespVO> selectPage(ApiCallLogPageReqVO reqVO) {
return selectJoinPage(reqVO, ApiCallLogRespVO.class,new MPJLambdaWrapperX<ApiCallLogDO>()
.selectAll(ApiCallLogDO.class)
.selectAs(MemberUserDO::getMobile, ApiCallLogRespVO::getUserMobile)
.leftJoin(MemberUserDO.class, MemberUserDO::getId, ApiCallLogDO::getUserId)
.eqIfPresent(ApiCallLogDO::getApiEndpointName, reqVO.getApiEndpointName())
.likeIfPresent(MemberUserDO::getMobile, reqVO.getUserMobile())
.betweenIfPresent(ApiCallLogDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(ApiCallLogDO::getId));
}
default List<ApiCallLogDO> selectList(ApiCallLogPageReqVO reqVO) {
return selectList(new LambdaQueryWrapperX<ApiCallLogDO>()
default List<ApiCallLogRespDTO> selectList(ApiCallLogPageReqDTO reqVO) {
List<ApiCallLogDO> list = selectList(new LambdaQueryWrapperX<ApiCallLogDO>()
.eqIfPresent(ApiCallLogDO::getUserId, reqVO.getUserId())
.eqIfPresent(ApiCallLogDO::getApiId, reqVO.getApiId())
.eqIfPresent(ApiCallLogDO::getResponseStatus, reqVO.getResponseStatus())
.betweenIfPresent(ApiCallLogDO::getCallTime, reqVO.getCallTime())
.betweenIfPresent(ApiCallLogDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(ApiCallLogDO::getId));
return list.stream().map(doObj -> {
ApiCallLogRespDTO dto = new ApiCallLogRespDTO();
BeanUtils.copyProperties(doObj, dto);
return dto;
}).collect(Collectors.toList());
}
default PageResult<ApiCallLogDO> selectPage(AppApiCallLogPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<ApiCallLogDO>()
.likeIfPresent(ApiCallLogDO::getApiEndpointName, reqVO.getApiEndpointName())
.eqIfPresent(ApiCallLogDO::getUserId, reqVO.getUserId())
.betweenIfPresent(ApiCallLogDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(ApiCallLogDO::getCreateTime));
}
}
\ No newline at end of file
......@@ -37,6 +37,14 @@ public interface ApiEndpointMapper extends BaseMapperX<ApiEndpointDO> {
return selectList();
}
default ApiEndpointDO getApiEndpointByPathAndMethod(String path, String method) {
return selectOne(new LambdaQueryWrapperX<ApiEndpointDO>()
.eqIfPresent(ApiEndpointDO::getMethod, method)
.eqIfPresent(ApiEndpointDO::getPath, path));
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.dal.mysql.apiendpointapplicationrel;
import java.util.*;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.luhu.computility.framework.mybatis.core.mapper.BaseMapperX;
import com.luhu.computility.framework.mybatis.core.query.MPJLambdaWrapperX;
import com.luhu.computility.module.apihub.controller.admin.apiendpoint.vo.ApiEndpointRespVO;
import com.luhu.computility.module.apihub.dal.dataobject.apiendpoint.ApiEndpointDO;
import com.luhu.computility.module.apihub.dal.dataobject.apiendpointapplicationrel.ApiEndpointApplicationRelDO;
import com.luhu.computility.module.apihub.dal.dataobject.apiendpointrel.ApiEndpointRelDO;
import com.luhu.computility.module.biz.controller.admin.industryapplication.vo.IndustryApplicationRespVO;
import com.luhu.computility.module.biz.dal.dataobject.industryapplication.IndustryApplicationDO;
import org.apache.ibatis.annotations.Mapper;
import com.luhu.computility.module.apihub.controller.admin.apiendpointapplicationrel.vo.*;
/**
* 行业应用与接口关联 Mapper
*
* @author ljq
*/
@Mapper
public interface ApiEndpointApplicationRelMapper extends BaseMapperX<ApiEndpointApplicationRelDO> {
default PageResult<ApiEndpointApplicationRelDO> selectPage(ApiEndpointApplicationRelPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<ApiEndpointApplicationRelDO>()
.eqIfPresent(ApiEndpointApplicationRelDO::getIndustryApplicationId, reqVO.getIndustryApplicationId())
.eqIfPresent(ApiEndpointApplicationRelDO::getApiEndpointId, reqVO.getApiEndpointId())
.betweenIfPresent(ApiEndpointApplicationRelDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(ApiEndpointApplicationRelDO::getId));
}
default int deleteByApiEndpointId(Long apiEndpointId) {
return delete(new LambdaQueryWrapperX<ApiEndpointApplicationRelDO>()
.eqIfPresent(ApiEndpointApplicationRelDO::getApiEndpointId, apiEndpointId));
}
default List<IndustryApplicationRespVO> getApiEndpointByApiId(Long apiEndpointId) {
return selectJoinList(IndustryApplicationRespVO.class, new MPJLambdaWrapperX<ApiEndpointApplicationRelDO>()
.selectAs(IndustryApplicationDO::getTitle, IndustryApplicationRespVO::getTitle)
.selectAs(ApiEndpointApplicationRelDO::getIndustryApplicationId, IndustryApplicationRespVO::getId)
.leftJoin(IndustryApplicationDO.class, IndustryApplicationDO::getId, ApiEndpointApplicationRelDO::getIndustryApplicationId)
.eqIfPresent(ApiEndpointApplicationRelDO::getApiEndpointId, apiEndpointId)
);
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.dal.mysql.apiorder;
import java.util.*;
import java.util.stream.Collectors;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.common.util.object.BeanUtils;
import com.luhu.computility.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.luhu.computility.framework.mybatis.core.mapper.BaseMapperX;
import com.luhu.computility.framework.mybatis.core.query.MPJLambdaWrapperX;
import com.luhu.computility.module.apihub.api.apicalllog.dto.ApiCallLogRespDTO;
import com.luhu.computility.module.apihub.api.apiorder.dto.ApiOrderPageReqDTO;
import com.luhu.computility.module.apihub.api.apiorder.dto.ApiOrderRespDTO;
import com.luhu.computility.module.apihub.controller.app.apiorder.vo.AppApiOrderPageReqVO;
import com.luhu.computility.module.apihub.dal.dataobject.api.ApiDO;
import com.luhu.computility.module.apihub.dal.dataobject.apicategory.ApiCategoryDO;
import com.luhu.computility.module.apihub.dal.dataobject.apiorder.ApiOrderDO;
import com.luhu.computility.module.apihub.enums.ApiOrderStatus;
import com.luhu.computility.module.member.dal.dataobject.user.MemberUserDO;
import org.apache.ibatis.annotations.Mapper;
import com.luhu.computility.module.apihub.controller.admin.apiorder.vo.*;
......@@ -36,8 +44,32 @@ public interface ApiOrderMapper extends BaseMapperX<ApiOrderDO> {
.orderByDesc(ApiOrderDO::getId));
}
default PageResult<ApiOrderDO> selectPage(ApiOrderPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<ApiOrderDO>()
default List<ApiOrderRespDTO> selectList(ApiOrderPageReqDTO reqVO) {
List<ApiOrderDO> list = selectList(new LambdaQueryWrapperX<ApiOrderDO>()
.eqIfPresent(ApiOrderDO::getUserId, reqVO.getUserId())
.eqIfPresent(ApiOrderDO::getApiId, reqVO.getApiId())
.eqIfPresent(ApiOrderDO::getPackageId, reqVO.getPackageId())
.eqIfPresent(ApiOrderDO::getOrderNo, reqVO.getOrderNo())
.eq(ApiOrderDO::getStatus, ApiOrderStatus.PAID.getValue())
.eqIfPresent(ApiOrderDO::getPayOrderId, reqVO.getPayOrderId())
.betweenIfPresent(ApiOrderDO::getPayTime, reqVO.getPayTime())
.eqIfPresent(ApiOrderDO::getPayChannelCode, reqVO.getPayChannelCode())
.betweenIfPresent(ApiOrderDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(ApiOrderDO::getId));
return list.stream().map(doObj -> {
ApiOrderRespDTO dto = new ApiOrderRespDTO();
BeanUtils.copyProperties(doObj, dto);
return dto;
}).collect(Collectors.toList());
}
default PageResult<ApiOrderRespVO> selectPage(ApiOrderPageReqVO reqVO) {
return selectJoinPage(reqVO, ApiOrderRespVO.class, new MPJLambdaWrapperX<ApiOrderDO>()
.selectAll(ApiOrderDO.class)
.selectAs(MemberUserDO::getMobile, ApiOrderRespVO::getUserMobile)
.leftJoin(MemberUserDO.class, MemberUserDO::getId, ApiOrderDO::getUserId)
.eqIfPresent(ApiOrderDO::getUserId, reqVO.getUserId())
.eqIfPresent(ApiOrderDO::getApiId, reqVO.getApiId())
.eqIfPresent(ApiOrderDO::getPackageId, reqVO.getPackageId())
......
......@@ -26,4 +26,9 @@ public interface AppCredentialMapper extends BaseMapperX<AppCredentialDO> {
.orderByDesc(AppCredentialDO::getId));
}
default AppCredentialDO selectOneByAppId(String appId) {
return selectOne(new LambdaQueryWrapperX<AppCredentialDO>()
.eqIfPresent(AppCredentialDO::getAppId, appId));
}
}
\ No newline at end of file
......@@ -3,13 +3,18 @@ package com.luhu.computility.module.apihub.dal.mysql.userapiusage;
import java.util.*;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.luhu.computility.framework.mybatis.core.mapper.BaseMapperX;
import com.luhu.computility.framework.mybatis.core.query.MPJLambdaWrapperX;
import com.luhu.computility.module.apihub.controller.app.userapiusage.vo.AppUserApiUsageRespVO;
import com.luhu.computility.module.apihub.dal.dataobject.api.ApiDO;
import com.luhu.computility.module.apihub.dal.dataobject.apicategory.ApiCategoryDO;
import com.luhu.computility.module.apihub.dal.dataobject.apiendpoint.ApiEndpointDO;
import com.luhu.computility.module.apihub.dal.dataobject.apiendpointrel.ApiEndpointRelDO;
import com.luhu.computility.module.apihub.dal.dataobject.userapiusage.UserApiUsageDO;
import com.luhu.computility.module.apihub.service.apiendpointrel.ApiEndpointRelService;
import com.luhu.computility.module.member.dal.dataobject.user.MemberUserDO;
import org.apache.ibatis.annotations.Mapper;
import com.luhu.computility.module.apihub.controller.admin.userapiusage.vo.*;
......@@ -29,7 +34,41 @@ public interface UserApiUsageMapper extends BaseMapperX<UserApiUsageDO> {
.leftJoin(MemberUserDO.class, MemberUserDO::getId,UserApiUsageDO::getUserId)
.like(!StringUtils.isEmpty(reqVO.getPackageName()), UserApiUsageDO::getPackageName, reqVO.getPackageName())
.like(!StringUtils.isEmpty(reqVO.getApiName()), UserApiUsageDO::getApiName, reqVO.getApiName())
.like(!StringUtils.isEmpty(reqVO.getUserMobile()), MemberUserDO::getMobile, reqVO.getUserMobile())
.orderByDesc(UserApiUsageDO::getCreateTime));
}
default PageResult<AppUserApiUsageRespVO> selectAppPage(UserApiUsagePageReqVO reqVO) {
return selectJoinPage(reqVO, AppUserApiUsageRespVO.class, new MPJLambdaWrapperX<UserApiUsageDO>()
.selectAll(UserApiUsageDO.class)
.selectAs(MemberUserDO :: getMobile, UserApiUsageRespVO :: getUserMobile)
.leftJoin(MemberUserDO.class, MemberUserDO::getId,UserApiUsageDO::getUserId)
.eqIfPresent(UserApiUsageDO::getUserId, reqVO.getUserId())
.like(!StringUtils.isEmpty(reqVO.getPackageName()), UserApiUsageDO::getPackageName, reqVO.getPackageName())
.like(!StringUtils.isEmpty(reqVO.getApiName()), UserApiUsageDO::getApiName, reqVO.getApiName())
.like(!StringUtils.isEmpty(reqVO.getUserMobile()), MemberUserDO::getMobile, reqVO.getUserMobile())
.orderByDesc(UserApiUsageDO::getCreateTime));
}
default List<JoinUserApiUsageResult> selectJoinUserApiUsageResult(Long userId, Long apiIdEndpoint) {
return selectJoinList(JoinUserApiUsageResult.class, new MPJLambdaWrapper<UserApiUsageDO>()
.select(UserApiUsageDO::getApiName)
.selectAs(UserApiUsageDO::getId, JoinUserApiUsageResult::getId)
.selectAs(ApiEndpointDO::getId, JoinUserApiUsageResult::getApiEndPointId)
.selectAs(UserApiUsageDO::getUserId, JoinUserApiUsageResult::getUserId)
.selectAs(ApiEndpointDO::getId, JoinUserApiUsageResult::getApiEndPointId)
.selectAs(UserApiUsageDO::getExpireTime, JoinUserApiUsageResult::getExpireTime)
.selectAs(UserApiUsageDO::getUsedTimes, JoinUserApiUsageResult::getUsedTimes)
.selectAs(UserApiUsageDO::getPackageTimes, JoinUserApiUsageResult::getPackageTimes)
.select(ApiEndpointDO::getName, ApiEndpointDO::getPath, ApiEndpointDO::getMethod) // 额外查接口信息
.innerJoin(ApiEndpointRelDO.class, ApiEndpointRelDO::getApiId, UserApiUsageDO::getApiId)
.innerJoin(ApiEndpointDO.class, ApiEndpointDO::getId, ApiEndpointRelDO::getApiEndpointId)
.eq(UserApiUsageDO::getUserId, userId)
.eqIfExists(ApiEndpointDO::getId, apiIdEndpoint)
/*.gt(UserApiUsageDO::getExpireTime, new Date()) // 没过期
.apply("(package_times - used_times) > 0") */ // 还有剩余额度
);
}
}
\ No newline at end of file
......@@ -19,7 +19,15 @@ public interface ErrorCodeConstants {
ErrorCode API_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR = new ErrorCode(1_010_001_014, "API订单更新支付状态失败,支付单编号不匹配");
ErrorCode API_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS = new ErrorCode(1_010_001_015, "API订单更新支付状态失败,支付单状态不是【支付成功】状态");
ErrorCode API_ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH = new ErrorCode(1_010_001_016, "API订单更新支付状态失败,支付单金额不匹配");
ErrorCode API_ENDPOINT_NOT_EXISTS = new ErrorCode(1_010_001_017, "API 接口不存在");
ErrorCode API_ENDPOINT_NOT_EXISTS = new ErrorCode(1_010_001_017, "接口不存在");
ErrorCode API_ENDPOINT_REL_NOT_EXISTS = new ErrorCode(1_010_001_018, "API 应用与接口关系不存在");
ErrorCode APP_CREDENTIAL_NOT_EXISTS = new ErrorCode(1_010_001_019, "用户密钥信息不存在");
ErrorCode API_ENDPOINT_APPLICATION_REL_NOT_EXISTS = new ErrorCode(1_010_001_020, "行业应用与接口关联不存在");
ErrorCode HEAD_EXCEPTION = new ErrorCode(1_010_001_021, "Header异常,缺少必须的参数");
ErrorCode API_ENDPOINT_NOT_AVAILABLE = new ErrorCode(1_010_001_022, "未订阅该接口");
ErrorCode API_ENDPOINT_EXPIRED = new ErrorCode(1_010_001_023, "接口调用额度不足或已过期");
ErrorCode TIMESTAMP_EXCEPTION = new ErrorCode(1_010_001_024, "参数timestamp异常");
ErrorCode INVALID_APPID = new ErrorCode(1_010_001_025, "无效的Appid");
}
......@@ -3,6 +3,7 @@ package com.luhu.computility.module.apihub.service.apicalllog;
import java.util.*;
import javax.validation.*;
import com.luhu.computility.module.apihub.controller.admin.apicalllog.vo.*;
import com.luhu.computility.module.apihub.controller.app.apicalllog.vo.AppApiCallLogPageReqVO;
import com.luhu.computility.module.apihub.dal.dataobject.apicalllog.ApiCallLogDO;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.common.pojo.PageParam;
......@@ -57,12 +58,15 @@ public interface ApiCallLogService {
* @param pageReqVO 分页查询
* @return API 调用日志分页
*/
PageResult<ApiCallLogDO> getApiCallLogPage(ApiCallLogPageReqVO pageReqVO);
PageResult<ApiCallLogRespVO> getApiCallLogPage(ApiCallLogPageReqVO pageReqVO);
/**
* 获得API 调用日志列表
* @param apiCallLogPageReqVO
* @return
* 获得API 调用日志分页
*
* @param pageReqVO 分页查询
* @return API 调用日志分页
*/
List<ApiCallLogDO> getApiCallLogList(ApiCallLogPageReqVO apiCallLogPageReqVO);
PageResult<ApiCallLogDO> getAppApiCallLogPage(AppApiCallLogPageReqVO pageReqVO);
}
\ No newline at end of file
package com.luhu.computility.module.apihub.service.apicalllog;
import cn.hutool.core.collection.CollUtil;
import com.luhu.computility.module.apihub.controller.app.apicalllog.vo.AppApiCallLogPageReqVO;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
......@@ -78,13 +79,13 @@ public class ApiCallLogServiceImpl implements ApiCallLogService {
}
@Override
public PageResult<ApiCallLogDO> getApiCallLogPage(ApiCallLogPageReqVO pageReqVO) {
public PageResult<ApiCallLogRespVO> getApiCallLogPage(ApiCallLogPageReqVO pageReqVO) {
return apiCallLogMapper.selectPage(pageReqVO);
}
@Override
public List<ApiCallLogDO> getApiCallLogList(ApiCallLogPageReqVO queryVO){
return apiCallLogMapper.selectList(queryVO);
public PageResult<ApiCallLogDO> getAppApiCallLogPage(AppApiCallLogPageReqVO pageReqVO) {
return apiCallLogMapper.selectPage(pageReqVO);
}
}
\ No newline at end of file
......@@ -68,6 +68,14 @@ public interface ApiEndpointService {
List<ApiEndpointDO> getApiEndpointList();
/**
* 根据path和方法 获得API 接口
*
* @param path、method 编号
* @return API 接口
*/
ApiEndpointDO getApiEndpointByPathAndMethod(String path, String method);
}
\ No newline at end of file
......@@ -88,6 +88,11 @@ public class ApiEndpointServiceImpl implements ApiEndpointService {
}
@Override
public ApiEndpointDO getApiEndpointByPathAndMethod(String path, String method) {
return apiEndpointMapper.getApiEndpointByPathAndMethod(path, method);
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.service.apiendpointapplicationrel;
import java.util.*;
import javax.validation.*;
import com.luhu.computility.module.apihub.controller.admin.apiendpoint.vo.ApiEndpointRespVO;
import com.luhu.computility.module.apihub.controller.admin.apiendpointapplicationrel.vo.*;
import com.luhu.computility.module.apihub.dal.dataobject.apiendpointapplicationrel.ApiEndpointApplicationRelDO;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.common.pojo.PageParam;
import com.luhu.computility.module.biz.controller.admin.industryapplication.vo.IndustryApplicationRespVO;
/**
* 行业应用与接口关联 Service 接口
*
* @author ljq
*/
public interface ApiEndpointApplicationRelService {
/**
* 创建行业应用与接口关联
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createApiEndpointApplicationRel(@Valid ApiEndpointApplicationRelSaveReqVO createReqVO);
/**
* 更新行业应用与接口关联
*
* @param updateReqVO 更新信息
*/
void updateApiEndpointApplicationRel(@Valid ApiEndpointApplicationRelSaveReqVO updateReqVO);
/**
* 删除行业应用与接口关联
*
* @param id 编号
*/
void deleteApiEndpointApplicationRel(Long id);
/**
* 删除行业应用与接口关联(根据接口id)
*
* @param apiEndpointId 编号
*/
void deleteApiEndpointApplicationRelByApiEndpointId(Long apiEndpointId);
/**
* 获得行业应用 (根据接口id)
*
* @param apiEndpointId
* @return 行业应用
*/
List<IndustryApplicationRespVO> getApplicationByApiEndpointId(Long apiEndpointId);
/**
* 批量删除行业应用与接口关联
*
* @param ids 编号
*/
void deleteApiEndpointApplicationRelListByIds(List<Long> ids);
/**
* 获得行业应用与接口关联
*
* @param id 编号
* @return 行业应用与接口关联
*/
ApiEndpointApplicationRelDO getApiEndpointApplicationRel(Long id);
/**
* 获得行业应用与接口关联分页
*
* @param pageReqVO 分页查询
* @return 行业应用与接口关联分页
*/
PageResult<ApiEndpointApplicationRelDO> getApiEndpointApplicationRelPage(ApiEndpointApplicationRelPageReqVO pageReqVO);
}
\ No newline at end of file
package com.luhu.computility.module.apihub.service.apiendpointapplicationrel;
import cn.hutool.core.collection.CollUtil;
import com.luhu.computility.module.biz.controller.admin.industryapplication.vo.IndustryApplicationRespVO;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import com.luhu.computility.module.apihub.controller.admin.apiendpointapplicationrel.vo.*;
import com.luhu.computility.module.apihub.dal.dataobject.apiendpointapplicationrel.ApiEndpointApplicationRelDO;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.common.pojo.PageParam;
import com.luhu.computility.framework.common.util.object.BeanUtils;
import com.luhu.computility.module.apihub.dal.mysql.apiendpointapplicationrel.ApiEndpointApplicationRelMapper;
import static com.luhu.computility.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.luhu.computility.framework.common.util.collection.CollectionUtils.convertList;
import static com.luhu.computility.framework.common.util.collection.CollectionUtils.diffList;
import static com.luhu.computility.module.apihub.enums.ErrorCodeConstants.*;
/**
* 行业应用与接口关联 Service 实现类
*
* @author ljq
*/
@Service
@Validated
public class ApiEndpointApplicationRelServiceImpl implements ApiEndpointApplicationRelService {
@Resource
private ApiEndpointApplicationRelMapper apiEndpointApplicationRelMapper;
@Override
public Long createApiEndpointApplicationRel(ApiEndpointApplicationRelSaveReqVO createReqVO) {
// 插入
ApiEndpointApplicationRelDO apiEndpointApplicationRel = BeanUtils.toBean(createReqVO, ApiEndpointApplicationRelDO.class);
apiEndpointApplicationRelMapper.insert(apiEndpointApplicationRel);
// 返回
return apiEndpointApplicationRel.getId();
}
@Override
public void updateApiEndpointApplicationRel(ApiEndpointApplicationRelSaveReqVO updateReqVO) {
// 校验存在
validateApiEndpointApplicationRelExists(updateReqVO.getId());
// 更新
ApiEndpointApplicationRelDO updateObj = BeanUtils.toBean(updateReqVO, ApiEndpointApplicationRelDO.class);
apiEndpointApplicationRelMapper.updateById(updateObj);
}
@Override
public void deleteApiEndpointApplicationRel(Long id) {
// 校验存在
validateApiEndpointApplicationRelExists(id);
// 删除
apiEndpointApplicationRelMapper.deleteById(id);
}
@Override
public void deleteApiEndpointApplicationRelListByIds(List<Long> ids) {
// 删除
apiEndpointApplicationRelMapper.deleteByIds(ids);
}
private void validateApiEndpointApplicationRelExists(Long id) {
if (apiEndpointApplicationRelMapper.selectById(id) == null) {
throw exception(API_ENDPOINT_APPLICATION_REL_NOT_EXISTS);
}
}
@Override
public ApiEndpointApplicationRelDO getApiEndpointApplicationRel(Long id) {
return apiEndpointApplicationRelMapper.selectById(id);
}
@Override
public PageResult<ApiEndpointApplicationRelDO> getApiEndpointApplicationRelPage(ApiEndpointApplicationRelPageReqVO pageReqVO) {
return apiEndpointApplicationRelMapper.selectPage(pageReqVO);
}
@Override
public void deleteApiEndpointApplicationRelByApiEndpointId(Long apiEndpointId) {
// 删除
apiEndpointApplicationRelMapper.deleteByApiEndpointId(apiEndpointId);
}
@Override
public List<IndustryApplicationRespVO> getApplicationByApiEndpointId(Long apiEndpointId) {
return apiEndpointApplicationRelMapper.getApiEndpointByApiId(apiEndpointId);
}
}
\ No newline at end of file
......@@ -71,7 +71,7 @@ public interface ApiOrderService {
* @param pageReqVO 分页查询
* @return api订单分页
*/
PageResult<ApiOrderDO> getApiOrderPage(ApiOrderPageReqVO pageReqVO);
PageResult<ApiOrderRespVO> getApiOrderPage(ApiOrderPageReqVO pageReqVO);
/**
......
......@@ -134,8 +134,7 @@ public class ApiOrderServiceImpl implements ApiOrderService {
return apiOrderMapper.selectList(reqVO);
}
@Override
public PageResult<ApiOrderDO> getApiOrderPage(ApiOrderPageReqVO pageReqVO) {
public PageResult<ApiOrderRespVO> getApiOrderPage(ApiOrderPageReqVO pageReqVO) {
return apiOrderMapper.selectPage(pageReqVO);
}
......
......@@ -59,4 +59,13 @@ public interface AppCredentialService {
*/
PageResult<AppCredentialDO> getAppCredentialPage(AppCredentialPageReqVO pageReqVO);
/**
* 获得用户密钥信息
*
* @param appId 编号
* @return 用户密钥信息
*/
AppCredentialDO getAppSecretByAppid(String appId);
}
\ No newline at end of file
......@@ -82,4 +82,12 @@ public class AppCredentialServiceImpl implements AppCredentialService {
return appCredentialMapper.selectPage(pageReqVO);
}
@Override
public AppCredentialDO getAppSecretByAppid(String appId) {
return appCredentialMapper.selectOneByAppId(appId);
}
}
\ No newline at end of file
......@@ -3,6 +3,7 @@ package com.luhu.computility.module.apihub.service.userapiusage;
import java.util.*;
import javax.validation.*;
import com.luhu.computility.module.apihub.controller.admin.userapiusage.vo.*;
import com.luhu.computility.module.apihub.controller.app.userapiusage.vo.AppUserApiUsageRespVO;
import com.luhu.computility.module.apihub.dal.dataobject.userapiusage.UserApiUsageDO;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.common.pojo.PageParam;
......@@ -59,4 +60,17 @@ public interface UserApiUsageService {
*/
PageResult<UserApiUsageRespVO> getUserApiUsagePage(UserApiUsagePageReqVO pageReqVO);
/**
* 获得用户 API 使用统计分页
*
* @param pageReqVO 分页查询
* @return 用户 API 使用统计分页
*/
PageResult<AppUserApiUsageRespVO> getAppUserApiUsagePage(UserApiUsagePageReqVO pageReqVO);
List<JoinUserApiUsageResult> selectJoinUserApiUsageResult(Long userId, Long apiIdEndpoint);
void asyncUpdateUsage(Long id, Integer used);
}
\ No newline at end of file
package com.luhu.computility.module.apihub.service.userapiusage;
import cn.hutool.core.collection.CollUtil;
import com.luhu.computility.module.apihub.controller.app.userapiusage.vo.AppUserApiUsageRespVO;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
......@@ -82,4 +84,26 @@ public class UserApiUsageServiceImpl implements UserApiUsageService {
return userApiUsageMapper.selectPage(pageReqVO);
}
@Override
public PageResult<AppUserApiUsageRespVO> getAppUserApiUsagePage(UserApiUsagePageReqVO pageReqVO) {
return userApiUsageMapper.selectAppPage(pageReqVO);
}
@Override
public List<JoinUserApiUsageResult> selectJoinUserApiUsageResult(Long userId, Long apiIdEndpoint) {
return userApiUsageMapper.selectJoinUserApiUsageResult(userId, apiIdEndpoint);
}
@Override
@Async
public void asyncUpdateUsage(Long id, Integer used) {
// 校验存在
validateUserApiUsageExists(id);
UserApiUsageDO userApiUsage = getUserApiUsage(id);
userApiUsage.setUsedTimes(userApiUsage.getUsedTimes() - used);
userApiUsageMapper.updateById(userApiUsage);
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.utils;
import cn.hutool.crypto.digest.DigestUtil;
import java.util.UUID;
/**
* @version 1.0
* @Author ljq
* @Date 2025/9/9
* @注释
*/
public class AppKeyGenerator {
/**
* 生成 appId(简单唯一标识)
*/
public static String generateAppId() {
// 使用 UUID 去掉“-”,保证长度唯一
return UUID.randomUUID().toString().replace("-", "");
}
/**
* 生成 appSecret(保密,建议加密存储)
*/
public static String generateAppSecret() {
// 随机 UUID + 当前时间戳 + SHA256 加密
String raw = UUID.randomUUID().toString() + System.currentTimeMillis();
return DigestUtil.sha256Hex(raw);
}
public static void main(String[] args) {
String appId = generateAppId();
String appSecret = generateAppSecret();
System.out.println("appId: " + appId);
System.out.println("appSecret: " + appSecret);
}
}
package com.luhu.computility.module.apihub.utils;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.symmetric.AES;
/**
* @version 1.0
* @Author ljq
* @Date 2025/9/9
* @注释
*/
public class AppSecretEncrypt {
// AES 对称密钥(32 字节,必须安全存储)
private static final String SECRET_KEY = "yoursupersecretkey123456789012";
private static final AES aes = new AES(Mode.ECB, Padding.PKCS5Padding, SECRET_KEY.getBytes());
/** 加密 appSecret 存入数据库 */
public static String encrypt(String appSecret) {
return aes.encryptHex(appSecret);
}
/** 解密数据库中的 appSecret,用于签名校验 */
public static String decrypt(String encryptedAppSecret) {
return aes.decryptStr(encryptedAppSecret);
}
public static void main(String[] args) {
String appSecret = "my-secret-value";
String encrypted = encrypt(appSecret);
String decrypted = decrypt(encrypted);
System.out.println("原始: " + appSecret);
System.out.println("加密后: " + encrypted);
System.out.println("解密后: " + decrypted);
}
}
......@@ -5,9 +5,13 @@
<groupId>com.luhu</groupId>
<version>${revision}</version>
</parent>
<modules>
<module>computility-module-apihub-api</module>
<module>computility-module-apihub-biz</module>
</modules>
<modelVersion>4.0.0</modelVersion>
<artifactId>computility-module-apihub</artifactId>
<packaging>jar</packaging>
<packaging>pom</packaging>
<name>${project.artifactId}</name>
<description>
......@@ -15,65 +19,4 @@
</description>
<dependencies>
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-module-pay</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-module-member</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-module-system</artifactId>
<version>${revision}</version>
</dependency>
<!-- 业务组件 -->
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-spring-boot-starter-biz-tenant</artifactId>
</dependency>
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-spring-boot-starter-biz-ip</artifactId>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-spring-boot-starter-security</artifactId>
</dependency>
<!-- DB 相关 -->
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-spring-boot-starter-mybatis</artifactId>
</dependency>
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-spring-boot-starter-redis</artifactId>
</dependency>
<!-- Test 测试相关 -->
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-spring-boot-starter-test</artifactId>
</dependency>
<!-- 工具类相关 -->
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-spring-boot-starter-excel</artifactId>
</dependency>
</dependencies>
</project>
......@@ -20,7 +20,7 @@
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-module-apihub</artifactId>
<artifactId>computility-module-apihub-api</artifactId>
<version>${revision}</version>
</dependency>
......
......@@ -96,6 +96,16 @@ public class IndustryApplicationController {
return success(respResult);
}
@GetMapping("/list")
@Operation(summary = "获得行业应用分页")
@PreAuthorize("@ss.hasPermission('biz:industry-application:query')")
public CommonResult<List<IndustryApplicationRespVO>> getIndustryApplicationList() {
List<IndustryApplicationDO> list = industryApplicationService.getAllIndustryApplication(); // 新增Service方法
List<IndustryApplicationRespVO> result = BeanUtils.toBean(list, IndustryApplicationRespVO.class);
return success(result);
}
@GetMapping("/export-excel")
@Operation(summary = "导出行业应用 Excel")
@PreAuthorize("@ss.hasPermission('biz:industry-application:export')")
......
......@@ -3,13 +3,12 @@ package com.luhu.computility.module.biz.service.home;
import cn.hutool.core.util.ObjectUtil;
import com.luhu.computility.framework.common.exception.ServiceException;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.module.apihub.controller.admin.apicalllog.vo.ApiCallLogPageReqVO;
import com.luhu.computility.module.apihub.controller.admin.apiorder.vo.ApiOrderPageReqVO;
import com.luhu.computility.module.apihub.dal.dataobject.apicalllog.ApiCallLogDO;
import com.luhu.computility.module.apihub.dal.dataobject.apiorder.ApiOrderDO;
import com.luhu.computility.module.apihub.enums.ApiOrderStatus;
import com.luhu.computility.module.apihub.service.apicalllog.ApiCallLogService;
import com.luhu.computility.module.apihub.service.apiorder.ApiOrderService;
import com.luhu.computility.module.apihub.api.apicalllog.ApiCallLogApi;
import com.luhu.computility.module.apihub.api.apicalllog.dto.ApiCallLogPageReqDTO;
import com.luhu.computility.module.apihub.api.apicalllog.dto.ApiCallLogRespDTO;
import com.luhu.computility.module.apihub.api.apiorder.ApiOrderApi;
import com.luhu.computility.module.apihub.api.apiorder.dto.ApiOrderPageReqDTO;
import com.luhu.computility.module.apihub.api.apiorder.dto.ApiOrderRespDTO;
import com.luhu.computility.module.biz.controller.admin.home.vo.HomeIndexApiCallsRespVO;
import com.luhu.computility.module.biz.controller.admin.home.vo.HomeIndexOrdersCountRespVO;
import com.luhu.computility.module.biz.controller.admin.home.vo.HomeIndexTopBarRespVO;
......@@ -46,9 +45,9 @@ public class HomeIndexServiceImpl implements HomeIndexService {
@Resource
TradeOrderQueryService tradeOrderQueryService;
@Resource
ApiOrderService apiOrderService;
ApiOrderApi apiOrderApi;
@Resource
ApiCallLogService apiCallLogService;
ApiCallLogApi apiCallLogApi;
@Override
public List<HomeIndexUsersCountRespVO> getRegisterUsersCount() {
......@@ -163,7 +162,7 @@ public class HomeIndexServiceImpl implements HomeIndexService {
@Override
public List<HomeIndexApiCallsRespVO> getApiCallsData(String dateType) {
ApiCallLogPageReqVO queryVO = new ApiCallLogPageReqVO();
ApiCallLogPageReqDTO queryVO = new ApiCallLogPageReqDTO();
LocalDate today = LocalDate.now();
LocalDateTime endTime = null;
......@@ -199,7 +198,7 @@ public class HomeIndexServiceImpl implements HomeIndexService {
LocalDateTime[] allTimePeriod = {LocalDate.of(1970, 1, 1).atStartOfDay(), endTime};
queryVO.setCreateTime(allTimePeriod);
List<ApiCallLogDO> apiCallLogList = apiCallLogService.getApiCallLogList(queryVO);
List<ApiCallLogRespDTO> apiCallLogList = apiCallLogApi.getApiCallLogList(queryVO);
// 按统计节点计算API调用次数(非累计,当前节点周期内的调用次数)
Map<LocalDate, Long> callsMap = new HashMap<>();
......@@ -258,10 +257,9 @@ public class HomeIndexServiceImpl implements HomeIndexService {
computeOrderQueryVO.setStatus(TradeOrderStatusEnum.COMPLETED.getStatus());
List<TradeOrderDO> computeOrderList = tradeOrderQueryService.getOrderList(computeOrderQueryVO);
ApiOrderPageReqVO apiOrderPageReqVO = new ApiOrderPageReqVO();
apiOrderPageReqVO.setCreateTime(todayLocalDateTime);
apiOrderPageReqVO.setStatus(ApiOrderStatus.PAID.getValue());
List<ApiOrderDO> apiOrderList = apiOrderService.getOrderList(apiOrderPageReqVO);
ApiOrderPageReqDTO apiOrderPageReqDTO = new ApiOrderPageReqDTO();
apiOrderPageReqDTO.setCreateTime(todayLocalDateTime);
List<ApiOrderRespDTO> apiOrderList = apiOrderApi.getOrderList(apiOrderPageReqDTO);
HomeIndexTopBarRespVO homeIndexTopBarRespVO = new HomeIndexTopBarRespVO();
......@@ -269,7 +267,7 @@ public class HomeIndexServiceImpl implements HomeIndexService {
.mapToInt(TradeOrderDO::getPayPrice)
.sum();
int newApiOrdersAmount = apiOrderList.stream()
.mapToInt(ApiOrderDO::getCostPrice)
.mapToInt(ApiOrderRespDTO::getCostPrice)
.sum();
homeIndexTopBarRespVO.setNewUsersCount(userList.size());
......@@ -326,10 +324,9 @@ public class HomeIndexServiceImpl implements HomeIndexService {
computeQueryVO.setStatus(TradeOrderStatusEnum.COMPLETED.getStatus());
List<TradeOrderDO> computeOrderList = tradeOrderQueryService.getOrderList(computeQueryVO);
// API订单:已支付状态
ApiOrderPageReqVO apiQueryVO = new ApiOrderPageReqVO();
apiQueryVO.setCreateTime(allTimePeriod);
apiQueryVO.setStatus(ApiOrderStatus.PAID.getValue());
List<ApiOrderDO> apiOrderList = apiOrderService.getOrderList(apiQueryVO);
ApiOrderPageReqDTO apiOrderPageReqDTO = new ApiOrderPageReqDTO();
apiOrderPageReqDTO.setCreateTime(allTimePeriod);
List<ApiOrderRespDTO> apiOrderList = apiOrderApi.getOrderList(apiOrderPageReqDTO);
// 3. 按节点分组统计:数量 + 金额
Map<LocalDate, Long> computeCountMap = groupOrderByNode(computeOrderList, timeNodes, dateType);
......@@ -414,7 +411,7 @@ public class HomeIndexServiceImpl implements HomeIndexService {
/**
* API订单金额分组统计(支持d/m/y)
*/
private Map<LocalDate, Integer> groupApiAmountByNode(List<ApiOrderDO> orderList, List<LocalDate> nodes, String dateType) {
private Map<LocalDate, Integer> groupApiAmountByNode(List<ApiOrderRespDTO> orderList, List<LocalDate> nodes, String dateType) {
if (CollectionUtils.isEmpty(orderList)) {
return new HashMap<>();
}
......@@ -422,7 +419,7 @@ public class HomeIndexServiceImpl implements HomeIndexService {
node -> node,
node -> orderList.stream()
.filter(order -> isDateMatch(order.getCreateTime().toLocalDate(), node, dateType))
.mapToInt(ApiOrderDO::getCostPrice)
.mapToInt(ApiOrderRespDTO::getCostPrice)
.sum()
));
}
......
......@@ -7,6 +7,7 @@ import com.luhu.computility.framework.common.exception.ServiceException;
import com.luhu.computility.framework.common.exception.enums.GlobalResponseCodeConstants;
import com.luhu.computility.framework.common.pojo.CommonResult;
import com.luhu.computility.framework.common.util.http.HttpUtils;
import com.luhu.computility.framework.signature.core.annotation.ApiSignature;
import com.luhu.computility.module.external.controller.openapi.dto.ImageRespDTO;
import com.luhu.computility.module.external.controller.openapi.dto.PoetryImageReqDTO;
import com.luhu.computility.module.external.controller.openapi.dto.TextToImageReqDTO;
......@@ -47,7 +48,7 @@ public class AigcNewApiController {
@ApiAccessLog
@PostMapping(value = "/text-to-image/season")
@Operation(summary = "四季和景点id生成图", description = "接收简单生图参数,将生成图片保存在本地服务器,并返回生成图片的url")
//@ApiSignature
@ApiSignature
public CommonResult<ImageRespDTO> textToImageV2(@RequestBody TextToImageReqDTO textToImageReqDTO){
try {
String requestBody = JSONUtil.toJsonStr(textToImageReqDTO);
......@@ -71,7 +72,7 @@ public class AigcNewApiController {
@ApiAccessLog
@PostMapping("/text-to-image/poetry")
@Operation(summary = "获取藏头诗图片", description = "接收关键词、景点id、省份id这些参数,返回藏头诗图片url")
//@ApiSignature
@ApiSignature
public CommonResult<ImageRespDTO> textToImageByPoetry(@RequestBody PoetryImageReqDTO poetryImageReqDTO){
try {
String requestBody = JSONUtil.toJsonStr(poetryImageReqDTO);
......
......@@ -7,6 +7,7 @@ import com.luhu.computility.framework.common.exception.ServiceException;
import com.luhu.computility.framework.common.exception.enums.GlobalResponseCodeConstants;
import com.luhu.computility.framework.common.pojo.CommonResult;
import com.luhu.computility.framework.common.util.http.HttpUtils;
import com.luhu.computility.framework.signature.core.annotation.ApiSignature;
import com.luhu.computility.module.external.controller.openapi.dto.ImageRespDTO;
import com.luhu.computility.module.external.controller.openapi.dto.PoetryImageReqDTO;
import com.luhu.computility.module.external.controller.openapi.dto.TextToImageReqDTO;
......@@ -72,7 +73,7 @@ public class AigcOldApiController {
@ApiAccessLog
@PostMapping("/text-to-image/poetry")
@Operation(summary = "获取藏头诗图片", description = "接收关键词、景点id、省份id这些参数,返回藏头诗图片url")
//@ApiSignature
@ApiSignature
public CommonResult<ImageRespDTO> textToImageByPoetry(@RequestBody PoetryImageReqDTO poetryImageReqDTO){
try {
String requestBody = JSONUtil.toJsonStr(poetryImageReqDTO);
......
......@@ -16,19 +16,6 @@ import com.luhu.computility.module.external.controller.openapi.dto.ViewImageReqD
import com.luhu.computility.module.external.controller.openapi.dto.ViewSourceRespDTO;
import com.luhu.computility.module.external.controller.openapi.dto.ViewVideoReqDTO;
import com.luhu.computility.module.external.controller.openapi.service.OpenApiService;
import com.luhu.computility.module.external.controller.openapi.dto.AIQAReqDTO;
import com.luhu.computility.module.external.controller.openapi.dto.AIQARespDTO;
import com.luhu.computility.module.external.controller.openapi.dto.CeateVideoStreamReqDTO;
import com.luhu.computility.module.external.controller.openapi.dto.CeateVideoStreamRespDTO;
import com.luhu.computility.module.external.controller.openapi.dto.ConversationReqDTO;
import com.luhu.computility.module.external.controller.openapi.dto.ConversationRespDTO;
import com.luhu.computility.module.external.controller.openapi.dto.GenerateFaceSwapRespDTO;
import com.luhu.computility.module.external.controller.openapi.dto.MatchImageRespDTO;
import com.luhu.computility.module.external.controller.openapi.dto.UploadImageRespDTO;
import com.luhu.computility.module.external.controller.openapi.dto.ViewImageReqDTO;
import com.luhu.computility.module.external.controller.openapi.dto.ViewSourceRespDTO;
import com.luhu.computility.module.external.controller.openapi.dto.ViewVideoReqDTO;
import com.luhu.computility.module.external.controller.openapi.service.OpenApiService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
......@@ -77,7 +64,7 @@ public class OpenApiController {
@Parameter(name = "url", description = "图片链接")
})
@Operation(summary = "ai换脸-上传图片", description = "用户上传头像将视频中人物头像替换")
//@ApiSignature
@ApiSignature
public CommonResult<UploadImageRespDTO> uploadFaceSwapImage(@RequestPart(value = "image", required = false) MultipartFile image,
@RequestParam(value = "url", required = false) String url) {
return openApiService.uploadFaceSwapImage(image, url);
......@@ -87,7 +74,7 @@ public class OpenApiController {
@ApiAccessLog
@GetMapping("/create-video-stream")
@Operation(summary = "ai换脸-生成换脸工作流", description = "只有先上传图片才能开始换脸工作流,用户根据promptId取最后生成的视频")
//@ApiSignature
@ApiSignature
public CommonResult<CeateVideoStreamRespDTO> ceateVideoStream(@RequestBody CeateVideoStreamReqDTO ceateVideoStreamReqDTO){
return openApiService.ceateVideoStream(ceateVideoStreamReqDTO);
}
......@@ -96,7 +83,7 @@ public class OpenApiController {
@ApiAccessLog
@PostMapping(value = "/generate-face-swap-image", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@Operation(summary = "ai换脸-图片换脸:上传图+图片生成", description = "ai换脸-图片换脸:上传图片+图片生成")
//@ApiSignature
@ApiSignature
public CommonResult<GenerateFaceSwapRespDTO> faceImageGenerate(@RequestPart(value = "sourceImage", required = false) MultipartFile sourceImage,
@RequestParam(value = "sourceImageUrl", required = false) String sourceImageUrl,
@RequestPart(value = "targetImage", required = false) MultipartFile targetImage,
......@@ -108,7 +95,7 @@ public class OpenApiController {
@ApiAccessLog
@GetMapping("/view-image")
@Operation(summary = "根据promptId取换脸后的图", description = "根据promptId取换脸后的图")
//@ApiSignature
@ApiSignature
public CommonResult<ViewSourceRespDTO> viewImage(@RequestBody ViewImageReqDTO viewImageReqDTO){
return openApiService.viewImage(viewImageReqDTO);
}
......@@ -121,7 +108,7 @@ public class OpenApiController {
@Parameter(name = "url", description = "图片链接")
})
@Operation(summary = "ai换脸-视频换脸;ai换脸-上传图片+视频流生成", description = "ai换脸-上传图片+视频流生成")
//@ApiSignature
@ApiSignature
public CommonResult<GenerateFaceSwapRespDTO> faceVideoGenerate(@RequestPart(value = "image", required = false) MultipartFile image,
@RequestParam(value = "url", required = false) String url) {
return openApiService.faceVideoGenerate(image, url);
......@@ -131,7 +118,7 @@ public class OpenApiController {
@ApiAccessLog
@GetMapping("/view-video")
@Operation(summary = "根据promptId取最后生成的视频", description = "根据promptId取最后生成的视频")
//@ApiSignature
@ApiSignature
public CommonResult<ViewSourceRespDTO> viewVideo(@RequestBody ViewVideoReqDTO viewVideoReqDTO){
return openApiService.viewVideo(viewVideoReqDTO);
}
......@@ -146,7 +133,7 @@ public class OpenApiController {
@Parameter(name = "touristAreaId", description = "景点编码")
})
@Operation(summary = "图片拍照-相似图查找", description = "图片拍照-相似图查找")
//@ApiSignature
@ApiSignature
public CommonResult<List<MatchImageRespDTO>> matchImage(@RequestPart(value = "image", required = false) MultipartFile image
, @RequestParam(value = "url", required = false) String url
, @RequestParam(value = "limit", required = false) Integer limit
......@@ -160,7 +147,7 @@ public class OpenApiController {
@ApiAccessLog
@PostMapping("/AIQA-chat")
@Operation(summary = "AI问答", description = "AI助手,关于行程和景区的疑问")
//@ApiSignature
@ApiSignature
public CommonResult<AIQARespDTO> AIQAChat(@RequestBody AIQAReqDTO aiqaReqDTO){
return openApiService.AIQAChat(aiqaReqDTO);
}
......
......@@ -289,6 +289,7 @@ computility:
- biz_industry_application
- biz_information
- biz_partner
- apihub_api_call_log
- system_tenant
- system_tenant_package
- system_dict_data
......@@ -378,7 +379,7 @@ pf4j:
digital-human-zhuxi:
conversation: http://117.157.192.95:8081/zx/llm/chat_sse
conversation: http://218.77.58.8:14970/llm/chat_sse
token: Basic emh1eGlAdHhnOndBSmNETDRMZVZ3QjlhdlV1OVJN
similar-image:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment