忽略本地配置文件

This commit is contained in:
francis-fh
2026-07-29 19:31:57 +08:00
parent 45289d5666
commit 0e675a1004
4 changed files with 4 additions and 1664 deletions

3
.gitignore vendored
View File

@@ -60,3 +60,6 @@ nbdist/
local.sh local.sh
.claude .claude
/test-reports/ /test-reports/
ruoyi-admin/src/main/resources/application-local.yml
ruoyi-bussiness/src/main/java/com/ruoyi/cms/service/impl/ESJobSearchImpl.java
ruoyi-bussiness/src/main/java/com/ruoyi/cms/service/impl/JobTitleSuggestServiceImpl.java

View File

@@ -1,158 +0,0 @@
# 项目相关配置
ruoyi:
# 名称
name: RuoYi
# 版本
version: 3.8.8
# 版权年份
copyrightYear: 2024
# 文件路径 示例( Windows配置D:/ruoyi/uploadPathLinux配置 /home/ruoyi/uploadPath
profile: /Users/chenyanchang/logs/ruoyi/uploadPath
# 获取ip地址开关
addressEnabled: false
# 验证码类型 math 数字计算 char 字符验证
captchaType: math
# 数据源配置
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.highgo.jdbc.Driver
druid:
# 主库数据源
# master:
# url: jdbc:highgo://124.243.245.42:5866/shz?useUnicode=true&characterEncoding=utf8&currentSchema=shz&stringtype=unspecified
# #username: syssso
# username: sysdba
# password: ZKR2024@comzkr
# 正式环境
# master:
# url: jdbc:highgo://39.98.44.136:6023/highgo?useUnicode=true&characterEncoding=utf8&currentSchema=shz&stringtype=unspecified
# username: sysdba
# password: Hello@2026
# 测试环境
master:
url: jdbc:highgo://47.111.103.66:5866/highgo?useUnicode=true&characterEncoding=utf8&currentSchema=shz&stringtype=unspecified
username: sysdba
password: Hello@2026
# 从库数据源
slave:
# 从数据源开关/默认关闭
enabled: false
url:
username:
password:
# 初始连接数
initialSize: 10
# 最小连接池数量
minIdle: 30
# 最大连接池数量
maxActive: 50
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置连接超时时间
connectTimeout: 30000
# 配置网络超时时间
socketTimeout: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
# 配置一个连接在池中最大生存的时间,单位是毫秒
maxEvictableIdleTimeMillis: 900000
# 配置检测连接是否有效
validationQuery: SELECT version()
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
webStatFilter:
enabled: true
statViewServlet:
enabled: true
# 设置白名单,不填则允许所有访问
allow:
url-pattern: /druid/*
# 控制台管理用户名和密码
login-username: ruoyi
login-password: 123456
filter:
stat:
enabled: true
# 慢SQL记录
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: true
wall:
config:
multi-statement-allow: true
redis:
# 本地
#host: 127.0.0.1
#port: 6379
host: 124.243.245.42
port: 5379
# 数据库索引
database: 0
# 密码(本地通常无密码)
password:
# 连接超时时间
timeout: 100s
lettuce:
pool:
# 连接池中的最小空闲连接
min-idle: 0
# 连接池中的最大空闲连接
max-idle: 8
# 连接池的最大数据库连接数
max-active: 8
# #连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
# easy-es
easy-es:
enable: true
banner: false
address: 124.243.245.42:9200
global-config:
process-index-mode: manual
db-config:
refresh-policy: immediate
username: elastic
password: zkr2024@@.com
#ai
chat:
baseUrl: http://39.98.44.136:8082
chatUrl: /v1/chat/completions
chatDetailUrl: /core/chat/getPaginationRecords
chatHistoryUrl: /core/chat/getHistories
updateNameUrl: /core/chat/updateHistory
stickChatUrl: /core/chat/updateHistory
delChatUrl: /core/chat/delHistory
delAllChatUrl: /core/chat/clearHistories
guestUrl: /v1/chat/completions
praiseUrl: /core/chat/feedback/updateUserFeedback
appId: 67cd49095e947ae0ca7fadd8
apiKey: fastgpt-qMl63276wPZvKAxEkW77bur0sSJpmuC6Ngg9lzyEjufLhsBAurjT55j
model: qd-job-turbo
audioText:
asr: http://127.0.0.1:8000/asr/file
tts: http://127.0.0.1:19527/synthesize
#浪潮单点登录相关
#互联网端:
lc_web_auth:
appId: cloud-out-2fb6330e9c0843e1a1424efda5d604c0
appSecret: x14lueHbtLQL7Pz2G7gE4wcGCV6TDblO5xfeu9V2wGk=
getTokenUrl: http://218.31.252.15:9081/prod-psout-api/auth/token
getUserInfoUrl: http://218.31.252.15:9081/prod-psout-api/system/app/authorize/user/info
editUserInfoUrl: http://218.31.252.15:9081/prod-psout-api/auth/user/edit
#监管端:
lc_cms_auth:
appId: cloud-9793ee8a8c3d47b8871007ffc4128502
appSecret: Yi+NACK70UPg8rFvsnnfBUq1wcLD4nm6ilC4II/4C4k=
getTokenUrl: http://218.31.252.15:9081/prod-api/auth/token
getUserInfoUrl: http://218.31.252.15:9081/prod-api/system/app/authorize/user/info
resrtPwdUrl: http://218.31.252.15:9081/prod-api/ps/user/resetPwd/zkr
changeStatusUrl: http://218.31.252.15:9081/prod-api/ps/user/change/status/zkr

View File

@@ -1,187 +0,0 @@
package com.ruoyi.cms.service.impl;
import com.ruoyi.cms.mapper.JobMapper;
import com.ruoyi.cms.service.IJobTitleSuggestService;
import com.ruoyi.cms.util.JobTitleSuggestTokenizer;
import com.ruoyi.common.core.redis.RedisCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* 岗位名称 IK 分词联想服务实现。
*/
@Service
public class JobTitleSuggestServiceImpl implements IJobTitleSuggestService {
private static final Logger logger = LoggerFactory.getLogger(JobTitleSuggestServiceImpl.class);
/**
* Redis Hashfield 是 IK 分词value 是包含该分词的完整岗位名称列表。
*/
private static final String CACHE_KEY = "app:job:title:suggest";
private static final String BUILDING_CACHE_KEY = CACHE_KEY + ":building";
private static final String LOCK_KEY = CACHE_KEY + ":rebuild:lock";
private static final int DEFAULT_LIMIT = 10;
private static final int MAX_LIMIT = 20;
private static final int LOCK_EXPIRE_MINUTES = 30;
@Autowired
private JobMapper jobMapper;
@Autowired
private RedisCache redisCache;
/**
* 确保服务启动后 Redis 中已有一份缓存;后续由 Quartz 定时任务周期性重建。
*/
@PostConstruct
public void init() {
rebuildCache();
}
@Override
public List<String> suggest(String keyword, Integer limit) {
String normalizedKeyword = JobTitleSuggestTokenizer.normalize(keyword);
if (normalizedKeyword.isEmpty()) {
return Collections.emptyList();
}
int resultLimit = normalizeLimit(limit);
try {
Map<String, Object> tokenTitles = redisCache.getCacheMap(CACHE_KEY);
if (tokenTitles == null || tokenTitles.isEmpty()) {
return Collections.emptyList();
}
// Hash field 只来自 IK 分词;这里仅对已有词项做前缀过滤,不生成新的前缀词。
List<Map.Entry<String, Object>> matchedTokens = tokenTitles.entrySet().stream()
.filter(entry -> entry.getKey() != null)
.filter(entry -> entry.getKey().startsWith(normalizedKeyword))
.sorted(Map.Entry.comparingByKey())
.collect(Collectors.toList());
Set<String> result = new LinkedHashSet<>();
for (Map.Entry<String, Object> entry : matchedTokens) {
if (result.size() >= resultLimit) {
break;
}
// 先返回匹配到的 IK 分词本身。
result.add(entry.getKey());
// 再返回包含该 IK 分词的完整岗位名称。
appendTitles(result, entry.getValue(), resultLimit);
}
return new ArrayList<>(result).subList(0, Math.min(result.size(), resultLimit));
} catch (Exception e) {
// 联想属于非核心能力Redis 异常时返回空列表,不影响岗位主搜索。
logger.warn("查询岗位名称 IK 分词缓存失败keyword={}", keyword, e);
return Collections.emptyList();
}
}
@Override
public void rebuildCache() {
String lockValue = UUID.randomUUID().toString();
boolean lockAcquired = false;
try {
lockAcquired = redisCache.setIfAbsent(
LOCK_KEY, lockValue, LOCK_EXPIRE_MINUTES, TimeUnit.MINUTES);
if (!lockAcquired) {
logger.info("其他节点正在重建岗位名称 IK 分词缓存,本节点跳过");
return;
}
List<String> sourceList = jobMapper.selectValidJobTitles();
Map<String, List<String>> cacheData = buildTokenTitles(sourceList);
// 先写临时 Hash再原子替换正式 Hash避免接口读到半成品。
redisCache.deleteObject(BUILDING_CACHE_KEY);
if (cacheData.isEmpty()) {
redisCache.deleteObject(CACHE_KEY);
} else {
redisCache.setCacheMap(BUILDING_CACHE_KEY, cacheData);
redisCache.redisTemplate.rename(BUILDING_CACHE_KEY, CACHE_KEY);
}
logger.info("岗位名称 IK 分词缓存重建完成,有效岗位名称{}个IK 词{}个",
sourceList == null ? 0 : sourceList.size(), cacheData.size());
} catch (Exception e) {
logger.error("重建岗位名称 IK 分词缓存失败", e);
} finally {
if (lockAcquired) {
redisCache.deleteObject(LOCK_KEY);
}
}
}
private Map<String, List<String>> buildTokenTitles(List<String> sourceList) {
Map<String, Set<String>> tokenTitles = new TreeMap<>();
if (sourceList == null) {
return Collections.emptyMap();
}
for (String title : sourceList) {
String displayTitle = normalizeDisplayTitle(title);
if (displayTitle.isEmpty()) {
continue;
}
Set<String> tokens = JobTitleSuggestTokenizer.tokenize(displayTitle);
for (String token : tokens) {
tokenTitles.computeIfAbsent(token, key -> new TreeSet<>()).add(displayTitle);
}
}
Map<String, List<String>> result = new LinkedHashMap<>();
for (Map.Entry<String, Set<String>> entry : tokenTitles.entrySet()) {
result.put(entry.getKey(), new ArrayList<>(entry.getValue()));
}
return result;
}
private void appendTitles(Set<String> result, Object cachedTitles, int resultLimit) {
if (!(cachedTitles instanceof Iterable)) {
return;
}
for (Object cachedTitle : (Iterable<?>) cachedTitles) {
if (cachedTitle == null || result.size() >= resultLimit) {
break;
}
String title = String.valueOf(cachedTitle);
if (!title.isEmpty()) {
result.add(title);
}
}
}
private String normalizeDisplayTitle(String title) {
if (title == null) {
return "";
}
return title.trim().replaceAll("\\s+", " ");
}
private int normalizeLimit(Integer limit) {
if (limit == null) {
return DEFAULT_LIMIT;
}
return Math.max(1, Math.min(limit, MAX_LIMIT));
}
}