Remove obsolete code and documentation

This commit is contained in:
wkc
2026-05-12 17:53:02 +08:00
parent 598f5dec1c
commit b822cc202e
9 changed files with 167 additions and 8 deletions

View File

@@ -71,9 +71,9 @@ public class CcdiFileUploadController extends BaseController {
return AjaxResult.error("文件名不能为空");
}
String lowerFileName = fileName.toLowerCase();
if (!lowerFileName.endsWith(".xlsx") && !lowerFileName.endsWith(".xls")
&& !lowerFileName.endsWith(".csv") && !lowerFileName.endsWith(".pdf")) {
return AjaxResult.error("文件 " + fileName + " 格式不支持, 仅支持 PDF, CSV, Excel 文件");
if (!lowerFileName.endsWith(".xlsx") && !lowerFileName.endsWith(".csv")
&& !lowerFileName.endsWith(".pdf")) {
return AjaxResult.error("文件 " + fileName + " 格式不支持, 仅支持 PDF, CSV, XLSX 文件");
}
}

View File

@@ -0,0 +1,26 @@
# 上传流水格式与行外命名提示实施记录
## 修改内容
- 更新项目详情“上传数据”页的“批量上传流水文件”弹窗提示,明确支持 `PDF``CSV``XLSX` 格式。
- 将批量上传前端格式校验收敛为 `.pdf``.csv``.xlsx`,错误提示统一使用 `XLSX` 表述。
- 同步后端 `/ccdi/file-upload/batch` 接口格式校验与错误提示,避免绕过前端上传 `.xls` 后出现页面与接口口径不一致。
- 在上传提示中补充行外流水文件命名规则:`客户身份证号-其他内容`
## 影响范围
- 前端文件:`ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue`
- 后端文件:`ccdi-project/src/main/java/com/ruoyi/ccdi/project/controller/CcdiFileUploadController.java`
- 影响功能:项目详情上传数据页的“上传流水”批量上传弹窗与批量上传接口格式校验。
## 验证情况
- `mvn -pl ccdi-project -am compile -DskipTests`:通过。
- `npm run lint -- --no-fix`:未执行,前端工程未配置 `lint` 脚本。
- `source ~/.nvm/nvm.sh && nvm use && npm run build:prod`:通过,仅存在既有包体积 warning。
- `sh bin/restart_java_backend.sh`:后端构建并启动成功。
- 前端使用 `nvm use` 后以 `npm_config_port=9528 npm run dev` 启动,真实页面进入项目详情“上传数据”页,点击“上传流水”后确认弹窗展示:
- `支持 PDF、CSV、XLSX 格式文件最多100个文件单个文件不超过50MB`
- `行外流水文件命名规则:客户身份证号-其他内容`
- 调用 `/ccdi/file-upload/batch` 上传伪装文件名 `test.xls`,接口返回 `文件 test.xls 格式不支持, 仅支持 PDF, CSV, XLSX 文件`
- 测试结束后已关闭本次启动的前端 `9528` 端口与后端 `62318` 端口进程。

View File

@@ -0,0 +1,43 @@
# PDF 中文字体离线文件下载记录
## 保存路径确认
- 实施记录保存路径:`docs/reports/implementation/2026-05-11-pdf-font-offline-download.md`
- 离线字体文件保存路径:`deploy/fonts/wqy-microhei.ttc`
## 背景
生产环境无法在线安装中文字体包,需要提前准备 PDF 导出使用的中文字体文件,保证生产配置项 `ccdi.report.pdf-font-path` 指向的字体可以离线放置。
## 修改内容
- 新增离线字体文件:`deploy/fonts/wqy-microhei.ttc`
- 字体来源Debian 官方包源 `fonts-wqy-microhei_0.2.0-beta-4_all.deb`
- 从离线包中提取路径:`usr/share/fonts/truetype/wqy/wqy-microhei.ttc`
## 生产放置方式
生产服务器解压或上传后,将字体放到配置指定路径:
```bash
sudo mkdir -p /usr/share/fonts/truetype/wqy
sudo cp wqy-microhei.ttc /usr/share/fonts/truetype/wqy/wqy-microhei.ttc
sudo chmod 644 /usr/share/fonts/truetype/wqy/wqy-microhei.ttc
```
如果服务器存在 `fc-cache`,可执行:
```bash
sudo fc-cache -fv
```
## 验证记录
- 文件大小:约 4.9M
- 文件类型TrueType font collection data
- SHA256
```text
2420e8078af796b19a3f6ef13de527a1a91c1e7171eea115926c614ced1009b3
```

View File

@@ -0,0 +1,29 @@
# 用户修改密码强密码校验实施记录
## 保存路径检查
- 本次为功能修改实施记录,保存路径确认使用 `docs/reports/implementation/`
## 修改内容
- 后端新增 `PasswordStrengthUtils`,统一校验强密码规则。
- 个人中心修改密码接口 `/system/user/profile/updatePwd` 在旧密码正确后,校验新密码必须满足强密码要求,再校验新旧密码不能相同。
- 前端个人中心“修改密码”表单同步强密码校验提示,提交前拦截弱密码。
- 新增后端单元测试覆盖强密码通过、缺少字符类型、长度不合规、空白与非法字符等场景。
## 强密码规则
- 长度为 8 到 20 位。
- 必须同时包含大写字母、小写字母、数字和特殊字符。
- 不能包含空格或字符:`< > " ' \ |`
## 影响范围
- 影响用户个人中心修改密码功能。
- 不调整登录、注册、管理员新增用户、管理员重置密码等其他密码入口。
## 验证情况
- `mvn -pl ruoyi-admin -am -Dtest=PasswordStrengthUtilsTest -Dsurefire.failIfNoSpecifiedTests=false test`通过3 个强密码规则用例全部成功。
- `source ~/.nvm/nvm.sh && cd ruoyi-ui && nvm use && node -v && npm run build:prod`通过Node 版本为 `v14.21.3`;构建仅保留既有 asset size / entrypoint size 警告。
- 真实页面验证:登录 `http://localhost:9528/user/profile`,进入“修改密码”,输入新密码 `Abc12345` 后点击保存,页面展示强密码校验提示并拦截提交。

View File

@@ -18,6 +18,7 @@ import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.PasswordStrengthUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
@@ -98,10 +99,18 @@ public class SysProfileController extends BaseController
Long userId = loginUser.getUserId();
SysUser user = userService.selectUserById(userId);
String password = user.getPassword();
if (StringUtils.isEmpty(oldPassword))
{
return error("修改密码失败,旧密码错误");
}
if (!SecurityUtils.matchesPassword(oldPassword, password))
{
return error("修改密码失败,旧密码错误");
}
if (!PasswordStrengthUtils.isStrongPassword(newPassword))
{
return error(PasswordStrengthUtils.STRONG_PASSWORD_MESSAGE);
}
if (SecurityUtils.matchesPassword(newPassword, password))
{
return error("新密码不能与旧密码相同");

View File

@@ -0,0 +1,49 @@
package com.ruoyi.common.utils;
import java.util.regex.Pattern;
/**
* 密码强度校验工具
*/
public class PasswordStrengthUtils
{
public static final int STRONG_PASSWORD_MIN_LENGTH = 8;
public static final int STRONG_PASSWORD_MAX_LENGTH = 20;
public static final String STRONG_PASSWORD_MESSAGE = "新密码必须为8到20位并同时包含大写字母、小写字母、数字和特殊字符且不能包含空格或字符< > \" ' \\ |";
private static final Pattern UPPER_CASE_PATTERN = Pattern.compile("[A-Z]");
private static final Pattern LOWER_CASE_PATTERN = Pattern.compile("[a-z]");
private static final Pattern DIGIT_PATTERN = Pattern.compile("\\d");
private static final Pattern SPECIAL_CHAR_PATTERN = Pattern.compile("[^A-Za-z0-9\\s<>\"'|\\\\]");
private static final Pattern ILLEGAL_CHAR_PATTERN = Pattern.compile("[\\s<>\"'|\\\\]");
private PasswordStrengthUtils()
{
}
public static boolean isStrongPassword(String password)
{
if (StringUtils.isEmpty(password))
{
return false;
}
if (password.length() < STRONG_PASSWORD_MIN_LENGTH || password.length() > STRONG_PASSWORD_MAX_LENGTH)
{
return false;
}
if (ILLEGAL_CHAR_PATTERN.matcher(password).find())
{
return false;
}
return UPPER_CASE_PATTERN.matcher(password).find()
&& LOWER_CASE_PATTERN.matcher(password).find()
&& DIGIT_PATTERN.matcher(password).find()
&& SPECIAL_CHAR_PATTERN.matcher(password).find();
}
}

View File

@@ -219,7 +219,8 @@
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip">
支持 PDFCSVExcel 格式文件最多100个文件单个文件不超过50MB
<div>支持 PDFCSVXLSX 格式文件最多100个文件单个文件不超过50MB</div>
<div>行外流水文件命名规则客户身份证号-其他内容</div>
</div>
</el-upload>
@@ -650,14 +651,14 @@ export default {
fileList = fileList.slice(0, 100);
}
const validTypes = ['.pdf', '.csv', '.xlsx', '.xls'];
const validTypes = ['.pdf', '.csv', '.xlsx'];
const invalidFiles = fileList.filter((f) => {
const ext = f.name.substring(f.name.lastIndexOf(".")).toLowerCase();
return !validTypes.includes(ext);
});
if (invalidFiles.length > 0) {
this.$message.error("仅支持 PDF、CSV、Excel 格式文件");
this.$message.error("仅支持 PDF、CSV、XLSX 格式文件");
return;
}

View File

@@ -19,6 +19,9 @@
<script>
import { updateUserPwd } from "@/api/system/user"
const strongPasswordMessage = "新密码必须为8到20位并同时包含大写字母、小写字母、数字和特殊字符且不能包含空格或字符< > \" ' \\ |"
const strongPasswordPattern = /^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[^A-Za-z0-9\s<>"'|\\])[^<>"'|\\\s]{8,20}$/
export default {
data() {
const equalToPassword = (rule, value, callback) => {
@@ -41,8 +44,7 @@ export default {
],
newPassword: [
{ required: true, message: "新密码不能为空", trigger: "blur" },
{ min: 6, max: 20, message: "长度在 6 到 20 个字符", trigger: "blur" },
{ pattern: /^[^<>"'|\\]+$/, message: "不能包含非法字符:< > \" ' \\\ |", trigger: "blur" }
{ pattern: strongPasswordPattern, message: strongPasswordMessage, trigger: "blur" }
],
confirmPassword: [
{ required: true, message: "确认密码不能为空", trigger: "blur" },