chore: initialize qiming workspace repository
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>app-platform-subscription</artifactId>
|
||||
<groupId>com.xspaceagi</groupId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>app-platform-subscription-web</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.xspaceagi</groupId>
|
||||
<artifactId>app-platform-subscription-application</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.xspaceagi</groupId>
|
||||
<artifactId>app-platform-subscription-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.xspaceagi</groupId>
|
||||
<artifactId>app-platform-agent-core-sdk</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.xspaceagi</groupId>
|
||||
<artifactId>app-platform-bill-sdk</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,132 @@
|
||||
package com.xspaceagi.subscription.web.controller;
|
||||
|
||||
import com.xspaceagi.agent.core.sdk.IAgentRpcService;
|
||||
import com.xspaceagi.agent.core.sdk.dto.AgentInfoDto;
|
||||
import com.xspaceagi.subscription.app.service.SubscriptionPlanAppService;
|
||||
import com.xspaceagi.subscription.app.service.UserSubscriptionAppService;
|
||||
import com.xspaceagi.subscription.sdk.dto.PlanDTO;
|
||||
import com.xspaceagi.subscription.sdk.dto.PlanQueryRequest;
|
||||
import com.xspaceagi.subscription.sdk.dto.SubscriptionStatsDTO;
|
||||
import com.xspaceagi.subscription.sdk.dto.SubscriptionStatsQueryRequest;
|
||||
import com.xspaceagi.subscription.spec.enums.BizTypeEnum;
|
||||
import com.xspaceagi.subscription.web.controller.dto.SortUpdateDTO;
|
||||
import com.xspaceagi.system.sdk.permission.SpacePermissionService;
|
||||
import com.xspaceagi.system.spec.dto.ReqResult;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/api/agent/plan")
|
||||
@Tag(name = "智能体订阅计划管理")
|
||||
public class AgentPlanManController {
|
||||
|
||||
@Resource
|
||||
private SubscriptionPlanAppService subscriptionPlanAppService;
|
||||
|
||||
@Resource
|
||||
private UserSubscriptionAppService userSubscriptionAppService;
|
||||
|
||||
@Resource
|
||||
private IAgentRpcService iAgentRpcService;
|
||||
|
||||
@Resource
|
||||
private SpacePermissionService spacePermissionService;
|
||||
|
||||
@GetMapping("/subscription/stats")
|
||||
@Operation(summary = "查询智能体订阅统计")
|
||||
public ReqResult<SubscriptionStatsDTO> getSubscriptionStats(
|
||||
@RequestParam Long agentId,
|
||||
@RequestParam(defaultValue = "1") Integer pageNum,
|
||||
@RequestParam(defaultValue = "20") Integer pageSize) {
|
||||
checkAgentPermission(agentId);
|
||||
SubscriptionStatsQueryRequest request = new SubscriptionStatsQueryRequest();
|
||||
request.setBizType(BizTypeEnum.AGENT);
|
||||
request.setBizId(agentId.toString());
|
||||
request.setPageNum(pageNum);
|
||||
request.setPageSize(pageSize);
|
||||
return ReqResult.success(userSubscriptionAppService.getSubscriptionStats(request));
|
||||
}
|
||||
|
||||
@PostMapping(value = "/create")
|
||||
@Operation(summary = "添加订阅计划")
|
||||
public ReqResult<Long> createPlan(@RequestBody PlanDTO dto) {
|
||||
Assert.notNull(dto.getBizId(), "智能体ID不能为空");
|
||||
dto.setBizType(BizTypeEnum.AGENT);
|
||||
checkAgentPermission(Long.parseLong(dto.getBizId()));
|
||||
return ReqResult.success(subscriptionPlanAppService.createPlan(dto));
|
||||
}
|
||||
|
||||
@PostMapping(value = "/update")
|
||||
@Operation(summary = "修改订阅计划")
|
||||
public ReqResult<Boolean> updatePlan(@RequestBody PlanDTO dto) {
|
||||
Assert.notNull(dto.getId(), "计划ID不能为空");
|
||||
dto.setBizId(null);
|
||||
dto.setBizType(BizTypeEnum.AGENT);
|
||||
PlanDTO planById = subscriptionPlanAppService.getPlanById(dto.getId());
|
||||
Assert.isTrue(planById != null && planById.getBizType() == BizTypeEnum.AGENT, "计划不存在");
|
||||
checkAgentPermission(Long.parseLong(planById.getBizId()));
|
||||
return ReqResult.success(subscriptionPlanAppService.updatePlan(dto));
|
||||
}
|
||||
|
||||
@PostMapping(value = "/sort/update")
|
||||
@Operation(summary = "修改订阅计划排序")
|
||||
public ReqResult<Void> updatePlanSort(@RequestBody List<SortUpdateDTO> updateDTOS) {
|
||||
updateDTOS.forEach(updateDTO -> {
|
||||
PlanDTO planById = subscriptionPlanAppService.getPlanById(updateDTO.getId());
|
||||
Assert.isTrue(planById != null && planById.getBizType() == BizTypeEnum.AGENT, "计划不存在");
|
||||
checkAgentPermission(Long.parseLong(planById.getBizId()));
|
||||
PlanDTO dto = new PlanDTO();
|
||||
dto.setId(updateDTO.getId());
|
||||
dto.setSort(updateDTO.getSort());
|
||||
subscriptionPlanAppService.updatePlan(dto);
|
||||
});
|
||||
return ReqResult.success();
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "查询订阅计划列表")
|
||||
public ReqResult<List<PlanDTO>> listPlans(
|
||||
@RequestParam Long agentId,
|
||||
@RequestParam(required = false) Integer status,
|
||||
@RequestParam(required = false) String keyword) {
|
||||
PlanQueryRequest query = new PlanQueryRequest();
|
||||
query.setBizType(BizTypeEnum.AGENT);
|
||||
query.setBizId(agentId.toString());
|
||||
query.setStatus(status);
|
||||
query.setKeyword(keyword);
|
||||
return ReqResult.success(subscriptionPlanAppService.listPlans(query));
|
||||
}
|
||||
|
||||
@PostMapping("/{id}/offline")
|
||||
@Operation(summary = "下架订阅计划")
|
||||
public ReqResult<Boolean> offlinePlan(@PathVariable Long id) {
|
||||
PlanDTO planById = subscriptionPlanAppService.getPlanById(id);
|
||||
Assert.isTrue(planById != null && planById.getBizType() == BizTypeEnum.AGENT, "计划不存在");
|
||||
checkAgentPermission(Long.parseLong(planById.getBizId()));
|
||||
return ReqResult.success(subscriptionPlanAppService.offlinePlan(id));
|
||||
}
|
||||
|
||||
@PostMapping("/{id}/delete")
|
||||
@Operation(summary = "删除订阅计划")
|
||||
public ReqResult<Boolean> deletePlan(@PathVariable Long id) {
|
||||
PlanDTO planById = subscriptionPlanAppService.getPlanById(id);
|
||||
Assert.isTrue(planById != null && planById.getBizType() == BizTypeEnum.AGENT, "计划不存在");
|
||||
checkAgentPermission(Long.parseLong(planById.getBizId()));
|
||||
return ReqResult.success(subscriptionPlanAppService.deletePlan(id));
|
||||
}
|
||||
|
||||
private void checkAgentPermission(Long agentId) {
|
||||
com.xspaceagi.agent.core.sdk.dto.ReqResult<List<AgentInfoDto>> listReqResult = iAgentRpcService.queryAgentInfoList(List.of(agentId));
|
||||
if (listReqResult.getData() == null || listReqResult.getData().isEmpty()) {
|
||||
throw new IllegalArgumentException("错误的智能体ID");
|
||||
}
|
||||
spacePermissionService.checkSpaceUserPermission(listReqResult.getData().get(0).getSpaceId());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
package com.xspaceagi.subscription.web.controller;
|
||||
|
||||
import com.xspaceagi.agent.core.sdk.IAgentRpcService;
|
||||
import com.xspaceagi.agent.core.sdk.dto.AgentInfoDto;
|
||||
import com.xspaceagi.agent.core.sdk.dto.SkillInfoDto;
|
||||
import com.xspaceagi.bill.sdk.dto.CreateOrderRequest;
|
||||
import com.xspaceagi.bill.sdk.dto.OrderDTO;
|
||||
import com.xspaceagi.bill.sdk.rpc.IBillRpcService;
|
||||
import com.xspaceagi.bill.spec.enums.TargetTypeEnum;
|
||||
import com.xspaceagi.subscription.api.rpc.SubscriptionRpcService;
|
||||
import com.xspaceagi.subscription.app.service.SubscriptionPlanAppService;
|
||||
import com.xspaceagi.subscription.app.service.UserSubscriptionAppService;
|
||||
import com.xspaceagi.subscription.sdk.dto.*;
|
||||
import com.xspaceagi.subscription.spec.enums.BizTypeEnum;
|
||||
import com.xspaceagi.subscription.web.controller.dto.MySubscriptionDTO;
|
||||
import com.xspaceagi.system.application.util.DefaultIconUrlUtil;
|
||||
import com.xspaceagi.system.spec.common.RequestContext;
|
||||
import com.xspaceagi.system.spec.dto.ReqResult;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/api/subscription")
|
||||
@Tag(name = "用户订阅相关接口")
|
||||
public class SubscriptionController {
|
||||
|
||||
@Resource
|
||||
private UserSubscriptionAppService userSubscriptionAppService;
|
||||
|
||||
@Resource
|
||||
private SubscriptionPlanAppService subscriptionPlanAppService;
|
||||
|
||||
@Resource
|
||||
private SubscriptionRpcService subscriptionRpcService;
|
||||
|
||||
@Resource
|
||||
private IBillRpcService iBillRpcService;
|
||||
|
||||
@Resource
|
||||
private IAgentRpcService iAgentRpcService;
|
||||
|
||||
@PostMapping("/order/create")
|
||||
@Operation(summary = "创建订阅订单")
|
||||
public ReqResult<OrderDTO> createOrder(@RequestParam Long planId) {
|
||||
PlanDTO planDTO = subscriptionPlanAppService.getPlanById(planId);
|
||||
if (planDTO == null) {
|
||||
return ReqResult.error("Invalid planId");
|
||||
}
|
||||
if (planDTO.getPrice().compareTo(BigDecimal.ZERO) <= 0) {
|
||||
RequestContext<Object> ctx = RequestContext.get();
|
||||
CreateSubscriptionRequest request = new CreateSubscriptionRequest();
|
||||
request.setTenantId(ctx.getTenantId());
|
||||
request.setUserId(ctx.getUserId());
|
||||
request.setPlanId(planId);
|
||||
request.setBizType(planDTO.getBizType());
|
||||
request.setExtra(Map.of("plan", planDTO));
|
||||
subscriptionRpcService.createSubscription(request);
|
||||
return ReqResult.success();
|
||||
}
|
||||
CreateOrderRequest request = new CreateOrderRequest();
|
||||
request.setTenantId(RequestContext.get().getTenantId());
|
||||
request.setUserId(RequestContext.get().getUserId());
|
||||
request.setDescription("订阅[" + planDTO.getName() + "]");
|
||||
request.setBizType(com.xspaceagi.bill.spec.enums.BizTypeEnum.SUBSCRIPTION);
|
||||
CreateOrderRequest.CreateOrderItem item = new CreateOrderRequest.CreateOrderItem();
|
||||
item.setTargetName(planDTO.getName());
|
||||
item.setTargetType(TargetTypeEnum.PLAN.getCode());
|
||||
item.setTargetId(planDTO.getId());
|
||||
item.setPrice(planDTO.getPrice());
|
||||
item.setCount(1);
|
||||
item.setSnapshot(Map.of("plan", planDTO));
|
||||
request.setItems(List.of(item));
|
||||
OrderDTO order = iBillRpcService.createOrder(request);
|
||||
return ReqResult.success(order);
|
||||
}
|
||||
|
||||
@GetMapping("/system/plans")
|
||||
@Operation(summary = "查询可订阅的系统计划列表")
|
||||
public ReqResult<List<PlanDTO>> listPlans() {
|
||||
PlanQueryRequest query = new PlanQueryRequest();
|
||||
query.setBizType(BizTypeEnum.SYSTEM);
|
||||
query.setBizId(null);
|
||||
query.setStatus(1);
|
||||
return ReqResult.success(subscriptionPlanAppService.listPlans(query));
|
||||
}
|
||||
|
||||
@GetMapping("/my")
|
||||
@Operation(summary = "查询我的订阅")
|
||||
public ReqResult<MySubscriptionDTO> getMySubscriptions(@RequestParam(required = false) BizTypeEnum bizType, @RequestParam(required = false) String bizId) {
|
||||
SubscriptionQueryRequest query = new SubscriptionQueryRequest();
|
||||
query.setUserId(RequestContext.get().getUserId());
|
||||
query.setBizType(bizType);
|
||||
query.setBizId(bizId);
|
||||
if (bizType == null) {
|
||||
query.setBizType(BizTypeEnum.SYSTEM);
|
||||
query.setBizId(null);
|
||||
}
|
||||
List<UserSubscriptionDTO> subscriptions = userSubscriptionAppService.getUserSubscriptions(query);
|
||||
MySubscriptionDTO dto = new MySubscriptionDTO();
|
||||
dto.setSubscriptions(subscriptions);
|
||||
if (bizType == BizTypeEnum.SYSTEM || StringUtils.isNotBlank(bizId)) {
|
||||
dto.setCurrentSubscription(subscriptions.stream().findFirst().orElse(null));
|
||||
}
|
||||
if (bizType == BizTypeEnum.AGENT && CollectionUtils.isNotEmpty(subscriptions)) {
|
||||
List<Long> agentIds = subscriptions.stream().map(subscriptionDTO -> Long.parseLong(subscriptionDTO.getBizId())).collect(Collectors.toList());
|
||||
Map<Long, AgentInfoDto> agentInfoDtoMap = iAgentRpcService.queryAgentInfoList(agentIds).getData().stream().collect(Collectors.toMap(AgentInfoDto::getId, agentInfoDto -> agentInfoDto, (a, b) -> a));
|
||||
subscriptions.forEach(subscriptionDTO -> {
|
||||
AgentInfoDto agentInfoDto = agentInfoDtoMap.get(Long.parseLong(subscriptionDTO.getBizId()));
|
||||
if (agentInfoDto != null) {
|
||||
subscriptionDTO.setBizName(agentInfoDto.getName());
|
||||
subscriptionDTO.setIcon(DefaultIconUrlUtil.setDefaultIconUrl(agentInfoDto.getIcon(), agentInfoDto.getName(), "agent"));
|
||||
}
|
||||
});
|
||||
}
|
||||
if (bizType == BizTypeEnum.SKILL && CollectionUtils.isNotEmpty(subscriptions)) {
|
||||
subscriptions.forEach(subscriptionDTO -> {
|
||||
SkillInfoDto publishedSkillInfo = iAgentRpcService.getPublishedSkillInfo(Long.parseLong(subscriptionDTO.getBizId()), null).getData();
|
||||
if (publishedSkillInfo != null) {
|
||||
subscriptionDTO.setBizName(publishedSkillInfo.getName());
|
||||
subscriptionDTO.setIcon(DefaultIconUrlUtil.setDefaultIconUrl(publishedSkillInfo.getIcon(), publishedSkillInfo.getName(), "skill"));
|
||||
}
|
||||
});
|
||||
}
|
||||
return ReqResult.success(dto);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package com.xspaceagi.subscription.web.controller;
|
||||
|
||||
import com.xspaceagi.subscription.app.service.SubscriptionPlanAppService;
|
||||
import com.xspaceagi.subscription.app.service.UserSubscriptionAppService;
|
||||
import com.xspaceagi.subscription.sdk.dto.PlanDTO;
|
||||
import com.xspaceagi.subscription.sdk.dto.PlanQueryRequest;
|
||||
import com.xspaceagi.subscription.sdk.dto.SubscriptionStatsDTO;
|
||||
import com.xspaceagi.subscription.sdk.dto.SubscriptionStatsQueryRequest;
|
||||
import com.xspaceagi.subscription.spec.enums.BizTypeEnum;
|
||||
import com.xspaceagi.subscription.web.controller.dto.SortUpdateDTO;
|
||||
import com.xspaceagi.system.spec.annotation.RequireResource;
|
||||
import com.xspaceagi.system.spec.dto.ReqResult;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.xspaceagi.system.spec.enums.ResourceEnum.*;
|
||||
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/api/system/plan")
|
||||
@Tag(name = "系统订阅计划管理")
|
||||
public class SystemPlanManController {
|
||||
|
||||
@Resource
|
||||
private SubscriptionPlanAppService subscriptionPlanAppService;
|
||||
|
||||
@Resource
|
||||
private UserSubscriptionAppService userSubscriptionAppService;
|
||||
|
||||
@RequireResource(SUBSCRIPTION_POINTS_QUERY)
|
||||
@GetMapping("/subscription/stats")
|
||||
@Operation(summary = "查询指定对象的订阅统计")
|
||||
public ReqResult<SubscriptionStatsDTO> getSubscriptionStats(
|
||||
@RequestParam BizTypeEnum bizType,
|
||||
@RequestParam String bizId,
|
||||
@RequestParam(defaultValue = "1") Integer pageNum,
|
||||
@RequestParam(defaultValue = "20") Integer pageSize) {
|
||||
SubscriptionStatsQueryRequest request = new SubscriptionStatsQueryRequest();
|
||||
request.setBizType(bizType);
|
||||
request.setBizId(bizId);
|
||||
request.setPageNum(pageNum);
|
||||
request.setPageSize(pageSize);
|
||||
return ReqResult.success(userSubscriptionAppService.getSubscriptionStats(request));
|
||||
}
|
||||
|
||||
@RequireResource(SUBSCRIPTION_POINTS_MODIFY)
|
||||
@PostMapping(value = "/create")
|
||||
@Operation(summary = "添加订阅计划")
|
||||
public ReqResult<Long> createPlan(@RequestBody PlanDTO dto) {
|
||||
dto.setBizType(BizTypeEnum.SYSTEM);
|
||||
return ReqResult.success(subscriptionPlanAppService.createPlan(dto));
|
||||
}
|
||||
|
||||
@RequireResource(SUBSCRIPTION_POINTS_MODIFY)
|
||||
@PostMapping(value = "/update")
|
||||
@Operation(summary = "修改订阅计划")
|
||||
public ReqResult<Boolean> updatePlan(@RequestBody PlanDTO dto) {
|
||||
return ReqResult.success(subscriptionPlanAppService.updatePlan(dto));
|
||||
}
|
||||
|
||||
@RequireResource(SUBSCRIPTION_POINTS_MODIFY)
|
||||
@PostMapping(value = "/sort/update")
|
||||
@Operation(summary = "修改订阅计划排序")
|
||||
public ReqResult<Void> updatePlanSort(@RequestBody List<SortUpdateDTO> updateDTOS) {
|
||||
updateDTOS.forEach(updateDTO -> {
|
||||
PlanDTO dto = new PlanDTO();
|
||||
dto.setId(updateDTO.getId());
|
||||
dto.setSort(updateDTO.getSort());
|
||||
subscriptionPlanAppService.updatePlan(dto);
|
||||
});
|
||||
return ReqResult.success();
|
||||
}
|
||||
|
||||
@RequireResource(SUBSCRIPTION_POINTS_QUERY)
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "查询订阅计划列表")
|
||||
public ReqResult<List<PlanDTO>> listPlans(
|
||||
@RequestParam(required = false) Integer status,
|
||||
@RequestParam(required = false) String keyword) {
|
||||
PlanQueryRequest query = new PlanQueryRequest();
|
||||
query.setBizType(BizTypeEnum.SYSTEM);
|
||||
query.setStatus(status);
|
||||
query.setKeyword(keyword);
|
||||
return ReqResult.success(subscriptionPlanAppService.listPlans(query));
|
||||
}
|
||||
|
||||
@RequireResource(SUBSCRIPTION_POINTS_MODIFY)
|
||||
@PostMapping("/{id}/offline")
|
||||
@Operation(summary = "下架订阅计划")
|
||||
public ReqResult<Boolean> offlinePlan(@PathVariable Long id) {
|
||||
return ReqResult.success(subscriptionPlanAppService.offlinePlan(id));
|
||||
}
|
||||
|
||||
@RequireResource(SUBSCRIPTION_POINTS_DELETE)
|
||||
@PostMapping("/{id}/delete")
|
||||
@Operation(summary = "删除订阅计划")
|
||||
public ReqResult<Boolean> deletePlan(@PathVariable Long id) {
|
||||
return ReqResult.success(subscriptionPlanAppService.deletePlan(id));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.xspaceagi.subscription.web.controller.dto;
|
||||
|
||||
import com.xspaceagi.subscription.sdk.dto.UserSubscriptionDTO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class MySubscriptionDTO {
|
||||
|
||||
@Schema(description = "当前订阅")
|
||||
private UserSubscriptionDTO currentSubscription;
|
||||
|
||||
@Schema(description = "所有订阅")
|
||||
private List<UserSubscriptionDTO> subscriptions;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.xspaceagi.subscription.web.controller.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class SortUpdateDTO {
|
||||
|
||||
private Long id;
|
||||
private Integer sort;
|
||||
}
|
||||
Reference in New Issue
Block a user