Add file size update after upload
This commit is contained in:
@@ -656,6 +656,9 @@ public class CcdiFileUploadServiceImpl implements ICcdiFileUploadService {
|
|||||||
if (StringUtils.hasText(fileName)) {
|
if (StringUtils.hasText(fileName)) {
|
||||||
record.setFileName(fileName);
|
record.setFileName(fileName);
|
||||||
}
|
}
|
||||||
|
if (logItem.getFileSize() != null) {
|
||||||
|
record.setFileSize(logItem.getFileSize());
|
||||||
|
}
|
||||||
|
|
||||||
log.info("【文件上传】文件状态: status={}, uploadStatusDesc={}", status, uploadStatusDesc);
|
log.info("【文件上传】文件状态: status={}, uploadStatusDesc={}", status, uploadStatusDesc);
|
||||||
boolean parseSuccess = status != null && status == -5
|
boolean parseSuccess = status != null && status == -5
|
||||||
|
|||||||
@@ -223,31 +223,37 @@ class CcdiFileUploadServiceImplTest {
|
|||||||
verify(bankStatementMapper).deleteByProjectIdAndBatchId(PROJECT_ID, LOG_ID);
|
verify(bankStatementMapper).deleteByProjectIdAndBatchId(PROJECT_ID, LOG_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Test
|
@Test
|
||||||
// void processPullBankInfoAsync_shouldUpdateFileNameFromStatusResponse() {
|
void processPullBankInfoAsync_shouldUpdateFileSizeFromStatusResponse() {
|
||||||
// when(lsfxClient.fetchInnerFlow(any())).thenReturn(buildFetchInnerFlowResponse(LOG_ID));
|
GetFileUploadStatusResponse statusResponse = buildParsedSuccessStatusResponse("XX身份证.xlsx");
|
||||||
// when(lsfxClient.checkParseStatus(LSFX_PROJECT_ID, String.valueOf(LOG_ID)))
|
statusResponse.getData().getLogs().get(0).setFileSize(2048L);
|
||||||
// .thenReturn(buildCheckParseStatusResponse(false));
|
|
||||||
// when(lsfxClient.getFileUploadStatus(any())).thenReturn(buildParsedSuccessStatusResponse("XX身份证.xlsx"));
|
when(lsfxClient.fetchInnerFlow(any())).thenReturn(buildFetchInnerFlowResponse(LOG_ID));
|
||||||
// when(lsfxClient.getBankStatement(any(GetBankStatementRequest.class)))
|
when(lsfxClient.checkParseStatus(LSFX_PROJECT_ID, String.valueOf(LOG_ID)))
|
||||||
// .thenReturn(buildEmptyBankStatementResponse());
|
.thenReturn(buildCheckParseStatusResponse(false));
|
||||||
//
|
when(lsfxClient.getFileUploadStatus(any())).thenReturn(statusResponse);
|
||||||
// CcdiFileUploadRecord record = buildRecord();
|
when(lsfxClient.getBankStatement(any(GetBankStatementRequest.class)))
|
||||||
// service.processPullBankInfoAsync(
|
.thenReturn(buildEmptyBankStatementResponse());
|
||||||
// PROJECT_ID,
|
|
||||||
// LSFX_PROJECT_ID,
|
CcdiFileUploadRecord record = buildRecord();
|
||||||
// record,
|
record.setFileSize(0L);
|
||||||
// "110101199001018888",
|
|
||||||
// "2026-03-01",
|
service.processPullBankInfoAsync(
|
||||||
// "2026-03-10",
|
PROJECT_ID,
|
||||||
// 9527L
|
LSFX_PROJECT_ID,
|
||||||
// );
|
record,
|
||||||
//
|
"110101199001018888",
|
||||||
// verify(recordMapper, org.mockito.Mockito.atLeastOnce()).updateById(org.mockito.ArgumentMatchers.<CcdiFileUploadRecord>argThat(item ->
|
"2026-03-01",
|
||||||
// "XX身份证.xlsx".equals(item.getFileName())));
|
"2026-03-10"
|
||||||
// verify(recordMapper, org.mockito.Mockito.atLeastOnce()).updateById(org.mockito.ArgumentMatchers.<CcdiFileUploadRecord>argThat(item ->
|
);
|
||||||
// "parsed_success".equals(item.getFileStatus())));
|
|
||||||
// }
|
verify(recordMapper, org.mockito.Mockito.atLeastOnce()).updateById(
|
||||||
|
org.mockito.ArgumentMatchers.<CcdiFileUploadRecord>argThat(item ->
|
||||||
|
Long.valueOf(2048L).equals(item.getFileSize())
|
||||||
|
&& "XX身份证.xlsx".equals(item.getFileName())
|
||||||
|
&& "parsed_success".equals(item.getFileStatus()))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// @Test
|
// @Test
|
||||||
// void processPullBankInfoAsync_shouldMarkParsedFailedWhenFetchInnerFlowThrows() {
|
// void processPullBankInfoAsync_shouldMarkParsedFailedWhenFetchInnerFlowThrows() {
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
# Pull Bank Info Date Limit Backend Implementation Plan
|
||||||
|
|
||||||
|
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||||||
|
|
||||||
|
**Goal:** Confirm the new date restriction is fully handled in the frontend and does not require backend changes.
|
||||||
|
|
||||||
|
**Architecture:** The allowed date window is enforced in the Vue dialog before the request is submitted. The backend request contract remains `projectId`, `idCards`, `startDate`, and `endDate`, so this plan records a no-op backend implementation boundary and the verification needed to avoid accidental API changes.
|
||||||
|
|
||||||
|
**Tech Stack:** Java 21, Spring Boot 3, Maven, existing `ccdi-project` upload APIs
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 1: Verify backend impact is zero
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Review: `docs/plans/2026-03-12-pull-bank-info-date-limit-design.md`
|
||||||
|
- Review: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/controller/`
|
||||||
|
- Review: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/`
|
||||||
|
|
||||||
|
**Step 1: Confirm bug scope**
|
||||||
|
|
||||||
|
Check that the requirement only changes frontend date selection and frontend submit validation.
|
||||||
|
|
||||||
|
**Step 2: Verify request contract stays unchanged**
|
||||||
|
|
||||||
|
Confirm the request still submits the same fields:
|
||||||
|
|
||||||
|
- `projectId`
|
||||||
|
- `idCards`
|
||||||
|
- `startDate`
|
||||||
|
- `endDate`
|
||||||
|
|
||||||
|
**Step 3: Keep backend code unchanged**
|
||||||
|
|
||||||
|
Do not modify controller, service, mapper, DTO, or test classes for this task.
|
||||||
45
docs/plans/2026-03-12-pull-bank-info-date-limit-design.md
Normal file
45
docs/plans/2026-03-12-pull-bank-info-date-limit-design.md
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
# 拉取本行信息日期范围限制设计
|
||||||
|
|
||||||
|
## 背景
|
||||||
|
项目详情页“上传数据”中的“拉取本行信息”弹窗当前允许选择今天及未来日期,这与业务规则不符。用户只能拉取截止到当前日期前一天的数据。
|
||||||
|
|
||||||
|
## 目标
|
||||||
|
- 日期范围组件中禁用今天及未来日期
|
||||||
|
- 提交时兜底校验,阻止异常方式带入今天或未来日期
|
||||||
|
- 保持现有接口、文件解析和弹窗结构不变
|
||||||
|
|
||||||
|
## 非目标
|
||||||
|
- 不调整后端接口
|
||||||
|
- 不修改现有日期范围字段格式
|
||||||
|
- 不改变“至少输入一个身份证号”和“必须完整选择时间跨度”的现有校验
|
||||||
|
|
||||||
|
## 方案对比
|
||||||
|
|
||||||
|
### 方案一:仅在日期面板禁选
|
||||||
|
- 优点:改动最小,交互直观
|
||||||
|
- 缺点:若后续通过脚本赋值或异常回填带入无效日期,提交时缺少保护
|
||||||
|
|
||||||
|
### 方案二:仅在提交时校验
|
||||||
|
- 优点:实现简单
|
||||||
|
- 缺点:用户仍然可以在面板中选到无效日期,体验较差
|
||||||
|
|
||||||
|
### 方案三:日期面板禁选 + 提交兜底校验
|
||||||
|
- 优点:同时覆盖交互层和数据层,最稳妥
|
||||||
|
- 缺点:多一小段前端校验逻辑
|
||||||
|
|
||||||
|
## 最终方案
|
||||||
|
采用方案三。
|
||||||
|
|
||||||
|
在前端日期范围选择器上增加 `picker-options.disabledDate`,将本地当前日期零点及之后的日期全部禁用。以 `2026-03-12` 为例,最晚只能选择到 `2026-03-11`。
|
||||||
|
|
||||||
|
在提交逻辑中新增“最大可选日期”为昨天的兜底校验。如果开始日期或结束日期晚于昨天,则阻止提交并提示“时间跨度最晚只能选择到昨天”。
|
||||||
|
|
||||||
|
## 影响范围
|
||||||
|
- 前端组件:`ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue`
|
||||||
|
- 前端测试:`ruoyi-ui/tests/unit/`
|
||||||
|
- 后端:无代码改动,仅保留接口契约不变
|
||||||
|
|
||||||
|
## 验收标准
|
||||||
|
- 日期面板无法选择今天和未来日期
|
||||||
|
- 通过异常赋值带入今天或未来日期时,提交会被拦截
|
||||||
|
- 原有弹窗交互和上传相关逻辑无回归
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
# Pull Bank Info Date Limit Frontend Implementation Plan
|
||||||
|
|
||||||
|
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||||||
|
|
||||||
|
**Goal:** Restrict the pull-bank-info date range so users can only select dates up to yesterday and block invalid submissions.
|
||||||
|
|
||||||
|
**Architecture:** Keep the existing dialog and request flow in `UploadData.vue`. Add one focused source-level regression test that asserts the date picker has an explicit restriction hook, then implement a shared “yesterday” boundary for both Element UI `disabledDate` behavior and submit-time validation.
|
||||||
|
|
||||||
|
**Tech Stack:** Vue 2, Element UI 2, scoped SFC logic, Node-based source assertions in `ruoyi-ui/tests/unit`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 1: Add a regression test for the date restriction hook
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `ruoyi-ui/tests/unit/upload-data-pull-bank-info-date-limit.test.js`
|
||||||
|
- Modify: `ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue`
|
||||||
|
|
||||||
|
**Step 1: Write the failing test**
|
||||||
|
|
||||||
|
Create a source-based test that verifies the pull-bank-info date picker:
|
||||||
|
|
||||||
|
- uses `picker-options`
|
||||||
|
- binds to a dedicated `pullBankInfoDatePickerOptions`
|
||||||
|
- the script contains a helper for calculating the latest allowed date
|
||||||
|
|
||||||
|
**Step 2: Run test to verify it fails**
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
node ruoyi-ui/tests/unit/upload-data-pull-bank-info-date-limit.test.js
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: FAIL because the current component does not define the new date limit hook yet.
|
||||||
|
|
||||||
|
### Task 2: Implement date picker restrictions
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue`
|
||||||
|
- Test: `ruoyi-ui/tests/unit/upload-data-pull-bank-info-date-limit.test.js`
|
||||||
|
|
||||||
|
**Step 1: Add the date picker option**
|
||||||
|
|
||||||
|
Bind the pull-bank-info date range picker to `pullBankInfoDatePickerOptions`.
|
||||||
|
|
||||||
|
**Step 2: Add the latest allowed date helper**
|
||||||
|
|
||||||
|
Add a method or computed-backed helper that returns yesterday based on the browser local date.
|
||||||
|
|
||||||
|
**Step 3: Disable today and future dates**
|
||||||
|
|
||||||
|
Implement `disabledDate` so dates greater than or equal to today 00:00 are disabled.
|
||||||
|
|
||||||
|
**Step 4: Run the new test**
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
node ruoyi-ui/tests/unit/upload-data-pull-bank-info-date-limit.test.js
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: PASS
|
||||||
|
|
||||||
|
### Task 3: Add submit-time fallback validation
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue`
|
||||||
|
- Test: `ruoyi-ui/tests/unit/upload-data-pull-bank-info-date-limit.test.js`
|
||||||
|
|
||||||
|
**Step 1: Reuse the same date boundary in submit logic**
|
||||||
|
|
||||||
|
Before calling `pullBankInfo(payload)`, verify both selected dates are not later than yesterday.
|
||||||
|
|
||||||
|
**Step 2: Show a clear warning**
|
||||||
|
|
||||||
|
If validation fails, warn the user with a concise message such as `时间跨度最晚只能选择到昨天`.
|
||||||
|
|
||||||
|
**Step 3: Keep existing validations intact**
|
||||||
|
|
||||||
|
Retain the current empty-ID-card and incomplete-date-range checks.
|
||||||
|
|
||||||
|
### Task 4: Run regression verification
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue`
|
||||||
|
|
||||||
|
**Step 1: Run focused tests**
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
node ruoyi-ui/tests/unit/upload-data-pull-bank-info-date-limit.test.js
|
||||||
|
node ruoyi-ui/tests/unit/upload-data-pull-bank-info-dialog-layout.test.js
|
||||||
|
node ruoyi-ui/tests/unit/upload-data-batch-upload.test.js
|
||||||
|
node ruoyi-ui/tests/unit/upload-data-file-list-settings.test.js
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: all tests pass.
|
||||||
|
|
||||||
|
**Step 2: Run build verification**
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run build:prod
|
||||||
|
```
|
||||||
|
|
||||||
|
Workdir: `ruoyi-ui`
|
||||||
|
|
||||||
|
Expected: build succeeds without introducing Vue template or script errors.
|
||||||
@@ -270,6 +270,7 @@
|
|||||||
v-model="pullBankInfoForm.dateRange"
|
v-model="pullBankInfoForm.dateRange"
|
||||||
type="daterange"
|
type="daterange"
|
||||||
value-format="yyyy-MM-dd"
|
value-format="yyyy-MM-dd"
|
||||||
|
:picker-options="pullBankInfoDatePickerOptions"
|
||||||
range-separator="至"
|
range-separator="至"
|
||||||
start-placeholder="开始日期"
|
start-placeholder="开始日期"
|
||||||
end-placeholder="结束日期"
|
end-placeholder="结束日期"
|
||||||
@@ -502,6 +503,13 @@ export default {
|
|||||||
pollingInterval: 5000,
|
pollingInterval: 5000,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
pullBankInfoDatePickerOptions() {
|
||||||
|
return {
|
||||||
|
disabledDate: (time) => this.isPullBankInfoDateDisabled(time),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
created() {
|
created() {
|
||||||
// 加载初始数据
|
// 加载初始数据
|
||||||
// this.loadInitialData();
|
// this.loadInitialData();
|
||||||
@@ -860,6 +868,36 @@ export default {
|
|||||||
this.idCardFileList = [];
|
this.idCardFileList = [];
|
||||||
this.parsingIdCardFile = false;
|
this.parsingIdCardFile = false;
|
||||||
},
|
},
|
||||||
|
getPullBankInfoTodayStart() {
|
||||||
|
const today = new Date();
|
||||||
|
today.setHours(0, 0, 0, 0);
|
||||||
|
return today;
|
||||||
|
},
|
||||||
|
getPullBankInfoMaxSelectableDate() {
|
||||||
|
const yesterday = this.getPullBankInfoTodayStart();
|
||||||
|
yesterday.setDate(yesterday.getDate() - 1);
|
||||||
|
return yesterday;
|
||||||
|
},
|
||||||
|
parsePullBankInfoDate(dateValue) {
|
||||||
|
if (!dateValue) return null;
|
||||||
|
const [year, month, day] = String(dateValue)
|
||||||
|
.split("-")
|
||||||
|
.map((item) => Number(item));
|
||||||
|
if (![year, month, day].every(Number.isFinite)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new Date(year, month - 1, day);
|
||||||
|
},
|
||||||
|
isPullBankInfoDateDisabled(time) {
|
||||||
|
return time.getTime() >= this.getPullBankInfoTodayStart().getTime();
|
||||||
|
},
|
||||||
|
hasInvalidPullBankInfoDateRange(dateRange) {
|
||||||
|
const maxSelectableDate = this.getPullBankInfoMaxSelectableDate();
|
||||||
|
return (dateRange || []).some((dateValue) => {
|
||||||
|
const date = this.parsePullBankInfoDate(dateValue);
|
||||||
|
return !date || date.getTime() > maxSelectableDate.getTime();
|
||||||
|
});
|
||||||
|
},
|
||||||
buildFinalIdCardList() {
|
buildFinalIdCardList() {
|
||||||
return this.parseIdCardText(this.pullBankInfoForm.idCardText);
|
return this.parseIdCardText(this.pullBankInfoForm.idCardText);
|
||||||
},
|
},
|
||||||
@@ -877,6 +915,11 @@ export default {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.hasInvalidPullBankInfoDateRange([startDate, endDate])) {
|
||||||
|
this.$message.warning("时间跨度最晚只能选择到昨天");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.pullBankInfoLoading = true;
|
this.pullBankInfoLoading = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
const assert = require("assert");
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
const componentPath = path.resolve(
|
||||||
|
__dirname,
|
||||||
|
"../../src/views/ccdiProject/components/detail/UploadData.vue"
|
||||||
|
);
|
||||||
|
const source = fs.readFileSync(componentPath, "utf8");
|
||||||
|
|
||||||
|
assert(
|
||||||
|
/:picker-options="pullBankInfoDatePickerOptions"/.test(source),
|
||||||
|
"拉取本行信息日期范围应绑定专用的 picker-options"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(
|
||||||
|
/pullBankInfoDatePickerOptions/.test(source),
|
||||||
|
"组件脚本中应定义拉取本行信息日期范围的专用配置"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(
|
||||||
|
/getPullBankInfoMaxSelectableDate/.test(source),
|
||||||
|
"组件脚本中应提供“最晚可选日期”为昨天的统一 helper"
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log("upload-data-pull-bank-info-date-limit test passed");
|
||||||
Reference in New Issue
Block a user