minitest2.0 0.0.8 → 0.0.10

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "minitest2.0",
3
- "version": "0.0.8",
3
+ "version": "0.0.10",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "repository": {
@@ -7,53 +7,103 @@ import {
7
7
  import { useAppStore } from '@/stores/app'
8
8
 
9
9
  export type ForeignForecastRecord = {
10
- /** 业务类型。 */
10
+ /** 授权标志。 */
11
+ authorization?: string
12
+ /** 账户行。 */
13
+ bankAcct?: string
14
+ /** 旧接口业务类型字段,详情接口暂时兼容使用。 */
11
15
  busiType?: string
12
- /** 币种字段,不同后端版本可能返回不同命名。 */
16
+ /** 币种。 */
13
17
  ccy?: string
14
- currency?: string
15
- currencyCode?: string
16
- currCode?: string
17
- curType?: string
18
- tranCcy?: string
19
- /** 客户类型或客户名称,用于列表副标题兜底。 */
18
+ /** 客户账号。 */
19
+ clientAcct?: string
20
+ /** 客户名称。 */
20
21
  clientName?: string
21
- clientType?: string
22
+ /** 交易对手账号。 */
23
+ competAcct?: string
24
+ /** 交易对手 Swift Code。 */
25
+ competAcctSc?: string
26
+ /** 交易对手。 */
22
27
  competName?: string
23
- /** 交易对手或清算行信息。 */
24
- bankSwift?: string
25
- bicCode?: string
26
- routeCode?: string
27
- swiftCode?: string
28
- /** 落地机构,列表主标题展示字段。 */
28
+ /** 单证业务编号。 */
29
+ docbusinessno?: string
30
+ /** 落地机构。 */
29
31
  groundBranch?: string
32
+ /** 中间行 Swift Code。 */
33
+ midBankSc?: string
34
+ /** 结汇、购汇或现汇。 */
35
+ originalForeign?: string
36
+ /** 收支方向。 */
37
+ payDirec?: string
38
+ /** 联系电话。 */
39
+ phoneNo?: string
30
40
  /** 预报金额,接口按元级金额返回,页面转换为万元级展示。 */
31
41
  predAmt?: string
42
+ /** 预报人编号。 */
43
+ predCode?: string
44
+ /** 预报时间。 */
45
+ predDate?: string
46
+ /** 预报机构。 */
47
+ predDept?: string
48
+ /** 预报人。 */
49
+ predName?: string
32
50
  /** 预报流水号,后续详情查询主键。 */
33
51
  predRefNo?: string
34
52
  /** 预报状态。 */
35
53
  predStatus?: string
36
- /** 交易日期。 */
54
+ /** 预报类型。 */
55
+ predType?: string
56
+ /** 预报方式。 */
57
+ predWay?: string
58
+ /** 交易对手行名称。 */
59
+ rcvBank?: string
60
+ /** 交易对手行 Swift Code。 */
61
+ rcvBankSc?: string
62
+ /** 备注。 */
63
+ remark?: string
64
+ /** 起息日期。 */
37
65
  tranDate?: string
66
+ /** 业务类型。 */
67
+ tranType?: string
68
+ /** 未核销金额。 */
69
+ unverifyAmt?: string
70
+ /** 审批时间。 */
71
+ updateTime?: string
72
+ /** 核销金额。 */
73
+ verifyAmt?: string
38
74
  /** 核销状态。 */
39
75
  verifyStatus?: string
76
+ /** 兼容旧接口可能返回的币种字段。 */
77
+ currency?: string
78
+ currencyCode?: string
79
+ currCode?: string
80
+ curType?: string
81
+ tranCcy?: string
82
+ /** 兼容旧接口返回字段。 */
83
+ clientType?: string
84
+ bankSwift?: string
85
+ bicCode?: string
86
+ routeCode?: string
87
+ swiftCode?: string
40
88
  }
41
89
 
42
90
  export type ForeignForecastQueryForm = {
43
- /** 交易时间,当前视图必填筛选项。 */
91
+ /** 起息日。 */
44
92
  tranDate: string
45
- /** 落地机构关键字。 */
46
- groundBranch?: string
47
- /** 币种,当前后端交易未明确入参时页面做兼容筛选。 */
48
- currency?: string
93
+ /** 机构名称。 */
94
+ orgName?: string
95
+ /** 币种。 */
96
+ ccy?: string
49
97
  /** 业务类型。 */
50
- busiType?: string
98
+ tranType?: string
51
99
  /** 预报状态。 */
52
100
  predStatus?: string
101
+ /** 筛选 FTU 数据,否为空、是为 1。 */
102
+ filter?: string
53
103
  /** 起始金额,页面单位为万元。 */
54
- startTranAmt?: string
104
+ startAmt?: string
55
105
  /** 截止金额,页面单位为万元。 */
56
- endTranAmt?: string
106
+ endAmt?: string
57
107
  }
58
108
 
59
109
  export type ForeignForecastQueryPayload = {
@@ -79,23 +129,30 @@ export type ForeignForecastDetailResult = {
79
129
  }
80
130
 
81
131
  type ForeignForecastQueryBody = {
82
- busiType: string
132
+ amtOrder: number | ''
133
+ authorization: string
134
+ ccy: string
83
135
  clientName: string
84
- competName: string
85
- endTransAmt: string
86
- groundBranch: string
87
- payChannel: string
136
+ endAmt: string
137
+ filter: string
138
+ opType: string
139
+ orgName: string
140
+ originalForeign: string
88
141
  payDirec: string
142
+ predOrder: number | ''
89
143
  predStatus: string
90
- sortRule: string
91
- startTransAmt: string
144
+ predWay: string
145
+ startAmt: string
146
+ timeOrder: number | ''
92
147
  tranDate: string
148
+ tranType: string
93
149
  verifyStatus: string
94
150
  }
95
151
 
96
152
  type ForeignForecastQueryResultBody = {
97
- resultList: ForeignForecastRecord[]
153
+ resultInfos: ForeignForecastRecord[]
98
154
  totalCount: string
155
+ totalPage: string
99
156
  }
100
157
 
101
158
  type ForeignForecastDetailBody = {
@@ -148,7 +205,7 @@ type QueryOptions = {
148
205
  pageSize: number
149
206
  }
150
207
 
151
- const QUERY_TRAN_CODE = '/TAM/0001/140101001'
208
+ const QUERY_TRAN_CODE = '/TAM/0001/140201001'
152
209
  const DETAIL_TRAN_CODE = '/TAM/0001/140101002'
153
210
 
154
211
  export function buildForeignForecastQueryPayload({
@@ -163,17 +220,23 @@ export function buildForeignForecastQueryPayload({
163
220
  pageIndex,
164
221
  pageSize,
165
222
  body: {
166
- busiType: form.busiType || '',
223
+ amtOrder: '',
224
+ authorization: '',
225
+ ccy: form.ccy || '',
167
226
  clientName: '',
168
- competName: '',
169
- endTransAmt: toRequestAmount(form.endTranAmt),
170
- groundBranch: form.groundBranch || '',
171
- payChannel: '',
227
+ endAmt: toRequestAmount(form.endAmt),
228
+ filter: form.filter || '',
229
+ opType: '',
230
+ orgName: form.orgName || '',
231
+ originalForeign: '',
172
232
  payDirec: '',
233
+ predOrder: '',
173
234
  predStatus: form.predStatus || '',
174
- sortRule: '',
175
- startTransAmt: toRequestAmount(form.startTranAmt),
235
+ predWay: '',
236
+ startAmt: toRequestAmount(form.startAmt),
237
+ timeOrder: '',
176
238
  tranDate,
239
+ tranType: form.tranType || '',
177
240
  verifyStatus: '',
178
241
  },
179
242
  })
@@ -0,0 +1,38 @@
1
+ import { defineStore } from 'pinia'
2
+
3
+ /**
4
+ * 头寸预报查询筛选区状态 Store
5
+ *
6
+ * 只保存列表页筛选条件面板的展开/收起状态,避免和应用级配置混在一起。
7
+ */
8
+ export const usePositionFilterStore = defineStore(
9
+ 'positionFilter',
10
+ () => {
11
+ /** 人民币头寸预报及查询列表筛选条件是否展开,默认收起并持久化用户选择。 */
12
+ const rmbFilterExpanded = ref(false)
13
+
14
+ /** 外币头寸预报及查询列表筛选条件是否展开,默认收起并持久化用户选择。 */
15
+ const foreignFilterExpanded = ref(false)
16
+
17
+ function setRmbFilterExpanded(value: boolean) {
18
+ rmbFilterExpanded.value = value
19
+ }
20
+
21
+ function setForeignFilterExpanded(value: boolean) {
22
+ foreignFilterExpanded.value = value
23
+ }
24
+
25
+ return {
26
+ rmbFilterExpanded,
27
+ foreignFilterExpanded,
28
+ setRmbFilterExpanded,
29
+ setForeignFilterExpanded,
30
+ }
31
+ },
32
+ {
33
+ persist: {
34
+ key: 'mini2_position_filter_settings',
35
+ pick: ['rmbFilterExpanded', 'foreignFilterExpanded'],
36
+ },
37
+ },
38
+ )
@@ -23,28 +23,37 @@ export const allForeignCurrencyOption: ForeignCurrencyOption = {
23
23
 
24
24
  export const foreignCurrencyOptions: ForeignCurrencyOption[] = [
25
25
  allForeignCurrencyOption,
26
- { label: '美元', shortLabel: '美元', value: 'USD', unit: '万美元' },
27
- { label: '欧元', shortLabel: '欧元', value: 'EUR', unit: '万欧元' },
28
- { label: '港币', shortLabel: '港币', value: 'HKD', unit: '万港币' },
29
- { label: '日元', shortLabel: '日元', value: 'JPY', unit: '万日元' },
30
- { label: '英镑', shortLabel: '英镑', value: 'GBP', unit: '万英镑' },
31
- { label: '加拿大元', shortLabel: '加元', value: 'CAD', unit: '万加元' },
32
- { label: '澳大利亚元', shortLabel: '澳元', value: 'AUD', unit: '万澳元' },
33
- { label: '新加坡元', shortLabel: '新元', value: 'SGD', unit: '万新元' },
34
- { label: '瑞士法郎', shortLabel: '瑞郎', value: 'CHF', unit: '万瑞郎' },
26
+ { label: 'CNY-人民币', shortLabel: '人民币', value: 'CNY', unit: '万元' },
27
+ { label: 'USD-美元', shortLabel: '美元', value: 'USD', unit: '万美元' },
28
+ { label: 'HKD-港元', shortLabel: '港元', value: 'HKD', unit: '万港元' },
29
+ { label: 'EUR-欧元', shortLabel: '欧元', value: 'EUR', unit: '万欧元' },
30
+ { label: 'AUD-澳大利亚元', shortLabel: '澳大利亚元', value: 'AUD', unit: '万澳大利亚元' },
31
+ { label: 'CHF-瑞士法郎', shortLabel: '瑞士法郎', value: 'CHF', unit: '万瑞士法郎' },
32
+ { label: 'GBP-英镑', shortLabel: '英镑', value: 'GBP', unit: '万英镑' },
33
+ { label: 'CAD-加拿大元', shortLabel: '加拿大元', value: 'CAD', unit: '万加拿大元' },
34
+ { label: 'NZD-新西兰元', shortLabel: '新西兰元', value: 'NZD', unit: '万新西兰元' },
35
+ { label: 'SGD-新加坡元', shortLabel: '新加坡元', value: 'SGD', unit: '万新加坡元' },
36
+ { label: 'JPY-日元', shortLabel: '日元', value: 'JPY', unit: '万日元' },
37
+ { label: 'SEK-瑞典克朗', shortLabel: '瑞典克朗', value: 'SEK', unit: '万瑞典克朗' },
38
+ { label: 'NOK-挪威克朗', shortLabel: '挪威克朗', value: 'NOK', unit: '万挪威克朗' },
39
+ { label: 'DKK-丹麦克朗', shortLabel: '丹麦克朗', value: 'DKK', unit: '万丹麦克朗' },
40
+ {
41
+ label: 'KZT-哈萨克斯坦坚戈',
42
+ shortLabel: '哈萨克斯坦坚戈',
43
+ value: 'KZT',
44
+ unit: '万哈萨克斯坦坚戈',
45
+ },
35
46
  ]
36
47
 
37
48
  export const allForeignBusinessOption: ForeignOption = { label: '全部业务类型', value: '' }
38
- export const defaultForeignBusinessOption: ForeignOption = { label: '普通汇款', value: '1' }
49
+ export const defaultForeignBusinessOption: ForeignOption = { label: '普通汇款', value: '10' }
39
50
 
40
51
  export const foreignBusinessOptions: ForeignOption[] = [
41
52
  allForeignBusinessOption,
42
53
  defaultForeignBusinessOption,
43
- { label: '外汇买卖', value: '2' },
44
- { label: '结售汇', value: '3' },
45
- { label: '资金调拨', value: '4' },
46
- { label: '同业业务', value: '5' },
47
- { label: '贸易融资', value: '6' },
54
+ { label: '单证业务', value: '11' },
55
+ { label: '同业/其他业务', value: '12' },
56
+ { label: '资金调拨', value: '13' },
48
57
  ]
49
58
 
50
59
  export const allForeignStatusOption: ForeignStatusOption = {
@@ -30,7 +30,7 @@ const form = reactive({
30
30
  tranDate: getInitialTranDate(),
31
31
  institution: '北京银行总行核算中心',
32
32
  currency: 'USD',
33
- business: '1',
33
+ business: '10',
34
34
  counterparty: '',
35
35
  amount: '',
36
36
  })
@@ -6,6 +6,7 @@ import {
6
6
  type ForeignForecastRecord,
7
7
  } from '@/api/foreign-position'
8
8
  import { useAppStore } from '@/stores/app'
9
+ import { usePositionFilterStore } from '@/stores/position-filter'
9
10
  import {
10
11
  allForeignBusinessOption,
11
12
  allForeignStatusOption,
@@ -48,23 +49,30 @@ type PendingForecast = {
48
49
  amount: number
49
50
  }
50
51
 
51
- type SelectorType = 'currency' | 'business' | 'status'
52
+ type SelectorType = 'currency' | 'business' | 'status' | 'filterFTU'
52
53
 
53
54
  type SelectorOption = ForeignOption | ForeignStatusOption
54
55
 
55
56
  const router = useRouter()
56
57
  const appStore = useAppStore()
58
+ const positionFilterStore = usePositionFilterStore()
57
59
  const defaultTranDate = appStore.systemWorkDate
58
60
  const heroImage = `${import.meta.env.BASE_URL}images/12a73787-86a9-4891-a65f-66104746f6a8.png`
59
61
  const pageSize = 10
60
62
  const backTopThreshold = 520
61
63
  const pendingForecastKey = 'foreign-position:pending-create'
64
+ const defaultFilterFTUOption: ForeignOption = { label: '否', value: '' }
65
+ const filterFTUOptions: ForeignOption[] = [
66
+ defaultFilterFTUOption,
67
+ { label: '是', value: '1' },
68
+ ]
62
69
 
63
70
  const queryForm = reactive({
64
71
  institution: '',
65
72
  currency: '',
66
73
  business: '',
67
74
  status: '',
75
+ filterFTU: '',
68
76
  minAmount: '',
69
77
  maxAmount: '',
70
78
  })
@@ -74,7 +82,8 @@ const showDatePicker = ref(false)
74
82
  const datePickerValue = ref(selectedDate.value.split('-'))
75
83
  const minDate = new Date(2020, 0, 1)
76
84
  const maxDate = new Date(2030, 11, 31)
77
- const isFilterExpanded = ref(true)
85
+ // 筛选区展开状态由 Pinia 持久化;首次进入无缓存时默认收起。
86
+ const isFilterExpanded = computed(() => positionFilterStore.foreignFilterExpanded)
78
87
 
79
88
  const forecastList = ref<Forecast[]>([])
80
89
  const forecastTotal = ref(0)
@@ -97,11 +106,16 @@ const selectedStatus = computed(
97
106
  () =>
98
107
  foreignStatusOptions.find((item) => item.value === queryForm.status) || allForeignStatusOption,
99
108
  )
109
+ const selectedFilterFTU = computed(
110
+ () =>
111
+ filterFTUOptions.find((item) => item.value === queryForm.filterFTU) || defaultFilterFTUOption,
112
+ )
100
113
  const selectorTitle = computed(() => {
101
114
  const titleMap: Record<SelectorType, string> = {
102
115
  currency: '选择币种',
103
116
  business: '选择业务类型',
104
117
  status: '选择预报状态',
118
+ filterFTU: '筛选FTU',
105
119
  }
106
120
 
107
121
  return titleMap[selectorType.value]
@@ -109,6 +123,7 @@ const selectorTitle = computed(() => {
109
123
  const selectorOptions = computed<SelectorOption[]>(() => {
110
124
  if (selectorType.value === 'currency') return foreignCurrencyOptions
111
125
  if (selectorType.value === 'business') return foreignBusinessOptions
126
+ if (selectorType.value === 'filterFTU') return filterFTUOptions
112
127
 
113
128
  return foreignStatusOptions
114
129
  })
@@ -116,7 +131,7 @@ const filterSummary = computed(() => {
116
131
  const institution = queryForm.institution.trim() || '全部机构'
117
132
  const currency = selectedCurrency.value.shortLabel
118
133
 
119
- return `${selectedDate.value} · ${institution} · ${currency}`
134
+ return `${selectedDate.value} · ${institution} · ${currency} · FTU${selectedFilterFTU.value.label}`
120
135
  })
121
136
 
122
137
  onMounted(async () => {
@@ -135,7 +150,14 @@ function mapForeignRecordToForecast(record: ForeignForecastRecord, index: number
135
150
  const currency = resolveForeignCurrency(currencyValue)
136
151
  const status = resolveForeignStatus(record.predStatus)
137
152
  const counterparty =
138
- record.competName || record.clientName || record.bankSwift || record.swiftCode || '-'
153
+ record.competName ||
154
+ record.clientName ||
155
+ record.rcvBank ||
156
+ record.competAcctSc ||
157
+ record.rcvBankSc ||
158
+ record.bankSwift ||
159
+ record.swiftCode ||
160
+ '-'
139
161
 
140
162
  return {
141
163
  id: index + 1,
@@ -143,7 +165,7 @@ function mapForeignRecordToForecast(record: ForeignForecastRecord, index: number
143
165
  date: formatForeignForecastDate(record.tranDate),
144
166
  currency: currency.shortLabel,
145
167
  currencyUnit: currency.unit,
146
- business: resolveForeignBusinessType(record.busiType),
168
+ business: resolveForeignBusinessType(record.tranType || record.busiType),
147
169
  counterparty,
148
170
  amount: toTenThousandAmount(record.predAmt),
149
171
  predRefNo: record.predRefNo || '',
@@ -155,12 +177,13 @@ function mapForeignRecordToForecast(record: ForeignForecastRecord, index: number
155
177
  function buildQueryForm(): ForeignForecastQueryForm {
156
178
  return {
157
179
  tranDate: selectedDate.value,
158
- groundBranch: queryForm.institution.trim(),
159
- currency: queryForm.currency,
160
- busiType: queryForm.business,
180
+ orgName: queryForm.institution.trim(),
181
+ ccy: queryForm.currency,
182
+ tranType: queryForm.business,
161
183
  predStatus: queryForm.status,
162
- startTranAmt: queryForm.minAmount,
163
- endTranAmt: queryForm.maxAmount,
184
+ filter: queryForm.filterFTU,
185
+ startAmt: queryForm.minAmount,
186
+ endAmt: queryForm.maxAmount,
164
187
  }
165
188
  }
166
189
 
@@ -183,6 +206,10 @@ function scrollToTop() {
183
206
  })
184
207
  }
185
208
 
209
+ function toggleFilterExpanded() {
210
+ positionFilterStore.setForeignFilterExpanded(!isFilterExpanded.value)
211
+ }
212
+
186
213
  function openCreatePage() {
187
214
  router.push({
188
215
  name: 'ForeignPositionCreate',
@@ -200,6 +227,8 @@ function chooseSelectorOption(option: SelectorOption) {
200
227
  queryForm.currency = option.value
201
228
  } else if (selectorType.value === 'business') {
202
229
  queryForm.business = option.value
230
+ } else if (selectorType.value === 'filterFTU') {
231
+ queryForm.filterFTU = option.value
203
232
  } else {
204
233
  queryForm.status = option.value
205
234
  }
@@ -238,6 +267,7 @@ async function handleReset() {
238
267
  queryForm.currency = ''
239
268
  queryForm.business = ''
240
269
  queryForm.status = ''
270
+ queryForm.filterFTU = ''
241
271
  queryForm.minAmount = ''
242
272
  queryForm.maxAmount = ''
243
273
 
@@ -278,20 +308,16 @@ async function loadNextPage() {
278
308
 
279
309
  try {
280
310
  const response = await queryForeignForecastPage(payload)
281
- const records = filterRecordsByCurrency(response.body.resultList)
311
+ const records = response.body.resultInfos || []
282
312
  const nextList = records.map((item, index) =>
283
313
  mapForeignRecordToForecast(item, forecastList.value.length + index),
284
314
  )
285
315
 
286
316
  forecastList.value.push(...nextList)
287
- forecastTotal.value = queryForm.currency
288
- ? forecastList.value.length
289
- : Number(response.body.totalCount) || forecastList.value.length
317
+ forecastTotal.value = Number(response.body.totalCount) || forecastList.value.length
290
318
  currentPage.value += 1
291
- listFinished.value = queryForm.currency
292
- ? response.body.resultList.length < pageSize
293
- : forecastList.value.length >= forecastTotal.value ||
294
- response.body.resultList.length < pageSize
319
+ listFinished.value =
320
+ forecastList.value.length >= forecastTotal.value || records.length < pageSize
295
321
  } catch (error) {
296
322
  console.error('[外币预报查询失败]', error)
297
323
  listError.value = true
@@ -302,14 +328,6 @@ async function loadNextPage() {
302
328
  }
303
329
  }
304
330
 
305
- function filterRecordsByCurrency(records: ForeignForecastRecord[]) {
306
- const currency = queryForm.currency.trim().toUpperCase()
307
-
308
- if (!currency) return records
309
-
310
- return records.filter((item) => getRecordCurrency(item) === currency)
311
- }
312
-
313
331
  function getRecordCurrency(record: ForeignForecastRecord) {
314
332
  return (
315
333
  record.ccy ||
@@ -417,7 +435,7 @@ function isPendingForecast(value: Partial<PendingForecast> | null): value is Pen
417
435
  class="filter-toggle"
418
436
  type="button"
419
437
  :aria-expanded="isFilterExpanded"
420
- @click="isFilterExpanded = !isFilterExpanded"
438
+ @click="toggleFilterExpanded"
421
439
  >
422
440
  <van-icon :name="isFilterExpanded ? 'arrow-up' : 'arrow-down'" />
423
441
  <span>{{ isFilterExpanded ? '收起' : '展开' }}</span>
@@ -468,6 +486,13 @@ function isPendingForecast(value: Partial<PendingForecast> | null): value is Pen
468
486
  <van-icon class="row-arrow" name="arrow" />
469
487
  </button>
470
488
 
489
+ <button class="filter-row" type="button" @click="openSelector('filterFTU')">
490
+ <span class="row-icon"><van-icon name="filter-o" /></span>
491
+ <span class="row-label">筛选FTU</span>
492
+ <span class="row-value muted-value">{{ selectedFilterFTU.label }}</span>
493
+ <van-icon class="row-arrow" name="arrow" />
494
+ </button>
495
+
471
496
  <div class="filter-row amount-row">
472
497
  <span class="row-icon row-icon-money"><van-icon name="gold-coin-o" /></span>
473
498
  <span class="row-label">金额区间</span>
@@ -592,7 +617,8 @@ function isPendingForecast(value: Partial<PendingForecast> | null): value is Pen
592
617
  v-if="
593
618
  (selectorType === 'currency' && item.value === queryForm.currency) ||
594
619
  (selectorType === 'business' && item.value === queryForm.business) ||
595
- (selectorType === 'status' && item.value === queryForm.status)
620
+ (selectorType === 'status' && item.value === queryForm.status) ||
621
+ (selectorType === 'filterFTU' && item.value === queryForm.filterFTU)
596
622
  "
597
623
  name="success"
598
624
  />
@@ -6,6 +6,7 @@ import {
6
6
  type RmbForecastRecord,
7
7
  } from '@/api/rmb-position'
8
8
  import { useAppStore } from '@/stores/app'
9
+ import { usePositionFilterStore } from '@/stores/position-filter'
9
10
  import {
10
11
  forecastStatusMap,
11
12
  formatForecastAmount,
@@ -41,6 +42,7 @@ type PendingForecast = {
41
42
 
42
43
  const router = useRouter()
43
44
  const appStore = useAppStore()
45
+ const positionFilterStore = usePositionFilterStore()
44
46
  const defaultTranDate = appStore.systemWorkDate
45
47
  const heroImage = `${import.meta.env.BASE_URL}images/5798d7aa-ba8b-4605-8079-58b35495ac55.png`
46
48
  const pageSize = 10
@@ -58,7 +60,8 @@ const showDatePicker = ref(false)
58
60
  const datePickerValue = ref(selectedDate.value.split('-'))
59
61
  const minDate = new Date(2020, 0, 1)
60
62
  const maxDate = new Date(2030, 11, 31)
61
- const isFilterExpanded = ref(true)
63
+ // 筛选区展开状态由 Pinia 持久化;首次进入无缓存时默认收起。
64
+ const isFilterExpanded = computed(() => positionFilterStore.rmbFilterExpanded)
62
65
 
63
66
  const forecastList = ref<Forecast[]>([])
64
67
  const forecastTotal = ref(0)
@@ -135,6 +138,10 @@ function scrollToTop() {
135
138
  })
136
139
  }
137
140
 
141
+ function toggleFilterExpanded() {
142
+ positionFilterStore.setRmbFilterExpanded(!isFilterExpanded.value)
143
+ }
144
+
138
145
  function openCreatePage() {
139
146
  router.push({
140
147
  name: 'RmbPositionCreate',
@@ -311,7 +318,7 @@ function isPendingForecast(value: Partial<PendingForecast> | null): value is Pen
311
318
  class="filter-toggle"
312
319
  type="button"
313
320
  :aria-expanded="isFilterExpanded"
314
- @click="isFilterExpanded = !isFilterExpanded"
321
+ @click="toggleFilterExpanded"
315
322
  >
316
323
  <van-icon :name="isFilterExpanded ? 'arrow-up' : 'arrow-down'" />
317
324
  <span>{{ isFilterExpanded ? '收起' : '展开' }}</span>