Commit da36632f by lijinqi

api使用记录完成

parent 977fa279
...@@ -3,48 +3,42 @@ package com.luhu.computility.framework.signature.core.aop; ...@@ -3,48 +3,42 @@ package com.luhu.computility.framework.signature.core.aop;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil; 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.ServiceException;
import com.luhu.computility.framework.common.exception.enums.GlobalErrorCodeConstants;
import com.luhu.computility.framework.common.pojo.CommonResult; import com.luhu.computility.framework.common.pojo.CommonResult;
import com.luhu.computility.framework.common.util.servlet.ServletUtils; 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.annotation.ApiSignature;
import com.luhu.computility.framework.signature.core.redis.ApiSignatureRedisDAO; 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.controller.admin.userapiusage.vo.JoinUserApiUsageResult;
import com.luhu.computility.module.apihub.dal.dataobject.apiendpoint.ApiEndpointDO; 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.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.apiendpoint.ApiEndpointService;
import com.luhu.computility.module.apihub.service.appcredential.AppCredentialService; import com.luhu.computility.module.apihub.service.appcredential.AppCredentialService;
import com.luhu.computility.module.apihub.service.userapiusage.UserApiUsageService; import com.luhu.computility.module.apihub.service.userapiusage.UserApiUsageService;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.checkerframework.checker.units.qual.A;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.SortedMap; import java.util.SortedMap;
import java.util.TreeMap; import java.util.TreeMap;
import static com.luhu.computility.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
import static com.luhu.computility.framework.signature.core.redis.ApiSignatureRedisDAO.USAGE_KEY;
import static com.luhu.computility.module.apihub.enums.ErrorCodeConstants.API_ENDPOINT_EXPIRED; 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_AVAILABLE;
import static com.luhu.computility.module.apihub.enums.ErrorCodeConstants.API_ENDPOINT_NOT_EXISTS; import static com.luhu.computility.module.apihub.enums.ErrorCodeConstants.API_ENDPOINT_NOT_EXISTS;
import static com.luhu.computility.module.apihub.enums.ErrorCodeConstants.HEAD_EXCEPTION;
import static com.luhu.computility.module.apihub.enums.ErrorCodeConstants.INVALID_APPID; import static com.luhu.computility.module.apihub.enums.ErrorCodeConstants.INVALID_APPID;
import static com.luhu.computility.module.apihub.enums.ErrorCodeConstants.TIMESTAMP_EXCEPTION; import static com.luhu.computility.module.apihub.enums.ErrorCodeConstants.TIMESTAMP_EXCEPTION;
...@@ -67,6 +61,9 @@ public class ApiSignatureAspect { ...@@ -67,6 +61,9 @@ public class ApiSignatureAspect {
private ApiEndpointService appEndpointService; private ApiEndpointService appEndpointService;
@Resource @Resource
private ApiCallLogService apiCallLogService;
@Resource
private UserApiUsageService userApiUsageService; private UserApiUsageService userApiUsageService;
public ApiSignatureAspect(ApiSignatureRedisDAO signatureRedisDAO) { public ApiSignatureAspect(ApiSignatureRedisDAO signatureRedisDAO) {
...@@ -77,6 +74,7 @@ public class ApiSignatureAspect { ...@@ -77,6 +74,7 @@ public class ApiSignatureAspect {
@Around("@annotation(signature)") @Around("@annotation(signature)")
public Object aroundPointCut(ProceedingJoinPoint joinPoint, ApiSignature signature) throws Throwable { public Object aroundPointCut(ProceedingJoinPoint joinPoint, ApiSignature signature) throws Throwable {
HttpServletRequest request = Objects.requireNonNull(ServletUtils.getRequest()); HttpServletRequest request = Objects.requireNonNull(ServletUtils.getRequest());
// 1.校验 Header // 1.校验 Header
/* if (!verifyHeaders(signature, request)) { /* if (!verifyHeaders(signature, request)) {
throw new ServiceException(HEAD_EXCEPTION); throw new ServiceException(HEAD_EXCEPTION);
...@@ -127,8 +125,23 @@ public class ApiSignatureAspect { ...@@ -127,8 +125,23 @@ public class ApiSignatureAspect {
Object result = joinPoint.proceed(); Object result = joinPoint.proceed();
// 5. 只有当接口执行成功才扣减额度 // 5. 只有当接口执行成功才扣减额度
if (isSuccessResult(result)) { ApiCallLogSaveReqVO apiCallLogSaveReqVO = new ApiCallLogSaveReqVO();
consumeUsage(joinUserApiUsageResults); 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; return result;
...@@ -137,7 +150,7 @@ public class ApiSignatureAspect { ...@@ -137,7 +150,7 @@ public class ApiSignatureAspect {
/** 扣减一次额度(优先扣最近过期的套餐,用 Redis 保证并发安全) */ /** 扣减一次额度(优先扣最近过期的套餐,用 Redis 保证并发安全) */
private void consumeUsage(List<JoinUserApiUsageResult> joinUserApiUsageResults) { private void consumeUsage(List<JoinUserApiUsageResult> joinUserApiUsageResults, Integer consumptionPoints) {
JoinUserApiUsageResult target = null; JoinUserApiUsageResult target = null;
LocalDateTime now = LocalDateTime.now(); LocalDateTime now = LocalDateTime.now();
...@@ -153,28 +166,17 @@ public class ApiSignatureAspect { ...@@ -153,28 +166,17 @@ public class ApiSignatureAspect {
// Redis key:USAGE_KEY + apiEndpointId + userId // Redis key:USAGE_KEY + apiEndpointId + userId
String key = ApiSignatureRedisDAO.USAGE_KEY + target.getApiEndPointId() + target.getUserId(); String key = ApiSignatureRedisDAO.USAGE_KEY + target.getApiEndPointId() + target.getUserId();
// 自增使用次数,如果是第一次使用则设置过期时间 // 自增使用次数
Integer used = signatureRedisDAO.incrementUsageWithExpire(key); Integer used = signatureRedisDAO.incrementUsageWithExpire(key, consumptionPoints.longValue());
if (!ObjectUtil.isEmpty(used) && used <= target.getPackageTimes()) { if (!ObjectUtil.isEmpty(used) && used <= target.getPackageTimes()) {
// 异步回写 DB // 异步回写 DB
userApiUsageService.asyncUpdateUsage(target.getId(), used); userApiUsageService.asyncUpdateUsage(target.getId(), used);
} }
} }
/** 判断返回结果是否为成功(可按你项目的 CommonResult 判断) */
private boolean isSuccessResult(Object result) {
if (result instanceof CommonResult) {
return ((CommonResult<?>) result).isSuccess();
}
return true; // 默认认为执行成功
}
public boolean verifySignature(ApiSignature signature, HttpServletRequest request, AppCredentialDO appCredentialDO) { public boolean verifySignature(ApiSignature signature, HttpServletRequest request, AppCredentialDO appCredentialDO) {
// 1.2 校验 appId 是否能获取到对应的 appSecret // 1.2 校验 appId 是否能获取到对应的 appSecret
......
...@@ -99,13 +99,13 @@ public class ApiSignatureRedisDAO { ...@@ -99,13 +99,13 @@ public class ApiSignatureRedisDAO {
} }
/** /**
* 原子自增用户套餐使用次数,并设置过期时间 * 增加用户套餐使用次数,并设置过期时间
* *
* @param key Redis key * @param key Redis key
* @return 当前使用次数 * @return 当前使用次数
*/ */
public Integer incrementUsageWithExpire(String key) { public Integer incrementUsageWithExpire(String key, Long consumptionPoints) {
Integer used = stringRedisTemplate.opsForValue().increment(key, 1).intValue(); Integer used = stringRedisTemplate.opsForValue().increment(key, consumptionPoints).intValue();
return used; return used;
} }
......
...@@ -84,8 +84,8 @@ public class ApiCallLogController { ...@@ -84,8 +84,8 @@ public class ApiCallLogController {
@Operation(summary = "获得API 调用日志分页") @Operation(summary = "获得API 调用日志分页")
@PreAuthorize("@ss.hasPermission('apihub:api-call-log:query')") @PreAuthorize("@ss.hasPermission('apihub:api-call-log:query')")
public CommonResult<PageResult<ApiCallLogRespVO>> getApiCallLogPage(@Valid ApiCallLogPageReqVO pageReqVO) { public CommonResult<PageResult<ApiCallLogRespVO>> getApiCallLogPage(@Valid ApiCallLogPageReqVO pageReqVO) {
PageResult<ApiCallLogDO> pageResult = apiCallLogService.getApiCallLogPage(pageReqVO); PageResult<ApiCallLogRespVO> pageResult = apiCallLogService.getApiCallLogPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, ApiCallLogRespVO.class)); return success(pageResult);
} }
@GetMapping("/export-excel") @GetMapping("/export-excel")
...@@ -95,10 +95,9 @@ public class ApiCallLogController { ...@@ -95,10 +95,9 @@ public class ApiCallLogController {
public void exportApiCallLogExcel(@Valid ApiCallLogPageReqVO pageReqVO, public void exportApiCallLogExcel(@Valid ApiCallLogPageReqVO pageReqVO,
HttpServletResponse response) throws IOException { HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<ApiCallLogDO> list = apiCallLogService.getApiCallLogPage(pageReqVO).getList(); List<ApiCallLogRespVO> list = apiCallLogService.getApiCallLogPage(pageReqVO).getList();
// 导出 Excel // 导出 Excel
ExcelUtils.write(response, "API 调用日志.xls", "数据", ApiCallLogRespVO.class, ExcelUtils.write(response, "API 调用日志.xls", "数据", ApiCallLogRespVO.class, list);
BeanUtils.toBean(list, ApiCallLogRespVO.class));
} }
} }
\ No newline at end of file
...@@ -5,6 +5,8 @@ import java.util.*; ...@@ -5,6 +5,8 @@ import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import com.luhu.computility.framework.common.pojo.PageParam; import com.luhu.computility.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat; import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import static com.luhu.computility.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; import static com.luhu.computility.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
...@@ -13,11 +15,12 @@ import static com.luhu.computility.framework.common.util.date.DateUtils.FORMAT_Y ...@@ -13,11 +15,12 @@ import static com.luhu.computility.framework.common.util.date.DateUtils.FORMAT_Y
@Data @Data
public class ApiCallLogPageReqVO extends PageParam { public class ApiCallLogPageReqVO extends PageParam {
@Schema(description = "调用用户ID", example = "25965") @Schema(description = "调用用户手机号", example = "25965")
private Long userId; private String userMobile;
@Schema(description = "调用的API ID", example = "11672") @Schema(description = "接口名称", example = "11672")
private Long apiId; private String apiEndpointName;
@Schema(description = "响应状态(如200, 500等)", example = "2") @Schema(description = "响应状态(如200, 500等)", example = "2")
private String responseStatus; private String responseStatus;
......
...@@ -7,6 +7,8 @@ import org.springframework.format.annotation.DateTimeFormat; ...@@ -7,6 +7,8 @@ import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*; import com.alibaba.excel.annotation.*;
import javax.validation.constraints.NotNull;
@Schema(description = "管理后台 - API 调用日志 Response VO") @Schema(description = "管理后台 - API 调用日志 Response VO")
@Data @Data
@ExcelIgnoreUnannotated @ExcelIgnoreUnannotated
...@@ -20,14 +22,32 @@ public class ApiCallLogRespVO { ...@@ -20,14 +22,32 @@ public class ApiCallLogRespVO {
@ExcelProperty("调用用户ID") @ExcelProperty("调用用户ID")
private Long userId; private Long userId;
@Schema(description = "调用的API ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "11672")
@ExcelProperty("调用的API ID") @Schema(description = "用户手机号", requiredMode = Schema.RequiredMode.REQUIRED, example = "25965")
private Long apiId; @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 = "请求参数") @Schema(description = "请求参数")
@ExcelProperty("请求参数") @ExcelProperty("请求参数")
private String requestParams; private String requestParams;
@Schema(description = "返回结果")
@ExcelProperty("返回结果")
private String responseParams;
@Schema(description = "响应状态(如200, 500等)", example = "2") @Schema(description = "响应状态(如200, 500等)", example = "2")
@ExcelProperty("响应状态(如200, 500等)") @ExcelProperty("响应状态(如200, 500等)")
private String responseStatus; private String responseStatus;
......
...@@ -2,9 +2,8 @@ package com.luhu.computility.module.apihub.controller.admin.apicalllog.vo; ...@@ -2,9 +2,8 @@ package com.luhu.computility.module.apihub.controller.admin.apicalllog.vo;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*; import lombok.*;
import java.util.*;
import javax.validation.constraints.*; import javax.validation.constraints.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@Schema(description = "管理后台 - API 调用日志新增/修改 Request VO") @Schema(description = "管理后台 - API 调用日志新增/修改 Request VO")
...@@ -18,9 +17,17 @@ public class ApiCallLogSaveReqVO { ...@@ -18,9 +17,17 @@ public class ApiCallLogSaveReqVO {
@NotNull(message = "调用用户ID不能为空") @NotNull(message = "调用用户ID不能为空")
private Long userId; private Long userId;
@Schema(description = "调用的API ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "11672") @Schema(description = "接口名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "11672")
@NotNull(message = "调用的API ID不能为空") @NotNull(message = "接口名称不能为空")
private Long apiId; 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 = "请求参数") @Schema(description = "请求参数")
private String requestParams; private String requestParams;
...@@ -28,6 +35,9 @@ public class ApiCallLogSaveReqVO { ...@@ -28,6 +35,9 @@ public class ApiCallLogSaveReqVO {
@Schema(description = "响应状态(如200, 500等)", example = "2") @Schema(description = "响应状态(如200, 500等)", example = "2")
private String responseStatus; private String responseStatus;
@Schema(description = "请求参数")
private String responseParams;
@Schema(description = "调用时间") @Schema(description = "调用时间")
private LocalDateTime callTime; private LocalDateTime callTime;
......
...@@ -27,6 +27,11 @@ public class ApiEndpointRespVO { ...@@ -27,6 +27,11 @@ public class ApiEndpointRespVO {
@ExcelProperty("接口路径,全路径例如 https://phsl.lijinqi.com/openn_ip/xxx") @ExcelProperty("接口路径,全路径例如 https://phsl.lijinqi.com/openn_ip/xxx")
private String path; 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) @Schema(description = "请求方式: GET/POST/PUT/DELETE", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("请求方式: GET/POST/PUT/DELETE") @ExcelProperty("请求方式: GET/POST/PUT/DELETE")
private String method; private String method;
......
package com.luhu.computility.module.apihub.controller.admin.apiendpoint.vo; 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 com.luhu.computility.module.biz.controller.admin.industryapplication.vo.IndustryApplicationRespVO;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*; import lombok.*;
...@@ -21,6 +22,11 @@ public class ApiEndpointSaveReqVO { ...@@ -21,6 +22,11 @@ public class ApiEndpointSaveReqVO {
@NotEmpty(message = "接口路径,全路径例如 https://phsl.lijinqi.com/openn_ip/xxx不能为空") @NotEmpty(message = "接口路径,全路径例如 https://phsl.lijinqi.com/openn_ip/xxx不能为空")
private String path; 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) @Schema(description = "请求方式: GET/POST/PUT/DELETE", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "请求方式: GET/POST/PUT/DELETE不能为空") @NotEmpty(message = "请求方式: GET/POST/PUT/DELETE不能为空")
private String method; private String method;
......
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.dal.dataobject.apicalllog; 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 lombok.*;
import java.util.*; import java.util.*;
import java.time.LocalDateTime; import java.time.LocalDateTime;
...@@ -8,6 +10,8 @@ import java.time.LocalDateTime; ...@@ -8,6 +10,8 @@ import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*; import com.baomidou.mybatisplus.annotation.*;
import com.luhu.computility.framework.mybatis.core.dataobject.BaseDO; import com.luhu.computility.framework.mybatis.core.dataobject.BaseDO;
import javax.validation.constraints.NotNull;
/** /**
* API 调用日志 DO * API 调用日志 DO
* *
...@@ -33,9 +37,21 @@ public class ApiCallLogDO extends BaseDO { ...@@ -33,9 +37,21 @@ public class ApiCallLogDO extends BaseDO {
*/ */
private Long userId; 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 { ...@@ -31,8 +31,13 @@ public class ApiEndpointDO extends BaseDO {
* 接口名称 * 接口名称
*/ */
private String name; private String name;
/**
* 接口消费点数
*/
private Integer consumptionPoints;
/** /**
* 接口路径,全路径例如 https://phsl.lijinqi.com/openn_ip/xxx * 接口路径,全路径例如 https://phsl.lijinqi.com/open-ip/xxx
*/ */
private String path; private String path;
/** /**
......
...@@ -5,7 +5,10 @@ import java.util.*; ...@@ -5,7 +5,10 @@ import java.util.*;
import com.luhu.computility.framework.common.pojo.PageResult; import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.mybatis.core.query.LambdaQueryWrapperX; 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.mapper.BaseMapperX;
import com.luhu.computility.framework.mybatis.core.query.MPJLambdaWrapperX;
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.dataobject.apicalllog.ApiCallLogDO;
import com.luhu.computility.module.member.dal.dataobject.user.MemberUserDO;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import com.luhu.computility.module.apihub.controller.admin.apicalllog.vo.*; import com.luhu.computility.module.apihub.controller.admin.apicalllog.vo.*;
...@@ -17,14 +20,23 @@ import com.luhu.computility.module.apihub.controller.admin.apicalllog.vo.*; ...@@ -17,14 +20,23 @@ import com.luhu.computility.module.apihub.controller.admin.apicalllog.vo.*;
@Mapper @Mapper
public interface ApiCallLogMapper extends BaseMapperX<ApiCallLogDO> { public interface ApiCallLogMapper extends BaseMapperX<ApiCallLogDO> {
default PageResult<ApiCallLogDO> selectPage(ApiCallLogPageReqVO reqVO) { 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 PageResult<ApiCallLogDO> selectPage(AppApiCallLogPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<ApiCallLogDO>() return selectPage(reqVO, new LambdaQueryWrapperX<ApiCallLogDO>()
.likeIfPresent(ApiCallLogDO::getApiEndpointName, reqVO.getApiEndpointName())
.eqIfPresent(ApiCallLogDO::getUserId, reqVO.getUserId()) .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()) .betweenIfPresent(ApiCallLogDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(ApiCallLogDO::getId)); .orderByDesc(ApiCallLogDO::getCreateTime));
} }
} }
\ No newline at end of file
...@@ -3,6 +3,7 @@ package com.luhu.computility.module.apihub.service.apicalllog; ...@@ -3,6 +3,7 @@ package com.luhu.computility.module.apihub.service.apicalllog;
import java.util.*; import java.util.*;
import javax.validation.*; import javax.validation.*;
import com.luhu.computility.module.apihub.controller.admin.apicalllog.vo.*; 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.module.apihub.dal.dataobject.apicalllog.ApiCallLogDO;
import com.luhu.computility.framework.common.pojo.PageResult; import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.common.pojo.PageParam; import com.luhu.computility.framework.common.pojo.PageParam;
...@@ -57,6 +58,15 @@ public interface ApiCallLogService { ...@@ -57,6 +58,15 @@ public interface ApiCallLogService {
* @param pageReqVO 分页查询 * @param pageReqVO 分页查询
* @return API 调用日志分页 * @return API 调用日志分页
*/ */
PageResult<ApiCallLogDO> getApiCallLogPage(ApiCallLogPageReqVO pageReqVO); PageResult<ApiCallLogRespVO> getApiCallLogPage(ApiCallLogPageReqVO pageReqVO);
/**
* 获得API 调用日志分页
*
* @param pageReqVO 分页查询
* @return API 调用日志分页
*/
PageResult<ApiCallLogDO> getAppApiCallLogPage(AppApiCallLogPageReqVO pageReqVO);
} }
\ No newline at end of file
package com.luhu.computility.module.apihub.service.apicalllog; package com.luhu.computility.module.apihub.service.apicalllog;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import com.luhu.computility.module.apihub.controller.app.apicalllog.vo.AppApiCallLogPageReqVO;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
...@@ -78,8 +79,15 @@ public class ApiCallLogServiceImpl implements ApiCallLogService { ...@@ -78,8 +79,15 @@ public class ApiCallLogServiceImpl implements ApiCallLogService {
} }
@Override @Override
public PageResult<ApiCallLogDO> getApiCallLogPage(ApiCallLogPageReqVO pageReqVO) { public PageResult<ApiCallLogRespVO> getApiCallLogPage(ApiCallLogPageReqVO pageReqVO) {
return apiCallLogMapper.selectPage(pageReqVO); return apiCallLogMapper.selectPage(pageReqVO);
} }
@Override
public PageResult<ApiCallLogDO> getAppApiCallLogPage(AppApiCallLogPageReqVO pageReqVO) {
return apiCallLogMapper.selectPage(pageReqVO);
}
} }
\ No newline at end of file
...@@ -7,6 +7,7 @@ import com.luhu.computility.framework.common.exception.ServiceException; ...@@ -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.exception.enums.GlobalResponseCodeConstants;
import com.luhu.computility.framework.common.pojo.CommonResult; import com.luhu.computility.framework.common.pojo.CommonResult;
import com.luhu.computility.framework.common.util.http.HttpUtils; 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.ImageRespDTO;
import com.luhu.computility.module.external.controller.openapi.dto.PoetryImageReqDTO; import com.luhu.computility.module.external.controller.openapi.dto.PoetryImageReqDTO;
import com.luhu.computility.module.external.controller.openapi.dto.TextToImageReqDTO; import com.luhu.computility.module.external.controller.openapi.dto.TextToImageReqDTO;
...@@ -72,7 +73,7 @@ public class AigcOldApiController { ...@@ -72,7 +73,7 @@ public class AigcOldApiController {
@ApiAccessLog @ApiAccessLog
@PostMapping("/text-to-image/poetry") @PostMapping("/text-to-image/poetry")
@Operation(summary = "获取藏头诗图片", description = "接收关键词、景点id、省份id这些参数,返回藏头诗图片url") @Operation(summary = "获取藏头诗图片", description = "接收关键词、景点id、省份id这些参数,返回藏头诗图片url")
//@ApiSignature @ApiSignature
public CommonResult<ImageRespDTO> textToImageByPoetry(@RequestBody PoetryImageReqDTO poetryImageReqDTO){ public CommonResult<ImageRespDTO> textToImageByPoetry(@RequestBody PoetryImageReqDTO poetryImageReqDTO){
try { try {
String requestBody = JSONUtil.toJsonStr(poetryImageReqDTO); String requestBody = JSONUtil.toJsonStr(poetryImageReqDTO);
......
...@@ -64,7 +64,7 @@ public class OpenApiController { ...@@ -64,7 +64,7 @@ public class OpenApiController {
@Parameter(name = "url", description = "图片链接") @Parameter(name = "url", description = "图片链接")
}) })
@Operation(summary = "ai换脸-上传图片", description = "用户上传头像将视频中人物头像替换") @Operation(summary = "ai换脸-上传图片", description = "用户上传头像将视频中人物头像替换")
//@ApiSignature @ApiSignature
public CommonResult<UploadImageRespDTO> uploadFaceSwapImage(@RequestPart(value = "image", required = false) MultipartFile image, public CommonResult<UploadImageRespDTO> uploadFaceSwapImage(@RequestPart(value = "image", required = false) MultipartFile image,
@RequestParam(value = "url", required = false) String url) { @RequestParam(value = "url", required = false) String url) {
return openApiService.uploadFaceSwapImage(image, url); return openApiService.uploadFaceSwapImage(image, url);
...@@ -74,7 +74,7 @@ public class OpenApiController { ...@@ -74,7 +74,7 @@ public class OpenApiController {
@ApiAccessLog @ApiAccessLog
@GetMapping("/create-video-stream") @GetMapping("/create-video-stream")
@Operation(summary = "ai换脸-生成换脸工作流", description = "只有先上传图片才能开始换脸工作流,用户根据promptId取最后生成的视频") @Operation(summary = "ai换脸-生成换脸工作流", description = "只有先上传图片才能开始换脸工作流,用户根据promptId取最后生成的视频")
//@ApiSignature @ApiSignature
public CommonResult<CeateVideoStreamRespDTO> ceateVideoStream(@RequestBody CeateVideoStreamReqDTO ceateVideoStreamReqDTO){ public CommonResult<CeateVideoStreamRespDTO> ceateVideoStream(@RequestBody CeateVideoStreamReqDTO ceateVideoStreamReqDTO){
return openApiService.ceateVideoStream(ceateVideoStreamReqDTO); return openApiService.ceateVideoStream(ceateVideoStreamReqDTO);
} }
...@@ -83,7 +83,7 @@ public class OpenApiController { ...@@ -83,7 +83,7 @@ public class OpenApiController {
@ApiAccessLog @ApiAccessLog
@PostMapping(value = "/generate-face-swap-image", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @PostMapping(value = "/generate-face-swap-image", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@Operation(summary = "ai换脸-图片换脸:上传图+图片生成", description = "ai换脸-图片换脸:上传图片+图片生成") @Operation(summary = "ai换脸-图片换脸:上传图+图片生成", description = "ai换脸-图片换脸:上传图片+图片生成")
//@ApiSignature @ApiSignature
public CommonResult<GenerateFaceSwapRespDTO> faceImageGenerate(@RequestPart(value = "sourceImage", required = false) MultipartFile sourceImage, public CommonResult<GenerateFaceSwapRespDTO> faceImageGenerate(@RequestPart(value = "sourceImage", required = false) MultipartFile sourceImage,
@RequestParam(value = "sourceImageUrl", required = false) String sourceImageUrl, @RequestParam(value = "sourceImageUrl", required = false) String sourceImageUrl,
@RequestPart(value = "targetImage", required = false) MultipartFile targetImage, @RequestPart(value = "targetImage", required = false) MultipartFile targetImage,
...@@ -95,7 +95,7 @@ public class OpenApiController { ...@@ -95,7 +95,7 @@ public class OpenApiController {
@ApiAccessLog @ApiAccessLog
@GetMapping("/view-image") @GetMapping("/view-image")
@Operation(summary = "根据promptId取换脸后的图", description = "根据promptId取换脸后的图") @Operation(summary = "根据promptId取换脸后的图", description = "根据promptId取换脸后的图")
//@ApiSignature @ApiSignature
public CommonResult<ViewSourceRespDTO> viewImage(@RequestBody ViewImageReqDTO viewImageReqDTO){ public CommonResult<ViewSourceRespDTO> viewImage(@RequestBody ViewImageReqDTO viewImageReqDTO){
return openApiService.viewImage(viewImageReqDTO); return openApiService.viewImage(viewImageReqDTO);
} }
...@@ -108,7 +108,7 @@ public class OpenApiController { ...@@ -108,7 +108,7 @@ public class OpenApiController {
@Parameter(name = "url", description = "图片链接") @Parameter(name = "url", description = "图片链接")
}) })
@Operation(summary = "ai换脸-视频换脸;ai换脸-上传图片+视频流生成", description = "ai换脸-上传图片+视频流生成") @Operation(summary = "ai换脸-视频换脸;ai换脸-上传图片+视频流生成", description = "ai换脸-上传图片+视频流生成")
//@ApiSignature @ApiSignature
public CommonResult<GenerateFaceSwapRespDTO> faceVideoGenerate(@RequestPart(value = "image", required = false) MultipartFile image, public CommonResult<GenerateFaceSwapRespDTO> faceVideoGenerate(@RequestPart(value = "image", required = false) MultipartFile image,
@RequestParam(value = "url", required = false) String url) { @RequestParam(value = "url", required = false) String url) {
return openApiService.faceVideoGenerate(image, url); return openApiService.faceVideoGenerate(image, url);
...@@ -118,7 +118,7 @@ public class OpenApiController { ...@@ -118,7 +118,7 @@ public class OpenApiController {
@ApiAccessLog @ApiAccessLog
@GetMapping("/view-video") @GetMapping("/view-video")
@Operation(summary = "根据promptId取最后生成的视频", description = "根据promptId取最后生成的视频") @Operation(summary = "根据promptId取最后生成的视频", description = "根据promptId取最后生成的视频")
//@ApiSignature @ApiSignature
public CommonResult<ViewSourceRespDTO> viewVideo(@RequestBody ViewVideoReqDTO viewVideoReqDTO){ public CommonResult<ViewSourceRespDTO> viewVideo(@RequestBody ViewVideoReqDTO viewVideoReqDTO){
return openApiService.viewVideo(viewVideoReqDTO); return openApiService.viewVideo(viewVideoReqDTO);
} }
...@@ -133,7 +133,7 @@ public class OpenApiController { ...@@ -133,7 +133,7 @@ public class OpenApiController {
@Parameter(name = "touristAreaId", description = "景点编码") @Parameter(name = "touristAreaId", description = "景点编码")
}) })
@Operation(summary = "图片拍照-相似图查找", description = "图片拍照-相似图查找") @Operation(summary = "图片拍照-相似图查找", description = "图片拍照-相似图查找")
//@ApiSignature @ApiSignature
public CommonResult<List<MatchImageRespDTO>> matchImage(@RequestPart(value = "image", required = false) MultipartFile image public CommonResult<List<MatchImageRespDTO>> matchImage(@RequestPart(value = "image", required = false) MultipartFile image
, @RequestParam(value = "url", required = false) String url , @RequestParam(value = "url", required = false) String url
, @RequestParam(value = "limit", required = false) Integer limit , @RequestParam(value = "limit", required = false) Integer limit
...@@ -147,7 +147,7 @@ public class OpenApiController { ...@@ -147,7 +147,7 @@ public class OpenApiController {
@ApiAccessLog @ApiAccessLog
@PostMapping("/AIQA-chat") @PostMapping("/AIQA-chat")
@Operation(summary = "AI问答", description = "AI助手,关于行程和景区的疑问") @Operation(summary = "AI问答", description = "AI助手,关于行程和景区的疑问")
//@ApiSignature @ApiSignature
public CommonResult<AIQARespDTO> AIQAChat(@RequestBody AIQAReqDTO aiqaReqDTO){ public CommonResult<AIQARespDTO> AIQAChat(@RequestBody AIQAReqDTO aiqaReqDTO){
return openApiService.AIQAChat(aiqaReqDTO); return openApiService.AIQAChat(aiqaReqDTO);
} }
......
...@@ -289,6 +289,7 @@ computility: ...@@ -289,6 +289,7 @@ computility:
- biz_industry_application - biz_industry_application
- biz_information - biz_information
- biz_partner - biz_partner
- apihub_api_call_log
- system_tenant - system_tenant
- system_tenant_package - system_tenant_package
- system_dict_data - system_dict_data
...@@ -378,7 +379,7 @@ pf4j: ...@@ -378,7 +379,7 @@ pf4j:
digital-human-zhuxi: 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 token: Basic emh1eGlAdHhnOndBSmNETDRMZVZ3QjlhdlV1OVJN
similar-image: 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