minitest2.0 0.0.6 → 0.0.8

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.
Files changed (32) hide show
  1. package/package.json +1 -1
  2. package/public/images/dashboard/01-rmb-great-wall-bg.jpg +0 -0
  3. package/public/images/dashboard/02-city-clearing-skyline-bg.jpg +0 -0
  4. package/public/images/dashboard/03-cross-border-rmb-world-map-bg.jpg +0 -0
  5. package/public/images/dashboard/04-digital-currency-fintech-bg.jpg +0 -0
  6. package/public/images/dashboard/05-usd-liberty-bg.jpg +0 -0
  7. package/public/images/dashboard/06-eur-europe-architecture-bg.jpg +0 -0
  8. package/public/images/dashboard/07-hkd-hong-kong-skyline-bg.jpg +0 -0
  9. package/public/images/dashboard/08-jpy-mount-fuji-bg.jpg +0 -0
  10. package/src/api/dashboard.ts +44 -0
  11. package/src/api/foreign-position.ts +71 -0
  12. package/src/router/index.ts +29 -17
  13. package/src/utils/foreign-forecast.ts +37 -5
  14. package/src/views/{article-detail → announcement/detail}/index.vue +35 -1
  15. package/src/views/dashboard/index.vue +535 -2
  16. package/src/views/foreign/position/create/index.vue +363 -0
  17. package/src/views/foreign/position/detail/index.vue +390 -0
  18. package/src/views/foreign/position/index.vue +1223 -0
  19. package/src/views/foreign-position/index.vue +0 -26
  20. /package/src/views/{article-edit → announcement/edit}/index.vue +0 -0
  21. /package/src/views/{articles → announcement}/index.vue +0 -0
  22. /package/src/views/{settings → mine/settings}/index.vue +0 -0
  23. /package/src/views/{clearing-detail → rmb/clearing-detail}/index.vue +0 -0
  24. /package/src/views/{net-debit → rmb/net-debit}/index.vue +0 -0
  25. /package/src/views/{pbc-position → rmb/pbc-position}/index.vue +0 -0
  26. /package/src/views/{rmb-position-create → rmb/position/create}/index.vue +0 -0
  27. /package/src/views/{rmb-position-detail → rmb/position/detail}/index.vue +0 -0
  28. /package/src/views/{rmb-position → rmb/position}/index.vue +0 -0
  29. /package/src/views/{position-estimate → rmb/position-estimate}/index.vue +0 -0
  30. /package/src/views/{opening-reserve-estimate → rmb/position-estimate/opening-reserve}/index.vue +0 -0
  31. /package/src/views/{position-estimate-report → rmb/position-estimate/report}/index.vue +0 -0
  32. /package/src/views/{warning → rmb/warning}/index.vue +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "minitest2.0",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "repository": {
@@ -0,0 +1,44 @@
1
+ import { buildTamRequestPayload, tamRequest } from '@/api/tam'
2
+
3
+ export type RmbDashboardBody = {
4
+ /** 城银账户资金余额 */
5
+ availCredit?: string
6
+ /** 跨境人民币可用余额 */
7
+ cipsAvailBal?: string
8
+ /** 数字人民币可用余额 */
9
+ dcpTotalAmt?: string
10
+ /** 人行账户资金余额 */
11
+ settleAccAmt?: string
12
+ }
13
+
14
+ export type ForeignDashboardBody = {
15
+ eurDomesticAmt?: string
16
+ eurOverseasAmt?: string
17
+ hkdDomesticAmt?: string
18
+ hkdOverseasAmt?: string
19
+ jpyDomesticAmt?: string
20
+ jpyOverseasAmt?: string
21
+ usdDomesticAmt?: string
22
+ usdOverseasAmt?: string
23
+ }
24
+
25
+ const RMB_DASHBOARD_TRAN_CODE = '/TAM/0001/140000007'
26
+ const FOREIGN_DASHBOARD_TRAN_CODE = '/TAM/0001/140000008'
27
+
28
+ export function queryRmbDashboard() {
29
+ return tamRequest<Record<string, never>, RmbDashboardBody>(
30
+ buildTamRequestPayload({
31
+ tranCode: RMB_DASHBOARD_TRAN_CODE,
32
+ body: {},
33
+ }),
34
+ )
35
+ }
36
+
37
+ export function queryForeignDashboard() {
38
+ return tamRequest<Record<string, never>, ForeignDashboardBody>(
39
+ buildTamRequestPayload({
40
+ tranCode: FOREIGN_DASHBOARD_TRAN_CODE,
41
+ body: {},
42
+ }),
43
+ )
44
+ }
@@ -67,6 +67,17 @@ export type ForeignForecastQueryResult = {
67
67
  head: TamResponse<ForeignForecastQueryResultBody>['head']
68
68
  }
69
69
 
70
+ export type ForeignForecastDetailPayload = {
71
+ appHead: TamRequestPayload<ForeignForecastDetailBody>['appHead']
72
+ body: ForeignForecastDetailBody
73
+ head: TamRequestPayload<ForeignForecastDetailBody>['head']
74
+ }
75
+
76
+ export type ForeignForecastDetailResult = {
77
+ body: ForeignForecastDetailRecord
78
+ head: TamResponse<ForeignForecastDetailRecord>['head']
79
+ }
80
+
70
81
  type ForeignForecastQueryBody = {
71
82
  busiType: string
72
83
  clientName: string
@@ -87,6 +98,50 @@ type ForeignForecastQueryResultBody = {
87
98
  totalCount: string
88
99
  }
89
100
 
101
+ type ForeignForecastDetailBody = {
102
+ /** 预报流水号,详情查询主键。 */
103
+ predRefNo: string
104
+ }
105
+
106
+ export type ForeignForecastDetailRecord = ForeignForecastRecord & {
107
+ /** 出票日 */
108
+ billDate?: string
109
+ /** 票号 */
110
+ billNo?: string
111
+ /** 交易对手账号 */
112
+ competAcct?: string
113
+ /** 额度标志 */
114
+ eduFlag?: string
115
+ /** 落地机构代码 */
116
+ groundBranchCode?: string
117
+ /** 联系人 */
118
+ linkMan?: string
119
+ /** 支付渠道 */
120
+ payChannel?: string
121
+ /** 收支方向 */
122
+ payDirec?: string
123
+ /** 联系电话 */
124
+ phoneNo?: string
125
+ /** 预报机构 */
126
+ predBranch?: string
127
+ /** 预报机构名称 */
128
+ predBranchName?: string
129
+ /** 预报人员编号 */
130
+ predCode?: string
131
+ /** 预报日期 */
132
+ predDate?: string
133
+ /** 预报人员姓名 */
134
+ predName?: string
135
+ /** 用途 */
136
+ purpose?: string
137
+ /** 备注 */
138
+ remark?: string
139
+ /** 标准名称 */
140
+ standardName?: string
141
+ /** 已核销金额 */
142
+ verifyAmt?: string
143
+ }
144
+
90
145
  type QueryOptions = {
91
146
  form: ForeignForecastQueryForm
92
147
  pageIndex: number
@@ -94,6 +149,7 @@ type QueryOptions = {
94
149
  }
95
150
 
96
151
  const QUERY_TRAN_CODE = '/TAM/0001/140101001'
152
+ const DETAIL_TRAN_CODE = '/TAM/0001/140101002'
97
153
 
98
154
  export function buildForeignForecastQueryPayload({
99
155
  form,
@@ -129,6 +185,21 @@ export async function queryForeignForecastPage(
129
185
  return tamRequest<ForeignForecastQueryBody, ForeignForecastQueryResultBody>(payload)
130
186
  }
131
187
 
188
+ export function buildForeignForecastDetailPayload(predRefNo: string): ForeignForecastDetailPayload {
189
+ return buildTamRequestPayload({
190
+ tranCode: DETAIL_TRAN_CODE,
191
+ body: {
192
+ predRefNo,
193
+ },
194
+ })
195
+ }
196
+
197
+ export async function queryForeignForecastDetail(
198
+ payload: ForeignForecastDetailPayload,
199
+ ): Promise<ForeignForecastDetailResult> {
200
+ return tamRequest<ForeignForecastDetailBody, ForeignForecastDetailRecord>(payload)
201
+ }
202
+
132
203
  function normalizeDate(value: string) {
133
204
  if (/^\d{8}$/.test(value)) return value
134
205
  return value.replaceAll('-', '')
@@ -26,67 +26,79 @@ const router = createRouter({
26
26
  {
27
27
  path: '/rmb-position',
28
28
  name: 'RmbPosition',
29
- component: () => import('@/views/rmb-position/index.vue'),
29
+ component: () => import('@/views/rmb/position/index.vue'),
30
30
  meta: { requiresAuth: true, title: '本币预报信息查询' },
31
31
  },
32
32
  {
33
33
  path: '/rmb-position/new',
34
34
  name: 'RmbPositionCreate',
35
- component: () => import('@/views/rmb-position-create/index.vue'),
35
+ component: () => import('@/views/rmb/position/create/index.vue'),
36
36
  meta: { requiresAuth: true, title: '新增本币预报' },
37
37
  },
38
38
  {
39
39
  path: '/rmb-position/:predRefNo',
40
40
  name: 'RmbPositionDetail',
41
- component: () => import('@/views/rmb-position-detail/index.vue'),
41
+ component: () => import('@/views/rmb/position/detail/index.vue'),
42
42
  meta: { requiresAuth: true, title: '预报详情' },
43
43
  },
44
44
  {
45
45
  path: '/foreign-position',
46
46
  name: 'ForeignPosition',
47
- component: () => import('@/views/foreign-position/index.vue'),
48
- meta: { requiresAuth: true, title: '外币头寸预报及查询' },
47
+ component: () => import('@/views/foreign/position/index.vue'),
48
+ meta: { requiresAuth: true, title: '外币预报信息查询' },
49
+ },
50
+ {
51
+ path: '/foreign-position/new',
52
+ name: 'ForeignPositionCreate',
53
+ component: () => import('@/views/foreign/position/create/index.vue'),
54
+ meta: { requiresAuth: true, title: '新增外币预报' },
55
+ },
56
+ {
57
+ path: '/foreign-position/:predRefNo',
58
+ name: 'ForeignPositionDetail',
59
+ component: () => import('@/views/foreign/position/detail/index.vue'),
60
+ meta: { requiresAuth: true, title: '外币预报详情' },
49
61
  },
50
62
  {
51
63
  path: '/pbc-position',
52
64
  name: 'PbcPosition',
53
- component: () => import('@/views/pbc-position/index.vue'),
65
+ component: () => import('@/views/rmb/pbc-position/index.vue'),
54
66
  meta: { requiresAuth: true, title: '人行头寸余额查询' },
55
67
  },
56
68
  {
57
69
  path: '/position-estimate',
58
70
  name: 'PositionEstimate',
59
- component: () => import('@/views/position-estimate/index.vue'),
71
+ component: () => import('@/views/rmb/position-estimate/index.vue'),
60
72
  meta: { requiresAuth: true, title: '头寸匡算' },
61
73
  },
62
74
  {
63
75
  path: '/position-estimate/report',
64
76
  name: 'PositionEstimateReport',
65
- component: () => import('@/views/position-estimate-report/index.vue'),
77
+ component: () => import('@/views/rmb/position-estimate/report/index.vue'),
66
78
  meta: { requiresAuth: true, title: '头寸匡算报表' },
67
79
  },
68
80
  {
69
81
  path: '/position-estimate/opening-reserve',
70
82
  name: 'OpeningReserveEstimate',
71
- component: () => import('@/views/opening-reserve-estimate/index.vue'),
83
+ component: () => import('@/views/rmb/position-estimate/opening-reserve/index.vue'),
72
84
  meta: { requiresAuth: true, title: '日初备款数匡算' },
73
85
  },
74
86
  {
75
87
  path: '/net-debit',
76
88
  name: 'NetDebit',
77
- component: () => import('@/views/net-debit/index.vue'),
89
+ component: () => import('@/views/rmb/net-debit/index.vue'),
78
90
  meta: { requiresAuth: true, title: '人民币净借记可用额度管理' },
79
91
  },
80
92
  {
81
93
  path: '/clearing-detail',
82
94
  name: 'ClearingDetail',
83
- component: () => import('@/views/clearing-detail/index.vue'),
95
+ component: () => import('@/views/rmb/clearing-detail/index.vue'),
84
96
  meta: { requiresAuth: true, title: '人民币小额网银清算场次明细' },
85
97
  },
86
98
  {
87
99
  path: '/warning',
88
100
  name: 'Warning',
89
- component: () => import('@/views/warning/index.vue'),
101
+ component: () => import('@/views/rmb/warning/index.vue'),
90
102
  meta: { requiresAuth: true, title: '头寸管理平台' },
91
103
  },
92
104
  {
@@ -98,25 +110,25 @@ const router = createRouter({
98
110
  {
99
111
  path: '/articles',
100
112
  name: 'Articles',
101
- component: () => import('@/views/articles/index.vue'),
113
+ component: () => import('@/views/announcement/index.vue'),
102
114
  meta: { requiresAuth: true, showTabbar: true, title: '公告' },
103
115
  },
104
116
  {
105
117
  path: '/articles/new',
106
118
  name: 'ArticlePublish',
107
- component: () => import('@/views/article-edit/index.vue'),
119
+ component: () => import('@/views/announcement/edit/index.vue'),
108
120
  meta: { requiresAuth: true, title: '发布公告' },
109
121
  },
110
122
  {
111
123
  path: '/articles/:id',
112
124
  name: 'ArticleDetail',
113
- component: () => import('@/views/article-detail/index.vue'),
125
+ component: () => import('@/views/announcement/detail/index.vue'),
114
126
  meta: { requiresAuth: true, title: '公告详情' },
115
127
  },
116
128
  {
117
129
  path: '/articles/:id/edit',
118
130
  name: 'ArticleEdit',
119
- component: () => import('@/views/article-edit/index.vue'),
131
+ component: () => import('@/views/announcement/edit/index.vue'),
120
132
  meta: { requiresAuth: true, title: '编辑公告' },
121
133
  },
122
134
  {
@@ -128,7 +140,7 @@ const router = createRouter({
128
140
  {
129
141
  path: '/settings',
130
142
  name: 'Settings',
131
- component: () => import('@/views/settings/index.vue'),
143
+ component: () => import('@/views/mine/settings/index.vue'),
132
144
  meta: { requiresAuth: true, title: '设置' },
133
145
  },
134
146
  ],
@@ -14,8 +14,15 @@ export type ForeignStatusOption = ForeignOption & {
14
14
  className: string
15
15
  }
16
16
 
17
+ export const allForeignCurrencyOption: ForeignCurrencyOption = {
18
+ label: '全部币种',
19
+ shortLabel: '全部币种',
20
+ value: '',
21
+ unit: '万元',
22
+ }
23
+
17
24
  export const foreignCurrencyOptions: ForeignCurrencyOption[] = [
18
- { label: '全部币种', shortLabel: '全部币种', value: '', unit: '万元' },
25
+ allForeignCurrencyOption,
19
26
  { label: '美元', shortLabel: '美元', value: 'USD', unit: '万美元' },
20
27
  { label: '欧元', shortLabel: '欧元', value: 'EUR', unit: '万欧元' },
21
28
  { label: '港币', shortLabel: '港币', value: 'HKD', unit: '万港币' },
@@ -27,9 +34,12 @@ export const foreignCurrencyOptions: ForeignCurrencyOption[] = [
27
34
  { label: '瑞士法郎', shortLabel: '瑞郎', value: 'CHF', unit: '万瑞郎' },
28
35
  ]
29
36
 
37
+ export const allForeignBusinessOption: ForeignOption = { label: '全部业务类型', value: '' }
38
+ export const defaultForeignBusinessOption: ForeignOption = { label: '普通汇款', value: '1' }
39
+
30
40
  export const foreignBusinessOptions: ForeignOption[] = [
31
- { label: '全部业务类型', value: '' },
32
- { label: '普通汇款', value: '1' },
41
+ allForeignBusinessOption,
42
+ defaultForeignBusinessOption,
33
43
  { label: '外汇买卖', value: '2' },
34
44
  { label: '结售汇', value: '3' },
35
45
  { label: '资金调拨', value: '4' },
@@ -37,8 +47,14 @@ export const foreignBusinessOptions: ForeignOption[] = [
37
47
  { label: '贸易融资', value: '6' },
38
48
  ]
39
49
 
50
+ export const allForeignStatusOption: ForeignStatusOption = {
51
+ label: '全部预报状态',
52
+ value: '',
53
+ className: 'status-tag-unknown',
54
+ }
55
+
40
56
  export const foreignStatusOptions: ForeignStatusOption[] = [
41
- { label: '全部预报状态', value: '', className: 'status-tag-unknown' },
57
+ allForeignStatusOption,
42
58
  { label: '已确认', value: '1', className: 'status-tag-confirmed' },
43
59
  { label: '待确认', value: '2', className: 'status-tag-pending' },
44
60
  { label: '已撤销', value: '3', className: 'status-tag-cancelled' },
@@ -56,7 +72,7 @@ export function resolveForeignCurrency(value?: string) {
56
72
  const normalizedValue = value?.trim().toUpperCase()
57
73
 
58
74
  if (!normalizedValue) {
59
- return foreignCurrencyOptions[0]
75
+ return allForeignCurrencyOption
60
76
  }
61
77
 
62
78
  return (
@@ -100,3 +116,19 @@ export function formatForeignForecastAmount(value: number) {
100
116
  const sign = value >= 0 ? '+' : '-'
101
117
  return `${sign}${Math.abs(value).toFixed(2)}`
102
118
  }
119
+
120
+ export function formatForeignForecastAmountText(value?: string, currencyValue?: string) {
121
+ const currency = resolveForeignCurrency(currencyValue)
122
+ return `${formatForeignForecastAmount(toTenThousandAmount(value))}${currency.unit}`
123
+ }
124
+
125
+ export function formatForeignForecastAmountYuanText(value?: string) {
126
+ const amount = Number(value?.replaceAll(',', '') || 0)
127
+
128
+ if (!Number.isFinite(amount)) return '-'
129
+
130
+ return `${amount.toLocaleString('zh-CN', {
131
+ maximumFractionDigits: 2,
132
+ minimumFractionDigits: 2,
133
+ })} 元`
134
+ }
@@ -1,4 +1,5 @@
1
1
  <script setup lang="ts">
2
+ import { showImagePreview } from 'vant'
2
3
  import { highlightArticleHtml } from '@/utils/code-highlight'
3
4
  import { copyText } from '@/utils/copy'
4
5
  import { formatArticleDate, getArticleDetail, type Article } from '@/api/announcement'
@@ -81,6 +82,38 @@ function articleContentToText(html: string) {
81
82
 
82
83
  return root.textContent?.replace(/\n{3,}/g, '\n\n').trim() || ''
83
84
  }
85
+
86
+ function previewArticleImage(event: MouseEvent) {
87
+ if (!(event.target instanceof HTMLImageElement)) {
88
+ return
89
+ }
90
+
91
+ const container = event.currentTarget
92
+
93
+ if (!(container instanceof HTMLElement)) {
94
+ return
95
+ }
96
+
97
+ const images = Array.from(container.querySelectorAll('img'))
98
+ .map((image) => image.currentSrc || image.src || image.getAttribute('src') || '')
99
+ .filter(Boolean)
100
+ const currentSrc =
101
+ event.target.currentSrc || event.target.src || event.target.getAttribute('src') || ''
102
+ const startPosition = Math.max(images.findIndex((image) => image === currentSrc), 0)
103
+
104
+ if (!images.length || !currentSrc) {
105
+ return
106
+ }
107
+
108
+ event.preventDefault()
109
+ event.stopPropagation()
110
+
111
+ showImagePreview({
112
+ images,
113
+ startPosition,
114
+ closeable: true,
115
+ })
116
+ }
84
117
  </script>
85
118
 
86
119
  <template>
@@ -98,7 +131,7 @@ function articleContentToText(html: string) {
98
131
  </div>
99
132
  </div>
100
133
 
101
- <div class="article-content" v-html="highlightedContent"></div>
134
+ <div class="article-content" @click="previewArticleImage" v-html="highlightedContent"></div>
102
135
 
103
136
  <footer class="detail-actions">
104
137
  <van-button block plain type="danger" icon="description-o" @click="copyArticleContent">
@@ -225,6 +258,7 @@ function articleContentToText(html: string) {
225
258
  height: auto;
226
259
  margin: 8px auto 14px;
227
260
  border-radius: 6px;
261
+ cursor: zoom-in;
228
262
  object-fit: contain;
229
263
  }
230
264