feat: implement campaign rule management infrastructure including criteria models, services, and tooling support
This commit is contained in:
@@ -4,7 +4,8 @@ import static org.springframework.security.oauth2.client.web.client.RequestAttri
|
||||
import static org.springframework.security.oauth2.client.web.client.RequestAttributePrincipalResolver.principal;
|
||||
|
||||
import org.springframework.http.HttpStatusCode;
|
||||
import dev.sonpx.loyalty.mcp.reward.client.RewardClient;
|
||||
import dev.sonpx.loyalty.mcp.reward.client.CampaignClient;
|
||||
import dev.sonpx.loyalty.mcp.reward.client.CampaignRuleClient;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -20,13 +21,13 @@ import org.springframework.web.service.invoker.HttpServiceProxyFactory;
|
||||
* Created by SonPhung on Sunday, 19-Jul-2026
|
||||
**/
|
||||
@Configuration
|
||||
public class ClientConfig {
|
||||
public class RestClientConfig {
|
||||
|
||||
@Value("${loyalty.core.base-url}")
|
||||
private String coreBaseUrl;
|
||||
|
||||
@Bean
|
||||
public RestClient rewardReClient(OAuth2AuthorizedClientManager authorizedClientManager) {
|
||||
public RestClient rewardRestClient(OAuth2AuthorizedClientManager authorizedClientManager) {
|
||||
OAuth2ClientHttpRequestInterceptor oauth2Interceptor =
|
||||
new OAuth2ClientHttpRequestInterceptor(authorizedClientManager);
|
||||
oauth2Interceptor.setClientRegistrationIdResolver(new RequestAttributeClientRegistrationIdResolver());
|
||||
@@ -50,15 +51,20 @@ public class ClientConfig {
|
||||
|
||||
|
||||
@Bean
|
||||
public HttpServiceProxyFactory httpServiceProxyFactory(RestClient rewardReClient) {
|
||||
return HttpServiceProxyFactory.builderFor(RestClientAdapter.create(rewardReClient))
|
||||
public HttpServiceProxyFactory rewardHttpServiceProxyFactory(RestClient rewardRestClient) {
|
||||
return HttpServiceProxyFactory.builderFor(RestClientAdapter.create(rewardRestClient))
|
||||
.customArgumentResolver(new PageableArgumentResolver())
|
||||
.customArgumentResolver(new PojoArgumentResolver())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RewardClient rewardClient(HttpServiceProxyFactory httpServiceProxyFactory) {
|
||||
return httpServiceProxyFactory.createClient(RewardClient.class);
|
||||
public CampaignClient campaignClient(HttpServiceProxyFactory rewardHttpServiceProxyFactory) {
|
||||
return rewardHttpServiceProxyFactory.createClient(CampaignClient.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CampaignRuleClient campaignRuleClient(HttpServiceProxyFactory rewardHttpServiceProxyFactory) {
|
||||
return rewardHttpServiceProxyFactory.createClient(CampaignRuleClient.class);
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ import lombok.Data;
|
||||
* Created by SonPhung on Monday, 20-Jul-2026
|
||||
*/
|
||||
@Data
|
||||
public abstract class AbstractFwCriteria implements FwCriteria {
|
||||
public abstract class AbstractFwCriteria {
|
||||
|
||||
protected StringFilter status;
|
||||
protected RangeFilter<Instant> lastUpdateDate;
|
||||
@@ -31,8 +31,4 @@ public abstract class AbstractFwCriteria implements FwCriteria {
|
||||
this.search = search;
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract String[] getColumns();
|
||||
|
||||
protected abstract String[] getComponentColumns();
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
|
||||
package dev.sonpx.loyalty.mcp.criteria;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
|
||||
|
||||
/**
|
||||
* Created by SonPhung on Tuesday, 10-Oct-2023
|
||||
*/
|
||||
@JsonIgnoreProperties(value = {"columns", "columnsComponent"})
|
||||
public interface FwCriteria {
|
||||
|
||||
}
|
||||
@@ -18,7 +18,7 @@ import org.springframework.web.service.annotation.PostExchange;
|
||||
* Created by SonPhung on Sunday, 19-Jul-2026
|
||||
**/
|
||||
@HttpExchange
|
||||
public interface RewardClient {
|
||||
public interface CampaignClient {
|
||||
|
||||
@GetExchange("/api/campaign/csr/list")
|
||||
List<Campaign> getAll(CampaignCriteria criteria, Pageable pageable);
|
||||
@@ -0,0 +1,43 @@
|
||||
package dev.sonpx.loyalty.mcp.reward.client;
|
||||
|
||||
import dev.sonpx.loyalty.mcp.model.OperationResult;
|
||||
import dev.sonpx.loyalty.mcp.reward.criteria.CampaignRuleCriteria;
|
||||
import dev.sonpx.loyalty.mcp.reward.model.CampaignRule;
|
||||
import jakarta.validation.Valid;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.service.annotation.GetExchange;
|
||||
import org.springframework.web.service.annotation.HttpExchange;
|
||||
import org.springframework.web.service.annotation.PostExchange;
|
||||
|
||||
/**
|
||||
* Created by SonPhung on Sunday, 19-Jul-2026
|
||||
**/
|
||||
@HttpExchange
|
||||
public interface CampaignRuleClient {
|
||||
|
||||
@GetExchange("/api/campaign-rule/csr/list")
|
||||
List<CampaignRule> getAll(CampaignRuleCriteria criteria, Pageable pageable);
|
||||
|
||||
@GetExchange("/api/campaign-rule/csr/count")
|
||||
Long count(CampaignRuleCriteria criteria);
|
||||
|
||||
@GetExchange("/api/campaign-rule/csr/id/{id}")
|
||||
CampaignRule findActiveById(@PathVariable String id);
|
||||
|
||||
@GetExchange("/api/campaign-rule/csr/id")
|
||||
List<CampaignRule> findActiveByIds(@RequestParam Map<String, String> params);
|
||||
|
||||
@GetExchange("/api/campaign-rule/csr/id/generate")
|
||||
String generateId();
|
||||
|
||||
@GetExchange("/api/campaign-rule/csr/id/check/{id}")
|
||||
String checkId(@PathVariable String id);
|
||||
|
||||
@PostExchange("/api/campaign-rule/csr/create")
|
||||
OperationResult<CampaignRule> create(@Valid @RequestBody CampaignRule dto);
|
||||
}
|
||||
@@ -27,8 +27,4 @@ public class CampaignCriteria extends AbstractFwCriteria {
|
||||
|
||||
@JsonPropertyDescription("Bộ lọc theo Loại chiến dịch (ví dụ: POINT, VOUCHER, v.v.)")
|
||||
private StringFilter campaignType;
|
||||
|
||||
// for search text and component
|
||||
private String[] componentColumns = {"campaign_id", "name"};
|
||||
private String[] columns = {"description"};
|
||||
}
|
||||
|
||||
@@ -21,9 +21,4 @@ public class CampaignRuleCriteria extends AbstractFwCriteria {
|
||||
private LocalDateTimeFilter effectiveTo;
|
||||
private StringFilter ruleType;
|
||||
private StringFilter poolId;
|
||||
|
||||
// for search text and component
|
||||
private String[] componentColumns = {"rule_id", "rule_name"};
|
||||
private String[] columns = {"campaign_id", "description"};
|
||||
|
||||
}
|
||||
|
||||
@@ -15,10 +15,4 @@ public class ComponentCriteria extends AbstractFwCriteria {
|
||||
private StringFilter key;
|
||||
private StringFilter code;
|
||||
private StringFilter name;
|
||||
|
||||
// for search text
|
||||
private String[] componentColumns = {"code", "name"};
|
||||
private String[] columns = {};
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -26,9 +26,4 @@ public class CounterDefinitionCriteria extends AbstractFwCriteria {
|
||||
private LocalDateFilter firstStartDate;
|
||||
private StringFilter stateCounter;
|
||||
private StringFilter lateValuePosting;
|
||||
|
||||
// for search text
|
||||
private String[] componentColumns = {"counter_id", "counter_name"};
|
||||
private String[] columns = {"entity", "what_to_count"};
|
||||
|
||||
}
|
||||
|
||||
@@ -18,10 +18,4 @@ public class CurrencyRateCriteria extends AbstractFwCriteria {
|
||||
private StringFilter effectiveTo;
|
||||
private DoubleFilter buyRate;
|
||||
private DoubleFilter sellRate;
|
||||
|
||||
// for search text
|
||||
private String[] componentColumns = {"pcr_code"};
|
||||
private String[] columns = {};
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -15,10 +15,4 @@ public class DeductionSequencesCriteria extends AbstractFwCriteria {
|
||||
private LocalDateFilter effectiveFrom;
|
||||
private LocalDateFilter effectiveTo;
|
||||
private StringFilter isDefault;
|
||||
|
||||
// for search and component
|
||||
private String[] componentColumns = {"sequence_id", "sequence_name"};
|
||||
private String[] columns = {"description", "effective_from", "effective_to", "is_default"};
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -14,10 +14,4 @@ public class EventMaintenanceCriteria extends AbstractFwCriteria {
|
||||
|
||||
private StringFilter eventId;
|
||||
private StringFilter description;
|
||||
|
||||
// for search text
|
||||
private String[] componentColumns = {"event_id", "description"};
|
||||
private String[] columns = {};
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -14,10 +14,4 @@ public class PoolConversionRateCriteria extends AbstractFwCriteria {
|
||||
|
||||
private StringFilter code;
|
||||
private StringFilter description;
|
||||
|
||||
// for search text
|
||||
private String[] componentColumns = {"code", "description"};
|
||||
private String[] columns = {};
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -18,10 +18,4 @@ public class PoolDefinitionCriteria extends AbstractFwCriteria {
|
||||
private StringFilter entityLevel;
|
||||
private StringFilter expiryPolicy;
|
||||
private StringFilter atgGroupId;
|
||||
|
||||
// for search and component
|
||||
private String[] componentColumns = {"pool_id", "pool_name"};
|
||||
private String[] columns = {"description"};
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -14,10 +14,4 @@ public class StatementOutputPoolCriteria extends AbstractFwCriteria {
|
||||
|
||||
private StringFilter poolId;
|
||||
private StringFilter entityLevel;
|
||||
|
||||
// for search text
|
||||
private String[] componentColumns = {"pool_id"};
|
||||
private String[] columns = {"entity_level"};
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -15,10 +15,4 @@ public class TransactionCategoryCriteria extends AbstractFwCriteria {
|
||||
private StringFilter code;
|
||||
private StringFilter name;
|
||||
private StringFilter description;
|
||||
|
||||
// for search text and component
|
||||
private String[] componentColumns = {"code", "name"};
|
||||
private String[] columns = {};
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -16,10 +16,4 @@ public class TransactionCodeCriteria extends AbstractFwCriteria {
|
||||
private StringFilter code;
|
||||
private StringFilter description;
|
||||
private BooleanFilter reversalInd;
|
||||
|
||||
// for search text and component
|
||||
private String[] componentColumns = {"code", "description"};
|
||||
private String[] columns = {"reversal_ind"};
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
package dev.sonpx.loyalty.mcp.reward.enums;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
import java.util.Arrays;
|
||||
import lombok.Getter;
|
||||
@@ -13,7 +14,11 @@ import lombok.RequiredArgsConstructor;
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public enum BaseDateType {
|
||||
|
||||
@JsonPropertyDescription("Ngày hệ thống ghi nhận giao dịch")
|
||||
POST_DATE("PD"),
|
||||
|
||||
@JsonPropertyDescription("Ngày khách hàng thực hiện giao dịch")
|
||||
TRANSACTION_DATE("TD");
|
||||
|
||||
@JsonValue
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
package dev.sonpx.loyalty.mcp.reward.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
@@ -13,5 +14,6 @@ import lombok.Setter;
|
||||
public class CampaignCriteria extends Fw {
|
||||
|
||||
@NotBlank
|
||||
@JsonPropertyDescription("Cấu hình các tiêu chí có định dạng json")
|
||||
private String criteria;
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ public class CampaignRule extends Fw {
|
||||
private Boolean notUpdatePool;
|
||||
|
||||
@Valid
|
||||
@JsonPropertyDescription("Danh sách liên kết điều khoản (T&C)")
|
||||
@JsonPropertyDescription("Danh sách liên kết Transaction Code")
|
||||
private List<CampaignTcLinkage> campaignTcLinkages;
|
||||
|
||||
/**
|
||||
@@ -107,11 +107,9 @@ public class CampaignRule extends Fw {
|
||||
@JsonPropertyDescription("Mã sản phẩm/quà tặng")
|
||||
private ReferenceData itemCode;
|
||||
|
||||
// Aplly the first criterion satified in Formula 10
|
||||
@JsonPropertyDescription("Chỉ áp dụng tiêu chí đầu tiên thỏa mãn trong Formula 10")
|
||||
private Boolean attrApplyFirstFlag;
|
||||
|
||||
// Aplly the first criterion satified in Formula 11
|
||||
@JsonPropertyDescription("Chỉ áp dụng tiêu chí đầu tiên thỏa mãn trong Formula 11")
|
||||
private Boolean segApplyFirstFlag;
|
||||
|
||||
@@ -128,7 +126,7 @@ public class CampaignRule extends Fw {
|
||||
private CampaignFormulaOne campaignFormulaOne;
|
||||
|
||||
@Valid
|
||||
@JsonPropertyDescription("Cấu hình Formula 2")
|
||||
@JsonPropertyDescription("Cấu hình Formula 2, Thưởng điểm theo giá trị cố định")
|
||||
private CampaignFormulaTwo campaignFormulaTwo;
|
||||
|
||||
@Valid
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
package dev.sonpx.loyalty.mcp.service;
|
||||
|
||||
import dev.sonpx.loyalty.mcp.model.OperationResult;
|
||||
import dev.sonpx.loyalty.mcp.model.Result;
|
||||
import dev.sonpx.loyalty.mcp.reward.client.CampaignRuleClient;
|
||||
import dev.sonpx.loyalty.mcp.reward.criteria.CampaignRuleCriteria;
|
||||
import dev.sonpx.loyalty.mcp.reward.model.CampaignRule;
|
||||
import dev.sonpx.loyalty.mcp.util.MarkdownGenerator;
|
||||
import java.util.List;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* Created by SonPhung on Monday, 20-Jul-2026
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class CampaignRuleService {
|
||||
|
||||
private final CampaignRuleClient campaignRuleClient;
|
||||
|
||||
public Result<List<CampaignRule>> getAll(CampaignRuleCriteria criteria) {
|
||||
try {
|
||||
List<CampaignRule> rules = campaignRuleClient.getAll(criteria, Pageable.ofSize(10));
|
||||
return Result.of(rules, MarkdownGenerator.generateCampaignRuleMD(rules));
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.of(null);
|
||||
}
|
||||
}
|
||||
|
||||
public Result<Long> count(CampaignRuleCriteria criteria) {
|
||||
try {
|
||||
Long count = campaignRuleClient.count(criteria);
|
||||
return Result.of(count, MarkdownGenerator.generateCampaignRuleMD(count));
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.of(null);
|
||||
}
|
||||
}
|
||||
|
||||
public Result<CampaignRule> findActiveById(String id) {
|
||||
try {
|
||||
CampaignRule rule = campaignRuleClient.findActiveById(id);
|
||||
return Result.of(rule, MarkdownGenerator.generateCampaignRuleMD(rule));
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.of(null);
|
||||
}
|
||||
}
|
||||
|
||||
public Result<List<CampaignRule>> findActiveByIds(String ids) {
|
||||
try {
|
||||
List<CampaignRule> rules = campaignRuleClient.findActiveByIds(java.util.Map.of("id", ids));
|
||||
return Result.of(rules, MarkdownGenerator.generateCampaignRuleMD(rules));
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.of(null);
|
||||
}
|
||||
}
|
||||
|
||||
public Result<String> generateId() {
|
||||
try {
|
||||
String id = campaignRuleClient.generateId();
|
||||
return Result.of(id, MarkdownGenerator.generateCampaignRuleIdMD(id));
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.of(null);
|
||||
}
|
||||
}
|
||||
|
||||
public Result<String> checkId(String id) {
|
||||
try {
|
||||
String checkResult = campaignRuleClient.checkId(id);
|
||||
return Result.of(checkResult, MarkdownGenerator.generateCheckResultMD(checkResult));
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.of(null);
|
||||
}
|
||||
}
|
||||
|
||||
public Result<OperationResult<CampaignRule>> create(CampaignRule dto) {
|
||||
try {
|
||||
OperationResult<CampaignRule> opResult = campaignRuleClient.create(dto);
|
||||
return Result.of(opResult, MarkdownGenerator.generateCampaignRuleOperationResultMD(opResult));
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.of(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import static dev.sonpx.loyalty.mcp.util.MarkdownGenerator.generateCampaignMD;
|
||||
|
||||
import dev.sonpx.loyalty.mcp.model.OperationResult;
|
||||
import dev.sonpx.loyalty.mcp.model.Result;
|
||||
import dev.sonpx.loyalty.mcp.reward.client.RewardClient;
|
||||
import dev.sonpx.loyalty.mcp.reward.client.CampaignClient;
|
||||
import dev.sonpx.loyalty.mcp.reward.criteria.CampaignCriteria;
|
||||
import dev.sonpx.loyalty.mcp.reward.model.Campaign;
|
||||
import dev.sonpx.loyalty.mcp.util.MarkdownGenerator;
|
||||
@@ -22,11 +22,11 @@ import org.springframework.stereotype.Service;
|
||||
@RequiredArgsConstructor
|
||||
public class CampaignService {
|
||||
|
||||
private final RewardClient rewardClient;
|
||||
private final CampaignClient campaignClient;
|
||||
|
||||
public Result<List<Campaign>> getAll(CampaignCriteria criteria) {
|
||||
try {
|
||||
List<Campaign> campaigns = rewardClient.getAll(criteria, Pageable.ofSize(10));
|
||||
List<Campaign> campaigns = campaignClient.getAll(criteria, Pageable.ofSize(10));
|
||||
|
||||
return Result.of(campaigns, generateCampaignMD(campaigns));
|
||||
} catch (Exception e) {
|
||||
@@ -37,7 +37,7 @@ public class CampaignService {
|
||||
|
||||
public Result<Long> count(CampaignCriteria criteria) {
|
||||
try {
|
||||
Long count = rewardClient.count(criteria);
|
||||
Long count = campaignClient.count(criteria);
|
||||
return Result.of(count, MarkdownGenerator.generateCampaignMD(count));
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
@@ -47,7 +47,7 @@ public class CampaignService {
|
||||
|
||||
public Result<Campaign> findActiveById(String id) {
|
||||
try {
|
||||
Campaign campaign = rewardClient.findActiveById(id);
|
||||
Campaign campaign = campaignClient.findActiveById(id);
|
||||
return Result.of(campaign, MarkdownGenerator.generateCampaignMD(campaign));
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
@@ -57,7 +57,7 @@ public class CampaignService {
|
||||
|
||||
public Result<List<Campaign>> findActiveByIds(String ids) {
|
||||
try {
|
||||
List<Campaign> campaigns = rewardClient.findActiveByIds(java.util.Map.of("id", ids));
|
||||
List<Campaign> campaigns = campaignClient.findActiveByIds(java.util.Map.of("id", ids));
|
||||
return Result.of(campaigns, MarkdownGenerator.generateCampaignMD(campaigns));
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
@@ -67,7 +67,7 @@ public class CampaignService {
|
||||
|
||||
public Result<String> generateId() {
|
||||
try {
|
||||
String id = rewardClient.generateId();
|
||||
String id = campaignClient.generateId();
|
||||
return Result.of(id, MarkdownGenerator.generateCampaignIdMD(id));
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
@@ -77,7 +77,7 @@ public class CampaignService {
|
||||
|
||||
public Result<String> checkId(String id) {
|
||||
try {
|
||||
String checkResult = rewardClient.checkId(id);
|
||||
String checkResult = campaignClient.checkId(id);
|
||||
return Result.of(checkResult, MarkdownGenerator.generateCheckResultMD(checkResult));
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
@@ -87,7 +87,7 @@ public class CampaignService {
|
||||
|
||||
public Result<OperationResult<Campaign>> create(Campaign dto) {
|
||||
try {
|
||||
OperationResult<Campaign> opResult = rewardClient.create(dto);
|
||||
OperationResult<Campaign> opResult = campaignClient.create(dto);
|
||||
return Result.of(opResult, MarkdownGenerator.generateOperationResultMD(opResult));
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package dev.sonpx.loyalty.mcp.tool;
|
||||
|
||||
import dev.sonpx.loyalty.mcp.model.OperationResult;
|
||||
import dev.sonpx.loyalty.mcp.model.Result;
|
||||
import dev.sonpx.loyalty.mcp.reward.criteria.CampaignRuleCriteria;
|
||||
import dev.sonpx.loyalty.mcp.reward.model.CampaignRule;
|
||||
import dev.sonpx.loyalty.mcp.service.CampaignRuleService;
|
||||
import java.util.List;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.ai.mcp.annotation.McpTool;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Created by SonPhung on Monday, 20-Jul-2026
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class CampaignRuleTools {
|
||||
|
||||
private final CampaignRuleService campaignRuleService;
|
||||
|
||||
@McpTool(description = "Lấy danh sách các Campaign Rule, cho phép tìm kiếm với param search, hiển thị tối đa 10 bản ghi")
|
||||
public Result<List<CampaignRule>> campaignRules(String search) {
|
||||
CampaignRuleCriteria criteria = new CampaignRuleCriteria();
|
||||
criteria.setSearch(search);
|
||||
return campaignRuleService.getAll(criteria);
|
||||
}
|
||||
|
||||
@McpTool(description = "Đếm số lượng Campaign Rule, cho phép tìm kiếm với param search")
|
||||
public Result<Long> countCampaignRules(String search) {
|
||||
CampaignRuleCriteria criteria = new CampaignRuleCriteria();
|
||||
criteria.setSearch(search);
|
||||
return campaignRuleService.count(criteria);
|
||||
}
|
||||
|
||||
@McpTool(description = "Lấy thông tin chi tiết một Campaign Rule theo ID")
|
||||
public Result<CampaignRule> getCampaignRuleById(String id) {
|
||||
return campaignRuleService.findActiveById(id);
|
||||
}
|
||||
|
||||
@McpTool(description = "Lấy thông tin nhiều Campaign Rule theo danh sách ID, phân tách bằng dấu phẩy")
|
||||
public Result<List<CampaignRule>> getCampaignRulesByIds(String ids) {
|
||||
return campaignRuleService.findActiveByIds(ids);
|
||||
}
|
||||
|
||||
@McpTool(description = "Tạo một ID Campaign Rule mới")
|
||||
public Result<String> generateCampaignRuleId() {
|
||||
return campaignRuleService.generateId();
|
||||
}
|
||||
|
||||
@McpTool(description = "Kiểm tra trạng thái hoặc tính hợp lệ của một ID Campaign Rule")
|
||||
public Result<String> checkCampaignRuleId(String id) {
|
||||
return campaignRuleService.checkId(id);
|
||||
}
|
||||
|
||||
@McpTool(description = "Tạo một Campaign Rule mới")
|
||||
public Result<OperationResult<CampaignRule>> createCampaignRule(CampaignRule dto) {
|
||||
return campaignRuleService.create(dto);
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ import org.springframework.stereotype.Component;
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class ApiMcpTools {
|
||||
public class CampaignTools {
|
||||
|
||||
private final CampaignService campaignService;
|
||||
|
||||
@@ -2,6 +2,7 @@ package dev.sonpx.loyalty.mcp.util;
|
||||
|
||||
import dev.sonpx.loyalty.mcp.model.OperationResult;
|
||||
import dev.sonpx.loyalty.mcp.reward.model.Campaign;
|
||||
import dev.sonpx.loyalty.mcp.reward.model.CampaignRule;
|
||||
import java.util.List;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
@@ -60,6 +61,65 @@ public class MarkdownGenerator {
|
||||
return "Campaign ID: " + id;
|
||||
}
|
||||
|
||||
public static String generateCampaignRuleMD(CampaignRule rule) {
|
||||
if (rule == null) {
|
||||
return "No campaign rule data available.";
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("### 📜 Campaign Rule Details\n\n");
|
||||
sb.append("| Field | Value |\n");
|
||||
sb.append("| :--- | :--- |\n");
|
||||
sb.append("| **Rule ID** | ").append(rule.getRuleId()).append(" |\n");
|
||||
sb.append("| **Name** | ").append(rule.getRuleName()).append(" |\n");
|
||||
if (rule.getRuleType() != null) {
|
||||
sb.append("| **Type** | ").append(rule.getRuleType()).append(" |\n");
|
||||
}
|
||||
if (rule.getCampaignId() != null) {
|
||||
sb.append("| **Campaign ID** | ").append(rule.getCampaignId().getCode()).append(" |\n");
|
||||
}
|
||||
if (rule.getDescription() != null) {
|
||||
sb.append("| **Description** | ").append(rule.getDescription()).append(" |\n");
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String generateCampaignRuleMD(List<CampaignRule> rules) {
|
||||
if (CollectionUtils.isEmpty(rules)) {
|
||||
return "No campaign rules data available.";
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("### 📜 Campaign Rule List\n\n");
|
||||
sb.append("| Rule Id | Name | Type | Campaign Id | Description |\n");
|
||||
sb.append("| :--- | :--- | :--- | :--- | :--- |\n");
|
||||
|
||||
rules.forEach((rule) -> {
|
||||
sb.append("| ").append(rule.getRuleId());
|
||||
sb.append(" | ").append(rule.getRuleName());
|
||||
sb.append(" | ").append(rule.getRuleType() != null ? rule.getRuleType() : "");
|
||||
sb.append(" | ").append(rule.getCampaignId() != null ? rule.getCampaignId().getCode() : "");
|
||||
sb.append(" | ").append(rule.getDescription() != null ? rule.getDescription() : "").append(" |\n");
|
||||
});
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String generateCampaignRuleMD(Long count) {
|
||||
if (count == null) {
|
||||
return "Total campaign rules: 0";
|
||||
}
|
||||
return "Total campaign rules: " + count;
|
||||
}
|
||||
|
||||
public static String generateCampaignRuleIdMD(String id) {
|
||||
if (id == null) {
|
||||
return "No campaign rule ID available.";
|
||||
}
|
||||
return "Campaign Rule ID: " + id;
|
||||
}
|
||||
|
||||
public static String generateCheckResultMD(String result) {
|
||||
if (result == null) {
|
||||
return "No check result available.";
|
||||
@@ -85,4 +145,23 @@ public class MarkdownGenerator {
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String generateCampaignRuleOperationResultMD(OperationResult<CampaignRule> result) {
|
||||
if (result == null) {
|
||||
return "No operation result available.";
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if ("00".equals(result.getErrorCode()) || result.getErrorCode() == null) {
|
||||
sb.append("✅ Operation successful.\n\n");
|
||||
if (result.getEntity() != null) {
|
||||
sb.append(generateCampaignRuleMD(result.getEntity()));
|
||||
}
|
||||
} else {
|
||||
sb.append("❌ Operation failed.\n\n");
|
||||
sb.append("**Error Code:** ").append(result.getErrorCode()).append("\n");
|
||||
sb.append("**Message:** ").append(result.getMessage()).append("\n");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user