feat(site): integrate multilingual content management / 集成多语言内容管理
完善官网、管理后台与后端的多语言内容编辑和发布流程,调整站点页面及相关接口,并同步数据库脚本。 新增容器部署配置,改用环境变量注入数据库凭据;补充仓库忽略规则,并停止跟踪本地环境文件和 Maven 构建产物。
This commit is contained in:
1 parent
4ee6e9ae83
commit
85083ab962
1056 files changed
+15449
-132933
No files matched your search
@@ -0,0 +1,7 @@
|
||||
# 使用 JDK8 镜像(RuoYi 默认用 8,如果是 17 请换成 openjdk:17-jdk-alpine)
|
||||
FROM eclipse-temurin:17-jdk-alpine
|
||||
WORKDIR /app
|
||||
# 复制本地已经打包好的 jar 包 (前提是你已经在本地执行过 mvn clean package)
|
||||
COPY ruoyi-admin/target/ruoyi-admin.jar app.jar
|
||||
EXPOSE 7003
|
||||
ENTRYPOINT ["java", "-jar", "app.jar"]
|
||||
+9
-2
@@ -18,6 +18,7 @@ import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.file.FileUploadUtils;
|
||||
import com.ruoyi.common.utils.file.FileUtils;
|
||||
import com.ruoyi.common.utils.file.ImageUploadUtils;
|
||||
import com.ruoyi.framework.config.ServerConfig;
|
||||
|
||||
/**
|
||||
@@ -79,7 +80,7 @@ public class CommonController
|
||||
// 上传文件路径
|
||||
String filePath = RuoYiConfig.getUploadPath();
|
||||
// 上传并返回新文件名称
|
||||
String fileName = FileUploadUtils.upload(filePath, file);
|
||||
String fileName = upload(filePath, file);
|
||||
String url = serverConfig.getUrl() + fileName;
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
ajax.put("url", url);
|
||||
@@ -111,7 +112,7 @@ public class CommonController
|
||||
for (MultipartFile file : files)
|
||||
{
|
||||
// 上传并返回新文件名称
|
||||
String fileName = FileUploadUtils.upload(filePath, file);
|
||||
String fileName = upload(filePath, file);
|
||||
String url = serverConfig.getUrl() + fileName;
|
||||
urls.add(url);
|
||||
fileNames.add(fileName);
|
||||
@@ -159,4 +160,10 @@ public class CommonController
|
||||
log.error("下载文件失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
private String upload(String filePath, MultipartFile file) throws Exception
|
||||
{
|
||||
return ImageUploadUtils.isImage(file) ? ImageUploadUtils.upload(filePath, file)
|
||||
: FileUploadUtils.upload(filePath, file);
|
||||
}
|
||||
}
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
package com.ruoyi.web.controller.common;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Base64;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.http.CacheControl;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.ruoyi.common.config.RuoYiConfig;
|
||||
|
||||
/**
|
||||
* Handles uploaded portal assets before the generic static resource handler.
|
||||
*/
|
||||
@RestController
|
||||
public class ProfileUploadController
|
||||
{
|
||||
private static final String PROFILE_PREFIX = "/profile/";
|
||||
private static final byte[] MISSING_IMAGE_BYTES = Base64.getDecoder().decode(
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+/p9sAAAAASUVORK5CYII=");
|
||||
|
||||
@RequestMapping(value = "/profile/upload/**", method = { RequestMethod.GET, RequestMethod.HEAD })
|
||||
public ResponseEntity<Resource> getUploadResource(HttpServletRequest request) throws IOException
|
||||
{
|
||||
String requestUri = request.getRequestURI();
|
||||
String relativePath = requestUri.startsWith(PROFILE_PREFIX) ? requestUri.substring(PROFILE_PREFIX.length()) : "";
|
||||
relativePath = URLDecoder.decode(relativePath, StandardCharsets.UTF_8);
|
||||
Path root = Path.of(RuoYiConfig.getProfile()).toAbsolutePath().normalize();
|
||||
Path target = root.resolve(relativePath).normalize();
|
||||
|
||||
if (target.startsWith(root) && Files.isRegularFile(target) && Files.isReadable(target))
|
||||
{
|
||||
MediaType mediaType = resolveMediaType(target);
|
||||
return ResponseEntity.ok()
|
||||
.contentType(mediaType)
|
||||
.cacheControl(CacheControl.noCache())
|
||||
.body(new FileSystemResource(target));
|
||||
}
|
||||
|
||||
if (isImagePath(relativePath))
|
||||
{
|
||||
return ResponseEntity.ok()
|
||||
.contentType(MediaType.IMAGE_PNG)
|
||||
.cacheControl(CacheControl.noStore())
|
||||
.body(new ByteArrayResource(MISSING_IMAGE_BYTES));
|
||||
}
|
||||
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
|
||||
private static MediaType resolveMediaType(Path path)
|
||||
{
|
||||
try
|
||||
{
|
||||
String contentType = Files.probeContentType(path);
|
||||
if (contentType != null && !contentType.isBlank())
|
||||
{
|
||||
return MediaType.parseMediaType(contentType);
|
||||
}
|
||||
}
|
||||
catch (IOException | IllegalArgumentException ignored)
|
||||
{
|
||||
}
|
||||
return MediaType.APPLICATION_OCTET_STREAM;
|
||||
}
|
||||
|
||||
private static boolean isImagePath(String path)
|
||||
{
|
||||
if (path == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
String lowerPath = path.toLowerCase();
|
||||
return lowerPath.endsWith(".png") || lowerPath.endsWith(".jpg") || lowerPath.endsWith(".jpeg")
|
||||
|| lowerPath.endsWith(".gif") || lowerPath.endsWith(".webp") || lowerPath.endsWith(".svg")
|
||||
|| lowerPath.endsWith(".ico");
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -20,7 +20,7 @@ import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.common.utils.file.FileUploadUtils;
|
||||
import com.ruoyi.common.utils.file.ImageUploadUtils;
|
||||
import com.ruoyi.framework.config.ServerConfig;
|
||||
import com.ruoyi.system.domain.HuayangCompanyHonor;
|
||||
import com.ruoyi.system.service.IHuayangCompanyHonorService;
|
||||
@@ -113,7 +113,7 @@ public class HuayangCompanyHonorController extends BaseController
|
||||
// 上传文件路径
|
||||
String filePath = RuoYiConfig.getUploadPath() + "/huayang/honor";
|
||||
// 上传并返回新文件名称
|
||||
String fileName = FileUploadUtils.upload(filePath, file);
|
||||
String fileName = ImageUploadUtils.upload(filePath, file);
|
||||
String url = serverConfig.getUrl() + fileName;
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
ajax.put("url", url);
|
||||
@@ -125,4 +125,4 @@ public class HuayangCompanyHonorController extends BaseController
|
||||
return error("上传失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -47,7 +47,7 @@ public class HuayangCompanySectionController extends BaseController
|
||||
/**
|
||||
* 按板块标识查询(用于后台快速打开 about_intro 等,须在 /{sectionId} 之前声明)
|
||||
*/
|
||||
@PreAuthorize("@ss.hasAnyPermi('huayang:companySection:query,huayang:joinPageContent:query')")
|
||||
@PreAuthorize("@ss.hasPermi('huayang:companySection:query')")
|
||||
@GetMapping("/byCode/{sectionCode}")
|
||||
public AjaxResult getBySectionCode(@PathVariable("sectionCode") String sectionCode)
|
||||
{
|
||||
@@ -67,7 +67,7 @@ public class HuayangCompanySectionController extends BaseController
|
||||
/**
|
||||
* 新增公司简介
|
||||
*/
|
||||
@PreAuthorize("@ss.hasAnyPermi('huayang:companySection:add,huayang:joinPageContent:edit')")
|
||||
@PreAuthorize("@ss.hasPermi('huayang:companySection:add')")
|
||||
@Log(title = "公司简介", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@Validated @RequestBody HuayangCompanySection huayangCompanySection)
|
||||
@@ -79,7 +79,7 @@ public class HuayangCompanySectionController extends BaseController
|
||||
/**
|
||||
* 修改公司简介
|
||||
*/
|
||||
@PreAuthorize("@ss.hasAnyPermi('huayang:companySection:edit,huayang:joinPageContent:edit')")
|
||||
@PreAuthorize("@ss.hasPermi('huayang:companySection:edit')")
|
||||
@Log(title = "公司简介", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@Validated @RequestBody HuayangCompanySection huayangCompanySection)
|
||||
|
||||
-91
@@ -1,91 +0,0 @@
|
||||
package com.ruoyi.web.controller.huayang;
|
||||
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.system.domain.HuayangCompanyTech;
|
||||
import com.ruoyi.system.service.IHuayangCompanyTechService;
|
||||
|
||||
/**
|
||||
* 品质技术管理Controller
|
||||
*
|
||||
* @author huayang
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/huayang/companyTech")
|
||||
public class HuayangCompanyTechController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private IHuayangCompanyTechService huayangCompanyTechService;
|
||||
|
||||
/**
|
||||
* 查询品质技术列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('huayang:companyTech:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(HuayangCompanyTech huayangCompanyTech)
|
||||
{
|
||||
startPage();
|
||||
List<HuayangCompanyTech> list = huayangCompanyTechService.selectHuayangCompanyTechList(huayangCompanyTech);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取品质技术详情
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('huayang:companyTech:query')")
|
||||
@GetMapping(value = "/{techId}")
|
||||
public AjaxResult getInfo(@PathVariable("techId") Long techId)
|
||||
{
|
||||
return success(huayangCompanyTechService.selectHuayangCompanyTechByTechId(techId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增品质技术
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('huayang:companyTech:add')")
|
||||
@Log(title = "品质技术", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@Validated @RequestBody HuayangCompanyTech huayangCompanyTech)
|
||||
{
|
||||
huayangCompanyTech.setCreateBy(getUsername());
|
||||
return toAjax(huayangCompanyTechService.insertHuayangCompanyTech(huayangCompanyTech));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改品质技术
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('huayang:companyTech:edit')")
|
||||
@Log(title = "品质技术", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@Validated @RequestBody HuayangCompanyTech huayangCompanyTech)
|
||||
{
|
||||
huayangCompanyTech.setUpdateBy(getUsername());
|
||||
return toAjax(huayangCompanyTechService.updateHuayangCompanyTech(huayangCompanyTech));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除品质技术
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('huayang:companyTech:remove')")
|
||||
@Log(title = "品质技术", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{techIds}")
|
||||
public AjaxResult remove(@PathVariable Long[] techIds)
|
||||
{
|
||||
return toAjax(huayangCompanyTechService.deleteHuayangCompanyTechByTechIds(techIds));
|
||||
}
|
||||
}
|
||||
-60
@@ -1,60 +0,0 @@
|
||||
package com.ruoyi.web.controller.huayang;
|
||||
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.system.domain.HuayangJoinApply;
|
||||
import com.ruoyi.system.service.IHuayangJoinApplyService;
|
||||
|
||||
/**
|
||||
* 招商申请管理端Controller
|
||||
*
|
||||
* @author huayang
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/huayang/joinApply")
|
||||
public class HuayangJoinApplyController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private IHuayangJoinApplyService joinApplyService;
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('huayang:joinApply:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(HuayangJoinApply apply)
|
||||
{
|
||||
startPage();
|
||||
List<HuayangJoinApply> list = joinApplyService.selectHuayangJoinApplyList(apply);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('huayang:joinApply:query')")
|
||||
@GetMapping(value = "/{applyId}")
|
||||
public AjaxResult getInfo(@PathVariable("applyId") Long applyId)
|
||||
{
|
||||
return success(joinApplyService.selectHuayangJoinApplyById(applyId));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('huayang:joinApply:remove')")
|
||||
@Log(title = "招商申请", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{applyIds}")
|
||||
public AjaxResult remove(@PathVariable Long[] applyIds)
|
||||
{
|
||||
return toAjax(joinApplyService.deleteHuayangJoinApplyByIds(applyIds));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('huayang:joinApply:handle')")
|
||||
@Log(title = "处理招商申请", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/handle")
|
||||
public AjaxResult handle(@Validated @RequestBody HuayangJoinApply apply)
|
||||
{
|
||||
apply.setUpdateBy(getUsername());
|
||||
return toAjax(joinApplyService.handleApply(apply));
|
||||
}
|
||||
}
|
||||
+280
@@ -1,9 +1,14 @@
|
||||
package com.ruoyi.web.controller.huayang;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
@@ -21,6 +26,8 @@ import com.ruoyi.system.service.IHuayangI18nService;
|
||||
@RequestMapping("/huayang")
|
||||
public class HuayangLanguageController extends BaseController
|
||||
{
|
||||
private static final Pattern I18N_KEY_PATTERN = Pattern.compile("^[a-zA-Z0-9_.-]{2,100}$");
|
||||
|
||||
@Autowired
|
||||
private IHuayangLanguageService languageService;
|
||||
|
||||
@@ -84,4 +91,277 @@ public class HuayangLanguageController extends BaseController
|
||||
{
|
||||
return toAjax(i18nService.deleteHuayangI18nByIds(i18nIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量导入翻译(支持草稿模式、统计结果、逐条错误信息)
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('huayang:translation:add')")
|
||||
@PostMapping("/translation/import")
|
||||
public AjaxResult importTranslation(@RequestBody TranslationImportRequest request)
|
||||
{
|
||||
if (request == null || request.getItems() == null || request.getItems().isEmpty())
|
||||
{
|
||||
return error("导入数据不能为空");
|
||||
}
|
||||
String defaultStatus = StringUtils.defaultIfBlank(request.getDefaultStatus(), "0");
|
||||
if (!"0".equals(defaultStatus) && !"1".equals(defaultStatus))
|
||||
{
|
||||
return error("默认发布状态仅支持 0(草稿) 或 1(已发布)");
|
||||
}
|
||||
|
||||
int total = request.getItems().size();
|
||||
int inserted = 0;
|
||||
int updated = 0;
|
||||
int skipped = 0;
|
||||
List<String> errors = new ArrayList<>();
|
||||
|
||||
int index = 0;
|
||||
for (TranslationImportItem item : request.getItems())
|
||||
{
|
||||
index++;
|
||||
String rowPrefix = "第" + index + "行";
|
||||
if (item == null)
|
||||
{
|
||||
skipped++;
|
||||
errors.add(rowPrefix + ":空记录已跳过");
|
||||
continue;
|
||||
}
|
||||
String langCode = StringUtils.lowerCase(StringUtils.trimToEmpty(item.getLangCode()));
|
||||
String pageModule = StringUtils.trimToEmpty(item.getPageModule());
|
||||
String i18nKey = StringUtils.trimToEmpty(item.getI18nKey());
|
||||
String i18nValue = item.getI18nValue() == null ? "" : item.getI18nValue();
|
||||
String fallbackLangCode = StringUtils.lowerCase(StringUtils.trimToEmpty(item.getFallbackLangCode()));
|
||||
String translateStatus = StringUtils.trimToEmpty(item.getTranslateStatus());
|
||||
|
||||
if (StringUtils.isBlank(langCode) || StringUtils.isBlank(i18nKey))
|
||||
{
|
||||
skipped++;
|
||||
errors.add(rowPrefix + ":langCode / i18nKey 不能为空");
|
||||
continue;
|
||||
}
|
||||
if (!I18N_KEY_PATTERN.matcher(i18nKey).matches())
|
||||
{
|
||||
skipped++;
|
||||
errors.add(rowPrefix + ":i18nKey 格式非法(仅支持字母数字._-,长度2-100)");
|
||||
continue;
|
||||
}
|
||||
if (StringUtils.isBlank(pageModule))
|
||||
{
|
||||
pageModule = "common";
|
||||
}
|
||||
if (StringUtils.isBlank(fallbackLangCode))
|
||||
{
|
||||
fallbackLangCode = "zh_cn";
|
||||
}
|
||||
if (StringUtils.isBlank(translateStatus))
|
||||
{
|
||||
translateStatus = defaultStatus;
|
||||
}
|
||||
if (!"0".equals(translateStatus) && !"1".equals(translateStatus))
|
||||
{
|
||||
skipped++;
|
||||
errors.add(rowPrefix + ":translateStatus 仅支持 0/1");
|
||||
continue;
|
||||
}
|
||||
|
||||
HuayangI18n exists = i18nService.selectHuayangI18nByKey(langCode, i18nKey);
|
||||
if (exists != null)
|
||||
{
|
||||
exists.setI18nValue(i18nValue);
|
||||
exists.setPageModule(pageModule);
|
||||
exists.setFallbackLangCode(fallbackLangCode);
|
||||
exists.setTranslateStatus(translateStatus);
|
||||
exists.setUpdateBy(getUsername());
|
||||
i18nService.updateHuayangI18n(exists);
|
||||
updated++;
|
||||
}
|
||||
else
|
||||
{
|
||||
HuayangI18n record = new HuayangI18n();
|
||||
record.setLangCode(langCode);
|
||||
record.setPageModule(pageModule);
|
||||
record.setI18nKey(i18nKey);
|
||||
record.setI18nValue(i18nValue);
|
||||
record.setFallbackLangCode(fallbackLangCode);
|
||||
record.setTranslateStatus(translateStatus);
|
||||
record.setCreateBy(getUsername());
|
||||
i18nService.insertHuayangI18n(record);
|
||||
inserted++;
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Object> result = new LinkedHashMap<>();
|
||||
result.put("total", total);
|
||||
result.put("inserted", inserted);
|
||||
result.put("updated", updated);
|
||||
result.put("skipped", skipped);
|
||||
result.put("errors", errors);
|
||||
return success(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 按筛选条件一键发布(将草稿改为已发布)
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('huayang:translation:edit')")
|
||||
@PostMapping("/translation/publish")
|
||||
public AjaxResult publishTranslation(@RequestBody TranslationPublishRequest request)
|
||||
{
|
||||
HuayangI18n query = new HuayangI18n();
|
||||
if (request != null)
|
||||
{
|
||||
query.setLangCode(request.getLangCode());
|
||||
query.setPageModule(request.getPageModule());
|
||||
query.setI18nKey(request.getI18nKey());
|
||||
}
|
||||
List<HuayangI18n> rows = i18nService.selectHuayangI18nList(query);
|
||||
int affected = 0;
|
||||
for (HuayangI18n row : rows)
|
||||
{
|
||||
if ("1".equals(row.getTranslateStatus()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
row.setTranslateStatus("1");
|
||||
row.setUpdateBy(getUsername());
|
||||
i18nService.updateHuayangI18n(row);
|
||||
affected++;
|
||||
}
|
||||
Map<String, Object> result = new LinkedHashMap<>();
|
||||
result.put("matched", rows.size());
|
||||
result.put("published", affected);
|
||||
return success(result);
|
||||
}
|
||||
|
||||
public static class TranslationImportRequest
|
||||
{
|
||||
private String defaultStatus;
|
||||
private List<TranslationImportItem> items;
|
||||
|
||||
public String getDefaultStatus()
|
||||
{
|
||||
return defaultStatus;
|
||||
}
|
||||
|
||||
public void setDefaultStatus(String defaultStatus)
|
||||
{
|
||||
this.defaultStatus = defaultStatus;
|
||||
}
|
||||
|
||||
public List<TranslationImportItem> getItems()
|
||||
{
|
||||
return items;
|
||||
}
|
||||
|
||||
public void setItems(List<TranslationImportItem> items)
|
||||
{
|
||||
this.items = items;
|
||||
}
|
||||
}
|
||||
|
||||
public static class TranslationImportItem
|
||||
{
|
||||
private String langCode;
|
||||
private String pageModule;
|
||||
private String i18nKey;
|
||||
private String i18nValue;
|
||||
private String fallbackLangCode;
|
||||
private String translateStatus;
|
||||
|
||||
public String getLangCode()
|
||||
{
|
||||
return langCode;
|
||||
}
|
||||
|
||||
public void setLangCode(String langCode)
|
||||
{
|
||||
this.langCode = langCode;
|
||||
}
|
||||
|
||||
public String getPageModule()
|
||||
{
|
||||
return pageModule;
|
||||
}
|
||||
|
||||
public void setPageModule(String pageModule)
|
||||
{
|
||||
this.pageModule = pageModule;
|
||||
}
|
||||
|
||||
public String getI18nKey()
|
||||
{
|
||||
return i18nKey;
|
||||
}
|
||||
|
||||
public void setI18nKey(String i18nKey)
|
||||
{
|
||||
this.i18nKey = i18nKey;
|
||||
}
|
||||
|
||||
public String getI18nValue()
|
||||
{
|
||||
return i18nValue;
|
||||
}
|
||||
|
||||
public void setI18nValue(String i18nValue)
|
||||
{
|
||||
this.i18nValue = i18nValue;
|
||||
}
|
||||
|
||||
public String getFallbackLangCode()
|
||||
{
|
||||
return fallbackLangCode;
|
||||
}
|
||||
|
||||
public void setFallbackLangCode(String fallbackLangCode)
|
||||
{
|
||||
this.fallbackLangCode = fallbackLangCode;
|
||||
}
|
||||
|
||||
public String getTranslateStatus()
|
||||
{
|
||||
return translateStatus;
|
||||
}
|
||||
|
||||
public void setTranslateStatus(String translateStatus)
|
||||
{
|
||||
this.translateStatus = translateStatus;
|
||||
}
|
||||
}
|
||||
|
||||
public static class TranslationPublishRequest
|
||||
{
|
||||
private String langCode;
|
||||
private String pageModule;
|
||||
private String i18nKey;
|
||||
|
||||
public String getLangCode()
|
||||
{
|
||||
return langCode;
|
||||
}
|
||||
|
||||
public void setLangCode(String langCode)
|
||||
{
|
||||
this.langCode = langCode;
|
||||
}
|
||||
|
||||
public String getPageModule()
|
||||
{
|
||||
return pageModule;
|
||||
}
|
||||
|
||||
public void setPageModule(String pageModule)
|
||||
{
|
||||
this.pageModule = pageModule;
|
||||
}
|
||||
|
||||
public String getI18nKey()
|
||||
{
|
||||
return i18nKey;
|
||||
}
|
||||
|
||||
public void setI18nKey(String i18nKey)
|
||||
{
|
||||
this.i18nKey = i18nKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
-102
@@ -1,102 +0,0 @@
|
||||
package com.ruoyi.web.controller.huayang;
|
||||
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.domain.entity.SysDictData;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.system.service.ISysDictDataService;
|
||||
|
||||
/**
|
||||
* 新闻类型(字典 huayang_news_type)管理,供「新闻分类」子菜单使用
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/huayang/newsCategory")
|
||||
public class HuayangNewsCategoryController extends BaseController
|
||||
{
|
||||
public static final String NEWS_TYPE_DICT = "huayang_news_type";
|
||||
|
||||
@Autowired
|
||||
private ISysDictDataService dictDataService;
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('huayang:newsCategory:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(SysDictData query)
|
||||
{
|
||||
query.setDictType(NEWS_TYPE_DICT);
|
||||
if (StringUtils.isNotEmpty(query.getDictLabel()))
|
||||
{
|
||||
query.setDictLabel(query.getDictLabel().trim());
|
||||
}
|
||||
startPage();
|
||||
List<SysDictData> list = dictDataService.selectDictDataList(query);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('huayang:newsCategory:query')")
|
||||
@GetMapping(value = "/{dictCode}")
|
||||
public AjaxResult getInfo(@PathVariable Long dictCode)
|
||||
{
|
||||
SysDictData data = dictDataService.selectDictDataById(dictCode);
|
||||
if (data == null || !NEWS_TYPE_DICT.equals(data.getDictType()))
|
||||
{
|
||||
return error("数据不存在或无权访问");
|
||||
}
|
||||
return success(data);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('huayang:newsCategory:add')")
|
||||
@Log(title = "新闻类型字典", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody SysDictData data)
|
||||
{
|
||||
data.setDictType(NEWS_TYPE_DICT);
|
||||
data.setCreateBy(getUsername());
|
||||
return toAjax(dictDataService.insertDictData(data));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('huayang:newsCategory:edit')")
|
||||
@Log(title = "新闻类型字典", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@RequestBody SysDictData data)
|
||||
{
|
||||
SysDictData existing = dictDataService.selectDictDataById(data.getDictCode());
|
||||
if (existing == null || !NEWS_TYPE_DICT.equals(existing.getDictType()))
|
||||
{
|
||||
return error("数据不存在或无权修改");
|
||||
}
|
||||
data.setDictType(NEWS_TYPE_DICT);
|
||||
data.setUpdateBy(getUsername());
|
||||
return toAjax(dictDataService.updateDictData(data));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('huayang:newsCategory:remove')")
|
||||
@Log(title = "新闻类型字典", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{dictCodes}")
|
||||
public AjaxResult remove(@PathVariable Long[] dictCodes)
|
||||
{
|
||||
for (Long dictCode : dictCodes)
|
||||
{
|
||||
SysDictData d = dictDataService.selectDictDataById(dictCode);
|
||||
if (d == null || !NEWS_TYPE_DICT.equals(d.getDictType()))
|
||||
{
|
||||
return error("包含非法数据,已中止删除");
|
||||
}
|
||||
}
|
||||
dictDataService.deleteDictDataByIds(dictCodes);
|
||||
return success();
|
||||
}
|
||||
}
|
||||
-106
@@ -1,106 +0,0 @@
|
||||
package com.ruoyi.web.controller.huayang;
|
||||
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||
import com.ruoyi.system.domain.HuayangNews;
|
||||
import com.ruoyi.system.service.IHuayangNewsService;
|
||||
|
||||
/**
|
||||
* 新闻动态管理端Controller
|
||||
*
|
||||
* @author huayang
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/huayang/news")
|
||||
public class HuayangNewsController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private IHuayangNewsService newsService;
|
||||
|
||||
/**
|
||||
* 查询新闻动态列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('huayang:news:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(HuayangNews news)
|
||||
{
|
||||
startPage();
|
||||
List<HuayangNews> list = newsService.selectHuayangNewsList(news);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出新闻动态列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('huayang:news:export')")
|
||||
@Log(title = "新闻动态", businessType = BusinessType.EXPORT)
|
||||
@GetMapping("/export")
|
||||
public AjaxResult export(HuayangNews news)
|
||||
{
|
||||
List<HuayangNews> list = newsService.selectHuayangNewsList(news);
|
||||
ExcelUtil<HuayangNews> util = new ExcelUtil<HuayangNews>(HuayangNews.class);
|
||||
return util.exportExcel(list, "新闻数据");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取新闻动态详情
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('huayang:news:query')")
|
||||
@GetMapping(value = "/{newsId}")
|
||||
public AjaxResult getInfo(@PathVariable("newsId") Long newsId)
|
||||
{
|
||||
return success(newsService.selectHuayangNewsById(newsId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增新闻动态
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('huayang:news:add')")
|
||||
@Log(title = "新闻动态", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@Validated @RequestBody HuayangNews news)
|
||||
{
|
||||
news.setCreateBy(getUsername());
|
||||
return toAjax(newsService.insertHuayangNews(news));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改新闻动态
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('huayang:news:edit')")
|
||||
@Log(title = "新闻动态", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@Validated @RequestBody HuayangNews news)
|
||||
{
|
||||
news.setUpdateBy(getUsername());
|
||||
return toAjax(newsService.updateHuayangNews(news));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除新闻动态
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('huayang:news:remove')")
|
||||
@Log(title = "新闻动态", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{newsIds}")
|
||||
public AjaxResult remove(@PathVariable Long[] newsIds)
|
||||
{
|
||||
return toAjax(newsService.deleteHuayangNewsByIds(newsIds));
|
||||
}
|
||||
}
|
||||
-220
@@ -1,220 +0,0 @@
|
||||
package com.ruoyi.web.controller.huayang;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.system.domain.HuayangFixedSection;
|
||||
import com.ruoyi.system.domain.HuayangFixedSectionItem;
|
||||
import com.ruoyi.system.service.IHuayangFixedSectionService;
|
||||
|
||||
/**
|
||||
* 官网「新闻动态」页通栏横幅图(固定板块 news_banner,section_id=7)
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/huayang/newsPage")
|
||||
public class HuayangNewsPageBannerController extends BaseController
|
||||
{
|
||||
private static final Long NEWS_BANNER_SECTION_ID = 8L;
|
||||
private static final String NEWS_BANNER_SECTION_CODE = "news_banner";
|
||||
private static final String HOME_BANNER_SECTION_CODE = "section1";
|
||||
private static final String NEWS_BANNER_ITEM_TYPE_HOME_NEWS_BG = "home_news_bg";
|
||||
|
||||
@Autowired
|
||||
private IHuayangFixedSectionService huayangFixedSectionService;
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('huayang:newsBanner:query')")
|
||||
@GetMapping("/banner")
|
||||
public AjaxResult getBanner()
|
||||
{
|
||||
HuayangFixedSection section = huayangFixedSectionService.selectHuayangFixedSectionBySectionId(NEWS_BANNER_SECTION_ID);
|
||||
HuayangFixedSection full = huayangFixedSectionService.selectHuayangFixedSectionByCode(NEWS_BANNER_SECTION_CODE);
|
||||
Map<String, Object> data = new HashMap<>(4);
|
||||
data.put("backgroundImage", section != null ? section.getBackgroundImage() : null);
|
||||
data.put("sectionText", section != null ? section.getSectionText() : null);
|
||||
data.put("homeBackgroundImage", getHomeFirstBannerImage());
|
||||
data.put("homeNewsBackgroundImage", getHomeNewsBackgroundImage(full));
|
||||
return AjaxResult.success(data);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('huayang:newsBanner:edit')")
|
||||
@Log(title = "新闻动态页顶横幅", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/banner")
|
||||
public AjaxResult saveBanner(@RequestBody NewsPageBannerSaveRequest body)
|
||||
{
|
||||
HuayangFixedSection existing = huayangFixedSectionService.selectHuayangFixedSectionBySectionId(NEWS_BANNER_SECTION_ID);
|
||||
if (existing == null || !NEWS_BANNER_SECTION_CODE.equals(existing.getSectionCode()))
|
||||
{
|
||||
return AjaxResult.error("新闻动态顶图未初始化:请在数据库执行 backend/sql/huayang_news_dynamic_submenus.sql(含 fixed_section section_id=8)");
|
||||
}
|
||||
existing.setBackgroundImage(body != null ? body.getBackgroundImage() : null);
|
||||
existing.setSectionText(body != null ? body.getSectionText() : null);
|
||||
existing.setUpdateBy(getUsername());
|
||||
int updated = huayangFixedSectionService.updateHuayangFixedSection(existing);
|
||||
if (updated <= 0)
|
||||
{
|
||||
return toAjax(updated);
|
||||
}
|
||||
// 与首页顶部轮播图同步:保存新闻页横幅时,同时更新首页 section1 第一张轮播图
|
||||
if (existing.getBackgroundImage() != null && !existing.getBackgroundImage().trim().isEmpty())
|
||||
{
|
||||
upsertHomeFirstBannerImage(existing.getBackgroundImage().trim());
|
||||
}
|
||||
if (body != null && body.getHomeNewsBackgroundImage() != null)
|
||||
{
|
||||
upsertHomeNewsBackgroundImage(body.getHomeNewsBackgroundImage());
|
||||
}
|
||||
return toAjax(updated);
|
||||
}
|
||||
|
||||
private String getHomeFirstBannerImage()
|
||||
{
|
||||
HuayangFixedSection homeSection = huayangFixedSectionService.selectHuayangFixedSectionByCode(HOME_BANNER_SECTION_CODE);
|
||||
if (homeSection == null || homeSection.getItemList() == null || homeSection.getItemList().isEmpty())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
HuayangFixedSectionItem first = homeSection.getItemList().get(0);
|
||||
return first != null ? first.getItemImage() : null;
|
||||
}
|
||||
|
||||
private void upsertHomeFirstBannerImage(String image)
|
||||
{
|
||||
HuayangFixedSection homeSection = huayangFixedSectionService.selectHuayangFixedSectionByCode(HOME_BANNER_SECTION_CODE);
|
||||
if (homeSection == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
List<HuayangFixedSectionItem> items = homeSection.getItemList();
|
||||
HuayangFixedSectionItem first = (items != null && !items.isEmpty()) ? items.get(0) : null;
|
||||
if (first != null && first.getItemId() != null)
|
||||
{
|
||||
HuayangFixedSectionItem update = new HuayangFixedSectionItem();
|
||||
update.setItemId(first.getItemId());
|
||||
update.setItemImage(image);
|
||||
update.setUpdateBy(getUsername());
|
||||
huayangFixedSectionService.updateHuayangFixedSectionItem(update);
|
||||
return;
|
||||
}
|
||||
HuayangFixedSectionItem create = new HuayangFixedSectionItem();
|
||||
create.setSectionId(homeSection.getSectionId());
|
||||
create.setItemTitle("首页轮播图1");
|
||||
create.setItemType("slide");
|
||||
create.setSortOrder(1);
|
||||
create.setStatus("0");
|
||||
create.setItemImage(image);
|
||||
create.setCreateBy(getUsername());
|
||||
huayangFixedSectionService.insertHuayangFixedSectionItem(create);
|
||||
}
|
||||
|
||||
private String getHomeNewsBackgroundImage(HuayangFixedSection newsBanner)
|
||||
{
|
||||
if (newsBanner == null || newsBanner.getItemList() == null || newsBanner.getItemList().isEmpty())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
HuayangFixedSectionItem target = newsBanner.getItemList().stream()
|
||||
.filter(it -> it != null && NEWS_BANNER_ITEM_TYPE_HOME_NEWS_BG.equals(it.getItemType()))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
return target != null ? target.getItemImage() : null;
|
||||
}
|
||||
|
||||
private void upsertHomeNewsBackgroundImage(String image)
|
||||
{
|
||||
HuayangFixedSection banner = huayangFixedSectionService.selectHuayangFixedSectionByCode(NEWS_BANNER_SECTION_CODE);
|
||||
if (banner == null || banner.getSectionId() == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
List<HuayangFixedSectionItem> items = banner.getItemList();
|
||||
HuayangFixedSectionItem existing = null;
|
||||
if (items != null)
|
||||
{
|
||||
for (HuayangFixedSectionItem it : items)
|
||||
{
|
||||
if (it != null && NEWS_BANNER_ITEM_TYPE_HOME_NEWS_BG.equals(it.getItemType()))
|
||||
{
|
||||
existing = it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (existing != null && existing.getItemId() != null)
|
||||
{
|
||||
HuayangFixedSectionItem update = new HuayangFixedSectionItem();
|
||||
update.setItemId(existing.getItemId());
|
||||
update.setItemImage(image);
|
||||
update.setUpdateBy(getUsername());
|
||||
huayangFixedSectionService.updateHuayangFixedSectionItem(update);
|
||||
return;
|
||||
}
|
||||
HuayangFixedSectionItem create = new HuayangFixedSectionItem();
|
||||
create.setSectionId(banner.getSectionId());
|
||||
create.setItemTitle("首页华阳新闻背景图");
|
||||
create.setItemType(NEWS_BANNER_ITEM_TYPE_HOME_NEWS_BG);
|
||||
create.setSortOrder(999);
|
||||
create.setStatus("0");
|
||||
create.setItemImage(image);
|
||||
create.setCreateBy(getUsername());
|
||||
huayangFixedSectionService.insertHuayangFixedSectionItem(create);
|
||||
}
|
||||
|
||||
public static class NewsPageBannerSaveRequest
|
||||
{
|
||||
private String backgroundImage;
|
||||
private String sectionText;
|
||||
private String homeBackgroundImage;
|
||||
private String homeNewsBackgroundImage;
|
||||
|
||||
public String getBackgroundImage()
|
||||
{
|
||||
return backgroundImage;
|
||||
}
|
||||
|
||||
public void setBackgroundImage(String backgroundImage)
|
||||
{
|
||||
this.backgroundImage = backgroundImage;
|
||||
}
|
||||
|
||||
public String getSectionText()
|
||||
{
|
||||
return sectionText;
|
||||
}
|
||||
|
||||
public void setSectionText(String sectionText)
|
||||
{
|
||||
this.sectionText = sectionText;
|
||||
}
|
||||
|
||||
public String getHomeBackgroundImage()
|
||||
{
|
||||
return homeBackgroundImage;
|
||||
}
|
||||
|
||||
public void setHomeBackgroundImage(String homeBackgroundImage)
|
||||
{
|
||||
this.homeBackgroundImage = homeBackgroundImage;
|
||||
}
|
||||
|
||||
public String getHomeNewsBackgroundImage()
|
||||
{
|
||||
return homeNewsBackgroundImage;
|
||||
}
|
||||
|
||||
public void setHomeNewsBackgroundImage(String homeNewsBackgroundImage)
|
||||
{
|
||||
this.homeNewsBackgroundImage = homeNewsBackgroundImage;
|
||||
}
|
||||
}
|
||||
}
|
||||
+675
@@ -0,0 +1,675 @@
|
||||
package com.ruoyi.web.controller.huayang;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.domain.entity.SysMenu;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.system.domain.HuayangI18n;
|
||||
import com.ruoyi.system.domain.HuayangLanguage;
|
||||
import com.ruoyi.system.service.IHuayangSiteConfigService;
|
||||
import com.ruoyi.system.service.IHuayangI18nService;
|
||||
import com.ruoyi.system.service.IHuayangLanguageService;
|
||||
import com.ruoyi.system.service.ISysMenuService;
|
||||
import com.ruoyi.system.service.translation.ITranslationScanner;
|
||||
import com.ruoyi.system.service.translation.TranslationScannerRegistry;
|
||||
import com.ruoyi.system.service.translation.vo.PageInfoVO;
|
||||
import com.ruoyi.system.service.translation.vo.PageTranslationVO;
|
||||
import com.ruoyi.system.service.translation.vo.TranslationSectionVO;
|
||||
|
||||
/**
|
||||
* 翻译管理(按页面维度)
|
||||
*
|
||||
* <p>提供"翻译管理"菜单的核心能力:</p>
|
||||
* <ul>
|
||||
* <li>列出所有可翻译页面</li>
|
||||
* <li>实时扫描某页面下所有可翻译条目(中文原文 + 已存在翻译)</li>
|
||||
* <li>批量保存翻译</li>
|
||||
* <li>全局完成度统计</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author huayang
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/huayang/translation")
|
||||
public class HuayangTranslationController extends BaseController
|
||||
{
|
||||
/** 默认语种(不参与翻译,只作为原文兜底) */
|
||||
private static final String DEFAULT_LANG = "zh_cn";
|
||||
/** 翻译菜单选择配置 key(保存 sys_menu.menu_id 列表,逗号分隔) */
|
||||
private static final String MENU_SELECTION_CONFIG_KEY = "translation_menu_selected_ids";
|
||||
|
||||
@Autowired
|
||||
private TranslationScannerRegistry scannerRegistry;
|
||||
|
||||
@Autowired
|
||||
private IHuayangLanguageService languageService;
|
||||
|
||||
@Autowired
|
||||
private IHuayangI18nService i18nService;
|
||||
|
||||
@Autowired
|
||||
private ISysMenuService sysMenuService;
|
||||
|
||||
@Autowired
|
||||
private IHuayangSiteConfigService siteConfigService;
|
||||
|
||||
/**
|
||||
* 列出可翻译页面(用于左侧页面树)
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('huayang:translation:list')")
|
||||
@GetMapping("/pages")
|
||||
public AjaxResult listPages()
|
||||
{
|
||||
Set<String> selectedModules = resolveSelectedModules();
|
||||
List<PageInfoVO> pages = new ArrayList<>();
|
||||
for (PageInfoVO page : scannerRegistry.listAllPages())
|
||||
{
|
||||
if (selectedModules.isEmpty() || selectedModules.contains(page.getPageModule()))
|
||||
{
|
||||
pages.add(page);
|
||||
}
|
||||
}
|
||||
return success(pages);
|
||||
}
|
||||
|
||||
/**
|
||||
* 列出当前启用的目标语种(不含默认语种 zh_cn)
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('huayang:translation:list')")
|
||||
@GetMapping("/targetLangs")
|
||||
public AjaxResult listTargetLangs()
|
||||
{
|
||||
List<String> langs = resolveTargetLangCodes();
|
||||
List<HuayangLanguage> all = languageService.selectEnabledLanguageList();
|
||||
// 返回完整对象(含 langName),便于前端展示
|
||||
List<HuayangLanguage> result = new ArrayList<>();
|
||||
if (all != null)
|
||||
{
|
||||
for (HuayangLanguage l : all)
|
||||
{
|
||||
if (l != null && langs.contains(l.getLangCode()))
|
||||
{
|
||||
result.add(l);
|
||||
}
|
||||
}
|
||||
}
|
||||
return success(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 扫描某页面,返回完整翻译条目(含中文原文与已存在翻译)
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('huayang:translation:list')")
|
||||
@GetMapping("/scan")
|
||||
public AjaxResult scan(@RequestParam("pageModule") String pageModule)
|
||||
{
|
||||
if (StringUtils.isBlank(pageModule))
|
||||
{
|
||||
return error("参数 pageModule 必填");
|
||||
}
|
||||
ITranslationScanner scanner = scannerRegistry.getScanner(pageModule);
|
||||
if (scanner == null)
|
||||
{
|
||||
return error("未知页面模块:" + pageModule);
|
||||
}
|
||||
List<String> targetLangs = resolveTargetLangCodes();
|
||||
if (targetLangs.isEmpty())
|
||||
{
|
||||
return error("未配置除默认语种外的可翻译语言,请先在「语言配置」中启用语种");
|
||||
}
|
||||
PageTranslationVO data = scanner.scan(targetLangs);
|
||||
Set<String> allowedSections = resolveAllowedSections(pageModule);
|
||||
if (!allowedSections.isEmpty())
|
||||
{
|
||||
List<TranslationSectionVO> sections = new ArrayList<>();
|
||||
for (TranslationSectionVO section : data.getSections())
|
||||
{
|
||||
if (section != null && allowedSections.contains(section.getSectionKey()))
|
||||
{
|
||||
sections.add(section);
|
||||
}
|
||||
}
|
||||
data.setSections(sections);
|
||||
recalculatePageStats(data, targetLangs);
|
||||
}
|
||||
return success(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取菜单树选项(一级+二级)
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('huayang:translation:list')")
|
||||
@GetMapping("/menuOptions")
|
||||
public AjaxResult menuOptions()
|
||||
{
|
||||
List<SysMenu> rawMenus = sysMenuService.selectMenuList(new SysMenu(), getUserId());
|
||||
List<SysMenu> candidateMenus = filterTranslationCandidateMenus(rawMenus);
|
||||
List<SysMenu> tree = sysMenuService.buildMenuTree(candidateMenus);
|
||||
List<MenuTreeNode> nodes = toMenuTreeNodes(tree);
|
||||
return success(nodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前已选择的菜单 ID 列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('huayang:translation:list')")
|
||||
@GetMapping("/menuSelection")
|
||||
public AjaxResult menuSelection()
|
||||
{
|
||||
return success(new ArrayList<>(resolveSelectedMenuIds()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存菜单选择
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('huayang:translation:edit')")
|
||||
@Log(title = "翻译管理-菜单选择", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/menuSelection")
|
||||
public AjaxResult saveMenuSelection(@RequestBody MenuSelectionRequest request)
|
||||
{
|
||||
List<Long> menuIds = request == null ? Collections.emptyList() : request.getMenuIds();
|
||||
String value = joinMenuIds(menuIds);
|
||||
siteConfigService.upsertConfigValueByKey(
|
||||
MENU_SELECTION_CONFIG_KEY,
|
||||
value,
|
||||
"翻译管理-菜单选择",
|
||||
"翻译管理左侧菜单显示控制(sys_menu.menu_id 列表)"
|
||||
);
|
||||
return success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量保存翻译条目
|
||||
* <p>请求体示例:</p>
|
||||
* <pre>
|
||||
* {
|
||||
* "pageModule": "home",
|
||||
* "items": [
|
||||
* { "langCode": "en_us", "key": "home.banner.1.title", "value": "Ocean Food" },
|
||||
* { "langCode": "ja_jp", "key": "home.banner.1.title", "value": "" } // 空字符串=删除
|
||||
* ]
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('huayang:translation:edit')")
|
||||
@Log(title = "翻译管理-批量保存", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/batch")
|
||||
public AjaxResult batchSave(@RequestBody BatchSaveRequest request)
|
||||
{
|
||||
if (request == null || request.getItems() == null || request.getItems().isEmpty())
|
||||
{
|
||||
return error("无可保存的条目");
|
||||
}
|
||||
if (StringUtils.isBlank(request.getPageModule()))
|
||||
{
|
||||
return error("参数 pageModule 必填");
|
||||
}
|
||||
|
||||
List<String> validLangs = resolveTargetLangCodes();
|
||||
List<HuayangI18n> rows = new ArrayList<>();
|
||||
for (BatchSaveItem item : request.getItems())
|
||||
{
|
||||
if (item == null) continue;
|
||||
if (StringUtils.isBlank(item.getLangCode()) || StringUtils.isBlank(item.getKey()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// 安全校验:禁止写入未启用的语种或默认语种
|
||||
if (DEFAULT_LANG.equals(item.getLangCode()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!validLangs.contains(item.getLangCode()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
HuayangI18n row = new HuayangI18n();
|
||||
row.setLangCode(item.getLangCode());
|
||||
row.setI18nKey(item.getKey());
|
||||
row.setI18nValue(item.getValue());
|
||||
row.setPageModule(request.getPageModule());
|
||||
rows.add(row);
|
||||
}
|
||||
|
||||
if (rows.isEmpty())
|
||||
{
|
||||
return error("没有有效的条目可保存(语种未启用或缺失 key)");
|
||||
}
|
||||
|
||||
IHuayangI18nService.BatchUpsertStat stat =
|
||||
i18nService.batchUpsertTranslations(rows, getUsername());
|
||||
|
||||
Map<String, Object> data = new LinkedHashMap<>();
|
||||
data.put("upserted", stat.getUpserted());
|
||||
data.put("deleted", stat.getDeleted());
|
||||
return AjaxResult.success("保存成功", data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 全局完成度统计:每个页面 × 每个语种 → 已翻译数 / 总数
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('huayang:translation:list')")
|
||||
@GetMapping("/stats")
|
||||
public AjaxResult stats()
|
||||
{
|
||||
List<PageInfoVO> pages = scannerRegistry.listAllPages();
|
||||
List<String> targetLangs = resolveTargetLangCodes();
|
||||
List<Map<String, Object>> result = new ArrayList<>();
|
||||
|
||||
for (PageInfoVO page : pages)
|
||||
{
|
||||
ITranslationScanner scanner = scannerRegistry.getScanner(page.getPageModule());
|
||||
if (scanner == null) continue;
|
||||
// 实时扫描以获取总 key 数(数据量小,性能可接受;若数据量增长后可改为缓存)
|
||||
PageTranslationVO pageVO = scanner.scan(targetLangs);
|
||||
Map<String, Object> row = new LinkedHashMap<>();
|
||||
row.put("pageModule", page.getPageModule());
|
||||
row.put("pageName", page.getPageName());
|
||||
row.put("totalKeys", pageVO.getTotalKeys());
|
||||
row.put("translated", pageVO.getTranslatedByLang());
|
||||
result.add(row);
|
||||
}
|
||||
|
||||
Map<String, Object> data = new LinkedHashMap<>();
|
||||
data.put("targetLangs", targetLangs);
|
||||
data.put("pages", result);
|
||||
return success(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析当前启用、且非默认语种的目标语种列表
|
||||
*/
|
||||
private List<String> resolveTargetLangCodes()
|
||||
{
|
||||
List<HuayangLanguage> langs = languageService.selectEnabledLanguageList();
|
||||
if (langs == null) return Collections.emptyList();
|
||||
List<String> result = new ArrayList<>();
|
||||
for (HuayangLanguage l : langs)
|
||||
{
|
||||
if (l == null) continue;
|
||||
String code = l.getLangCode();
|
||||
if (StringUtils.isBlank(code) || DEFAULT_LANG.equals(code)) continue;
|
||||
result.add(code);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Set<Long> resolveSelectedMenuIds()
|
||||
{
|
||||
String value = siteConfigService.selectConfigValueByKey(MENU_SELECTION_CONFIG_KEY);
|
||||
if (StringUtils.isBlank(value))
|
||||
{
|
||||
return Collections.emptySet();
|
||||
}
|
||||
Set<Long> result = new LinkedHashSet<>();
|
||||
for (String part : value.split(","))
|
||||
{
|
||||
if (StringUtils.isBlank(part))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
String trimmed = part.trim();
|
||||
if (!trimmed.matches("\\d+"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
result.add(Long.valueOf(trimmed));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Set<String> resolveSelectedModules()
|
||||
{
|
||||
Set<Long> selectedIds = resolveSelectedMenuIds();
|
||||
if (selectedIds.isEmpty())
|
||||
{
|
||||
return Collections.emptySet();
|
||||
}
|
||||
Set<String> modules = new HashSet<>();
|
||||
for (SysMenu menu : sysMenuService.selectMenuList(new SysMenu(), getUserId()))
|
||||
{
|
||||
if (menu == null || !selectedIds.contains(menu.getMenuId()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
String module = resolveMenuModule(menu);
|
||||
if (StringUtils.isNotBlank(module))
|
||||
{
|
||||
modules.add(module);
|
||||
}
|
||||
}
|
||||
return modules;
|
||||
}
|
||||
|
||||
private Set<String> resolveAllowedSections(String pageModule)
|
||||
{
|
||||
Set<Long> selectedIds = resolveSelectedMenuIds();
|
||||
if (selectedIds.isEmpty())
|
||||
{
|
||||
return Collections.emptySet();
|
||||
}
|
||||
Set<String> sections = new LinkedHashSet<>();
|
||||
for (SysMenu menu : sysMenuService.selectMenuList(new SysMenu(), getUserId()))
|
||||
{
|
||||
if (menu == null || !selectedIds.contains(menu.getMenuId()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
String module = resolveMenuModule(menu);
|
||||
if (module == null || !module.equals(pageModule))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
String section = resolveSectionKey(pageModule, menu);
|
||||
if (StringUtils.isNotBlank(section))
|
||||
{
|
||||
sections.add(section);
|
||||
}
|
||||
}
|
||||
return sections;
|
||||
}
|
||||
|
||||
private String resolveMenuModule(SysMenu menu)
|
||||
{
|
||||
String component = lower(menu.getComponent());
|
||||
String path = lower(menu.getPath());
|
||||
String perms = lower(menu.getPerms());
|
||||
if (component.contains("homeworkbench")
|
||||
|| component.contains("huayang/home")
|
||||
|| component.contains("huayang/company")
|
||||
|| component.contains("huayang/fixedsection")
|
||||
|| path.contains("home")
|
||||
|| perms.startsWith("huayang:home")
|
||||
|| perms.startsWith("huayang:company")
|
||||
|| perms.startsWith("huayang:fixedsection"))
|
||||
{
|
||||
return "home";
|
||||
}
|
||||
if (component.contains("huayang/product")
|
||||
|| path.contains("product")
|
||||
|| perms.startsWith("huayang:product")
|
||||
|| perms.startsWith("huayang:productcategory")
|
||||
|| perms.startsWith("huayang:productinquiry")
|
||||
|| perms.startsWith("huayang:productbanner"))
|
||||
{
|
||||
return "product";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String resolveSectionKey(String pageModule, SysMenu menu)
|
||||
{
|
||||
String perms = lower(menu.getPerms());
|
||||
String path = lower(menu.getPath());
|
||||
String component = lower(menu.getComponent());
|
||||
|
||||
if ("product".equals(pageModule))
|
||||
{
|
||||
if (perms.equals("huayang:productcategory:list") || path.equals("productcategory") || component.contains("huayang/productcategory/index"))
|
||||
{
|
||||
return "category";
|
||||
}
|
||||
if (perms.equals("huayang:product:list") || path.equals("product") || component.contains("huayang/product/index"))
|
||||
{
|
||||
return "item";
|
||||
}
|
||||
}
|
||||
|
||||
// home 目前不细分到 section,避免误过滤
|
||||
return null;
|
||||
}
|
||||
|
||||
private void recalculatePageStats(PageTranslationVO page, List<String> targetLangs)
|
||||
{
|
||||
int totalKeys = 0;
|
||||
Map<String, Integer> translated = new LinkedHashMap<>();
|
||||
for (String lang : targetLangs)
|
||||
{
|
||||
translated.put(lang, 0);
|
||||
}
|
||||
for (TranslationSectionVO section : page.getSections())
|
||||
{
|
||||
if (section == null || section.getItems() == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for (var item : section.getItems())
|
||||
{
|
||||
if (item == null || item.getFields() == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for (var field : item.getFields())
|
||||
{
|
||||
if (field == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
totalKeys++;
|
||||
for (String lang : targetLangs)
|
||||
{
|
||||
if (field.getTranslations() != null
|
||||
&& field.getTranslations().get(lang) != null
|
||||
&& StringUtils.isNotBlank(field.getTranslations().get(lang).getValue()))
|
||||
{
|
||||
translated.put(lang, translated.get(lang) + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
page.setTotalKeys(totalKeys);
|
||||
page.setTranslatedByLang(translated);
|
||||
}
|
||||
|
||||
private List<SysMenu> filterTranslationCandidateMenus(List<SysMenu> menus)
|
||||
{
|
||||
if (menus == null)
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Map<Long, SysMenu> byId = new HashMap<>();
|
||||
for (SysMenu m : menus)
|
||||
{
|
||||
if (m != null && m.getMenuId() != null)
|
||||
{
|
||||
byId.put(m.getMenuId(), m);
|
||||
}
|
||||
}
|
||||
|
||||
Set<Long> includeIds = new HashSet<>();
|
||||
for (SysMenu m : menus)
|
||||
{
|
||||
if (m == null || m.getMenuId() == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!isTranslationRelatedMenu(m))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
includeIds.add(m.getMenuId());
|
||||
Long parentId = m.getParentId();
|
||||
while (parentId != null && parentId > 0 && byId.containsKey(parentId))
|
||||
{
|
||||
includeIds.add(parentId);
|
||||
parentId = byId.get(parentId).getParentId();
|
||||
}
|
||||
}
|
||||
|
||||
List<SysMenu> result = new ArrayList<>();
|
||||
for (SysMenu m : menus)
|
||||
{
|
||||
if (m != null && includeIds.contains(m.getMenuId()))
|
||||
{
|
||||
result.add(m);
|
||||
}
|
||||
}
|
||||
result.sort(Comparator.comparing(SysMenu::getParentId, Comparator.nullsLast(Long::compareTo))
|
||||
.thenComparing(SysMenu::getOrderNum, Comparator.nullsLast(Integer::compareTo))
|
||||
.thenComparing(SysMenu::getMenuId, Comparator.nullsLast(Long::compareTo)));
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean isTranslationRelatedMenu(SysMenu menu)
|
||||
{
|
||||
if (menu == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if ("底部导航栏显示".equals(menu.getMenuName()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
String menuType = lower(menu.getMenuType());
|
||||
if ("f".equals(menuType))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
String perms = lower(menu.getPerms());
|
||||
String component = lower(menu.getComponent());
|
||||
String path = lower(menu.getPath());
|
||||
return perms.startsWith("huayang:")
|
||||
|| component.startsWith("huayang/")
|
||||
|| path.startsWith("huayangsite/");
|
||||
}
|
||||
|
||||
private List<MenuTreeNode> toMenuTreeNodes(List<SysMenu> menus)
|
||||
{
|
||||
List<MenuTreeNode> result = new ArrayList<>();
|
||||
if (menus == null)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
for (SysMenu m : menus)
|
||||
{
|
||||
if (m == null || m.getMenuId() == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
MenuTreeNode node = new MenuTreeNode();
|
||||
node.setId(m.getMenuId());
|
||||
node.setLabel(m.getMenuName());
|
||||
node.setPageModule(resolveMenuModule(m));
|
||||
node.setSectionKey(resolveSectionKey(resolveMenuModule(m), m));
|
||||
node.setPath(m.getPath());
|
||||
node.setComponent(m.getComponent());
|
||||
node.setPerms(m.getPerms());
|
||||
node.setRemark(m.getRemark());
|
||||
node.setChildren(toMenuTreeNodes(m.getChildren()));
|
||||
result.add(node);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private String joinMenuIds(List<Long> menuIds)
|
||||
{
|
||||
if (menuIds == null || menuIds.isEmpty())
|
||||
{
|
||||
return "";
|
||||
}
|
||||
Set<Long> unique = new LinkedHashSet<>(menuIds);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Long id : unique)
|
||||
{
|
||||
if (id == null || id <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (sb.length() > 0)
|
||||
{
|
||||
sb.append(",");
|
||||
}
|
||||
sb.append(id);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String lower(String value)
|
||||
{
|
||||
return value == null ? "" : value.toLowerCase();
|
||||
}
|
||||
|
||||
// ============== 请求体 DTO ==============
|
||||
|
||||
public static class MenuTreeNode
|
||||
{
|
||||
private Long id;
|
||||
private String label;
|
||||
private String pageModule;
|
||||
private String sectionKey;
|
||||
private String path;
|
||||
private String component;
|
||||
private String perms;
|
||||
private String remark;
|
||||
private List<MenuTreeNode> children = new ArrayList<>();
|
||||
public Long getId() { return id; }
|
||||
public void setId(Long id) { this.id = id; }
|
||||
public String getLabel() { return label; }
|
||||
public void setLabel(String label) { this.label = label; }
|
||||
public String getPageModule() { return pageModule; }
|
||||
public void setPageModule(String pageModule) { this.pageModule = pageModule; }
|
||||
public String getSectionKey() { return sectionKey; }
|
||||
public void setSectionKey(String sectionKey) { this.sectionKey = sectionKey; }
|
||||
public String getPath() { return path; }
|
||||
public void setPath(String path) { this.path = path; }
|
||||
public String getComponent() { return component; }
|
||||
public void setComponent(String component) { this.component = component; }
|
||||
public String getPerms() { return perms; }
|
||||
public void setPerms(String perms) { this.perms = perms; }
|
||||
public String getRemark() { return remark; }
|
||||
public void setRemark(String remark) { this.remark = remark; }
|
||||
public List<MenuTreeNode> getChildren() { return children; }
|
||||
public void setChildren(List<MenuTreeNode> children) { this.children = children; }
|
||||
}
|
||||
|
||||
public static class MenuSelectionRequest
|
||||
{
|
||||
private List<Long> menuIds = new ArrayList<>();
|
||||
public List<Long> getMenuIds() { return menuIds; }
|
||||
public void setMenuIds(List<Long> menuIds) { this.menuIds = menuIds; }
|
||||
}
|
||||
|
||||
public static class BatchSaveRequest
|
||||
{
|
||||
private String pageModule;
|
||||
private List<BatchSaveItem> items;
|
||||
public String getPageModule() { return pageModule; }
|
||||
public void setPageModule(String pageModule) { this.pageModule = pageModule; }
|
||||
public List<BatchSaveItem> getItems() { return items; }
|
||||
public void setItems(List<BatchSaveItem> items) { this.items = items; }
|
||||
}
|
||||
|
||||
public static class BatchSaveItem
|
||||
{
|
||||
private String langCode;
|
||||
private String key;
|
||||
private String value;
|
||||
public String getLangCode() { return langCode; }
|
||||
public void setLangCode(String langCode) { this.langCode = langCode; }
|
||||
public String getKey() { return key; }
|
||||
public void setKey(String key) { this.key = key; }
|
||||
public String getValue() { return value; }
|
||||
public void setValue(String value) { this.value = value; }
|
||||
}
|
||||
}
|
||||
+275
-27
@@ -1,8 +1,12 @@
|
||||
package com.ruoyi.web.controller.site;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -10,6 +14,8 @@ import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.ruoyi.common.annotation.Anonymous;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
@@ -48,10 +54,31 @@ public class SiteCompanyController extends BaseController
|
||||
@Autowired
|
||||
private IHuayangI18nService i18nService;
|
||||
|
||||
/** 占位串完整匹配表(逗号分隔初始化),调整时请改此类静态代码块 */
|
||||
private static final int PLACEHOLDER_PLAIN_MAX_LEN = 200;
|
||||
|
||||
private static final int PLACEHOLDER_SINGLE_CHAR_REPEAT_MAX_LEN = 16;
|
||||
|
||||
private static final Set<String> PLACEHOLDER_EXACT_MATCH_SET;
|
||||
|
||||
static
|
||||
{
|
||||
Set<String> s = new HashSet<>();
|
||||
for (String part : "qq,qw,qwe,qwer,qweqwe,qweqeqe,qweqweqweqwe,qqq,qqqq,ww,www,wwww,vv,vvv,vvvv,test,xxx,asd,asdf".split(","))
|
||||
{
|
||||
String t = part.trim().toLowerCase(Locale.ROOT);
|
||||
if (!t.isEmpty())
|
||||
{
|
||||
s.add(t);
|
||||
}
|
||||
}
|
||||
PLACEHOLDER_EXACT_MATCH_SET = Collections.unmodifiableSet(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取公司简介分块。
|
||||
* <p>可选 {@code lang}:非 zh_cn 时,用 i18n key {@code company.section.{sectionCode}.title}、
|
||||
* {@code company.section.{sectionCode}.content} 覆盖(content 受库表 i18n_value 长度限制,长文建议后续扩展字段)。</p>
|
||||
* <p>可选 {@code lang}:非 zh_cn 时,优先 {@code extra_data.langContent}(翻译管理),缺省再用词典
|
||||
* {@code company.section.{sectionCode}.title|content}。</p>
|
||||
*/
|
||||
@GetMapping("/sections")
|
||||
public AjaxResult sections(@RequestParam(value = "lang", required = false) String lang)
|
||||
@@ -63,11 +90,22 @@ public class SiteCompanyController extends BaseController
|
||||
return success(list);
|
||||
}
|
||||
|
||||
/** 与门户 {@code normalizeLangCode} 对齐:query 可为 ja-JP、JA_JP、jp 等 */
|
||||
private static String normalizeSiteLang(String lang) {
|
||||
if (StringUtils.isBlank(lang)) {
|
||||
return "zh_cn";
|
||||
}
|
||||
return lang.trim().toLowerCase();
|
||||
String s = lang.trim().toLowerCase(Locale.ROOT).replace('-', '_');
|
||||
if (s.startsWith("zh")) {
|
||||
return "zh_cn";
|
||||
}
|
||||
if (s.startsWith("en")) {
|
||||
return "en_us";
|
||||
}
|
||||
if (s.startsWith("ja") || s.startsWith("jp")) {
|
||||
return "ja_jp";
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
private void applySectionLocale(String langNorm, List<HuayangCompanySection> list) {
|
||||
@@ -83,25 +121,207 @@ public class SiteCompanyController extends BaseController
|
||||
keys.add("company.section." + s.getSectionCode() + ".content");
|
||||
}
|
||||
Map<String, String> dict = i18nService.selectI18nValueMapByLangAndKeys(langNorm, keys);
|
||||
if (dict.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (HuayangCompanySection s : list) {
|
||||
if (StringUtils.isBlank(s.getSectionCode())) {
|
||||
continue;
|
||||
}
|
||||
String prefix = "company.section." + s.getSectionCode() + ".";
|
||||
String t = dict.get(prefix + "title");
|
||||
// 翻译管理写入的 extra_data.langContent 优先,但测试占位串不会下发到门户。
|
||||
// 无有效手工译文时再尝试 huayang_i18n 词典。
|
||||
String manualTitle = getManualLangTitleFromExtraData(s.getExtraData(), langNorm);
|
||||
String dictTitle = dict.get(prefix + "title");
|
||||
String t = pickBestLocalizedSectionText(manualTitle, dictTitle);
|
||||
if (StringUtils.isNotEmpty(t)) {
|
||||
s.setSectionTitle(t);
|
||||
}
|
||||
String c = dict.get(prefix + "content");
|
||||
String manualContent = getManualLangContentFromExtraData(s.getExtraData(), langNorm);
|
||||
String dictContent = dict.get(prefix + "content");
|
||||
String c = pickBestLocalizedSectionText(manualContent, dictContent);
|
||||
if (StringUtils.isNotEmpty(c)) {
|
||||
s.setSectionContent(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 手工译文(翻译管理)优先;无手工时再尝试词典。
|
||||
*/
|
||||
private static String pickBestLocalizedSectionText(String manual, String dict) {
|
||||
if (StringUtils.isNotBlank(manual) && !looksLikePlaceholderTranslation(manual)) {
|
||||
return manual.trim();
|
||||
}
|
||||
if (StringUtils.isNotBlank(dict) && !looksLikePlaceholderTranslation(dict)) {
|
||||
return dict;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 翻译后台误填的测试文案(完整匹配见 {@link #PLACEHOLDER_EXACT_MATCH_SET})。
|
||||
*/
|
||||
private static boolean looksLikePlaceholderTranslation(String raw) {
|
||||
if (StringUtils.isBlank(raw)) {
|
||||
return true;
|
||||
}
|
||||
String trimmed = raw.trim();
|
||||
String plain =
|
||||
trimmed.replaceAll("(?i)<br\\s*/?>", " ")
|
||||
.replaceAll("<[^>]+>", " ")
|
||||
.replaceAll(" ", " ")
|
||||
.replaceAll("\\s+", " ")
|
||||
.trim();
|
||||
if (StringUtils.isBlank(plain)) {
|
||||
return true;
|
||||
}
|
||||
if (plain.length() > PLACEHOLDER_PLAIN_MAX_LEN) {
|
||||
return false;
|
||||
}
|
||||
String lower = plain.toLowerCase(Locale.ROOT);
|
||||
if (PLACEHOLDER_EXACT_MATCH_SET.contains(lower)) {
|
||||
return true;
|
||||
}
|
||||
if (lower.matches("^(qwe|wer|asd|zxc|www|vvv|xxx)+$")) {
|
||||
return true;
|
||||
}
|
||||
if (plain.length() <= PLACEHOLDER_SINGLE_CHAR_REPEAT_MAX_LEN && plain.codePoints().distinct().count() == 1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 section.extra_data 解析手动翻译(标题)。
|
||||
* <p>约定:{@code langContent.{lang}} 可为 {@code {"title":"...","content":"..."}},
|
||||
* 标题从此处读取;旧版仅有正文 JSON 字符串时不返回标题。</p>
|
||||
*/
|
||||
private String getManualLangTitleFromExtraData(String extraData, String langNorm) {
|
||||
Object entry = getLangContentEntry(extraData, langNorm);
|
||||
if (!(entry instanceof JSONObject)) {
|
||||
return null;
|
||||
}
|
||||
String title = ((JSONObject) entry).getString("title");
|
||||
return StringUtils.isNotBlank(title) ? title : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 section.extra_data 解析手动翻译(正文)。
|
||||
* <p>约定:
|
||||
* <ul>
|
||||
* <li>新结构:{@code langContent.en_us} = {@code {"title":"...","content":"..."}}</li>
|
||||
* <li>旧结构:{@code langContent.en_us} = 整段 HTML 字符串(兼容)</li>
|
||||
* </ul>
|
||||
*/
|
||||
private String getManualLangContentFromExtraData(String extraData, String langNorm) {
|
||||
Object entry = getLangContentEntry(extraData, langNorm);
|
||||
if (entry instanceof JSONObject) {
|
||||
String content = ((JSONObject) entry).getString("content");
|
||||
return StringUtils.isNotBlank(content) ? content : null;
|
||||
}
|
||||
if (entry instanceof String) {
|
||||
String value = (String) entry;
|
||||
return StringUtils.isNotBlank(value) ? value : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Object getLangContentEntry(String extraData, String langNorm) {
|
||||
if (StringUtils.isBlank(extraData) || StringUtils.isBlank(langNorm)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
JSONObject root = JSON.parseObject(extraData);
|
||||
if (root == null) {
|
||||
return null;
|
||||
}
|
||||
JSONObject langContent = root.getJSONObject("langContent");
|
||||
if (langContent == null) {
|
||||
langContent = root.getJSONObject("lang_content");
|
||||
}
|
||||
if (langContent == null) {
|
||||
return null;
|
||||
}
|
||||
String canonical = normalizeSiteLang(langNorm);
|
||||
Object direct = langContent.get(canonical);
|
||||
if (direct != null) {
|
||||
return direct;
|
||||
}
|
||||
for (String k : langContent.keySet()) {
|
||||
if (canonical.equals(normalizeSiteLang(k))) {
|
||||
return langContent.get(k);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
} catch (Exception ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private String storeExtraJsonField(String extraData, String langNorm, String field) {
|
||||
Object entry = getLangContentEntry(extraData, langNorm);
|
||||
if (!(entry instanceof JSONObject)) {
|
||||
return null;
|
||||
}
|
||||
String v = ((JSONObject) entry).getString(field);
|
||||
return StringUtils.isNotBlank(v) && !looksLikePlaceholderTranslation(v) ? v : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 店面展示页(about_showcase)条目的多语言:i18n 或 extra_data.langContent 的 name/address/phone。
|
||||
*/
|
||||
private void applyAboutShowcaseStoreLocale(String langNorm, List<HuayangCompanyStore> list) {
|
||||
if ("zh_cn".equals(langNorm) || list == null || list.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<String> keys = new ArrayList<>();
|
||||
for (HuayangCompanyStore s : list) {
|
||||
if (s.getStoreId() == null) {
|
||||
continue;
|
||||
}
|
||||
String sid = String.valueOf(s.getStoreId());
|
||||
keys.add("company.store." + sid + ".name");
|
||||
keys.add("company.store." + sid + ".address");
|
||||
keys.add("company.store." + sid + ".phone");
|
||||
}
|
||||
Map<String, String> dict = i18nService.selectI18nValueMapByLangAndKeys(langNorm, keys);
|
||||
for (HuayangCompanyStore s : list) {
|
||||
if (s.getStoreId() == null) {
|
||||
continue;
|
||||
}
|
||||
String sid = String.valueOf(s.getStoreId());
|
||||
String p = "company.store." + sid + ".";
|
||||
|
||||
String name = dict.get(p + "name");
|
||||
if (StringUtils.isBlank(name)) {
|
||||
name = storeExtraJsonField(s.getExtraData(), langNorm, "name");
|
||||
}
|
||||
if (StringUtils.isBlank(name)) {
|
||||
name = storeExtraJsonField(s.getExtraData(), langNorm, "title");
|
||||
}
|
||||
if (StringUtils.isNotEmpty(name)) {
|
||||
s.setStoreName(name);
|
||||
}
|
||||
|
||||
String address = dict.get(p + "address");
|
||||
if (StringUtils.isBlank(address)) {
|
||||
address = storeExtraJsonField(s.getExtraData(), langNorm, "address");
|
||||
}
|
||||
if (StringUtils.isNotEmpty(address)) {
|
||||
s.setStoreAddress(address);
|
||||
}
|
||||
|
||||
String phone = dict.get(p + "phone");
|
||||
if (StringUtils.isBlank(phone)) {
|
||||
phone = storeExtraJsonField(s.getExtraData(), langNorm, "phone");
|
||||
}
|
||||
if (StringUtils.isBlank(phone)) {
|
||||
phone = storeExtraJsonField(s.getExtraData(), langNorm, "tel");
|
||||
}
|
||||
if (StringUtils.isNotEmpty(phone)) {
|
||||
s.setStorePhone(phone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取店面展示列表(首页等通用场景,不含页面专用/地图专表类型)
|
||||
*/
|
||||
@@ -117,29 +337,18 @@ public class SiteCompanyController extends BaseController
|
||||
return success(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 门户「发展历程」页底部店面轮播:仅 {@code store_type = history}
|
||||
*/
|
||||
@GetMapping("/stores/history")
|
||||
public AjaxResult storesForHistoryPage()
|
||||
{
|
||||
HuayangCompanyStore query = new HuayangCompanyStore();
|
||||
query.setStatus("0");
|
||||
query.setStoreType("history");
|
||||
List<HuayangCompanyStore> list = storeService.selectHuayangCompanyStoreList(query);
|
||||
return success(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 门户「店面展示页」(关于我们模块):仅 {@code store_type = about_showcase}
|
||||
* <p>可选 {@code lang}:详见 {@link #applyAboutShowcaseStoreLocale}。</p>
|
||||
*/
|
||||
@GetMapping("/stores/about-showcase")
|
||||
public AjaxResult storesForAboutPage()
|
||||
public AjaxResult storesForAboutPage(@RequestParam(value = "lang", required = false) String lang)
|
||||
{
|
||||
HuayangCompanyStore query = new HuayangCompanyStore();
|
||||
query.setStatus("0");
|
||||
query.setStoreType("about_showcase");
|
||||
List<HuayangCompanyStore> list = storeService.selectHuayangCompanyStoreList(query);
|
||||
applyAboutShowcaseStoreLocale(normalizeSiteLang(lang), list);
|
||||
return success(list);
|
||||
}
|
||||
|
||||
@@ -147,20 +356,20 @@ public class SiteCompanyController extends BaseController
|
||||
* 门户「全国门店」页左侧「店面位置」列表:仅 {@code store_type = map_location}
|
||||
*/
|
||||
@GetMapping("/stores/map-locations")
|
||||
public AjaxResult storesForMapPage()
|
||||
public AjaxResult storesForMapPage(@RequestParam(value = "lang", required = false) String lang)
|
||||
{
|
||||
HuayangCompanyStore query = new HuayangCompanyStore();
|
||||
query.setStatus("0");
|
||||
query.setStoreType("map_location");
|
||||
List<HuayangCompanyStore> list = storeService.selectHuayangCompanyStoreList(query);
|
||||
applyAboutShowcaseStoreLocale(normalizeSiteLang(lang), list);
|
||||
return success(list);
|
||||
}
|
||||
|
||||
/** 不参与通用 {@link #stores()} 列表的类型(专页/专块数据) */
|
||||
private static boolean isExcludedFromGeneralStoresList(String storeType)
|
||||
{
|
||||
return "history".equals(storeType) || "about_showcase".equals(storeType)
|
||||
|| "map_location".equals(storeType);
|
||||
return "about_showcase".equals(storeType) || "map_location".equals(storeType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -176,14 +385,53 @@ public class SiteCompanyController extends BaseController
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取品质技术列表
|
||||
* 获取品质技术列表。
|
||||
* <p>可选 {@code lang}:非 zh_cn 时,优先使用 {@code extra_data.langContent}(翻译管理手工保存),
|
||||
* 缺省再使用词典 {@code company.tech.{techId}.title|.content}。</p>
|
||||
*/
|
||||
@GetMapping("/tech")
|
||||
public AjaxResult techList()
|
||||
public AjaxResult techList(@RequestParam(value = "lang", required = false) String lang)
|
||||
{
|
||||
HuayangCompanyTech query = new HuayangCompanyTech();
|
||||
query.setStatus("0");
|
||||
List<HuayangCompanyTech> list = techService.selectHuayangCompanyTechList(query);
|
||||
applyTechLocale(normalizeSiteLang(lang), list);
|
||||
return success(list);
|
||||
}
|
||||
|
||||
private void applyTechLocale(String langNorm, List<HuayangCompanyTech> list) {
|
||||
if ("zh_cn".equals(langNorm) || list == null || list.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<String> keys = new ArrayList<>();
|
||||
for (HuayangCompanyTech t : list) {
|
||||
if (t.getTechId() == null) {
|
||||
continue;
|
||||
}
|
||||
String id = String.valueOf(t.getTechId());
|
||||
keys.add("company.tech." + id + ".title");
|
||||
keys.add("company.tech." + id + ".content");
|
||||
}
|
||||
Map<String, String> dict = i18nService.selectI18nValueMapByLangAndKeys(langNorm, keys);
|
||||
for (HuayangCompanyTech t : list) {
|
||||
if (t.getTechId() == null) {
|
||||
continue;
|
||||
}
|
||||
String id = String.valueOf(t.getTechId());
|
||||
String prefix = "company.tech." + id + ".";
|
||||
// 翻译管理写入的 extra_data.langContent 优先于词典:避免扫描任务把中文误写入 i18n 后盖住手工英/日文
|
||||
String manualTitle = getManualLangTitleFromExtraData(t.getExtraData(), langNorm);
|
||||
String dictTitle = dict.get(prefix + "title");
|
||||
String title = pickBestLocalizedSectionText(manualTitle, dictTitle);
|
||||
if (StringUtils.isNotEmpty(title)) {
|
||||
t.setTechTitle(title);
|
||||
}
|
||||
String manualContent = getManualLangContentFromExtraData(t.getExtraData(), langNorm);
|
||||
String dictContent = dict.get(prefix + "content");
|
||||
String content = pickBestLocalizedSectionText(manualContent, dictContent);
|
||||
if (StringUtils.isNotEmpty(content)) {
|
||||
t.setTechContent(content);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+73
-4
@@ -1,6 +1,8 @@
|
||||
package com.ruoyi.web.controller.site;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
@@ -13,7 +15,9 @@ import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.system.domain.HuayangCultureCategory;
|
||||
import com.ruoyi.system.domain.HuayangCultureTag;
|
||||
import com.ruoyi.system.service.IHuayangCultureCategoryService;
|
||||
import com.ruoyi.system.service.IHuayangI18nService;
|
||||
import com.ruoyi.system.service.IHuayangCultureTagService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* 门户:华阳文化页公开数据
|
||||
@@ -30,17 +34,22 @@ public class SiteCultureController extends BaseController
|
||||
@Autowired
|
||||
private IHuayangCultureTagService cultureTagService;
|
||||
|
||||
@Autowired
|
||||
private IHuayangI18nService i18nService;
|
||||
|
||||
@Anonymous
|
||||
@GetMapping("/categories/public")
|
||||
public AjaxResult categoriesPublic()
|
||||
public AjaxResult categoriesPublic(@RequestParam(value = "lang", required = false) String lang)
|
||||
{
|
||||
List<HuayangCultureCategory> list = cultureCategoryService.selectHuayangCultureCategoryPublicList();
|
||||
applyCultureCategoryLocale(normalizeSiteLang(lang), list);
|
||||
return success(list);
|
||||
}
|
||||
|
||||
@Anonymous
|
||||
@GetMapping("/tags/public")
|
||||
public AjaxResult tagsPublic(@RequestParam("categoryId") Long categoryId)
|
||||
public AjaxResult tagsPublic(@RequestParam("categoryId") Long categoryId,
|
||||
@RequestParam(value = "lang", required = false) String lang)
|
||||
{
|
||||
if (categoryId == null || categoryId <= 0)
|
||||
{
|
||||
@@ -52,12 +61,14 @@ public class SiteCultureController extends BaseController
|
||||
return error("分类不存在或已停用");
|
||||
}
|
||||
List<HuayangCultureTag> list = cultureTagService.selectHuayangCultureTagPublicListByCategoryId(categoryId);
|
||||
applyCultureTagLocale(normalizeSiteLang(lang), list);
|
||||
return success(list);
|
||||
}
|
||||
|
||||
@Anonymous
|
||||
@GetMapping("/tags/{tagId}/public")
|
||||
public AjaxResult tagDetailPublic(@PathVariable("tagId") Long tagId)
|
||||
public AjaxResult tagDetailPublic(@PathVariable("tagId") Long tagId,
|
||||
@RequestParam(value = "lang", required = false) String lang)
|
||||
{
|
||||
HuayangCultureTag tag = cultureTagService.selectHuayangCultureTagPublicById(tagId);
|
||||
if (tag == null)
|
||||
@@ -70,6 +81,64 @@ public class SiteCultureController extends BaseController
|
||||
return error("内容不存在或已下架");
|
||||
}
|
||||
cultureTagService.incrementReadCount(tagId);
|
||||
return success(cultureTagService.selectHuayangCultureTagById(tagId));
|
||||
HuayangCultureTag detail = cultureTagService.selectHuayangCultureTagById(tagId);
|
||||
applyCultureTagDetailLocale(normalizeSiteLang(lang), detail);
|
||||
return success(detail);
|
||||
}
|
||||
|
||||
private static String normalizeSiteLang(String lang) {
|
||||
if (StringUtils.isBlank(lang)) {
|
||||
return "zh_cn";
|
||||
}
|
||||
return lang.trim().toLowerCase();
|
||||
}
|
||||
|
||||
private void applyCultureCategoryLocale(String langNorm, List<HuayangCultureCategory> list) {
|
||||
if ("zh_cn".equals(langNorm) || list == null || list.isEmpty()) return;
|
||||
List<String> keys = new ArrayList<>();
|
||||
for (HuayangCultureCategory item : list) {
|
||||
if (item.getCategoryId() != null) {
|
||||
keys.add("culture.category." + item.getCategoryId() + ".name");
|
||||
}
|
||||
}
|
||||
Map<String, String> dict = i18nService.selectI18nValueMapByLangAndKeys(langNorm, keys);
|
||||
for (HuayangCultureCategory item : list) {
|
||||
if (item.getCategoryId() == null) continue;
|
||||
String v = dict.get("culture.category." + item.getCategoryId() + ".name");
|
||||
if (StringUtils.isNotEmpty(v)) item.setCategoryName(v);
|
||||
}
|
||||
}
|
||||
|
||||
private void applyCultureTagLocale(String langNorm, List<HuayangCultureTag> list) {
|
||||
if ("zh_cn".equals(langNorm) || list == null || list.isEmpty()) return;
|
||||
List<String> keys = new ArrayList<>();
|
||||
for (HuayangCultureTag item : list) {
|
||||
if (item.getTagId() != null) {
|
||||
keys.add("culture.tag." + item.getTagId() + ".title");
|
||||
keys.add("culture.tag." + item.getTagId() + ".content");
|
||||
}
|
||||
}
|
||||
Map<String, String> dict = i18nService.selectI18nValueMapByLangAndKeys(langNorm, keys);
|
||||
for (HuayangCultureTag item : list) {
|
||||
if (item.getTagId() == null) continue;
|
||||
String prefix = "culture.tag." + item.getTagId() + ".";
|
||||
String t = dict.get(prefix + "title");
|
||||
if (StringUtils.isNotEmpty(t)) item.setTagTitle(t);
|
||||
String c = dict.get(prefix + "content");
|
||||
if (StringUtils.isNotEmpty(c)) item.setTagContent(c);
|
||||
}
|
||||
}
|
||||
|
||||
private void applyCultureTagDetailLocale(String langNorm, HuayangCultureTag detail) {
|
||||
if ("zh_cn".equals(langNorm) || detail == null || detail.getTagId() == null) return;
|
||||
String prefix = "culture.tag." + detail.getTagId() + ".";
|
||||
List<String> keys = new ArrayList<>(2);
|
||||
keys.add(prefix + "title");
|
||||
keys.add(prefix + "content");
|
||||
Map<String, String> dict = i18nService.selectI18nValueMapByLangAndKeys(langNorm, keys);
|
||||
String t = dict.get(prefix + "title");
|
||||
if (StringUtils.isNotEmpty(t)) detail.setTagTitle(t);
|
||||
String c = dict.get(prefix + "content");
|
||||
if (StringUtils.isNotEmpty(c)) detail.setTagContent(c);
|
||||
}
|
||||
}
|
||||
+73
-27
@@ -3,6 +3,7 @@ package com.ruoyi.web.controller.site;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.ArrayList;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import com.ruoyi.common.annotation.Anonymous;
|
||||
@@ -10,10 +11,9 @@ import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.system.domain.HuayangContact;
|
||||
import com.ruoyi.system.domain.HuayangJoinApply;
|
||||
import com.ruoyi.system.domain.HuayangMessage;
|
||||
import com.ruoyi.system.service.IHuayangContactService;
|
||||
import com.ruoyi.system.service.IHuayangJoinApplyService;
|
||||
import com.ruoyi.system.service.IHuayangI18nService;
|
||||
import com.ruoyi.system.service.IHuayangMessageService;
|
||||
import com.ruoyi.system.service.IHuayangSiteConfigService;
|
||||
|
||||
@@ -33,34 +33,69 @@ public class SiteCustomerController extends BaseController
|
||||
private IHuayangMessageService messageService;
|
||||
|
||||
@Autowired
|
||||
private IHuayangJoinApplyService joinApplyService;
|
||||
private IHuayangSiteConfigService siteConfigService;
|
||||
|
||||
@Autowired
|
||||
private IHuayangSiteConfigService siteConfigService;
|
||||
private IHuayangI18nService i18nService;
|
||||
|
||||
/**
|
||||
* 获取联系信息(公开)
|
||||
*/
|
||||
@Anonymous
|
||||
@GetMapping("/contact/list")
|
||||
public AjaxResult contactList()
|
||||
public AjaxResult contactList(@RequestParam(value = "lang", required = false) String lang)
|
||||
{
|
||||
List<HuayangContact> list = contactService.selectEnabledContactList();
|
||||
Map<String, String> siteValueByType = new HashMap<>(3);
|
||||
siteValueByType.put("phone", siteConfigService.selectConfigValueByKey("contact_phone"));
|
||||
siteValueByType.put("email", siteConfigService.selectConfigValueByKey("contact_email"));
|
||||
siteValueByType.put("address", siteConfigService.selectConfigValueByKey("contact_address"));
|
||||
for (HuayangContact item : list)
|
||||
if (list == null || list.isEmpty())
|
||||
{
|
||||
String siteValue = siteValueByType.get(item.getContactType());
|
||||
if (StringUtils.isNotBlank(siteValue))
|
||||
list = buildFallbackContacts();
|
||||
}
|
||||
else
|
||||
{
|
||||
Map<String, String> siteValueByType = new HashMap<>(3);
|
||||
siteValueByType.put("phone", siteConfigService.selectConfigValueByKey("contact_phone"));
|
||||
siteValueByType.put("email", siteConfigService.selectConfigValueByKey("contact_email"));
|
||||
siteValueByType.put("address", siteConfigService.selectConfigValueByKey("contact_address"));
|
||||
for (HuayangContact item : list)
|
||||
{
|
||||
item.setContactValue(siteValue);
|
||||
if (item == null || StringUtils.isNotBlank(item.getContactValue()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
String siteValue = siteValueByType.get(item.getContactType());
|
||||
if (StringUtils.isNotBlank(siteValue))
|
||||
{
|
||||
item.setContactValue(siteValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
applyContactLocale(normalizeSiteLang(lang), list);
|
||||
return success(list);
|
||||
}
|
||||
|
||||
private List<HuayangContact> buildFallbackContacts()
|
||||
{
|
||||
List<HuayangContact> list = new ArrayList<>();
|
||||
appendConfigGroup(list, siteConfigService.selectConfigValueByKey("contact_phone"), "phone", "商务热线", 0);
|
||||
appendConfigGroup(list, siteConfigService.selectConfigValueByKey("contact_email"), "email", "E-mail", 1);
|
||||
appendConfigGroup(list, siteConfigService.selectConfigValueByKey("contact_address"), "address", "地址", 2);
|
||||
return list;
|
||||
}
|
||||
|
||||
private void appendConfigGroup(List<HuayangContact> list, String raw, String type, String defaultLabel, int sortOrder)
|
||||
{
|
||||
if (StringUtils.isBlank(raw))
|
||||
{
|
||||
return;
|
||||
}
|
||||
HuayangContact item = new HuayangContact();
|
||||
item.setContactType(type);
|
||||
item.setContactLabel(defaultLabel);
|
||||
item.setContactValue(raw.trim());
|
||||
item.setSortOrder(sortOrder);
|
||||
list.add(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交在线留言(公开)
|
||||
*/
|
||||
@@ -78,20 +113,31 @@ public class SiteCustomerController extends BaseController
|
||||
return error("提交失败,请稍后重试");
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交招商申请(公开)
|
||||
*/
|
||||
@Anonymous
|
||||
@PostMapping("/contact/join")
|
||||
public AjaxResult submitJoinApply(@RequestBody HuayangJoinApply apply)
|
||||
{
|
||||
apply.setCreateBy("anonymous");
|
||||
apply.setApplyStatus("0");
|
||||
int rows = joinApplyService.insertHuayangJoinApply(apply);
|
||||
if (rows > 0)
|
||||
{
|
||||
return success("申请提交成功,我们的招商经理会尽快与您联系!");
|
||||
private static String normalizeSiteLang(String lang) {
|
||||
if (StringUtils.isBlank(lang)) {
|
||||
return "zh_cn";
|
||||
}
|
||||
return lang.trim().toLowerCase();
|
||||
}
|
||||
|
||||
private void applyContactLocale(String langNorm, List<HuayangContact> list) {
|
||||
if ("zh_cn".equals(langNorm) || list == null || list.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<String> keys = new ArrayList<>(3);
|
||||
keys.add("contact.phone.label");
|
||||
keys.add("contact.email.label");
|
||||
keys.add("contact.address.label");
|
||||
Map<String, String> dict = i18nService.selectI18nValueMapByLangAndKeys(langNorm, keys);
|
||||
for (HuayangContact item : list) {
|
||||
if (item == null || StringUtils.isBlank(item.getContactType())) {
|
||||
continue;
|
||||
}
|
||||
String labelKey = "contact." + item.getContactType() + ".label";
|
||||
String translatedLabel = dict.get(labelKey);
|
||||
if (StringUtils.isNotBlank(translatedLabel)) {
|
||||
item.setContactLabel(translatedLabel);
|
||||
}
|
||||
}
|
||||
return error("提交失败,请稍后重试");
|
||||
}
|
||||
}
|
||||
+169
-6
@@ -1,14 +1,26 @@
|
||||
package com.ruoyi.web.controller.site;
|
||||
|
||||
import com.ruoyi.common.annotation.Anonymous;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.system.service.IHuayangFixedSectionService;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.ruoyi.common.annotation.Anonymous;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.system.domain.HuayangFixedSection;
|
||||
import com.ruoyi.system.domain.HuayangFixedSectionItem;
|
||||
import com.ruoyi.system.domain.HuayangI18n;
|
||||
import com.ruoyi.system.mapper.HuayangI18nMapper;
|
||||
import com.ruoyi.system.service.IHuayangFixedSectionService;
|
||||
import com.ruoyi.system.service.IHuayangI18nService;
|
||||
|
||||
/**
|
||||
* 门户固定板块公开接口
|
||||
@@ -18,15 +30,166 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
@RequestMapping("/site/fixedSection")
|
||||
public class SiteFixedSectionController extends BaseController
|
||||
{
|
||||
private static final String DEFAULT_LANG = "zh_cn";
|
||||
|
||||
@Autowired
|
||||
private IHuayangFixedSectionService fixedSectionService;
|
||||
|
||||
@Autowired
|
||||
private HuayangI18nMapper i18nMapper;
|
||||
|
||||
@Autowired
|
||||
private IHuayangI18nService i18nService;
|
||||
|
||||
/**
|
||||
* 按编码获取固定板块(包含启用子项)
|
||||
*/
|
||||
@GetMapping("/code/{sectionCode}")
|
||||
public AjaxResult getByCode(@PathVariable("sectionCode") String sectionCode)
|
||||
public AjaxResult getByCode(@PathVariable("sectionCode") String sectionCode,
|
||||
@RequestParam(value = "lang", required = false) String lang)
|
||||
{
|
||||
return success(fixedSectionService.selectHuayangFixedSectionByCode(sectionCode));
|
||||
HuayangFixedSection section = fixedSectionService.selectHuayangFixedSectionByCode(sectionCode);
|
||||
applyTranslations(section, normalizeLang(lang));
|
||||
return success(section);
|
||||
}
|
||||
|
||||
private void applyTranslations(HuayangFixedSection section, String lang)
|
||||
{
|
||||
if (section == null || DEFAULT_LANG.equals(lang))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String code = section.getSectionCode();
|
||||
if (StringUtils.isBlank(code))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<String> keys = new ArrayList<>();
|
||||
keys.add("home." + code + ".main.title");
|
||||
keys.add("home." + code + ".main.text");
|
||||
if (section.getItemList() != null)
|
||||
{
|
||||
for (HuayangFixedSectionItem item : section.getItemList())
|
||||
{
|
||||
if (item == null || item.getItemId() == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
keys.add("home." + code + ".item." + item.getItemId() + ".title");
|
||||
keys.add("home." + code + ".item." + item.getItemId() + ".desc");
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, String> translations = selectRawTranslations(lang, keys);
|
||||
if (translations == null || translations.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String mainTitle = translations.get("home." + code + ".main.title");
|
||||
if (StringUtils.isNotBlank(mainTitle))
|
||||
{
|
||||
section.setSectionName(mainTitle);
|
||||
}
|
||||
String mainText = translations.get("home." + code + ".main.text");
|
||||
if (StringUtils.isNotBlank(mainText))
|
||||
{
|
||||
section.setSectionText(mainText);
|
||||
}
|
||||
|
||||
if (section.getItemList() != null)
|
||||
{
|
||||
for (HuayangFixedSectionItem item : section.getItemList())
|
||||
{
|
||||
if (item == null || item.getItemId() == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
String prefix = "home." + code + ".item." + item.getItemId();
|
||||
String title = translations.get(prefix + ".title");
|
||||
if (StringUtils.isNotBlank(title))
|
||||
{
|
||||
item.setItemTitle(title);
|
||||
}
|
||||
String desc = translations.get(prefix + ".desc");
|
||||
if (StringUtils.isNotBlank(desc))
|
||||
{
|
||||
item.setItemDesc(desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, String> selectRawTranslations(String lang, List<String> keys)
|
||||
{
|
||||
Map<String, String> translations = new HashMap<>();
|
||||
if (StringUtils.isBlank(lang) || keys == null || keys.isEmpty())
|
||||
{
|
||||
return translations;
|
||||
}
|
||||
try
|
||||
{
|
||||
List<HuayangI18n> rows = i18nMapper.selectHuayangI18nByLangAndKeyList(lang, keys);
|
||||
if (rows != null)
|
||||
{
|
||||
for (HuayangI18n row : rows)
|
||||
{
|
||||
if (row != null && StringUtils.isNotBlank(row.getI18nKey()) && row.getI18nValue() != null)
|
||||
{
|
||||
translations.put(row.getI18nKey(), row.getI18nValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (RuntimeException | LinkageError ignored)
|
||||
{
|
||||
List<Map<String, String>> rows = i18nService.selectTranslationByLang(lang);
|
||||
if (rows == null)
|
||||
{
|
||||
return translations;
|
||||
}
|
||||
for (Map<String, String> row : rows)
|
||||
{
|
||||
String key = row.get("i18nKey");
|
||||
if (StringUtils.isBlank(key))
|
||||
{
|
||||
key = row.get("i18n_key");
|
||||
}
|
||||
if (!keys.contains(key))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
String value = row.get("i18nValue");
|
||||
if (value == null)
|
||||
{
|
||||
value = row.get("i18n_value");
|
||||
}
|
||||
if (value != null)
|
||||
{
|
||||
translations.put(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return translations;
|
||||
}
|
||||
|
||||
private String normalizeLang(String raw)
|
||||
{
|
||||
String value = StringUtils.defaultString(raw).trim().toLowerCase(Locale.ROOT).replace('-', '_');
|
||||
if (StringUtils.isBlank(value) || value.startsWith("zh"))
|
||||
{
|
||||
return DEFAULT_LANG;
|
||||
}
|
||||
if (value.startsWith("en"))
|
||||
{
|
||||
return "en_us";
|
||||
}
|
||||
if (value.startsWith("ja") || value.startsWith("jp"))
|
||||
{
|
||||
return "ja_jp";
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
+3
-37
@@ -6,12 +6,10 @@ import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.system.domain.HuayangHomeBanner;
|
||||
import com.ruoyi.system.domain.HuayangHomeFeature;
|
||||
import com.ruoyi.system.domain.HuayangProduct;
|
||||
import com.ruoyi.system.domain.HuayangNews;
|
||||
import com.ruoyi.system.service.IHuayangHomeBannerService;
|
||||
import com.ruoyi.system.service.IHuayangHomeFeatureService;
|
||||
import com.ruoyi.system.service.IHuayangI18nService;
|
||||
import com.ruoyi.system.service.IHuayangProductService;
|
||||
import com.ruoyi.system.service.IHuayangNewsService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
@@ -34,8 +32,6 @@ public class SiteHomeController extends BaseController {
|
||||
@Autowired
|
||||
private IHuayangProductService productService;
|
||||
@Autowired
|
||||
private IHuayangNewsService newsService;
|
||||
@Autowired
|
||||
private IHuayangI18nService i18nService;
|
||||
|
||||
/**
|
||||
@@ -45,7 +41,6 @@ public class SiteHomeController extends BaseController {
|
||||
* <li>轮播标题:{@code home.banner.{bannerId}.title}</li>
|
||||
* <li>特色标题/描述:{@code home.feature.{featureId}.title}、{@code home.feature.{featureId}.desc}</li>
|
||||
* <li>推荐产品名称:{@code home.product.{productId}.name}</li>
|
||||
* <li>推荐新闻标题:{@code home.news.{newsId}.title}</li>
|
||||
* </ul>
|
||||
*/
|
||||
@Anonymous
|
||||
@@ -59,25 +54,17 @@ public class SiteHomeController extends BaseController {
|
||||
queryFeature.setStatus("0");
|
||||
List<HuayangHomeFeature> features = featureService.selectHuayangHomeFeatureList(queryFeature);
|
||||
|
||||
// 首页推荐产品
|
||||
HuayangProduct queryProduct = new HuayangProduct();
|
||||
queryProduct.setStatus("0");
|
||||
queryProduct.setIsHome("1"); // 推荐到首页
|
||||
queryProduct.setIsHome("1");
|
||||
List<HuayangProduct> products = productService.selectHuayangProductList(queryProduct);
|
||||
|
||||
// 首页推荐新闻
|
||||
HuayangNews queryNews = new HuayangNews();
|
||||
queryNews.setStatus("0");
|
||||
queryNews.setIsHome("1"); // 推荐到首页
|
||||
List<HuayangNews> news = newsService.selectHuayangNewsList(queryNews);
|
||||
|
||||
applyHomePublicLocale(normalizeSiteLang(lang), banners, features, products, news);
|
||||
applyHomePublicLocale(normalizeSiteLang(lang), banners, features, products);
|
||||
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("banners", banners);
|
||||
data.put("features", features);
|
||||
data.put("products", products);
|
||||
data.put("news", news);
|
||||
return success(data);
|
||||
}
|
||||
|
||||
@@ -88,11 +75,8 @@ public class SiteHomeController extends BaseController {
|
||||
return lang.trim().toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* 中文库表为基准;其它语言在 huayang_i18n 中维护对应 key 后在此覆盖。
|
||||
*/
|
||||
private void applyHomePublicLocale(String langNorm, List<HuayangHomeBanner> banners,
|
||||
List<HuayangHomeFeature> features, List<HuayangProduct> products, List<HuayangNews> news) {
|
||||
List<HuayangHomeFeature> features, List<HuayangProduct> products) {
|
||||
if ("zh_cn".equals(langNorm)) {
|
||||
return;
|
||||
}
|
||||
@@ -119,13 +103,6 @@ public class SiteHomeController extends BaseController {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (news != null) {
|
||||
for (HuayangNews n : news) {
|
||||
if (n.getNewsId() != null) {
|
||||
keys.add("home.news." + n.getNewsId() + ".title");
|
||||
}
|
||||
}
|
||||
}
|
||||
Map<String, String> dict = i18nService.selectI18nValueMapByLangAndKeys(langNorm, keys);
|
||||
if (dict.isEmpty()) {
|
||||
return;
|
||||
@@ -167,16 +144,5 @@ public class SiteHomeController extends BaseController {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (news != null) {
|
||||
for (HuayangNews n : news) {
|
||||
if (n.getNewsId() == null) {
|
||||
continue;
|
||||
}
|
||||
String v = dict.get("home.news." + n.getNewsId() + ".title");
|
||||
if (StringUtils.isNotEmpty(v)) {
|
||||
n.setNewsTitle(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+61
-1
@@ -1,8 +1,12 @@
|
||||
package com.ruoyi.web.controller.site;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.ruoyi.common.annotation.Anonymous;
|
||||
@@ -10,6 +14,7 @@ import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.system.domain.HuayangCompanyHonor;
|
||||
import com.ruoyi.system.service.IHuayangCompanyHonorService;
|
||||
import com.ruoyi.system.service.IHuayangI18nService;
|
||||
|
||||
/**
|
||||
* 门户站点公开接口:资质荣誉
|
||||
@@ -23,14 +28,69 @@ public class SiteHonorController extends BaseController
|
||||
@Autowired
|
||||
private IHuayangCompanyHonorService huayangCompanyHonorService;
|
||||
|
||||
@Autowired
|
||||
private IHuayangI18nService i18nService;
|
||||
|
||||
/**
|
||||
* 对外公开:正常状态的资质荣誉列表(无需登录)
|
||||
*/
|
||||
@Anonymous
|
||||
@GetMapping("/public")
|
||||
public AjaxResult publicList()
|
||||
public AjaxResult publicList(@RequestParam(value = "lang", required = false) String lang)
|
||||
{
|
||||
List<HuayangCompanyHonor> list = huayangCompanyHonorService.selectHuayangCompanyHonorPublicList();
|
||||
applyHonorLocale(normalizeSiteLang(lang), list);
|
||||
return success(list);
|
||||
}
|
||||
|
||||
private static String normalizeSiteLang(String lang)
|
||||
{
|
||||
if (StringUtils.isBlank(lang))
|
||||
{
|
||||
return "zh_cn";
|
||||
}
|
||||
return lang.trim().toLowerCase();
|
||||
}
|
||||
|
||||
private void applyHonorLocale(String langNorm, List<HuayangCompanyHonor> list)
|
||||
{
|
||||
if ("zh_cn".equals(langNorm) || list == null || list.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
List<String> keys = new ArrayList<>();
|
||||
for (HuayangCompanyHonor item : list)
|
||||
{
|
||||
if (item == null || item.getHonorId() == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
keys.add("company.honor." + item.getHonorId() + ".title");
|
||||
keys.add("company.honor." + item.getHonorId() + ".desc");
|
||||
}
|
||||
if (keys.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
Map<String, String> dict = i18nService.selectI18nValueMapByLangAndKeys(langNorm, keys);
|
||||
for (HuayangCompanyHonor item : list)
|
||||
{
|
||||
if (item == null || item.getHonorId() == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
String titleKey = "company.honor." + item.getHonorId() + ".title";
|
||||
String descKey = "company.honor." + item.getHonorId() + ".desc";
|
||||
String title = dict.get(titleKey);
|
||||
String desc = dict.get(descKey);
|
||||
if (StringUtils.isNotBlank(title))
|
||||
{
|
||||
item.setHonorTitle(title);
|
||||
}
|
||||
if (StringUtils.isNotBlank(desc))
|
||||
{
|
||||
item.setHonorDesc(desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-148
@@ -1,148 +0,0 @@
|
||||
package com.ruoyi.web.controller.site;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.ruoyi.common.annotation.Anonymous;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.domain.entity.SysDictData;
|
||||
import com.ruoyi.system.domain.HuayangNews;
|
||||
import com.ruoyi.system.service.IHuayangNewsService;
|
||||
import com.ruoyi.system.service.ISysDictDataService;
|
||||
|
||||
/**
|
||||
* 门户站点公开接口:新闻动态
|
||||
*
|
||||
* @author huayang
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/site/news")
|
||||
public class SiteNewsController extends BaseController
|
||||
{
|
||||
private static final String NEWS_TYPE_DICT = "huayang_news_type";
|
||||
|
||||
@Autowired
|
||||
private IHuayangNewsService newsService;
|
||||
|
||||
@Autowired
|
||||
private ISysDictDataService dictDataService;
|
||||
|
||||
/**
|
||||
* 对外公开:新闻列表(支持类型筛选、分页)
|
||||
*/
|
||||
@Anonymous
|
||||
@GetMapping("/public")
|
||||
public AjaxResult publicList(
|
||||
@RequestParam(required = false) String newsType,
|
||||
@RequestParam(required = false) Integer pageNum,
|
||||
@RequestParam(required = false) Integer pageSize)
|
||||
{
|
||||
// 默认返回10条
|
||||
if (pageSize == null || pageSize <= 0) {
|
||||
pageSize = 10;
|
||||
}
|
||||
if (pageNum == null || pageNum <= 0) {
|
||||
pageNum = 1;
|
||||
}
|
||||
int offset = (pageNum - 1) * pageSize;
|
||||
long total = newsService.countNewsPublic(newsType);
|
||||
List<HuayangNews> list = newsService.selectNewsForHome(newsType, offset, pageSize);
|
||||
Map<String, Object> data = new HashMap<>(4);
|
||||
data.put("rows", list);
|
||||
data.put("total", total);
|
||||
return success(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对外公开:新闻详情
|
||||
*/
|
||||
@Anonymous
|
||||
@GetMapping("/{newsId}/public")
|
||||
public AjaxResult publicDetail(@PathVariable("newsId") Long newsId)
|
||||
{
|
||||
HuayangNews news = newsService.selectHuayangNewsById(newsId);
|
||||
if (news == null || !"0".equals(news.getStatus()))
|
||||
{
|
||||
return error("新闻不存在或已下架");
|
||||
}
|
||||
// 增加阅读次数
|
||||
newsService.incrementReadCount(newsId);
|
||||
return success(news);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对外公开:首页推荐新闻(与 /site/home/public 中 news 列表一致,供首页聚合接口失败时单独拉取)
|
||||
*/
|
||||
@Anonymous
|
||||
@GetMapping("/homeRecommend")
|
||||
public AjaxResult homeRecommend(@RequestParam(required = false) Integer limit)
|
||||
{
|
||||
if (limit == null || limit <= 0)
|
||||
{
|
||||
limit = 3;
|
||||
}
|
||||
if (limit > 20)
|
||||
{
|
||||
limit = 20;
|
||||
}
|
||||
HuayangNews query = new HuayangNews();
|
||||
query.setStatus("0");
|
||||
query.setIsHome("1");
|
||||
List<HuayangNews> list = newsService.selectHuayangNewsList(query);
|
||||
if (list == null)
|
||||
{
|
||||
list = List.of();
|
||||
}
|
||||
else if (list.size() > limit)
|
||||
{
|
||||
list = new ArrayList<>(list.subList(0, limit));
|
||||
}
|
||||
return success(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对外公开:获取最新新闻(用于首页展示)
|
||||
*/
|
||||
@Anonymous
|
||||
@GetMapping("/latest")
|
||||
public AjaxResult latestNews(
|
||||
@RequestParam(required = false) String newsType,
|
||||
@RequestParam(required = false) Integer limit)
|
||||
{
|
||||
if (limit == null || limit <= 0) {
|
||||
limit = 5;
|
||||
}
|
||||
List<HuayangNews> list = newsService.selectNewsForHome(newsType, null, limit);
|
||||
return success(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对外公开:新闻类型(来源 sys_dict_data,dict_type=huayang_news_type)
|
||||
*/
|
||||
@Anonymous
|
||||
@GetMapping("/types")
|
||||
public AjaxResult types()
|
||||
{
|
||||
SysDictData query = new SysDictData();
|
||||
query.setDictType(NEWS_TYPE_DICT);
|
||||
query.setStatus("0");
|
||||
List<SysDictData> list = dictDataService.selectDictDataList(query);
|
||||
List<Map<String, Object>> data = list.stream().map(item -> {
|
||||
Map<String, Object> row = new HashMap<>(4);
|
||||
row.put("label", item.getDictLabel());
|
||||
row.put("value", item.getDictValue());
|
||||
row.put("sort", item.getDictSort());
|
||||
return row;
|
||||
}).collect(Collectors.toList());
|
||||
return success(data);
|
||||
}
|
||||
}
|
||||
+73
-3
@@ -1,6 +1,8 @@
|
||||
package com.ruoyi.web.controller.site;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
@@ -17,7 +19,9 @@ import com.ruoyi.system.domain.HuayangProductCategory;
|
||||
import com.ruoyi.system.domain.HuayangProductInquiry;
|
||||
import com.ruoyi.system.service.IHuayangProductCategoryService;
|
||||
import com.ruoyi.system.service.IHuayangProductInquiryService;
|
||||
import com.ruoyi.system.service.IHuayangI18nService;
|
||||
import com.ruoyi.system.service.IHuayangProductService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* 门户站点公开接口:产品中心
|
||||
@@ -37,14 +41,18 @@ public class SiteProductController extends BaseController
|
||||
@Autowired
|
||||
private IHuayangProductInquiryService productInquiryService;
|
||||
|
||||
@Autowired
|
||||
private IHuayangI18nService i18nService;
|
||||
|
||||
/**
|
||||
* 对外公开:产品分类列表(无需登录)
|
||||
*/
|
||||
@Anonymous
|
||||
@GetMapping("/category/public")
|
||||
public AjaxResult publicCategoryList()
|
||||
public AjaxResult publicCategoryList(@RequestParam(required = false) String lang)
|
||||
{
|
||||
List<HuayangProductCategory> list = productCategoryService.selectHuayangProductCategoryPublicList();
|
||||
applyProductCategoryLocale(normalizeSiteLang(lang), list);
|
||||
return success(list);
|
||||
}
|
||||
|
||||
@@ -55,9 +63,11 @@ public class SiteProductController extends BaseController
|
||||
@GetMapping("/public")
|
||||
public AjaxResult publicList(
|
||||
@RequestParam(required = false) Long categoryId,
|
||||
@RequestParam(required = false) String keyword)
|
||||
@RequestParam(required = false) String keyword,
|
||||
@RequestParam(required = false) String lang)
|
||||
{
|
||||
List<HuayangProduct> list = productService.selectHuayangProductPublicList(categoryId, keyword);
|
||||
applyProductLocale(normalizeSiteLang(lang), list);
|
||||
return success(list);
|
||||
}
|
||||
|
||||
@@ -66,13 +76,15 @@ public class SiteProductController extends BaseController
|
||||
*/
|
||||
@Anonymous
|
||||
@GetMapping("/{productId}/public")
|
||||
public AjaxResult publicDetail(@PathVariable("productId") Long productId)
|
||||
public AjaxResult publicDetail(@PathVariable("productId") Long productId,
|
||||
@RequestParam(required = false) String lang)
|
||||
{
|
||||
HuayangProduct product = productService.selectHuayangProductById(productId);
|
||||
if (product == null || !"0".equals(product.getStatus()))
|
||||
{
|
||||
return error("产品不存在或已下架");
|
||||
}
|
||||
applyProductDetailLocale(normalizeSiteLang(lang), product);
|
||||
return success(product);
|
||||
}
|
||||
|
||||
@@ -93,4 +105,62 @@ public class SiteProductController extends BaseController
|
||||
}
|
||||
return error("提交失败,请稍后重试");
|
||||
}
|
||||
|
||||
private static String normalizeSiteLang(String lang) {
|
||||
if (StringUtils.isBlank(lang)) {
|
||||
return "zh_cn";
|
||||
}
|
||||
return lang.trim().toLowerCase();
|
||||
}
|
||||
|
||||
private void applyProductCategoryLocale(String langNorm, List<HuayangProductCategory> list) {
|
||||
if ("zh_cn".equals(langNorm) || list == null || list.isEmpty()) return;
|
||||
List<String> keys = new ArrayList<>();
|
||||
for (HuayangProductCategory item : list) {
|
||||
if (item.getCategoryId() != null) {
|
||||
keys.add("product.category." + item.getCategoryId() + ".name");
|
||||
}
|
||||
}
|
||||
Map<String, String> dict = i18nService.selectI18nValueMapByLangAndKeys(langNorm, keys);
|
||||
for (HuayangProductCategory item : list) {
|
||||
if (item.getCategoryId() == null) continue;
|
||||
String v = dict.get("product.category." + item.getCategoryId() + ".name");
|
||||
if (StringUtils.isNotEmpty(v)) {
|
||||
item.setCategoryName(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void applyProductLocale(String langNorm, List<HuayangProduct> list) {
|
||||
if ("zh_cn".equals(langNorm) || list == null || list.isEmpty()) return;
|
||||
List<String> keys = new ArrayList<>();
|
||||
for (HuayangProduct item : list) {
|
||||
if (item.getProductId() != null) {
|
||||
keys.add("product.item." + item.getProductId() + ".name");
|
||||
keys.add("product.item." + item.getProductId() + ".desc");
|
||||
}
|
||||
}
|
||||
Map<String, String> dict = i18nService.selectI18nValueMapByLangAndKeys(langNorm, keys);
|
||||
for (HuayangProduct item : list) {
|
||||
if (item.getProductId() == null) continue;
|
||||
String prefix = "product.item." + item.getProductId() + ".";
|
||||
String n = dict.get(prefix + "name");
|
||||
if (StringUtils.isNotEmpty(n)) item.setProductName(n);
|
||||
String d = dict.get(prefix + "desc");
|
||||
if (StringUtils.isNotEmpty(d)) item.setProductDesc(d);
|
||||
}
|
||||
}
|
||||
|
||||
private void applyProductDetailLocale(String langNorm, HuayangProduct product) {
|
||||
if ("zh_cn".equals(langNorm) || product == null || product.getProductId() == null) return;
|
||||
List<String> keys = new ArrayList<>();
|
||||
String prefix = "product.item." + product.getProductId() + ".";
|
||||
keys.add(prefix + "name");
|
||||
keys.add(prefix + "desc");
|
||||
Map<String, String> dict = i18nService.selectI18nValueMapByLangAndKeys(langNorm, keys);
|
||||
String n = dict.get(prefix + "name");
|
||||
if (StringUtils.isNotEmpty(n)) product.setProductName(n);
|
||||
String d = dict.get(prefix + "desc");
|
||||
if (StringUtils.isNotEmpty(d)) product.setProductDesc(d);
|
||||
}
|
||||
}
|
||||
+1
-13
@@ -12,9 +12,7 @@ import com.ruoyi.common.annotation.Anonymous;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.system.domain.HuayangProduct;
|
||||
import com.ruoyi.system.domain.HuayangNews;
|
||||
import com.ruoyi.system.service.IHuayangProductService;
|
||||
import com.ruoyi.system.service.IHuayangNewsService;
|
||||
|
||||
/**
|
||||
* 全站搜索接口
|
||||
@@ -29,11 +27,8 @@ public class SiteSearchController extends BaseController
|
||||
@Autowired
|
||||
private IHuayangProductService productService;
|
||||
|
||||
@Autowired
|
||||
private IHuayangNewsService newsService;
|
||||
|
||||
/**
|
||||
* 根据关键词搜索产品和新闻
|
||||
* 根据关键词搜索产品
|
||||
*/
|
||||
@GetMapping("/all")
|
||||
public AjaxResult search(@RequestParam(value = "keyword", required = false) String keyword)
|
||||
@@ -41,17 +36,10 @@ public class SiteSearchController extends BaseController
|
||||
Map<String, Object> results = new HashMap<>();
|
||||
|
||||
if (keyword != null && !keyword.trim().isEmpty()) {
|
||||
// 搜索产品
|
||||
HuayangProduct productQuery = new HuayangProduct();
|
||||
productQuery.setProductName(keyword);
|
||||
List<HuayangProduct> products = productService.selectHuayangProductList(productQuery);
|
||||
results.put("products", products);
|
||||
|
||||
// 搜索新闻
|
||||
HuayangNews newsQuery = new HuayangNews();
|
||||
newsQuery.setNewsTitle(keyword);
|
||||
List<HuayangNews> news = newsService.selectHuayangNewsList(newsQuery);
|
||||
results.put("news", news);
|
||||
}
|
||||
|
||||
return success(results);
|
||||
|
||||
+126
-2
@@ -1,15 +1,22 @@
|
||||
package com.ruoyi.web.controller.site;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.ruoyi.common.annotation.Anonymous;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.system.domain.HuayangCompanyTimeline;
|
||||
import com.ruoyi.system.service.IHuayangCompanyTimelineService;
|
||||
import com.ruoyi.system.service.IHuayangI18nService;
|
||||
|
||||
/**
|
||||
* 门户站点公开接口:发展历程
|
||||
@@ -23,14 +30,131 @@ public class SiteTimelineController extends BaseController
|
||||
@Autowired
|
||||
private IHuayangCompanyTimelineService huayangCompanyTimelineService;
|
||||
|
||||
@Autowired
|
||||
private IHuayangI18nService i18nService;
|
||||
|
||||
/**
|
||||
* 对外公开:正常状态的发展历程列表(无需登录)
|
||||
* 对外公开:正常状态的发展历程列表(无需登录)。
|
||||
* <p>可选 {@code lang}:非 zh_cn 时用 i18n key {@code company.timeline.{timelineId}.title|summary|detail},
|
||||
* 暂无则读 {@code extra_data.langContent}(对象字段 title、summary、detail;旧版整段字符串视为 detail)。</p>
|
||||
*/
|
||||
@Anonymous
|
||||
@GetMapping("/public")
|
||||
public AjaxResult publicList()
|
||||
public AjaxResult publicList(@RequestParam(value = "lang", required = false) String lang)
|
||||
{
|
||||
List<HuayangCompanyTimeline> list = huayangCompanyTimelineService.selectHuayangCompanyTimelinePublicList();
|
||||
applyTimelineLocale(normalizeSiteLang(lang), list);
|
||||
return success(list);
|
||||
}
|
||||
|
||||
private static String normalizeSiteLang(String lang) {
|
||||
if (StringUtils.isBlank(lang)) {
|
||||
return "zh_cn";
|
||||
}
|
||||
return lang.trim().toLowerCase();
|
||||
}
|
||||
|
||||
private void applyTimelineLocale(String langNorm, List<HuayangCompanyTimeline> list)
|
||||
{
|
||||
if ("zh_cn".equals(langNorm) || list == null || list.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<String> keys = new ArrayList<>();
|
||||
for (HuayangCompanyTimeline t : list) {
|
||||
if (t.getTimelineId() == null) {
|
||||
continue;
|
||||
}
|
||||
String id = String.valueOf(t.getTimelineId());
|
||||
keys.add("company.timeline." + id + ".title");
|
||||
keys.add("company.timeline." + id + ".summary");
|
||||
keys.add("company.timeline." + id + ".detail");
|
||||
}
|
||||
Map<String, String> dict = i18nService.selectI18nValueMapByLangAndKeys(langNorm, keys);
|
||||
for (HuayangCompanyTimeline t : list) {
|
||||
if (t.getTimelineId() == null) {
|
||||
continue;
|
||||
}
|
||||
String id = String.valueOf(t.getTimelineId());
|
||||
String p = "company.timeline." + id + ".";
|
||||
|
||||
String title = dict.get(p + "title");
|
||||
if (StringUtils.isBlank(title)) {
|
||||
title = timelineManualField(t.getExtraData(), langNorm, "title");
|
||||
}
|
||||
if (StringUtils.isNotEmpty(title)) {
|
||||
t.setEventTitle(title);
|
||||
}
|
||||
|
||||
String summary = dict.get(p + "summary");
|
||||
if (StringUtils.isBlank(summary)) {
|
||||
summary = timelineManualField(t.getExtraData(), langNorm, "summary");
|
||||
}
|
||||
if (StringUtils.isNotEmpty(summary)) {
|
||||
t.setEventContent(summary);
|
||||
}
|
||||
|
||||
String detail = dict.get(p + "detail");
|
||||
if (StringUtils.isBlank(detail)) {
|
||||
detail = timelineManualDetailFromExtra(t.getExtraData(), langNorm);
|
||||
}
|
||||
if (StringUtils.isNotEmpty(detail)) {
|
||||
t.setEventDetail(detail);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String timelineManualField(String extraData, String langNorm, String field)
|
||||
{
|
||||
Object entry = getLangContentEntry(extraData, langNorm);
|
||||
if (entry instanceof JSONObject) {
|
||||
JSONObject o = (JSONObject) entry;
|
||||
if ("summary".equals(field)) {
|
||||
String s = o.getString("summary");
|
||||
if (StringUtils.isBlank(s)) {
|
||||
s = o.getString("content");
|
||||
}
|
||||
return StringUtils.isNotBlank(s) ? s : null;
|
||||
}
|
||||
if ("title".equals(field)) {
|
||||
String s = o.getString("title");
|
||||
return StringUtils.isNotBlank(s) ? s : null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** summary/detail 落空时:旧版仅存一段字符串 → 视作 detail */
|
||||
private String timelineManualDetailFromExtra(String extraData, String langNorm)
|
||||
{
|
||||
Object entry = getLangContentEntry(extraData, langNorm);
|
||||
if (entry instanceof JSONObject) {
|
||||
String detail = ((JSONObject) entry).getString("detail");
|
||||
return StringUtils.isNotBlank(detail) ? detail : null;
|
||||
}
|
||||
if (entry instanceof String) {
|
||||
String s = (String) entry;
|
||||
return StringUtils.isNotBlank(s) ? s : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Object getLangContentEntry(String extraData, String langNorm)
|
||||
{
|
||||
if (StringUtils.isBlank(extraData) || StringUtils.isBlank(langNorm)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
JSONObject root = JSON.parseObject(extraData);
|
||||
if (root == null) {
|
||||
return null;
|
||||
}
|
||||
JSONObject langContent = root.getJSONObject("langContent");
|
||||
if (langContent == null) {
|
||||
return null;
|
||||
}
|
||||
return langContent.get(langNorm);
|
||||
} catch (Exception ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-3
@@ -20,9 +20,8 @@ import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.common.utils.DateUtils;
|
||||
import com.ruoyi.common.utils.SecurityUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.file.FileUploadUtils;
|
||||
import com.ruoyi.common.utils.file.FileUtils;
|
||||
import com.ruoyi.common.utils.file.MimeTypeUtils;
|
||||
import com.ruoyi.common.utils.file.ImageUploadUtils;
|
||||
import com.ruoyi.framework.web.service.TokenService;
|
||||
import com.ruoyi.system.service.ISysUserService;
|
||||
|
||||
@@ -128,7 +127,7 @@ public class SysProfileController extends BaseController
|
||||
if (!file.isEmpty())
|
||||
{
|
||||
LoginUser loginUser = getLoginUser();
|
||||
String avatar = FileUploadUtils.upload(RuoYiConfig.getAvatarPath(), file, MimeTypeUtils.IMAGE_EXTENSION, true);
|
||||
String avatar = ImageUploadUtils.upload(RuoYiConfig.getAvatarPath(), file, true);
|
||||
if (userService.updateUserAvatar(loginUser.getUserId(), avatar))
|
||||
{
|
||||
String oldAvatar = loginUser.getUser().getAvatar();
|
||||
|
||||
@@ -6,9 +6,9 @@ spring:
|
||||
druid:
|
||||
# 主库数据源
|
||||
master:
|
||||
url: jdbc:mysql://localhost:3306/hauyang?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
||||
username: root
|
||||
password: root
|
||||
url: ${DB_URL:jdbc:mysql://localhost:3306/huayang?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true}
|
||||
username: ${DB_USERNAME:huayang}
|
||||
password: ${DB_PASSWORD:}
|
||||
# 从库数据源
|
||||
slave:
|
||||
# 从数据源开关/默认关闭
|
||||
@@ -58,4 +58,4 @@ spring:
|
||||
merge-sql: true
|
||||
wall:
|
||||
config:
|
||||
multi-statement-allow: true
|
||||
multi-statement-allow: true
|
||||
@@ -0,0 +1,17 @@
|
||||
# 生产环境(与 druid 数据源一起启用,例如:--spring.profiles.active=prod,druid)
|
||||
# 请在服务器用环境变量或独立配置覆盖:数据源、Redis、ruoyi.profile 上传目录、token.secret 等
|
||||
spring:
|
||||
devtools:
|
||||
restart:
|
||||
enabled: false
|
||||
|
||||
logging:
|
||||
level:
|
||||
com.ruoyi: info
|
||||
org.springframework: warn
|
||||
|
||||
springdoc:
|
||||
api-docs:
|
||||
enabled: false
|
||||
swagger-ui:
|
||||
enabled: false
|
||||
@@ -7,7 +7,8 @@ ruoyi:
|
||||
# 版权年份
|
||||
copyrightYear: 2026
|
||||
# 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
|
||||
profile: D:/ruoyi/uploadPath
|
||||
# 开发环境使用项目内目录,避免本机不存在 D:/ruoyi/uploadPath 时上传图全部 404
|
||||
profile: ./uploadPath
|
||||
# 获取ip地址开关
|
||||
addressEnabled: false
|
||||
# 验证码类型 math 数字计算 char 字符验证
|
||||
@@ -16,7 +17,7 @@ ruoyi:
|
||||
# 开发环境配置
|
||||
server:
|
||||
# 服务器的HTTP端口,默认为8080
|
||||
port: 8080
|
||||
port: 7003
|
||||
servlet:
|
||||
# 应用的访问路径
|
||||
context-path: /
|
||||
@@ -135,8 +136,7 @@ referer:
|
||||
# 防盗链开关
|
||||
enabled: false
|
||||
# 允许的域名列表
|
||||
allowed-domains: localhost,127.0.0.1,ruoyi.vip,www.ruoyi.vip
|
||||
|
||||
allowed-domains: localhost,127.0.0.1,192.168.1.159,ruoyi.vip,www.ruoyi.vip
|
||||
# 防止XSS攻击
|
||||
xss:
|
||||
# 过滤开关
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<!-- 日志存放路径 -->
|
||||
<property name="log.path" value="/home/ruoyi/logs" />
|
||||
<property name="log.path" value="./logs" />
|
||||
<!-- 日志输出格式 -->
|
||||
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
restart.include.json=/com.alibaba.fastjson2.*.jar
|
||||
@@ -1,61 +0,0 @@
|
||||
# 数据源配置
|
||||
spring:
|
||||
datasource:
|
||||
type: com.alibaba.druid.pool.DruidDataSource
|
||||
driverClassName: com.mysql.cj.jdbc.Driver
|
||||
druid:
|
||||
# 主库数据源
|
||||
master:
|
||||
url: jdbc:mysql://localhost:3306/hauyang?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
||||
username: root
|
||||
password: root
|
||||
# 从库数据源
|
||||
slave:
|
||||
# 从数据源开关/默认关闭
|
||||
enabled: false
|
||||
url:
|
||||
username:
|
||||
password:
|
||||
# 初始连接数
|
||||
initialSize: 5
|
||||
# 最小连接池数量
|
||||
minIdle: 10
|
||||
# 最大连接池数量
|
||||
maxActive: 20
|
||||
# 配置获取连接等待超时的时间
|
||||
maxWait: 60000
|
||||
# 配置连接超时时间
|
||||
connectTimeout: 30000
|
||||
# 配置网络超时时间
|
||||
socketTimeout: 60000
|
||||
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
|
||||
timeBetweenEvictionRunsMillis: 60000
|
||||
# 配置一个连接在池中最小生存的时间,单位是毫秒
|
||||
minEvictableIdleTimeMillis: 300000
|
||||
# 配置一个连接在池中最大生存的时间,单位是毫秒
|
||||
maxEvictableIdleTimeMillis: 900000
|
||||
# 配置检测连接是否有效
|
||||
validationQuery: SELECT 1 FROM DUAL
|
||||
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
|
||||
@@ -1,147 +0,0 @@
|
||||
# 项目相关配置
|
||||
ruoyi:
|
||||
# 名称
|
||||
name: RuoYi
|
||||
# 版本
|
||||
version: 3.9.2
|
||||
# 版权年份
|
||||
copyrightYear: 2026
|
||||
# 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
|
||||
profile: D:/ruoyi/uploadPath
|
||||
# 获取ip地址开关
|
||||
addressEnabled: false
|
||||
# 验证码类型 math 数字计算 char 字符验证
|
||||
captchaType: math
|
||||
|
||||
# 开发环境配置
|
||||
server:
|
||||
# 服务器的HTTP端口,默认为8080
|
||||
port: 8080
|
||||
servlet:
|
||||
# 应用的访问路径
|
||||
context-path: /
|
||||
tomcat:
|
||||
# tomcat的URI编码
|
||||
uri-encoding: UTF-8
|
||||
# 连接数满后的排队数,默认为100
|
||||
accept-count: 1000
|
||||
threads:
|
||||
# tomcat最大线程数,默认为200
|
||||
max: 800
|
||||
# Tomcat启动初始化的线程数,默认值10
|
||||
min-spare: 100
|
||||
|
||||
# 日志配置
|
||||
logging:
|
||||
level:
|
||||
com.ruoyi: debug
|
||||
org.springframework: warn
|
||||
|
||||
# 用户配置
|
||||
user:
|
||||
password:
|
||||
# 密码最大错误次数
|
||||
maxRetryCount: 5
|
||||
# 密码锁定时间(默认10分钟)
|
||||
lockTime: 10
|
||||
|
||||
# Spring配置
|
||||
spring:
|
||||
# 资源信息
|
||||
messages:
|
||||
# 国际化资源文件路径
|
||||
basename: i18n/messages
|
||||
profiles:
|
||||
active: druid
|
||||
# 文件上传
|
||||
servlet:
|
||||
multipart:
|
||||
# 单个文件大小
|
||||
max-file-size: 10MB
|
||||
# 设置总上传的文件大小
|
||||
max-request-size: 20MB
|
||||
jackson:
|
||||
time-zone: GMT+8
|
||||
date-format: yyyy-MM-dd HH:mm:ss
|
||||
# 服务模块
|
||||
devtools:
|
||||
restart:
|
||||
# 热部署开关
|
||||
enabled: true
|
||||
data:
|
||||
# redis 配置
|
||||
redis:
|
||||
# 地址
|
||||
host: localhost
|
||||
# 端口,默认为6379
|
||||
port: 6379
|
||||
# 数据库索引
|
||||
database: 0
|
||||
# 密码
|
||||
password:
|
||||
# 连接超时时间
|
||||
timeout: 10s
|
||||
lettuce:
|
||||
pool:
|
||||
# 连接池中的最小空闲连接
|
||||
min-idle: 0
|
||||
# 连接池中的最大空闲连接
|
||||
max-idle: 8
|
||||
# 连接池的最大数据库连接数
|
||||
max-active: 8
|
||||
# #连接池最大阻塞等待时间(使用负值表示没有限制)
|
||||
max-wait: -1ms
|
||||
|
||||
# token配置
|
||||
token:
|
||||
# 令牌自定义标识
|
||||
header: Authorization
|
||||
# 令牌密钥
|
||||
secret: abcdefghijklmnopqrstuvwxyz
|
||||
# 令牌有效期(默认30分钟)
|
||||
expireTime: 30
|
||||
|
||||
# MyBatis配置
|
||||
mybatis:
|
||||
# 搜索指定包别名
|
||||
typeAliasesPackage: com.ruoyi.**.domain
|
||||
# 配置mapper的扫描,找到所有的mapper.xml映射文件
|
||||
mapperLocations: classpath*:mapper/**/*Mapper.xml
|
||||
# 加载全局的配置文件
|
||||
configLocation: classpath:mybatis/mybatis-config.xml
|
||||
|
||||
# PageHelper分页插件
|
||||
pagehelper:
|
||||
helperDialect: mysql
|
||||
supportMethodsArguments: true
|
||||
params: count=countSql
|
||||
|
||||
# Springdoc配置
|
||||
springdoc:
|
||||
api-docs:
|
||||
path: /v3/api-docs
|
||||
swagger-ui:
|
||||
enabled: true
|
||||
path: /swagger-ui.html
|
||||
tags-sorter: alpha
|
||||
group-configs:
|
||||
- group: 'default'
|
||||
display-name: '测试模块'
|
||||
paths-to-match: '/**'
|
||||
packages-to-scan: com.ruoyi.web.controller.tool
|
||||
|
||||
# 防盗链配置
|
||||
referer:
|
||||
# 防盗链开关
|
||||
enabled: false
|
||||
# 允许的域名列表
|
||||
allowed-domains: localhost,127.0.0.1,ruoyi.vip,www.ruoyi.vip
|
||||
|
||||
# 防止XSS攻击
|
||||
xss:
|
||||
# 过滤开关
|
||||
enabled: true
|
||||
# 排除链接(多个用逗号分隔)
|
||||
excludes: /system/notice
|
||||
# 匹配链接
|
||||
urlPatterns: /system/*,/monitor/*,/tool/*
|
||||
@@ -1,24 +0,0 @@
|
||||
Application Version: ${ruoyi.version}
|
||||
Spring Boot Version: ${spring-boot.version}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// _ooOoo_ //
|
||||
// o8888888o //
|
||||
// 88" . "88 //
|
||||
// (| ^_^ |) //
|
||||
// O\ = /O //
|
||||
// ____/`---'\____ //
|
||||
// .' \\| |// `. //
|
||||
// / \\||| : |||// \ //
|
||||
// / _||||| -:- |||||- \ //
|
||||
// | | \\\ - /// | | //
|
||||
// | \_| ''\---/'' | | //
|
||||
// \ .-\__ `-` ___/-. / //
|
||||
// ___`. .' /--.--\ `. . ___ //
|
||||
// ."" '< `.___\_<|>_/___.' >'"". //
|
||||
// | | : `- \`.;`\ _ /`;.`/ - ` : | | //
|
||||
// \ \ `-. \_ __\ /__ _/ .-` / / //
|
||||
// ========`-.____`-.___\_____/___.-`____.-'======== //
|
||||
// `=---=' //
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //
|
||||
// 佛祖保佑 永不宕机 永无BUG //
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,38 +0,0 @@
|
||||
#错误消息
|
||||
not.null=* 必须填写
|
||||
user.jcaptcha.error=验证码错误
|
||||
user.jcaptcha.expire=验证码已失效
|
||||
user.not.exists=用户不存在/密码错误
|
||||
user.password.not.match=用户不存在/密码错误
|
||||
user.password.retry.limit.count=密码输入错误{0}次
|
||||
user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟
|
||||
user.password.delete=对不起,您的账号已被删除
|
||||
user.blocked=用户已封禁,请联系管理员
|
||||
role.blocked=角色已封禁,请联系管理员
|
||||
login.blocked=很遗憾,访问IP已被列入系统黑名单
|
||||
user.logout.success=退出成功
|
||||
|
||||
length.not.valid=长度必须在{min}到{max}个字符之间
|
||||
|
||||
user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头
|
||||
user.password.not.valid=* 5-50个字符
|
||||
|
||||
user.email.not.valid=邮箱格式错误
|
||||
user.mobile.phone.number.not.valid=手机号格式错误
|
||||
user.login.success=登录成功
|
||||
user.register.success=注册成功
|
||||
user.notfound=请重新登录
|
||||
user.forcelogout=管理员强制退出,请重新登录
|
||||
user.unknown.error=未知错误,请重新登录
|
||||
|
||||
##文件上传消息
|
||||
upload.exceed.maxSize=上传的文件大小超出限制的文件大小!<br/>允许的文件最大大小是:{0}MB!
|
||||
upload.filename.exceed.length=上传的文件名最长{0}个字符
|
||||
|
||||
##权限
|
||||
no.permission=您没有数据的权限,请联系管理员添加权限 [{0}]
|
||||
no.create.permission=您没有创建数据的权限,请联系管理员添加权限 [{0}]
|
||||
no.update.permission=您没有修改数据的权限,请联系管理员添加权限 [{0}]
|
||||
no.delete.permission=您没有删除数据的权限,请联系管理员添加权限 [{0}]
|
||||
no.export.permission=您没有导出数据的权限,请联系管理员添加权限 [{0}]
|
||||
no.view.permission=您没有查看数据的权限,请联系管理员添加权限 [{0}]
|
||||
@@ -1,93 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<!-- 日志存放路径 -->
|
||||
<property name="log.path" value="/home/ruoyi/logs" />
|
||||
<!-- 日志输出格式 -->
|
||||
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
|
||||
|
||||
<!-- 控制台输出 -->
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- 系统日志输出 -->
|
||||
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${log.path}/sys-info.log</file>
|
||||
<!-- 循环政策:基于时间创建日志文件 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 日志文件名格式 -->
|
||||
<fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
<!-- 日志最大的历史 60天 -->
|
||||
<maxHistory>60</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<!-- 过滤的级别 -->
|
||||
<level>INFO</level>
|
||||
<!-- 匹配时的操作:接收(记录) -->
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<!-- 不匹配时的操作:拒绝(不记录) -->
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${log.path}/sys-error.log</file>
|
||||
<!-- 循环政策:基于时间创建日志文件 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 日志文件名格式 -->
|
||||
<fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
<!-- 日志最大的历史 60天 -->
|
||||
<maxHistory>60</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<!-- 过滤的级别 -->
|
||||
<level>ERROR</level>
|
||||
<!-- 匹配时的操作:接收(记录) -->
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<!-- 不匹配时的操作:拒绝(不记录) -->
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<!-- 用户访问日志输出 -->
|
||||
<appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${log.path}/sys-user.log</file>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 按天回滚 daily -->
|
||||
<fileNamePattern>${log.path}/sys-user.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
<!-- 日志最大的历史 60天 -->
|
||||
<maxHistory>60</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- 系统模块日志级别控制 -->
|
||||
<logger name="com.ruoyi" level="info" />
|
||||
<!-- Spring日志级别控制 -->
|
||||
<logger name="org.springframework" level="warn" />
|
||||
|
||||
<root level="info">
|
||||
<appender-ref ref="console" />
|
||||
</root>
|
||||
|
||||
<!--系统操作日志-->
|
||||
<root level="info">
|
||||
<appender-ref ref="file_info" />
|
||||
<appender-ref ref="file_error" />
|
||||
</root>
|
||||
|
||||
<!--系统用户操作日志-->
|
||||
<logger name="sys-user" level="info">
|
||||
<appender-ref ref="sys-user"/>
|
||||
</logger>
|
||||
</configuration>
|
||||
@@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE configuration
|
||||
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-config.dtd">
|
||||
<configuration>
|
||||
<!-- 全局参数 -->
|
||||
<settings>
|
||||
<!-- 使全局的映射器启用或禁用缓存 -->
|
||||
<setting name="cacheEnabled" value="true" />
|
||||
<!-- 允许JDBC 支持自动生成主键 -->
|
||||
<setting name="useGeneratedKeys" value="true" />
|
||||
<!-- 配置默认的执行器.SIMPLE就是普通执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新 -->
|
||||
<setting name="defaultExecutorType" value="SIMPLE" />
|
||||
<!-- 指定 MyBatis 所用日志的具体实现 -->
|
||||
<setting name="logImpl" value="SLF4J" />
|
||||
<!-- 使用驼峰命名法转换字段 -->
|
||||
<!-- <setting name="mapUnderscoreToCamelCase" value="true"/> -->
|
||||
</settings>
|
||||
|
||||
</configuration>
|
||||
Loaded 100 of 1056 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user