412 lines
10 KiB
Markdown
412 lines
10 KiB
Markdown
|
|
# Project Detail Transaction Query Frontend Implementation Plan
|
||
|
|
|
||
|
|
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||
|
|
|
||
|
|
**Goal:** Replace the placeholder `DetailQuery.vue` with the full project detail bank statement query page and remove the obsolete upload-record jump entry.
|
||
|
|
|
||
|
|
**Architecture:** Keep the page inside the existing `ccdiProject/detail.vue` dynamic component system. Use one dedicated API module for list, options, detail, and export calls; preload project-wide select options on page entry; keep the entire interaction inside `DetailQuery.vue` plus a minimal cleanup in `UploadData.vue`.
|
||
|
|
|
||
|
|
**Tech Stack:** Vue 2.6, Element UI 2.15, Axios request wrapper, existing global `this.download`, `npm run build:prod` + manual smoke validation
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Task 1: Replace the placeholder with a typed page shell and make the build fail first
|
||
|
|
|
||
|
|
**Files:**
|
||
|
|
- Modify: `ruoyi-ui/src/views/ccdiProject/components/detail/DetailQuery.vue`
|
||
|
|
- Create: `ruoyi-ui/src/api/ccdiProjectBankStatement.js`
|
||
|
|
|
||
|
|
**Step 1: Write the failing verification**
|
||
|
|
|
||
|
|
In `DetailQuery.vue`, replace the placeholder text with the final top-level data structure and import the new API module before creating it:
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
import {
|
||
|
|
listBankStatement,
|
||
|
|
getBankStatementOptions,
|
||
|
|
getBankStatementDetail
|
||
|
|
} from "@/api/ccdiProjectBankStatement";
|
||
|
|
```
|
||
|
|
|
||
|
|
Also add empty methods `getList`, `getOptions`, and `handleExport`.
|
||
|
|
|
||
|
|
**Step 2: Run build to verify it fails**
|
||
|
|
|
||
|
|
Run: `cd ruoyi-ui && npm run build:prod`
|
||
|
|
|
||
|
|
Expected: FAIL because `@/api/ccdiProjectBankStatement` does not exist yet.
|
||
|
|
|
||
|
|
**Step 3: Write minimal implementation**
|
||
|
|
|
||
|
|
Create `ruoyi-ui/src/api/ccdiProjectBankStatement.js` with:
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
import request from "@/utils/request";
|
||
|
|
|
||
|
|
export function listBankStatement(query) {
|
||
|
|
return request({
|
||
|
|
url: "/ccdi/project/bank-statement/list",
|
||
|
|
method: "get",
|
||
|
|
params: query
|
||
|
|
});
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
Add stubs for:
|
||
|
|
|
||
|
|
- `getBankStatementOptions(projectId)`
|
||
|
|
- `getBankStatementDetail(bankStatementId)`
|
||
|
|
|
||
|
|
Do not add export wrapper here; use `this.download` directly in the component.
|
||
|
|
|
||
|
|
**Step 4: Run build to verify it passes**
|
||
|
|
|
||
|
|
Run: `cd ruoyi-ui && npm run build:prod`
|
||
|
|
|
||
|
|
Expected: PASS or fail only on unfinished component template bindings.
|
||
|
|
|
||
|
|
**Step 5: Commit**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
git add ruoyi-ui/src/views/ccdiProject/components/detail/DetailQuery.vue ruoyi-ui/src/api/ccdiProjectBankStatement.js
|
||
|
|
git commit -m "搭建流水明细查询前端页面骨架"
|
||
|
|
```
|
||
|
|
|
||
|
|
### Task 2: Implement page state, preload list and project-wide select options
|
||
|
|
|
||
|
|
**Files:**
|
||
|
|
- Modify: `ruoyi-ui/src/views/ccdiProject/components/detail/DetailQuery.vue`
|
||
|
|
|
||
|
|
**Step 1: Write the failing verification**
|
||
|
|
|
||
|
|
Add the real component state before wiring the template:
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
data() {
|
||
|
|
return {
|
||
|
|
loading: false,
|
||
|
|
optionsLoading: false,
|
||
|
|
activeTab: "all",
|
||
|
|
queryParams: {
|
||
|
|
projectId: this.projectId,
|
||
|
|
pageNum: 1,
|
||
|
|
pageSize: 10,
|
||
|
|
tabType: "all",
|
||
|
|
transactionStartTime: "",
|
||
|
|
transactionEndTime: "",
|
||
|
|
counterpartyName: "",
|
||
|
|
counterpartyNameEmpty: false,
|
||
|
|
userMemo: "",
|
||
|
|
userMemoEmpty: false,
|
||
|
|
ourSubjects: [],
|
||
|
|
ourBanks: [],
|
||
|
|
ourAccounts: [],
|
||
|
|
amountMin: "",
|
||
|
|
amountMax: "",
|
||
|
|
counterpartyAccount: "",
|
||
|
|
counterpartyAccountEmpty: false,
|
||
|
|
transactionType: "",
|
||
|
|
transactionTypeEmpty: false,
|
||
|
|
orderBy: "trxDate",
|
||
|
|
orderDirection: "desc"
|
||
|
|
},
|
||
|
|
optionData: {
|
||
|
|
ourSubjectOptions: [],
|
||
|
|
ourBankOptions: [],
|
||
|
|
ourAccountOptions: []
|
||
|
|
}
|
||
|
|
};
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
Call both `getList()` and `getOptions()` in `created()`.
|
||
|
|
|
||
|
|
**Step 2: Run build to verify it fails**
|
||
|
|
|
||
|
|
Run: `cd ruoyi-ui && npm run build:prod`
|
||
|
|
|
||
|
|
Expected: FAIL because the template has not been updated to use the new reactive state yet, or methods are incomplete.
|
||
|
|
|
||
|
|
**Step 3: Write minimal implementation**
|
||
|
|
|
||
|
|
Implement:
|
||
|
|
|
||
|
|
- `getList()`
|
||
|
|
- `getOptions()`
|
||
|
|
- `syncProjectId()`
|
||
|
|
- `handleQuery()`
|
||
|
|
- `resetQuery()`
|
||
|
|
|
||
|
|
Ensure `created()` and the `projectId` watcher both call:
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
this.queryParams.projectId = this.projectId;
|
||
|
|
this.getOptions();
|
||
|
|
this.getList();
|
||
|
|
```
|
||
|
|
|
||
|
|
**Step 4: Run build to verify it passes**
|
||
|
|
|
||
|
|
Run: `cd ruoyi-ui && npm run build:prod`
|
||
|
|
|
||
|
|
Expected: PASS
|
||
|
|
|
||
|
|
**Step 5: Commit**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
git add ruoyi-ui/src/views/ccdiProject/components/detail/DetailQuery.vue
|
||
|
|
git commit -m "实现流水明细查询页面初始加载逻辑"
|
||
|
|
```
|
||
|
|
|
||
|
|
### Task 3: Build the left filter panel and local-search multi-selects
|
||
|
|
|
||
|
|
**Files:**
|
||
|
|
- Modify: `ruoyi-ui/src/views/ccdiProject/components/detail/DetailQuery.vue`
|
||
|
|
|
||
|
|
**Step 1: Write the failing verification**
|
||
|
|
|
||
|
|
Replace the old placeholder template with the final left column filter markup using Element UI controls:
|
||
|
|
|
||
|
|
- `el-date-picker` for transaction time range
|
||
|
|
- `el-input` + `el-checkbox` for counterparty name, summary, counterparty account, transaction type
|
||
|
|
- `el-select multiple filterable collapse-tags` for subject, bank, account
|
||
|
|
- amount range inputs
|
||
|
|
|
||
|
|
Do not wire the search/reset buttons yet.
|
||
|
|
|
||
|
|
**Step 2: Run build to verify it fails**
|
||
|
|
|
||
|
|
Run: `cd ruoyi-ui && npm run build:prod`
|
||
|
|
|
||
|
|
Expected: FAIL because methods or bound state used in the template are incomplete.
|
||
|
|
|
||
|
|
**Step 3: Write minimal implementation**
|
||
|
|
|
||
|
|
Wire the filter controls to `queryParams` and `dateRange`:
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
watch: {
|
||
|
|
dateRange(value) {
|
||
|
|
this.queryParams.transactionStartTime = value && value[0] ? value[0] : "";
|
||
|
|
this.queryParams.transactionEndTime = value && value[1] ? value[1] : "";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
Add the left action buttons:
|
||
|
|
|
||
|
|
- `查询`
|
||
|
|
- `重置`
|
||
|
|
|
||
|
|
Add local filter support inside each `el-select` using Element UI `filterable`.
|
||
|
|
|
||
|
|
**Step 4: Run build to verify it passes**
|
||
|
|
|
||
|
|
Run: `cd ruoyi-ui && npm run build:prod`
|
||
|
|
|
||
|
|
Expected: PASS
|
||
|
|
|
||
|
|
**Step 5: Commit**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
git add ruoyi-ui/src/views/ccdiProject/components/detail/DetailQuery.vue
|
||
|
|
git commit -m "完成流水明细查询筛选栏布局"
|
||
|
|
```
|
||
|
|
|
||
|
|
### Task 4: Build the right result area, tabs, table, pagination, and detail drawer
|
||
|
|
|
||
|
|
**Files:**
|
||
|
|
- Modify: `ruoyi-ui/src/views/ccdiProject/components/detail/DetailQuery.vue`
|
||
|
|
|
||
|
|
**Step 1: Write the failing verification**
|
||
|
|
|
||
|
|
Add the right-side structure:
|
||
|
|
|
||
|
|
- top tabs `全部 / 流入 / 流出`
|
||
|
|
- export button
|
||
|
|
- `el-table`
|
||
|
|
- `pagination`
|
||
|
|
- detail drawer or dialog
|
||
|
|
|
||
|
|
Reference the final columns:
|
||
|
|
|
||
|
|
- `trxDate`
|
||
|
|
- `leAccountNo / leAccountName`
|
||
|
|
- `customerAccountName / customerAccountNo`
|
||
|
|
- `userMemo / cashType`
|
||
|
|
- `displayAmount`
|
||
|
|
- `详情`
|
||
|
|
|
||
|
|
**Step 2: Run build to verify it fails**
|
||
|
|
|
||
|
|
Run: `cd ruoyi-ui && npm run build:prod`
|
||
|
|
|
||
|
|
Expected: FAIL because event handlers like `handleTabChange`, `handleSortChange`, `handleViewDetail`, or `handlePageChange` are missing.
|
||
|
|
|
||
|
|
**Step 3: Write minimal implementation**
|
||
|
|
|
||
|
|
Implement:
|
||
|
|
|
||
|
|
- `handleTabChange(tab)`
|
||
|
|
- `handleSortChange({ prop, order })`
|
||
|
|
- `handlePageChange(pageNum)`
|
||
|
|
- `handleViewDetail(row)`
|
||
|
|
- `closeDetailDialog()`
|
||
|
|
|
||
|
|
Sort mapping:
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
const sortMap = {
|
||
|
|
trxDate: "trxDate",
|
||
|
|
displayAmount: "amount"
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
Tab mapping:
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
const tabMap = {
|
||
|
|
all: "all",
|
||
|
|
in: "in",
|
||
|
|
out: "out"
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
**Step 4: Run build to verify it passes**
|
||
|
|
|
||
|
|
Run: `cd ruoyi-ui && npm run build:prod`
|
||
|
|
|
||
|
|
Expected: PASS
|
||
|
|
|
||
|
|
**Step 5: Commit**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
git add ruoyi-ui/src/views/ccdiProject/components/detail/DetailQuery.vue
|
||
|
|
git commit -m "完成流水明细查询结果区与详情展示"
|
||
|
|
```
|
||
|
|
|
||
|
|
### Task 5: Wire export, empty/error states, and responsive styles
|
||
|
|
|
||
|
|
**Files:**
|
||
|
|
- Modify: `ruoyi-ui/src/views/ccdiProject/components/detail/DetailQuery.vue`
|
||
|
|
|
||
|
|
**Step 1: Write the failing verification**
|
||
|
|
|
||
|
|
Add the `导出流水` button click handler without implementation:
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
handleExport() {
|
||
|
|
// TODO
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
Show the button in the UI but keep it clickable.
|
||
|
|
|
||
|
|
**Step 2: Run build to verify it fails functionally in manual smoke**
|
||
|
|
|
||
|
|
Run:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
cd ruoyi-ui
|
||
|
|
npm run build:prod
|
||
|
|
```
|
||
|
|
|
||
|
|
Expected: BUILD PASS, but manual smoke in browser should show export button with no behavior yet.
|
||
|
|
|
||
|
|
**Step 3: Write minimal implementation**
|
||
|
|
|
||
|
|
Implement export with the existing global helper:
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
this.download(
|
||
|
|
"ccdi/project/bank-statement/export",
|
||
|
|
{ ...this.queryParams },
|
||
|
|
`${this.projectInfo.projectName || "项目"}_流水明细_${Date.now()}.xlsx`
|
||
|
|
);
|
||
|
|
```
|
||
|
|
|
||
|
|
Add:
|
||
|
|
|
||
|
|
- empty state when `list.length === 0`
|
||
|
|
- inline error tip when list load fails
|
||
|
|
- disabled export when total is `0`
|
||
|
|
- responsive layout styles for mobile widths
|
||
|
|
|
||
|
|
**Step 4: Run build and manual smoke verification**
|
||
|
|
|
||
|
|
Run:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
cd ruoyi-ui
|
||
|
|
npm run build:prod
|
||
|
|
```
|
||
|
|
|
||
|
|
Expected: BUILD PASS
|
||
|
|
|
||
|
|
Manual smoke:
|
||
|
|
|
||
|
|
1. Open project detail page
|
||
|
|
2. Switch to `流水明细查询`
|
||
|
|
3. Confirm left filters render
|
||
|
|
4. Confirm export button is disabled on empty data and enabled on non-empty data
|
||
|
|
|
||
|
|
**Step 5: Commit**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
git add ruoyi-ui/src/views/ccdiProject/components/detail/DetailQuery.vue
|
||
|
|
git commit -m "补齐流水明细查询导出与状态反馈"
|
||
|
|
```
|
||
|
|
|
||
|
|
### Task 6: Remove obsolete upload-page operation column and finish smoke verification
|
||
|
|
|
||
|
|
**Files:**
|
||
|
|
- Modify: `ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue`
|
||
|
|
- Modify if needed: `ruoyi-ui/src/views/ccdiProject/components/detail/DetailQuery.vue`
|
||
|
|
|
||
|
|
**Step 1: Write the failing verification**
|
||
|
|
|
||
|
|
Delete only the old upload-table operation column usage in the template, but do not clean methods yet.
|
||
|
|
|
||
|
|
**Step 2: Run build to verify it fails**
|
||
|
|
|
||
|
|
Run: `cd ruoyi-ui && npm run build:prod`
|
||
|
|
|
||
|
|
Expected: FAIL because `handleViewFlow` or `handleViewError` remains unused or referenced.
|
||
|
|
|
||
|
|
**Step 3: Write minimal implementation**
|
||
|
|
|
||
|
|
In `UploadData.vue`:
|
||
|
|
|
||
|
|
- remove the upload-record operation column entirely
|
||
|
|
- remove methods:
|
||
|
|
- `handleViewFlow`
|
||
|
|
- `handleViewError`
|
||
|
|
- remove any event payload that tried to change menu to `detail`
|
||
|
|
|
||
|
|
Keep upload, polling, and record-list refresh behavior unchanged.
|
||
|
|
|
||
|
|
**Step 4: Run final verification**
|
||
|
|
|
||
|
|
Run:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
cd ruoyi-ui
|
||
|
|
npm run build:prod
|
||
|
|
```
|
||
|
|
|
||
|
|
Expected: BUILD PASS
|
||
|
|
|
||
|
|
Manual smoke:
|
||
|
|
|
||
|
|
1. Open one project detail page
|
||
|
|
2. Confirm `上传数据` 页不再出现“查看流水”入口
|
||
|
|
3. Confirm `流水明细查询` 可独立查询、筛选、分页、导出
|
||
|
|
4. Confirm手机宽度下左右布局能够折叠为上下布局
|
||
|
|
|
||
|
|
**Step 5: Commit**
|
||
|
|
|
||
|
|
```bash
|
||
|
|
git add ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue ruoyi-ui/src/views/ccdiProject/components/detail/DetailQuery.vue ruoyi-ui/src/api/ccdiProjectBankStatement.js
|
||
|
|
git commit -m "完成流水明细查询前端实现并移除旧跳转入口"
|
||
|
|
```
|