BaseLangServiceImpl.java 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. package jnpf.base.service.impl;
  2. import cn.hutool.cache.CacheUtil;
  3. import cn.hutool.cache.impl.TimedCache;
  4. import cn.hutool.core.bean.BeanUtil;
  5. import com.alibaba.fastjson.JSONObject;
  6. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  7. import com.baomidou.mybatisplus.core.metadata.IPage;
  8. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  9. import com.google.common.collect.ImmutableList;
  10. import com.google.common.collect.Lists;
  11. import jnpf.base.Pagination;
  12. import jnpf.base.entity.BaseLangEntity;
  13. import jnpf.base.entity.DictionaryDataEntity;
  14. import jnpf.base.mapper.BaseLangMapper;
  15. import jnpf.base.model.language.BaseLangForm;
  16. import jnpf.base.model.language.BaseLangListVO;
  17. import jnpf.base.model.language.BaseLangPage;
  18. import jnpf.base.service.BaseLangService;
  19. import jnpf.base.service.DictionaryDataService;
  20. import jnpf.base.service.SuperServiceImpl;
  21. import jnpf.base.vo.PaginationVO;
  22. import jnpf.config.ConfigValueUtil;
  23. import jnpf.constant.ConfigConst;
  24. import jnpf.constant.GlobalConst;
  25. import jnpf.constant.MsgCode;
  26. import jnpf.consts.ProjectEventConst;
  27. import jnpf.event.ProjectEventListener;
  28. import jnpf.exception.DataException;
  29. import jnpf.i18n.config.I18nProperties;
  30. import jnpf.i18n.constant.I18nConst;
  31. import jnpf.module.ProjectEventBuilder;
  32. import jnpf.module.ProjectEventInstance;
  33. import jnpf.util.*;
  34. import lombok.Cleanup;
  35. import org.apache.commons.collections4.CollectionUtils;
  36. import org.apache.commons.collections4.MapUtils;
  37. import org.springframework.beans.factory.annotation.Autowired;
  38. import org.springframework.stereotype.Service;
  39. import java.io.File;
  40. import java.io.FileInputStream;
  41. import java.util.*;
  42. import java.util.concurrent.ConcurrentHashMap;
  43. import java.util.concurrent.TimeUnit;
  44. import java.util.concurrent.locks.ReentrantLock;
  45. import java.util.stream.Collectors;
  46. /**
  47. * 多语言
  48. *
  49. * @author JNPF开发平台组
  50. * @version v5.0.0
  51. * @copyright 引迈信息技术有限公司
  52. * @date 2024/4/28 16:05:49
  53. */
  54. @Service
  55. public class BaseLangServiceImpl extends SuperServiceImpl<BaseLangMapper, BaseLangEntity> implements BaseLangService {
  56. @Autowired
  57. private ConfigValueUtil configValueUtil;
  58. @Autowired
  59. private DictionaryDataService dictionaryDataApi;
  60. @Autowired
  61. private RedisUtil redisUtil;
  62. @Autowired
  63. private I18nProperties i18nProperties;
  64. // 未使用的情况下, 默认48小时失效, 使用后重新计算缓存时效 租户/语种/前端json
  65. private TimedCache<String, Map<String, String>> tenantMessageProperties = CacheUtil.newTimedCache(48 * 60 * 60000L);
  66. // 租户语言加载锁
  67. private final ConcurrentHashMap<String, ReentrantLock> lockMap = new ConcurrentHashMap<>();
  68. @Override
  69. public BaseLangListVO getList(Pagination pagination) {
  70. List<DictionaryDataEntity> langTypeList = dictionaryDataApi.getListByTypeDataCode(ConfigConst.BASE_LANGUAGE);
  71. String path = FileUploadUtils.getLocalBasePath() + configValueUtil.getBaseLanguagePath();
  72. List<Map<String, Object>> tableHead = new ArrayList<>();
  73. List<Map<String, String>> list = new ArrayList<>();
  74. List<Map<String, String>> resList = new ArrayList<>();
  75. tableHead.add(new HashMap() {{
  76. put("prop", "code");
  77. put("label", "翻译标记");
  78. }});
  79. //不同语言的转换map
  80. Map<String, LinkedHashMap<String, String>> langKeyMap = new HashMap<>();
  81. for (DictionaryDataEntity item : langTypeList) {
  82. tableHead.add(new HashMap() {{
  83. put("prop", item.getEnCode());
  84. put("label", item.getFullName());
  85. }});
  86. String filePath = path + "java/" + item.getEnCode() + ".json";
  87. LinkedHashMap<String, String> resMap = new LinkedHashMap<>();
  88. try {
  89. File file = new File(filePath);
  90. @Cleanup FileInputStream fileInputStream = new FileInputStream(file);
  91. LinkedHashMap<String, Object> jsonObject = JSONObject.parseObject(fileInputStream, LinkedHashMap.class);
  92. this.parseMap(jsonObject, resMap, null);
  93. } catch (Exception e) {
  94. e.printStackTrace();
  95. }
  96. langKeyMap.put(item.getEnCode(), resMap);
  97. }
  98. for (DictionaryDataEntity item : langTypeList) {
  99. LinkedHashMap<String, String> eachMap = langKeyMap.get(item.getEnCode());
  100. for (String key : eachMap.keySet()) {
  101. Map<String, String> map = list.stream().filter(t -> t.get("code").equals(key)).findFirst().orElse(null);
  102. if (map != null) {
  103. map.put(item.getEnCode(), eachMap.get(key));
  104. } else {
  105. map = new HashMap<>();
  106. map.put("code", key);
  107. map.put(item.getEnCode(), eachMap.get(key));
  108. list.add(map);
  109. }
  110. }
  111. }
  112. if (StringUtil.isNotEmpty(pagination.getKeyword())) {
  113. list = list.stream().filter(t -> {
  114. for (String tkey : t.keySet()) {
  115. if (t.get(tkey).contains(pagination.getKeyword())) {
  116. return true;
  117. }
  118. }
  119. return false;
  120. }).collect(Collectors.toList());
  121. }
  122. //假分页
  123. if (CollectionUtils.isNotEmpty(list)) {
  124. List<List<Map<String, String>>> partition = Lists.partition(list, (int) pagination.getPageSize());
  125. int i = (int) pagination.getCurrentPage() - 1;
  126. resList = partition.size() > i ? partition.get(i) : Collections.emptyList();
  127. pagination.setTotal(list.size());
  128. }
  129. BaseLangListVO vo = new BaseLangListVO();
  130. PaginationVO page = JsonUtil.getJsonToBean(pagination, PaginationVO.class);
  131. vo.setList(resList);
  132. vo.setTableHead(tableHead);
  133. vo.setPagination(page);
  134. return vo;
  135. }
  136. /**
  137. * 多层map,解析成单层key,value
  138. *
  139. * @param sourMap
  140. * @param resMap
  141. * @param supKey
  142. */
  143. public void parseMap(LinkedHashMap<String, Object> sourMap, LinkedHashMap<String, String> resMap, String supKey) {
  144. for (String key : sourMap.keySet()) {
  145. if (sourMap.get(key).toString().startsWith("{") && sourMap.get(key).toString().endsWith("}")) {
  146. LinkedHashMap<String, Object> childSourMap = JSONObject.parseObject(sourMap.get(key).toString(), LinkedHashMap.class);
  147. String newSupKey = key;
  148. if (StringUtil.isNotEmpty(supKey)) {
  149. newSupKey = supKey + "." + key;
  150. }
  151. this.parseMap(childSourMap, resMap, newSupKey);
  152. } else {
  153. String value = sourMap.get(key).toString();
  154. if (supKey != null) {
  155. String skey = supKey + "." + key;
  156. resMap.put(skey, value);
  157. } else {
  158. String skey = key;
  159. resMap.put(skey, value);
  160. }
  161. }
  162. }
  163. }
  164. /**
  165. * 根据不同语种查询列表最大列表
  166. *
  167. * @param pagination
  168. * @param langTypeList
  169. * @param idList
  170. * @return
  171. */
  172. private IPage<BaseLangEntity> getList(BaseLangPage pagination, List<DictionaryDataEntity> langTypeList, List<String> idList) {
  173. IPage<BaseLangEntity> listRes = null;
  174. for (DictionaryDataEntity item : langTypeList) {
  175. String enCode = item.getEnCode();
  176. QueryWrapper<BaseLangEntity> queryWrapper = new QueryWrapper<>();
  177. queryWrapper.lambda().eq(BaseLangEntity::getLanguage, enCode);
  178. if (CollectionUtils.isNotEmpty(idList)) {
  179. queryWrapper.lambda().in(BaseLangEntity::getId, idList);
  180. }
  181. if (Objects.nonNull(pagination.getType())) {
  182. queryWrapper.lambda().eq(BaseLangEntity::getType, pagination.getType());
  183. }
  184. queryWrapper.lambda().orderByDesc(BaseLangEntity::getCreatorTime);
  185. Page<BaseLangEntity> page = new Page<>(pagination.getCurrentPage(), pagination.getPageSize());
  186. IPage<BaseLangEntity> list = this.page(page, queryWrapper);
  187. if (listRes == null) {
  188. listRes = list;
  189. } else {
  190. if (listRes.getTotal() < list.getTotal()) {
  191. listRes = list;
  192. }
  193. }
  194. }
  195. return listRes;
  196. }
  197. @Override
  198. public BaseLangListVO list(BaseLangPage pagination) {
  199. List<DictionaryDataEntity> langTypeList = dictionaryDataApi.getListByTypeDataCode(ConfigConst.BASE_LANGUAGE);
  200. List<Map<String, Object>> tableHead = new ArrayList<>();
  201. tableHead.add(new HashMap() {{
  202. put("prop", "code");
  203. put("label", "翻译标记");
  204. }});
  205. for (DictionaryDataEntity item : langTypeList) {
  206. tableHead.add(new HashMap() {{
  207. put("prop", item.getEnCode());
  208. put("label", item.getFullName());
  209. }});
  210. }
  211. String keyword = pagination.getKeyword();
  212. List<String> idList = new ArrayList<>();
  213. if (StringUtil.isNotEmpty(keyword)) {
  214. QueryWrapper<BaseLangEntity> queryWrapper = new QueryWrapper<>();
  215. queryWrapper.lambda().and(t -> t.like(BaseLangEntity::getEnCode, keyword)
  216. .or().like(BaseLangEntity::getFullName, keyword));
  217. List<BaseLangEntity> list = list(queryWrapper);
  218. if (CollectionUtils.isEmpty(list)) {
  219. return new BaseLangListVO(new ArrayList<>(), tableHead, pagination);
  220. } else {
  221. idList = list.stream().map(BaseLangEntity::getId).collect(Collectors.toList());
  222. }
  223. }
  224. IPage<BaseLangEntity> list = getList(pagination, langTypeList, idList);
  225. List<BaseLangEntity> baseLangEntities = pagination.setData(list.getRecords(), list.getTotal());
  226. List<Map<String, String>> resList = new ArrayList<>();
  227. for (BaseLangEntity item : baseLangEntities) {
  228. String groupId = item.getGroupId();
  229. Map<String, String> resMap = new LinkedHashMap<>();
  230. List<BaseLangEntity> byGroupId = this.getByGroupId(item.getGroupId());
  231. resMap.put("id", groupId);
  232. resMap.put("code", item.getEnCode());
  233. resMap.put("typeName", Objects.equals(item.getType(), 0) ? "客户端" : "服务端");
  234. for (BaseLangEntity entity : byGroupId) {
  235. resMap.put(entity.getLanguage(), entity.getFullName());
  236. }
  237. resList.add(resMap);
  238. }
  239. BaseLangListVO vo = new BaseLangListVO();
  240. PaginationVO pagevo = JsonUtil.getJsonToBean(pagination, PaginationVO.class);
  241. vo.setList(resList);
  242. vo.setTableHead(tableHead);
  243. vo.setPagination(pagevo);
  244. return vo;
  245. }
  246. @Override
  247. public void create(BaseLangForm form) {
  248. List<BaseLangEntity> byEnode = this.getByEnodeLang(form.getEnCode(), null);
  249. if (CollectionUtils.isNotEmpty(byEnode)) {
  250. throw new DataException(MsgCode.SYS051.get());
  251. }
  252. Map<String, String> map = form.getMap();
  253. boolean atLeastOne = false;
  254. if (MapUtils.isNotEmpty(map)) {
  255. atLeastOne = map.values().stream().anyMatch(v -> v != null && !v.trim().isEmpty());
  256. }
  257. if (!atLeastOne) {
  258. throw new DataException(MsgCode.SYS052.get());
  259. }
  260. String groupId = RandomUtil.uuId();
  261. for (String key : map.keySet()) {
  262. BaseLangEntity entity = JsonUtil.getJsonToBean(form, BaseLangEntity.class);
  263. entity.setGroupId(groupId);
  264. entity.setLanguage(key);
  265. entity.setFullName(map.get(key));
  266. saveEntity(entity);
  267. }
  268. this.createReids(form.getType());
  269. }
  270. @Override
  271. public void update(BaseLangForm form) {
  272. List<BaseLangEntity> langList = getByGroupId(form.getId());
  273. if (CollectionUtils.isEmpty(langList)) {
  274. throw new DataException(MsgCode.FA002.get());
  275. }
  276. List<BaseLangEntity> byEnodeLang = getByEnodeLang(form.getEnCode(), null);
  277. List<BaseLangEntity> hasLang = byEnodeLang.stream().filter(t -> !t.getGroupId().equals(form.getId())).collect(Collectors.toList());
  278. if (CollectionUtils.isNotEmpty(hasLang)) {
  279. throw new DataException(MsgCode.SYS051.get());
  280. }
  281. Map<String, String> map = form.getMap();
  282. boolean atLeastOne = false;
  283. if (MapUtils.isNotEmpty(map)) {
  284. atLeastOne = map.values().stream().anyMatch(v -> v != null && !v.trim().isEmpty());
  285. }
  286. if (!atLeastOne) {
  287. throw new DataException(MsgCode.SYS052.get());
  288. }
  289. List<String> keyList = new ArrayList<>(map.keySet());
  290. String groupId = "";
  291. List<BaseLangEntity> deleteList = new ArrayList<>();
  292. for (BaseLangEntity t : langList) {
  293. if (!keyList.contains(t.getLanguage())) {
  294. deleteList.add(t);
  295. }
  296. groupId = t.getGroupId();
  297. }
  298. //删除移除的
  299. if (CollectionUtils.isNotEmpty(deleteList)) {
  300. this.removeBatchByIds(deleteList.stream().map(BaseLangEntity::getId).collect(Collectors.toList()));
  301. }
  302. for (String key : keyList) {
  303. BaseLangEntity entity = langList.stream().filter(t -> key.equals(t.getLanguage())).findFirst().orElse(new BaseLangEntity());
  304. if (StringUtil.isNotEmpty(entity.getId())) {
  305. entity.setEnCode(form.getEnCode());
  306. entity.setType(form.getType());
  307. entity.setFullName(map.get(key));
  308. entity.setLastModifyTime(DateUtil.getNowDate());
  309. entity.setLastModifyUserId(UserProvider.getUser().getUserId());
  310. this.updateById(entity);
  311. } else {
  312. entity.setId(RandomUtil.uuId());
  313. entity.setGroupId(groupId);
  314. entity.setEnCode(form.getEnCode());
  315. entity.setType(form.getType());
  316. entity.setLanguage(key);
  317. entity.setFullName(map.get(key));
  318. entity.setCreatorTime(new Date());
  319. entity.setCreatorUserId(UserProvider.getUser().getUserId());
  320. this.save(entity);
  321. }
  322. }
  323. this.createReids(form.getType());
  324. }
  325. @Override
  326. public BaseLangForm getInfo(String groupId) {
  327. List<BaseLangEntity> byEnodeLang = getByGroupId(groupId);
  328. BaseLangForm form = new BaseLangForm();
  329. form.setId(groupId);
  330. LinkedHashMap<String, String> map = new LinkedHashMap<>();
  331. for (BaseLangEntity entity : byEnodeLang) {
  332. form.setEnCode(entity.getEnCode());
  333. form.setType(entity.getType());
  334. map.put(entity.getLanguage(), entity.getFullName());
  335. }
  336. form.setMap(map);
  337. return form;
  338. }
  339. @Override
  340. public void delete(String groupId) {
  341. List<BaseLangEntity> byGroupId = getByGroupId(groupId);
  342. Integer type = byGroupId.get(0).getType();
  343. QueryWrapper<BaseLangEntity> queryWrapper = new QueryWrapper<>();
  344. queryWrapper.lambda().select(BaseLangEntity::getId);
  345. queryWrapper.lambda().eq(BaseLangEntity::getGroupId, groupId);
  346. this.removeByIds(list(queryWrapper));
  347. this.createReids(type);
  348. }
  349. @Override
  350. public void importSaveOrUpdate(List<BaseLangEntity> list) {
  351. Map<String, String> enCodeGroupId = new HashMap<>();
  352. boolean hasFront = false;
  353. boolean hasServer = false;
  354. for (BaseLangEntity item : list) {
  355. if (Objects.equals(item.getType(), 0)) {
  356. hasFront = true;
  357. }
  358. if (Objects.equals(item.getType(), 1) || Objects.equals(item.getType(), 2)) {
  359. hasServer = true;
  360. }
  361. List<BaseLangEntity> byEnodeLang = getByEnodeLang(item.getEnCode(), null);
  362. String groupId = RandomUtil.uuId();
  363. if (CollectionUtils.isNotEmpty(byEnodeLang)) {
  364. groupId = byEnodeLang.get(0).getGroupId();
  365. if (!enCodeGroupId.containsKey(byEnodeLang.get(0).getEnCode())) {
  366. enCodeGroupId.put(item.getEnCode(), groupId);
  367. }
  368. BaseLangEntity entity = byEnodeLang.stream().filter(t -> t.getLanguage().equals(item.getLanguage())).findFirst().orElse(null);
  369. if (entity != null) {
  370. boolean modify = false;
  371. if(!Objects.equals(entity.getType(), item.getType())) {
  372. entity.setType(item.getType());
  373. modify = true;
  374. }
  375. if(!Objects.equals(entity.getFullName(), item.getFullName())) {
  376. entity.setFullName(item.getFullName());
  377. modify = true;
  378. }
  379. if(modify) {
  380. entity.setLastModifyTime(new Date());
  381. entity.setLastModifyUserId(UserProvider.getUser().getUserId());
  382. this.updateById(entity);
  383. }
  384. } else {
  385. entity = JsonUtil.getJsonToBean(item, BaseLangEntity.class);
  386. entity.setGroupId(groupId);
  387. saveEntity(entity);
  388. }
  389. } else {
  390. if (enCodeGroupId.containsKey(item.getEnCode())) {
  391. groupId = enCodeGroupId.get(item.getEnCode());
  392. } else {
  393. enCodeGroupId.put(item.getEnCode(), groupId);
  394. }
  395. BaseLangEntity entity = BeanUtil.copyProperties(item, BaseLangEntity.class);
  396. entity.setGroupId(groupId);
  397. saveEntity(entity);
  398. }
  399. }
  400. if (hasFront) {
  401. this.createReids(0);
  402. }
  403. if (hasServer) {
  404. this.createReids(1);
  405. }
  406. }
  407. private void saveEntity(BaseLangEntity entity) {
  408. entity.setId(RandomUtil.uuId());
  409. entity.setCreatorTime(new Date());
  410. entity.setCreatorUserId(UserProvider.getUser().getUserId());
  411. this.save(entity);
  412. }
  413. /**
  414. * 根据翻译标记和语种获取数据
  415. *
  416. * @param enCode
  417. * @param language
  418. * @return
  419. */
  420. private List<BaseLangEntity> getByEnodeLang(String enCode, String language) {
  421. QueryWrapper<BaseLangEntity> queryWrapper = new QueryWrapper<>();
  422. if (StringUtil.isNotEmpty(enCode)) {
  423. queryWrapper.lambda().eq(BaseLangEntity::getEnCode, enCode);
  424. }
  425. if (StringUtil.isNotEmpty(language)) {
  426. queryWrapper.lambda().eq(BaseLangEntity::getLanguage, language);
  427. }
  428. return this.list(queryWrapper);
  429. }
  430. /**
  431. * 根据翻译标记id获取数据
  432. *
  433. * @param groupId
  434. * @return
  435. */
  436. private List<BaseLangEntity> getByGroupId(String groupId) {
  437. QueryWrapper<BaseLangEntity> queryWrapper = new QueryWrapper<>();
  438. queryWrapper.lambda().eq(BaseLangEntity::getGroupId, groupId);
  439. queryWrapper.lambda().orderByAsc(BaseLangEntity::getSortCode).orderByAsc(BaseLangEntity::getCreatorTime);
  440. return this.list(queryWrapper);
  441. }
  442. /**
  443. * 创建修改添加缓存触发
  444. *
  445. * @param type
  446. */
  447. private void createReids(Integer type) {
  448. String tenantId = GlobalConst.DEFAULT_TENANT_VALUE;
  449. if (configValueUtil.isMultiTenancy()) {
  450. tenantId = TenantHolder.getDatasourceId();
  451. }
  452. String cacheType = I18nConst.CACHE_KEY_FRONT;
  453. if (Objects.equals(type, 1)) {
  454. cacheType = I18nConst.CACHE_KEY_SERVER;
  455. }
  456. String redisKey = cacheType + tenantId;
  457. PublishEventUtil.publish(new ProjectEventBuilder(redisKey, System.currentTimeMillis()).setMessageModel(ProjectEventConst.EVENT_PUBLISH_MODEL_BROADCASTING));
  458. }
  459. /**
  460. * 组装语种json
  461. *
  462. * @param language
  463. * @return
  464. */
  465. private String makeLanguageJson(String language) {
  466. QueryWrapper<BaseLangEntity> queryWrapper = new QueryWrapper<>();
  467. queryWrapper.lambda().eq(BaseLangEntity::getLanguage, language);
  468. queryWrapper.lambda().eq(BaseLangEntity::getType, 0);
  469. JSONObject json = new JSONObject();
  470. List<BaseLangEntity> list = list(queryWrapper);
  471. for (BaseLangEntity baseLangEntity : list) {
  472. // 不需要组装成对象。(组装成对象父级key如果被存储信息了转换json对象有问题)
  473. // addJsonTree(baseLangEntity.getEnCode(), json, baseLangEntity.getFullName());
  474. json.put(baseLangEntity.getEnCode(), baseLangEntity.getFullName());
  475. }
  476. return json.toJSONString();
  477. }
  478. /**
  479. * 递归添加属性
  480. *
  481. * @param enCode
  482. * @param json
  483. * @param fullName
  484. */
  485. private void addJsonTree(String enCode, JSONObject json, String fullName) {
  486. if (enCode.contains(".")) {
  487. String one = enCode.substring(0, enCode.indexOf("."));
  488. String two = enCode.substring(enCode.indexOf(".") + 1);
  489. JSONObject towJson = new JSONObject();
  490. if (json.containsKey(one)) {
  491. towJson = (JSONObject) json.get(one);
  492. }
  493. addJsonTree(two, towJson, fullName);
  494. json.put(one, towJson);
  495. } else {
  496. if (!json.containsKey(enCode)) {
  497. json.put(enCode, fullName);
  498. }
  499. }
  500. }
  501. /**
  502. * 监听缓存修改语种信息
  503. *
  504. * @param redisEvent
  505. */
  506. @ProjectEventListener(channelRegex = I18nConst.CACHE_KEY_FRONT + ".*")
  507. public void onRedisKeySetEvent(ProjectEventInstance redisEvent) {
  508. String key = redisEvent.getChannel();
  509. // 获取多租户编码
  510. key = key.substring(I18nConst.CACHE_KEY_FRONT.length());
  511. tenantMessageProperties.remove(key);
  512. }
  513. /**
  514. * 初始化语种
  515. *
  516. * @param tenantId
  517. * @param locale
  518. */
  519. public void loadTenantMessage(String tenantId, Locale locale) {
  520. String languageJson = this.makeLanguageJson(locale.toLanguageTag());
  521. Map<String, String> tenantLangJson = tenantMessageProperties.get(tenantId);
  522. if (tenantLangJson == null) {
  523. tenantLangJson = new HashMap<>();
  524. tenantMessageProperties.put(tenantId, tenantLangJson);
  525. }
  526. tenantLangJson.put(locale.toLanguageTag(), languageJson);
  527. }
  528. /**
  529. * 前端获取语种json
  530. *
  531. * @param locale 语种
  532. * @return
  533. */
  534. @Override
  535. public String getLanguageJson(Locale locale) {
  536. // 默认租户或者当前租户
  537. String tenantId = GlobalConst.DEFAULT_TENANT_VALUE;
  538. if (configValueUtil.isMultiTenancy()) {
  539. tenantId = TenantHolder.getDatasourceId();
  540. }
  541. // 开启租户未获取到租户 不进行翻译获取
  542. if (tenantId != null) {
  543. String language;
  544. // 租户配置中的语言配置
  545. String languageTag = locale.toLanguageTag();
  546. if (!tenantMessageProperties.containsKey(tenantId) || !tenantMessageProperties.get(tenantId).containsKey(languageTag)) {
  547. // 租户其他线程正在加载多语言则直接返回
  548. ReentrantLock lock = lockMap.computeIfAbsent(tenantId, k -> new ReentrantLock());
  549. boolean isLock = false;
  550. try {
  551. // 如果其他线程正在处理租户翻译则最多等待十秒钟
  552. isLock = lock.tryLock(5L, TimeUnit.SECONDS);
  553. if (isLock) {
  554. if (!tenantMessageProperties.containsKey(tenantId) || !tenantMessageProperties.get(tenantId).containsKey(languageTag)) {
  555. loadTenantMessage(tenantId, locale);
  556. }
  557. }
  558. } catch (InterruptedException e) {
  559. } finally {
  560. if (isLock) {
  561. lock.unlock();
  562. }
  563. }
  564. }
  565. language = tenantMessageProperties.get(tenantId).get(languageTag);
  566. // 语言不存在翻译配置, 强制返回默认配置语言, 已经是默认语言无法处理
  567. if ((language == null || "{}".equals(language)) && !Objects.equals(locale.toLanguageTag(), i18nProperties.getDefaultLanguage())) {
  568. return getLanguageJson(Locale.forLanguageTag(i18nProperties.getDefaultLanguage()));
  569. }
  570. return language;
  571. }
  572. return null;
  573. }
  574. @Override
  575. public List<BaseLangEntity> getServerLang(Locale locale) {
  576. QueryWrapper<BaseLangEntity> queryWrapper = new QueryWrapper<>();
  577. queryWrapper.lambda().eq(BaseLangEntity::getLanguage, locale.toLanguageTag());
  578. List<Integer> type = ImmutableList.of(0, 1);
  579. queryWrapper.lambda().in(BaseLangEntity::getType, type);
  580. return list(queryWrapper);
  581. }
  582. }