Remove obsolete code and documentation
This commit is contained in:
@@ -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 文件");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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` 端口进程。
|
||||
@@ -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
|
||||
```
|
||||
|
||||
@@ -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` 后点击保存,页面展示强密码校验提示并拦截提交。
|
||||
@@ -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("新密码不能与旧密码相同");
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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">
|
||||
支持 PDF、CSV、Excel 格式文件,最多100个文件,单个文件不超过50MB
|
||||
<div>支持 PDF、CSV、XLSX 格式文件,最多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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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" },
|
||||
|
||||
Reference in New Issue
Block a user