Commit d74be380 by Jony.L

Merge remote-tracking branch 'origin/api' into develop

parents 4355cf03 401032c1
package com.luhu.computility.framework.common;
/**
* @version 1.0
* @Author ljq
* @Date 2025/4/23
* @注释
*/
public interface CustomizerHttpHeaders {
public static final String APPID = "appId";
public static final String TIMESTAMP = "timestamp";
public static final String NONCE = "nonce";
public static final String SIGN = "sign";
}
package com.luhu.computility.framework.common.exception.enums;
import com.luhu.computility.framework.common.exception.ErrorCode;
/**
* 全局错误码枚举
* 0-999 系统异常编码保留
*
* 一般情况下,使用 HTTP 响应状态码 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status
* 虽然说,HTTP 响应状态码作为业务使用表达能力偏弱,但是使用在系统层面还是非常不错的
* 比较特殊的是,因为之前一直使用 0 作为成功,就不使用 200 啦。
*
* @author 芋道源码
*/
public interface GlobalResponseCodeConstants {
ErrorCode SUCCESS = new ErrorCode(0, "成功");
ErrorCode EXTERNAL_SUCCESS = new ErrorCode(200, "请求成功");
// ========== 客户端错误段 ==========
ErrorCode BAD_REQUEST = new ErrorCode(400, "请求参数不正确");
ErrorCode UNAUTHORIZED = new ErrorCode(401, "账号未登录");
ErrorCode FORBIDDEN = new ErrorCode(403, "没有该操作权限");
ErrorCode NOT_FOUND = new ErrorCode(404, "请求未找到");
ErrorCode METHOD_NOT_ALLOWED = new ErrorCode(405, "请求方法不正确");
ErrorCode LOCKED = new ErrorCode(423, "请求失败,请稍后重试"); // 并发请求,不允许
ErrorCode TOO_MANY_REQUESTS = new ErrorCode(429, "请求过于频繁,请稍后重试");
ErrorCode REQUEST_TIMEOUT = new ErrorCode(408, "请求超时");
ErrorCode PAYLOAD_TOO_LARGE = new ErrorCode(413, "请求体过大");
ErrorCode URI_TOO_LONG = new ErrorCode(414, "请求 URI 过长");
ErrorCode UNSUPPORTED_MEDIA_TYPE = new ErrorCode(415, "不支持的媒体类型");
ErrorCode UNPROCESSABLE_ENTITY = new ErrorCode(422, "请求无法处理");
// ========== 服务端错误段 ==========
ErrorCode INTERNAL_SERVER_ERROR = new ErrorCode(500, "系统异常");
ErrorCode TIME_OUT_ERROR = new ErrorCode(408, "请求超时");
ErrorCode NOT_IMPLEMENTED = new ErrorCode(501, "功能未实现/未开启");
ErrorCode ERROR_CONFIGURATION = new ErrorCode(502, "错误的配置项");
ErrorCode BAD_GATEWAY = new ErrorCode(502, "网关错误");
ErrorCode SERVICE_UNAVAILABLE = new ErrorCode(503, "服务不可用");
ErrorCode GATEWAY_TIMEOUT = new ErrorCode(504, "网关超时");
ErrorCode HTTP_VERSION_NOT_SUPPORTED = new ErrorCode(505, "不支持的 HTTP 版本");
// ========== 自定义错误段 ==========
ErrorCode REPEATED_REQUESTS = new ErrorCode(900, "重复请求,请稍后重试"); // 重复请求
ErrorCode DEMO_DENY = new ErrorCode(901, "演示模式,禁止写操作");
ErrorCode UNKNOWN = new ErrorCode(999, "未知错误");
ErrorCode IMAGE_EXCEPTION = new ErrorCode(998, "图片文件或地址必须上传一个");
ErrorCode SOURCEIMAGE_IMAGE_EXCEPTION = new ErrorCode(996, "原始图片文件或地址必传一个且仅能传一个。二选一");
ErrorCode TARGETIMAGE_IMAGE_EXCEPTION = new ErrorCode(995, "模板图片文件或地址必传一个且仅能传一个。二选一");
ErrorCode IMAGE_UNIQUE = new ErrorCode(994, "图片文件或地址只能上传一个");
ErrorCode INVALID_SERIAL_NUMBER = new ErrorCode(993, "无效的流水号");
ErrorCode BEING_GENERATED = new ErrorCode(992, "还在生成中...");
}
......@@ -174,4 +174,54 @@ public class HttpUtils {
}
}
public static String postIncludeImage(String url, Map<String, String> headers, Map<String, Object> formMaps) {
try (HttpResponse response = openApiPost(url)
.addHeaders(headers)
.form(formMaps)
//.form(fileName, file) // 上传文件,"fileName"是接口中定义的字段名
.execute()) {
return response.body();
}
}
public static HttpRequest openApiPost(String url) {
return HttpRequest.post(url)
.setReadTimeout(300000);
}
public static String get(String url, Map<String, String> headers, Map<String, String> queryParams) {
try {
// 构建查询参数字符串
StringBuilder queryBuilder = new StringBuilder();
for (Map.Entry<String, String> entry : queryParams.entrySet()) {
if (queryBuilder.length() > 0) {
queryBuilder.append("&");
}
queryBuilder.append(entry.getKey())
.append("=")
.append(entry.getValue());
}
// 拼接完整的 URL
String fullUrl = url;
if (queryBuilder.length() > 0) {
fullUrl += "?" + queryBuilder.toString();
}
// 发送 GET 请求并返回响应体
try (HttpResponse response = HttpRequest.get(fullUrl)
.addHeaders(headers)
.execute()) {
return response.body();
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
......@@ -28,6 +28,10 @@ public abstract class AuthorizeRequestsCustomizer
return webProperties.getAppApi().getPrefix() + url;
}
protected String buildOpenApi(String url) {
return webProperties.getOpenApi().getPrefix() + url;
}
@Override
public int getOrder() {
return 0;
......
package com.luhu.computility.framework.swagger.config;
import com.luhu.computility.framework.common.CustomizerHttpHeaders;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
......@@ -152,5 +153,36 @@ public class ComputilitySwaggerAutoConfiguration {
.schema(new StringSchema()._default("Bearer test1").name(HEADER_TENANT_ID).description("认证 Token")); // 默认:使用用户编号为 1
}
public static GroupedOpenApi buildGroupedOpenApiAuthBySign(String group) {
return GroupedOpenApi.builder()
.group(group)
.pathsToMatch( "/open-api/" + group + "/**")
.addOperationCustomizer((operation, handlerMethod) -> operation
.addParametersItem(new Parameter()
.name(CustomizerHttpHeaders.APPID) // header 名
.description("应用id") // 描述
.in(String.valueOf(SecurityScheme.In.HEADER)) // 请求 header
.schema(new StringSchema()._default("1").name(CustomizerHttpHeaders.APPID).description("appid"))))
.addOperationCustomizer((operation, handlerMethod) -> operation
.addParametersItem(new Parameter()
.name(CustomizerHttpHeaders.NONCE) // header 名
.description("随机数,不少于10位") // 描述
.in(String.valueOf(SecurityScheme.In.HEADER)) // 请求 header
.schema(new StringSchema()._default("1111111111111").name(CustomizerHttpHeaders.NONCE).description("nonce"))))
.addOperationCustomizer((operation, handlerMethod) -> operation
.addParametersItem(new Parameter()
.name(CustomizerHttpHeaders.TIMESTAMP) // header 名
.description("时间戳,与服务器时间不相差10min") // 描述
.in(String.valueOf(SecurityScheme.In.HEADER)) // 请求 header
.schema(new StringSchema()._default("1745472001234").name(CustomizerHttpHeaders.TIMESTAMP).description("timestamp"))))
.addOperationCustomizer((operation, handlerMethod) -> operation
.addParametersItem(new Parameter()
.name(CustomizerHttpHeaders.SIGN) // header 名
.description("时间戳,与服务器时间不相差10min") // 描述
.in(String.valueOf(SecurityScheme.In.HEADER)) // 请求 header
.schema(new StringSchema()._default("fndjfhqofhjdsafsalfbshab").name(CustomizerHttpHeaders.SIGN).description("sign"))))
.build();
}
}
......@@ -44,6 +44,8 @@ public class ComputilityWebAutoConfiguration implements WebMvcConfigurer {
public void configurePathMatch(PathMatchConfigurer configurer) {
configurePathMatch(configurer, webProperties.getAdminApi());
configurePathMatch(configurer, webProperties.getAppApi());
configurePathMatch(configurer, webProperties.getOpenApi());
}
/**
......
......@@ -21,6 +21,9 @@ public class WebProperties {
@NotNull(message = "Admin API 不能为空")
private Api adminApi = new Api("/admin-api", "**.controller.admin.**");
@NotNull(message = "Open API 不能为空")
private Api openApi = new Api("/open-api", "**.controller.openapi.**");
@NotNull(message = "Admin UI 不能为空")
private Ui adminUi;
......
......@@ -21,7 +21,7 @@ public abstract class ApiRequestFilter extends OncePerRequestFilter {
protected boolean shouldNotFilter(HttpServletRequest request) {
// 只过滤 API 请求的地址
String apiUri = request.getRequestURI().substring(request.getContextPath().length());
return !StrUtil.startWithAny(apiUri, webProperties.getAdminApi().getPrefix(), webProperties.getAppApi().getPrefix());
return !StrUtil.startWithAny(apiUri, webProperties.getAdminApi().getPrefix(), webProperties.getAppApi().getPrefix(), webProperties.getOpenApi().getPrefix());
}
}
......@@ -115,6 +115,7 @@ public class WebFrameworkUtils {
if (request.getServletPath().startsWith(properties.getAppApi().getPrefix())) {
return UserTypeEnum.MEMBER.getValue();
}
return null;
}
......
<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/maven-v4_0_0.xsd">
<parent>
<artifactId>computility</artifactId>
<groupId>com.luhu</groupId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>computility-module-apihub</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>
api应用
</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>
package com.luhu.computility.module.apihub.config;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* @author LeeYan9
* @since 2022-09-15
*/
@Configuration
@EnableConfigurationProperties(ApiOrderProperties.class)
public class ApiOrderConfig {
}
package com.luhu.computility.module.apihub.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.time.Duration;
/**
* 交易订单的配置项
*
* @author ljq
* @since 2025-09-07
*/
@ConfigurationProperties(prefix = "computility.api.order")
@Data
@Validated
public class ApiOrderProperties {
private static final String PAY_APP_KEY_DEFAULT = "apimall";
/**
* 支付应用标识
*
* 在 pay 模块的 [支付管理 -> 应用信息]
*/
@NotEmpty(message = "Pay 应用标识不能为空")
private String payAppKey = PAY_APP_KEY_DEFAULT;
/**
* 支付超时时间
*/
@NotNull(message = "支付超时时间不能为空")
private Duration payExpireTime;
/**
* 收货超时时间
*/
@NotNull(message = "收货超时时间不能为空")
private Duration receiveExpireTime;
/**
* 评论超时时间
*/
@NotNull(message = "评论超时时间不能为空")
private Duration commentExpireTime;
/**
* 是否同步订单状态到微信小程序
*/
@NotNull(message = "是否同步订单状态到微信小程序不能为空")
private Boolean statusSyncToWxaEnable;
}
package com.luhu.computility.module.apihub.controller.admin.api;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
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.apiendpointrel.vo.ApiEndpointRelPageReqVO;
import com.luhu.computility.module.apihub.controller.admin.apiendpointrel.vo.ApiEndpointRelSaveReqVO;
import com.luhu.computility.module.apihub.controller.admin.apipackage.vo.ApiPackageRespVO;
import com.luhu.computility.module.apihub.controller.admin.apipackage.vo.ApiPackageSaveReqVO;
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.apiendpointrel.ApiEndpointRelService;
import com.luhu.computility.module.apihub.service.apipackage.ApiPackageService;
import org.checkerframework.checker.units.qual.A;
import org.springframework.transaction.annotation.Transactional;
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.api.vo.*;
import com.luhu.computility.module.apihub.dal.dataobject.api.ApiDO;
import com.luhu.computility.module.apihub.service.api.ApiService;
@Tag(name = "管理后台 - API信息")
@RestController
@RequestMapping("/apihub/api")
@Validated
public class ApiController {
@Resource
private ApiService apiService;
@Resource
private ApiEndpointRelService apiEndpointRelService;
@Resource
private ApiPackageService apiPackageService;
@PostMapping("/create")
@Operation(summary = "创建API信息")
@Transactional(rollbackFor = Exception.class)
public CommonResult<Long> createApi(@Valid @RequestBody ApiSaveReqVO createReqVO) {
Long apiId = apiService.createApi(createReqVO);
//创建套餐包
if (!CollectionUtil.isEmpty(createReqVO.getApiPackages())) {
for (ApiPackageSaveReqVO apiPackageSaveReqVO : createReqVO.getApiPackages()) {
apiPackageSaveReqVO.setApiId(apiId);
apiPackageService.createApiPackage(apiPackageSaveReqVO);
}
}
//api应用+api接口关联
if (!CollectionUtil.isEmpty(createReqVO.getApiEndPoints())) {
for (ApiEndpointSaveReqVO apiEndpointSaveReqVO : createReqVO.getApiEndPoints()) {
apiEndpointRelService.createApiEndpointRel(new ApiEndpointRelSaveReqVO()
.setApiEndpointId(apiEndpointSaveReqVO.getId())
.setApiId(apiId));
}
}
return success(apiId);
}
@PutMapping("/update")
@Operation(summary = "更新API信息")
//@PreAuthorize("@ss.hasPermission('apihub:api:update')")
@Transactional(rollbackFor = Exception.class)
public CommonResult<Boolean> updateApi(@Valid @RequestBody ApiSaveReqVO updateReqVO) {
//有套餐则更新套餐
if (!CollectionUtil.isEmpty(updateReqVO.getApiPackages())) {
for (ApiPackageSaveReqVO apiPackageSaveReqVO : updateReqVO.getApiPackages()) {
if (ObjectUtil.isEmpty(apiPackageSaveReqVO.getId())) {
apiPackageSaveReqVO.setApiId(updateReqVO.getId());
apiPackageService.createApiPackage(apiPackageSaveReqVO);
} else {
apiPackageService.updateApiPackage(BeanUtils.toBean(apiPackageSaveReqVO,ApiPackageSaveReqVO.class));
}
}
}
if (!CollectionUtil.isEmpty(updateReqVO.getApiEndPoints())) {
//删除已经关联的
apiEndpointRelService.deleteByApiId(updateReqVO.getId());
for (ApiEndpointSaveReqVO apiEndpointSaveReqVO : updateReqVO.getApiEndPoints()) {
apiEndpointRelService.createApiEndpointRel(new ApiEndpointRelSaveReqVO()
.setApiEndpointId(apiEndpointSaveReqVO.getId())
.setApiId(updateReqVO.getId()));
}
}
apiService.updateApi(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除API信息")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('apihub:api:delete')")
public CommonResult<Boolean> deleteApi(@RequestParam("id") Long id) {
apiService.deleteApi(id);
return success(true);
}
@DeleteMapping("/delete-list")
@Parameter(name = "ids", description = "编号", required = true)
@Operation(summary = "批量删除API信息")
@PreAuthorize("@ss.hasPermission('apihub:api:delete')")
public CommonResult<Boolean> deleteApiList(@RequestParam("ids") List<Long> ids) {
apiService.deleteApiListByIds(ids);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得API信息")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('apihub:api:query')")
public CommonResult<ApiRespVO> getApi(@RequestParam("id") Long id) {
ApiDO api = apiService.getApi(id);
ApiRespVO apiRespVO = BeanUtils.toBean(api, ApiRespVO.class);
List<ApiPackageDO> apiPackageDOS = apiPackageService.selectByApiId(id);
apiRespVO.setApiPackages(BeanUtils.toBean(apiPackageDOS, ApiPackageRespVO.class));
List<ApiEndpointRespVO> apiEndpointRespVOS = apiEndpointRelService.getApiEndpointByApiId(id);
apiRespVO.setApiEndPoints(apiEndpointRespVOS);
return success(apiRespVO);
}
@GetMapping("/page")
@Operation(summary = "获得API信息分页")
public CommonResult<PageResult<ApiRespVO>> getApiPage(@Valid ApiPageReqVO pageReqVO) {
return success(apiService.getApiPage(pageReqVO));
}
@GetMapping("/export-excel")
@Operation(summary = "导出API信息 Excel")
@PreAuthorize("@ss.hasPermission('apihub:api:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportApiExcel(@Valid ApiPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<ApiRespVO> list = apiService.getApiPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "API信息.xls", "数据", ApiRespVO.class,
BeanUtils.toBean(list, ApiRespVO.class));
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.admin.api.vo;
import com.alibaba.excel.annotation.ExcelProperty;
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 = "管理后台 - API信息分页 Request VO")
@Data
public class ApiPageReqVO extends PageParam {
@Schema(description = "API 名称", example = "李四")
private String name;
@Schema(description = "状态:1=上架,0=下架", example = "1")
private Integer status;
@Schema(description = "API 分类", example = "4891084201")
@ExcelProperty("API 分类")
private Long categoryId;
@Schema(description = "关键字查找", example = "通用型API")
@ExcelProperty("关键字查找")
private String searchQuery;
@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.api.vo;
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.admin.apipackage.vo.ApiPackageSaveReqVO;
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 = "管理后台 - API信息 Response VO")
@Data
@ExcelIgnoreUnannotated
public class ApiRespVO {
@Schema(description = "API ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "11243")
@ExcelProperty("API ID")
private Long id;
@Schema(description = "API 名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
@ExcelProperty("API 名称")
private String name;
@Schema(description = "API 简介", example = "你说的对")
@ExcelProperty("API 简介")
private String description;
@Schema(description = "API 最低价格描述", example = "你说的对")
@ExcelProperty("API 最低价格描述")
private String priceInfo;
@Schema(description = "API coverimage", example = "https://xxx.png")
@ExcelProperty("API coverimage")
private String coverImage;
@Schema(description = "API 分类", example = "4891084201")
@ExcelProperty("API 分类")
private Long categoryId;
@Schema(description = "API 分类名称", example = "通用api")
@ExcelProperty("API 分类名称")
private String categoryName;
@Schema(description = "API 详细介绍")
@ExcelProperty("API 详细介绍")
private String detail;
@Schema(description = "接口文档内容")
@ExcelProperty("接口文档内容")
private String doc;
@Schema(description = "状态:1=上架,0=下架", example = "1")
@ExcelProperty("状态:1=上架,0=下架")
private Integer status;
@Schema(description = "备注", example = "随便")
@ExcelProperty("备注")
private String remark;
@Schema(description = "资源包", example = "[{}]")
private List<ApiPackageRespVO> apiPackages;
@Schema(description = "", example = "[{}]")
private List<ApiEndpointRespVO> apiEndPoints;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.admin.api.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import com.luhu.computility.module.apihub.controller.admin.apiendpoint.vo.ApiEndpointSaveReqVO;
import com.luhu.computility.module.apihub.controller.admin.apiendpointrel.vo.ApiEndpointRelRespVO;
import com.luhu.computility.module.apihub.controller.admin.apiendpointrel.vo.ApiEndpointRelSaveReqVO;
import com.luhu.computility.module.apihub.controller.admin.apipackage.vo.ApiPackageSaveReqVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - API信息新增/修改 Request VO")
@Data
public class ApiSaveReqVO {
@Schema(description = "API ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "11243")
private Long id;
@Schema(description = "API 名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
@NotEmpty(message = "API 名称不能为空")
private String name;
@Schema(description = "API 简介", example = "你说的对")
private String description;
@Schema(description = "API 最低价格描述", example = "你说的对")
private String priceInfo;
@Schema(description = "API coverimage", example = "https://xxx.png")
private String coverImage;
@Schema(description = "API 分类")
private Long categoryId;
@Schema(description = "API 详细介绍")
private String detail;
@Schema(description = "接口文档内容")
private String doc;
@Schema(description = "状态:1=上架,0=下架", example = "1")
private Integer status;
@Schema(description = "备注", example = "随便")
private String remark;
@Schema(description = "资源包", example = "随便")
private List<ApiPackageSaveReqVO> apiPackages;
@Schema(description = "api接口", example = "随便")
private List<ApiEndpointSaveReqVO> apiEndPoints;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.admin.apicalllog;
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.apicalllog.vo.*;
import com.luhu.computility.module.apihub.dal.dataobject.apicalllog.ApiCallLogDO;
import com.luhu.computility.module.apihub.service.apicalllog.ApiCallLogService;
@Tag(name = "管理后台 - API 调用日志")
@RestController
@RequestMapping("/apihub/api-call-log")
@Validated
public class ApiCallLogController {
@Resource
private ApiCallLogService apiCallLogService;
@PostMapping("/create")
@Operation(summary = "创建API 调用日志")
@PreAuthorize("@ss.hasPermission('apihub:api-call-log:create')")
public CommonResult<Long> createApiCallLog(@Valid @RequestBody ApiCallLogSaveReqVO createReqVO) {
return success(apiCallLogService.createApiCallLog(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新API 调用日志")
@PreAuthorize("@ss.hasPermission('apihub:api-call-log:update')")
public CommonResult<Boolean> updateApiCallLog(@Valid @RequestBody ApiCallLogSaveReqVO updateReqVO) {
apiCallLogService.updateApiCallLog(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除API 调用日志")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('apihub:api-call-log:delete')")
public CommonResult<Boolean> deleteApiCallLog(@RequestParam("id") Long id) {
apiCallLogService.deleteApiCallLog(id);
return success(true);
}
@DeleteMapping("/delete-list")
@Parameter(name = "ids", description = "编号", required = true)
@Operation(summary = "批量删除API 调用日志")
@PreAuthorize("@ss.hasPermission('apihub:api-call-log:delete')")
public CommonResult<Boolean> deleteApiCallLogList(@RequestParam("ids") List<Long> ids) {
apiCallLogService.deleteApiCallLogListByIds(ids);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得API 调用日志")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('apihub:api-call-log:query')")
public CommonResult<ApiCallLogRespVO> getApiCallLog(@RequestParam("id") Long id) {
ApiCallLogDO apiCallLog = apiCallLogService.getApiCallLog(id);
return success(BeanUtils.toBean(apiCallLog, ApiCallLogRespVO.class));
}
@GetMapping("/page")
@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));
}
@GetMapping("/export-excel")
@Operation(summary = "导出API 调用日志 Excel")
@PreAuthorize("@ss.hasPermission('apihub:api-call-log:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportApiCallLogExcel(@Valid ApiCallLogPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<ApiCallLogDO> list = apiCallLogService.getApiCallLogPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "API 调用日志.xls", "数据", ApiCallLogRespVO.class,
BeanUtils.toBean(list, ApiCallLogRespVO.class));
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.admin.apicalllog.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 = "管理后台 - API 调用日志分页 Request VO")
@Data
public class ApiCallLogPageReqVO extends PageParam {
@Schema(description = "调用用户ID", example = "25965")
private Long userId;
@Schema(description = "调用的API ID", example = "11672")
private Long apiId;
@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.admin.apicalllog.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 = "管理后台 - API 调用日志 Response VO")
@Data
@ExcelIgnoreUnannotated
public class ApiCallLogRespVO {
@Schema(description = "调用日志ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "8682")
@ExcelProperty("调用日志ID")
private Long id;
@Schema(description = "调用用户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "25965")
@ExcelProperty("调用用户ID")
private Long userId;
@Schema(description = "调用的API ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "11672")
@ExcelProperty("调用的API ID")
private Long apiId;
@Schema(description = "请求参数")
@ExcelProperty("请求参数")
private String requestParams;
@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.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")
@Data
public class ApiCallLogSaveReqVO {
@Schema(description = "调用日志ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "8682")
private Long id;
@Schema(description = "调用用户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "25965")
@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 = "请求参数")
private String requestParams;
@Schema(description = "响应状态(如200, 500等)", example = "2")
private String responseStatus;
@Schema(description = "调用时间")
private LocalDateTime callTime;
@Schema(description = "备注", example = "你猜")
private String remark;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.admin.apicategory;
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.apicategory.vo.*;
import com.luhu.computility.module.apihub.dal.dataobject.apicategory.ApiCategoryDO;
import com.luhu.computility.module.apihub.service.apicategory.ApiCategoryService;
@Tag(name = "管理后台 - API分类")
@RestController
@RequestMapping("/apihub/api-category")
@Validated
public class ApiCategoryController {
@Resource
private ApiCategoryService apiCategoryService;
@PostMapping("/create")
@Operation(summary = "创建API分类")
@PreAuthorize("@ss.hasPermission('apihub:api-category:create')")
public CommonResult<Long> createApiCategory(@Valid @RequestBody ApiCategorySaveReqVO createReqVO) {
return success(apiCategoryService.createApiCategory(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新API分类")
@PreAuthorize("@ss.hasPermission('apihub:api-category:update')")
public CommonResult<Boolean> updateApiCategory(@Valid @RequestBody ApiCategorySaveReqVO updateReqVO) {
apiCategoryService.updateApiCategory(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除API分类")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('apihub:api-category:delete')")
public CommonResult<Boolean> deleteApiCategory(@RequestParam("id") Long id) {
apiCategoryService.deleteApiCategory(id);
return success(true);
}
@DeleteMapping("/delete-list")
@Parameter(name = "ids", description = "编号", required = true)
@Operation(summary = "批量删除API分类")
@PreAuthorize("@ss.hasPermission('apihub:api-category:delete')")
public CommonResult<Boolean> deleteApiCategoryList(@RequestParam("ids") List<Long> ids) {
apiCategoryService.deleteApiCategoryListByIds(ids);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得API分类")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('apihub:api-category:query')")
public CommonResult<ApiCategoryRespVO> getApiCategory(@RequestParam("id") Long id) {
ApiCategoryDO apiCategory = apiCategoryService.getApiCategory(id);
return success(BeanUtils.toBean(apiCategory, ApiCategoryRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得API分类分页")
@PreAuthorize("@ss.hasPermission('apihub:api-category:query')")
public CommonResult<PageResult<ApiCategoryRespVO>> getApiCategoryPage(@Valid ApiCategoryPageReqVO pageReqVO) {
PageResult<ApiCategoryDO> pageResult = apiCategoryService.getApiCategoryPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, ApiCategoryRespVO.class));
}
@GetMapping("/list")
@Operation(summary = "获得API所有分类")
public CommonResult<List<ApiCategoryRespVO>> getAllApiCategory() {
List<ApiCategoryDO> apiCategoryDOS = apiCategoryService.getAllApiCategory();
return success(BeanUtils.toBean(apiCategoryDOS, ApiCategoryRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出API分类 Excel")
@PreAuthorize("@ss.hasPermission('apihub:api-category:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportApiCategoryExcel(@Valid ApiCategoryPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<ApiCategoryDO> list = apiCategoryService.getApiCategoryPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "API分类.xls", "数据", ApiCategoryRespVO.class,
BeanUtils.toBean(list, ApiCategoryRespVO.class));
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.admin.apicategory.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 = "管理后台 - API分类分页 Request VO")
@Data
public class ApiCategoryPageReqVO extends PageParam {
@Schema(description = "分类名称", example = "张三")
private String name;
@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.apicategory.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 = "管理后台 - API分类 Response VO")
@Data
@ExcelIgnoreUnannotated
public class ApiCategoryRespVO {
@Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "4302")
@ExcelProperty("ID")
private Long id;
@Schema(description = "分类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
@ExcelProperty("分类名称")
private String name;
@Schema(description = "分类简介", example = "你说的对")
@ExcelProperty("分类简介")
private String description;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.admin.apicategory.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - API分类新增/修改 Request VO")
@Data
public class ApiCategorySaveReqVO {
@Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "4302")
private Long id;
@Schema(description = "分类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
@NotEmpty(message = "分类名称不能为空")
private String name;
@Schema(description = "分类简介", example = "你说的对")
private String description;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.admin.apiendpoint;
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.apiendpoint.vo.*;
import com.luhu.computility.module.apihub.dal.dataobject.apiendpoint.ApiEndpointDO;
import com.luhu.computility.module.apihub.service.apiendpoint.ApiEndpointService;
@Tag(name = "管理后台 - API 接口")
@RestController
@RequestMapping("/apihub/api-endpoint")
@Validated
public class ApiEndpointController {
@Resource
private ApiEndpointService apiEndpointService;
@PostMapping("/create")
@Operation(summary = "创建API 接口")
@PreAuthorize("@ss.hasPermission('apihub:api-endpoint:create')")
public CommonResult<Long> createApiEndpoint(@Valid @RequestBody ApiEndpointSaveReqVO createReqVO) {
return success(apiEndpointService.createApiEndpoint(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新API 接口")
@PreAuthorize("@ss.hasPermission('apihub:api-endpoint:update')")
public CommonResult<Boolean> updateApiEndpoint(@Valid @RequestBody ApiEndpointSaveReqVO updateReqVO) {
apiEndpointService.updateApiEndpoint(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除API 接口")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('apihub:api-endpoint:delete')")
public CommonResult<Boolean> deleteApiEndpoint(@RequestParam("id") Long id) {
apiEndpointService.deleteApiEndpoint(id);
return success(true);
}
@DeleteMapping("/delete-list")
@Parameter(name = "ids", description = "编号", required = true)
@Operation(summary = "批量删除API 接口")
@PreAuthorize("@ss.hasPermission('apihub:api-endpoint:delete')")
public CommonResult<Boolean> deleteApiEndpointList(@RequestParam("ids") List<Long> ids) {
apiEndpointService.deleteApiEndpointListByIds(ids);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得API 接口")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@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));
}
@GetMapping("/page")
@Operation(summary = "获得API 接口分页")
@PreAuthorize("@ss.hasPermission('apihub:api-endpoint:query')")
public CommonResult<PageResult<ApiEndpointRespVO>> getApiEndpointPage(@Valid ApiEndpointPageReqVO pageReqVO) {
PageResult<ApiEndpointDO> pageResult = apiEndpointService.getApiEndpointPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, ApiEndpointRespVO.class));
}
@GetMapping("/list")
@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));
}
@GetMapping("/export-excel")
@Operation(summary = "导出API 接口 Excel")
@PreAuthorize("@ss.hasPermission('apihub:api-endpoint:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportApiEndpointExcel(@Valid ApiEndpointPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<ApiEndpointDO> list = apiEndpointService.getApiEndpointPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "API 接口.xls", "数据", ApiEndpointRespVO.class,
BeanUtils.toBean(list, ApiEndpointRespVO.class));
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.admin.apiendpoint.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 = "管理后台 - API 接口分页 Request VO")
@Data
public class ApiEndpointPageReqVO extends PageParam {
@Schema(description = "接口名称", example = "王五")
private String name;
@Schema(description = "接口路径,全路径例如 https://phsl.lijinqi.com/openn_ip/xxx")
private String path;
@Schema(description = "请求方式: GET/POST/PUT/DELETE")
private String method;
@Schema(description = "参数定义(JSON)")
private String params;
@Schema(description = "返回结果示例")
private String response;
@Schema(description = "鉴权方式,例如 API_KEY/OAUTH", example = "2")
private String authType;
@Schema(description = "接口级限流规则,例如 100 QPS")
private String rateLimit;
@Schema(description = "备注", example = "你说的对")
private String remark;
@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.apiendpoint.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 = "管理后台 - API 接口 Response VO")
@Data
@ExcelIgnoreUnannotated
public class ApiEndpointRespVO {
@Schema(description = "接口ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "30761")
@ExcelProperty("接口ID")
private Long id;
@Schema(description = "接口名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
@ExcelProperty("接口名称")
private String name;
@Schema(description = "接口路径,全路径例如 https://phsl.lijinqi.com/openn_ip/xxx", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("接口路径,全路径例如 https://phsl.lijinqi.com/openn_ip/xxx")
private String path;
@Schema(description = "请求方式: GET/POST/PUT/DELETE", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("请求方式: GET/POST/PUT/DELETE")
private String method;
@Schema(description = "参数定义(JSON)")
@ExcelProperty("参数定义(JSON)")
private String params;
@Schema(description = "返回结果示例")
@ExcelProperty("返回结果示例")
private String response;
@Schema(description = "鉴权方式,例如 API_KEY/OAUTH", example = "2")
@ExcelProperty("鉴权方式,例如 API_KEY/OAUTH")
private String authType;
@Schema(description = "接口级限流规则,例如 100 QPS")
@ExcelProperty("接口级限流规则,例如 100 QPS")
private String rateLimit;
@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.admin.apiendpoint.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - API 接口新增/修改 Request VO")
@Data
public class ApiEndpointSaveReqVO {
@Schema(description = "接口ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "30761")
private Long id;
@Schema(description = "接口名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
@NotEmpty(message = "接口名称不能为空")
private String name;
@Schema(description = "接口路径,全路径例如 https://phsl.lijinqi.com/openn_ip/xxx", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "接口路径,全路径例如 https://phsl.lijinqi.com/openn_ip/xxx不能为空")
private String path;
@Schema(description = "请求方式: GET/POST/PUT/DELETE", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "请求方式: GET/POST/PUT/DELETE不能为空")
private String method;
@Schema(description = "参数定义(JSON)")
private String params;
@Schema(description = "返回结果示例")
private String response;
@Schema(description = "鉴权方式,例如 API_KEY/OAUTH", example = "2")
private String authType;
@Schema(description = "接口级限流规则,例如 100 QPS")
private String rateLimit;
@Schema(description = "备注", example = "你说的对")
private String remark;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.admin.apiendpointrel;
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.apiendpointrel.vo.*;
import com.luhu.computility.module.apihub.dal.dataobject.apiendpointrel.ApiEndpointRelDO;
import com.luhu.computility.module.apihub.service.apiendpointrel.ApiEndpointRelService;
@Tag(name = "管理后台 - API 应用与接口关系")
@RestController
@RequestMapping("/apihub/api-endpoint-rel")
@Validated
public class ApiEndpointRelController {
@Resource
private ApiEndpointRelService apiEndpointRelService;
@PostMapping("/create")
@Operation(summary = "创建API 应用与接口关系")
@PreAuthorize("@ss.hasPermission('apihub:api-endpoint-rel:create')")
public CommonResult<Long> createApiEndpointRel(@Valid @RequestBody ApiEndpointRelSaveReqVO createReqVO) {
return success(apiEndpointRelService.createApiEndpointRel(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新API 应用与接口关系")
@PreAuthorize("@ss.hasPermission('apihub:api-endpoint-rel:update')")
public CommonResult<Boolean> updateApiEndpointRel(@Valid @RequestBody ApiEndpointRelSaveReqVO updateReqVO) {
apiEndpointRelService.updateApiEndpointRel(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除API 应用与接口关系")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('apihub:api-endpoint-rel:delete')")
public CommonResult<Boolean> deleteApiEndpointRel(@RequestParam("id") Long id) {
apiEndpointRelService.deleteApiEndpointRel(id);
return success(true);
}
@DeleteMapping("/delete-list")
@Parameter(name = "ids", description = "编号", required = true)
@Operation(summary = "批量删除API 应用与接口关系")
@PreAuthorize("@ss.hasPermission('apihub:api-endpoint-rel:delete')")
public CommonResult<Boolean> deleteApiEndpointRelList(@RequestParam("ids") List<Long> ids) {
apiEndpointRelService.deleteApiEndpointRelListByIds(ids);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得API 应用与接口关系")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('apihub:api-endpoint-rel:query')")
public CommonResult<ApiEndpointRelRespVO> getApiEndpointRel(@RequestParam("id") Long id) {
ApiEndpointRelDO apiEndpointRel = apiEndpointRelService.getApiEndpointRel(id);
return success(BeanUtils.toBean(apiEndpointRel, ApiEndpointRelRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得API 应用与接口关系分页")
@PreAuthorize("@ss.hasPermission('apihub:api-endpoint-rel:query')")
public CommonResult<PageResult<ApiEndpointRelRespVO>> getApiEndpointRelPage(@Valid ApiEndpointRelPageReqVO pageReqVO) {
PageResult<ApiEndpointRelDO> pageResult = apiEndpointRelService.getApiEndpointRelPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, ApiEndpointRelRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出API 应用与接口关系 Excel")
@PreAuthorize("@ss.hasPermission('apihub:api-endpoint-rel:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportApiEndpointRelExcel(@Valid ApiEndpointRelPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<ApiEndpointRelDO> list = apiEndpointRelService.getApiEndpointRelPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "API 应用与接口关系.xls", "数据", ApiEndpointRelRespVO.class,
BeanUtils.toBean(list, ApiEndpointRelRespVO.class));
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.admin.apiendpointrel.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 = "管理后台 - API 应用与接口关系分页 Request VO")
@Data
public class ApiEndpointRelPageReqVO extends PageParam {
@Schema(description = "API 应用ID,关联 apihub_api.id", example = "15662")
private Long apiId;
@Schema(description = "接口ID,关联 apihub_api_endpoint.id", example = "14690")
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.apiendpointrel.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 = "管理后台 - API 应用与接口关系 Response VO")
@Data
@ExcelIgnoreUnannotated
public class ApiEndpointRelRespVO {
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "30202")
@ExcelProperty("主键")
private Long id;
@Schema(description = "API 应用ID,关联 apihub_api.id", requiredMode = Schema.RequiredMode.REQUIRED, example = "15662")
@ExcelProperty("API 应用ID,关联 apihub_api.id")
private Long apiId;
@Schema(description = "接口ID,关联 apihub_api_endpoint.id", requiredMode = Schema.RequiredMode.REQUIRED, example = "14690")
@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.apiendpointrel.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - API 应用与接口关系新增/修改 Request VO")
@Data
public class ApiEndpointRelSaveReqVO {
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "30202")
private Long id;
@Schema(description = "API 应用ID,关联 apihub_api.id", requiredMode = Schema.RequiredMode.REQUIRED, example = "15662")
@NotNull(message = "API 应用ID,关联 apihub_api.id不能为空")
private Long apiId;
@Schema(description = "接口ID,关联 apihub_api_endpoint.id", requiredMode = Schema.RequiredMode.REQUIRED, example = "14690")
@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 com.luhu.computility.module.apihub.controller.admin.userapiusage.vo.UserApiUsageSaveReqVO;
import com.luhu.computility.module.apihub.service.userapiusage.UserApiUsageService;
import com.luhu.computility.module.pay.api.notify.dto.PayOrderNotifyReqDTO;
import lombok.extern.slf4j.Slf4j;
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.annotation.security.PermitAll;
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.apiorder.vo.*;
import com.luhu.computility.module.apihub.dal.dataobject.apiorder.ApiOrderDO;
import com.luhu.computility.module.apihub.service.apiorder.ApiOrderService;
@Tag(name = "管理后台 - api订单")
@RestController
@RequestMapping("/apihub/api-order")
@Validated
@Slf4j
public class ApiOrderController {
@Resource
private ApiOrderService apiOrderService;
@Resource
private UserApiUsageService userApiUsageService;
@PostMapping("/create")
@Operation(summary = "创建api订单")
@PreAuthorize("@ss.hasPermission('apihub:api-order:create')")
public CommonResult<Long> createApiOrder(@Valid @RequestBody ApiOrderSaveReqVO createReqVO) {
return success(apiOrderService.createApiOrder(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新api订单")
@PreAuthorize("@ss.hasPermission('apihub:api-order:update')")
public CommonResult<Boolean> updateApiOrder(@Valid @RequestBody ApiOrderSaveReqVO updateReqVO) {
apiOrderService.updateApiOrder(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除api订单")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('apihub:api-order:delete')")
public CommonResult<Boolean> deleteApiOrder(@RequestParam("id") Long id) {
apiOrderService.deleteApiOrder(id);
return success(true);
}
@DeleteMapping("/delete-list")
@Parameter(name = "ids", description = "编号", required = true)
@Operation(summary = "批量删除api订单")
@PreAuthorize("@ss.hasPermission('apihub:api-order:delete')")
public CommonResult<Boolean> deleteApiOrderList(@RequestParam("ids") List<Long> ids) {
apiOrderService.deleteApiOrderListByIds(ids);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得api订单")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('apihub:api-order:query')")
public CommonResult<ApiOrderRespVO> getApiOrder(@RequestParam("id") Long id) {
ApiOrderDO apiOrder = apiOrderService.getApiOrder(id);
return success(BeanUtils.toBean(apiOrder, ApiOrderRespVO.class));
}
@GetMapping("/page")
@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));
}
@GetMapping("/export-excel")
@Operation(summary = "导出api订单 Excel")
@PreAuthorize("@ss.hasPermission('apihub:api-order:export')")
@ApiAccessLog(operateType = EXPORT)
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));
}
/**
* 内部支付任务回调
*/
@PostMapping("/update-paid")
@PermitAll
public CommonResult<Boolean> updateApiOrderPaid(@RequestBody PayOrderNotifyReqDTO notifyReqDTO) {
apiOrderService.updateApiOrderPaid(Long.valueOf(notifyReqDTO.getMerchantOrderId()),
notifyReqDTO.getPayOrderId());
log.error("更新Api订单为已支付------------" + notifyReqDTO.getMerchantOrderId());
ApiOrderDO apiOrder = apiOrderService.getApiOrder(Long.parseLong(notifyReqDTO.getMerchantOrderId()));
userApiUsageService.createUserApiUsage(
new UserApiUsageSaveReqVO().setApiId(apiOrder.getApiId())
.setApiName(apiOrder.getApiName())
.setPackageId(apiOrder.getPackageId())
.setPackageName(apiOrder.getPackageName())
.setPackageTimes(apiOrder.getPackageTimes())
.setPackageValidDays(apiOrder.getPackageValidDays())
.setUserId(apiOrder.getUserId())
.setExpireTime(DateUtil.offsetDay(new Date(), apiOrder.getPackageTimes()).toLocalDateTime() )
.setPackagePrice(apiOrder.getPackagePrice())
);
log.error("创建用户Api资源包数据------------" + notifyReqDTO.getMerchantOrderId());
log.error("内部支付任务回调 ");
return success(true);
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.admin.apiorder.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import com.luhu.computility.framework.common.pojo.PageParam;
import java.math.BigDecimal;
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 ApiOrderPageReqVO extends PageParam {
@Schema(description = "下单用户ID", example = "3895")
private Long userId;
@Schema(description = "购买的API ID", example = "10347")
private Long apiId;
@Schema(description = "购买的套餐ID", example = "8957")
private Long packageId;
@Schema(description = "订单编号")
private String orderNo;
@Schema(description = "订单状态:0=待支付,1=已支付,2=已取消", example = "2")
private Integer status;
@Schema(description = "支付订单编号", example = "14961")
private Long payOrderId;
@Schema(description = "订单支付时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] payTime;
@Schema(description = "支付成功的支付渠道")
private String payChannelCode;
@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.apiorder.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import java.math.BigDecimal;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - api订单 Response VO")
@Data
@ExcelIgnoreUnannotated
public class ApiOrderRespVO {
@Schema(description = "订单ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "30231")
@ExcelProperty("订单ID")
private Long id;
@Schema(description = "下单用户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "3895")
@ExcelProperty("下单用户ID")
private Long userId;
@Schema(description = "购买的API ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "10347")
@ExcelProperty("购买的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)
@ExcelProperty("订单编号")
private String orderNo;
@Schema(description = "订单实际支付金额(分)", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("订单实际支付金额(分)")
private Integer costPrice;
@Schema(description = "订单状态:0=待支付,1=已支付,2=已取消", example = "2")
@ExcelProperty("订单状态:0=待支付,1=已支付,2=已取消")
private Integer status;
@Schema(description = "支付订单编号", example = "14961")
@ExcelProperty("支付订单编号")
private Long payOrderId;
@Schema(description = "订单支付时间")
@ExcelProperty("订单支付时间")
private LocalDateTime payTime;
@Schema(description = "支付成功的支付渠道")
@ExcelProperty("支付成功的支付渠道")
private String payChannelCode;
@Schema(description = "订单完成时间")
@ExcelProperty("订单完成时间")
private LocalDateTime finishTime;
@Schema(description = "订单取消时间")
@ExcelProperty("订单取消时间")
private LocalDateTime cancelTime;
@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.admin.apiorder.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
import java.math.BigDecimal;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - api订单新增/修改 Request VO")
@Data
public class ApiOrderSaveReqVO {
@Schema(description = "订单ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "30231")
private Long id;
@Schema(description = "下单用户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "3895")
@NotNull(message = "下单用户ID不能为空")
private Long userId;
@Schema(description = "购买的API ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "10347")
@NotNull(message = "购买的API ID不能为空")
private Long apiId;
@Schema(description = "购买的套餐ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "8957")
@NotNull(message = "购买的套餐ID不能为空")
private Long packageId;
@Schema(description = "订单编号", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "订单编号不能为空")
private String orderNo;
@Schema(description = "订单实际支付金额(分)", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "订单实际支付金额(分)不能为空")
private Integer costPrice;
@Schema(description = "订单状态:0=待支付,1=已支付,2=已取消", example = "2")
private Integer status;
@Schema(description = "支付订单编号", example = "14961")
private Long payOrderId;
@Schema(description = "订单支付时间")
private LocalDateTime payTime;
@Schema(description = "支付成功的支付渠道")
private String payChannelCode;
@Schema(description = "订单完成时间")
private LocalDateTime finishTime;
@Schema(description = "订单取消时间")
private LocalDateTime cancelTime;
@Schema(description = "备注", example = "你说的对")
private String remark;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.admin.apipackage;
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.apipackage.vo.*;
import com.luhu.computility.module.apihub.dal.dataobject.apipackage.ApiPackageDO;
import com.luhu.computility.module.apihub.service.apipackage.ApiPackageService;
@Tag(name = "管理后台 - API 套餐")
@RestController
@RequestMapping("/apihub/api-package")
@Validated
public class ApiPackageController {
@Resource
private ApiPackageService apiPackageService;
@PostMapping("/create")
@Operation(summary = "创建API 套餐")
@PreAuthorize("@ss.hasPermission('apihub:api-package:create')")
public CommonResult<Long> createApiPackage(@Valid @RequestBody ApiPackageSaveReqVO createReqVO) {
return success(apiPackageService.createApiPackage(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新API 套餐")
@PreAuthorize("@ss.hasPermission('apihub:api-package:update')")
public CommonResult<Boolean> updateApiPackage(@Valid @RequestBody ApiPackageSaveReqVO updateReqVO) {
apiPackageService.updateApiPackage(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除API 套餐")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('apihub:api-package:delete')")
public CommonResult<Boolean> deleteApiPackage(@RequestParam("id") Long id) {
apiPackageService.deleteApiPackage(id);
return success(true);
}
@DeleteMapping("/delete-list")
@Parameter(name = "ids", description = "编号", required = true)
@Operation(summary = "批量删除API 套餐")
@PreAuthorize("@ss.hasPermission('apihub:api-package:delete')")
public CommonResult<Boolean> deleteApiPackageList(@RequestParam("ids") List<Long> ids) {
apiPackageService.deleteApiPackageListByIds(ids);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得API 套餐")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('apihub:api-package:query')")
public CommonResult<ApiPackageRespVO> getApiPackage(@RequestParam("id") Long id) {
ApiPackageDO apiPackage = apiPackageService.getApiPackage(id);
return success(BeanUtils.toBean(apiPackage, ApiPackageRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得API 套餐分页")
@PreAuthorize("@ss.hasPermission('apihub:api-package:query')")
public CommonResult<PageResult<ApiPackageRespVO>> getApiPackagePage(@Valid ApiPackagePageReqVO pageReqVO) {
PageResult<ApiPackageDO> pageResult = apiPackageService.getApiPackagePage(pageReqVO);
return success(BeanUtils.toBean(pageResult, ApiPackageRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出API 套餐 Excel")
@PreAuthorize("@ss.hasPermission('apihub:api-package:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportApiPackageExcel(@Valid ApiPackagePageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<ApiPackageDO> list = apiPackageService.getApiPackagePage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "API 套餐.xls", "数据", ApiPackageRespVO.class,
BeanUtils.toBean(list, ApiPackageRespVO.class));
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.admin.apipackage.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import com.luhu.computility.framework.common.pojo.PageParam;
import java.math.BigDecimal;
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 ApiPackagePageReqVO extends PageParam {
@Schema(description = "关联的API ID", example = "23999")
private Long apiId;
@Schema(description = "套餐名称", example = "芋艿")
private String name;
@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.apipackage.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import java.math.BigDecimal;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - API 套餐 Response VO")
@Data
@ExcelIgnoreUnannotated
public class ApiPackageRespVO {
@Schema(description = "套餐ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1592")
@ExcelProperty("套餐ID")
private Long id;
@Schema(description = "关联的API ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "23999")
@ExcelProperty("关联的API ID")
private Long apiId;
@Schema(description = "套餐名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
@ExcelProperty("套餐名称")
private String name;
@Schema(description = "可调用次数", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("可调用次数")
private Integer times;
@Schema(description = "价格(元)", requiredMode = Schema.RequiredMode.REQUIRED, example = "9887")
@ExcelProperty("价格(元)")
private Integer price;
@Schema(description = "有效期(天),0表示永久有效")
@ExcelProperty("有效期(天),0表示永久有效")
private Integer validDays;
@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.admin.apipackage.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
import java.math.BigDecimal;
@Schema(description = "管理后台 - API 套餐新增/修改 Request VO")
@Data
public class ApiPackageSaveReqVO {
@Schema(description = "套餐ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1592")
private Long id;
@Schema(description = "关联的API ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "23999")
private Long apiId;
@Schema(description = "套餐名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
@NotEmpty(message = "套餐名称不能为空")
private String name;
@Schema(description = "可调用次数", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "可调用次数不能为空")
private Integer times;
@Schema(description = "价格(元)", requiredMode = Schema.RequiredMode.REQUIRED, example = "9887")
@NotNull(message = "价格(元)不能为空")
private Integer price;
@Schema(description = "有效期(天),0表示永久有效")
private Integer validDays;
@Schema(description = "有效期(天),0表示永久有效")
private Boolean status;
@Schema(description = "备注", example = "随便")
private String remark;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.admin.appcredential;
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.appcredential.vo.*;
import com.luhu.computility.module.apihub.dal.dataobject.appcredential.AppCredentialDO;
import com.luhu.computility.module.apihub.service.appcredential.AppCredentialService;
@Tag(name = "管理后台 - 用户密钥信息")
@RestController
@RequestMapping("/apihub/app-credential")
@Validated
public class AppCredentialController {
@Resource
private AppCredentialService appCredentialService;
@PostMapping("/create")
@Operation(summary = "创建用户密钥信息")
@PreAuthorize("@ss.hasPermission('apihub:app-credential:create')")
public CommonResult<Long> createAppCredential(@Valid @RequestBody AppCredentialSaveReqVO createReqVO) {
return success(appCredentialService.createAppCredential(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新用户密钥信息")
@PreAuthorize("@ss.hasPermission('apihub:app-credential:update')")
public CommonResult<Boolean> updateAppCredential(@Valid @RequestBody AppCredentialSaveReqVO updateReqVO) {
appCredentialService.updateAppCredential(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除用户密钥信息")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('apihub:app-credential:delete')")
public CommonResult<Boolean> deleteAppCredential(@RequestParam("id") Long id) {
appCredentialService.deleteAppCredential(id);
return success(true);
}
@DeleteMapping("/delete-list")
@Parameter(name = "ids", description = "编号", required = true)
@Operation(summary = "批量删除用户密钥信息")
@PreAuthorize("@ss.hasPermission('apihub:app-credential:delete')")
public CommonResult<Boolean> deleteAppCredentialList(@RequestParam("ids") List<Long> ids) {
appCredentialService.deleteAppCredentialListByIds(ids);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得用户密钥信息")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('apihub:app-credential:query')")
public CommonResult<AppCredentialRespVO> getAppCredential(@RequestParam("id") Long id) {
AppCredentialDO appCredential = appCredentialService.getAppCredential(id);
return success(BeanUtils.toBean(appCredential, AppCredentialRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得用户密钥信息分页")
@PreAuthorize("@ss.hasPermission('apihub:app-credential:query')")
public CommonResult<PageResult<AppCredentialRespVO>> getAppCredentialPage(@Valid AppCredentialPageReqVO pageReqVO) {
PageResult<AppCredentialDO> pageResult = appCredentialService.getAppCredentialPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, AppCredentialRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出用户密钥信息 Excel")
@PreAuthorize("@ss.hasPermission('apihub:app-credential:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportAppCredentialExcel(@Valid AppCredentialPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<AppCredentialDO> list = appCredentialService.getAppCredentialPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "用户密钥信息.xls", "数据", AppCredentialRespVO.class,
BeanUtils.toBean(list, AppCredentialRespVO.class));
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.admin.appcredential.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 AppCredentialPageReqVO extends PageParam {
@Schema(description = "应用ID,唯一", example = "23068")
private String appId;
@Schema(description = "AES加密后的应用密钥")
private String appSecret;
@Schema(description = "所属用户ID", example = "11786")
private Long userId;
@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.appcredential.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 AppCredentialRespVO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "8721")
@ExcelProperty("主键ID")
private Long id;
@Schema(description = "应用ID,唯一", requiredMode = Schema.RequiredMode.REQUIRED, example = "23068")
@ExcelProperty("应用ID,唯一")
private String appId;
@Schema(description = "AES加密后的应用密钥", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("AES加密后的应用密钥")
private String appSecret;
@Schema(description = "所属用户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "11786")
@ExcelProperty("所属用户ID")
private Long userId;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.admin.appcredential.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 AppCredentialSaveReqVO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "8721")
private Long id;
@Schema(description = "应用ID,唯一", requiredMode = Schema.RequiredMode.REQUIRED, example = "23068")
@NotEmpty(message = "应用ID,唯一不能为空")
private String appId;
@Schema(description = "AES加密后的应用密钥", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "AES加密后的应用密钥不能为空")
private String appSecret;
@Schema(description = "所属用户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "11786")
@NotNull(message = "所属用户ID不能为空")
private Long userId;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.admin.userapiusage;
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.userapiusage.vo.*;
import com.luhu.computility.module.apihub.dal.dataobject.userapiusage.UserApiUsageDO;
import com.luhu.computility.module.apihub.service.userapiusage.UserApiUsageService;
@Tag(name = "管理后台 - 用户API管理")
@RestController
@RequestMapping("/apihub/user-api-usage")
@Validated
public class UserApiUsageController {
@Resource
private UserApiUsageService userApiUsageService;
@PostMapping("/create")
@Operation(summary = "创建用户API管理")
@PreAuthorize("@ss.hasPermission('apihub:user-api-usage:create')")
public CommonResult<Long> createUserApiUsage(@Valid @RequestBody UserApiUsageSaveReqVO createReqVO) {
return success(userApiUsageService.createUserApiUsage(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新用户API管理")
@PreAuthorize("@ss.hasPermission('apihub:user-api-usage:update')")
public CommonResult<Boolean> updateUserApiUsage(@Valid @RequestBody UserApiUsageSaveReqVO updateReqVO) {
userApiUsageService.updateUserApiUsage(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除用户API管理")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('apihub:user-api-usage:delete')")
public CommonResult<Boolean> deleteUserApiUsage(@RequestParam("id") Long id) {
userApiUsageService.deleteUserApiUsage(id);
return success(true);
}
@DeleteMapping("/delete-list")
@Parameter(name = "ids", description = "编号", required = true)
@Operation(summary = "批量删除用户API管理")
@PreAuthorize("@ss.hasPermission('apihub:user-api-usage:delete')")
public CommonResult<Boolean> deleteUserApiUsageList(@RequestParam("ids") List<Long> ids) {
userApiUsageService.deleteUserApiUsageListByIds(ids);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得用户API管理")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('apihub:user-api-usage:query')")
public CommonResult<UserApiUsageRespVO> getUserApiUsage(@RequestParam("id") Long id) {
UserApiUsageDO userApiUsage = userApiUsageService.getUserApiUsage(id);
return success(BeanUtils.toBean(userApiUsage, UserApiUsageRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得用户API管理分页")
@PreAuthorize("@ss.hasPermission('apihub:user-api-usage:query')")
public CommonResult<PageResult<UserApiUsageRespVO>> getUserApiUsagePage(@Valid UserApiUsagePageReqVO pageReqVO) {
return success(userApiUsageService.getUserApiUsagePage(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", "数据", UserApiUsageRespVO.class,
userApiUsageService.getUserApiUsagePage(pageReqVO).getList());
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.admin.userapiusage.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 = "管理后台 - 用户 API 使用统计分页 Request VO")
@Data
public class UserApiUsagePageReqVO extends PageParam {
@Schema(description = "用户ID", example = "26592")
private Long userId;
@Schema(description = "用户手机", example = "8522")
private String userMobile;
@Schema(description = "api名称", example = "8522")
private String apiName;
@Schema(description = "资源包名称", example = "8522")
private String packageName;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.admin.userapiusage.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 = "管理后台 - 用户 API 使用统计 Response VO")
@Data
@ExcelIgnoreUnannotated
public class UserApiUsageRespVO {
@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.admin.userapiusage.vo;
import com.alibaba.excel.annotation.ExcelProperty;
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")
@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.controller.app.api;
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.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.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;
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.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.apipackage.ApiPackageService;
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.annotation.security.PermitAll;
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")
@Validated
public class AppApiController {
@Resource
private ApiService apiService;
@Resource
private ApiCategoryService apiCategoryService;
@Resource
private ApiPackageService apiPackageService;
@GetMapping("/get")
@Operation(summary = "获得API信息")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PermitAll
public CommonResult<AppApiRespVO> getApi(@RequestParam("id") Long id) {
ApiDO api = apiService.getApi(id);
ApiCategoryDO apiCategory = apiCategoryService.getApiCategory(api.getCategoryId());
AppApiRespVO apiRespVO = BeanUtils.toBean(api, AppApiRespVO.class);
apiRespVO.setCategoryName(apiCategory.getName());
List<ApiPackageDO> apiPackageDOS = apiPackageService.selectByApiId(id);
apiRespVO.setApiPackages(BeanUtils.toBean(apiPackageDOS, AppApiPackageRespVO.class));
return success(apiRespVO);
}
@GetMapping("/page")
@Operation(summary = "获得API信息分页")
@PermitAll
public CommonResult<PageResult<AppApiRespVO>> getApiPage(@Valid ApiPageReqVO pageReqVO) {
PageResult<ApiRespVO> pageResult = apiService.getApiPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, AppApiRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出API信息 Excel")
@PreAuthorize("@ss.hasPermission('apihub:api:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportApiExcel(@Valid ApiPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<ApiRespVO> list = apiService.getApiPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "API信息.xls", "数据", AppApiRespVO.class,
BeanUtils.toBean(list, AppApiRespVO.class));
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.app.api.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.math.BigDecimal;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - API 套餐 Response VO")
@Data
@ExcelIgnoreUnannotated
public class AppApiPackageRespVO {
@Schema(description = "套餐ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1592")
@ExcelProperty("套餐ID")
private Long id;
@Schema(description = "关联的API ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "23999")
@ExcelProperty("关联的API ID")
private Long apiId;
@Schema(description = "套餐名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
@ExcelProperty("套餐名称")
private String name;
@Schema(description = "可调用次数", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("可调用次数")
private Integer times;
@Schema(description = "价格(元)", requiredMode = Schema.RequiredMode.REQUIRED, example = "9887")
@ExcelProperty("价格(元)")
private BigDecimal price;
@Schema(description = "有效期(天),0表示永久有效")
@ExcelProperty("有效期(天),0表示永久有效")
private Integer validDays;
@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.api.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.luhu.computility.module.apihub.controller.admin.apipackage.vo.ApiPackageRespVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
@Schema(description = "用户端 - API信息 Response VO")
@Data
@ExcelIgnoreUnannotated
public class AppApiRespVO {
@Schema(description = "API ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "11243")
@ExcelProperty("API ID")
private Long id;
@Schema(description = "API 名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
@ExcelProperty("API 名称")
private String name;
@Schema(description = "API 最低价格描述", example = "你说的对")
@ExcelProperty("API 最低价格描述")
private String priceInfo;
@Schema(description = "API coverimage", example = "https://xxx.png")
@ExcelProperty("API coverimage")
private String coverImage;
@Schema(description = "API 分类", example = "4891084201")
@ExcelProperty("API 分类")
private Long categoryId;
@Schema(description = "API 分类名称", example = "通用api")
@ExcelProperty("API 分类名称")
private String categoryName;
@Schema(description = "API 详细介绍")
@ExcelProperty("API 详细介绍")
private String detail;
@Schema(description = "接口文档内容")
@ExcelProperty("接口文档内容")
private String doc;
@Schema(description = "API 简介", example = "你说的对")
@ExcelProperty("API 简介")
private String description;
@Schema(description = "套餐包", example = "[{}]")
private List<AppApiPackageRespVO> apiPackages;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.app.apicategory;
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.module.apihub.controller.admin.apicategory.vo.ApiCategoryPageReqVO;
import com.luhu.computility.module.apihub.controller.admin.apicategory.vo.ApiCategoryRespVO;
import com.luhu.computility.module.apihub.controller.admin.apicategory.vo.ApiCategorySaveReqVO;
import com.luhu.computility.module.apihub.dal.dataobject.apicategory.ApiCategoryDO;
import com.luhu.computility.module.apihub.service.apicategory.ApiCategoryService;
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.annotation.security.PermitAll;
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-category")
@Validated
public class AppApiCategoryController {
@Resource
private ApiCategoryService apiCategoryService;
@GetMapping("/list")
@Operation(summary = "获得API所有分类")
@PermitAll
public CommonResult<List<ApiCategoryRespVO>> getAllApiCategory() {
List<ApiCategoryDO> apiCategoryDOS = apiCategoryService.getAllApiCategory();
return success(BeanUtils.toBean(apiCategoryDOS, ApiCategoryRespVO.class));
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.app.apiorder;
import cn.hutool.core.collection.CollectionUtil;
import com.luhu.computility.framework.common.pojo.CommonResult;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.common.util.object.BeanUtils;
import com.luhu.computility.framework.security.core.util.SecurityFrameworkUtils;
import com.luhu.computility.module.apihub.controller.app.apiorder.vo.AppApiOrderCreateReqVO;
import com.luhu.computility.module.apihub.controller.app.apiorder.vo.AppApiOrderCreateRespVO;
import com.luhu.computility.module.apihub.controller.app.apiorder.vo.AppApiOrderPageReqVO;
import com.luhu.computility.module.apihub.controller.app.apiorder.vo.AppApiOrderRespVO;
import com.luhu.computility.module.apihub.dal.dataobject.api.ApiDO;
import com.luhu.computility.module.apihub.dal.dataobject.apiorder.ApiOrderDO;
import com.luhu.computility.module.apihub.dal.dataobject.apipackage.ApiPackageDO;
import com.luhu.computility.module.apihub.enums.ApiOrderStatus;
import com.luhu.computility.module.apihub.service.api.ApiService;
import com.luhu.computility.module.apihub.service.apiorder.ApiOrderService;
import com.luhu.computility.module.apihub.service.apipackage.ApiPackageService;
import io.swagger.v3.oas.annotations.Operation;
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.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
import static com.luhu.computility.framework.common.pojo.CommonResult.success;
@Tag(name = "用户端 - api订单")
@RestController
@RequestMapping("/apihub/api-order")
@Validated
public class AppApiOrderController {
@Resource
private ApiOrderService apiOrderService;
@PostMapping("/create")
@Operation(summary = "创建api订单")
public CommonResult<AppApiOrderCreateRespVO> createApiOrder(@Valid @RequestBody AppApiOrderCreateReqVO createReqVO) {
//创建订单
createReqVO.setUserId(SecurityFrameworkUtils.getLoginUser().getId());
ApiOrderDO order = apiOrderService.createOrder(createReqVO);
return success(new AppApiOrderCreateRespVO().setId(order.getId()).setPayOrderId(order.getPayOrderId()));
}
@GetMapping("/page")
@Operation(summary = "获得api订单分页")
public CommonResult<PageResult<AppApiOrderRespVO>> getApiOrderPage(@Valid AppApiOrderPageReqVO pageReqVO) {
PageResult<ApiOrderDO> pageResult = apiOrderService.getAppApiOrderPage(pageReqVO);
PageResult<AppApiOrderRespVO> appApiOrderRespVOPageResult
= BeanUtils.toBean(pageResult, AppApiOrderRespVO.class);
//处理状态,这里一般是交给前端处理
List<AppApiOrderRespVO> list = appApiOrderRespVOPageResult.getList();
if (!CollectionUtil.isEmpty(list)) {
for (AppApiOrderRespVO vo : list) {
vo.setStatusName(ApiOrderStatus.getRemarkByValue(vo.getStatus()));
}
}
appApiOrderRespVOPageResult.setList(list);
return success(appApiOrderRespVOPageResult);
}
/*
@PutMapping("/update")
@Operation(summary = "更新api订单")
@PreAuthorize("@ss.hasPermission('apihub:api-order:update')")
public CommonResult<Boolean> updateApiOrder(@Valid @RequestBody AppApiOrderCreateReqVO updateReqVO) {
apiOrderService.updateApiOrder(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除api订单")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('apihub:api-order:delete')")
public CommonResult<Boolean> deleteApiOrder(@RequestParam("id") Long id) {
apiOrderService.deleteApiOrder(id);
return success(true);
}
@DeleteMapping("/delete-list")
@Parameter(name = "ids", description = "编号", required = true)
@Operation(summary = "批量删除api订单")
@PreAuthorize("@ss.hasPermission('apihub:api-order:delete')")
public CommonResult<Boolean> deleteApiOrderList(@RequestParam("ids") List<Long> ids) {
apiOrderService.deleteApiOrderListByIds(ids);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得api订单")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('apihub:api-order:query')")
public CommonResult<AppApiOrderRespVO> getApiOrder(@RequestParam("id") Long id) {
ApiOrderDO apiOrder = apiOrderService.getApiOrder(id);
return success(BeanUtils.toBean(apiOrder, AppApiOrderRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得api订单分页")
@PreAuthorize("@ss.hasPermission('apihub:api-order:query')")
public CommonResult<PageResult<AppApiOrderRespVO>> getApiOrderPage(@Valid AppApiOrderPageReqVO pageReqVO) {
PageResult<ApiOrderDO> pageResult = apiOrderService.getApiOrderPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, AppApiOrderRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出api订单 Excel")
@PreAuthorize("@ss.hasPermission('apihub:api-order:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportApiOrderExcel(@Valid AppApiOrderPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<ApiOrderDO> list = apiOrderService.getApiOrderPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "api订单.xls", "数据", AppApiOrderRespVO.class,
BeanUtils.toBean(list, AppApiOrderRespVO.class));
}*/
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.app.apiorder.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
@Schema(description = "用户端 - api订单新增/修改 Request VO")
@Data
public class AppApiOrderCreateReqVO {
@Schema(description = "订单ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "30231")
private Long id;
@Schema(description = "下单用户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "3895")
private Long userId;
@Schema(description = "购买的API ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "10347")
@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")
@NotNull(message = "购买的套餐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)
private String orderNo;
@Schema(description = "订单实际支付金额(元)", requiredMode = Schema.RequiredMode.REQUIRED)
private Integer costPrice;
@Schema(description = "订单状态:0=待支付,1=已支付,2=已取消", example = "2")
private Integer status;
@Schema(description = "支付订单编号", example = "14961")
private Long payOrderId;
@Schema(description = "订单支付时间")
private LocalDateTime payTime;
@Schema(description = "支付成功的支付渠道")
private String payChannelCode;
@Schema(description = "订单完成时间")
private LocalDateTime finishTime;
@Schema(description = "订单取消时间")
private LocalDateTime cancelTime;
@Schema(description = "备注", example = "你说的对")
private String remark;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.app.apiorder.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "用户 App - api交易订单创建 Response VO")
@Data
public class AppApiOrderCreateRespVO {
@Schema(description = "订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long id;
@Schema(description = "支付订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long payOrderId;
}
package com.luhu.computility.module.apihub.controller.app.apiorder.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 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;
@Schema(description = "用户端 - api订单分页 Request VO")
@Data
public class AppApiOrderPageReqVO extends PageParam {
@Schema(description = "下单用户ID", example = "3895")
private Long userId;
@Schema(description = "关键字查询", requiredMode = Schema.RequiredMode.REQUIRED, example = "10347")
private String searchQuery;
@Schema(description = "订单状态:0=待支付,1=已支付,2=已取消", example = "2")
private Integer status;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.controller.app.apiorder.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.math.BigDecimal;
import java.time.LocalDateTime;
@Schema(description = "用户端 - api订单 Response VO")
@Data
@ExcelIgnoreUnannotated
public class AppApiOrderRespVO {
@Schema(description = "订单ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "30231")
@ExcelProperty("订单ID")
private Long id;
@Schema(description = "购买的API ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "10347")
@ExcelProperty("购买的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, example = "8957")
private Integer costPrice;
@Schema(description = "订单编号", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("订单编号")
private String orderNo;
@Schema(description = "订单状态", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("订单状态")
private String statusName;
@Schema(description = "订单状态:0=待支付,1=已支付,2=已取消", example = "2")
@ExcelProperty("订单状态:0=待支付,1=已支付,2=已取消")
private Integer status;
@Schema(description = "支付订单编号", example = "14961")
@ExcelProperty("支付订单编号")
private Long payOrderId;
@Schema(description = "订单支付时间")
@ExcelProperty("订单支付时间")
private LocalDateTime payTime;
@Schema(description = "支付成功的支付渠道")
@ExcelProperty("支付成功的支付渠道")
private String payChannelCode;
@Schema(description = "订单完成时间")
@ExcelProperty("订单完成时间")
private LocalDateTime finishTime;
@Schema(description = "订单取消时间")
@ExcelProperty("订单取消时间")
private LocalDateTime cancelTime;
@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.api;
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;
/**
* API信息 DO
*
* @author ljq
*/
@TableName("apihub_api")
@KeySequence("apihub_api_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ApiDO extends BaseDO {
/**
* API ID
*/
@TableId
private Long id;
/**
* API 名称
*/
private String name;
/**
* API 最低价格描述
*/
private String priceInfo;
/**
* API coverimage
*/
private String coverImage;
/**
* API 分类
*/
private Long categoryId;
/**
* API 简介
*/
private String description;
/**
* API 详细介绍
*/
private String detail;
/**
* 接口文档内容
*/
private String doc;
/**
* 状态:1=上架,0=下架
*/
private Integer status;
/**
* 备注
*/
private String remark;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.dal.dataobject.apicalllog;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import com.luhu.computility.framework.mybatis.core.dataobject.BaseDO;
/**
* API 调用日志 DO
*
* @author ljq
*/
@TableName("apihub_api_call_log")
@KeySequence("apihub_api_call_log_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ApiCallLogDO extends BaseDO {
/**
* 调用日志ID
*/
@TableId
private Long id;
/**
* 调用用户ID
*/
private Long userId;
/**
* 调用的API ID
*/
private Long apiId;
/**
* 请求参数
*/
private String requestParams;
/**
* 响应状态(如200, 500等)
*/
private String responseStatus;
/**
* 调用时间
*/
private LocalDateTime callTime;
/**
* 备注
*/
private String remark;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.dal.dataobject.apicategory;
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;
/**
* API分类 DO
*
* @author ljq
*/
@TableName("apihub_api_category")
@KeySequence("apihub_api_category_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ApiCategoryDO extends BaseDO {
/**
* ID
*/
@TableId
private Long id;
/**
* 分类名称
*/
private String name;
/**
* 分类简介
*/
private String description;
/**
* 备注
*/
private String remark;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.dal.dataobject.apiendpoint;
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;
/**
* API 接口 DO
*
* @author ljq
*/
@TableName("apihub_api_endpoint")
@KeySequence("apihub_api_endpoint_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ApiEndpointDO extends BaseDO {
/**
* 接口ID
*/
@TableId
private Long id;
/**
* 接口名称
*/
private String name;
/**
* 接口路径,全路径例如 https://phsl.lijinqi.com/openn_ip/xxx
*/
private String path;
/**
* 请求方式: GET/POST/PUT/DELETE
*/
private String method;
/**
* 参数定义(JSON)
*/
private String params;
/**
* 返回结果示例
*/
private String response;
/**
* 鉴权方式,例如 API_KEY/OAUTH
*/
private String authType;
/**
* 接口级限流规则,例如 100 QPS
*/
private String rateLimit;
/**
* 备注
*/
private String remark;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.dal.dataobject.apiendpointrel;
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;
/**
* API 应用与接口关系 DO
*
* @author ljq
*/
@TableName("apihub_api_endpoint_rel")
@KeySequence("apihub_api_endpoint_rel_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ApiEndpointRelDO extends BaseDO {
/**
* 主键
*/
@TableId
private Long id;
/**
* API 应用ID,关联 apihub_api.id
*/
private Long apiId;
/**
* 接口ID,关联 apihub_api_endpoint.id
*/
private Long apiEndpointId;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.dal.dataobject.apiorder;
import com.alipay.api.domain.AlipayOpenStsTokenGetModel;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import com.luhu.computility.framework.mybatis.core.dataobject.BaseDO;
/**
* api订单 DO
*
* @author ljq
*/
@TableName("apihub_api_order")
@KeySequence("apihub_api_order_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ApiOrderDO extends BaseDO {
/**
* 订单ID
*/
@TableId
private Long id;
/**
* 下单用户ID
*/
private Long userId;
/**
* 购买的API ID
*/
private Long apiId;
/**
* 购买的套餐名称
*/
private String apiName;
/**
* 购买的套餐ID
*/
private Long packageId;
/**
* 购买的套餐名
*/
private String packageName;
/**
* 购买的套餐最大可用次数
*/
private Integer packageTimes;
/**
* 购买的套餐有效期
*/
private Integer packageValidDays;
/**
* 购买的套餐实际费用
*/private Integer costPrice;
/**
* 购买的套餐单价
*/
private Integer packagePrice;
/**
* 订单编号
*/
private String orderNo;
/**
* 订单状态:0=待支付,1=已支付,2=已取消
*/
private Integer status;
/**
* 支付状态:1=已支付,2=未支付
*/
private Integer payStatus;
/**
* 支付订单编号
*/
private Long payOrderId;
/**
* 订单支付时间
*/
private LocalDateTime payTime;
/**
* 支付成功的支付渠道
*/
private String payChannelCode;
/**
* 订单完成时间
*/
private LocalDateTime finishTime;
/**
* 订单取消时间
*/
private LocalDateTime cancelTime;
/**
* 备注
*/
private String remark;
/**
* ip
*/
private String userIp;
/**
* 退款状态
*/
private Integer refundStatus;
/**
* 退款金额,单位:分
*/
private Integer refundPrice;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.dal.dataobject.apipackage;
import lombok.*;
import java.util.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import com.luhu.computility.framework.mybatis.core.dataobject.BaseDO;
/**
* API 套餐 DO
*
* @author ljq
*/
@TableName("apihub_api_package")
@KeySequence("apihub_api_package_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ApiPackageDO extends BaseDO {
/**
* 套餐ID
*/
@TableId
private Long id;
/**
* 关联的API ID
*/
private Long apiId;
/**
* 套餐名称
*/
private String name;
/**
* 可调用次数
*/
private Integer times;
/**
* 价格(元)
*/
private Integer price;
/**
* 有效期(天),0表示永久有效
*/
private Integer validDays;
/**
* 上架状态
*/
private Boolean status;
/**
* 备注
*/
private String remark;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.dal.dataobject.appcredential;
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_app_credential")
@KeySequence("apihub_app_credential_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AppCredentialDO extends BaseDO {
/**
* 主键ID
*/
@TableId
private Long id;
/**
* 应用ID,唯一
*/
private String appId;
/**
* AES加密后的应用密钥
*/
private String appSecret;
/**
* 所属用户ID
*/
private Long userId;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.dal.dataobject.userapiusage;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import com.luhu.computility.framework.mybatis.core.dataobject.BaseDO;
/**
* 用户 API 使用统计 DO
*
* @author ljq
*/
@TableName("apihub_user_api_usage")
@KeySequence("apihub_user_api_usage_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserApiUsageDO extends BaseDO {
/**
* 记录ID
*/
@TableId
private Long id;
/**
* 用户ID
*/
private Long userId;
/**
* 购买的API ID
*/
private Long apiId;
/**
* 购买的套餐名称
*/
private String apiName;
/**
* 购买的套餐ID
*/
private Long packageId;
/**
* 购买的套餐名
*/
private String packageName;
/**
* 购买的套餐最大可用次数
*/
private Long packageTimes;
/**
* 购买的套餐有效期
*/
private Integer packageValidDays;
/**
* 已使用次数
*/
private Integer usedTimes;
/**
* 过期时间
*/
private LocalDateTime expireTime;
/**
* 备注
*/
private String remark;
}
\ No newline at end of file
package com.luhu.computility.module.apihub.dal.mysql.api;
import java.util.*;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
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.dal.dataobject.api.ApiDO;
import com.luhu.computility.module.apihub.dal.dataobject.apicategory.ApiCategoryDO;
import org.apache.ibatis.annotations.Mapper;
import com.luhu.computility.module.apihub.controller.admin.api.vo.*;
/**
* API信息 Mapper
*
* @author ljq
*/
@Mapper
public interface ApiMapper extends BaseMapperX<ApiDO> {
default PageResult<ApiDO> selectPage(ApiPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<ApiDO>()
.likeIfPresent(ApiDO::getName, reqVO.getName())
.eqIfPresent(ApiDO::getStatus, reqVO.getStatus())
.eqIfPresent(ApiDO::getCategoryId, reqVO.getCategoryId())
.betweenIfPresent(ApiDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(ApiDO::getId));
}
default PageResult<ApiRespVO> selectJoinPage(ApiPageReqVO reqVO) {
return selectJoinPage(reqVO, ApiRespVO.class , new MPJLambdaWrapperX<ApiDO>()
.selectAll(ApiDO.class)
.selectAs(ApiCategoryDO :: getName, ApiRespVO :: getCategoryName)
.leftJoin(ApiCategoryDO.class, ApiCategoryDO::getId, ApiDO::getCategoryId)
.eq(!ObjectUtil.isEmpty(reqVO.getCategoryId()), ApiCategoryDO::getId, reqVO.getCategoryId() )
.like(!StringUtils.isEmpty(reqVO.getSearchQuery()), ApiCategoryDO::getName, reqVO.getSearchQuery())
.or(!StringUtils.isEmpty(reqVO.getSearchQuery()))
.like(!StringUtils.isEmpty(reqVO.getSearchQuery()), ApiDO::getName, reqVO.getSearchQuery())
.orderByDesc(ApiDO::getId));
}
/*selectJoinPage(queryVO, ProductSkuRespVO.class, new MPJLambdaWrapperX<ProductSkuDO>()
.selectAll(ProductSkuDO.class)
.select(ProductSpuDO::getName)
.leftJoin(ProductSpuDO.class, ProductSpuDO::getId, ProductSkuDO::getSpuId)
.eq(!ObjectUtil.isEmpty(queryVO.getCategoryId()), ProductSpuDO::getCategoryId, queryVO.getCategoryId() )
.orderByDesc(ProductSkuDO::getCreator));*/
}
\ No newline at end of file
package com.luhu.computility.module.apihub.dal.mysql.apicalllog;
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.module.apihub.dal.dataobject.apicalllog.ApiCallLogDO;
import org.apache.ibatis.annotations.Mapper;
import com.luhu.computility.module.apihub.controller.admin.apicalllog.vo.*;
/**
* API 调用日志 Mapper
*
* @author ljq
*/
@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())
.betweenIfPresent(ApiCallLogDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(ApiCallLogDO::getId));
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.dal.mysql.apicategory;
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.module.apihub.dal.dataobject.apicategory.ApiCategoryDO;
import org.apache.ibatis.annotations.Mapper;
import com.luhu.computility.module.apihub.controller.admin.apicategory.vo.*;
/**
* API分类 Mapper
*
* @author ljq
*/
@Mapper
public interface ApiCategoryMapper extends BaseMapperX<ApiCategoryDO> {
default PageResult<ApiCategoryDO> selectPage(ApiCategoryPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<ApiCategoryDO>()
.likeIfPresent(ApiCategoryDO::getName, reqVO.getName())
.betweenIfPresent(ApiCategoryDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(ApiCategoryDO::getId));
}
default List<ApiCategoryDO> selectAll() {
return selectList();
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.dal.mysql.apiendpoint;
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.dal.dataobject.apiendpoint.ApiEndpointDO;
import com.luhu.computility.module.apihub.dal.dataobject.apiendpointrel.ApiEndpointRelDO;
import org.apache.ibatis.annotations.Mapper;
import com.luhu.computility.module.apihub.controller.admin.apiendpoint.vo.*;
/**
* API 接口 Mapper
*
* @author ljq
*/
@Mapper
public interface ApiEndpointMapper extends BaseMapperX<ApiEndpointDO> {
default PageResult<ApiEndpointDO> selectPage(ApiEndpointPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<ApiEndpointDO>()
.likeIfPresent(ApiEndpointDO::getName, reqVO.getName())
.eqIfPresent(ApiEndpointDO::getPath, reqVO.getPath())
.eqIfPresent(ApiEndpointDO::getMethod, reqVO.getMethod())
.eqIfPresent(ApiEndpointDO::getParams, reqVO.getParams())
.eqIfPresent(ApiEndpointDO::getResponse, reqVO.getResponse())
.eqIfPresent(ApiEndpointDO::getAuthType, reqVO.getAuthType())
.eqIfPresent(ApiEndpointDO::getRateLimit, reqVO.getRateLimit())
.eqIfPresent(ApiEndpointDO::getRemark, reqVO.getRemark())
.betweenIfPresent(ApiEndpointDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(ApiEndpointDO::getId));
}
default List<ApiEndpointDO> selectAll() {
return selectList();
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.dal.mysql.apiendpointrel;
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.apiendpointrel.ApiEndpointRelDO;
import org.apache.ibatis.annotations.Mapper;
import com.luhu.computility.module.apihub.controller.admin.apiendpointrel.vo.*;
/**
* API 应用与接口关系 Mapper
*
* @author ljq
*/
@Mapper
public interface ApiEndpointRelMapper extends BaseMapperX<ApiEndpointRelDO> {
default PageResult<ApiEndpointRelDO> selectPage(ApiEndpointRelPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<ApiEndpointRelDO>()
.eqIfPresent(ApiEndpointRelDO::getApiId, reqVO.getApiId())
.eqIfPresent(ApiEndpointRelDO::getApiEndpointId, reqVO.getApiEndpointId())
.betweenIfPresent(ApiEndpointRelDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(ApiEndpointRelDO::getId));
}
default int deleteByApiId(Long apiId) {
return delete(new LambdaQueryWrapperX<ApiEndpointRelDO>()
.eqIfPresent(ApiEndpointRelDO::getApiId, apiId));
}
default List<ApiEndpointRespVO> getApiEndpointByApiId(Long apiId) {
return selectJoinList(ApiEndpointRespVO.class, new MPJLambdaWrapperX<ApiEndpointRelDO>()
.selectAs(ApiEndpointDO::getName, ApiEndpointRespVO::getName)
.selectAs(ApiEndpointDO::getMethod, ApiEndpointRespVO::getMethod)
.selectAs(ApiEndpointDO::getPath, ApiEndpointRespVO::getPath)
.selectAs(ApiEndpointRelDO::getApiEndpointId, ApiEndpointRespVO::getId)
.leftJoin(ApiEndpointDO.class, ApiEndpointDO::getId, ApiEndpointRelDO::getApiEndpointId)
.eqIfPresent(ApiEndpointRelDO::getApiId, apiId)
);
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.dal.mysql.apiorder;
import java.util.*;
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.mybatis.core.query.LambdaQueryWrapperX;
import com.luhu.computility.framework.mybatis.core.mapper.BaseMapperX;
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 org.apache.ibatis.annotations.Mapper;
import com.luhu.computility.module.apihub.controller.admin.apiorder.vo.*;
/**
* api订单 Mapper
*
* @author ljq
*/
@Mapper
public interface ApiOrderMapper extends BaseMapperX<ApiOrderDO> {
default PageResult<ApiOrderDO> selectPage(ApiOrderPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<ApiOrderDO>()
.eqIfPresent(ApiOrderDO::getUserId, reqVO.getUserId())
.eqIfPresent(ApiOrderDO::getApiId, reqVO.getApiId())
.eqIfPresent(ApiOrderDO::getPackageId, reqVO.getPackageId())
.eqIfPresent(ApiOrderDO::getOrderNo, reqVO.getOrderNo())
.eqIfPresent(ApiOrderDO::getStatus, reqVO.getStatus())
.eqIfPresent(ApiOrderDO::getPayOrderId, reqVO.getPayOrderId())
.betweenIfPresent(ApiOrderDO::getPayTime, reqVO.getPayTime())
.eqIfPresent(ApiOrderDO::getPayChannelCode, reqVO.getPayChannelCode())
.betweenIfPresent(ApiOrderDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(ApiOrderDO::getId));
}
default PageResult<ApiOrderDO> selectAppPage(AppApiOrderPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<ApiOrderDO>()
.eqIfPresent(ApiOrderDO::getUserId, reqVO.getUserId())
.eqIfPresent(ApiOrderDO::getStatus, reqVO.getStatus())
.like(!StringUtils.isEmpty(reqVO.getSearchQuery()), ApiOrderDO::getOrderNo, reqVO.getSearchQuery())
.or(!StringUtils.isEmpty(reqVO.getSearchQuery()))
.like(!StringUtils.isEmpty(reqVO.getSearchQuery()), ApiOrderDO::getApiName, reqVO.getSearchQuery())
.orderByDesc(ApiOrderDO::getId));
}
default int updateByIdAndStatus(Long id, Integer status, ApiOrderDO update) {
return update(update, new LambdaUpdateWrapper<ApiOrderDO>()
.eq(ApiOrderDO::getId, id).eq(ApiOrderDO::getStatus, status));
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.dal.mysql.apipackage;
import java.util.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.QueryWrapperX;
import com.luhu.computility.module.apihub.dal.dataobject.apipackage.ApiPackageDO;
import org.apache.ibatis.annotations.Mapper;
import com.luhu.computility.module.apihub.controller.admin.apipackage.vo.*;
/**
* API 套餐 Mapper
*
* @author ljq
*/
@Mapper
public interface ApiPackageMapper extends BaseMapperX<ApiPackageDO> {
default PageResult<ApiPackageDO> selectPage(ApiPackagePageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<ApiPackageDO>()
.eqIfPresent(ApiPackageDO::getApiId, reqVO.getApiId())
.likeIfPresent(ApiPackageDO::getName, reqVO.getName())
.betweenIfPresent(ApiPackageDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(ApiPackageDO::getId));
}
default List<ApiPackageDO> selectByApiId(Long id) {
return selectList(new LambdaQueryWrapperX<ApiPackageDO>()
.eqIfPresent(ApiPackageDO::getApiId, id)
.orderByDesc(ApiPackageDO::getId));
}
default boolean deleteApiPackageByApiId(Long id ) {
return this.delete(new LambdaQueryWrapper<ApiPackageDO>()
.eq(ApiPackageDO::getApiId, id)) > 0;
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.dal.mysql.appcredential;
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.module.apihub.dal.dataobject.appcredential.AppCredentialDO;
import org.apache.ibatis.annotations.Mapper;
import com.luhu.computility.module.apihub.controller.admin.appcredential.vo.*;
/**
* 用户密钥信息 Mapper
*
* @author ljq
*/
@Mapper
public interface AppCredentialMapper extends BaseMapperX<AppCredentialDO> {
default PageResult<AppCredentialDO> selectPage(AppCredentialPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<AppCredentialDO>()
.eqIfPresent(AppCredentialDO::getAppId, reqVO.getAppId())
.eqIfPresent(AppCredentialDO::getAppSecret, reqVO.getAppSecret())
.eqIfPresent(AppCredentialDO::getUserId, reqVO.getUserId())
.betweenIfPresent(AppCredentialDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(AppCredentialDO::getId));
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.dal.mysql.userapiusage;
import java.util.*;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
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.dal.dataobject.api.ApiDO;
import com.luhu.computility.module.apihub.dal.dataobject.apicategory.ApiCategoryDO;
import com.luhu.computility.module.apihub.dal.dataobject.userapiusage.UserApiUsageDO;
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.*;
/**
* 用户 API 使用统计 Mapper
*
* @author ljq
*/
@Mapper
public interface UserApiUsageMapper extends BaseMapperX<UserApiUsageDO> {
default PageResult<UserApiUsageRespVO> selectPage(UserApiUsagePageReqVO reqVO) {
return selectJoinPage(reqVO, UserApiUsageRespVO.class, new MPJLambdaWrapperX<UserApiUsageDO>()
.selectAll(UserApiUsageDO.class)
.selectAs(MemberUserDO :: getMobile, UserApiUsageRespVO :: getUserMobile)
.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())
.orderByDesc(UserApiUsageDO::getCreateTime));
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.dal.redis;
/**
* 交易 Redis Key 枚举类
*
* @author 芋道源码
*/
public interface RedisKeyConstants {
/**
* api交易序号的缓存
*
* KEY 格式:trade_no:{prefix}
* VALUE 数据格式:编号自增
*/
String API_TRADE_NO = "api_trade_no:";
/**
* api交易序号的缓存
*
* KEY 格式:express_track:{code-logisticsNo-receiverMobile}
* VALUE 数据格式 String, 物流信息集合
*/
String EXPRESS_TRACK = "express_track";
}
package com.luhu.computility.module.apihub.dal.redis.no;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.luhu.computility.module.apihub.dal.redis.RedisKeyConstants;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
import java.time.Duration;
import java.time.LocalDateTime;
/**
* 订单序号的 Redis DAO
*
* @author HUIHUI
*/
@Repository
public class ApiOrderNoRedisDAO {
public static final String API_ORDER_NO_PREFIX = "a";
public static final String AFTER_SALE_NO_PREFIX = "p";
@Resource
private StringRedisTemplate stringRedisTemplate;
/**
* 生成序号
*
* @param prefix 前缀
* @return 序号
*/
public String generate(String prefix) {
// 递增序号
String noPrefix = prefix + DateUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_PATTERN);
String key = RedisKeyConstants.API_TRADE_NO + noPrefix;
Long no = stringRedisTemplate.opsForValue().increment(key);
// 设置过期时间
stringRedisTemplate.expire(key, Duration.ofMinutes(1L));
return noPrefix + no;
}
}
package com.luhu.computility.module.apihub.enums;
/**
* 订单支付状态
*/
public enum ApiOrderPayStatus {
// 请根据实际情况改成对应的值和备注
WAITING(0, "未支付"),
SUCCESS(10, "支付成功"),
REFUND(20, "已退款"),
CLOSED(30, "支付关闭"), // 注意:全部退款后,还是 REFUND 状态
;
private int value;
private String remark;
private ApiOrderPayStatus(int value, String remark) {
this.value = value;
this.remark = remark;
}
public int getValue() {
return value;
}
public String getRemark() {
return remark;
}
public static ApiOrderPayStatus getByValue(int value) {
for (ApiOrderPayStatus o : ApiOrderPayStatus.values()) {
if (o.getValue() == value) {
return o;
}
}
return null;
}
public static String getRemarkByValue(Integer value) {
for (ApiOrderPayStatus status : values()) {
if (status.getValue() == value) {
return status.getRemark();
}
}
return null;
}
}
package com.luhu.computility.module.apihub.enums;
/**
* 订单退款状态
*/
public enum ApiOrderRefundStatus {
// 请根据实际情况改成对应的值和备注
NONE(0, "未退款"),
ALL(20, "全部退款");
private int value;
private String remark;
private ApiOrderRefundStatus(int value, String remark) {
this.value = value;
this.remark = remark;
}
public int getValue() {
return value;
}
public String getRemark() {
return remark;
}
public static ApiOrderRefundStatus getByValue(int value) {
for (ApiOrderRefundStatus o : ApiOrderRefundStatus.values()) {
if (o.getValue() == value) {
return o;
}
}
return null;
}
}
package com.luhu.computility.module.apihub.enums;
/**
* 订单状态
*/
public enum ApiOrderStatus {
// 请根据实际情况改成对应的值和备注
UNPAID(0, "待支付"),
PAID(10, "已支付"),
CANCELED(40, "已取消");
private int value;
private String remark;
private ApiOrderStatus(int value, String remark) {
this.value = value;
this.remark = remark;
}
public int getValue() {
return value;
}
public String getRemark() {
return remark;
}
public static ApiOrderStatus getByValue(int value) {
for (ApiOrderStatus o : ApiOrderStatus.values()) {
if (o.getValue() == value) {
return o;
}
}
return null;
}
public static String getRemarkByValue(Integer value) {
for (ApiOrderStatus status : values()) {
if (status.getValue() == value) {
return status.getRemark();
}
}
return null;
}
}
package com.luhu.computility.module.apihub.enums;
import com.luhu.computility.framework.common.exception.ErrorCode;
/**
* ApiHub 错误码枚举类
* <p>
* ApiHub 系统,使用 1-010-000-000 段
*/
public interface ErrorCodeConstants {
ErrorCode USER_API_USAGE_NOT_EXISTS = new ErrorCode(1_010_001_000, "用户 API 使用统计不存在");
ErrorCode API_CALL_LOG_NOT_EXISTS = new ErrorCode(1_010_001_001, " API 日志不存在");
ErrorCode API_NOT_EXISTS = new ErrorCode(1_010_001_002, " API 模块不存在");
ErrorCode API_ORDER_NOT_EXISTS = new ErrorCode(1_010_001_003, " API 订单不存在");
ErrorCode API_PACKAGE_NOT_EXISTS = new ErrorCode(1_010_001_004, " API 套餐不存在");
ErrorCode API_CATEGORY_NOT_EXISTS = new ErrorCode(1_010_001_005, "API分类不存在");
ErrorCode API_ORDER_NOT_FOUND = new ErrorCode(1_010_001_011, "API订单不存在");
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_REL_NOT_EXISTS = new ErrorCode(1_010_001_018, "API 应用与接口关系不存在");
ErrorCode APP_CREDENTIAL_NOT_EXISTS = new ErrorCode(1_010_001_019, "用户密钥信息不存在");
}
package com.luhu.computility.module.apihub.service.api;
import java.util.*;
import javax.validation.*;
import com.luhu.computility.module.apihub.controller.admin.api.vo.*;
import com.luhu.computility.module.apihub.dal.dataobject.api.ApiDO;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.common.pojo.PageParam;
/**
* API信息 Service 接口
*
* @author ljq
*/
public interface ApiService {
/**
* 创建API信息
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createApi(@Valid ApiSaveReqVO createReqVO);
/**
* 更新API信息
*
* @param updateReqVO 更新信息
*/
void updateApi(@Valid ApiSaveReqVO updateReqVO);
/**
* 删除API信息
*
* @param id 编号
*/
void deleteApi(Long id);
/**
* 批量删除API信息
*
* @param ids 编号
*/
void deleteApiListByIds(List<Long> ids);
/**
* 获得API信息
*
* @param id 编号
* @return API信息
*/
ApiDO getApi(Long id);
/**
* 获得API信息分页
*
* @param pageReqVO 分页查询
* @return API信息分页
*/
PageResult<ApiRespVO> getApiPage(ApiPageReqVO pageReqVO);
}
\ No newline at end of file
package com.luhu.computility.module.apihub.service.api;
import cn.hutool.core.collection.CollUtil;
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.api.vo.*;
import com.luhu.computility.module.apihub.dal.dataobject.api.ApiDO;
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.api.ApiMapper;
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.*;
/**
* API信息 Service 实现类
*
* @author ljq
*/
@Service
@Validated
public class ApiServiceImpl implements ApiService {
@Resource
private ApiMapper apiMapper;
@Override
public Long createApi(ApiSaveReqVO createReqVO) {
// 插入
ApiDO api = BeanUtils.toBean(createReqVO, ApiDO.class);
apiMapper.insert(api);
// 返回
return api.getId();
}
@Override
public void updateApi(ApiSaveReqVO updateReqVO) {
// 校验存在
validateApiExists(updateReqVO.getId());
// 更新
ApiDO updateObj = BeanUtils.toBean(updateReqVO, ApiDO.class);
apiMapper.updateById(updateObj);
}
@Override
public void deleteApi(Long id) {
// 校验存在
validateApiExists(id);
// 删除
apiMapper.deleteById(id);
}
@Override
public void deleteApiListByIds(List<Long> ids) {
// 删除
apiMapper.deleteByIds(ids);
}
private void validateApiExists(Long id) {
if (apiMapper.selectById(id) == null) {
throw exception(API_NOT_EXISTS);
}
}
@Override
public ApiDO getApi(Long id) {
return apiMapper.selectById(id);
}
@Override
public PageResult<ApiRespVO> getApiPage(ApiPageReqVO pageReqVO) {
return apiMapper.selectJoinPage(pageReqVO);
}
}
\ No newline at end of file
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.dal.dataobject.apicalllog.ApiCallLogDO;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.common.pojo.PageParam;
/**
* API 调用日志 Service 接口
*
* @author ljq
*/
public interface ApiCallLogService {
/**
* 创建API 调用日志
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createApiCallLog(@Valid ApiCallLogSaveReqVO createReqVO);
/**
* 更新API 调用日志
*
* @param updateReqVO 更新信息
*/
void updateApiCallLog(@Valid ApiCallLogSaveReqVO updateReqVO);
/**
* 删除API 调用日志
*
* @param id 编号
*/
void deleteApiCallLog(Long id);
/**
* 批量删除API 调用日志
*
* @param ids 编号
*/
void deleteApiCallLogListByIds(List<Long> ids);
/**
* 获得API 调用日志
*
* @param id 编号
* @return API 调用日志
*/
ApiCallLogDO getApiCallLog(Long id);
/**
* 获得API 调用日志分页
*
* @param pageReqVO 分页查询
* @return API 调用日志分页
*/
PageResult<ApiCallLogDO> getApiCallLogPage(ApiCallLogPageReqVO pageReqVO);
}
\ No newline at end of file
package com.luhu.computility.module.apihub.service.apicalllog;
import cn.hutool.core.collection.CollUtil;
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.apicalllog.vo.*;
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;
import com.luhu.computility.framework.common.util.object.BeanUtils;
import com.luhu.computility.module.apihub.dal.mysql.apicalllog.ApiCallLogMapper;
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.*;
/**
* API 调用日志 Service 实现类
*
* @author ljq
*/
@Service
@Validated
public class ApiCallLogServiceImpl implements ApiCallLogService {
@Resource
private ApiCallLogMapper apiCallLogMapper;
@Override
public Long createApiCallLog(ApiCallLogSaveReqVO createReqVO) {
// 插入
ApiCallLogDO apiCallLog = BeanUtils.toBean(createReqVO, ApiCallLogDO.class);
apiCallLogMapper.insert(apiCallLog);
// 返回
return apiCallLog.getId();
}
@Override
public void updateApiCallLog(ApiCallLogSaveReqVO updateReqVO) {
// 校验存在
validateApiCallLogExists(updateReqVO.getId());
// 更新
ApiCallLogDO updateObj = BeanUtils.toBean(updateReqVO, ApiCallLogDO.class);
apiCallLogMapper.updateById(updateObj);
}
@Override
public void deleteApiCallLog(Long id) {
// 校验存在
validateApiCallLogExists(id);
// 删除
apiCallLogMapper.deleteById(id);
}
@Override
public void deleteApiCallLogListByIds(List<Long> ids) {
// 删除
apiCallLogMapper.deleteByIds(ids);
}
private void validateApiCallLogExists(Long id) {
if (apiCallLogMapper.selectById(id) == null) {
throw exception(API_CALL_LOG_NOT_EXISTS);
}
}
@Override
public ApiCallLogDO getApiCallLog(Long id) {
return apiCallLogMapper.selectById(id);
}
@Override
public PageResult<ApiCallLogDO> getApiCallLogPage(ApiCallLogPageReqVO pageReqVO) {
return apiCallLogMapper.selectPage(pageReqVO);
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.service.apicategory;
import java.util.*;
import javax.validation.*;
import com.luhu.computility.module.apihub.controller.admin.apicategory.vo.*;
import com.luhu.computility.module.apihub.dal.dataobject.apicategory.ApiCategoryDO;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.common.pojo.PageParam;
/**
* API分类 Service 接口
*
* @author ljq
*/
public interface ApiCategoryService {
/**
* 创建API分类
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createApiCategory(@Valid ApiCategorySaveReqVO createReqVO);
/**
* 更新API分类
*
* @param updateReqVO 更新信息
*/
void updateApiCategory(@Valid ApiCategorySaveReqVO updateReqVO);
/**
* 删除API分类
*
* @param id 编号
*/
void deleteApiCategory(Long id);
/**
* 批量删除API分类
*
* @param ids 编号
*/
void deleteApiCategoryListByIds(List<Long> ids);
/**
* 获得API分类
*
* @param id 编号
* @return API分类
*/
ApiCategoryDO getApiCategory(Long id);
/**
* 获得API分类分页
*
* @param pageReqVO 分页查询
* @return API分类分页
*/
PageResult<ApiCategoryDO> getApiCategoryPage(ApiCategoryPageReqVO pageReqVO);
/**
* 获得API分类分页
*
* @return API分类分页
*/
List<ApiCategoryDO> getAllApiCategory();
}
\ No newline at end of file
package com.luhu.computility.module.apihub.service.apicategory;
import cn.hutool.core.collection.CollUtil;
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.apicategory.vo.*;
import com.luhu.computility.module.apihub.dal.dataobject.apicategory.ApiCategoryDO;
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.apicategory.ApiCategoryMapper;
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.*;
/**
* API分类 Service 实现类
*
* @author ljq
*/
@Service
@Validated
public class ApiCategoryServiceImpl implements ApiCategoryService {
@Resource
private ApiCategoryMapper apiCategoryMapper;
@Override
public Long createApiCategory(ApiCategorySaveReqVO createReqVO) {
// 插入
ApiCategoryDO apiCategory = BeanUtils.toBean(createReqVO, ApiCategoryDO.class);
apiCategoryMapper.insert(apiCategory);
// 返回
return apiCategory.getId();
}
@Override
public void updateApiCategory(ApiCategorySaveReqVO updateReqVO) {
// 校验存在
validateApiCategoryExists(updateReqVO.getId());
// 更新
ApiCategoryDO updateObj = BeanUtils.toBean(updateReqVO, ApiCategoryDO.class);
apiCategoryMapper.updateById(updateObj);
}
@Override
public void deleteApiCategory(Long id) {
// 校验存在
validateApiCategoryExists(id);
// 删除
apiCategoryMapper.deleteById(id);
}
@Override
public void deleteApiCategoryListByIds(List<Long> ids) {
// 删除
apiCategoryMapper.deleteByIds(ids);
}
private void validateApiCategoryExists(Long id) {
if (apiCategoryMapper.selectById(id) == null) {
throw exception(API_CATEGORY_NOT_EXISTS);
}
}
@Override
public ApiCategoryDO getApiCategory(Long id) {
return apiCategoryMapper.selectById(id);
}
@Override
public PageResult<ApiCategoryDO> getApiCategoryPage(ApiCategoryPageReqVO pageReqVO) {
return apiCategoryMapper.selectPage(pageReqVO);
}
@Override
public List<ApiCategoryDO> getAllApiCategory() {
return apiCategoryMapper.selectAll();
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.service.apiendpoint;
import java.util.*;
import javax.validation.*;
import com.luhu.computility.module.apihub.controller.admin.apiendpoint.vo.*;
import com.luhu.computility.module.apihub.dal.dataobject.apiendpoint.ApiEndpointDO;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.common.pojo.PageParam;
/**
* API 接口 Service 接口
*
* @author ljq
*/
public interface ApiEndpointService {
/**
* 创建API 接口
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createApiEndpoint(@Valid ApiEndpointSaveReqVO createReqVO);
/**
* 更新API 接口
*
* @param updateReqVO 更新信息
*/
void updateApiEndpoint(@Valid ApiEndpointSaveReqVO updateReqVO);
/**
* 删除API 接口
*
* @param id 编号
*/
void deleteApiEndpoint(Long id);
/**
* 批量删除API 接口
*
* @param ids 编号
*/
void deleteApiEndpointListByIds(List<Long> ids);
/**
* 获得API 接口
*
* @param id 编号
* @return API 接口
*/
ApiEndpointDO getApiEndpoint(Long id);
/**
* 获得API 接口分页
*
* @param pageReqVO 分页查询
* @return API 接口分页
*/
PageResult<ApiEndpointDO> getApiEndpointPage(ApiEndpointPageReqVO pageReqVO);
/**
* 获得API所有接口
*
* @return API 接口
*/
List<ApiEndpointDO> getApiEndpointList();
}
\ No newline at end of file
package com.luhu.computility.module.apihub.service.apiendpoint;
import cn.hutool.core.collection.CollUtil;
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.apiendpoint.vo.*;
import com.luhu.computility.module.apihub.dal.dataobject.apiendpoint.ApiEndpointDO;
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.apiendpoint.ApiEndpointMapper;
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.*;
/**
* API 接口 Service 实现类
*
* @author ljq
*/
@Service
@Validated
public class ApiEndpointServiceImpl implements ApiEndpointService {
@Resource
private ApiEndpointMapper apiEndpointMapper;
@Override
public Long createApiEndpoint(ApiEndpointSaveReqVO createReqVO) {
// 插入
ApiEndpointDO apiEndpoint = BeanUtils.toBean(createReqVO, ApiEndpointDO.class);
apiEndpointMapper.insert(apiEndpoint);
// 返回
return apiEndpoint.getId();
}
@Override
public void updateApiEndpoint(ApiEndpointSaveReqVO updateReqVO) {
// 校验存在
validateApiEndpointExists(updateReqVO.getId());
// 更新
ApiEndpointDO updateObj = BeanUtils.toBean(updateReqVO, ApiEndpointDO.class);
apiEndpointMapper.updateById(updateObj);
}
@Override
public void deleteApiEndpoint(Long id) {
// 校验存在
validateApiEndpointExists(id);
// 删除
apiEndpointMapper.deleteById(id);
}
@Override
public void deleteApiEndpointListByIds(List<Long> ids) {
// 删除
apiEndpointMapper.deleteByIds(ids);
}
private void validateApiEndpointExists(Long id) {
if (apiEndpointMapper.selectById(id) == null) {
throw exception(API_ENDPOINT_NOT_EXISTS);
}
}
@Override
public ApiEndpointDO getApiEndpoint(Long id) {
return apiEndpointMapper.selectById(id);
}
@Override
public PageResult<ApiEndpointDO> getApiEndpointPage(ApiEndpointPageReqVO pageReqVO) {
return apiEndpointMapper.selectPage(pageReqVO);
}
@Override
public List<ApiEndpointDO> getApiEndpointList() {
return apiEndpointMapper.selectAll();
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.service.apiendpointrel;
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.apiendpointrel.vo.*;
import com.luhu.computility.module.apihub.dal.dataobject.apiendpointrel.ApiEndpointRelDO;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.common.pojo.PageParam;
/**
* API 应用与接口关系 Service 接口
*
* @author ljq
*/
public interface ApiEndpointRelService {
/**
* 创建API 应用与接口关系
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createApiEndpointRel(@Valid ApiEndpointRelSaveReqVO createReqVO);
/**
* 更新API 应用与接口关系
*
* @param updateReqVO 更新信息
*/
void updateApiEndpointRel(@Valid ApiEndpointRelSaveReqVO updateReqVO);
/**
* 删除API 应用与接口关系
*
* @param id 编号
*/
void deleteApiEndpointRel(Long id);
/**
* 批量删除API 应用与接口关系
*
* @param ids 编号
*/
void deleteApiEndpointRelListByIds(List<Long> ids);
/**
* 获得API 应用与接口关系
*
* @param id 编号
* @return API 应用与接口关系
*/
ApiEndpointRelDO getApiEndpointRel(Long id);
/**
* 获得API 应用与接口关系分页
*
* @param pageReqVO 分页查询
* @return API 应用与接口关系分页
*/
PageResult<ApiEndpointRelDO> getApiEndpointRelPage(ApiEndpointRelPageReqVO pageReqVO);
/**
* 获得API 应用与接口关系
*
* @param apiId 分页查询
* @return API 应用与接口关系分页
*/
List<ApiEndpointRespVO> getApiEndpointByApiId(Long apiId);
/**
* 根据apiId删除关联的ApiEndpoint
*/
Integer deleteByApiId(Long apiId);
}
\ No newline at end of file
package com.luhu.computility.module.apihub.service.apiendpointrel;
import cn.hutool.core.collection.CollUtil;
import com.luhu.computility.module.apihub.controller.admin.apiendpoint.vo.ApiEndpointRespVO;
import com.luhu.computility.module.apihub.dal.dataobject.apiendpoint.ApiEndpointDO;
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.apiendpointrel.vo.*;
import com.luhu.computility.module.apihub.dal.dataobject.apiendpointrel.ApiEndpointRelDO;
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.apiendpointrel.ApiEndpointRelMapper;
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.*;
/**
* API 应用与接口关系 Service 实现类
*
* @author ljq
*/
@Service
@Validated
public class ApiEndpointRelServiceImpl implements ApiEndpointRelService {
@Resource
private ApiEndpointRelMapper apiEndpointRelMapper;
@Override
public Long createApiEndpointRel(ApiEndpointRelSaveReqVO createReqVO) {
// 插入
ApiEndpointRelDO apiEndpointRel = BeanUtils.toBean(createReqVO, ApiEndpointRelDO.class);
apiEndpointRelMapper.insert(apiEndpointRel);
// 返回
return apiEndpointRel.getId();
}
@Override
public void updateApiEndpointRel(ApiEndpointRelSaveReqVO updateReqVO) {
// 校验存在
validateApiEndpointRelExists(updateReqVO.getId());
// 更新
ApiEndpointRelDO updateObj = BeanUtils.toBean(updateReqVO, ApiEndpointRelDO.class);
apiEndpointRelMapper.updateById(updateObj);
}
@Override
public void deleteApiEndpointRel(Long id) {
// 校验存在
validateApiEndpointRelExists(id);
// 删除
apiEndpointRelMapper.deleteById(id);
}
@Override
public void deleteApiEndpointRelListByIds(List<Long> ids) {
// 删除
apiEndpointRelMapper.deleteByIds(ids);
}
private void validateApiEndpointRelExists(Long id) {
if (apiEndpointRelMapper.selectById(id) == null) {
throw exception(API_ENDPOINT_REL_NOT_EXISTS);
}
}
@Override
public ApiEndpointRelDO getApiEndpointRel(Long id) {
return apiEndpointRelMapper.selectById(id);
}
@Override
public PageResult<ApiEndpointRelDO> getApiEndpointRelPage(ApiEndpointRelPageReqVO pageReqVO) {
return apiEndpointRelMapper.selectPage(pageReqVO);
}
@Override
public List<ApiEndpointRespVO> getApiEndpointByApiId(Long apiId) {
return apiEndpointRelMapper.getApiEndpointByApiId(apiId);
}
@Override
public Integer deleteByApiId(Long apiId) {
return apiEndpointRelMapper.deleteByApiId(apiId);
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.service.apiorder;
import java.util.*;
import javax.validation.*;
import com.luhu.computility.module.apihub.controller.admin.apiorder.vo.*;
import com.luhu.computility.module.apihub.controller.app.apiorder.vo.AppApiOrderCreateReqVO;
import com.luhu.computility.module.apihub.controller.app.apiorder.vo.AppApiOrderPageReqVO;
import com.luhu.computility.module.apihub.dal.dataobject.apiorder.ApiOrderDO;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.common.pojo.PageParam;
/**
* api订单 Service 接口
*
* @author ljq
*/
public interface ApiOrderService {
/**
* 创建api订单
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createApiOrder(@Valid ApiOrderSaveReqVO createReqVO);
ApiOrderDO createOrder(AppApiOrderCreateReqVO createReqVO);
/**
* 更新api订单
*
* @param updateReqVO 更新信息
*/
void updateApiOrder(@Valid ApiOrderSaveReqVO updateReqVO);
/**
* 删除api订单
*
* @param id 编号
*/
void deleteApiOrder(Long id);
/**
* 批量删除api订单
*
* @param ids 编号
*/
void deleteApiOrderListByIds(List<Long> ids);
/**
* 获得api订单
*
* @param id 编号
* @return api订单
*/
ApiOrderDO getApiOrder(Long id);
/**
* 获得api订单分页
*
* @param pageReqVO 分页查询
* @return api订单分页
*/
PageResult<ApiOrderDO> getApiOrderPage(ApiOrderPageReqVO pageReqVO);
/**
* 获得api订单分页(用户端)
*
* @param pageReqVO 分页查询
* @return api订单分页
*/
PageResult<ApiOrderDO> getAppApiOrderPage(AppApiOrderPageReqVO pageReqVO);
/**
* 更新api交易订单已支付
*
* @param merchantOrderId api交易订单id
* @param payOrderId api支付订单编号
*/
void updateApiOrderPaid(Long merchantOrderId, Long payOrderId);
}
\ No newline at end of file
package com.luhu.computility.module.apihub.service.apiorder;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import com.luhu.computility.framework.common.enums.UserTypeEnum;
import com.luhu.computility.framework.common.util.json.JsonUtils;
import com.luhu.computility.framework.common.util.string.StrUtils;
import com.luhu.computility.module.apihub.config.ApiOrderProperties;
import com.luhu.computility.module.apihub.controller.app.apiorder.vo.AppApiOrderCreateReqVO;
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.apipackage.ApiPackageDO;
import com.luhu.computility.module.apihub.dal.redis.no.ApiOrderNoRedisDAO;
import com.luhu.computility.module.apihub.enums.ApiOrderPayStatus;
import com.luhu.computility.module.apihub.enums.ApiOrderRefundStatus;
import com.luhu.computility.module.apihub.enums.ApiOrderStatus;
import com.luhu.computility.module.apihub.service.api.ApiService;
import com.luhu.computility.module.apihub.service.apipackage.ApiPackageService;
import com.luhu.computility.module.member.api.address.dto.MemberAddressRespDTO;
import com.luhu.computility.module.pay.api.order.PayOrderApi;
import com.luhu.computility.module.pay.api.order.dto.PayOrderCreateReqDTO;
import com.luhu.computility.module.pay.api.order.dto.PayOrderRespDTO;
import com.luhu.computility.module.pay.enums.order.PayOrderStatusEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.*;
import com.luhu.computility.module.apihub.controller.admin.apiorder.vo.*;
import com.luhu.computility.module.apihub.dal.dataobject.apiorder.ApiOrderDO;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.common.util.object.BeanUtils;
import com.luhu.computility.module.apihub.dal.mysql.apiorder.ApiOrderMapper;
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.getSumValue;
import static com.luhu.computility.framework.common.util.date.LocalDateTimeUtils.addTime;
import static com.luhu.computility.framework.common.util.servlet.ServletUtils.getClientIP;
import static com.luhu.computility.framework.web.core.util.WebFrameworkUtils.getTerminal;
import static com.luhu.computility.module.apihub.enums.ErrorCodeConstants.*;
/**
* api订单 Service 实现类
*
* @author ljq
*/
@Service
@Validated
@Slf4j
public class ApiOrderServiceImpl implements ApiOrderService {
@Resource
private ApiOrderMapper apiOrderMapper;
@Resource
private ApiService apiService;
@Resource
private ApiPackageService apiPackageService;
@Resource
private ApiOrderNoRedisDAO apiOrderNoRedisDAO;
@Resource
private ApiOrderProperties apiOrderProperties;
@Resource
private PayOrderApi payOrderApi;
@Override
public Long createApiOrder(ApiOrderSaveReqVO createReqVO) {
// 插入
ApiOrderDO apiOrder = BeanUtils.toBean(createReqVO, ApiOrderDO.class);
apiOrderMapper.insert(apiOrder);
// 返回
return apiOrder.getId();
}
@Override
public void updateApiOrder(ApiOrderSaveReqVO updateReqVO) {
// 校验存在
validateApiOrderExists(updateReqVO.getId());
// 更新
ApiOrderDO updateObj = BeanUtils.toBean(updateReqVO, ApiOrderDO.class);
apiOrderMapper.updateById(updateObj);
}
@Override
public void deleteApiOrder(Long id) {
// 校验存在
validateApiOrderExists(id);
// 删除
apiOrderMapper.deleteById(id);
}
@Override
public void deleteApiOrderListByIds(List<Long> ids) {
// 删除
apiOrderMapper.deleteByIds(ids);
}
@NotNull
private ApiOrderDO validateApiOrderExists(Long id) {
// 校验API订单是否存在
ApiOrderDO order = apiOrderMapper.selectById(id);
if (order == null) {
throw exception(API_ORDER_NOT_EXISTS);
}
return order;
}
@Override
public ApiOrderDO getApiOrder(Long id) {
return apiOrderMapper.selectById(id);
}
@Override
public PageResult<ApiOrderDO> getApiOrderPage(ApiOrderPageReqVO pageReqVO) {
return apiOrderMapper.selectPage(pageReqVO);
}
@Override
public PageResult<ApiOrderDO> getAppApiOrderPage(AppApiOrderPageReqVO pageReqVO) {
return apiOrderMapper.selectAppPage(pageReqVO);
}
@Override
@Transactional(rollbackFor = Exception.class)
//@TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_CREATE)
public ApiOrderDO createOrder(AppApiOrderCreateReqVO createReqVO) {
// 1.构建订单
ApiOrderDO order = buildApiOrder(createReqVO);
// 2. 保存订单
apiOrderMapper.insert(order);
// 3. 订单创建后的逻辑
//// 3. 生成预支付
if (order.getCostPrice() > 0) {
createPayOrder(order);
}
return order;
}
private ApiOrderDO buildApiOrder(AppApiOrderCreateReqVO createReqVO) {
ApiDO api = apiService.getApi(createReqVO.getApiId());
ApiPackageDO apiPackage = apiPackageService.getApiPackage(createReqVO.getPackageId());
//这部分数据是为了避免订单待支付期间修改api和套餐信息 所以存储
createReqVO.setApiName(api.getName());
createReqVO.setPackageName(apiPackage.getName());
createReqVO.setPackagePrice(apiPackage.getPrice());
createReqVO.setPackageTimes(apiPackage.getTimes());
createReqVO.setPackageValidDays(apiPackage.getValidDays());
//业务上,订单实际支付金额=套餐金额
createReqVO.setCostPrice(apiPackage.getPrice());
ApiOrderDO order = BeanUtils.toBean(createReqVO, ApiOrderDO.class);
order.setOrderNo(apiOrderNoRedisDAO.generate(ApiOrderNoRedisDAO.API_ORDER_NO_PREFIX));
order.setStatus(ApiOrderStatus.UNPAID.getValue());
order.setUserIp(getClientIP());
order.setRefundStatus(ApiOrderRefundStatus.NONE.getValue()).setRefundPrice(0);
return order;
}
private void createPayOrder(ApiOrderDO order) {
// 创建支付单,用于后续的支付
PayOrderCreateReqDTO payOrderCreateReqDTO = new PayOrderCreateReqDTO()
.setAppKey(apiOrderProperties.getPayAppKey()).setUserIp(order.getUserIp());
// 商户相关字段
payOrderCreateReqDTO.setMerchantOrderId(String.valueOf(order.getId()));
String subject = order.getApiName()+order.getPackageName();
subject = StrUtils.maxLength(subject, PayOrderCreateReqDTO.SUBJECT_MAX_LENGTH); // 避免超过 32 位
payOrderCreateReqDTO.setSubject(subject);
payOrderCreateReqDTO.setBody(subject);
// 订单相关字段
payOrderCreateReqDTO.setPrice(order.getCostPrice()).setExpireTime(addTime(apiOrderProperties.getPayExpireTime()));
Long payOrderId = payOrderApi.createOrder(payOrderCreateReqDTO);
// 更新到api交易单上
apiOrderMapper.updateById(new ApiOrderDO().setId(order.getId()).setPayOrderId(payOrderId));
order.setPayOrderId(payOrderId);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateApiOrderPaid(Long id, Long payOrderId) {
// 1.1 校验API订单是否存在
ApiOrderDO order = validateApiOrderExists(id);
// 1.2 校验API订单已支付
if (ApiOrderStatus.PAID.getValue() == order.getStatus()) {
// 特殊:支付单号相同,直接返回,说明重复回调
if (ObjectUtil.equals(order.getPayOrderId(), payOrderId)) {
log.warn("[updateApiOrderPaid][order({}) 已支付,且支付单号相同({}),直接返回]", order, payOrderId);
return;
}
log.error("[updateApiOrderPaid][order({}) 支付单不匹配({}),请进行处理!order 数据是:{}]",
id, payOrderId, JsonUtils.toJsonString(order));
}
// 2. 校验支付订单的合法性
PayOrderRespDTO payOrder = validatePayOrderPaid(order, payOrderId);
// 3. 更新 apiOrderDO 状态为已支付
apiOrderMapper.updateByIdAndStatus(id, order.getStatus(),
new ApiOrderDO().setStatus(ApiOrderStatus.PAID.getValue())
.setPayStatus(ApiOrderPayStatus.SUCCESS.getValue())
.setPayTime(LocalDateTime.now()).setPayChannelCode(payOrder.getChannelCode()));
// 5. 记录订单日志
//TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), TradeOrderStatusEnum.UNDELIVERED.getStatus());
//TradeOrderLogUtils.setUserInfo(order.getUserId(), UserTypeEnum.MEMBER.getValue());
}
/**
* 校验支付订单的合法性
*
* @param order 交易订单
* @param payOrderId 支付订单编号
* @return 支付订单
*/
private PayOrderRespDTO validatePayOrderPaid(ApiOrderDO order, Long payOrderId) {
// 1. 校验支付单是否存在
PayOrderRespDTO payOrder = payOrderApi.getOrder(payOrderId);
if (payOrder == null) {
log.error("[validatePayOrderPaid][order({}) payOrder({}) 不存在,请进行处理!]", order.getId(), payOrderId);
throw exception(API_ORDER_NOT_FOUND);
}
// 2.1 校验支付单已支付
if (!PayOrderStatusEnum.isSuccess(payOrder.getStatus())) {
log.error("[validatePayOrderPaid][order({}) payOrder({}) 未支付,请进行处理!payOrder 数据是:{}]",
order.getId(), payOrderId, JsonUtils.toJsonString(payOrder));
throw exception(API_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS);
}
// 2.2 校验支付金额一致
if (ObjectUtil.notEqual(payOrder.getPrice(), order.getCostPrice())) {
log.error("[validatePayOrderPaid][order({}) payOrder({}) api订单支付金额不匹配,请进行处理!order 数据是:{},payOrder 数据是:{}]",
order.getId(), payOrderId, JsonUtils.toJsonString(order), JsonUtils.toJsonString(payOrder));
throw exception(API_ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH);
}
// 2.2 校验支付订单匹配(二次)
if (ObjectUtil.notEqual(payOrder.getMerchantOrderId(), order.getId().toString())) {
log.error("[validatePayOrderPaid][order({}) api支付单不匹配({}),请进行处理!payOrder 数据是:{}]",
order.getId(), payOrderId, JsonUtils.toJsonString(payOrder));
throw exception(API_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR);
}
return payOrder;
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.service.apipackage;
import java.util.*;
import javax.validation.*;
import com.luhu.computility.module.apihub.controller.admin.apipackage.vo.*;
import com.luhu.computility.module.apihub.dal.dataobject.apipackage.ApiPackageDO;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.common.pojo.PageParam;
/**
* API 套餐 Service 接口
*
* @author ljq
*/
public interface ApiPackageService {
/**
* 创建API 套餐
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createApiPackage(@Valid ApiPackageSaveReqVO createReqVO);
/**
* 更新API 套餐
*
* @param updateReqVO 更新信息
*/
void updateApiPackage(@Valid ApiPackageSaveReqVO updateReqVO);
/**
* 删除API 套餐
*
* @param id 编号
*/
void deleteApiPackage(Long id);
/**
* 删除某个API下的套餐
*
* @param id 编号
*/
Boolean deleteApiPackageByApiId(Long id);
/**
* 批量删除API 套餐
*
* @param ids 编号
*/
void deleteApiPackageListByIds(List<Long> ids);
/**
* 获得API 套餐
*
* @param id 编号
* @return API 套餐
*/
ApiPackageDO getApiPackage(Long id);
/**
* 获得某api下的API 套餐
*
* @param id 编号
* @return API 套餐列表
*/
List<ApiPackageDO> selectByApiId(Long id);
/**
* 获得API 套餐分页
*
* @param pageReqVO 分页查询
* @return API 套餐分页
*/
PageResult<ApiPackageDO> getApiPackagePage(ApiPackagePageReqVO pageReqVO);
}
\ No newline at end of file
package com.luhu.computility.module.apihub.service.apipackage;
import cn.hutool.core.collection.CollUtil;
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.apipackage.vo.*;
import com.luhu.computility.module.apihub.dal.dataobject.apipackage.ApiPackageDO;
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.apipackage.ApiPackageMapper;
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.*;
/**
* API 套餐 Service 实现类
*
* @author ljq
*/
@Service
@Validated
public class ApiPackageServiceImpl implements ApiPackageService {
@Resource
private ApiPackageMapper apiPackageMapper;
@Override
public Long createApiPackage(ApiPackageSaveReqVO createReqVO) {
// 插入
ApiPackageDO apiPackage = BeanUtils.toBean(createReqVO, ApiPackageDO.class);
apiPackageMapper.insert(apiPackage);
// 返回
return apiPackage.getId();
}
@Override
public void updateApiPackage(ApiPackageSaveReqVO updateReqVO) {
// 校验存在
validateApiPackageExists(updateReqVO.getId());
// 更新
ApiPackageDO updateObj = BeanUtils.toBean(updateReqVO, ApiPackageDO.class);
apiPackageMapper.updateById(updateObj);
}
@Override
public void deleteApiPackage(Long id) {
// 校验存在
validateApiPackageExists(id);
// 删除
apiPackageMapper.deleteById(id);
}
@Override
public void deleteApiPackageListByIds(List<Long> ids) {
// 删除
apiPackageMapper.deleteByIds(ids);
}
private void validateApiPackageExists(Long id) {
if (apiPackageMapper.selectById(id) == null) {
throw exception(API_PACKAGE_NOT_EXISTS);
}
}
@Override
public ApiPackageDO getApiPackage(Long id) {
return apiPackageMapper.selectById(id);
}
@Override
public PageResult<ApiPackageDO> getApiPackagePage(ApiPackagePageReqVO pageReqVO) {
return apiPackageMapper.selectPage(pageReqVO);
}
@Override
public Boolean deleteApiPackageByApiId(Long id) {
return apiPackageMapper.deleteApiPackageByApiId(id);
}
@Override
public List<ApiPackageDO> selectByApiId(Long id) {
return apiPackageMapper.selectByApiId(id);
}
}
\ No newline at end of file
package com.luhu.computility.module.apihub.service.appcredential;
import java.util.*;
import javax.validation.*;
import com.luhu.computility.module.apihub.controller.admin.appcredential.vo.*;
import com.luhu.computility.module.apihub.dal.dataobject.appcredential.AppCredentialDO;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.common.pojo.PageParam;
/**
* 用户密钥信息 Service 接口
*
* @author ljq
*/
public interface AppCredentialService {
/**
* 创建用户密钥信息
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createAppCredential(@Valid AppCredentialSaveReqVO createReqVO);
/**
* 更新用户密钥信息
*
* @param updateReqVO 更新信息
*/
void updateAppCredential(@Valid AppCredentialSaveReqVO updateReqVO);
/**
* 删除用户密钥信息
*
* @param id 编号
*/
void deleteAppCredential(Long id);
/**
* 批量删除用户密钥信息
*
* @param ids 编号
*/
void deleteAppCredentialListByIds(List<Long> ids);
/**
* 获得用户密钥信息
*
* @param id 编号
* @return 用户密钥信息
*/
AppCredentialDO getAppCredential(Long id);
/**
* 获得用户密钥信息分页
*
* @param pageReqVO 分页查询
* @return 用户密钥信息分页
*/
PageResult<AppCredentialDO> getAppCredentialPage(AppCredentialPageReqVO pageReqVO);
}
\ No newline at end of file
package com.luhu.computility.module.apihub.service.appcredential;
import cn.hutool.core.collection.CollUtil;
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.appcredential.vo.*;
import com.luhu.computility.module.apihub.dal.dataobject.appcredential.AppCredentialDO;
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.appcredential.AppCredentialMapper;
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 AppCredentialServiceImpl implements AppCredentialService {
@Resource
private AppCredentialMapper appCredentialMapper;
@Override
public Long createAppCredential(AppCredentialSaveReqVO createReqVO) {
// 插入
AppCredentialDO appCredential = BeanUtils.toBean(createReqVO, AppCredentialDO.class);
appCredentialMapper.insert(appCredential);
// 返回
return appCredential.getId();
}
@Override
public void updateAppCredential(AppCredentialSaveReqVO updateReqVO) {
// 校验存在
validateAppCredentialExists(updateReqVO.getId());
// 更新
AppCredentialDO updateObj = BeanUtils.toBean(updateReqVO, AppCredentialDO.class);
appCredentialMapper.updateById(updateObj);
}
@Override
public void deleteAppCredential(Long id) {
// 校验存在
validateAppCredentialExists(id);
// 删除
appCredentialMapper.deleteById(id);
}
@Override
public void deleteAppCredentialListByIds(List<Long> ids) {
// 删除
appCredentialMapper.deleteByIds(ids);
}
private void validateAppCredentialExists(Long id) {
if (appCredentialMapper.selectById(id) == null) {
throw exception(APP_CREDENTIAL_NOT_EXISTS);
}
}
@Override
public AppCredentialDO getAppCredential(Long id) {
return appCredentialMapper.selectById(id);
}
@Override
public PageResult<AppCredentialDO> getAppCredentialPage(AppCredentialPageReqVO pageReqVO) {
return appCredentialMapper.selectPage(pageReqVO);
}
}
\ No newline at end of file
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.dal.dataobject.userapiusage.UserApiUsageDO;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.common.pojo.PageParam;
/**
* 用户 API 使用统计 Service 接口
*
* @author ljq
*/
public interface UserApiUsageService {
/**
* 创建用户 API 使用统计
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createUserApiUsage(@Valid UserApiUsageSaveReqVO createReqVO);
/**
* 更新用户 API 使用统计
*
* @param updateReqVO 更新信息
*/
void updateUserApiUsage(@Valid UserApiUsageSaveReqVO updateReqVO);
/**
* 删除用户 API 使用统计
*
* @param id 编号
*/
void deleteUserApiUsage(Long id);
/**
* 批量删除用户 API 使用统计
*
* @param ids 编号
*/
void deleteUserApiUsageListByIds(List<Long> ids);
/**
* 获得用户 API 使用统计
*
* @param id 编号
* @return 用户 API 使用统计
*/
UserApiUsageDO getUserApiUsage(Long id);
/**
* 获得用户 API 使用统计分页
*
* @param pageReqVO 分页查询
* @return 用户 API 使用统计分页
*/
PageResult<UserApiUsageRespVO> getUserApiUsagePage(UserApiUsagePageReqVO pageReqVO);
}
\ No newline at end of file
package com.luhu.computility.module.apihub.service.userapiusage;
import cn.hutool.core.collection.CollUtil;
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.userapiusage.vo.*;
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;
import com.luhu.computility.framework.common.util.object.BeanUtils;
import com.luhu.computility.module.apihub.dal.mysql.userapiusage.UserApiUsageMapper;
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.*;
/**
* 用户 API 使用统计 Service 实现类
*
* @author ljq
*/
@Service
@Validated
public class UserApiUsageServiceImpl implements UserApiUsageService {
@Resource
private UserApiUsageMapper userApiUsageMapper;
@Override
public Long createUserApiUsage(UserApiUsageSaveReqVO createReqVO) {
// 插入
UserApiUsageDO userApiUsage = BeanUtils.toBean(createReqVO, UserApiUsageDO.class);
userApiUsageMapper.insert(userApiUsage);
// 返回
return userApiUsage.getId();
}
@Override
public void updateUserApiUsage(UserApiUsageSaveReqVO updateReqVO) {
// 校验存在
validateUserApiUsageExists(updateReqVO.getId());
// 更新
UserApiUsageDO updateObj = BeanUtils.toBean(updateReqVO, UserApiUsageDO.class);
userApiUsageMapper.updateById(updateObj);
}
@Override
public void deleteUserApiUsage(Long id) {
// 校验存在
validateUserApiUsageExists(id);
// 删除
userApiUsageMapper.deleteById(id);
}
@Override
public void deleteUserApiUsageListByIds(List<Long> ids) {
// 删除
userApiUsageMapper.deleteByIds(ids);
}
private void validateUserApiUsageExists(Long id) {
if (userApiUsageMapper.selectById(id) == null) {
throw exception(USER_API_USAGE_NOT_EXISTS);
}
}
@Override
public UserApiUsageDO getUserApiUsage(Long id) {
return userApiUsageMapper.selectById(id);
}
@Override
public PageResult<UserApiUsageRespVO> getUserApiUsagePage(UserApiUsagePageReqVO pageReqVO) {
return userApiUsageMapper.selectPage(pageReqVO);
}
}
\ No newline at end of file
package com.luhu.computility.module.biz.controller.app.index;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.math.Money;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.luhu.computility.framework.apilog.core.annotation.ApiAccessLog;
import com.luhu.computility.framework.common.exception.ServiceException;
import com.luhu.computility.framework.common.pojo.CommonResult;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.common.util.object.BeanUtils;
import com.luhu.computility.module.biz.controller.admin.bannerinfo.vo.BannerInfoPageReqVO;
import com.luhu.computility.module.biz.controller.admin.bannerinfo.vo.BannerInfoRespVO;
import com.luhu.computility.module.biz.controller.admin.computilityinformation.vo.ComputilityInformationRespVO;
import com.luhu.computility.module.biz.controller.admin.solution.vo.SolutionMenuRespVO;
import com.luhu.computility.module.biz.controller.admin.solution.vo.SolutionPageReqVO;
import com.luhu.computility.module.biz.controller.app.index.vo.BizOrderCreateReqVO;
import com.luhu.computility.module.biz.controller.app.index.vo.ResourcesDetailRespVO;
import com.luhu.computility.module.biz.controller.client.dto.MenuDTO;
import com.luhu.computility.module.biz.dal.dataobject.bannerinfo.BannerInfoDO;
import com.luhu.computility.module.biz.dal.dataobject.solution.SolutionDO;
import com.luhu.computility.module.biz.dal.mysql.solution.SolutionMapper;
import com.luhu.computility.module.biz.service.bannerinfo.BannerInfoService;
import com.luhu.computility.module.biz.service.order.OrderService;
import com.luhu.computility.module.biz.service.resources.ResourcesDetailService;
import com.luhu.computility.module.biz.service.solution.SolutionService;
import com.luhu.computility.module.product.dal.dataobject.category.ProductCategoryDO;
import com.luhu.computility.module.product.dal.dataobject.sku.ProductSkuDO;
import com.luhu.computility.module.product.dal.dataobject.spu.ProductSpuDO;
import com.luhu.computility.module.product.enums.spu.ProductSpuStatusEnum;
import com.luhu.computility.module.product.service.category.ProductCategoryService;
import com.luhu.computility.module.product.service.sku.ProductSkuService;
import com.luhu.computility.module.product.service.spu.ProductSpuService;
import com.luhu.computility.module.system.dal.dataobject.dict.DictDataDO;
import com.luhu.computility.module.system.util.dict.DictUtils;
import io.netty.util.internal.ObjectUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.java.Log;
import org.apache.ibatis.annotations.Param;
import org.checkerframework.checker.units.qual.C;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.stereotype.Controller;
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.PathVariable;
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.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static com.luhu.computility.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.luhu.computility.framework.common.pojo.CommonResult.error;
import static com.luhu.computility.framework.common.pojo.CommonResult.success;
import static com.luhu.computility.module.biz.enums.ErrorCodeConstants.GET_SOLUTION_ERROR;
import static com.luhu.computility.module.product.enums.ErrorCodeConstants.SPU_NOT_ENABLE;
import static com.luhu.computility.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
/**
......@@ -81,7 +46,7 @@ import static com.luhu.computility.module.product.enums.ErrorCodeConstants.SPU_N
@RestController
@RequestMapping("/api/v1")
@Validated
public class ApiController {
public class ApiControllerUnuse {
@Resource
private ProductSpuService productSpuService;
@Resource
......
<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/maven-v4_0_0.xsd">
<parent>
<artifactId>computility</artifactId>
<groupId>com.luhu</groupId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>computility-module-external</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<dependencies>
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-common</artifactId>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-spring-boot-starter-protection</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>
<!-- 工具类相关 -->
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-spring-boot-starter-excel</artifactId>
</dependency>
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-spring-boot-starter-biz-tenant</artifactId>
</dependency>
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-module-infra</artifactId>
<version>${revision}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-module-system</artifactId>
<version>${revision}</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
package com.luhu.computility.module.external;
/**
* @version 1.0
* @Author ljq
* @Date 2025/4/16
* @注释
*/
public interface AppCredentialsApi {
/**
* 根据appId获得外部应用鉴权信息
*
* @param appId 编号
* @return 外部应用鉴权信息
*/
String getAppSecretByAppid(String appId);
}
package com.luhu.computility.module.external;
import com.luhu.computility.framework.common.exception.ErrorCode;
public interface ExternalResponseCode {
ErrorCode SUCCESS = new ErrorCode(200, "成功");
// ========== 客户端错误段 ==========
ErrorCode BAD_REQUEST = new ErrorCode(400, "请求参数不正确");
ErrorCode UNAUTHORIZED = new ErrorCode(401, "账号未登录");
ErrorCode FORBIDDEN = new ErrorCode(403, "没有该操作权限");
ErrorCode NOT_FOUND = new ErrorCode(404, "请求未找到");
ErrorCode METHOD_NOT_ALLOWED = new ErrorCode(405, "请求方法不正确");
ErrorCode LOCKED = new ErrorCode(423, "请求失败,请稍后重试"); // 并发请求,不允许
ErrorCode TOO_MANY_REQUESTS = new ErrorCode(429, "请求过于频繁,请稍后重试");
// ========== 服务端错误段 ==========
ErrorCode INTERNAL_SERVER_ERROR = new ErrorCode(500, "");
ErrorCode NOT_IMPLEMENTED = new ErrorCode(501, "功能未实现/未开启");
ErrorCode ERROR_CONFIGURATION = new ErrorCode(502, "错误的配置项");
// ========== 自定义错误段 ==========
ErrorCode REPEATED_REQUESTS = new ErrorCode(900, "重复请求,请稍后重试"); // 重复请求
ErrorCode DEMO_DENY = new ErrorCode(901, "演示模式,禁止写操作");
ErrorCode UNKNOWN = new ErrorCode(999, "未知错误");
ErrorCode ERROR_IMAGE = new ErrorCode(1000, "没有接收到合适的图片文件,请确认上传的是jpg、png、jpeg格式的图片文");
}
package com.luhu.computility.module.external.api;
/**
* 转发AI相关 API 接口
*
* @author ljq
*/
public interface AiServiceApi {
String imageComparison(String Url);
}
package com.luhu.computility.module.external.api;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
/**
* AiService API 实现类
*
* @author ljq
*/
@Service
@Validated
public class AiServiceApiImpl implements AiServiceApi {
@Override
public String imageComparison(String Url) {
return null;
}
}
package com.luhu.computility.module.external.controller.admin.appcredentials;
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.module.external.controller.admin.appcredentials.vo.AppCredentialsPageReqVO;
import com.luhu.computility.module.external.controller.admin.appcredentials.vo.AppCredentialsRespVO;
import com.luhu.computility.module.external.controller.admin.appcredentials.vo.AppCredentialsSaveReqVO;
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.module.external.dal.dataobject.appcredentials.AppCredentialsDO;
import com.luhu.computility.module.external.service.appcredentials.AppCredentialsService;
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("/external/app-credentials")
@Validated
public class AppCredentialsController {
@Resource
private AppCredentialsService appCredentialsService;
@PostMapping("/create")
@Operation(summary = "创建外部应用鉴权信息")
@PreAuthorize("@ss.hasPermission('external:app-credentials:create')")
public CommonResult<Long> createAppCredentials(@Valid @RequestBody AppCredentialsSaveReqVO createReqVO) {
return success(appCredentialsService.createAppCredentials(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新外部应用鉴权信息")
@PreAuthorize("@ss.hasPermission('external:app-credentials:update')")
public CommonResult<Boolean> updateAppCredentials(@Valid @RequestBody AppCredentialsSaveReqVO updateReqVO) {
appCredentialsService.updateAppCredentials(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除外部应用鉴权信息")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('external:app-credentials:delete')")
public CommonResult<Boolean> deleteAppCredentials(@RequestParam("id") Long id) {
appCredentialsService.deleteAppCredentials(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得外部应用鉴权信息")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('external:app-credentials:query')")
public CommonResult<AppCredentialsRespVO> getAppCredentials(@RequestParam("id") Long id) {
AppCredentialsDO appCredentials = appCredentialsService.getAppCredentials(id);
return success(BeanUtils.toBean(appCredentials, AppCredentialsRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得外部应用鉴权信息分页")
@PreAuthorize("@ss.hasPermission('external:app-credentials:query')")
public CommonResult<PageResult<AppCredentialsRespVO>> getAppCredentialsPage(@Valid AppCredentialsPageReqVO pageReqVO) {
PageResult<AppCredentialsDO> pageResult = appCredentialsService.getAppCredentialsPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, AppCredentialsRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出外部应用鉴权信息 Excel")
@PreAuthorize("@ss.hasPermission('external:app-credentials:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportAppCredentialsExcel(@Valid AppCredentialsPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<AppCredentialsDO> list = appCredentialsService.getAppCredentialsPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "外部应用鉴权信息.xls", "数据", AppCredentialsRespVO.class,
BeanUtils.toBean(list, AppCredentialsRespVO.class));
}
}
\ No newline at end of file
package com.luhu.computility.module.external.controller.admin.appcredentials.vo;
import com.luhu.computility.framework.common.pojo.PageParam;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
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
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class AppCredentialsPageReqVO extends PageParam {
@Schema(description = "应用名", example = "王五")
private String appName;
@Schema(description = "应用id", example = "6835")
private String appId;
@Schema(description = "应用密钥")
private String appSecret;
@Schema(description = "备注", example = "你说的对")
private String remark;
@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.external.controller.admin.appcredentials.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 AppCredentialsRespVO {
@Schema(description = "参数主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "26230")
@ExcelProperty("参数主键")
private Long id;
@Schema(description = "应用名", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
@ExcelProperty("应用名")
private String appName;
@Schema(description = "应用id", requiredMode = Schema.RequiredMode.REQUIRED, example = "6835")
@ExcelProperty("应用id")
private String appId;
@Schema(description = "应用密钥", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("应用密钥")
private String appSecret;
@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.external.controller.admin.appcredentials.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 AppCredentialsSaveReqVO {
@Schema(description = "参数主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "26230")
private Long id;
@Schema(description = "应用名", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
@NotEmpty(message = "应用名不能为空")
private String appName;
@Schema(description = "应用id", requiredMode = Schema.RequiredMode.REQUIRED, example = "6835")
@NotEmpty(message = "应用id不能为空")
private String appId;
@Schema(description = "应用密钥", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "应用密钥不能为空")
private String appSecret;
@Schema(description = "备注", example = "你说的对")
private String remark;
}
\ No newline at end of file
package com.luhu.computility.module.external.controller.admin.file;
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.module.external.controller.admin.file.vo.AiGeneratedFilePageReqVO;
import com.luhu.computility.module.external.controller.admin.file.vo.AiGeneratedFileRespVO;
import com.luhu.computility.module.external.controller.admin.file.vo.AiGeneratedFileSaveReqVO;
import com.luhu.computility.module.external.dal.dataobject.file.AiGeneratedFileDO;
import com.luhu.computility.module.external.service.file.AiGeneratedFileService;
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 = "管理后台 - ai换脸-生成文件")
@RestController
@RequestMapping("/external/ai-generated-file")
@Validated
public class AiGeneratedFileController {
@Resource
private AiGeneratedFileService aiGeneratedFileService;
@PostMapping("/create")
@Operation(summary = "创建ai换脸-生成文件")
@PreAuthorize("@ss.hasPermission('external:ai-generated-file:create')")
public CommonResult<Integer> createAiGeneratedFile(@Valid @RequestBody AiGeneratedFileSaveReqVO createReqVO) {
return success(aiGeneratedFileService.createAiGeneratedFile(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新ai换脸-生成文件")
@PreAuthorize("@ss.hasPermission('external:ai-generated-file:update')")
public CommonResult<Boolean> updateAiGeneratedFile(@Valid @RequestBody AiGeneratedFileSaveReqVO updateReqVO) {
aiGeneratedFileService.updateAiGeneratedFile(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除ai换脸-生成文件")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('external:ai-generated-file:delete')")
public CommonResult<Boolean> deleteAiGeneratedFile(@RequestParam("id") Integer id) {
aiGeneratedFileService.deleteAiGeneratedFile(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得ai换脸-生成文件")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('external:ai-generated-file:query')")
public CommonResult<AiGeneratedFileRespVO> getAiGeneratedFile(@RequestParam("id") Integer id) {
AiGeneratedFileDO aiGeneratedFile = aiGeneratedFileService.getAiGeneratedFile(id);
return success(BeanUtils.toBean(aiGeneratedFile, AiGeneratedFileRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得ai换脸-生成文件分页")
@PreAuthorize("@ss.hasPermission('external:ai-generated-file:query')")
public CommonResult<PageResult<AiGeneratedFileRespVO>> getAiGeneratedFilePage(@Valid AiGeneratedFilePageReqVO pageReqVO) {
PageResult<AiGeneratedFileDO> pageResult = aiGeneratedFileService.getAiGeneratedFilePage(pageReqVO);
return success(BeanUtils.toBean(pageResult, AiGeneratedFileRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出ai换脸-生成文件 Excel")
@PreAuthorize("@ss.hasPermission('external:ai-generated-file:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportAiGeneratedFileExcel(@Valid AiGeneratedFilePageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<AiGeneratedFileDO> list = aiGeneratedFileService.getAiGeneratedFilePage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "ai换脸-生成文件.xls", "数据", AiGeneratedFileRespVO.class,
BeanUtils.toBean(list, AiGeneratedFileRespVO.class));
}
}
\ No newline at end of file
package com.luhu.computility.module.external.controller.admin.file.vo;
import com.luhu.computility.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
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 = "管理后台 - ai换脸-生成文件分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class AiGeneratedFilePageReqVO extends PageParam {
@Schema(description = "任务id", example = "21088")
private String promptId;
@Schema(description = "文件类型 1.图片 2.视频", example = "2")
private Integer type;
@Schema(description = "文件生成状态 1.未开始 2.上传中 3.已上传 ", example = "2")
private Integer status;
@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.external.controller.admin.file.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.luhu.computility.framework.excel.core.annotations.DictFormat;
import com.luhu.computility.framework.excel.core.convert.DictConvert;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - ai换脸-生成文件 Response VO")
@Data
@ExcelIgnoreUnannotated
public class AiGeneratedFileRespVO {
@Schema(description = "自增主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "28105")
@ExcelProperty("自增主键")
private Integer id;
@Schema(description = "任务id", requiredMode = Schema.RequiredMode.REQUIRED, example = "21088")
@ExcelProperty("任务id")
private String promptId;
@Schema(description = "文件类型 1.图片 2.视频", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@ExcelProperty(value = "文件类型 1.图片 2.视频", converter = DictConvert.class)
@DictFormat("ai_generated_file") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
private Integer type;
@Schema(description = "文件生成状态 1.未开始 2.上传中 3.已上传 ", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@ExcelProperty(value = "文件生成状态 1.未开始 2.上传中 3.已上传 ", converter = DictConvert.class)
@DictFormat("ai_generated_file_status") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
private Integer status;
@Schema(description = "oss存储地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn")
@ExcelProperty("oss存储地址")
private String url;
@Schema(description = "原始地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn")
@ExcelProperty("原始地址")
private String originalUrl;
@Schema(description = "缩略图/首帧地址")
@ExcelProperty("缩略图/首帧地址")
private String coverImage;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}
\ No newline at end of file
package com.luhu.computility.module.external.controller.admin.file.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - ai换脸-生成文件新增/修改 Request VO")
@Data
public class AiGeneratedFileSaveReqVO {
@Schema(description = "自增主键", example = "28105")
private Integer id;
@Schema(description = "任务id", requiredMode = Schema.RequiredMode.REQUIRED, example = "21088")
private String promptId;
@Schema(description = "文件类型 1.图片 2.视频", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
private Integer type;
@Schema(description = "文件生成状态 1.未开始 2.上传中 3.已上传 ", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
private Integer status;
@Schema(description = "oss存储地址", example = "https://www.iocoder.cn")
private String url;
@Schema(description = "原始地址", example = "https://www.iocoder.cn")
private String originalUrl;
@Schema(description = "缩略图/首帧地址")
private String coverImage;
}
\ No newline at end of file
package com.luhu.computility.module.external.controller.enums;
/**
* @version 1.0
* @Author ljq
* @Date 2025/6/17
* @注释
*/
public enum AiGeneratedFileStatus {
// 文件生成状态 1.未开始 2.上传中 3.已上传
UNSTART(1, "未开始"),
UPLOADING(2, "上传中"),
FINISHED(3, "已上传"),
FAILED(4, "上传失败");
private int value;
private String remark;
private AiGeneratedFileStatus(int value, String remark) {
this.value = value;
this.remark = remark;
}
public int getValue() {
return value;
}
public String getRemark() {
return remark;
}
public static AiGeneratedFileStatus getByValue(int value) {
for (AiGeneratedFileStatus o : AiGeneratedFileStatus.values()) {
if (o.getValue() == value) {
return o;
}
}
return null;
}
}
package com.luhu.computility.module.external.controller.enums;
/**
* @version 1.0
* @Author ljq
* @Date 2025/6/17
* @注释
*/
public enum AiGeneratedFileType {
// 文件类型 1.图片 2.视频
IMAGE(1, "图片"),
VIDEO(2, "视频");
private int value;
private String remark;
private AiGeneratedFileType(int value, String remark) {
this.value = value;
this.remark = remark;
}
public int getValue() {
return value;
}
public String getRemark() {
return remark;
}
public static AiGeneratedFileType getByValue(int value) {
for (AiGeneratedFileType o : AiGeneratedFileType.values()) {
if (o.getValue() == value) {
return o;
}
}
return null;
}
}
package com.luhu.computility.module.external.controller.enums;
import com.luhu.computility.framework.common.exception.ErrorCode;
/**
* External 错误码枚举类
*
* product 系统,使用 1_009_111_000 段
*/
public interface ErrorCodeConstants {
ErrorCode APPID_ERROR_NOT_EXISTS = new ErrorCode(1_009_111_001, "appid错误或不存在");
ErrorCode CATEGORY_PARENT_NOT_EXISTS = new ErrorCode(1_009_111_002, "父分类不存在");
ErrorCode AI_GENERATED_FILE_NOT_EXISTS = new ErrorCode(1_009_111_003, "ai换脸-生成文件不存在");
}
package com.luhu.computility.module.external.controller.openapi;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.luhu.computility.framework.apilog.core.annotation.ApiAccessLog;
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.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;
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;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import static com.luhu.computility.framework.common.pojo.CommonResult.error;
import static com.luhu.computility.framework.common.pojo.CommonResult.success;
/**
* @version 1.0
* @Author ljq
* @Date 2025/4/28
* @注释
*/
@Tag(name = "调取新aigc接口")
@RestController
@RequestMapping("/external/v2")
public class AigcNewApiController {
@Value("${new-aigc.text-to-image-v2}")
private String textToImageV2;
@Value("${new-aigc.poetry-v2}")
private String textToImageByPoetryV2;
@ApiAccessLog
@PostMapping(value = "/text-to-image/season")
@Operation(summary = "四季和景点id生成图", description = "接收简单生图参数,将生成图片保存在本地服务器,并返回生成图片的url")
//@ApiSignature
public CommonResult<ImageRespDTO> textToImageV2(@RequestBody TextToImageReqDTO textToImageReqDTO){
try {
String requestBody = JSONUtil.toJsonStr(textToImageReqDTO);
String result = HttpUtils.post(textToImageV2, null, requestBody);
return textToImageBySeasonResponseResult(result);
}catch (Exception e){
Integer errorCode = GlobalResponseCodeConstants.INTERNAL_SERVER_ERROR.getCode();
String errorMsg = GlobalResponseCodeConstants.INTERNAL_SERVER_ERROR.getMsg();
if (e instanceof ServiceException) {
ServiceException serviceException = (ServiceException) e;
errorCode = serviceException.getCode();
errorMsg = serviceException.getMessage();
}
return error(errorCode, errorMsg);
}
}
@ApiAccessLog
@PostMapping("/text-to-image/poetry")
@Operation(summary = "获取藏头诗图片", description = "接收关键词、景点id、省份id这些参数,返回藏头诗图片url")
//@ApiSignature
public CommonResult<ImageRespDTO> textToImageByPoetry(@RequestBody PoetryImageReqDTO poetryImageReqDTO){
try {
String requestBody = JSONUtil.toJsonStr(poetryImageReqDTO);
String result = HttpUtils.post(textToImageByPoetryV2, null, requestBody);
return textToImageBySeasonResponseResult(result);
}catch (Exception e) {
Integer errorCode = GlobalResponseCodeConstants.INTERNAL_SERVER_ERROR.getCode();
String errorMsg = GlobalResponseCodeConstants.INTERNAL_SERVER_ERROR.getMsg();
return error(errorCode, errorMsg);
}
}
public CommonResult<ImageRespDTO> textToImageBySeasonResponseResult(String result) {
JSONObject resultJson = JSONUtil.parseObj(result);
Integer responseCode = (Integer) resultJson.get("code");
if (responseCode.equals(GlobalResponseCodeConstants.EXTERNAL_SUCCESS.getCode())) {
ImageRespDTO textToImageRespDTO = JSONUtil.toBean((JSONObject) resultJson.get("result"), ImageRespDTO.class);
return success(textToImageRespDTO);
} else {
return error((Integer) resultJson.get("code"), (String)resultJson.get("message"));
}
}
public <T> CommonResult<T> handleJsonObjectResult(String result, Class<T> clazz) {
JSONObject resultJson = JSONUtil.parseObj(result);
Integer responseCode = (Integer) resultJson.get("code");
if (responseCode.equals(GlobalResponseCodeConstants.EXTERNAL_SUCCESS.getCode())) {
T data = JSONUtil.toBean((JSONObject) resultJson.get("data"), clazz);
return success(data);
} else {
return error((Integer) resultJson.get("code"), (String) resultJson.get("message"));
}
}
}
package com.luhu.computility.module.external.controller.openapi;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.luhu.computility.framework.apilog.core.annotation.ApiAccessLog;
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.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;
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;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import static com.luhu.computility.framework.common.pojo.CommonResult.error;
import static com.luhu.computility.framework.common.pojo.CommonResult.success;
/**
* @version 1.0
* @Author ljq
* @Date 2025/4/28
* @注释
*/
@Tag(name = "调取前aigc接口")
@RestController
@RequestMapping("/external/v1")
public class AigcOldApiController {
@Value("${text-to-image.season}")
private String textToImageBySeason;
@Value("${text-to-image.file-name}")
private String textToImageByFileName;
@Value("${text-to-image.poetry}")
private String textToImageByPoetry;
@ApiAccessLog
@PostMapping(value = "/text-to-image/season")
@Operation(summary = "四季和景点id生成图", description = "接收简单生图参数,将生成图片保存在本地服务器,并返回生成图片的url")
//@ApiSignature
public CommonResult<ImageRespDTO> textToImageBySeason(@RequestBody TextToImageReqDTO textToImageReqDTO){
try {
String requestBody = JSONUtil.toJsonStr(textToImageReqDTO);
String result = HttpUtils.post(textToImageBySeason, null, requestBody);
return textToImageBySeasonResponseResult(result);
}catch (Exception e){
Integer errorCode = GlobalResponseCodeConstants.INTERNAL_SERVER_ERROR.getCode();
String errorMsg = GlobalResponseCodeConstants.INTERNAL_SERVER_ERROR.getMsg();
if (e instanceof ServiceException) {
ServiceException serviceException = (ServiceException) e;
errorCode = serviceException.getCode();
errorMsg = serviceException.getMessage();
}
return error(errorCode, errorMsg);
}
}
@ApiAccessLog
@PostMapping("/text-to-image/poetry")
@Operation(summary = "获取藏头诗图片", description = "接收关键词、景点id、省份id这些参数,返回藏头诗图片url")
//@ApiSignature
public CommonResult<ImageRespDTO> textToImageByPoetry(@RequestBody PoetryImageReqDTO poetryImageReqDTO){
try {
String requestBody = JSONUtil.toJsonStr(poetryImageReqDTO);
String result = HttpUtils.post(textToImageByPoetry, null, requestBody);
return textToImageBySeasonResponseResult(result);
}catch (Exception e) {
Integer errorCode = GlobalResponseCodeConstants.INTERNAL_SERVER_ERROR.getCode();
String errorMsg = GlobalResponseCodeConstants.INTERNAL_SERVER_ERROR.getMsg();
return error(errorCode, errorMsg);
}
}
public CommonResult<ImageRespDTO> textToImageBySeasonResponseResult(String result) {
JSONObject resultJson = JSONUtil.parseObj(result);
Integer responseCode = (Integer) resultJson.get("code");
if (responseCode.equals(GlobalResponseCodeConstants.EXTERNAL_SUCCESS.getCode())) {
ImageRespDTO textToImageRespDTO = JSONUtil.toBean((JSONObject) resultJson.get("result"), ImageRespDTO.class);
return success(textToImageRespDTO);
} else {
return error((Integer) resultJson.get("code"), (String)resultJson.get("message"));
}
}
public <T> CommonResult<T> handleJsonObjectResult(String result, Class<T> clazz) {
JSONObject resultJson = JSONUtil.parseObj(result);
Integer responseCode = (Integer) resultJson.get("code");
if (responseCode.equals(GlobalResponseCodeConstants.EXTERNAL_SUCCESS.getCode())) {
T data = JSONUtil.toBean((JSONObject) resultJson.get("data"), clazz);
return success(data);
} else {
return error((Integer) resultJson.get("code"), (String) resultJson.get("message"));
}
}
}
package com.luhu.computility.module.external.controller.openapi;
import com.luhu.computility.framework.apilog.core.annotation.ApiAccessLog;
import com.luhu.computility.framework.common.pojo.CommonResult;
import com.luhu.computility.framework.signature.core.annotation.ApiSignature;
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 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;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
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.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import java.util.List;
/**
* @version 1.0
* @Author ljq
* @Date 2025/4/12
* @注释
*/
@Tag(name = "调取ai模型接口")
@RestController
@RequestMapping("/external/v1")
public class OpenApiController {
@Autowired
private OpenApiService openApiService;
@ApiAccessLog
@PostMapping(value = "/digital-human-conversation")
@Operation(summary = "数字人对话", description = "和数字人朱熹进行一问一答的对话")
@ApiSignature
public CommonResult<ConversationRespDTO> digitalHumanConversation(@RequestBody ConversationReqDTO conversationReqDTO){
return openApiService.digitalHumanConversation(conversationReqDTO);
}
@ApiAccessLog
@PostMapping(value = "/upload-face-image", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@Parameters({
@Parameter(name = "image", description = "图片文件"),
@Parameter(name = "url", description = "图片链接")
})
@Operation(summary = "ai换脸-上传图片", description = "用户上传头像将视频中人物头像替换")
//@ApiSignature
public CommonResult<UploadImageRespDTO> uploadFaceSwapImage(@RequestPart(value = "image", required = false) MultipartFile image,
@RequestParam(value = "url", required = false) String url) {
return openApiService.uploadFaceSwapImage(image, url);
}
@ApiAccessLog
@GetMapping("/create-video-stream")
@Operation(summary = "ai换脸-生成换脸工作流", description = "只有先上传图片才能开始换脸工作流,用户根据promptId取最后生成的视频")
//@ApiSignature
public CommonResult<CeateVideoStreamRespDTO> ceateVideoStream(@RequestBody CeateVideoStreamReqDTO ceateVideoStreamReqDTO){
return openApiService.ceateVideoStream(ceateVideoStreamReqDTO);
}
@ApiAccessLog
@PostMapping(value = "/generate-face-swap-image", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@Operation(summary = "ai换脸-图片换脸:上传图+图片生成", description = "ai换脸-图片换脸:上传图片+图片生成")
//@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,
@RequestParam(value = "targetImageUrl", required = false) String targetImageUrl) {
return openApiService.faceImageGenerate(sourceImage, sourceImageUrl, targetImage, targetImageUrl);
}
@ApiAccessLog
@GetMapping("/view-image")
@Operation(summary = "根据promptId取换脸后的图", description = "根据promptId取换脸后的图")
//@ApiSignature
public CommonResult<ViewSourceRespDTO> viewImage(@RequestBody ViewImageReqDTO viewImageReqDTO){
return openApiService.viewImage(viewImageReqDTO);
}
@ApiAccessLog
@PostMapping(value = "/generate-face-swap-video", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@Parameters({
@Parameter(name = "image", description = "图片文件"),
@Parameter(name = "url", description = "图片链接")
})
@Operation(summary = "ai换脸-视频换脸;ai换脸-上传图片+视频流生成", description = "ai换脸-上传图片+视频流生成")
//@ApiSignature
public CommonResult<GenerateFaceSwapRespDTO> faceVideoGenerate(@RequestPart(value = "image", required = false) MultipartFile image,
@RequestParam(value = "url", required = false) String url) {
return openApiService.faceVideoGenerate(image, url);
}
@ApiAccessLog
@GetMapping("/view-video")
@Operation(summary = "根据promptId取最后生成的视频", description = "根据promptId取最后生成的视频")
//@ApiSignature
public CommonResult<ViewSourceRespDTO> viewVideo(@RequestBody ViewVideoReqDTO viewVideoReqDTO){
return openApiService.viewVideo(viewVideoReqDTO);
}
@ApiAccessLog
@PostMapping(value = "/match-image")
@Parameters({
@Parameter(name = "image", description = "图片文件"),
@Parameter(name = "url", description = "图片地址"),
@Parameter(name = "limit", description = "返回图片数量(Integer)"),
@Parameter(name = "cityId", description = "城市编码"),
@Parameter(name = "touristAreaId", description = "景点编码")
})
@Operation(summary = "图片拍照-相似图查找", description = "图片拍照-相似图查找")
//@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
, @RequestParam(value = "cityId", required = false) String cityId
, @RequestParam(value = "touristAreaId", required = false) String touristAreaId){
return openApiService.matchImage(image, url, limit, cityId, touristAreaId);
}
@ApiAccessLog
@PostMapping("/AIQA-chat")
@Operation(summary = "AI问答", description = "AI助手,关于行程和景区的疑问")
//@ApiSignature
public CommonResult<AIQARespDTO> AIQAChat(@RequestBody AIQAReqDTO aiqaReqDTO){
return openApiService.AIQAChat(aiqaReqDTO);
}
@ApiAccessLog
@PostMapping(value = "/AIQA-stream-chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
@Operation(summary = "AI问答流式返回", description = "流式返回AI助手,关于行程和景区的疑问")
public SseEmitter AIQAStreamChat(@RequestBody AIQAReqDTO aiqaReqDTO) {
return openApiService.AIQAStreamChat(aiqaReqDTO);
}
@ApiAccessLog
@PostMapping(value = "/aliyun-stream-chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
@Operation(summary = "AI问答流式返回", description = "流式返回AI助手,关于行程和景区的疑问")
public SseEmitter aliyunStreamChat(@RequestBody AIQAReqDTO aiqaReqDTO) {
return openApiService.aliyunStreamChat(aiqaReqDTO);
}
}
package com.luhu.computility.module.external.controller.openapi.dto;
import lombok.Data;
import java.util.List;
@Data
public class AIQAReqDTO {
// 用户提的问题
private String text;
//历史消息
private List<MessageDTO> message;
//知识库id
private List<String> pipelineIds;
//查询时所用的标签
private List<String> tags;
//查询时使用的文档ID。传入文档ID时,还需要传入文档所属的知识库ID才会生效
private List<String> fileIds;
}
\ No newline at end of file
package com.luhu.computility.module.external.controller.openapi.dto;
import lombok.Data;
@Data
public class AIQARespDTO {
//请求唯一标识
private String requestId;
// 回答的问题
private String text;
//输入消耗token数
private String inputTokens;
//输出消耗token数
private String outputTokens;
//历史对话记录(包含最新对话)
private String messages;
}
\ No newline at end of file
package com.luhu.computility.module.external.controller.openapi.dto;
import lombok.Data;
@Data
public class AIQAStreamRespDTO {
//内容
private String content;
//事件名称
private String eventName;
private MetadataDTO metadata;
}
\ No newline at end of file
package com.luhu.computility.module.external.controller.openapi.dto;
import lombok.Data;
@Data
public class CeateVideoStreamReqDTO {
//文件名
private String fileName;
}
\ No newline at end of file
package com.luhu.computility.module.external.controller.openapi.dto;
import lombok.Data;
@Data
public class CeateVideoStreamRespDTO {
//请求唯一标识
private String clientId;
//生成视频的唯一标识
private String promptId;
}
\ No newline at end of file
package com.luhu.computility.module.external.controller.openapi.dto;
import lombok.Data;
@Data
public class ConversationReqDTO {
//问题
private String text;
}
\ No newline at end of file
package com.luhu.computility.module.external.controller.openapi.dto;
import lombok.Data;
@Data
public class ConversationRespDTO {
//回答
private String text;
}
\ No newline at end of file
package com.luhu.computility.module.external.controller.openapi.dto;
import lombok.Data;
@Data
public class GenerateFaceSwapRespDTO {
//请求唯一标识
private String clientId;
//生成视频/图片的唯一标识
private String promptId;
}
\ No newline at end of file
package com.luhu.computility.module.external.controller.openapi.dto;
import lombok.Data;
import java.util.List;
@Data
public class ImageRespDTO {
private List<String> images;
}
\ No newline at end of file
package com.luhu.computility.module.external.controller.openapi.dto;
import lombok.Data;
import org.springframework.web.multipart.MultipartFile;
@Data
public class MatchImageReqDTO {
private MultipartFile image;
private String url;
private Integer limit;
}
\ No newline at end of file
package com.luhu.computility.module.external.controller.openapi.dto;
import lombok.Data;
@Data
public class MatchImageRespDTO {
//相似度
private Double score;
// 简介,用来对应应用端的文章id
private String brief;
//模型返回的图片签名,图形在数据资源库的唯一id
private String cont_sign;
}
\ No newline at end of file
package com.luhu.computility.module.external.controller.openapi.dto;
import lombok.Data;
@Data
public class MessageDTO {
//角色
private String role;
// 内容
private String content;
}
\ No newline at end of file
package com.luhu.computility.module.external.controller.openapi.dto;
import lombok.Data;
import java.util.List;
@Data
public class MetadataDTO {
//请求唯一标识
private String requestID;
//历史对话记录(包含最新对话)
private List<MessageDTO> messages;
//输入消耗token数
private String inputTokens;
// 回答的问题
private String text;
//输出消耗token数
private String outputTokens;
}
\ No newline at end of file
package com.luhu.computility.module.external.controller.openapi.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.List;
/**
* @version 1.0
* @Author ljq
* @Date 2025/7/16
* @注释
*/
@Data
public class NewAigcTextToImageV2ReqDTO {
@JsonProperty("scenic_spot_id")
private Integer scenicSpotId;
@JsonProperty("category")
private Integer category;
@JsonProperty("season")
private Integer season;
@JsonProperty("addition_content")
private List<String> additionContent;
@JsonProperty("image_count")
private Integer imageCount;
}
package com.luhu.computility.module.external.controller.openapi.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
* @version 1.0
* @Author ljq
* @Date 2025/7/16
* @注释
*/
@Data
public class NewPoetryImageV2ReqDTO {
@JsonProperty("keyword")
private String keyword;
@JsonProperty("province_id")
private Integer provinceId;
@JsonProperty("scenic_spot_id")
private Integer scenicSpotId;
}
package com.luhu.computility.module.external.controller.openapi.dto;
import lombok.Data;
@Data
public class PoetryImageReqDTO {
private String keyword;
private Integer province_id;
private Integer scenic_spot_id;
}
\ No newline at end of file
package com.luhu.computility.module.external.controller.openapi.dto;
import lombok.Data;
import java.util.List;
@Data
public class TextToImageReqDTO {
private Integer scenic_spot_id;
private Integer category;
private Integer season;
private Integer artistic_style;
private List<String> addition_content;
private Integer image_count;
}
\ No newline at end of file
package com.luhu.computility.module.external.controller.openapi.dto;
import lombok.Data;
import org.springframework.web.multipart.MultipartFile;
@Data
public class UploadImageReqDTO {
private MultipartFile image;
private String url;
}
\ No newline at end of file
package com.luhu.computility.module.external.controller.openapi.dto;
import lombok.Data;
@Data
public class UploadImageRespDTO {
//图片文件名
private String imageFileName;
}
\ No newline at end of file
package com.luhu.computility.module.external.controller.openapi.dto;
import lombok.Data;
@Data
public class ViewImageReqDTO {
//视频流id
private String promptId;
}
\ No newline at end of file
package com.luhu.computility.module.external.controller.openapi.dto;
import lombok.Data;
@Data
public class ViewSourceRespDTO {
//视频/图片地址
private String url;
private String coverImage;
}
\ No newline at end of file
package com.luhu.computility.module.external.controller.openapi.dto;
import lombok.Data;
@Data
public class ViewVideoReqDTO {
//视频流id
private String promptId;
}
\ No newline at end of file
package com.luhu.computility.module.external.controller.openapi.service;
import com.luhu.computility.framework.common.pojo.CommonResult;
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.GenerateFaceSwapRespDTO;
import com.luhu.computility.module.external.controller.openapi.dto.ViewImageReqDTO;
import com.luhu.computility.module.external.controller.openapi.dto.ViewVideoReqDTO;
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.ViewVideoReqDTO;
import com.luhu.computility.module.external.controller.openapi.dto.ViewSourceRespDTO;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import java.util.List;
/**
* 转发- Service 接口
*
* @author 智慧导览
*/
public interface OpenApiService {
CommonResult<ConversationRespDTO> digitalHumanConversation(ConversationReqDTO conversationReqDTO);
CommonResult<UploadImageRespDTO> uploadFaceSwapImage(MultipartFile image, String url);
CommonResult<CeateVideoStreamRespDTO> ceateVideoStream(CeateVideoStreamReqDTO ceateVideoStreamReqDTO);
CommonResult<GenerateFaceSwapRespDTO> faceVideoGenerate(MultipartFile image, String url);
CommonResult<ViewSourceRespDTO> viewVideo(ViewVideoReqDTO viewVideoReqDTO);
CommonResult<GenerateFaceSwapRespDTO> faceImageGenerate(MultipartFile sourceImage, String sourceImageUrl,
MultipartFile targetImage, String targetImageUrl);
CommonResult<ViewSourceRespDTO> viewImage(ViewImageReqDTO viewImageReqDTO);
CommonResult<List<MatchImageRespDTO>> matchImage(MultipartFile image, String url, Integer limit, String cityId, String touristAreaId);
CommonResult<AIQARespDTO> AIQAChat(AIQAReqDTO aiqaReqDTO);
SseEmitter AIQAStreamChat(AIQAReqDTO aiqaReqDTO);
SseEmitter aliyunStreamChat(AIQAReqDTO aiqaReqDTO);
String getSourceUrl(String promptId, Integer type);
}
\ No newline at end of file
package com.luhu.computility.module.external.controller.openapi.service;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
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.module.external.controller.admin.file.vo.AiGeneratedFileSaveReqVO;
import com.luhu.computility.module.external.controller.enums.AiGeneratedFileStatus;
import com.luhu.computility.module.external.controller.enums.AiGeneratedFileType;
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.GenerateFaceSwapRespDTO;
import com.luhu.computility.module.external.controller.openapi.dto.ViewImageReqDTO;
import com.luhu.computility.module.external.controller.openapi.dto.ViewVideoReqDTO;
import com.luhu.computility.module.external.dal.dataobject.file.AiGeneratedFileDO;
import com.luhu.computility.module.external.enums.CityEnum;
import com.luhu.computility.module.external.eums.DictDataConstants;
import com.luhu.computility.module.external.eums.DictTypeConstants;
import com.luhu.computility.module.external.service.file.AiGeneratedFileService;
import com.luhu.computility.module.system.service.dict.DictDataService;
import com.luhu.computility.module.external.controller.admin.file.vo.AiGeneratedFileSaveReqVO;
import com.luhu.computility.module.external.controller.enums.AiGeneratedFileStatus;
import com.luhu.computility.module.external.controller.enums.AiGeneratedFileType;
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.service.SSEService;
import com.luhu.computility.module.external.dal.dataobject.file.AiGeneratedFileDO;
import com.luhu.computility.module.external.enums.CityEnum;
import com.luhu.computility.module.external.eums.DictDataConstants;
import com.luhu.computility.module.external.eums.DictTypeConstants;
import com.luhu.computility.module.external.service.file.AiGeneratedFileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static com.luhu.computility.framework.common.pojo.CommonResult.error;
import static com.luhu.computility.framework.common.pojo.CommonResult.success;
/**
* ai换脸-生成文件 Service 实现类
*
* @author 智慧导览
*/
@Service
@Validated
@Slf4j
public class OpenApiServiceImpl implements OpenApiService {
@Resource
private AiGeneratedFileService aiGeneratedFileService;
@Value("${digital-human-zhuxi.conversation}")
private String digitalHumanZhuxiConversation;
@Value("${digital-human-zhuxi.token}")
private String digitalHumanZhuxiToken;
@Value("${swap-face.upload-image}")
private String uploadFaceSwapImageUrl;
@Value("${similar-image.match-mage}")
private String matchImageUrl;
@Value("${swap-face.create-video-stream}")
private String createVideoStreamUrl;
@Value("${swap-face.image-to-video}")
private String imageToVideoUrl;
@Value("${swap-face.image-to-image}")
private String imageToImageUrl;
@Value("${swap-face.view-video}")
private String viewVideoUrl;
@Value("${swap-face.view-image}")
private String viewImageUrl;
@Value("${swap-face.AIQA-chat}")
private String AIQAchat;
@Value("${swap-face.AIQA-stream-chat}")
private String AIQAStreamchat;
@Value("${swap-face.aliyun-stream-chat}")
private String aliyunStreamchat;
@Autowired
private SSEService sseService;
@Autowired
private DictDataService dictDataService;
@Override
public CommonResult<ConversationRespDTO> digitalHumanConversation(ConversationReqDTO conversationReqDTO) {
TreeMap<String, String> header = new TreeMap<>();
header.put("Content-Type", "text/plain");
header.put("Authorization", digitalHumanZhuxiToken);
try {
String result = HttpUtils.post(digitalHumanZhuxiConversation, header, conversationReqDTO.getText());
return checkConversationResponseResult(result);
}catch (Exception e){
Integer errorCode = GlobalResponseCodeConstants.INTERNAL_SERVER_ERROR.getCode();
String errorMsg = GlobalResponseCodeConstants.INTERNAL_SERVER_ERROR.getMsg();
if (e instanceof ServiceException) {
ServiceException serviceException = (ServiceException) e;
errorCode = serviceException.getCode();
errorMsg = serviceException.getMessage();
}
return error(errorCode, errorMsg);
}
}
@Override
public CommonResult<UploadImageRespDTO> uploadFaceSwapImage(MultipartFile image, String url) {
if (ObjectUtils.isEmpty(image) && StringUtils.isEmpty(url)) {
return error(GlobalResponseCodeConstants.IMAGE_EXCEPTION.getCode(),
GlobalResponseCodeConstants.IMAGE_EXCEPTION.getMsg());
} else if (!ObjectUtils.isEmpty(image) && StringUtils.isEmpty(url)) {
//上传的是图片文件
// 创建临时文件
File tempFile = null;
try {
tempFile = File.createTempFile("upload", image.getOriginalFilename());
image.transferTo(tempFile);
Map<String, Object> formMaps = new HashMap<>();
formMaps.put("image", tempFile);
String result = HttpUtils.postIncludeImage(uploadFaceSwapImageUrl, null, formMaps);
return handleJsonObjectResult(result,UploadImageRespDTO.class);
}catch (Exception e) {
// 删除临时文件
if (tempFile != null) {
tempFile.delete();
}
return error(GlobalResponseCodeConstants.INTERNAL_SERVER_ERROR.getCode(),
GlobalResponseCodeConstants.INTERNAL_SERVER_ERROR.getMsg());
}
} else if (ObjectUtils.isEmpty(image) && !StringUtils.isEmpty(url)) {
try {
Map<String, Object> formMaps = new HashMap<>();
formMaps.put("url", url);
String result = HttpUtils.postIncludeImage(uploadFaceSwapImageUrl, null, formMaps);
return handleJsonObjectResult(result,UploadImageRespDTO.class);
}catch (Exception e) {
return error(GlobalResponseCodeConstants.INTERNAL_SERVER_ERROR.getCode(),
GlobalResponseCodeConstants.INTERNAL_SERVER_ERROR.getMsg());
}
} else
return error(GlobalResponseCodeConstants.IMAGE_UNIQUE.getCode(),
GlobalResponseCodeConstants.IMAGE_UNIQUE.getMsg());
}
@Override
public CommonResult<CeateVideoStreamRespDTO> ceateVideoStream(CeateVideoStreamReqDTO ceateVideoStreamReqDTO) {
try {
Map<String, String> queryParams = new HashMap<>();
queryParams.put("filename", ceateVideoStreamReqDTO.getFileName());
String result = HttpUtils.get(createVideoStreamUrl, null, queryParams);
return handleJsonObjectResult(result, CeateVideoStreamRespDTO.class);
}catch (Exception e) {
Integer errorCode = GlobalResponseCodeConstants.INTERNAL_SERVER_ERROR.getCode();
String errorMsg = GlobalResponseCodeConstants.INTERNAL_SERVER_ERROR.getMsg();
return error(errorCode, errorMsg);
}
}
@Override
public CommonResult<GenerateFaceSwapRespDTO> faceVideoGenerate(MultipartFile image, String url) {
if (ObjectUtils.isEmpty(image) && StringUtils.isEmpty(url)) {
return error(GlobalResponseCodeConstants.IMAGE_EXCEPTION.getCode(),
GlobalResponseCodeConstants.IMAGE_EXCEPTION.getMsg());
}
Map<String, Object> formMaps = new HashMap<>();
File tempFile = null;
try {
if (!ObjectUtils.isEmpty(image)) {
tempFile = convertMultipartFileToTempFile(image, "upload");
formMaps.put("image", tempFile);
} else {
formMaps.put("url", url);
}
return sendFormRequestWithFiles(imageToVideoUrl, formMaps, GenerateFaceSwapRespDTO.class, AiGeneratedFileType.VIDEO.getValue());
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
safelyDeleteTempFile(tempFile);
}
}
public CommonResult<GenerateFaceSwapRespDTO> faceImageGenerate(MultipartFile sourceImage, String sourceImageUrl,
MultipartFile targetImage, String targetImageUrl) {
boolean hasSourceImage = !ObjectUtils.isEmpty(sourceImage);
boolean hasSourceUrl = !StringUtils.isEmpty(sourceImageUrl);
if (hasSourceImage == hasSourceUrl) {
return error(GlobalResponseCodeConstants.SOURCEIMAGE_IMAGE_EXCEPTION.getCode(),
GlobalResponseCodeConstants.SOURCEIMAGE_IMAGE_EXCEPTION.getMsg());
}
boolean hasTargetImage = !ObjectUtils.isEmpty(targetImage);
boolean hasTargetUrl = !StringUtils.isEmpty(targetImageUrl);
if (hasTargetImage == hasTargetUrl) {
return error(GlobalResponseCodeConstants.TARGETIMAGE_IMAGE_EXCEPTION.getCode(),
GlobalResponseCodeConstants.TARGETIMAGE_IMAGE_EXCEPTION.getMsg());
}
Map<String, Object> formMaps = new HashMap<>();
File sourceTemp = null, targetTemp = null;
try {
if (hasSourceImage) {
sourceTemp = convertMultipartFileToTempFile(sourceImage, "source_");
formMaps.put("sourceImage", sourceTemp);
} else {
formMaps.put("sourceImageUrl", sourceImageUrl);
}
if (hasTargetImage) {
targetTemp = convertMultipartFileToTempFile(targetImage, "target_");
formMaps.put("targetImage", targetTemp);
} else {
formMaps.put("targetImageUrl", targetImageUrl);
}
return sendFormRequestWithFiles(imageToImageUrl, formMaps, GenerateFaceSwapRespDTO.class, AiGeneratedFileType.IMAGE.getValue());
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
safelyDeleteTempFile(sourceTemp);
safelyDeleteTempFile(targetTemp);
}
}
private File convertMultipartFileToTempFile(MultipartFile file, String prefix) throws IOException {
File tempFile = File.createTempFile(prefix, file.getOriginalFilename());
file.transferTo(tempFile);
return tempFile;
}
private void safelyDeleteTempFile(File file) {
if (file != null && file.exists()) {
file.delete();
}
}
private <T> CommonResult<T> sendFormRequestWithFiles(String url, Map<String, Object> formData, Class<T> responseType, Integer type) {
try {
String result = HttpUtils.postIncludeImage(url, null, formData);
return handleJsonObjectIncludeSourceResult(result, responseType, type);
} catch (Exception e) {
return error(GlobalResponseCodeConstants.INTERNAL_SERVER_ERROR.getCode(),
GlobalResponseCodeConstants.INTERNAL_SERVER_ERROR.getMsg());
}
}
@Override
public CommonResult<ViewSourceRespDTO> viewVideo(ViewVideoReqDTO viewVideoReqDTO) {
try {
/*Map<String, String> queryParams = new HashMap<>();
queryParams.put("promptId", viewVideoReqDTO.getPromptId());
String result = HttpUtils.get(viewVideoUrl, null, queryParams);
return handleJsonObjectResult(result, ViewSourceRespDTO.class);*/
AiGeneratedFileDO aiGeneratedFileDO =
aiGeneratedFileService.getAiGeneratedFileByPromptId(viewVideoReqDTO.getPromptId());
if (!ObjectUtils.isEmpty(aiGeneratedFileDO)) {
if (!StringUtils.isEmpty(aiGeneratedFileDO.getUrl())) {
String videoSuffix = dictDataService.getDictData(DictTypeConstants.FILE_SUFFIX, DictDataConstants.VIDEO_SUFFIX).getLabel();
return success(new ViewSourceRespDTO()
.setUrl(aiGeneratedFileDO.getUrl())
.setCoverImage(aiGeneratedFileDO.getUrl() + videoSuffix));
} else {
Integer errorCode = GlobalResponseCodeConstants.BEING_GENERATED.getCode();
String errorMsg = GlobalResponseCodeConstants.INVALID_SERIAL_NUMBER.getMsg();
return error(errorCode, errorMsg);
}
} else {
Integer errorCode = GlobalResponseCodeConstants.INVALID_SERIAL_NUMBER.getCode();
String errorMsg = GlobalResponseCodeConstants.INVALID_SERIAL_NUMBER.getMsg();
return error(errorCode, errorMsg);
}
}catch (Exception e) {
Integer errorCode = GlobalResponseCodeConstants.INTERNAL_SERVER_ERROR.getCode();
String errorMsg = GlobalResponseCodeConstants.INTERNAL_SERVER_ERROR.getMsg();
return error(errorCode, errorMsg);
}
}
@Override
public CommonResult<ViewSourceRespDTO> viewImage(ViewImageReqDTO viewImageReqDTO) {
try {
/*Map<String, String> queryParams = new HashMap<>();
queryParams.put("promptId", viewImageReqDTO.getPromptId());
String result = HttpUtils.get(viewImageUrl, null, queryParams);
return handleJsonObjectResult(result, ViewImageRespDTO.class);*/
AiGeneratedFileDO aiGeneratedFileDO =
aiGeneratedFileService.getAiGeneratedFileByPromptId(viewImageReqDTO.getPromptId());
if (!ObjectUtils.isEmpty(aiGeneratedFileDO)) {
if (!StringUtils.isEmpty(aiGeneratedFileDO.getUrl())) {
String imageSuffix = dictDataService.getDictData(DictTypeConstants.FILE_SUFFIX, DictDataConstants.IMAGE_SUFFIX).getLabel();
return success(new ViewSourceRespDTO()
.setUrl(aiGeneratedFileDO.getUrl())
.setCoverImage(aiGeneratedFileDO.getUrl() + imageSuffix));
} else {
Integer errorCode = GlobalResponseCodeConstants.BEING_GENERATED.getCode();
String errorMsg = GlobalResponseCodeConstants.BEING_GENERATED.getMsg();
return error(errorCode, errorMsg);
}
} else {
Integer errorCode = GlobalResponseCodeConstants.INVALID_SERIAL_NUMBER.getCode();
String errorMsg = GlobalResponseCodeConstants.INVALID_SERIAL_NUMBER.getMsg();
return error(errorCode, errorMsg);
}
}catch (Exception e) {
Integer errorCode = GlobalResponseCodeConstants.INTERNAL_SERVER_ERROR.getCode();
String errorMsg = GlobalResponseCodeConstants.INTERNAL_SERVER_ERROR.getMsg();
return error(errorCode, errorMsg);
}
}
@Override
public CommonResult<List<MatchImageRespDTO>> matchImage(MultipartFile image, String url, Integer limit, String cityId, String touristAreaId) {
File tempFile = null;
//都没传
if (ObjectUtils.isEmpty(image) && StringUtils.isEmpty(url)) {
return error(GlobalResponseCodeConstants.IMAGE_EXCEPTION.getCode(),
GlobalResponseCodeConstants.IMAGE_EXCEPTION.getMsg());
} else if (!ObjectUtils.isEmpty(image) && StringUtils.isEmpty(url)) {
try {
tempFile = File.createTempFile("upload", image.getOriginalFilename());
image.transferTo(tempFile);
Map<String, Object> formMaps = new HashMap<>();
formMaps.put("image", tempFile);
formMaps.put("limit", limit);
//classId1、2为设置的分类名
formMaps.put("classId1", cityId);
formMaps.put("classId2", touristAreaId);
String result = HttpUtils.postIncludeImage(matchImageUrl, null, formMaps);
return checkMatchImageResponseResult(result);
} catch (Exception e) {
// 删除临时文件
if (tempFile != null) {
tempFile.delete();
}
Integer errorCode = GlobalResponseCodeConstants.INTERNAL_SERVER_ERROR.getCode();
String errorMsg = GlobalResponseCodeConstants.INTERNAL_SERVER_ERROR.getMsg();
return error(errorCode, errorMsg);
}
} else if (ObjectUtils.isEmpty(image) && !StringUtils.isEmpty(url)) {
try {
Map<String, Object> formMaps = new HashMap<>();
formMaps.put("url", url);
formMaps.put("limit", limit);
formMaps.put("classId1", cityId);
formMaps.put("classId2", touristAreaId);
String result = HttpUtils.postIncludeImage(matchImageUrl, null, formMaps);
return checkMatchImageResponseResult(result);
}catch (Exception e) {
return error(GlobalResponseCodeConstants.INTERNAL_SERVER_ERROR.getCode(),
GlobalResponseCodeConstants.INTERNAL_SERVER_ERROR.getMsg());
}
} else
return error(GlobalResponseCodeConstants.INTERNAL_SERVER_ERROR.getCode(),
GlobalResponseCodeConstants.INTERNAL_SERVER_ERROR.getMsg());
}
@Override
public CommonResult<AIQARespDTO> AIQAChat(AIQAReqDTO aiqaReqDTO) {
try {
String requesyBody = JSONUtil.toJsonStr(aiqaReqDTO);
String result = HttpUtils.post(AIQAchat, null, requesyBody);
return handleJsonObjectResult(result, AIQARespDTO.class);
} catch (Exception e) {
Integer errorCode = GlobalResponseCodeConstants.INTERNAL_SERVER_ERROR.getCode();
String errorMsg = GlobalResponseCodeConstants.INTERNAL_SERVER_ERROR.getMsg();
return error(errorCode, errorMsg);
}
}
@Override
public SseEmitter AIQAStreamChat(AIQAReqDTO aiqaReqDTO) {
//如果城市不为空,则要从枚举类取知识库id
if (!CollectionUtil.isEmpty(aiqaReqDTO.getPipelineIds())) {
List<String> list = new ArrayList<>();
for (String pipelineId : aiqaReqDTO.getPipelineIds()) {
if (!ObjectUtils.isEmpty(CityEnum.getByValue(pipelineId))) {
list.add(CityEnum.getByValue(pipelineId).getRemark());
}
}
aiqaReqDTO.setPipelineIds(list);
}
SseEmitter emitter = new SseEmitter(Long.MAX_VALUE);
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.submit(() -> {
try {
sseService.receiveSSEStream(AIQAStreamchat, aiqaReqDTO)
.subscribe(message -> {
try {
emitter.send(SseEmitter.event().data(message));
} catch (IOException e) {
log.error("AI问答流式返回异常" + e.toString());
emitter.completeWithError(e);
}
},
error -> emitter.completeWithError(error),
() -> emitter.complete()
);
} catch (Exception e) {
emitter.completeWithError(e);
}
});
return emitter;
}
@Override
public SseEmitter aliyunStreamChat(AIQAReqDTO aiqaReqDTO) {
//如果城市不为空,则要从枚举类取知识库id
if (!CollectionUtil.isEmpty(aiqaReqDTO.getPipelineIds())) {
List<String> list = new ArrayList<>();
for (String pipelineId : aiqaReqDTO.getPipelineIds()) {
if (!ObjectUtils.isEmpty(CityEnum.getByValue(pipelineId))) {
list.add(CityEnum.getByValue(pipelineId).getRemark());
}
}
aiqaReqDTO.setPipelineIds(list);
}
SseEmitter emitter = new SseEmitter(Long.MAX_VALUE);
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.submit(() -> {
try {
sseService.receiveSSEStream(aliyunStreamchat, aiqaReqDTO)
.subscribe(message -> {
try {
emitter.send(SseEmitter.event().data(message));
} catch (IOException e) {
log.error("AI问答流式返回异常" + e.toString());
emitter.completeWithError(e);
}
},
error -> emitter.completeWithError(error),
() -> emitter.complete()
);
} catch (Exception e) {
emitter.completeWithError(e);
}
});
return emitter;
}
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//验证对话朱熹转发接口的回复
public CommonResult<ConversationRespDTO> checkConversationResponseResult(String result) {
Map<String, String> resultMap = parseSSEData(result);
JSONObject dataJson = JSONUtil.parseObj((String)resultMap.get("data"));
ConversationRespDTO conversationRespDTO = new ConversationRespDTO();
conversationRespDTO.setText((String)dataJson.get("message"));
return success(conversationRespDTO);
}
public CommonResult<List<MatchImageRespDTO>> checkMatchImageResponseResult(String result) {
JSONObject resultJson = JSONUtil.parseObj(result);
Integer responseCode = (Integer) resultJson.get("code");
if (responseCode.equals(GlobalResponseCodeConstants.EXTERNAL_SUCCESS.getCode())) {
List<MatchImageRespDTO> matchImageRespDTOS = JSONUtil.toList((JSONArray) resultJson.get("data"), MatchImageRespDTO.class);
return success(matchImageRespDTOS);
} else {
return error((Integer) resultJson.get("code"), (String)resultJson.get("message"));
}
}
public Map<String, String> parseSSEData(String data) {
Map<String, String> result = new HashMap<>();
String[] lines = data.split("\n");
for (String line : lines) {
String[] parts = line.split(": ", 2); // 限制分割次数为2,防止data中的冒号被误分割
if (parts.length == 2) {
String key = parts[0].trim();
String value = parts[1].trim();
result.put(key, value);
}
}
return result;
}
public <T> CommonResult<T> handleJsonObjectResult(String result, Class<T> clazz) {
JSONObject resultJson = JSONUtil.parseObj(result);
Integer responseCode = (Integer) resultJson.get("code");
if (responseCode.equals(GlobalResponseCodeConstants.EXTERNAL_SUCCESS.getCode())) {
T data = JSONUtil.toBean((JSONObject) resultJson.get("data"), clazz);
return success(data);
} else {
return error((Integer) resultJson.get("code"), (String) resultJson.get("message"));
}
}
public <T> CommonResult<T> handleJsonObjectIncludeSourceResult(String result, Class<T> clazz, Integer type) {
JSONObject resultJson = JSONUtil.parseObj(result);
Integer responseCode = (Integer) resultJson.get("code");
if (responseCode.equals(GlobalResponseCodeConstants.EXTERNAL_SUCCESS.getCode())) {
T data = JSONUtil.toBean((JSONObject) resultJson.get("data"), clazz);
//如果是视频/图片换脸,则要在数据库存下原始端任务信息
if (data instanceof GenerateFaceSwapRespDTO) {
String promptId = ((GenerateFaceSwapRespDTO) data).getPromptId();
AiGeneratedFileDO aiGeneratedFileByPromptId = aiGeneratedFileService.getAiGeneratedFileByPromptId(promptId);
//生成者回传的任务id出现了两条一样的数据,这种情况基本不可能发生,以防万一
if (ObjectUtils.isEmpty(aiGeneratedFileByPromptId)) {
//生成视频需要时间,默认未开始上传
aiGeneratedFileService.createAiGeneratedFile(
new AiGeneratedFileSaveReqVO().setPromptId(promptId)
.setStatus(AiGeneratedFileStatus.UNSTART.getValue())
.setType(type));
} else {
Integer errorCode = GlobalResponseCodeConstants.INTERNAL_SERVER_ERROR.getCode();
String errorMsg = GlobalResponseCodeConstants.INTERNAL_SERVER_ERROR.getMsg();
return error(errorCode, errorMsg);
}
}
return success(data);
} else {
return error((Integer) resultJson.get("code"), (String) resultJson.get("message"));
}
}
@Override
public String getSourceUrl(String promptId, Integer type) {
try {
Map<String, String> queryParams = new HashMap<>();
queryParams.put("promptId", promptId);
String result;
if (type.intValue() == AiGeneratedFileType.VIDEO.getValue() ) {
result = HttpUtils.get(viewVideoUrl, null, queryParams);
} else {
result = HttpUtils.get(viewImageUrl, null, queryParams);
}
CommonResult<ViewSourceRespDTO> viewVideoRespDTOCommonResult = handleJsonObjectResult(result, ViewSourceRespDTO.class);
return viewVideoRespDTOCommonResult.getData().getUrl();
}catch (Exception e) {
return "获资源地址异常";
}
}
}
\ No newline at end of file
package com.luhu.computility.module.external.controller.openapi.vo;
import lombok.Data;
@Data
public class AIQAStreamRespVO {
//内容
private String content;
//
private String eventName;
}
\ No newline at end of file
package com.luhu.computility.module.external.controller.service;
/**
* @version 1.0
* @Author ljq
* @Date 2025/4/28
* @注释
*/
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.luhu.computility.module.external.controller.openapi.dto.AIQAReqDTO;
import com.luhu.computility.module.external.controller.openapi.dto.AIQAStreamRespDTO;
import com.luhu.computility.module.external.controller.openapi.dto.AIQAReqDTO;
import com.luhu.computility.module.external.controller.openapi.dto.AIQAStreamRespDTO;
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
@Service
public class SSEService {
private final WebClient webClient;
private final BlockingQueue<String> messageQueue = new LinkedBlockingQueue<>();
private AIQAStreamRespDTO aiqaStreamRespDTO;
public SSEService() {
this.webClient = WebClient.create();
}
public Flux<AIQAStreamRespDTO> receiveSSEStream(String url, AIQAReqDTO aiqaReqDTO) {
return webClient.post()
.uri(url)
.contentType(MediaType.APPLICATION_JSON) // 设置请求体的Content-Type为JSON
.bodyValue(aiqaReqDTO)
.retrieve()
.bodyToFlux(ServerSentEvent.class)
.map(response -> {
System.out.println(response.event());
System.out.println(response.data());
JSONObject data = JSONUtil.parseObj(response.data());
aiqaStreamRespDTO = JSONUtil.toBean(data, AIQAStreamRespDTO.class);
//针对源端的error进行处理,如果事件名称包含error,为了给用户一个好的体验,返回一个用户看得懂的语句
if (response.event().contains("error")) {
aiqaStreamRespDTO.setEventName("complete");
aiqaStreamRespDTO.setContent("当前系统访问人数较多,请稍后试试...");
} else {
aiqaStreamRespDTO.setEventName(response.event());
}
/* if (!ObjectUtils.isEmpty(data.get("content"))) {
aiqaStreamRespDTO.setContent((String)data.get("content"));
}
if (!ObjectUtils.isEmpty(data.get("messages"))) {
aiqaStreamRespDTO.setMessages(JsonUtils.parseArray((String) data.get("messages"), MessageDTO.class));
}*/
return aiqaStreamRespDTO;
})
.filter(result -> {
//content有内容或者eventName为complete
return !ObjectUtils.isEmpty(aiqaStreamRespDTO.getContent()) || "complete".equals(result.getEventName());
});
}
//备用方法
public String backUp(String response) {
String[] lines = response.split("\n");
JSONObject jsonObject = JSONUtil.parseObj(response);
if (!StringUtils.isEmpty((String)jsonObject.get("content")) && "null".equals((String)jsonObject.get("content"))) {
}
StringBuilder message = new StringBuilder();
for (String line : lines) {
if (line.startsWith("content: ")) {
message.append(line.substring(6)).append("\n");
} else if (line.isEmpty() && message.length() > 0) {
String completeMessage = message.toString().trim();
message.setLength(0);
return completeMessage;
}
}
return null;
}
}
\ No newline at end of file
package com.luhu.computility.module.external.dal.dataobject.appcredentials;
import com.luhu.computility.framework.mybatis.core.dataobject.BaseDO;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
/**
* 外部应用鉴权信息 DO
*
* @author 芋道源码
*/
@TableName("external_app_credentials")
@KeySequence("external_app_credentials_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AppCredentialsDO extends BaseDO {
/**
* 参数主键
*/
@TableId
private Long id;
/**
* 应用名
*/
private String appName;
/**
* 应用id
*/
private String appId;
/**
* 应用密钥
*/
private String appSecret;
/**
* 备注
*/
private String remark;
}
\ No newline at end of file
package com.luhu.computility.module.external.dal.dataobject.file;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.luhu.computility.framework.mybatis.core.dataobject.BaseDO;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.ToString;
/**
* ai换脸-生成文件 DO
*
* @author 智慧导览
*/
@TableName("external_file")
@KeySequence("external_file_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AiGeneratedFileDO extends BaseDO {
/**
* 自增主键
*/
@TableId
private Integer id;
/**
* 任务id
*/
private String promptId;
/**
* 文件类型 1.图片 2.视频
*
*/
private Integer type;
/**
* 文件生成状态 1.未开始 2.上传中 3.已上传
*
*/
private Integer status;
/**
* oss存储地址
*/
private String url;
/**
* 原始存储地址
*/
private String originalUrl;
/**
* 缩略图/首帧地址
*/
private String coverImage;
}
\ No newline at end of file
package com.luhu.computility.module.external.dal.mysql.appcredentials;
import java.util.*;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.mybatis.core.mapper.BaseMapperX;
import com.luhu.computility.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.luhu.computility.module.external.controller.admin.appcredentials.vo.AppCredentialsPageReqVO;
import com.luhu.computility.module.external.dal.dataobject.appcredentials.AppCredentialsDO;
import com.luhu.computility.module.external.dal.dataobject.appcredentials.AppCredentialsDO;
import org.apache.ibatis.annotations.Mapper;
/**
* 外部应用鉴权信息 Mapper
*
* @author 芋道源码
*/
@Mapper
public interface AppCredentialsMapper extends BaseMapperX<AppCredentialsDO> {
default PageResult<AppCredentialsDO> selectPage(AppCredentialsPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<AppCredentialsDO>()
.likeIfPresent(AppCredentialsDO::getAppName, reqVO.getAppName())
.eqIfPresent(AppCredentialsDO::getAppId, reqVO.getAppId())
.eqIfPresent(AppCredentialsDO::getAppSecret, reqVO.getAppSecret())
.eqIfPresent(AppCredentialsDO::getRemark, reqVO.getRemark())
.betweenIfPresent(AppCredentialsDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(AppCredentialsDO::getId));
}
}
\ No newline at end of file
package com.luhu.computility.module.external.dal.mysql.file;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.mybatis.core.mapper.BaseMapperX;
import com.luhu.computility.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.luhu.computility.module.external.controller.admin.file.vo.AiGeneratedFilePageReqVO;
import com.luhu.computility.module.external.controller.enums.AiGeneratedFileStatus;
import com.luhu.computility.module.external.dal.dataobject.file.AiGeneratedFileDO;
import com.luhu.computility.module.external.controller.admin.file.vo.AiGeneratedFilePageReqVO;
import com.luhu.computility.module.external.controller.enums.AiGeneratedFileStatus;
import com.luhu.computility.module.external.dal.dataobject.file.AiGeneratedFileDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* ai换脸-生成文件 Mapper
*
* @author 智慧导览
*/
@Mapper
public interface AiGeneratedFileMapper extends BaseMapperX<AiGeneratedFileDO> {
default PageResult<AiGeneratedFileDO> selectPage(AiGeneratedFilePageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<AiGeneratedFileDO>()
.eqIfPresent(AiGeneratedFileDO::getPromptId, reqVO.getPromptId())
.eqIfPresent(AiGeneratedFileDO::getType, reqVO.getType())
.eqIfPresent(AiGeneratedFileDO::getStatus, reqVO.getStatus())
.betweenIfPresent(AiGeneratedFileDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(AiGeneratedFileDO::getId));
}
default AiGeneratedFileDO getAiGeneratedFileByPromptId(String promptId) {
return selectOne(new LambdaQueryWrapperX<AiGeneratedFileDO>()
.eqIfPresent(AiGeneratedFileDO::getPromptId, promptId));
}
default List<AiGeneratedFileDO> getAiGeneratedFileByStatus(Integer status) {
return selectList(new LambdaQueryWrapperX<AiGeneratedFileDO>()
.eqIfPresent(AiGeneratedFileDO::getStatus, status));
}
default List<AiGeneratedFileDO> selectPendingTasks() {
return selectList(new LambdaQueryWrapperX<AiGeneratedFileDO>()
.eq(AiGeneratedFileDO::getStatus, AiGeneratedFileStatus.UNSTART.getValue())
.isNotNull(AiGeneratedFileDO::getOriginalUrl)
.or().eq(AiGeneratedFileDO::getStatus, AiGeneratedFileStatus.FAILED.getValue())
.last(" order by create_time desc limit 10"));
}
}
\ No newline at end of file
package com.luhu.computility.module.external.enums;
public enum CityEnum {
TIANSHUI("1", "t3gp1i7p7z"),
YUEYANG("3", "l6k1abp3yp"),
CHANGSHA("2", "fn3syzuf4a");
private String value;
private String remark;
private CityEnum(String value, String remark) {
this.value = value;
this.remark = remark;
}
public String getValue() {
return value;
}
public String getRemark() {
return remark;
}
public static CityEnum getByValue(String value) {
for (CityEnum o : CityEnum.values()) {
if (o.getValue() .equals(value) ) {
return o;
}
}
return null;
}
}
package com.luhu.computility.module.external.eums;
/**
* Infra 字典类型的枚举类
*
* @author 芋道源码
*/
public interface DictDataConstants {
String VIDEO_SUFFIX = "video_suffix";
String IMAGE_SUFFIX = "image_suffix";
}
package com.luhu.computility.module.external.eums;
/**
* Infra 字典类型的枚举类
*
* @author 芋道源码
*/
public interface DictTypeConstants {
String FILE_SUFFIX = "file_suffix";
}
package com.luhu.computility.module.external.job;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.luhu.computility.framework.quartz.core.handler.JobHandler;
import com.luhu.computility.framework.tenant.core.aop.TenantIgnore;
import com.luhu.computility.module.external.controller.admin.file.vo.AiGeneratedFileSaveReqVO;
import com.luhu.computility.module.external.controller.enums.AiGeneratedFileStatus;
import com.luhu.computility.module.external.dal.dataobject.file.AiGeneratedFileDO;
import com.luhu.computility.module.external.controller.admin.file.vo.AiGeneratedFileSaveReqVO;
import com.luhu.computility.module.external.controller.enums.AiGeneratedFileStatus;
import com.luhu.computility.module.external.controller.openapi.service.OpenApiService;
import com.luhu.computility.module.external.dal.dataobject.file.AiGeneratedFileDO;
import com.luhu.computility.module.external.service.file.AiGeneratedFileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
/**
* @version 1.0
* @Author ljq
* @Date 2025/6/17
* @ 定时查找模型已处理的视频,上传到oss并将新地址更新到数据库
*/
@Component
@Slf4j
public class UpdateAiGeneratedFileStatusJob implements JobHandler {
@Resource
private AiGeneratedFileService aiGeneratedFileService;
@Resource
private OpenApiService openApiService;
@Override
@TenantIgnore
public String execute(String param) {
List<AiGeneratedFileDO> aiGeneratedFileList = aiGeneratedFileService.getAiGeneratedFileByStatus(AiGeneratedFileStatus.UNSTART.getValue());
int num = 0;
if (!CollectionUtil.isEmpty(aiGeneratedFileList)){
for (AiGeneratedFileDO aiGeneratedFileDO : aiGeneratedFileList) {
String originalUrl = openApiService.getSourceUrl(aiGeneratedFileDO.getPromptId(), aiGeneratedFileDO.getType());
if (!ObjectUtil.isEmpty(originalUrl)) {
aiGeneratedFileService.updateAiGeneratedFile(new AiGeneratedFileSaveReqVO()
.setId(aiGeneratedFileDO.getId())
.setOriginalUrl(originalUrl));
num++;
}
}
}
return StrUtil.format("更新数量:", num);
}
}
package com.luhu.computility.module.external.job;
import cn.hutool.core.util.StrUtil;
import com.luhu.computility.framework.quartz.core.handler.JobHandler;
import com.luhu.computility.framework.tenant.core.aop.TenantIgnore;
import com.luhu.computility.module.external.service.file.AiGeneratedFileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* @version 1.0
* @Author ljq
* @Date 2025/6/17
* @ 定时查找模型已处理的视频,上传到oss并将新地址更新到数据库
*/
@Component
@Slf4j
public class UploadAiGeneratedFileJob implements JobHandler {
@Resource
private AiGeneratedFileService aiGeneratedFileService;
@Override
@TenantIgnore
public String execute(String param) {
aiGeneratedFileService.startUploadTask();
return StrUtil.format("更新数量:", "updateDOList.size()");
}
}
package com.luhu.computility.module.external.service.appcredentials;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.luhu.computility.framework.common.exception.ServiceException;
import com.luhu.computility.module.external.AppCredentialsApi;
import com.luhu.computility.module.external.AppCredentialsApi;
import com.luhu.computility.module.external.controller.enums.ErrorCodeConstants;
import com.luhu.computility.module.external.dal.dataobject.appcredentials.AppCredentialsDO;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import static com.luhu.computility.module.external.controller.enums.ErrorCodeConstants.APPID_ERROR_NOT_EXISTS;
/**
* @version 1.0
* @Author ljq
* @Date 2025/4/16
* @注释
*/
@Service
@Validated
public class AppCredentialsApiImpl implements AppCredentialsApi {
@Resource
private AppCredentialsService appCredentialsService;
@Override
public String getAppSecretByAppid(String appId) {
String appSecret = appCredentialsService.getAppSecretByAppid(appId);
if (StringUtils.isEmpty(appSecret)) {
throw new ServiceException(APPID_ERROR_NOT_EXISTS);
}
return appSecret;
}
}
package com.luhu.computility.module.external.service.appcredentials;
import java.util.*;
import javax.validation.*;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.module.external.controller.admin.appcredentials.vo.AppCredentialsPageReqVO;
import com.luhu.computility.module.external.controller.admin.appcredentials.vo.AppCredentialsSaveReqVO;
import com.luhu.computility.module.external.dal.dataobject.appcredentials.AppCredentialsDO;
import com.luhu.computility.module.external.dal.dataobject.appcredentials.AppCredentialsDO;
/**
* 外部应用鉴权信息 Service 接口
*
* @author 芋道源码
*/
public interface AppCredentialsService {
/**
* 创建外部应用鉴权信息
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createAppCredentials(@Valid AppCredentialsSaveReqVO createReqVO);
/**
* 更新外部应用鉴权信息
*
* @param updateReqVO 更新信息
*/
void updateAppCredentials(@Valid AppCredentialsSaveReqVO updateReqVO);
/**
* 删除外部应用鉴权信息
*
* @param id 编号
*/
void deleteAppCredentials(Long id);
/**
* 获得外部应用鉴权信息
*
* @param id 编号
* @return 外部应用鉴权信息
*/
AppCredentialsDO getAppCredentials(Long id);
/**
* 获得外部应用鉴权信息分页
*
* @param pageReqVO 分页查询
* @return 外部应用鉴权信息分页
*/
PageResult<AppCredentialsDO> getAppCredentialsPage(AppCredentialsPageReqVO pageReqVO);
String getAppSecretByAppid(String appId);
}
\ No newline at end of file
package com.luhu.computility.module.external.service.appcredentials;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.luhu.computility.framework.common.exception.ServiceException;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.common.util.object.BeanUtils;
import com.luhu.computility.module.external.controller.admin.appcredentials.vo.AppCredentialsPageReqVO;
import com.luhu.computility.module.external.controller.admin.appcredentials.vo.AppCredentialsSaveReqVO;
import com.luhu.computility.module.external.dal.dataobject.appcredentials.AppCredentialsDO;
import com.luhu.computility.module.external.dal.mysql.appcredentials.AppCredentialsMapper;
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.external.dal.dataobject.appcredentials.AppCredentialsDO;
import com.luhu.computility.module.external.dal.mysql.appcredentials.AppCredentialsMapper;
import static com.luhu.computility.module.external.controller.enums.ErrorCodeConstants.APPID_ERROR_NOT_EXISTS;
/**
* 外部应用鉴权信息 Service 实现类
*
* @author 芋道源码
*/
@Service
@Validated
public class AppCredentialsServiceImpl implements AppCredentialsService {
@Resource
private AppCredentialsMapper appCredentialsMapper;
@Override
public Long createAppCredentials(AppCredentialsSaveReqVO createReqVO) {
// 插入
AppCredentialsDO appCredentials = BeanUtils.toBean(createReqVO, AppCredentialsDO.class);
appCredentialsMapper.insert(appCredentials);
// 返回
return appCredentials.getId();
}
@Override
public void updateAppCredentials(AppCredentialsSaveReqVO updateReqVO) {
// 校验存在
validateAppCredentialsExists(updateReqVO.getId());
// 更新
AppCredentialsDO updateObj = BeanUtils.toBean(updateReqVO, AppCredentialsDO.class);
appCredentialsMapper.updateById(updateObj);
}
@Override
public void deleteAppCredentials(Long id) {
// 校验存在
validateAppCredentialsExists(id);
// 删除
appCredentialsMapper.deleteById(id);
}
private void validateAppCredentialsExists(Long id) {
if (appCredentialsMapper.selectById(id) == null) {
}
}
@Override
public AppCredentialsDO getAppCredentials(Long id) {
return appCredentialsMapper.selectById(id);
}
@Override
public PageResult<AppCredentialsDO> getAppCredentialsPage(AppCredentialsPageReqVO pageReqVO) {
return appCredentialsMapper.selectPage(pageReqVO);
}
@Override
public String getAppSecretByAppid(String appId) {
AppCredentialsDO appCredentialsDO = appCredentialsMapper.selectOne(Wrappers.<AppCredentialsDO>lambdaQuery()
.eq(AppCredentialsDO::getAppId, appId));
if (ObjectUtil.isEmpty(appCredentialsDO)) {
throw new ServiceException(APPID_ERROR_NOT_EXISTS);
}
return appCredentialsDO.getAppSecret();
}
}
\ No newline at end of file
package com.luhu.computility.module.external.service.file;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.module.external.controller.admin.file.vo.AiGeneratedFilePageReqVO;
import com.luhu.computility.module.external.controller.admin.file.vo.AiGeneratedFileSaveReqVO;
import com.luhu.computility.module.external.dal.dataobject.file.AiGeneratedFileDO;
import com.luhu.computility.module.external.controller.admin.file.vo.AiGeneratedFilePageReqVO;
import com.luhu.computility.module.external.controller.admin.file.vo.AiGeneratedFileSaveReqVO;
import com.luhu.computility.module.external.dal.dataobject.file.AiGeneratedFileDO;
import javax.validation.Valid;
import java.util.List;
/**
* ai换脸-生成文件 Service 接口
*
* @author 智慧导览
*/
public interface AiGeneratedFileService {
/**
* 创建ai换脸-生成文件
*
* @param createReqVO 创建信息
* @return 编号
*/
Integer createAiGeneratedFile(@Valid AiGeneratedFileSaveReqVO createReqVO);
/**
* 更新ai换脸-生成文件
*
* @param updateReqVO 更新信息
*/
void updateAiGeneratedFile(@Valid AiGeneratedFileSaveReqVO updateReqVO);
/**
* 删除ai换脸-生成文件
*
* @param id 编号
*/
void deleteAiGeneratedFile(Integer id);
/**
* 获得ai换脸-生成文件
*
* @param id 编号
* @return ai换脸-生成文件
*/
AiGeneratedFileDO getAiGeneratedFile(Integer id);
/**
* 获得ai换脸-生成文件分页
*
* @param pageReqVO 分页查询
* @return ai换脸-生成文件分页
*/
PageResult<AiGeneratedFileDO> getAiGeneratedFilePage(AiGeneratedFilePageReqVO pageReqVO);
/**
* 获得ai换脸-生成文件
*
* @param promptId 任务编号
* @return ai换脸-生成文件
*/
AiGeneratedFileDO getAiGeneratedFileByPromptId(String promptId);
List<AiGeneratedFileDO> getAiGeneratedFileByStatus(Integer status);
//开始上传
void startUploadTask();
}
\ No newline at end of file
package com.luhu.computility.module.external.service.file;
import cn.hutool.core.io.IoUtil;
import com.luhu.computility.framework.common.exception.ServiceException;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.common.util.object.BeanUtils;
import com.luhu.computility.module.external.controller.admin.file.vo.AiGeneratedFilePageReqVO;
import com.luhu.computility.module.external.controller.admin.file.vo.AiGeneratedFileSaveReqVO;
import com.luhu.computility.module.external.controller.enums.AiGeneratedFileStatus;
import com.luhu.computility.module.external.controller.enums.AiGeneratedFileType;
import com.luhu.computility.module.external.dal.dataobject.file.AiGeneratedFileDO;
import com.luhu.computility.module.external.dal.mysql.file.AiGeneratedFileMapper;
import com.luhu.computility.module.infra.api.file.FileApi;
import com.luhu.computility.module.external.controller.admin.file.vo.AiGeneratedFilePageReqVO;
import com.luhu.computility.module.external.controller.admin.file.vo.AiGeneratedFileSaveReqVO;
import com.luhu.computility.module.external.controller.enums.AiGeneratedFileStatus;
import com.luhu.computility.module.external.controller.enums.AiGeneratedFileType;
import com.luhu.computility.module.external.controller.enums.ErrorCodeConstants;
import com.luhu.computility.module.external.dal.dataobject.file.AiGeneratedFileDO;
import com.luhu.computility.module.external.dal.mysql.file.AiGeneratedFileMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StreamUtils;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* ai换脸-生成文件 Service 实现类
*
* @author 智慧导览
*/
@Service
@Validated
public class AiGeneratedFileServiceImpl implements AiGeneratedFileService {
private static final Logger log = LoggerFactory.getLogger(AiGeneratedFileServiceImpl.class);
@Resource
private AiGeneratedFileMapper aiGeneratedFileMapper;
@Autowired
private FileApi fileApi;
private final BlockingQueue<AiGeneratedFileDO> uploadQueue = new LinkedBlockingQueue<>();
@Resource(name = "videoUploadExecutor")
private Executor executor;
private final AtomicBoolean isUploading = new AtomicBoolean(false);
@Override
public Integer createAiGeneratedFile(AiGeneratedFileSaveReqVO createReqVO) {
// 插入
AiGeneratedFileDO aiGeneratedFile = BeanUtils.toBean(createReqVO, AiGeneratedFileDO.class);
aiGeneratedFileMapper.insert(aiGeneratedFile);
// 返回
return aiGeneratedFile.getId();
}
@Override
public void updateAiGeneratedFile(AiGeneratedFileSaveReqVO updateReqVO) {
// 校验存在
validateAiGeneratedFileExists(updateReqVO.getId());
// 更新
AiGeneratedFileDO updateObj = BeanUtils.toBean(updateReqVO, AiGeneratedFileDO.class);
aiGeneratedFileMapper.updateById(updateObj);
}
@Override
public void deleteAiGeneratedFile(Integer id) {
// 校验存在
validateAiGeneratedFileExists(id);
// 删除
aiGeneratedFileMapper.deleteById(id);
}
private void validateAiGeneratedFileExists(Integer id) {
if (aiGeneratedFileMapper.selectById(id) == null) {
throw new ServiceException(ErrorCodeConstants.AI_GENERATED_FILE_NOT_EXISTS);
}
}
@Override
public AiGeneratedFileDO getAiGeneratedFile(Integer id) {
return aiGeneratedFileMapper.selectById(id);
}
@Override
public PageResult<AiGeneratedFileDO> getAiGeneratedFilePage(AiGeneratedFilePageReqVO pageReqVO) {
return aiGeneratedFileMapper.selectPage(pageReqVO);
}
@Override
public AiGeneratedFileDO getAiGeneratedFileByPromptId(String promptId) {
return aiGeneratedFileMapper.getAiGeneratedFileByPromptId(promptId);
}
@Override
public List<AiGeneratedFileDO> getAiGeneratedFileByStatus(Integer status) {
return aiGeneratedFileMapper.getAiGeneratedFileByStatus(status);
}
@Override
public void startUploadTask() {
if (isUploading.get()) {
return;
}
List<AiGeneratedFileDO> aiGeneratedFileDOList = aiGeneratedFileMapper.selectPendingTasks();
if (CollectionUtils.isEmpty(aiGeneratedFileDOList)) {
return;
}
uploadQueue.addAll(aiGeneratedFileDOList);
isUploading.set(true);
executor.execute(this::processQueue); // 启动上传
}
//开始执行队列
private void processQueue() {
try {
while (!uploadQueue.isEmpty()) {
AiGeneratedFileDO aiGeneratedFileDO = uploadQueue.poll();
if (aiGeneratedFileDO != null) {
try {
String fileUrl = aiGeneratedFileDO.getOriginalUrl();
aiGeneratedFileDO.setStatus(AiGeneratedFileStatus.UPLOADING.getValue());
aiGeneratedFileMapper.updateById(aiGeneratedFileDO);
// 1. 下载到临时文件
String fileName = getFileNameFromUrl(fileUrl);
File tempFile = File.createTempFile("oss-", getFileExtension(fileName));
System.out.println("存放的路径:"+tempFile.getAbsolutePath());
InputStream in = new URL(fileUrl).openStream();
OutputStream out = new FileOutputStream(tempFile);
StreamUtils.copy(in, out);
// 2. 通过 InputStream 上传到 OSS
InputStream uploadStream = new FileInputStream(tempFile);
String ossUrl = fileApi.createFile(IoUtil.readBytes(uploadStream));
aiGeneratedFileDO.setUrl(ossUrl);
if (aiGeneratedFileDO.getType().intValue() == AiGeneratedFileType.VIDEO.getValue()) {
aiGeneratedFileDO.setCoverImage(ossUrl + "?x-oss-process=video/snapshot,t_0,f_jpg,w_0,h_0");
} else if (aiGeneratedFileDO.getType().intValue() == AiGeneratedFileType.IMAGE.getValue()) {
aiGeneratedFileDO.setCoverImage(ossUrl + "?x-oss-process=image/resize,p_30");
}
log.error(aiGeneratedFileDO.getCoverImage());
aiGeneratedFileDO.setStatus(AiGeneratedFileStatus.FINISHED.getValue());
// 3. 删除本地临时文件
boolean deleted = tempFile.delete();
if (!deleted) {
log.error("删除临时文件失败:{}", tempFile.getAbsolutePath());
}
} catch (Exception e) {
aiGeneratedFileDO.setStatus(AiGeneratedFileStatus.FAILED.getValue());
//task.setErrorMsg(e.getMessage());
log.error("上传失败,任务ID:{},错误:{}", aiGeneratedFileDO.getId(), e.getMessage(), e);
} finally {
aiGeneratedFileMapper.updateById(aiGeneratedFileDO);
}
}
}
} finally {
isUploading.set(false);
}
}
private String getFileNameFromUrl(String url) {
return url.substring(url.lastIndexOf("/") + 1);
}
private String getFileExtension(String fileName) {
int idx = fileName.lastIndexOf(".");
return (idx != -1) ? fileName.substring(idx) : ".tmp";
}
}
\ No newline at end of file
package com.luhu.computility.module.external.web.config;
import com.luhu.computility.framework.swagger.config.ComputilitySwaggerAutoConfiguration;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* external 模块的 web 组件的 Configuration
*
* @author ljq
*/
@Configuration(proxyBeanMethods = false)
public class ExternalWebConfiguration {
/**
* external 模块的 API 分组
*/
@Bean
public GroupedOpenApi externalGroupedOpenApi() {
return ComputilitySwaggerAutoConfiguration.buildGroupedOpenApiAuthBySign("external");
}
}
package com.luhu.computility.module.external.web.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @version 1.0
* @Author ljq
* @Date 2025/6/17
* @注释
*/
@Configuration
public class ThreadPoolConfig {
/*
@Bean(name = "videoUploadExecutor")
public ExecutorService videoUploadExecutor() {
//监控线程池状态
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(1);
executor.setMaxPoolSize(3);
executor.setQueueCapacity(10);
executor.setThreadNamePrefix("video-upload-");
executor.initialize();
return Executors.newSingleThreadExecutor();
}*/
public static final String VIDEO_UPLOAD_EXECUTOR = "videoUploadExecutor";
@Bean(VIDEO_UPLOAD_EXECUTOR)
public ThreadPoolTaskExecutor videoUploadExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(1); // 单线程
executor.setMaxPoolSize(1); // 最大线程数
executor.setQueueCapacity(100); // 可根据实际设置
executor.setThreadNamePrefix("video-upload-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
executor.initialize();
return executor;
}
}
/**
* infra 模块的 web 配置
*/
package com.luhu.computility.module.external.web;
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>$com.luhu</groupId>
<artifactId>$computility-module-external</artifactId>
<version>$2.6.0-jdk8-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
package $com.luhu;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{
System.out.println( "Hello World!" );
}
}
package $com.luhu;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Unit test for simple App.
*/
public class AppTest
extends TestCase
{
/**
* Create the test case
*
* @param testName name of the test case
*/
public AppTest( String testName )
{
super( testName );
}
/**
* @return the suite of tests being tested
*/
public static Test suite()
{
return new TestSuite( AppTest.class );
}
/**
* Rigourous Test :-)
*/
public void testApp()
{
assertTrue( true );
}
}
......@@ -129,21 +129,22 @@ public class FileController {
@Operation(summary = "购买PDF 文件预览")
@PermitAll
public void previewPdf(HttpServletResponse response) throws IOException {
// 假设 path = /data/xxx.pdf
File file = new File("/data/buy.pdf");
File file = new File("/Users/jackey/data/code/buy.pdf");
if (!file.exists()) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return;
}
// 设置 PDF 预览
response.setContentType("application/pdf");
// inline 表示浏览器内嵌预览,attachment 表示下载
response.setHeader("Content-Disposition", "inline; filename=\"" + file.getName() + "\"");
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // 避免缓存
response.setHeader("Pragma", "no-cache");
response.setHeader("Expires", "0");
// 输出文件流
try (InputStream inputStream = new FileInputStream(file);
OutputStream os = response.getOutputStream()) {
byte[] buffer = new byte[4096];
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
os.write(buffer, 0, bytesRead);
......
......@@ -37,6 +37,8 @@ public class SecurityConfiguration {
.requestMatchers(adminSeverContextPath + "/**").permitAll();
// 文件读取
registry.requestMatchers(buildAdminApi("/infra/file/*/get/**")).permitAll();
//模型返回数据转发
registry.requestMatchers(buildOpenApi("/external/**")).permitAll();
}
};
......
......@@ -41,11 +41,11 @@
<!-- 数据报表。默认注释,保证编译速度 -->
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-module-report</artifactId>
<version>${revision}</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.luhu</groupId>-->
<!-- <artifactId>computility-module-report</artifactId>-->
<!-- <version>${revision}</version>-->
<!-- </dependency>-->
<!-- 工作流。默认注释,保证编译速度 -->
<!-- <dependency>-->
<!-- <groupId>com.luhu</groupId>-->
......@@ -92,6 +92,16 @@
<artifactId>computility-module-biz</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-module-apihub</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-module-external</artifactId>
<version>${revision}</version>
</dependency>
<!-- CRM 相关模块。默认注释,保证编译速度 -->
......
......@@ -108,7 +108,7 @@ aj:
cache-number: 1000 # local 缓存的阈值,达到这个值,清除缓存
timing-clear: 180 # local定时清除过期缓存(单位秒),设置为0代表不执行
type: blockPuzzle # 验证码类型 default两种都实例化。 blockPuzzle 滑块拼图 clickWord 文字点选
water-mark: 芋道源码 # 右下角水印文字(我的水印),可使用 https://tool.chinaz.com/tools/unicode.aspx 中文转 Unicode,Linux 可能需要转 unicode
water-mark: 普惠算力 # 右下角水印文字(我的水印),可使用 https://tool.chinaz.com/tools/unicode.aspx 中文转 Unicode,Linux 可能需要转 unicode
interference-options: 0 # 滑动干扰项(0/1/2)
req-frequency-limit-enable: false # 接口请求次数一分钟限制是否开启 true|false
req-get-lock-limit: 5 # 验证失败 5 次,get接口锁定
......@@ -279,6 +279,7 @@ computility:
ignore-urls:
- /jmreport/* # 积木报表,无法携带租户编号
- /admin-api/infra/file/preview
- /open-api/external/**
ignore-visit-urls:
- /admin-api/system/user/profile/**
- /admin-api/system/auth/**
......@@ -329,6 +330,8 @@ computility:
- rep_demo_employee
- rep_demo_gongsi
- rep_demo_jianpiao
- external_app_credentials
- external_file
ignore-caches:
- user_role_ids
- permission_menu_ids
......@@ -351,6 +354,13 @@ computility:
receive-expire-time: 14d # 收货的过期时间
comment-expire-time: 7d # 评论的过期时间
status-sync-to-wxa-enable: true # 是否同步订单状态到微信小程序
api:
order:
pay-expire-time: 2h # 支付的过期时间
receive-expire-time: 14d # 收货的过期时间
comment-expire-time: 7d # 评论的过期时间
status-sync-to-wxa-enable: true # 是否同步订单状态到微信小程序
express:
client: kd_100
kd-niao:
......@@ -364,4 +374,49 @@ computility:
debug: false
# 插件配置 TODO 芋艿:【IOT】需要处理下
pf4j:
pluginsDir: /Users/anhaohao/code/gitee/ruoyi-vue-pro/plugins # 插件目录
\ No newline at end of file
pluginsDir: /Users/anhaohao/code/gitee/ruoyi-vue-pro/plugins # 插件目录
digital-human-zhuxi:
conversation: http://117.157.192.95:8081/zx/llm/chat_sse
token: Basic emh1eGlAdHhnOndBSmNETDRMZVZ3QjlhdlV1OVJN
similar-image:
base-url: http://117.157.192.95:8082/appDemo
match-mage: ${similar-image.base-url}/matchImage
swap-face:
base-url: http://117.157.192.95:8082/appDemo
upload-image: ${swap-face.base-url}/uploadFaceSwapImage
create-video-stream: ${swap-face.base-url}/reActorFaceSwap
view-video: ${swap-face.base-url}/viewVideo
image-to-video: ${swap-face.base-url}/generateFaceSwap
image-to-image: ${swap-face.base-url}/generateImageFaceSwap
view-image: ${swap-face.base-url}/viewImg
AIQA-chat: ${swap-face.base-url}/v1/AIQA-chat
AIQA-stream-chat: ${swap-face.base-url}/v1/AIQA-stream-chat
aliyun-stream-chat: ${swap-face.base-url}/v1/aliyun-ai-chat
new-aigc:
base-url: http://117.157.192.95:8082/api
# 文生图v1
text-to-image-v1: ${new-aigc.base-url}/v1/t2i/txt2Img
# 获取生图进度
progress: ${new-aigc.base-url}/v1/t2i/progress
# 预测
predict: ${new-aigc.base-url}/v1/t2i/run/predict
# 获取藏头诗图片v1
poetry-v1: ${new-aigc.base-url}/v1/t2i/getPoetryImg
# 文生图v2(其岸)
text-to-image-v2: ${new-aigc.base-url}/v2/t2i/txt2Img/
# 获取藏头诗图片v2
poetry-v2: ${new-aigc.base-url}/v2/t2i/getPoetryImg
text-to-image:
base-url: http://218.77.58.8:8189/api
season: ${text-to-image.base-url}/v2/t2i/txt2Img/
file-name: ${text-to-image.base-url}/user/images/
poetry: ${text-to-image.base-url}/v2/t2i/getPoetryImg
\ No newline at end of file
......@@ -17,11 +17,13 @@
<module>computility-module-infra</module>
<module>computility-module-member</module>
<!-- <module>computility-module-bpm</module>-->
<module>computility-module-report</module>
<!-- <module>computility-module-report</module>-->
<!-- <module>computility-module-mp</module>-->
<module>computility-module-pay</module>
<module>computility-module-mall</module>
<module>computility-module-biz</module>
<module>computility-module-apihub</module>
<module>computility-module-external</module>
<!-- <module>computility-module-crm</module>-->
<!-- <module>computility-module-erp</module>-->
<!-- <module>computility-module-iot</module>-->
......
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