vue3-element-plus-app-chu 0.0.18 → 0.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -2
- package/src/components/table/ArtTableHeader.vue +29 -6
- package/src/view/dcps/README.md +1 -1
- package/src/view/dcps/auth/index.vue +13 -13
- package/src/view/dcps/estimation/index.vue +9 -5
- package/src/view/dcps/forecast/index.vue +14 -15
- package/src/view/dcps/funding/balance/api.ts +8 -14
- package/src/view/dcps/funding/balance/index.vue +82 -124
- package/src/view/dcps/funding/injection/index.vue +3 -1
- package/src/view/dcps/runtime.ts +10 -29
- package/src/view/dcps/write-off/index.vue +17 -10
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vue3-element-plus-app-chu",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.20",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"dev": "run-p --print-label dev:frontend dev:backend",
|
|
15
15
|
"dev:frontend": "vite",
|
|
16
16
|
"dev:backend": "pnpm -C backend dev",
|
|
17
|
-
"build": "run-
|
|
17
|
+
"build": "run-s type-check build-only",
|
|
18
|
+
"build:fast": "vite build",
|
|
18
19
|
"preview": "vite preview",
|
|
19
20
|
"build-only": "vite build",
|
|
20
21
|
"type-check": "vue-tsc --build",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="art-table-header">
|
|
2
|
+
<div class="art-table-header" :class="`art-table-header--${localSettings.size}`">
|
|
3
3
|
<div class="art-table-header__left">
|
|
4
4
|
<slot name="title">
|
|
5
5
|
<span v-if="title" class="art-table-header__title">{{ title }}</span>
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
|
|
37
37
|
<ElDropdown
|
|
38
38
|
v-if="shouldShow('size')"
|
|
39
|
+
:size="localSettings.size"
|
|
39
40
|
trigger="click"
|
|
40
41
|
:teleported="false"
|
|
41
42
|
@command="changeSize"
|
|
@@ -121,6 +122,7 @@
|
|
|
121
122
|
|
|
122
123
|
<ElCheckbox
|
|
123
124
|
class="art-table-header__column-check"
|
|
125
|
+
:size="localSettings.size"
|
|
124
126
|
:model-value="getColumnVisibility(column)"
|
|
125
127
|
:disabled="column.disabled"
|
|
126
128
|
@update:model-value="changeVisibility(index, $event)"
|
|
@@ -177,6 +179,7 @@
|
|
|
177
179
|
<div class="art-table-header__settings">
|
|
178
180
|
<ElCheckbox
|
|
179
181
|
v-if="showZebra"
|
|
182
|
+
:size="localSettings.size"
|
|
180
183
|
:model-value="localSettings.stripe"
|
|
181
184
|
@update:model-value="changeBooleanSetting('stripe', $event)"
|
|
182
185
|
>
|
|
@@ -184,6 +187,7 @@
|
|
|
184
187
|
</ElCheckbox>
|
|
185
188
|
<ElCheckbox
|
|
186
189
|
v-if="showBorder"
|
|
190
|
+
:size="localSettings.size"
|
|
187
191
|
:model-value="localSettings.border"
|
|
188
192
|
@update:model-value="changeBooleanSetting('border', $event)"
|
|
189
193
|
>
|
|
@@ -191,6 +195,7 @@
|
|
|
191
195
|
</ElCheckbox>
|
|
192
196
|
<ElCheckbox
|
|
193
197
|
v-if="showHeaderBackground"
|
|
198
|
+
:size="localSettings.size"
|
|
194
199
|
:model-value="localSettings.headerBackground"
|
|
195
200
|
@update:model-value="changeBooleanSetting('headerBackground', $event)"
|
|
196
201
|
>
|
|
@@ -400,6 +405,10 @@ function clearDrag() {
|
|
|
400
405
|
|
|
401
406
|
<style scoped>
|
|
402
407
|
.art-table-header {
|
|
408
|
+
--art-table-control-size: 32px;
|
|
409
|
+
--art-table-move-width: 26px;
|
|
410
|
+
--art-table-move-height: 28px;
|
|
411
|
+
--art-table-column-height: 34px;
|
|
403
412
|
display: flex;
|
|
404
413
|
align-items: center;
|
|
405
414
|
justify-content: space-between;
|
|
@@ -409,6 +418,20 @@ function clearDrag() {
|
|
|
409
418
|
color: var(--art-table-text-color, var(--el-text-color-primary, #303133));
|
|
410
419
|
}
|
|
411
420
|
|
|
421
|
+
.art-table-header--small {
|
|
422
|
+
--art-table-control-size: 24px;
|
|
423
|
+
--art-table-move-width: 22px;
|
|
424
|
+
--art-table-move-height: 24px;
|
|
425
|
+
--art-table-column-height: 26px;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
.art-table-header--large {
|
|
429
|
+
--art-table-control-size: 40px;
|
|
430
|
+
--art-table-move-width: 30px;
|
|
431
|
+
--art-table-move-height: 32px;
|
|
432
|
+
--art-table-column-height: 42px;
|
|
433
|
+
}
|
|
434
|
+
|
|
412
435
|
.art-table-header__left,
|
|
413
436
|
.art-table-header__right {
|
|
414
437
|
display: flex;
|
|
@@ -435,8 +458,8 @@ function clearDrag() {
|
|
|
435
458
|
align-items: center;
|
|
436
459
|
justify-content: center;
|
|
437
460
|
flex-shrink: 0;
|
|
438
|
-
width:
|
|
439
|
-
height:
|
|
461
|
+
width: var(--art-table-control-size);
|
|
462
|
+
height: var(--art-table-control-size);
|
|
440
463
|
padding: 0;
|
|
441
464
|
border: 0;
|
|
442
465
|
border-radius: var(--art-table-toolbar-radius, 6px);
|
|
@@ -479,7 +502,7 @@ function clearDrag() {
|
|
|
479
502
|
display: flex;
|
|
480
503
|
align-items: center;
|
|
481
504
|
gap: 8px;
|
|
482
|
-
min-height:
|
|
505
|
+
min-height: var(--art-table-column-height);
|
|
483
506
|
padding: 0 4px;
|
|
484
507
|
border-radius: 4px;
|
|
485
508
|
background: transparent;
|
|
@@ -523,8 +546,8 @@ function clearDrag() {
|
|
|
523
546
|
}
|
|
524
547
|
|
|
525
548
|
.art-table-header__move {
|
|
526
|
-
width:
|
|
527
|
-
height:
|
|
549
|
+
width: var(--art-table-move-width);
|
|
550
|
+
height: var(--art-table-move-height);
|
|
528
551
|
border-radius: 4px;
|
|
529
552
|
background: transparent;
|
|
530
553
|
}
|
package/src/view/dcps/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
`src/view/dcps` 下每个业务页面统一保持三个文件,不再拆分子组件、工具文件:
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
跨页面共用的运行时配置统一放在 `src/view/dcps/runtime.ts`,仅默认导出一个对象,包含 `date`(共用业务日期,格式为 `YYYYMMDD`)、`approverId`(工号)和 `approverName`(姓名)。日期在模块加载时按上海时区生成一次,预报、匡算、核销及授权查询的默认日期均使用同一个 `date`;授权日期范围的开始和结束默认都取该值。页面通过 `import dcpsRuntime from '../runtime'`(分组子页面为 `../../runtime`)引入,不再单独导出日期工具或模块配置。
|
|
6
6
|
|
|
7
7
|
一级菜单为分组时,页面放在该分组目录下。例如“注资/预注资管理”的两个页面分别位于 `funding/injection/` 和 `funding/balance/`,各自保留下面三个文件。
|
|
8
8
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { computed, onBeforeUnmount, onMounted, reactive, ref } from 'vue'
|
|
3
|
-
import { ElMessage } from 'element-plus'
|
|
3
|
+
import { ElConfigProvider, ElMessage } from 'element-plus'
|
|
4
4
|
import { ArtDataTable, type ColumnOption, type PaginationOptions, type TableSettings } from '@/components/table'
|
|
5
5
|
import API from './api'
|
|
6
|
-
import
|
|
6
|
+
import dcpsRuntime from '../runtime'
|
|
7
7
|
import type { AuthorizationFilters, AuthorizationQueryParams, AuthorizationTask } from './typs'
|
|
8
8
|
|
|
9
9
|
defineOptions({ name: 'DcpsAuthPage' })
|
|
@@ -21,8 +21,8 @@ const defaultFilters: AuthorizationFilters = {
|
|
|
21
21
|
}
|
|
22
22
|
// 默认创建日期范围:[开始日期, 结束日期],格式为 YYYYMMDD,查询重置时使用。
|
|
23
23
|
const defaultDates: [string, string] = [
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
dcpsRuntime.date,
|
|
25
|
+
dcpsRuntime.date,
|
|
26
26
|
]
|
|
27
27
|
|
|
28
28
|
// 重复输入项共用一份配置,依次为字段、名称和长度限制。
|
|
@@ -270,8 +270,8 @@ const getQueryFilters = () => ({
|
|
|
270
270
|
payeeName: filters.value.payeeName.trim(), // 收款人名称。
|
|
271
271
|
platfSeqNo: filters.value.platfSeqNo.trim(), // 平台流水号。
|
|
272
272
|
taskSts: filters.value.taskSts, // 任务状态,空值表示全部。
|
|
273
|
-
createTmBegin: dateRange.value?.[0] ||
|
|
274
|
-
createTmEnd: dateRange.value?.[1] || dateRange.value?.[0] ||
|
|
273
|
+
createTmBegin: dateRange.value?.[0] || dcpsRuntime.date, // 创建开始日期,格式为 YYYYMMDD,未选择时取默认值。
|
|
274
|
+
createTmEnd: dateRange.value?.[1] || dateRange.value?.[0] || dcpsRuntime.date, // 创建结束日期,格式为 YYYYMMDD,缺失时回退到开始日期或默认值。
|
|
275
275
|
})
|
|
276
276
|
// 仅查询、重置时更新;翻页和刷新沿用这份条件。
|
|
277
277
|
let appliedQuery = getQueryFilters()
|
|
@@ -355,8 +355,8 @@ const openDecisionDialog = (task: any) => {
|
|
|
355
355
|
const submitDecision = async (decision: Decision) => {
|
|
356
356
|
const platfSeqNo = selectedTask.value?.platfSeqNo?.trim() // 本次审批任务的平台流水号,用于唯一定位任务。
|
|
357
357
|
if (!canApprove(selectedTask.value) || !platfSeqNo || pendingDecision.value || loading.value) return
|
|
358
|
-
const approverId =
|
|
359
|
-
const approverName =
|
|
358
|
+
const approverId = dcpsRuntime.approverId.trim() // 本次提交的审批人工号,同时作为公共用户标识。
|
|
359
|
+
const approverName = dcpsRuntime.approverName.trim() // 本次提交的审批人姓名。
|
|
360
360
|
const remarkText = remark.value.trim() // 去除首尾空白后的备注或拒绝原因。
|
|
361
361
|
if (!approverId || !approverName) {
|
|
362
362
|
ElMessage.warning('审批人信息未设置')
|
|
@@ -406,6 +406,7 @@ onBeforeUnmount(() => {
|
|
|
406
406
|
</script>
|
|
407
407
|
|
|
408
408
|
<template>
|
|
409
|
+
<ElConfigProvider :size="tableSettings.size">
|
|
409
410
|
<main class="dcps-page">
|
|
410
411
|
<!-- 查询条件:控件尺寸跟随表格设置,卡片内边距为 10px,点击查询生效。 -->
|
|
411
412
|
<el-card v-show="showSearchBar" class="authorization-search" shadow="never" :body-style="{ padding: '10px' }">
|
|
@@ -474,7 +475,6 @@ onBeforeUnmount(() => {
|
|
|
474
475
|
<el-button
|
|
475
476
|
text
|
|
476
477
|
bg
|
|
477
|
-
size="small"
|
|
478
478
|
type="primary"
|
|
479
479
|
:disabled="!canApprove(row) || loading || !!pendingDecision"
|
|
480
480
|
@click.stop="openDecisionDialog(row)"
|
|
@@ -535,9 +535,8 @@ onBeforeUnmount(() => {
|
|
|
535
535
|
</el-scrollbar>
|
|
536
536
|
|
|
537
537
|
<template #footer>
|
|
538
|
-
<el-button
|
|
538
|
+
<el-button @click="detailDialogVisible = false">关闭</el-button>
|
|
539
539
|
<el-button
|
|
540
|
-
size="small"
|
|
541
540
|
type="primary"
|
|
542
541
|
:disabled="loading || !!pendingDecision || !canApprove(detailTask)"
|
|
543
542
|
@click="openDecisionDialog(detailTask)"
|
|
@@ -571,12 +570,12 @@ onBeforeUnmount(() => {
|
|
|
571
570
|
<el-row :gutter="14">
|
|
572
571
|
<el-col :xs="24" :sm="12">
|
|
573
572
|
<el-form-item label="审批人工号">
|
|
574
|
-
<el-input :model-value="
|
|
573
|
+
<el-input :model-value="dcpsRuntime.approverId" disabled />
|
|
575
574
|
</el-form-item>
|
|
576
575
|
</el-col>
|
|
577
576
|
<el-col :xs="24" :sm="12">
|
|
578
577
|
<el-form-item label="审批人姓名">
|
|
579
|
-
<el-input :model-value="
|
|
578
|
+
<el-input :model-value="dcpsRuntime.approverName" readonly />
|
|
580
579
|
</el-form-item>
|
|
581
580
|
</el-col>
|
|
582
581
|
</el-row>
|
|
@@ -608,6 +607,7 @@ onBeforeUnmount(() => {
|
|
|
608
607
|
</template>
|
|
609
608
|
</el-dialog>
|
|
610
609
|
</main>
|
|
610
|
+
</ElConfigProvider>
|
|
611
611
|
</template>
|
|
612
612
|
|
|
613
613
|
<style scoped>
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { computed, onBeforeUnmount, onMounted, reactive, ref } from 'vue'
|
|
3
|
-
import { ElMessage } from 'element-plus'
|
|
3
|
+
import { ElConfigProvider, ElMessage } from 'element-plus'
|
|
4
4
|
import API from './api'
|
|
5
|
-
import
|
|
5
|
+
import dcpsRuntime from '../runtime'
|
|
6
6
|
import type {
|
|
7
7
|
EstimationAmounts, EstimationCell, EstimationPredRow, EstimationQueryParams, EstimationTranRow,
|
|
8
8
|
} from './typs'
|
|
9
9
|
|
|
10
10
|
defineOptions({ name: 'DcpsEstimationPage' })
|
|
11
11
|
|
|
12
|
+
const tableSize = 'small'
|
|
13
|
+
|
|
12
14
|
// 数字人民币头寸匡算页面:
|
|
13
15
|
// 查询条件为交易日期加上今日预计调拨收入、支出金额;交易日期变化后调用
|
|
14
16
|
// 历史预计调拨金额接口(140503004)预填金额,允许手工调整后重新匡算。
|
|
@@ -150,7 +152,7 @@ const cellOf = (position: string): EstimationCell => ({
|
|
|
150
152
|
})
|
|
151
153
|
|
|
152
154
|
// 查询条件:日期默认当天;预计调拨收支金额由历史接口预填。
|
|
153
|
-
const queryForm = reactive({ tranDate:
|
|
155
|
+
const queryForm = reactive({ tranDate: dcpsRuntime.date, predictAllotInAmt: '', predictAllotOutAmt: '' })
|
|
154
156
|
// 各金额输入的校验提示,空字符串表示没有错误。
|
|
155
157
|
const formError = reactive({ predictAllotInAmt: '', predictAllotOutAmt: '' })
|
|
156
158
|
|
|
@@ -340,6 +342,7 @@ onBeforeUnmount(() => {
|
|
|
340
342
|
</script>
|
|
341
343
|
|
|
342
344
|
<template>
|
|
345
|
+
<ElConfigProvider :size="tableSize">
|
|
343
346
|
<main class="dcps-page">
|
|
344
347
|
<!-- 顶部操作区:交易日期选择与导出、查询入口(收支金额在下方表格内填写)。 -->
|
|
345
348
|
<el-card class="estimation-header" shadow="never" :body-style="{ padding: '10px 14px' }">
|
|
@@ -542,7 +545,7 @@ onBeforeUnmount(() => {
|
|
|
542
545
|
<div v-loading="detailLoading" class="detail-tables">
|
|
543
546
|
<!-- 预报信息明细;列表为空时展示统一空态。 -->
|
|
544
547
|
<div class="dialog-section-title">预报信息</div>
|
|
545
|
-
<el-table :data="detailPredList" size="
|
|
548
|
+
<el-table :data="detailPredList" :size="tableSize" border max-height="240px" empty-text="暂无预报信息">
|
|
546
549
|
<el-table-column label="预报流水号" min-width="150" show-overflow-tooltip>
|
|
547
550
|
<template #default="{ row }">{{ displayText(row.predRefNo) }}</template>
|
|
548
551
|
</el-table-column>
|
|
@@ -580,7 +583,7 @@ onBeforeUnmount(() => {
|
|
|
580
583
|
|
|
581
584
|
<!-- 流水信息明细;失败的详情可重新打开弹窗重试。 -->
|
|
582
585
|
<div class="dialog-section-title">流水信息</div>
|
|
583
|
-
<el-table :data="detailTranList" size="
|
|
586
|
+
<el-table :data="detailTranList" :size="tableSize" border max-height="240px" empty-text="暂无流水信息">
|
|
584
587
|
<el-table-column label="交易参考号" min-width="150" show-overflow-tooltip>
|
|
585
588
|
<template #default="{ row }">{{ displayText(row.refNo) }}</template>
|
|
586
589
|
</el-table-column>
|
|
@@ -622,6 +625,7 @@ onBeforeUnmount(() => {
|
|
|
622
625
|
</template>
|
|
623
626
|
</el-dialog>
|
|
624
627
|
</main>
|
|
628
|
+
</ElConfigProvider>
|
|
625
629
|
</template>
|
|
626
630
|
|
|
627
631
|
<style scoped>
|
|
@@ -22,13 +22,10 @@ const recallForecastRow = (predRefNo?: string): ForecastRowType | null => {
|
|
|
22
22
|
<script setup lang="ts">
|
|
23
23
|
import { computed, onActivated, onBeforeUnmount, reactive, ref, watch } from 'vue'
|
|
24
24
|
import { useRouter } from 'vue-router'
|
|
25
|
-
import { ElMessage, ElMessageBox } from 'element-plus'
|
|
25
|
+
import { ElConfigProvider, ElMessage, ElMessageBox } from 'element-plus'
|
|
26
26
|
import API from './api'
|
|
27
|
-
import
|
|
27
|
+
import dcpsRuntime from '../runtime'
|
|
28
28
|
import { ArtDataTable, type ColumnOption, type PaginationOptions, type TableSettings } from '@/components/table'
|
|
29
|
-
import type {
|
|
30
|
-
ApiResponse,
|
|
31
|
-
} from '@/utils/request'
|
|
32
29
|
import type {
|
|
33
30
|
ForecastCreateBody,
|
|
34
31
|
ForecastDetail,
|
|
@@ -65,7 +62,7 @@ interface ForecastPage {
|
|
|
65
62
|
}
|
|
66
63
|
|
|
67
64
|
/** 校验公共响应头;retCode 不是 00000 时按服务端提示或 fallback 抛错。 */
|
|
68
|
-
const ensureSuccess = <T,>(response:
|
|
65
|
+
const ensureSuccess = <T,>(response: any, fallback: string): T | null => {
|
|
69
66
|
if (response?.head?.retCode !== '00000') {
|
|
70
67
|
throw new Error(response?.head?.retMsg?.trim() || fallback)
|
|
71
68
|
}
|
|
@@ -148,14 +145,13 @@ const compareAmounts = (left: string, right: string): number => {
|
|
|
148
145
|
return aValue < bValue ? -1 : aValue > bValue ? 1 : 0
|
|
149
146
|
}
|
|
150
147
|
|
|
151
|
-
/**
|
|
148
|
+
/** 新增和导入使用的表单初始值;日期取共用运行时配置。 */
|
|
152
149
|
const createFormValues = (): ForecastFormValues => {
|
|
153
|
-
const today = getToday()
|
|
154
150
|
return {
|
|
155
151
|
billDate: '', billNo: '', busiType: '', clientName: '', clientType: '',
|
|
156
152
|
competAcct: '', competName: '', custInfoSeq: '', groundBranch: '', groundBranchName: '',
|
|
157
|
-
linkMan: '', payChannel: '', payDirec: '', phoneNo: '', predAmt: '', predDate:
|
|
158
|
-
predName: '', predOrgName: '', purpose: '', remark: '', tranDate:
|
|
153
|
+
linkMan: '', payChannel: '', payDirec: '', phoneNo: '', predAmt: '', predDate: dcpsRuntime.date,
|
|
154
|
+
predName: '', predOrgName: '', purpose: '', remark: '', tranDate: dcpsRuntime.date,
|
|
159
155
|
}
|
|
160
156
|
}
|
|
161
157
|
|
|
@@ -217,7 +213,7 @@ onBeforeUnmount(() => { disposed = true })
|
|
|
217
213
|
|
|
218
214
|
type ListMutation = 'delete' | null
|
|
219
215
|
const createFilters = (): ForecastFilters => ({
|
|
220
|
-
tranDate:
|
|
216
|
+
tranDate: dcpsRuntime.date, clientName: '', competName: '', payDirec: '', busiType: '', payChannel: '',
|
|
221
217
|
groundBranch: '', predStatus: '', verifyStatus: '', startTransAmt: '', endTransAmt: '', sortRule: '',
|
|
222
218
|
})
|
|
223
219
|
const listFilters = ref(createFilters())
|
|
@@ -375,6 +371,7 @@ async function deleteRecords(records: ForecastRow[]) {
|
|
|
375
371
|
try {
|
|
376
372
|
await ElMessageBox.confirm(`确认删除选中的 ${references.length} 条预报记录?删除后将重新查询列表。`, '删除预报', {
|
|
377
373
|
confirmButtonText: '确认删除', cancelButtonText: '取消', type: 'warning', distinguishCancelAndClose: true,
|
|
374
|
+
buttonSize: listTableSettings.value.size,
|
|
378
375
|
})
|
|
379
376
|
if (disposed) return
|
|
380
377
|
ensureSuccess(await API.deleteApi(references), '删除预报失败')
|
|
@@ -485,8 +482,8 @@ const fieldPlaceholder = (field: EditorField) => {
|
|
|
485
482
|
const initializeForm = () => {
|
|
486
483
|
const nextValues = createFormValues()
|
|
487
484
|
if (editorMode.value === 'create') {
|
|
488
|
-
nextValues.tranDate = props.tranDate ||
|
|
489
|
-
nextValues.predDate =
|
|
485
|
+
nextValues.tranDate = props.tranDate || dcpsRuntime.date
|
|
486
|
+
nextValues.predDate = dcpsRuntime.date
|
|
490
487
|
} else {
|
|
491
488
|
for (const key of Object.keys(nextValues) as FieldKey[]) {
|
|
492
489
|
const value = initialFieldValue(key)
|
|
@@ -681,6 +678,7 @@ onActivated(() => {
|
|
|
681
678
|
</script>
|
|
682
679
|
|
|
683
680
|
<template>
|
|
681
|
+
<ElConfigProvider :size="listTableSettings.size">
|
|
684
682
|
<!-- 新增 / 修改页 -->
|
|
685
683
|
<main v-if="isEditor" class="page-shell">
|
|
686
684
|
<el-card class="shell-header" shadow="never" :body-style="{ padding: '10px' }">
|
|
@@ -703,7 +701,7 @@ onActivated(() => {
|
|
|
703
701
|
</el-alert>
|
|
704
702
|
<template v-else>
|
|
705
703
|
<p class="editor-note">金额单位为元,方向、业务类型、支付渠道和客户类型按业务代码填写。</p>
|
|
706
|
-
<el-form :model="form"
|
|
704
|
+
<el-form :model="form" label-position="top" :disabled="editorDisabled" @submit.prevent="submit">
|
|
707
705
|
<section v-for="group in visibleGroups" :key="group.title" class="editor-group" :aria-label="group.title">
|
|
708
706
|
<h3>{{ group.title }}</h3>
|
|
709
707
|
<div class="editor-fields">
|
|
@@ -783,7 +781,7 @@ onActivated(() => {
|
|
|
783
781
|
<div v-loading="detailLoading" class="detail-scroll">
|
|
784
782
|
<div v-if="detailError" class="detail-error" role="alert">
|
|
785
783
|
<el-alert :title="detailError" type="error" :closable="false" show-icon />
|
|
786
|
-
<el-button
|
|
784
|
+
<el-button :disabled="detailLoading" @click="loadDetail">重新加载</el-button>
|
|
787
785
|
</div>
|
|
788
786
|
<div v-else-if="detail" class="detail-content">
|
|
789
787
|
<!-- group 为当前详情分组,fields 中的每项对应一个字段。 -->
|
|
@@ -882,6 +880,7 @@ onActivated(() => {
|
|
|
882
880
|
</ArtDataTable>
|
|
883
881
|
</div>
|
|
884
882
|
</main>
|
|
883
|
+
</ElConfigProvider>
|
|
885
884
|
</template>
|
|
886
885
|
|
|
887
886
|
<style scoped>
|
|
@@ -1,17 +1,11 @@
|
|
|
1
|
-
import baseHttpClient from
|
|
1
|
+
import baseHttpClient, { type ApiResponse } from '@chic/http'
|
|
2
|
+
import type { AccountBalanceInfo, InjectionCreateParams } from './typs'
|
|
2
3
|
|
|
3
4
|
export default {
|
|
4
|
-
/**
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* 注资、预注资管理-注资/预注资发起。
|
|
12
|
-
* @param params 提交参数:adjustType 为调整类型(PRFD 注资调增、FDRD 注资调减、
|
|
13
|
-
* FFIC 预注资调增、FFRD 预注资调减),tranAmt 为调整金额(元)。
|
|
14
|
-
* 提交成功后重新查询账户行余额。
|
|
15
|
-
*/
|
|
16
|
-
createApi: (params: unknown) => baseHttpClient.post<any>("/TAM/0001/120506001", params)
|
|
5
|
+
/** 查询单条账户行余额,无筛选参数。 */
|
|
6
|
+
queryBalanceApi: () =>
|
|
7
|
+
baseHttpClient.post<ApiResponse<AccountBalanceInfo>>('/TAM/0001/140506001', {}),
|
|
8
|
+
/** 注资/预注资发起,响应未声明业务字段。 */
|
|
9
|
+
createApi: (params: InjectionCreateParams) =>
|
|
10
|
+
baseHttpClient.post<ApiResponse>('/TAM/0001/120506001', params),
|
|
17
11
|
}
|
|
@@ -1,155 +1,127 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import {
|
|
2
|
+
import { onBeforeUnmount, onMounted, reactive, ref } from 'vue'
|
|
3
3
|
import { ElMessage } from 'element-plus'
|
|
4
4
|
import API from './api'
|
|
5
5
|
import type { AccountBalanceInfo, InjectionCreateParams } from './typs'
|
|
6
6
|
|
|
7
7
|
defineOptions({ name: 'DcpsBalancePage' })
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
let
|
|
14
|
-
let disposed = false // 页面是否已卸载,避免未完成请求继续更新界面。
|
|
9
|
+
const balance = ref<AccountBalanceInfo | null>(null)
|
|
10
|
+
const loading = ref(false)
|
|
11
|
+
const lastQueryTime = ref('')
|
|
12
|
+
let requestId = 0 // 只处理最新一次查询的响应。
|
|
13
|
+
let disposed = false
|
|
15
14
|
|
|
16
|
-
// 提取异常提示;error 为捕获到的请求或处理异常。
|
|
17
15
|
const getErrorMessage = (error: unknown) => error instanceof Error ? error.message : '请求失败,请稍后重试'
|
|
18
16
|
|
|
19
|
-
//
|
|
17
|
+
// 时间转为本地显示,无效时间保留原文。
|
|
20
18
|
const formatDateTime = (value?: string) => {
|
|
21
19
|
if (!value?.trim()) return '—'
|
|
22
|
-
const date = new Date(value)
|
|
20
|
+
const date = new Date(value)
|
|
23
21
|
return Number.isNaN(date.getTime()) ? value : date.toLocaleString('zh-CN', { hour12: false })
|
|
24
22
|
}
|
|
25
23
|
|
|
26
|
-
//
|
|
27
|
-
const
|
|
24
|
+
// 使用整数分四舍五入,避免浮点数丢失金额精度。
|
|
25
|
+
const formatAmount = (value?: string) => {
|
|
28
26
|
const text = String(value ?? '').trim()
|
|
29
|
-
//
|
|
27
|
+
// 只移除合法千分位,格式错误时原样显示。
|
|
30
28
|
const normalized = /^[+-]?\d{1,3}(?:,\d{3})+(?:\.\d*)?$/.test(text) ? text.replace(/,/g, '') : text
|
|
31
|
-
const match = /^([+-]?)(\d*)(?:\.(\d*))?$/.exec(normalized)
|
|
32
|
-
if (!match || (!match[2] && !match[3])) return
|
|
33
|
-
|
|
34
|
-
return {
|
|
35
|
-
negative: match[1] === '-', // 是否为负数。
|
|
36
|
-
integer: (match[2] || '0').replace(/^0+(?=\d)/, ''), // 去掉前导零的整数部分。
|
|
37
|
-
fraction: (match[3] || '').replace(/0+$/, ''), // 去掉末尾零的小数部分。
|
|
38
|
-
}
|
|
39
|
-
}
|
|
29
|
+
const match = /^([+-]?)(\d*)(?:\.(\d*))?$/.exec(normalized)
|
|
30
|
+
if (!match || (!match[2] && !match[3])) return text || '—'
|
|
40
31
|
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
let cents = BigInt(amount.integer + fraction.slice(0, 2)) // 金额绝对值对应的整数分,使用 BigInt 保证精度。
|
|
48
|
-
if (fraction.charAt(2) >= '5') cents += 1n
|
|
49
|
-
|
|
50
|
-
const digits = cents.toString().padStart(3, '0') // 进位后的分字符串,至少三位以保证整数部分存在。
|
|
51
|
-
const integer = digits.slice(0, -2).replace(/\B(?=(\d{3})+(?!\d))/g, ',') // 带千分位的元整数部分。
|
|
52
|
-
const sign = amount.negative ? '-' : '' // 展示用的金额符号。
|
|
53
|
-
return `${sign}${integer}.${digits.slice(-2)}`
|
|
32
|
+
const [, sign, integer, decimals = ''] = match
|
|
33
|
+
const fraction = decimals.padEnd(3, '0')
|
|
34
|
+
const cents = BigInt((integer || '0') + fraction.slice(0, 2)) + (fraction.charAt(2) >= '5' ? 1n : 0n)
|
|
35
|
+
const whole = (cents / 100n).toLocaleString('en-US')
|
|
36
|
+
const decimal = (cents % 100n).toString().padStart(2, '0')
|
|
37
|
+
return `${sign === '-' ? '-' : ''}${whole}.${decimal}`
|
|
54
38
|
}
|
|
55
39
|
|
|
56
|
-
|
|
57
|
-
const
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const createForm = reactive({ adjustType: '', tranAmt: '' }) // 正在编辑的调整类型与调整金额。
|
|
64
|
-
const pendingCreate = ref(false) // 提交是否进行中,避免重复提交。
|
|
40
|
+
const dialogVisible = ref(false)
|
|
41
|
+
const pendingCreate = ref(false)
|
|
42
|
+
const formError = reactive({ adjustType: '', tranAmt: '' })
|
|
43
|
+
const createForm = reactive<{
|
|
44
|
+
adjustType: InjectionCreateParams['adjustType'] | ''
|
|
45
|
+
tranAmt: string
|
|
46
|
+
}>({ adjustType: '', tranAmt: '' })
|
|
65
47
|
|
|
66
|
-
|
|
67
|
-
const adjustTypeOptions = [
|
|
48
|
+
const adjustTypeOptions: { value: InjectionCreateParams['adjustType']; label: string }[] = [
|
|
68
49
|
{ value: 'PRFD', label: '注资调增' },
|
|
69
50
|
{ value: 'FDRD', label: '注资调减' },
|
|
70
51
|
{ value: 'FFIC', label: '预注资调增' },
|
|
71
52
|
{ value: 'FFRD', label: '预注资调减' },
|
|
72
|
-
]
|
|
53
|
+
]
|
|
73
54
|
|
|
74
55
|
// 打开发起弹窗,恢复默认表单。
|
|
75
56
|
const openCreateDialog = () => {
|
|
76
|
-
createForm
|
|
77
|
-
|
|
78
|
-
formError.adjustType = ''
|
|
79
|
-
formError.tranAmt = ''
|
|
57
|
+
Object.assign(createForm, { adjustType: '', tranAmt: '' })
|
|
58
|
+
Object.assign(formError, { adjustType: '', tranAmt: '' })
|
|
80
59
|
dialogVisible.value = true
|
|
81
60
|
}
|
|
82
61
|
|
|
83
|
-
//
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
const
|
|
62
|
+
// 提交成功后关闭弹窗并刷新余额。
|
|
63
|
+
const submitCreate = async () => {
|
|
64
|
+
if (pendingCreate.value || loading.value || disposed) return
|
|
65
|
+
const { adjustType } = createForm
|
|
66
|
+
const tranAmt = createForm.tranAmt.trim()
|
|
87
67
|
formError.adjustType = adjustType ? '' : '请选择调整类型'
|
|
88
|
-
formError.tranAmt = /^\d+(?:\.\d+)?$/.test(
|
|
89
|
-
? ''
|
|
68
|
+
formError.tranAmt = /^\d+(?:\.\d+)?$/.test(tranAmt) && /[1-9]/.test(tranAmt)
|
|
69
|
+
? ''
|
|
90
70
|
: '请输入大于 0 的调整金额'
|
|
91
|
-
|
|
92
|
-
}
|
|
71
|
+
if (!adjustType || formError.tranAmt) return
|
|
93
72
|
|
|
94
|
-
// 提交注资/预注资发起;成功后关闭弹窗,并重新查询账户行余额。
|
|
95
|
-
const submitCreate = async () => {
|
|
96
|
-
if (pendingCreate.value || loading.value) return
|
|
97
|
-
if (!validateForm()) return
|
|
98
|
-
const params: InjectionCreateParams = {
|
|
99
|
-
adjustType: createForm.adjustType as InjectionCreateParams['adjustType'],
|
|
100
|
-
tranAmt: createForm.tranAmt.trim(),
|
|
101
|
-
}
|
|
102
73
|
pendingCreate.value = true
|
|
103
74
|
try {
|
|
104
|
-
|
|
105
|
-
const { head } = await API.createApi(params) as any
|
|
75
|
+
const { head } = await API.createApi({ adjustType, tranAmt })
|
|
106
76
|
if (disposed) return
|
|
107
77
|
if (head?.retCode !== '00000') {
|
|
108
78
|
throw new Error(head?.retMsg || '提交失败')
|
|
109
79
|
}
|
|
110
80
|
ElMessage.success('注资/预注资发起已提交')
|
|
111
81
|
dialogVisible.value = false
|
|
112
|
-
void query()
|
|
113
|
-
} catch (error) {
|
|
82
|
+
void query()
|
|
83
|
+
} catch (error) {
|
|
114
84
|
if (!disposed) ElMessage.error(getErrorMessage(error))
|
|
115
85
|
} finally {
|
|
116
|
-
pendingCreate.value = false
|
|
86
|
+
if (!disposed) pendingCreate.value = false
|
|
117
87
|
}
|
|
118
88
|
}
|
|
119
89
|
|
|
120
|
-
|
|
121
|
-
|
|
90
|
+
type BalanceField = keyof AccountBalanceInfo
|
|
91
|
+
type DisplayField = [field: BalanceField, label: string, isMoney?: boolean]
|
|
92
|
+
|
|
93
|
+
const summaryAmounts: DisplayField[] = [
|
|
122
94
|
['bal', '结算钱包余额'],
|
|
123
95
|
['amount', '实时余额'],
|
|
124
96
|
['enableAmount', '其中:可用余额'],
|
|
125
97
|
['yesterdayAmount', '昨日余额'],
|
|
126
98
|
['nonBal', '对立账户余额(预注资金额)'],
|
|
127
|
-
]
|
|
99
|
+
]
|
|
128
100
|
|
|
129
|
-
//
|
|
130
|
-
const detailGroups = [
|
|
101
|
+
// 字段受接口类型约束,金额标记同时用于格式化和样式。
|
|
102
|
+
const detailGroups: { title: string; fields: DisplayField[] }[] = [
|
|
131
103
|
{
|
|
132
104
|
title: '机构与账户',
|
|
133
105
|
fields: [
|
|
134
|
-
['bankName', '机构名称'
|
|
135
|
-
['bankCode', '机构编码'
|
|
136
|
-
['innerName', '行内名称'
|
|
137
|
-
['innerAccount', '行内账号'
|
|
106
|
+
['bankName', '机构名称'],
|
|
107
|
+
['bankCode', '机构编码'],
|
|
108
|
+
['innerName', '行内名称'],
|
|
109
|
+
['innerAccount', '行内账号'],
|
|
138
110
|
],
|
|
139
111
|
},
|
|
140
112
|
{
|
|
141
113
|
title: '结算钱包',
|
|
142
114
|
fields: [
|
|
143
|
-
['sttlmWlltNm', '结算钱包名称'
|
|
144
|
-
['sttlmWlltId', '结算钱包 ID'
|
|
145
|
-
['sttlmWlltSts', '结算钱包状态'
|
|
146
|
-
['openDate', '开立时间'
|
|
115
|
+
['sttlmWlltNm', '结算钱包名称'],
|
|
116
|
+
['sttlmWlltId', '结算钱包 ID'],
|
|
117
|
+
['sttlmWlltSts', '结算钱包状态'],
|
|
118
|
+
['openDate', '开立时间'],
|
|
147
119
|
],
|
|
148
120
|
},
|
|
149
121
|
{
|
|
150
122
|
title: '注资参数',
|
|
151
123
|
fields: [
|
|
152
|
-
['ciSts', '注资预注资状态'
|
|
124
|
+
['ciSts', '注资预注资状态'],
|
|
153
125
|
['ciLmt', '注资最低金额(元)', true],
|
|
154
126
|
['realTmTxLmt', '实时业务注资下限(元)', true],
|
|
155
127
|
['wltWarnAmt', '钱包预警金额(元)', true],
|
|
@@ -166,58 +138,48 @@ const detailGroups = [
|
|
|
166
138
|
{
|
|
167
139
|
title: '报文信息',
|
|
168
140
|
fields: [
|
|
169
|
-
['refNo', '流水号'
|
|
170
|
-
['replyRefNo', '应答流水号'
|
|
171
|
-
['ptMsgId', '报文标识号'
|
|
172
|
-
['prtryDataType', '报文类型'
|
|
173
|
-
['sendOrganizeCode', '发起机构'
|
|
174
|
-
['rcvOrganizeCode', '接收机构'
|
|
175
|
-
['msgSendTime', '业务处理时间'
|
|
141
|
+
['refNo', '流水号'],
|
|
142
|
+
['replyRefNo', '应答流水号'],
|
|
143
|
+
['ptMsgId', '报文标识号'],
|
|
144
|
+
['prtryDataType', '报文类型'],
|
|
145
|
+
['sendOrganizeCode', '发起机构'],
|
|
146
|
+
['rcvOrganizeCode', '接收机构'],
|
|
147
|
+
['msgSendTime', '业务处理时间'],
|
|
176
148
|
],
|
|
177
149
|
},
|
|
178
150
|
{
|
|
179
151
|
title: '备注',
|
|
180
152
|
fields: [
|
|
181
|
-
['remark', '备注'
|
|
182
|
-
['rmk', '交易备注'
|
|
153
|
+
['remark', '备注'],
|
|
154
|
+
['rmk', '交易备注'],
|
|
183
155
|
],
|
|
184
156
|
},
|
|
185
|
-
]
|
|
186
|
-
|
|
187
|
-
// 展示数据:金额统一千分位、时间本地化,字段名 → 展示值。
|
|
188
|
-
const displayValues = computed<Record<string, string> | null>(() => {
|
|
189
|
-
if (!balance.value) return null
|
|
190
|
-
const raw = balance.value as unknown as Record<string, string | undefined>
|
|
191
|
-
return Object.fromEntries(Object.entries(raw).map(([key, value]) => {
|
|
192
|
-
const isAmount = detailGroups.some(group => group.fields.some(([field, , isMoney]) => field === key && isMoney))
|
|
193
|
-
|| summaryAmounts.some(([field]) => field === key) // 摘要金额同样千分位展示。
|
|
194
|
-
const isTime = key === 'msgSendTime'
|
|
195
|
-
if (key === 'sttlmWlltSts') return [key, formatWalletStatus(value)] // 钱包状态:先按字典映射,缺字典时保留原值。
|
|
196
|
-
return [key, isAmount ? formatAmount(value) : isTime ? formatDateTime(value) : String(value ?? '')]
|
|
197
|
-
}))
|
|
198
|
-
})
|
|
157
|
+
]
|
|
199
158
|
|
|
200
|
-
|
|
201
|
-
const
|
|
159
|
+
const displayValue = (field: BalanceField, isMoney = false) => {
|
|
160
|
+
const value = balance.value?.[field]?.trim()
|
|
161
|
+
if (!value) return '—'
|
|
162
|
+
if (isMoney) return formatAmount(value)
|
|
163
|
+
return field === 'msgSendTime' ? formatDateTime(value) : value
|
|
164
|
+
}
|
|
202
165
|
|
|
203
166
|
// 发起查询申请;接口未声明筛选条件,固定空参数。
|
|
204
167
|
const query = async () => {
|
|
205
168
|
if (disposed) return
|
|
206
|
-
const currentRequestId = ++requestId
|
|
169
|
+
const currentRequestId = ++requestId
|
|
207
170
|
loading.value = true
|
|
208
171
|
try {
|
|
209
|
-
|
|
210
|
-
const { head, body } = await API.queryBalanceApi() as any
|
|
172
|
+
const { head, body } = await API.queryBalanceApi()
|
|
211
173
|
if (currentRequestId !== requestId) return
|
|
212
174
|
if (head?.retCode !== '00000') {
|
|
213
175
|
throw new Error(head?.retMsg || '查询失败')
|
|
214
176
|
}
|
|
215
|
-
if (!body || typeof body !== 'object') {
|
|
177
|
+
if (!body || typeof body !== 'object' || Array.isArray(body)) {
|
|
216
178
|
throw new Error('查询结果格式异常')
|
|
217
179
|
}
|
|
218
180
|
balance.value = body
|
|
219
181
|
lastQueryTime.value = formatDateTime(new Date().toISOString())
|
|
220
|
-
} catch (error) {
|
|
182
|
+
} catch (error) {
|
|
221
183
|
if (currentRequestId !== requestId) return
|
|
222
184
|
balance.value = null
|
|
223
185
|
lastQueryTime.value = ''
|
|
@@ -227,7 +189,6 @@ const query = async () => {
|
|
|
227
189
|
}
|
|
228
190
|
}
|
|
229
191
|
|
|
230
|
-
// 页面首次显示时自动发起查询申请。
|
|
231
192
|
onMounted(query)
|
|
232
193
|
// 页面离开后,未完成的请求不再更新界面或弹出消息。
|
|
233
194
|
onBeforeUnmount(() => {
|
|
@@ -261,11 +222,10 @@ onBeforeUnmount(() => {
|
|
|
261
222
|
</div>
|
|
262
223
|
<el-tag class="wallet-status" type="warning" effect="light">{{ displayValue('sttlmWlltSts') }}</el-tag>
|
|
263
224
|
</header>
|
|
264
|
-
<!-- item 为摘要金额配置,value 为格式化后的展示值。 -->
|
|
265
225
|
<div class="amount-grid">
|
|
266
226
|
<div v-for="[field, label] in summaryAmounts" :key="field" class="amount-card">
|
|
267
227
|
<span class="amount-label">{{ label }}</span>
|
|
268
|
-
<strong class="amount-value">{{ displayValue(field) }}</strong>
|
|
228
|
+
<strong class="amount-value">{{ displayValue(field, true) }}</strong>
|
|
269
229
|
<span class="amount-unit">元</span>
|
|
270
230
|
</div>
|
|
271
231
|
</div>
|
|
@@ -274,14 +234,13 @@ onBeforeUnmount(() => {
|
|
|
274
234
|
<!-- 明细分组;group 为当前分组,包含标题和字段配置。无数据时展示空状态。 -->
|
|
275
235
|
<el-card class="balance-detail" shadow="never" :body-style="{ padding: '12px 14px' }">
|
|
276
236
|
<template v-if="balance">
|
|
277
|
-
<!-- field 为字段名,isMoney 为金额标记,label 为展示名称。 -->
|
|
278
237
|
<section v-for="group in detailGroups" :key="group.title" class="detail-group" :aria-label="group.title">
|
|
279
238
|
<h3>{{ group.title }}</h3>
|
|
280
239
|
<dl class="detail-fields">
|
|
281
|
-
<div v-for="[field, label] in group.fields" :key="field" class="detail-field">
|
|
240
|
+
<div v-for="[field, label, isMoney] in group.fields" :key="field" class="detail-field">
|
|
282
241
|
<dt>{{ label }}</dt>
|
|
283
|
-
<dd :class="{ 'detail-money':
|
|
284
|
-
{{ displayValue(field) }}
|
|
242
|
+
<dd :class="{ 'detail-money': isMoney }">
|
|
243
|
+
{{ displayValue(field, isMoney) }}
|
|
285
244
|
</dd>
|
|
286
245
|
</div>
|
|
287
246
|
</dl>
|
|
@@ -305,7 +264,6 @@ onBeforeUnmount(() => {
|
|
|
305
264
|
:close-on-press-escape="!pendingCreate"
|
|
306
265
|
>
|
|
307
266
|
<el-form :disabled="pendingCreate" label-position="top" @submit.prevent="submitCreate()">
|
|
308
|
-
<!-- value 为接口调整类型枚举,label 为中文含义。 -->
|
|
309
267
|
<el-form-item label="调整类型" :error="formError.adjustType">
|
|
310
268
|
<el-select v-model="createForm.adjustType" placeholder="请选择调整类型" clearable>
|
|
311
269
|
<el-option
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { computed, onBeforeUnmount, onMounted, reactive, ref } from 'vue'
|
|
3
|
-
import { ElMessage } from 'element-plus'
|
|
3
|
+
import { ElConfigProvider, ElMessage } from 'element-plus'
|
|
4
4
|
import { ArtDataTable, type ColumnOption, type PaginationOptions, type TableSettings } from '@/components/table'
|
|
5
5
|
import API from './api'
|
|
6
6
|
import type { InjectionFilters, InjectionQueryParams, InjectionRecord } from './typs'
|
|
@@ -318,6 +318,7 @@ onBeforeUnmount(() => {
|
|
|
318
318
|
</script>
|
|
319
319
|
|
|
320
320
|
<template>
|
|
321
|
+
<ElConfigProvider :size="tableSettings.size">
|
|
321
322
|
<main class="dcps-page">
|
|
322
323
|
<!-- 查询条件:控件尺寸跟随表格设置,卡片内边距为 10px,点击查询生效。 -->
|
|
323
324
|
<el-card v-show="showSearchBar" class="injection-search" shadow="never" :body-style="{ padding: '10px' }">
|
|
@@ -415,6 +416,7 @@ onBeforeUnmount(() => {
|
|
|
415
416
|
</template>
|
|
416
417
|
</el-dialog>
|
|
417
418
|
</main>
|
|
419
|
+
</ElConfigProvider>
|
|
418
420
|
</template>
|
|
419
421
|
|
|
420
422
|
<style scoped>
|
package/src/view/dcps/runtime.ts
CHANGED
|
@@ -1,35 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* 页面通过
|
|
2
|
+
* DCPS 各页面共用的运行时配置,仅默认导出一个对象。
|
|
3
|
+
* 页面通过 `import dcpsRuntime from '../runtime'` 引入;分组子页面使用 `../../runtime`。
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const parts = new Intl.DateTimeFormat('en-CA', {
|
|
12
|
-
timeZone: 'Asia/Shanghai', year: 'numeric', month: '2-digit', day: '2-digit',
|
|
13
|
-
}).formatToParts(new Date())
|
|
14
|
-
const read = (type: Intl.DateTimeFormatPartTypes) => parts.find((part) => part.type === type)?.value || ''
|
|
15
|
-
return read('year') + read('month') + read('day')
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/** 预报页面的默认查询日期;日期格式为 YYYYMMDD。 */
|
|
19
|
-
export const forecastRuntime = {
|
|
20
|
-
tranDate: getToday(), // 默认交易日期,查询和重置时使用。
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/** 授权页面的审批人和默认创建日期;日期格式为 YYYYMMDD,当前使用固定日期。 */
|
|
24
|
-
export const authRuntime = {
|
|
25
|
-
approverId: '10092', // 审批人工号。
|
|
26
|
-
approverName: '王干事', // 审批人姓名。
|
|
27
|
-
createTmBegin: '20261012', // 默认创建开始日期。
|
|
28
|
-
createTmEnd: '20261012', // 默认创建结束日期。
|
|
29
|
-
}
|
|
6
|
+
// 模块加载时按上海时区生成一次日期,所有页面共用,格式为 YYYYMMDD。
|
|
7
|
+
const dateParts = new Intl.DateTimeFormat('en-CA', {
|
|
8
|
+
timeZone: 'Asia/Shanghai', year: 'numeric', month: '2-digit', day: '2-digit',
|
|
9
|
+
}).formatToParts(new Date())
|
|
10
|
+
const readDatePart = (type: Intl.DateTimeFormatPartTypes) => dateParts.find((part) => part.type === type)?.value || ''
|
|
30
11
|
|
|
31
|
-
/** 按模块名聚合的运行时配置;也可从本文件直接引入单个模块的配置。 */
|
|
32
12
|
export default {
|
|
33
|
-
|
|
34
|
-
|
|
13
|
+
date: readDatePart('year') + readDatePart('month') + readDatePart('day'), // 共用业务日期。
|
|
14
|
+
approverId: '10092', // 工号。
|
|
15
|
+
approverName: '王干事', // 姓名。
|
|
35
16
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { computed, onBeforeUnmount, onMounted, reactive, ref } from 'vue'
|
|
3
|
-
import { ElMessage, ElMessageBox } from 'element-plus'
|
|
3
|
+
import { ElConfigProvider, ElMessage, ElMessageBox } from 'element-plus'
|
|
4
4
|
import API from './api'
|
|
5
|
-
import
|
|
5
|
+
import dcpsRuntime from '../runtime'
|
|
6
6
|
import { ArtDataTable, type ColumnOption, type PaginationOptions, type TableSettings } from '@/components/table'
|
|
7
7
|
import type {
|
|
8
8
|
CancelWriteOffPredItem, EditVerifyFormValues, FlowRow, ForecastRow, WriteOffFlowInput, WriteOffForecastItem, WriteOffItemInput,
|
|
@@ -246,7 +246,10 @@ const cancelWriteOff = async () => {
|
|
|
246
246
|
await ElMessageBox.confirm(
|
|
247
247
|
`确认撤销选中的${summaryParts.join('、')}核销?撤销后将重新查询两个列表。`,
|
|
248
248
|
'撤销核销',
|
|
249
|
-
{
|
|
249
|
+
{
|
|
250
|
+
confirmButtonText: '确认撤销', cancelButtonText: '取消', type: 'warning',
|
|
251
|
+
buttonSize: forecastTableSettings.value.size, distinguishCancelAndClose: true,
|
|
252
|
+
},
|
|
250
253
|
)
|
|
251
254
|
} catch { // 用户取消或关闭确认框时静默返回。
|
|
252
255
|
return
|
|
@@ -305,7 +308,7 @@ type ForecastAppliedQuery = {
|
|
|
305
308
|
|
|
306
309
|
// 默认查询条件;空字符串和空数组表示不限制该条件,重置时恢复此配置。
|
|
307
310
|
const createForecastFilters = () => ({
|
|
308
|
-
tranDate:
|
|
311
|
+
tranDate: dcpsRuntime.date,
|
|
309
312
|
acctNo: '',
|
|
310
313
|
banchPre: '',
|
|
311
314
|
busiType: '',
|
|
@@ -317,7 +320,7 @@ const createForecastFilters = () => ({
|
|
|
317
320
|
verifyStatusList: [] as string[],
|
|
318
321
|
})
|
|
319
322
|
const forecastFilters = ref(createForecastFilters())
|
|
320
|
-
let forecastAppliedQuery: ForecastAppliedQuery = { tranDate:
|
|
323
|
+
let forecastAppliedQuery: ForecastAppliedQuery = { tranDate: dcpsRuntime.date }
|
|
321
324
|
|
|
322
325
|
// 重复输入项共用一份配置,依次为字段、名称和输入框长度限制。
|
|
323
326
|
const forecastTextFilters = [
|
|
@@ -514,7 +517,7 @@ type FlowAppliedQuery = {
|
|
|
514
517
|
|
|
515
518
|
// 默认查询条件;空字符串表示不限制该条件,重置时恢复此配置。
|
|
516
519
|
const createFlowFilters = () => ({
|
|
517
|
-
tranDate:
|
|
520
|
+
tranDate: dcpsRuntime.date,
|
|
518
521
|
orgName: '',
|
|
519
522
|
payerName: '',
|
|
520
523
|
payeeName: '',
|
|
@@ -524,7 +527,7 @@ const createFlowFilters = () => ({
|
|
|
524
527
|
verifyStatus: '',
|
|
525
528
|
})
|
|
526
529
|
const flowFilters = ref(createFlowFilters())
|
|
527
|
-
let flowAppliedQuery: FlowAppliedQuery = { tranDate:
|
|
530
|
+
let flowAppliedQuery: FlowAppliedQuery = { tranDate: dcpsRuntime.date }
|
|
528
531
|
|
|
529
532
|
// 重复输入项共用一份配置,依次为字段、名称和输入框长度限制。
|
|
530
533
|
const flowTextFilters = [
|
|
@@ -678,6 +681,7 @@ onBeforeUnmount(() => {
|
|
|
678
681
|
</script>
|
|
679
682
|
|
|
680
683
|
<template>
|
|
684
|
+
<ElConfigProvider :size="forecastTableSettings.size">
|
|
681
685
|
<main class="dcps-page">
|
|
682
686
|
<!-- 上方:预报信息表格,核销、撤销核销按钮统一放在本表格工具栏。 -->
|
|
683
687
|
<section class="view-region">
|
|
@@ -810,6 +814,7 @@ onBeforeUnmount(() => {
|
|
|
810
814
|
</section>
|
|
811
815
|
|
|
812
816
|
<!-- 下方:流水信息表格,勾选行与预报勾选合并提交核销或撤销核销。 -->
|
|
817
|
+
<ElConfigProvider :size="flowTableSettings.size">
|
|
813
818
|
<section class="view-region">
|
|
814
819
|
<!-- 查询条件:控件尺寸跟随表格设置,卡片内边距为 10px,点击查询生效。 -->
|
|
815
820
|
<el-card v-show="flowShowSearchBar" class="write-off-search" shadow="never" :body-style="{ padding: '10px' }">
|
|
@@ -875,6 +880,7 @@ onBeforeUnmount(() => {
|
|
|
875
880
|
</ArtDataTable>
|
|
876
881
|
</div>
|
|
877
882
|
</section>
|
|
883
|
+
</ElConfigProvider>
|
|
878
884
|
|
|
879
885
|
<!-- 核销弹窗:预报信息逐条确认核销金额,流水信息按原值一并提交。 -->
|
|
880
886
|
<el-dialog
|
|
@@ -888,21 +894,21 @@ onBeforeUnmount(() => {
|
|
|
888
894
|
append-to-body
|
|
889
895
|
>
|
|
890
896
|
<div class="dialog-section-title">预报信息</div>
|
|
891
|
-
<el-table :data="writeOffPredItems" size="
|
|
897
|
+
<el-table :data="writeOffPredItems" :size="forecastTableSettings.size" border max-height="260px">
|
|
892
898
|
<el-table-column label="预报流水号" prop="predRefNo" min-width="190" show-overflow-tooltip />
|
|
893
899
|
<el-table-column label="预报金额(元)" width="160" align="right">
|
|
894
900
|
<template #default="{ row }"><span class="amount-cell">{{ formatAmount(row.predAmt) }}</span></template>
|
|
895
901
|
</el-table-column>
|
|
896
902
|
<el-table-column label="核销金额(元)" width="200">
|
|
897
903
|
<template #default="{ row }">
|
|
898
|
-
<el-input v-model="row.amount"
|
|
904
|
+
<el-input v-model="row.amount" inputmode="decimal" :maxlength="40" placeholder="输入核销金额" />
|
|
899
905
|
</template>
|
|
900
906
|
</el-table-column>
|
|
901
907
|
</el-table>
|
|
902
908
|
|
|
903
909
|
<template v-if="writeOffFlowItems.length">
|
|
904
910
|
<div class="dialog-section-title">流水信息</div>
|
|
905
|
-
<el-table :data="writeOffFlowItems" size="
|
|
911
|
+
<el-table :data="writeOffFlowItems" :size="flowTableSettings.size" border max-height="220px">
|
|
906
912
|
<el-table-column label="流水号" prop="refNo" min-width="190" show-overflow-tooltip />
|
|
907
913
|
<el-table-column label="交易金额(元)" width="180" align="right">
|
|
908
914
|
<template #default="{ row }"><span class="amount-cell">{{ formatAmount(row.tranAmt) }}</span></template>
|
|
@@ -918,6 +924,7 @@ onBeforeUnmount(() => {
|
|
|
918
924
|
</template>
|
|
919
925
|
</el-dialog>
|
|
920
926
|
</main>
|
|
927
|
+
</ElConfigProvider>
|
|
921
928
|
</template>
|
|
922
929
|
|
|
923
930
|
<style scoped>
|