|
|
@@ -1,313 +1,184 @@
|
|
1
|
1
|
|
|
2
|
|
-import { Component, AfterViewInit, inject } from '@angular/core';
|
|
|
2
|
+import { Component, inject, ViewChild, OnInit, AfterViewInit } from '@angular/core';
|
|
3
|
3
|
import { ConfigMetaService } from '../../services/config-meta.service';
|
|
4
|
|
-import { AuthService } from '../../services/auth.service';
|
|
5
|
|
-import { TabulatorMapper } from '../../utils/tabulator-mapper.util';
|
|
6
|
|
-import { ConfigService, StickyHeaderComponent, StickyHeaderButton } from 'base-core';
|
|
|
4
|
+import { ConfigService, StickyHeaderComponent, StickyHeaderButton, TabulatorGridComponent } from 'base-core';
|
|
7
|
5
|
import { CommonModule } from '@angular/common';
|
|
8
|
|
-
|
|
9
|
|
-// 声明全局类型
|
|
10
|
|
-declare var Tabulator: any;
|
|
11
|
|
-
|
|
|
6
|
+import { Observable } from 'rxjs';
|
|
12
|
7
|
|
|
13
|
8
|
@Component({
|
|
14
|
|
- imports: [CommonModule, StickyHeaderComponent],
|
|
|
9
|
+ imports: [CommonModule, StickyHeaderComponent, TabulatorGridComponent],
|
|
15
|
10
|
selector: 'app-service-register-config',
|
|
16
|
11
|
templateUrl: './service-register-config.component.html',
|
|
17
|
12
|
styleUrl: './service-register-config.component.scss'
|
|
18
|
13
|
})
|
|
19
|
|
-export class ServiceRegisterConfigComponent implements AfterViewInit {
|
|
20
|
|
- private tabulator!: any;
|
|
21
|
|
- private totalCount: number = 0;
|
|
|
14
|
+export class ServiceRegisterConfigComponent implements OnInit, AfterViewInit {
|
|
22
|
15
|
private configMetaService = inject(ConfigMetaService);
|
|
23
|
16
|
private config = inject(ConfigService);
|
|
24
|
|
- private authService = inject(AuthService);
|
|
25
|
|
-
|
|
26
|
|
- title = '注册服务配置';
|
|
27
|
|
- hintText = '点击"注册"按钮将同步所有配置元信息到数据库,并显示配置列表。';
|
|
28
|
|
- headerButtons: StickyHeaderButton[] = [
|
|
29
|
|
- { title: '注册', name: 'register', icon: 'add', color: 'primary' },
|
|
30
|
|
- { title: '刷新', name: 'refresh', icon: 'refresh', color: 'accent' }
|
|
31
|
|
- ];
|
|
32
|
|
- //registering = false;
|
|
33
|
|
-
|
|
34
|
|
- // 外部查询条件预留字段(用于将来扩展)
|
|
35
|
|
- externalFilters: any = {};
|
|
|
17
|
+
|
|
|
18
|
+ @ViewChild(TabulatorGridComponent) tabulatorGrid!: TabulatorGridComponent;
|
|
|
19
|
+
|
|
|
20
|
+ ngOnInit(): void {
|
|
|
21
|
+ console.log('ServiceRegisterConfigComponent 初始化');
|
|
|
22
|
+ // 确保使用代理API路径
|
|
|
23
|
+ this.config.apiBaseUrl = '/api';
|
|
|
24
|
+ console.log('ConfigService:', {
|
|
|
25
|
+ useMockData: this.config.useMockData,
|
|
|
26
|
+ apiBaseUrl: this.config.apiBaseUrl
|
|
|
27
|
+ });
|
|
|
28
|
+ }
|
|
36
|
29
|
|
|
37
|
30
|
ngAfterViewInit(): void {
|
|
38
|
|
- console.log('ServiceRegisterConfigComponent ngAfterViewInit');
|
|
39
|
|
- console.log('Tabulator global available:', typeof Tabulator !== 'undefined');
|
|
40
|
|
- console.log('ConfigService状态:', {
|
|
41
|
|
- useMockData: this.config.useMockData,
|
|
42
|
|
- apiBaseUrl: this.config.apiBaseUrl
|
|
43
|
|
- });
|
|
44
|
|
- console.log('ConfigMetaService API URL:', this.configMetaService.getListUrl());
|
|
45
|
|
-
|
|
46
|
|
- // 使用 setTimeout 确保 DOM 已渲染
|
|
47
|
|
- setTimeout(() => {
|
|
48
|
|
- console.log('Initializing Tabulator...');
|
|
49
|
|
- this.initTabulator();
|
|
50
|
|
- }, 100);
|
|
|
31
|
+ console.log('👀 ServiceRegisterConfigComponent: TabulatorGrid 视图初始化完成');
|
|
51
|
32
|
}
|
|
|
33
|
+
|
|
|
34
|
+ title = '注册服务配置';
|
|
|
35
|
+ hintText = '点击"注册"按钮将同步所有配置元信息到数据库,并显示配置列表。';
|
|
|
36
|
+ headerButtons: StickyHeaderButton[] = [
|
|
|
37
|
+ { title: '注册', name: 'register', icon: 'add', color: 'primary' },
|
|
|
38
|
+ { title: '刷新', name: 'refresh', icon: 'refresh', color: 'accent' }
|
|
|
39
|
+ ];
|
|
52
|
40
|
|
|
53
|
|
- /**
|
|
54
|
|
- * 初始化表格 - 标准远程分页版本
|
|
55
|
|
- */
|
|
56
|
|
- private initTabulator(): void {
|
|
57
|
|
- console.log('initTabulator called');
|
|
58
|
|
- console.log('Table element exists:', document.getElementById('tabulator-table'));
|
|
59
|
|
-
|
|
60
|
|
- // 获取Basic认证信息
|
|
61
|
|
- const basicAuth = this.authService.getBasicAuth();
|
|
62
|
|
- console.log('Basic认证信息:', basicAuth ? '有' : '无');
|
|
63
|
|
-
|
|
64
|
|
- this.tabulator = new Tabulator('#tabulator-table', {
|
|
65
|
|
-
|
|
66
|
|
- // 列定义 - 使用现有列配置
|
|
67
|
|
- columns: [
|
|
68
|
|
-
|
|
69
|
|
- { title: 'ID', field: 'id', sorter: 'number', headerFilter: 'input', width: 220 ,
|
|
70
|
|
- headerMenu: [
|
|
71
|
|
- {
|
|
72
|
|
- label: "<i class='fa fa-filter'></i> 切换筛选",
|
|
73
|
|
- action: (column:any) => {
|
|
74
|
|
- const headerFilterEl = column.getElement().querySelector('.tabulator-header-filter');
|
|
75
|
|
- if (headerFilterEl) {
|
|
76
|
|
- const isHidden = headerFilterEl.style.display === 'none';
|
|
77
|
|
- headerFilterEl.style.display = isHidden ? '' : 'none';
|
|
|
41
|
+ // 外部查询条件预留字段(用于将来扩展)
|
|
|
42
|
+ externalFilters: any = {};
|
|
|
43
|
+
|
|
|
44
|
+ // 表格列定义
|
|
|
45
|
+ columns = [
|
|
|
46
|
+ {
|
|
|
47
|
+ title: 'ID',
|
|
|
48
|
+ field: 'id',
|
|
|
49
|
+ sorter: 'number',
|
|
|
50
|
+ headerFilter: 'input',
|
|
|
51
|
+ width: 220,
|
|
|
52
|
+ headerMenu: [
|
|
|
53
|
+ {
|
|
|
54
|
+ label: "<i class='fa fa-filter'></i> 切换筛选",
|
|
|
55
|
+ action: (column: any) => {
|
|
|
56
|
+ const headerFilterEl = column.getElement().querySelector('.tabulator-header-filter');
|
|
|
57
|
+ if (headerFilterEl) {
|
|
|
58
|
+ const isHidden = headerFilterEl.style.display === 'none';
|
|
|
59
|
+ headerFilterEl.style.display = isHidden ? '' : 'none';
|
|
|
60
|
+ }
|
|
78
|
61
|
}
|
|
79
|
62
|
}
|
|
80
|
|
- }
|
|
81
|
|
- ]
|
|
82
|
|
- },
|
|
83
|
|
- { title: '配置名称', field: 'configName', sorter: 'string', headerFilter: 'input', headerFilterFunc: 'like',width: 110 },
|
|
84
|
|
- { title: '字段名', field: 'fieldName', sorter: 'string', headerFilter: 'input', headerFilterFunc: 'like' ,width: 130},
|
|
85
|
|
- { title: '字段类型', field: 'fieldType', sorter: 'string', headerFilter: 'input',width: 120, headerFilterParams: { values: ['string', 'number', 'boolean', 'array', 'object'] } },
|
|
86
|
|
- { title: '描述', field: 'fieldDesc', sorter: 'string', headerFilter: 'input', headerFilterFunc: 'like' }
|
|
87
|
|
- ],
|
|
88
|
|
-
|
|
89
|
|
- // 标准远程分页配置
|
|
90
|
|
- pagination: true,
|
|
91
|
|
- paginationMode: 'remote',
|
|
92
|
|
- paginationSize: 20,
|
|
93
|
|
- paginationSizeSelector: [10, 20, 50, 100],
|
|
94
|
|
- sortMode: 'remote',
|
|
95
|
|
- filterMode: 'remote',
|
|
96
|
|
-
|
|
97
|
|
- // 使用标准AJAX配置,通过代理调用后端API
|
|
98
|
|
- ajaxURL: '/api/config/meta/list',
|
|
99
|
|
- ajaxConfig: {
|
|
100
|
|
- method: 'POST',
|
|
101
|
|
- headers: {
|
|
102
|
|
- 'Authorization': basicAuth ? `Basic ${basicAuth}` : '',
|
|
103
|
|
- 'Content-Type': 'application/json'
|
|
104
|
|
- }
|
|
105
|
|
- },
|
|
106
|
|
- ajaxContentType: 'json',
|
|
107
|
|
-
|
|
108
|
|
- ajaxParams: function() {
|
|
109
|
|
- // 获取调用时的上下文信息
|
|
110
|
|
- const callTime = new Date().toISOString();
|
|
111
|
|
- const stack = new Error().stack; // 获取调用堆栈
|
|
112
|
|
-
|
|
113
|
|
- console.group("=== ajaxParams被调用 ===");
|
|
114
|
|
- console.log("调用时间:", callTime);
|
|
115
|
|
- console.log("当前页码:", this.getPage());
|
|
116
|
|
- console.log("筛选条件:", this.getFilters(true));
|
|
117
|
|
- console.log("排序条件:", this.getSorters());
|
|
118
|
|
- // console.log("调用来源:", stack.split('\n')[2]?.trim() || "未知");
|
|
119
|
|
- console.groupEnd();
|
|
120
|
|
-
|
|
121
|
|
- return {
|
|
122
|
|
- page: this.getPage() || 1,
|
|
123
|
|
- size: this.getPageSize() || 20,
|
|
124
|
|
- filter: this.getFilters(true) || [],
|
|
125
|
|
- sort: this.getSorters() || []
|
|
126
|
|
- };
|
|
|
63
|
+ ]
|
|
127
|
64
|
},
|
|
128
|
|
- // 参数生成器,将Tabulator参数转换为后端期望格式
|
|
129
|
|
- ajaxURLGenerator:function(url: string, config: any, params: any){
|
|
130
|
|
- //ajaxParamsGenerator: (url: string, config: any, params: any) => {
|
|
131
|
|
- console.log('=== Tabulator AJAX参数生成器被调用 ===');
|
|
132
|
|
- console.log('请求URL:', url);
|
|
133
|
|
- console.log('请求配置:', config);
|
|
134
|
|
- console.log('原始params类型:', typeof params);
|
|
135
|
|
- console.log('原始params完整结构:', JSON.stringify(params, null, 2));
|
|
136
|
|
-
|
|
137
|
|
- // 详细分析params对象
|
|
138
|
|
- if (params) {
|
|
139
|
|
- console.log('params所有键:', Object.keys(params));
|
|
140
|
|
- console.log('page:', params.page);
|
|
141
|
|
- console.log('size:', params.size);
|
|
142
|
|
- console.log('sort类型:', typeof params.sort);
|
|
143
|
|
- console.log('sort值:', params.sort);
|
|
144
|
|
- console.log('filter类型:', typeof params.filter);
|
|
145
|
|
- console.log('filter值:', params.filter);
|
|
146
|
|
-
|
|
147
|
|
- // 检查可能的别名
|
|
148
|
|
- console.log('sorters存在?:', 'sorters' in params);
|
|
149
|
|
- console.log('filters存在?:', 'filters' in params);
|
|
150
|
|
-
|
|
151
|
|
- // 检查是否有外部查询条件的预留字段
|
|
152
|
|
- console.log('当前外部查询条件预留字段:', this.externalFilters || '未定义');
|
|
153
|
|
- } else {
|
|
154
|
|
- console.log('params为undefined或null');
|
|
155
|
|
- params = {};
|
|
156
|
|
- }
|
|
157
|
|
-
|
|
158
|
|
- // 构建请求参数,使用TabulatorMapper转换为后端期望格式
|
|
159
|
|
- // Tabulator 6.x发送的是 sort/filter(单数),但后端期望 sorters/filters(复数)
|
|
160
|
|
- // const request = TabulatorMapper.buildServerRequest(
|
|
161
|
|
- // params.page || 1,
|
|
162
|
|
- //params.size || 20,
|
|
163
|
|
- //params.sorts || [], // Tabulator使用单数'sort'
|
|
164
|
|
- //params.filters || [] // Tabulator使用单数'filter'
|
|
165
|
|
- //);
|
|
166
|
|
-
|
|
167
|
|
- // console.log('生成的请求参数:', JSON.stringify(request, null, 2));
|
|
168
|
|
-
|
|
169
|
|
- const fullUrl = url + '?params=' + encodeURIComponent(JSON.stringify(params));
|
|
|
65
|
+ {
|
|
|
66
|
+ title: '配置名称',
|
|
|
67
|
+ field: 'configName',
|
|
|
68
|
+ sorter: 'string',
|
|
|
69
|
+ headerFilter: 'input',
|
|
|
70
|
+ headerFilterFunc: 'like',
|
|
|
71
|
+ width: 110
|
|
|
72
|
+ },
|
|
|
73
|
+ {
|
|
|
74
|
+ title: '字段名',
|
|
|
75
|
+ field: 'fieldName',
|
|
|
76
|
+ sorter: 'string',
|
|
|
77
|
+ headerFilter: 'input',
|
|
|
78
|
+ headerFilterFunc: 'like',
|
|
|
79
|
+ width: 130
|
|
|
80
|
+ },
|
|
|
81
|
+ {
|
|
|
82
|
+ title: '字段类型',
|
|
|
83
|
+ field: 'fieldType',
|
|
|
84
|
+ sorter: 'string',
|
|
|
85
|
+ headerFilter: 'input',
|
|
|
86
|
+ width: 120,
|
|
|
87
|
+ headerFilterParams: { values: ['string', 'number', 'boolean', 'array', 'object'] }
|
|
|
88
|
+ },
|
|
|
89
|
+ {
|
|
|
90
|
+ title: '描述',
|
|
|
91
|
+ field: 'fieldDesc',
|
|
|
92
|
+ sorter: 'string',
|
|
|
93
|
+ headerFilter: 'input',
|
|
|
94
|
+ headerFilterFunc: 'like'
|
|
|
95
|
+ }
|
|
|
96
|
+ ];
|
|
170
|
97
|
|
|
171
|
|
- console.log('完整URL:', fullUrl);
|
|
172
|
|
- console.log('=== 参数生成器执行结束 ===');
|
|
173
|
|
-
|
|
174
|
|
- return fullUrl;
|
|
|
98
|
+ /**
|
|
|
99
|
+ * 数据加载函数 - 适配 TabulatorGridComponent
|
|
|
100
|
+ */
|
|
|
101
|
+ dataLoader = (params: any): Observable<{ last_page: number; data: any[] }> => {
|
|
|
102
|
+ console.log('📊 ServiceRegisterConfigComponent 数据加载函数被调用');
|
|
|
103
|
+ console.log('原始参数:', params);
|
|
|
104
|
+ console.log('ConfigMetaService URL:', this.configMetaService.getListUrl());
|
|
175
|
105
|
|
|
176
|
|
- // 返回完整的请求配置对象
|
|
177
|
|
- // return {
|
|
178
|
|
- // method: 'POST', // 使用POST方法
|
|
179
|
|
- // headers: {
|
|
180
|
|
- // 'Content-Type': 'application/json',
|
|
181
|
|
- // 'Authorization': 'Basic YWRtaW46MTIz', // 你的认证信息
|
|
182
|
|
- // // 可以添加其他需要的headers
|
|
183
|
|
- // },
|
|
184
|
|
- // body: JSON.stringify({
|
|
185
|
|
- // filter: params.filter || [], // 根据后端期望的字段名调整
|
|
186
|
|
- // page: params.page || 1,
|
|
187
|
|
- // size: params.size || 20,
|
|
188
|
|
- // sort: params.sorter || [] // 根据后端期望的字段名调整
|
|
189
|
|
- // })
|
|
190
|
|
- //};
|
|
191
|
|
- },
|
|
192
|
|
-
|
|
193
|
|
- // 响应处理,将后端响应转换为Tabulator期望格式
|
|
194
|
|
- // ajaxResponse: (url: string, params: any, response: any) => {
|
|
195
|
|
- // console.log('Tabulator AJAX响应处理', { url, params, response });
|
|
196
|
|
-
|
|
197
|
|
- // // 检查响应格式
|
|
198
|
|
- // if (response && typeof response === 'object') {
|
|
199
|
|
- // // 后端返回格式:{success: true, data: [...], totalCount: N, last_page: N}
|
|
200
|
|
- // const data = response.data || [];
|
|
201
|
|
- // const totalCount = response.totalCount || 0;
|
|
202
|
|
- // const pageSize = params.size || 20;
|
|
203
|
|
- // const lastPage = response.last_page || Math.ceil(totalCount / pageSize);
|
|
204
|
|
-
|
|
205
|
|
- // return {
|
|
206
|
|
- // data: data,
|
|
207
|
|
- // last_page: lastPage
|
|
208
|
|
- // };
|
|
209
|
|
- // }
|
|
210
|
|
-
|
|
211
|
|
- // // 如果响应格式不符合预期,返回空数据
|
|
212
|
|
- // console.warn('响应格式不符合预期:', response);
|
|
213
|
|
- // return {
|
|
214
|
|
- // data: [],
|
|
215
|
|
- // last_page: 0
|
|
216
|
|
- // };
|
|
217
|
|
- // },
|
|
218
|
|
-
|
|
219
|
|
- tableAjaxError: (error: any) => {
|
|
220
|
|
- console.error('Tabulator AJAX错误:', error);
|
|
221
|
|
- if (error.status === 401 || error.status === 403) {
|
|
222
|
|
- console.warn('认证失败,跳转到登录页面');
|
|
223
|
|
- this.authService.logout();
|
|
|
106
|
+ // 确保参数有默认值
|
|
|
107
|
+ const safeParams = {
|
|
|
108
|
+ page: params?.page || 1,
|
|
|
109
|
+ size: params?.size || 20,
|
|
|
110
|
+ sort: params?.sort || [],
|
|
|
111
|
+ filter: params?.filter || []
|
|
|
112
|
+ };
|
|
|
113
|
+
|
|
|
114
|
+ console.log('处理后参数:', safeParams);
|
|
|
115
|
+
|
|
|
116
|
+ return this.configMetaService.listForTabulator(safeParams);
|
|
|
117
|
+ };
|
|
|
118
|
+
|
|
|
119
|
+ /**
|
|
|
120
|
+ * 注册配置元信息
|
|
|
121
|
+ */
|
|
|
122
|
+ onRegister(): void {
|
|
|
123
|
+ console.log('注册按钮被点击');
|
|
|
124
|
+ this.headerButtons[0].loading = true;
|
|
|
125
|
+
|
|
|
126
|
+ this.configMetaService.initConfigMeta().subscribe({
|
|
|
127
|
+ next: (result: any) => {
|
|
|
128
|
+ this.headerButtons[0].loading = false;
|
|
|
129
|
+ if (result.success) {
|
|
|
130
|
+ console.log('注册完成:', result.data);
|
|
|
131
|
+ // 注册成功后刷新表格数据
|
|
|
132
|
+ this.refresh();
|
|
|
133
|
+ console.log('注册成功,数据已重新加载');
|
|
|
134
|
+ } else {
|
|
|
135
|
+ console.error('注册失败:', result);
|
|
224
|
136
|
}
|
|
225
|
137
|
},
|
|
226
|
|
-
|
|
227
|
|
-
|
|
228
|
|
-
|
|
229
|
|
- // 表格样式
|
|
230
|
|
- layout: 'fitColumns',
|
|
231
|
|
- responsiveLayout: 'collapse',
|
|
232
|
|
- //height: '800px',
|
|
233
|
|
-
|
|
234
|
|
- // 初始加载
|
|
235
|
|
- ajaxInitialLoad: true,
|
|
236
|
|
-
|
|
237
|
|
- // 分页位置
|
|
238
|
|
- paginationCounter: 'rows',
|
|
239
|
|
- paginationButtonCount: 5
|
|
|
138
|
+ error: (error) => {
|
|
|
139
|
+ this.headerButtons[0].loading = false;
|
|
|
140
|
+ console.error('注册请求失败:', error);
|
|
|
141
|
+ }
|
|
240
|
142
|
});
|
|
241
|
143
|
}
|
|
242
|
|
-
|
|
243
|
144
|
|
|
244
|
|
- onRegister() {
|
|
245
|
|
- console.log('注册按钮被点击');
|
|
246
|
|
- //this.registering = true;
|
|
247
|
|
- this.headerButtons[0].loading = true;
|
|
248
|
|
-
|
|
249
|
|
- this.configMetaService.initConfigMeta().subscribe({
|
|
250
|
|
- next: (result: any) => {
|
|
251
|
|
- // this.registering = false;
|
|
252
|
|
- this.headerButtons[0].loading = false;
|
|
253
|
|
- //this.errorMessage = null;
|
|
254
|
|
- if (result.success) {
|
|
255
|
|
- console.log('注册完成:', result.data);
|
|
256
|
|
-
|
|
257
|
|
- // 注册后切换到真实API数据
|
|
258
|
|
- //this.debugInfo.useMockData = false;
|
|
259
|
|
- //this.updateDataConfig();
|
|
260
|
|
-
|
|
261
|
|
- // 重新加载数据
|
|
262
|
|
- //this.loadData(1);
|
|
263
|
|
-
|
|
264
|
|
- console.log('注册成功,数据已重新加载');
|
|
265
|
|
- } else {
|
|
266
|
|
- console.error('注册失败:', result);
|
|
267
|
|
- }
|
|
268
|
|
- },
|
|
269
|
|
- error: (error) => {
|
|
270
|
|
- // this.registering = false;
|
|
271
|
|
- this.headerButtons[0].loading = false;
|
|
272
|
|
- console.error('注册请求失败:', error);
|
|
273
|
|
- }
|
|
274
|
|
- });
|
|
|
145
|
+ /**
|
|
|
146
|
+ * 处理头部按钮点击事件
|
|
|
147
|
+ */
|
|
|
148
|
+ onHeaderButtonAction(name: string): void {
|
|
|
149
|
+ console.log(`头部按钮点击: ${name}`);
|
|
|
150
|
+ switch (name) {
|
|
|
151
|
+ case 'register':
|
|
|
152
|
+ this.onRegister();
|
|
|
153
|
+ break;
|
|
|
154
|
+ case 'refresh':
|
|
|
155
|
+ this.refresh();
|
|
|
156
|
+ break;
|
|
|
157
|
+ default:
|
|
|
158
|
+ console.warn(`未知按钮操作: ${name}`);
|
|
275
|
159
|
}
|
|
276
|
|
-
|
|
277
|
|
- onHeaderButtonAction(name: string) {
|
|
278
|
|
- console.log(`头部按钮点击: ${name}`);
|
|
279
|
|
- switch (name) {
|
|
280
|
|
- case 'register':
|
|
281
|
|
- this.onRegister();
|
|
282
|
|
- break;
|
|
283
|
|
- case 'refresh':
|
|
284
|
|
- this.refresh();
|
|
285
|
|
- break;
|
|
286
|
|
- default:
|
|
287
|
|
- console.warn(`未知按钮操作: ${name}`);
|
|
288
|
|
- }
|
|
|
160
|
+ }
|
|
|
161
|
+
|
|
|
162
|
+ /**
|
|
|
163
|
+ * 刷新表格数据
|
|
|
164
|
+ */
|
|
|
165
|
+ refresh(): void {
|
|
|
166
|
+ if (this.tabulatorGrid) {
|
|
|
167
|
+ this.headerButtons[1].loading = true;
|
|
|
168
|
+ this.tabulatorGrid.refresh();
|
|
|
169
|
+ // 简单延迟后清除loading状态
|
|
|
170
|
+ setTimeout(() => {
|
|
|
171
|
+ this.headerButtons[1].loading = false;
|
|
|
172
|
+ }, 500);
|
|
289
|
173
|
}
|
|
290
|
|
- /**
|
|
291
|
|
- * 刷新表格 - 重新加载数据
|
|
292
|
|
- */
|
|
293
|
|
- refresh(): void {
|
|
294
|
|
- if (this.tabulator) {
|
|
295
|
|
- this.headerButtons[1].loading = true;
|
|
296
|
|
- this.tabulator.replaceData();
|
|
297
|
|
- // 简单延迟后清除loading状态
|
|
298
|
|
- setTimeout(() => {
|
|
299
|
|
- this.headerButtons[1].loading = false;
|
|
300
|
|
- }, 500);
|
|
301
|
|
- }
|
|
302
|
|
- }
|
|
303
|
|
-
|
|
|
174
|
+ }
|
|
|
175
|
+
|
|
304
|
176
|
/**
|
|
305
|
177
|
* 重置筛选和排序
|
|
306
|
178
|
*/
|
|
307
|
179
|
reset(): void {
|
|
308
|
|
- if (this.tabulator) {
|
|
309
|
|
- this.tabulator.clearFilter();
|
|
310
|
|
- this.tabulator.clearSort();
|
|
|
180
|
+ if (this.tabulatorGrid) {
|
|
|
181
|
+ this.tabulatorGrid.reset();
|
|
311
|
182
|
}
|
|
312
|
183
|
}
|
|
313
|
184
|
|
|
|
@@ -326,11 +197,34 @@ export class ServiceRegisterConfigComponent implements AfterViewInit {
|
|
326
|
197
|
}
|
|
327
|
198
|
|
|
328
|
199
|
/**
|
|
329
|
|
- * 导出数据
|
|
|
200
|
+ * 导出数据为 CSV
|
|
330
|
201
|
*/
|
|
331
|
202
|
exportData(): void {
|
|
332
|
|
- if (this.tabulator) {
|
|
333
|
|
- this.tabulator.download('csv', 'config-meta-data.csv');
|
|
|
203
|
+ if (this.tabulatorGrid) {
|
|
|
204
|
+ this.tabulatorGrid.exportToCSV('config-meta-data.csv');
|
|
334
|
205
|
}
|
|
335
|
206
|
}
|
|
|
207
|
+
|
|
|
208
|
+ /**
|
|
|
209
|
+ * 处理表格数据加载完成事件
|
|
|
210
|
+ */
|
|
|
211
|
+ onDataLoaded(response: any): void {
|
|
|
212
|
+ console.log('✅ 表格数据加载完成:', {
|
|
|
213
|
+ last_page: response?.last_page,
|
|
|
214
|
+ data_count: response?.data?.length,
|
|
|
215
|
+ data_sample: response?.data?.slice(0, 2)
|
|
|
216
|
+ });
|
|
|
217
|
+ }
|
|
|
218
|
+
|
|
|
219
|
+ /**
|
|
|
220
|
+ * 处理 AJAX 错误事件
|
|
|
221
|
+ */
|
|
|
222
|
+ onAjaxError(error: any): void {
|
|
|
223
|
+ console.error('❌ 表格 AJAX 错误:', error);
|
|
|
224
|
+ console.error('错误详情:', {
|
|
|
225
|
+ message: error?.message,
|
|
|
226
|
+ status: error?.status,
|
|
|
227
|
+ url: error?.url
|
|
|
228
|
+ });
|
|
|
229
|
+ }
|
|
336
|
230
|
}
|