chore: demo fixed-code opt-in flag, sop tweaks and doc sync
短信固定验证码增加 aihr.sms.demo-fixed-code-enabled 显式开关(prod 默认仍禁用,演示环境可显式放行);SOP 服务小调整;mobile base 支持 VITE_BASE;作战清单/TechSpec/API_INTEGRATION/docs README 同步。
This commit is contained in:
@@ -62,11 +62,14 @@ public class CaptchaController {
|
||||
|
||||
/**
|
||||
* 演示/开发兜底:配置后不真发短信,验证码固定为该值,把短信通道从演示关键路径摘掉。
|
||||
* prod profile 下无条件忽略(代码级闸门,防止配置失误造成登录绕过)。
|
||||
* prod profile 仅在 aihr.sms.demo-fixed-code-enabled=true 时临时放行。
|
||||
*/
|
||||
@Value("${aihr.sms.dev-fixed-code:}")
|
||||
private String smsDevFixedCode;
|
||||
|
||||
@Value("${aihr.sms.demo-fixed-code-enabled:false}")
|
||||
private boolean smsDemoFixedCodeEnabled;
|
||||
|
||||
private final Environment environment;
|
||||
|
||||
/**
|
||||
@@ -80,7 +83,9 @@ public class CaptchaController {
|
||||
@NotBlank(message = "{user.phonenumber.not.blank}")
|
||||
@Pattern(regexp = RegexConstants.MOBILE, message = "{user.mobile.phone.number.not.valid}") String phonenumber) {
|
||||
String key = GlobalConstants.CAPTCHA_CODE_KEY + phonenumber;
|
||||
if (StringUtils.isNotBlank(smsDevFixedCode) && !environment.acceptsProfiles(Profiles.of("prod"))) {
|
||||
boolean fixedCodeEnabled = StringUtils.isNotBlank(smsDevFixedCode)
|
||||
&& (!environment.acceptsProfiles(Profiles.of("prod")) || smsDemoFixedCodeEnabled);
|
||||
if (fixedCodeEnabled) {
|
||||
log.warn("aihr.sms.dev-fixed-code 已启用,短信验证码走固定码,未真实发送短信");
|
||||
RedisUtils.setCacheObject(key, smsDevFixedCode, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
|
||||
return R.ok();
|
||||
|
||||
+11
-5
@@ -111,7 +111,7 @@ public class AihrSopSeedService {
|
||||
SopSeed seed = seeds.getOrDefault(requestedCategory, seeds.get("投诉处理 SOP"));
|
||||
String category = isBlank(requestedCategory) ? seed.category() : requestedCategory;
|
||||
String queryText = request == null || request.queryText() == null || request.queryText().isBlank() ? seed.question() : request.queryText();
|
||||
SearchResponse dbResponse = dbSearch(category, queryText, request == null ? null : request.limit());
|
||||
SearchResponse dbResponse = dbSearch(dbCategory(category), queryText, request == null ? null : request.limit());
|
||||
if (dbResponse != null && !dbResponse.snippets().isEmpty()) {
|
||||
return dbResponse;
|
||||
}
|
||||
@@ -1613,7 +1613,7 @@ public class AihrSopSeedService {
|
||||
join aihr_knowledge_info i on i.id = f.knowledge_id and i.tenant_id = f.tenant_id
|
||||
left join aihr_knowledge_attach a on a.knowledge_id = f.knowledge_id and a.doc_id = f.doc_id and a.tenant_id = f.tenant_id
|
||||
where f.tenant_id = ?
|
||||
and i.name = ?
|
||||
and (? = '' or i.name = ?)
|
||||
and match(f.content) against (? in natural language mode)
|
||||
order by score desc, f.idx asc
|
||||
limit ?
|
||||
@@ -1625,7 +1625,7 @@ public class AihrSopSeedService {
|
||||
rs.getString("content"),
|
||||
rs.getInt("idx"),
|
||||
rs.getDouble("score")
|
||||
), queryText, TENANT_ID, category, queryText, limit);
|
||||
), queryText, TENANT_ID, category, category, queryText, limit);
|
||||
}
|
||||
|
||||
private List<KnowledgeHit> likeHits(String category, String queryText, int limit) {
|
||||
@@ -1651,7 +1651,7 @@ public class AihrSopSeedService {
|
||||
join aihr_knowledge_info i on i.id = f.knowledge_id and i.tenant_id = f.tenant_id
|
||||
left join aihr_knowledge_attach a on a.knowledge_id = f.knowledge_id and a.doc_id = f.doc_id and a.tenant_id = f.tenant_id
|
||||
where f.tenant_id = ?
|
||||
and i.name = ?
|
||||
and (? = '' or i.name = ?)
|
||||
and (%s)
|
||||
order by score desc, f.idx asc
|
||||
limit ?
|
||||
@@ -1660,6 +1660,7 @@ public class AihrSopSeedService {
|
||||
terms.stream().map(AihrSopSeedService::likePattern).forEach(args::add);
|
||||
args.add(TENANT_ID);
|
||||
args.add(category);
|
||||
args.add(category);
|
||||
terms.stream().map(AihrSopSeedService::likePattern).forEach(args::add);
|
||||
args.add(limit);
|
||||
return jdbcTemplate.query(sql, (rs, rowNum) -> new KnowledgeHit(
|
||||
@@ -1727,6 +1728,7 @@ public class AihrSopSeedService {
|
||||
|
||||
private static SearchResponse responseFromHits(String category, String queryText, List<KnowledgeHit> hits) {
|
||||
KnowledgeHit first = hits.get(0);
|
||||
String responseCategory = isBlank(category) ? first.category() : category;
|
||||
List<SnippetResponse> snippets = hits.stream()
|
||||
.map(hit -> new SnippetResponse("第 " + hit.idx() + " 段:" + hit.title(), hit.content()))
|
||||
.toList();
|
||||
@@ -1736,7 +1738,7 @@ public class AihrSopSeedService {
|
||||
}
|
||||
return new SearchResponse(
|
||||
queryText,
|
||||
category,
|
||||
responseCategory,
|
||||
"根据已入库 SOP:" + first.content(),
|
||||
"引用 " + docs.size() + " 份文档 / " + snippets.size() + " 个片段",
|
||||
List.copyOf(docs.values()),
|
||||
@@ -1746,6 +1748,10 @@ public class AihrSopSeedService {
|
||||
);
|
||||
}
|
||||
|
||||
private static String dbCategory(String category) {
|
||||
return "sop".equalsIgnoreCase(Optional.ofNullable(category).orElse("").trim()) ? "" : category;
|
||||
}
|
||||
|
||||
private static int limitValue(Integer limit) {
|
||||
if (limit == null) {
|
||||
return 3;
|
||||
|
||||
Reference in New Issue
Block a user