n20-common-lib 3.2.38 → 3.2.40

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 (72) hide show
  1. package/package.json +1 -1
  2. package/src/components/AIButton/index.vue +6 -5
  3. package/src/components/AdvancedFilter/index.vue +4 -3
  4. package/src/components/ApprovalButtons/index.vue +26 -22
  5. package/src/components/ApprovalButtons/indexApp.vue +19 -13
  6. package/src/components/ApprovalButtons/selectSpr.vue +1 -1
  7. package/src/components/ApprovalButtons/showAppOpi.vue +5 -5
  8. package/src/components/ApprovalButtons/showOtherAttr.vue +1 -1
  9. package/src/components/ApprovalButtons/showOtherAttrNew.vue +4 -4
  10. package/src/components/ApprovalCard/index.vue +7 -7
  11. package/src/components/ApprovalCard/indexApp.vue +2 -2
  12. package/src/components/ApprovalRecord/approvalImgPro/child.vue +3 -3
  13. package/src/components/ApprovalRecord/approvalImgPro/index.vue +3 -3
  14. package/src/components/AttachmentPass/index.vue +7 -7
  15. package/src/components/DateChoose/index.vue +33 -33
  16. package/src/components/DatePicker/index.vue +1 -1
  17. package/src/components/DateSelect/busiDate.vue +7 -4
  18. package/src/components/DateSelect/index.vue +8 -8
  19. package/src/components/DateSelect/quarterDatePicker.vue +11 -11
  20. package/src/components/DynamicField/DynamicField.vue +2 -2
  21. package/src/components/DynamicField/DynamicFieldOptions.vue +57 -57
  22. package/src/components/DynamicField/DynamicFormView.vue +13 -13
  23. package/src/components/DynamicField/DynamicTable.vue +4 -4
  24. package/src/components/DynamicField/contentPop.vue +6 -6
  25. package/src/components/DynamicField/tableList.vue +5 -5
  26. package/src/components/DynamicField/tableView.vue +20 -6
  27. package/src/components/ElectronicArchive/index.vue +20 -17
  28. package/src/components/FileExportAsync/index.vue +3 -3
  29. package/src/components/FileUploadTable/aiCheckDialog.vue +11 -11
  30. package/src/components/FileUploadTable/index.vue +3 -3
  31. package/src/components/HandlingAdvice/index.vue +3 -3
  32. package/src/components/Layout/HeaderWrap/changePwd.vue +2 -2
  33. package/src/components/Layout/HeaderWrap/index.vue +2 -2
  34. package/src/components/Layout/HeaderWrap/switchUser.vue +1 -1
  35. package/src/components/LoginSetting/setItem.vue +16 -16
  36. package/src/components/LoginTemporary/form.vue +2 -2
  37. package/src/components/LoginTemporary/indexN.vue +15 -15
  38. package/src/components/LoginTemporary/retrievePw.vue +4 -4
  39. package/src/components/MdmSelect/index.vue +179 -0
  40. package/src/components/Pivot/ConfigSidebar.vue +27 -25
  41. package/src/components/Pivot/MainToolbar.vue +9 -9
  42. package/src/components/Pivot/ReportSidebar.vue +4 -4
  43. package/src/components/Pivot/TableView.vue +8 -11
  44. package/src/components/Pivot/index.vue +26 -26
  45. package/src/components/ProFilterView/advancedQuery.vue +57 -63
  46. package/src/components/ProFilterView/index.vue +26 -26
  47. package/src/components/SelectDatePickerPro/busiDate.vue +5 -5
  48. package/src/components/SelectDatePickerPro/halfYearPicker.vue +2 -2
  49. package/src/components/SelectDatePickerPro/index.vue +24 -16
  50. package/src/components/SelectDatePickerPro/quarterDatePicker.vue +4 -4
  51. package/src/components/SelectTree/pro.vue +1 -1
  52. package/src/components/Statis/index.vue +1 -1
  53. package/src/components/Statis/statisItem.vue +1 -1
  54. package/src/components/Table/indexO.vue +1 -1
  55. package/src/components/TablePro/filterContent.vue +2 -2
  56. package/src/components/TablePro/filterContent_tree.vue +5 -5
  57. package/src/components/TablePro/index.js +1 -1
  58. package/src/components/TableTransfer/index.vue +1 -1
  59. package/src/components/Upload/index.vue +2 -2
  60. package/src/components/WornPagination/index.vue +1 -1
  61. package/src/components/operatingStatus/index.vue +7 -7
  62. package/src/components/v3/Footer/index.vue +3 -3
  63. package/src/components/v3/TablePro/filterContent.vue +2 -2
  64. package/src/components/v3/TablePro/filterContent_tree.vue +5 -5
  65. package/src/components/v3/TablePro/index.js +1 -1
  66. package/src/components/v3/UploadList/components/aiCheckDialog.vue +11 -11
  67. package/src/components/v3/UploadList/index.vue +10 -10
  68. package/src/i18n.json +8972 -715
  69. package/src/index.js +3 -0
  70. package/src/plugins/SetMenuTree/index.vue +1 -1
  71. package/src/plugins/SetMenuTree/setmenutree.vue +34 -34
  72. package/src/utils/amountInWords.js +6 -6
@@ -0,0 +1,179 @@
1
+ <template>
2
+ <el-select
3
+ :value="value"
4
+ v-bind="computedAttrs"
5
+ :loading="loading"
6
+ v-on="computedListeners"
7
+ @input="handleInput"
8
+ @change="handleChange"
9
+ >
10
+ <el-option
11
+ v-for="option in options"
12
+ :key="`${type}-${option.code}`"
13
+ :label="getOptionLabel(option)"
14
+ :value="option.code"
15
+ />
16
+ </el-select>
17
+ </template>
18
+
19
+ <script>
20
+ import { $lc } from '../../utils/i18n/index'
21
+
22
+ const TYPE_CASH_FLOW_DIRECTION = 'cashFlowDirection'
23
+ const TYPE_PAYMENT_CATEGORY = 'paymentCategory'
24
+ const TYPE_PAY_BANK = 'payBank'
25
+ const VALID_TYPES = [TYPE_CASH_FLOW_DIRECTION, TYPE_PAYMENT_CATEGORY, TYPE_PAY_BANK]
26
+ const VALID_LABEL_MODES = ['value', 'code-value']
27
+
28
+ export default {
29
+ name: 'MdmSelect',
30
+ inheritAttrs: false,
31
+ props: {
32
+ value: {
33
+ type: [String, Number],
34
+ default: undefined
35
+ },
36
+ type: {
37
+ type: String,
38
+ required: true,
39
+ validator(value) {
40
+ return VALID_TYPES.includes(value)
41
+ }
42
+ },
43
+ labelMode: {
44
+ type: String,
45
+ default: 'value',
46
+ validator(value) {
47
+ return VALID_LABEL_MODES.includes(value)
48
+ }
49
+ }
50
+ },
51
+ data() {
52
+ return {
53
+ loading: false,
54
+ options: [],
55
+ requestSequence: 0
56
+ }
57
+ },
58
+ computed: {
59
+ computedAttrs() {
60
+ const attrs = Object.assign({}, this.$attrs)
61
+ delete attrs.loading
62
+ delete attrs.multiple
63
+ return Object.assign(
64
+ {
65
+ clearable: true,
66
+ filterable: true,
67
+ placeholder: $lc('请选择')
68
+ },
69
+ attrs
70
+ )
71
+ },
72
+ computedListeners() {
73
+ const listeners = Object.assign({}, this.$listeners)
74
+ delete listeners.input
75
+ delete listeners.change
76
+ delete listeners['load-error']
77
+ return listeners
78
+ }
79
+ },
80
+ watch: {
81
+ type(newValue, oldValue) {
82
+ if (newValue === oldValue) return
83
+ this.$emit('input', undefined)
84
+ this.$emit('change', undefined)
85
+ this.loadOptions()
86
+ }
87
+ },
88
+ created() {
89
+ this.loadOptions()
90
+ },
91
+ beforeDestroy() {
92
+ this.requestSequence += 1
93
+ },
94
+ methods: {
95
+ handleInput(value) {
96
+ this.$emit('input', value)
97
+ },
98
+ handleChange(value) {
99
+ this.$emit('change', value)
100
+ },
101
+ getOptionLabel(option) {
102
+ if (this.labelMode === 'code-value') {
103
+ if (this.type === TYPE_CASH_FLOW_DIRECTION) {
104
+ return `${option.label}(${option.code})`
105
+ }
106
+ return `${option.code} - ${option.label}`
107
+ }
108
+ return option.label
109
+ },
110
+ getPaymentCategoryOptions() {
111
+ return [
112
+ { code: 1, label: $lc('收入'), raw: { label: $lc("收入"), value: 1 } },
113
+ { code: 0, label: $lc('支出'), raw: { label: $lc("支出"), value: 0 } },
114
+ { code: 2, label: $lc('净额'), raw: { label: $lc("净额"), value: 2 } }
115
+ ]
116
+ },
117
+ normalizeResponse(response) {
118
+ if (Array.isArray(response)) return response
119
+ if (response && Array.isArray(response.data)) return response.data
120
+ if (response && response.data && Array.isArray(response.data.list)) {
121
+ return response.data.list
122
+ }
123
+ if (response && Array.isArray(response.list)) return response.list
124
+ return []
125
+ },
126
+ normalizeOptions(list, codeKey, labelKey) {
127
+ return list
128
+ .filter((item) => item && item[codeKey] !== undefined && item[codeKey] !== null)
129
+ .map((item) => ({
130
+ code: item[codeKey],
131
+ label: item[labelKey] === undefined || item[labelKey] === null ? '' : item[labelKey],
132
+ raw: item
133
+ }))
134
+ },
135
+ async loadOptions() {
136
+ const requestSequence = ++this.requestSequence
137
+ this.options = []
138
+
139
+ if (this.type === TYPE_PAYMENT_CATEGORY) {
140
+ this.loading = false
141
+ this.options = this.getPaymentCategoryOptions()
142
+ return
143
+ }
144
+
145
+ this.loading = true
146
+ try {
147
+ let response
148
+ let codeKey
149
+ let labelKey
150
+
151
+ if (this.type === TYPE_CASH_FLOW_DIRECTION) {
152
+ response = await this.$axios.get(
153
+ '/bems/1.0/cashflow/fieldinfo/MDM_G_CASHFLOWflowDir',
154
+ {},
155
+ { loading: false, noMsg: true }
156
+ )
157
+ codeKey = 'dbdata'
158
+ labelKey = 'otherdata'
159
+ } else if (this.type === TYPE_PAY_BANK) {
160
+ response = await this.$axios.get('/bems/1.0/bank', { isEnable: 1 }, { loading: false, noMsg: true })
161
+ codeKey = 'bankNo'
162
+ labelKey = 'bankName'
163
+ }
164
+
165
+ if (requestSequence !== this.requestSequence) return
166
+ this.options = this.normalizeOptions(this.normalizeResponse(response), codeKey, labelKey)
167
+ } catch (error) {
168
+ if (requestSequence !== this.requestSequence) return
169
+ this.options = []
170
+ this.$emit('load-error', error)
171
+ } finally {
172
+ if (requestSequence === this.requestSequence) {
173
+ this.loading = false
174
+ }
175
+ }
176
+ }
177
+ }
178
+ }
179
+ </script>
@@ -4,19 +4,19 @@
4
4
  <div class="sidebar-header">
5
5
  <template v-if="!isCollapsed">
6
6
  <i class="v3-icon-move-right sidebar-header-collapse" @click="handleToggleCollapse"></i>
7
- <span class="sidebar-title">维度配置</span>
7
+ <span class="sidebar-title">{{ $lc('维度配置') }}</span>
8
8
  </template>
9
9
  </div>
10
10
  <div class="config-form">
11
11
  <!-- 报表标题 -->
12
12
  <div class="form-item">
13
- <label class="form-label">报表标题</label>
14
- <el-input :value="reportName" size="small" placeholder="请输入报表名称" @input="handleNameChange" />
13
+ <label class="form-label">{{ $lc('报表标题') }}</label>
14
+ <el-input :value="reportName" size="small" :placeholder="$lc('请输入报表名称')" @input="handleNameChange" />
15
15
  </div>
16
16
 
17
17
  <!-- 统计类型 -->
18
18
  <div class="form-item">
19
- <label class="form-label">统计类型</label>
19
+ <label class="form-label">{{ $lc('统计类型') }}</label>
20
20
  <div class="radio-group">
21
21
  <ViewToggle :value="statType" :item-width="120" :options="statTypeOptions" @change="handleStatTypeChange" />
22
22
  </div>
@@ -24,7 +24,7 @@
24
24
 
25
25
  <!-- 展示形式 - 仅分组统计 + 图表视图时显示 -->
26
26
  <div v-if="!isCrossMode && viewMode === 'chart'" class="form-item">
27
- <label class="form-label">展示形式</label>
27
+ <label class="form-label">{{ $lc('展示形式') }}</label>
28
28
  <div
29
29
  class="select-wrapper"
30
30
  :class="{ active: showChartTypeDropdown }"
@@ -62,9 +62,9 @@
62
62
 
63
63
  <!-- 分组维度 - 仅分组统计显示,单选 -->
64
64
  <div v-if="!isCrossMode" class="form-item">
65
- <label class="form-label">
66
- 分组维度
67
- <el-tooltip content="选择维度字段作为分组依据" placement="top">
65
+ <label class="form-label"
66
+ >{{ $lc('分组维度')
67
+ }}<el-tooltip :content="$lc('选择维度字段作为分组依据')" placement="top">
68
68
  <i class="v3-icon-help"></i>
69
69
  </el-tooltip>
70
70
  </label>
@@ -74,7 +74,7 @@
74
74
  @click="showDimensionDropdown = !showDimensionDropdown"
75
75
  >
76
76
  <div class="select-value">
77
- <span v-if="!selectedDimension" class="placeholder">请选择</span>
77
+ <span v-if="!selectedDimension" class="placeholder">{{ $lc('请选择') }}</span>
78
78
  <span v-else>{{ getDimensionLabel(selectedDimension) }}</span>
79
79
  </div>
80
80
  <svg class="select-arrow" width="10" height="10" viewBox="0 0 10 10" fill="none">
@@ -102,9 +102,9 @@
102
102
 
103
103
  <!-- 行维度 - 仅交叉统计显示 -->
104
104
  <div v-if="isCrossMode" class="form-item">
105
- <label class="form-label">
106
- 行维度
107
- <el-tooltip content="选择维度字段作为行分组依据" placement="top">
105
+ <label class="form-label"
106
+ >{{ $lc('行维度')
107
+ }}<el-tooltip :content="$lc('选择维度字段作为行分组依据')" placement="top">
108
108
  <i class="v3-icon-help"></i>
109
109
  </el-tooltip>
110
110
  </label>
@@ -114,7 +114,7 @@
114
114
  @click="showRowDimensionDropdown = !showRowDimensionDropdown"
115
115
  >
116
116
  <div class="select-value">
117
- <span v-if="!rowDimension" class="placeholder">请选择</span>
117
+ <span v-if="!rowDimension" class="placeholder">{{ $lc('请选择') }}</span>
118
118
  <span v-else>{{ getDimensionLabel(rowDimension) }}</span>
119
119
  </div>
120
120
  <svg class="select-arrow" width="10" height="10" viewBox="0 0 10 10" fill="none">
@@ -144,9 +144,9 @@
144
144
 
145
145
  <!-- 列维度 - 仅交叉统计显示 -->
146
146
  <div v-if="isCrossMode" class="form-item">
147
- <label class="form-label">
148
- 列维度
149
- <el-tooltip content="选择维度字段作为列分组依据" placement="top">
147
+ <label class="form-label"
148
+ >{{ $lc('列维度')
149
+ }}<el-tooltip :content="$lc('选择维度字段作为列分组依据')" placement="top">
150
150
  <i class="v3-icon-help"></i>
151
151
  </el-tooltip>
152
152
  </label>
@@ -156,7 +156,7 @@
156
156
  @click="showColumnDimensionDropdown = !showColumnDimensionDropdown"
157
157
  >
158
158
  <div class="select-value">
159
- <span v-if="!columnDimension" class="placeholder">请选择</span>
159
+ <span v-if="!columnDimension" class="placeholder">{{ $lc('请选择') }}</span>
160
160
  <span v-else>{{ getDimensionLabel(columnDimension) }}</span>
161
161
  </div>
162
162
  <svg class="select-arrow" width="10" height="10" viewBox="0 0 10 10" fill="none">
@@ -188,15 +188,15 @@
188
188
  <div class="form-item">
189
189
  <div class="form-label-row">
190
190
  <div class="form-label-group">
191
- <label class="form-label">
192
- 计算指标
193
- <el-tooltip content="选择数值字段作为计算指标,支持多种聚合方式" placement="top">
191
+ <label class="form-label"
192
+ >{{ $lc('计算指标')
193
+ }}<el-tooltip :content="$lc('选择数值字段作为计算指标,支持多种聚合方式')" placement="top">
194
194
  <i class="v3-icon-help"></i>
195
195
  </el-tooltip>
196
196
  </label>
197
197
  </div>
198
198
  <div class="aggregate-dropdown" @click="showAggregateDropdown = !showAggregateDropdown">
199
- <span>自定义</span>
199
+ <span>{{ $lc('自定义') }}</span>
200
200
  <svg width="10" height="10" viewBox="0 0 10 10" fill="none">
201
201
  <path
202
202
  d="M2 3L5 7L8 3"
@@ -256,7 +256,7 @@
256
256
  <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
257
257
  <path d="M7 1V13M1 7H13" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" />
258
258
  </svg>
259
- <span>添加字段</span>
259
+ <span>{{ $lc('添加字段') }}</span>
260
260
  <!-- 添加字段下拉 -->
261
261
  <div v-if="showMetricAddDropdown" class="dropdown-menu metric-add-dropdown">
262
262
  <div
@@ -267,7 +267,7 @@
267
267
  >
268
268
  {{ metric.label }}
269
269
  </div>
270
- <div v-if="availableMetricsForAdd.length === 0" class="dropdown-item disabled">无可用字段</div>
270
+ <div v-if="availableMetricsForAdd.length === 0" class="dropdown-item disabled">{{ $lc('无可用字段') }}</div>
271
271
  </div>
272
272
  </div>
273
273
  </div>
@@ -276,6 +276,8 @@
276
276
  </template>
277
277
 
278
278
  <script>
279
+ import { $lc } from '@/utils/i18n/index.js'
280
+
279
281
  import ViewToggle from '../ViewToggle/index.vue'
280
282
 
281
283
  export default {
@@ -395,7 +397,7 @@ export default {
395
397
  // 获取图表类型标签
396
398
  getChartTypeLabel(type) {
397
399
  const chart = this.chartTypes.find((t) => t.value === type)
398
- return chart ? chart.label : '柱状图'
400
+ return chart ? chart.label : $lc('柱状图')
399
401
  },
400
402
 
401
403
  // 获取维度标签
@@ -424,7 +426,7 @@ export default {
424
426
  // 获取聚合类型标签
425
427
  getAggregateLabel(type) {
426
428
  const agg = this.aggregateTypes.find((t) => t.value === type)
427
- return agg ? agg.label : '求和'
429
+ return agg ? agg.label : $lc('求和')
428
430
  },
429
431
 
430
432
  // 切换折叠状态
@@ -11,13 +11,13 @@
11
11
  fill="#007AFF"
12
12
  />
13
13
  </svg>
14
- <span>添加到首页</span>
14
+ <span>{{ $lc('添加到首页') }}</span>
15
15
  </div>
16
16
  </div>
17
17
  <div class="report-stats">
18
- <span class="stat-item">计算耗时:{{ calculateTime }} ms</span>
18
+ <span class="stat-item">{{ $lc('计算耗时:') }}{{ calculateTime }} ms</span>
19
19
  <span class="stat-divider"></span>
20
- <span class="stat-item">数据条数:{{ dataCount }}</span>
20
+ <span class="stat-item">{{ $lc('数据条数:') }}{{ dataCount }}</span>
21
21
  </div>
22
22
  </div>
23
23
 
@@ -30,28 +30,28 @@
30
30
  />
31
31
  <span class="toolbar-divider"></span>
32
32
  <div class="action-buttons">
33
- <div class="action-btn" title="刷新" @click="handleRefresh">
33
+ <div class="action-btn" :title="$lc('刷新')" @click="handleRefresh">
34
34
  <i class="n20-icon-shuaxin"></i>
35
35
  </div>
36
- <div class="action-btn more-btn" :class="{ active: showMoreMenu }" title="更多" @click="toggleMoreMenu">
36
+ <div class="action-btn more-btn" :class="{ active: showMoreMenu }" :title="$lc('更多')" @click="toggleMoreMenu">
37
37
  <i class="v3-icon-more"></i>
38
38
  <div v-if="showMoreMenu" class="more-dropdown-menu" @click.stop>
39
39
  <div v-if="isRightSidebarCollapsed" class="dropdown-menu-item" @click="handleConfig">
40
40
  <i class="v3-icon-setting"></i>
41
- <span>配置</span>
41
+ <span>{{ $lc('配置') }}</span>
42
42
  </div>
43
43
  <div class="dropdown-menu-item" @click="handleAddToHome">
44
44
  <i class="v3-icon-add-menu"></i>
45
- <span>添加到首页</span>
45
+ <span>{{ $lc('添加到首页') }}</span>
46
46
  </div>
47
47
  <div class="dropdown-menu-item" @click="handleExport">
48
48
  <i class="v3-icon-upload"></i>
49
- <span>导出</span>
49
+ <span>{{ $lc('导出') }}</span>
50
50
  </div>
51
51
  <div class="dropdown-divider"></div>
52
52
  <div class="dropdown-menu-item danger" @click.stop="handleDeleteReport">
53
53
  <i class="v3-icon-delete"></i>
54
- <span>删除</span>
54
+ <span>{{ $lc('删除') }}</span>
55
55
  </div>
56
56
  </div>
57
57
  </div>
@@ -2,8 +2,8 @@
2
2
  <!-- 左侧报表清单 -->
3
3
  <div class="pivot-sidebar-left" :class="{ collapsed: isCollapsed }">
4
4
  <div class="sidebar-header">
5
- <span class="sidebar-title">我的报表清单</span>
6
- <div class="add-report-btn" title="新建" @click="handleAddReport">
5
+ <span class="sidebar-title">{{ $lc('我的报表清单') }}</span>
6
+ <div class="add-report-btn" :title="$lc('新建')" @click="handleAddReport">
7
7
  <i class="v3-icon-plus"></i>
8
8
  </div>
9
9
  </div>
@@ -42,11 +42,11 @@
42
42
  <div v-if="activeMenuId === report.id" class="report-menu">
43
43
  <div class="report-menu-item" @click.stop="handleStartRename(report)">
44
44
  <i class="v3-icon-edit"></i>
45
- <span>重命名</span>
45
+ <span>{{ $lc('重命名') }}</span>
46
46
  </div>
47
47
  <div class="report-menu-item delete" @click.stop="handleDeleteReport(report)">
48
48
  <i class="v3-icon-delete"></i>
49
- <span>删除</span>
49
+ <span>{{ $lc('删除') }}</span>
50
50
  </div>
51
51
  </div>
52
52
  </div>
@@ -51,8 +51,7 @@
51
51
  <template #default="{ row }">
52
52
  <div class="metric-cell-content">
53
53
  <span v-if="childCol.aggregateType === 'count'" class="metric-count">
54
- {{ formatCount(row._groupCount) }} 笔
55
- </span>
54
+ {{ formatCount(row._groupCount) }}{{ $lc('') }}</span>
56
55
  <span v-else class="metric-value">{{ formatNumber(row[childCol.key]) }}</span>
57
56
  </div>
58
57
  </template>
@@ -78,8 +77,7 @@
78
77
  <template v-else-if="col.type === 'metric'">
79
78
  <div class="metric-cell-content">
80
79
  <span v-if="col.aggregateType === 'count'" class="metric-count">
81
- {{ formatCount(row._groupCount) }} 笔
82
- </span>
80
+ {{ formatCount(row._groupCount) }}{{ $lc('') }}</span>
83
81
  <span v-else class="metric-value">{{ formatNumber(row[col.field]) }}</span>
84
82
  </div>
85
83
  </template>
@@ -96,7 +94,7 @@
96
94
 
97
95
  <!-- 分页组件 -->
98
96
  <div class="cross-pagination">
99
- <div class="pagination-info">共{{ totalCount }}条</div>
97
+ <div class="pagination-info">{{ $lc('共') }}{{ totalCount }}{{ $lc('条') }}</div>
100
98
  <div class="pagination-controls">
101
99
  <div class="pagination-btn" :class="{ disabled: currentPage <= 1 }" @click="handlePrevPage">
102
100
  <i class="v3-icon-left"></i>
@@ -109,7 +107,7 @@
109
107
  </div>
110
108
  </div>
111
109
  <div class="pagination-size-select" @click="showPageSizeDropdown = !showPageSizeDropdown">
112
- <span>{{ pageSize }}条/页</span>
110
+ <span>{{ pageSize }}{{ $lc('条/页') }}</span>
113
111
  <i class="v3-icon-down"></i>
114
112
  <div v-if="showPageSizeDropdown" class="pagination-size-dropdown">
115
113
  <div
@@ -119,19 +117,18 @@
119
117
  :class="{ active: pageSize === size }"
120
118
  @click.stop="handlePageSizeChange(size)"
121
119
  >
122
- {{ size }}条/页
123
- </div>
120
+ {{ size }}{{ $lc('条/页') }}</div>
124
121
  </div>
125
122
  </div>
126
123
  <div class="pagination-jump">
127
- <span class="pagination-jump-label">前往</span>
124
+ <span class="pagination-jump-label">{{ $lc('前往') }}</span>
128
125
  <input type="number" class="pagination-jump-input" :value="currentPage" @change="handleJumpToPage" min="1" />
129
- <span class="pagination-jump-label">页</span>
126
+ <span class="pagination-jump-label">{{ $lc('页') }}</span>
130
127
  </div>
131
128
  </div>
132
129
  </div>
133
130
  <div v-else class="empty-state">
134
- <Empty type="noData2" :height="200" :width="200" content="暂无数据" />
131
+ <Empty type="noData2" :height="200" :width="200" :content="$lc('暂无数据')" />
135
132
  </div>
136
133
  </div>
137
134
  </template>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <Dialog class="n20-pivot-dialog" width="95%" max-dialog :visible.sync="visibleC" title="数据透视分析中心">
2
+ <Dialog class="n20-pivot-dialog" width="95%" max-dialog :visible.sync="visibleC" :title="$lc('数据透视分析中心')">
3
3
  <div class="n20-pivot-container">
4
4
  <!-- 左侧报表清单 -->
5
5
  <ReportSidebar
@@ -230,26 +230,26 @@ export default {
230
230
  pageSizeOptions: [10, 20, 50, 100],
231
231
  // 视图模式选项
232
232
  viewModeOptions: [
233
- { label: '图表视图', value: 'chart' },
234
- { label: '表格视图', value: 'table' }
233
+ { label: $lc("图表视图"), value: 'chart' },
234
+ { label: $lc("表格视图"), value: 'table' }
235
235
  ],
236
236
  totalModeOptions: [
237
- { label: '分组统计', value: 'group' },
238
- { label: '交叉统计', value: 'cross' }
237
+ { label: $lc("分组统计"), value: 'group' },
238
+ { label: $lc("交叉统计"), value: 'cross' }
239
239
  ],
240
240
  // 图表类型选项
241
241
  chartTypes: [
242
- { value: 'bar', label: '柱状图' },
243
- { value: 'line', label: '折线图' },
244
- { value: 'pie', label: '饼图' }
242
+ { value: 'bar', label: $lc("柱状图") },
243
+ { value: 'line', label: $lc("折线图") },
244
+ { value: 'pie', label: $lc("饼图") }
245
245
  ],
246
246
  // 聚合类型选项
247
247
  aggregateTypes: [
248
- { value: 'sum', label: '求和' },
249
- { value: 'count', label: '计数' },
250
- { value: 'avg', label: '平均值' },
251
- { value: 'max', label: '最大值' },
252
- { value: 'min', label: '最小值' }
248
+ { value: 'sum', label: $lc("求和") },
249
+ { value: 'count', label: $lc("计数") },
250
+ { value: 'avg', label: $lc("平均值") },
251
+ { value: 'max', label: $lc("最大值") },
252
+ { value: 'min', label: $lc("最小值") }
253
253
  ]
254
254
  }
255
255
  },
@@ -476,10 +476,10 @@ export default {
476
476
 
477
477
  return result
478
478
  } catch (err) {
479
- console.error('数据透视计算失败:', err)
479
+ console.error($lc("数据透视计算失败:"), err)
480
480
  this.error = {
481
481
  code: 'AGGREGATION_ERROR',
482
- message: err.message || '数据计算过程中发生错误',
482
+ message: err.message || $lc("数据计算过程中发生错误"),
483
483
  stack: err.stack
484
484
  }
485
485
  this.calculateTime = 0
@@ -622,7 +622,7 @@ export default {
622
622
  // 获取第一个维度标签
623
623
  getFirstDimensionLabel() {
624
624
  const dim = this.currentReport.selectedDimension
625
- if (!dim) return '未选择'
625
+ if (!dim) return $lc("未选择")
626
626
  const dimDef = this.columns.find((c) => c.prop === dim)
627
627
  return dimDef ? dimDef.label : dim
628
628
  },
@@ -630,7 +630,7 @@ export default {
630
630
  // 获取行维度标签(交叉统计用)
631
631
  getRowDimensionLabel() {
632
632
  const dim = this.currentReport.rowDimension
633
- if (!dim) return '未选择'
633
+ if (!dim) return $lc("未选择")
634
634
  const dimDef = this.columns.find((c) => c.prop === dim)
635
635
  return dimDef ? dimDef.label : dim
636
636
  },
@@ -638,7 +638,7 @@ export default {
638
638
  // 获取列维度标签(交叉统计用)
639
639
  getColumnDimensionLabel() {
640
640
  const dim = this.currentReport.columnDimension
641
- if (!dim) return '未选择'
641
+ if (!dim) return $lc("未选择")
642
642
  const dimDef = this.columns.find((c) => c.prop === dim)
643
643
  return dimDef ? dimDef.label : dim
644
644
  },
@@ -732,7 +732,7 @@ export default {
732
732
  {
733
733
  type: 'text',
734
734
  style: {
735
- text: '总计',
735
+ text: $lc("总计"),
736
736
  textAlign: 'center',
737
737
  fill: getCSSVariableValue('--color-text-regular'),
738
738
  fontSize: 13,
@@ -1166,7 +1166,7 @@ export default {
1166
1166
  getDefaultReport() {
1167
1167
  return {
1168
1168
  id: this.generateId(),
1169
- name: '报表清单',
1169
+ name: $lc("报表清单"),
1170
1170
  statType: 'group',
1171
1171
  chartType: this.chartType || 'bar',
1172
1172
  selectedDimension: null,
@@ -1268,9 +1268,9 @@ export default {
1268
1268
  },
1269
1269
 
1270
1270
  handleDeleteReport(report) {
1271
- this.$confirm(`确定要删除报表"${report.name}"吗?`, '提示', {
1272
- confirmButtonText: '确定',
1273
- cancelButtonText: '取消',
1271
+ this.$confirm(`确定要删除报表"${report.name}"吗?`, $lc("提示"), {
1272
+ confirmButtonText: $lc("确定"),
1273
+ cancelButtonText: $lc("取消"),
1274
1274
  type: 'warning'
1275
1275
  })
1276
1276
  .then(() => {
@@ -1284,7 +1284,7 @@ export default {
1284
1284
  this.addNewReport()
1285
1285
  }
1286
1286
  this.saveToStorage()
1287
- this.$message.success('删除成功')
1287
+ this.$message.success($lc("删除成功"))
1288
1288
  }
1289
1289
  })
1290
1290
  .catch(() => {})
@@ -1319,7 +1319,7 @@ export default {
1319
1319
  handleExport() {
1320
1320
  const data = this.processedData
1321
1321
  if (data.length === 0) {
1322
- this.$message.warning('暂无数据可导出')
1322
+ this.$message.warning($lc("暂无数据可导出"))
1323
1323
  return
1324
1324
  }
1325
1325
 
@@ -1345,7 +1345,7 @@ export default {
1345
1345
 
1346
1346
  handleAddToHome() {
1347
1347
  this.$emit('add-to-home', this.currentReport)
1348
- this.$message.success('已添加到首页')
1348
+ this.$message.success($lc("已添加到首页"))
1349
1349
  },
1350
1350
 
1351
1351
  handleDeleteCurrentReport() {