@a2simcode/ui 0.0.68 → 0.0.70

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.
@@ -125,6 +125,19 @@
125
125
  </template>
126
126
  </Demo>
127
127
 
128
+ ## 树形异步数据加载(懒加载)
129
+
130
+ 当数据量较大时,可以将记录的 `children` 设置为 `true` 作为懒加载标识;展开该行时,组件会调用 `loadChildren(record)` 异步获取子节点并写入。
131
+
132
+ <Demo :source-code="tableTreeLazyCode">
133
+ <template #source>
134
+ <table-tree-lazy />
135
+ </template>
136
+ <template #description>
137
+ 设置 <code>isTree</code> 并在某些行上标记 <code>children: true</code>。展开时将调用 <code>loadChildren(record)</code> 获取并填充该行的子节点。
138
+ </template>
139
+ </Demo>
140
+
128
141
  ## 子表
129
142
 
130
143
  通过 `subColumns` 属性配置子表列信息(Master-Detail)。
@@ -272,6 +285,7 @@ import TableFrozenColumn from '../examples/table/frozen-column.vue'
272
285
  import TableHeightMode from '../examples/table/height-mode.vue'
273
286
  import TableTreeColumn from '../examples/table/tree-column.vue'
274
287
  import TableTreeData from '../examples/table/tree-data.vue'
288
+ import TableTreeLazy from '../examples/table/tree-lazy.vue'
275
289
  import TableSubTable from '../examples/table/sub-table.vue'
276
290
  import TableSubTableLazy from '../examples/table/sub-table-lazy.vue'
277
291
  import TableMultiple from '../examples/table/multiple.vue'
@@ -292,6 +306,7 @@ import tableFrozenColumnCode from '../examples/table/frozen-column.vue?raw'
292
306
  import tableHeightModeCode from '../examples/table/height-mode.vue?raw'
293
307
  import tableTreeColumnCode from '../examples/table/tree-column.vue?raw'
294
308
  import tableTreeDataCode from '../examples/table/tree-data.vue?raw'
309
+ import tableTreeLazyCode from '../examples/table/tree-lazy.vue?raw'
295
310
  import tableSubTableCode from '../examples/table/sub-table.vue?raw'
296
311
  import tableSubTableLazyCode from '../examples/table/sub-table-lazy.vue?raw'
297
312
  import tableMultipleCode from '../examples/table/multiple.vue?raw'
@@ -0,0 +1,207 @@
1
+ <template>
2
+ <div class="j-block j-user-center-log" style="height: 600px;">
3
+ <j-page :noPadding="true" :schema="schema" ref="indexRef" />
4
+ </div>
5
+ </template>
6
+ <script lang="ts" setup>
7
+ import type { TableColumnCompConfig, ColumnSchemaConfig,LayerParamType } from '@a2simcode/ui';
8
+
9
+ import { ref, h, defineComponent, resolveComponent } from 'vue';
10
+ import { iconLoaded, loadIcon } from '@iconify/vue';
11
+
12
+ const indexRef = ref();
13
+
14
+ const ExecuteResultLayer = defineComponent({
15
+ name: 'ExecuteResultLayer',
16
+ props: {
17
+ text: {
18
+ type: String,
19
+ default: '',
20
+ },
21
+ },
22
+ setup(props) {
23
+ const JCodeMirror = resolveComponent('j-code-mirror');
24
+ return () =>
25
+ h(
26
+ JCodeMirror,
27
+ {
28
+ readOnly: true,
29
+ value: props.text || '',
30
+ }
31
+ );
32
+ },
33
+ });
34
+
35
+ const browsers = [
36
+ { name: 'Chrome', icon: 'logos:chrome' },
37
+ { name: 'Firefox', icon: 'logos:firefox' },
38
+ { name: 'Safari', icon: 'logos:safari' },
39
+ { name: 'Edge', icon: 'logos:microsoft-edge' },
40
+ ];
41
+
42
+ interface ColumnType {
43
+ label: string;
44
+ id: string;
45
+ }
46
+
47
+ const columns: ColumnType[] = [
48
+ { label: '浏览器', id: 'j_BrowserTag' },
49
+ {
50
+ label: '类型',
51
+ id: 'j_CategoryId',
52
+ },
53
+ { label: '时间', id: 'j_CreateDate' },
54
+ { label: '时长(ms)', id: 'j_Times' },
55
+ { label: '请求接口', id: 'j_Url' },
56
+ { label: '请求类型', id: 'j_OperateType' },
57
+ { label: 'IP', id: 'j_IPAddress' },
58
+ { label: '结果', id: 'j_Result' },
59
+ { label: '描述', id: 'j_ExecuteResult' },
60
+ ];
61
+
62
+ const columnsConfig: Record<string, TableColumnCompConfig> = {
63
+ j_BrowserTag: {
64
+ width: 72,
65
+ type: 'j-icon',
66
+ align: 'center',
67
+ },
68
+ j_CategoryId: {
69
+ type: 'j-tag',
70
+ width: 72,
71
+ align: 'center',
72
+ dataType: 'options',
73
+ options: [
74
+ { label: '登录', value: 1, color: '#e8ffea' },
75
+ { label: '访问', value: 2, color: '#e8f3ff' },
76
+ { label: '操作', value: 3, color: '#e5f9f8' },
77
+ { label: '文件下载', value: 5, color: '#fff7e8' },
78
+ { label: '文件预览', value: 6, color: '#f5f2ff' },
79
+ { label: '接口请求', value: 7, color: '#f0f5ff' },
80
+ { label: '接口限流', value: 8, color: '#fffce8' },
81
+ { label: '接口熔断', value: 9, color: '#fff2e8' },
82
+ { label: '异常', value: 4, color: '#ffece8' },
83
+ ],
84
+ },
85
+ j_CreateDate: {
86
+ width: 160,
87
+ dataType: 'dateTime',
88
+ },
89
+ j_Times: {
90
+ width: 80,
91
+ align: 'center',
92
+ },
93
+ j_Url: {
94
+ width: 200,
95
+ isSearchKeyword: true,
96
+ },
97
+ j_OperateType: {
98
+ width: 80,
99
+ align: 'center',
100
+ },
101
+
102
+ j_IPAddress: {
103
+ width: 120,
104
+ isSearchKeyword: true,
105
+ },
106
+ j_Result: {
107
+ type: 'j-tag',
108
+ width: 72,
109
+ align: 'center',
110
+ dataType: 'options',
111
+ fieldFormat: (row: Record<string, any>) => (row.j_Result === 1 ? 1 : 2),
112
+ options: [
113
+ { label: '成功', value: 1, color: '#e8ffea' },
114
+ { label: '失败', value: 2, color: '#ffece8' },
115
+ ],
116
+ },
117
+ j_ExecuteResult: {
118
+ type: 'link',
119
+ width: 60,
120
+ align: 'center',
121
+ fieldFormat: () => '查看',
122
+ click: ({ row, openLayer }: { row: any,openLayer: (params: LayerParamType) => void }) => {
123
+ openLayer({
124
+ title: '描述',
125
+ name: ExecuteResultLayer,
126
+ config: { text: row?.j_ExecuteResult || '' },
127
+ width: 1000,
128
+ height: 600,
129
+ hasBtns: false,
130
+ });
131
+ },
132
+ },
133
+ };
134
+
135
+ const myColumns: ColumnSchemaConfig[] = [];
136
+ columns.forEach((item) => {
137
+ const config = columnsConfig[item.id || ''] || {};
138
+ const schemaItem: ColumnSchemaConfig = {
139
+ id: item.id || '',
140
+ type: config.type || '',
141
+ config: { ...config, label: item.label || '' },
142
+ };
143
+ myColumns.push(schemaItem);
144
+ });
145
+
146
+ // Mock API
147
+ const api = {
148
+ getMyPage: async (params: any) => {
149
+ // Simulate API call
150
+ await new Promise(resolve => setTimeout(resolve, 300));
151
+ return {
152
+ total: 20,
153
+ rows: Array.from({ length: 10 }).map((_, i) => ({
154
+ j_Id: i + 1,
155
+ j_BrowserTag: browsers[i % browsers.length].name,
156
+ j_CategoryId: (i % 9) + 1,
157
+ j_CreateDate: new Date().toISOString(),
158
+ j_Times: Math.floor(Math.random() * 1000),
159
+ j_Url: `/api/v1/resource/${i}`,
160
+ j_OperateType: ['GET', 'POST', 'PUT', 'DELETE'][i % 4],
161
+ j_IPAddress: `192.168.1.${i}`,
162
+ j_Result: i % 5 === 0 ? 2 : 1,
163
+ j_ExecuteResult: JSON.stringify({ status: 200, message: 'Success' })
164
+ }))
165
+ }
166
+ }
167
+ }
168
+
169
+ const schema = [
170
+ {
171
+ id: 'mainTable',
172
+ type: 'j-table-panel',
173
+ config: {
174
+ columns: myColumns,
175
+ rowKey: 'j_Id',
176
+ sort: 'j_CreateDate DESC',
177
+ isPage: true,
178
+ loadData: async (params: Record<string, any>) => {
179
+ let res = await api.getMyPage(params);
180
+ if (res && res.rows) {
181
+ const iconsToLoad = new Set();
182
+ res.rows.forEach((item: any) => {
183
+ const browser = browsers.find(
184
+ (b) => item.j_BrowserTag && item.j_BrowserTag === b.name
185
+ );
186
+ if (browser) {
187
+ item.j_BrowserTag = browser.icon;
188
+ iconsToLoad.add(browser.icon);
189
+ }
190
+ });
191
+
192
+ await Promise.all(
193
+ [...iconsToLoad].map(async (icon) => {
194
+ if (!iconLoaded(icon as string)) {
195
+ await loadIcon(icon as string);
196
+ }
197
+ })
198
+ );
199
+ }
200
+
201
+ console.log(res, 'res');
202
+ return res;
203
+ },
204
+ },
205
+ },
206
+ ];
207
+ </script>
@@ -0,0 +1,80 @@
1
+ <template>
2
+ <div style="position: relative; width: 100%; height: 500px">
3
+ <j-table
4
+ :columns="columns"
5
+ :records="records"
6
+ is-tree
7
+ :load-children="loadChildren"
8
+ />
9
+ </div>
10
+ </template>
11
+
12
+ <script setup lang="ts">
13
+ import { ref } from 'vue'
14
+
15
+ const columns = ref([
16
+ {
17
+ id: 'category',
18
+ config: {
19
+ label: '类别',
20
+ width: 200,
21
+ },
22
+ },
23
+ {
24
+ id: 'amount',
25
+ config: {
26
+ label: '销售额',
27
+ width: 'auto',
28
+ },
29
+ },
30
+ {
31
+ id: 'profit',
32
+ config: {
33
+ label: '利润',
34
+ width: 120,
35
+ },
36
+ },
37
+ ])
38
+
39
+ const records = ref([
40
+ {
41
+ category: '办公用品',
42
+ amount: '129.70',
43
+ profit: '-60.70',
44
+ children: [
45
+ { category: '信封', amount: '125.44', profit: '42.56' },
46
+ { category: '器具', amount: '1375.92', profit: '550.2' },
47
+ ],
48
+ },
49
+ {
50
+ category: '技术',
51
+ amount: '229.70',
52
+ profit: '90.70',
53
+ children: true,
54
+ },
55
+ {
56
+ category: '家具',
57
+ amount: '329.00',
58
+ profit: '120.30',
59
+ children: [
60
+ { category: '桌子', amount: '125.44', profit: '42.56' },
61
+ { category: '椅子', amount: '1375.92', profit: '550.2' },
62
+ ],
63
+ },
64
+ ])
65
+
66
+ const delay = (ms: number) => new Promise((r) => setTimeout(r, ms))
67
+
68
+ const loadChildren = async (record: any) => {
69
+ await delay(600)
70
+ if (record.category === '技术') {
71
+ return [
72
+ { category: '设备', amount: '225.44', profit: '462.56' },
73
+ { category: '配件', amount: '375.92', profit: '550.2' },
74
+ { category: '电话', amount: '175.92', profit: '750.2' },
75
+ ]
76
+ }
77
+ return []
78
+ }
79
+ </script>
80
+
@@ -0,0 +1,100 @@
1
+ <template>
2
+ <div style="position: relative; width: 100%; height: 500px">
3
+ <j-table-panel
4
+ :columns="columns"
5
+ :load-data="loadData"
6
+ :sub-columns="subColumns"
7
+ :load-children="loadChildren"
8
+ row-key="id"
9
+ />
10
+ </div>
11
+ </template>
12
+
13
+ <script lang="ts" setup>
14
+ import type { ColumnSchemaConfig } from '@a2simcode/ui'
15
+
16
+ const columns: ColumnSchemaConfig[] = [
17
+ {
18
+ id: 'id',
19
+ type: '',
20
+ config: {
21
+ align: 'center',
22
+ label: 'ID',
23
+ width: 100,
24
+ },
25
+ },
26
+ {
27
+ id: 'name',
28
+ type: '',
29
+ config: {
30
+ label: '名称',
31
+ width: 200,
32
+ },
33
+ },
34
+ {
35
+ id: 'value',
36
+ type: 'j-switch',
37
+ config: {
38
+ label: '值',
39
+ width: 100,
40
+ align: 'center',
41
+ activeValue: 1,
42
+ inactiveValue: 0,
43
+ },
44
+ },
45
+ ]
46
+
47
+ const subColumns: ColumnSchemaConfig[] = [
48
+ {
49
+ id: 'id',
50
+ type: '',
51
+ config: {
52
+ label: '子ID',
53
+ width: 100,
54
+ },
55
+ },
56
+ {
57
+ id: 'name',
58
+ type: '',
59
+ config: {
60
+ label: '子名称',
61
+ width: 200,
62
+ },
63
+ },
64
+ {
65
+ id: 'value',
66
+ type: '',
67
+ config: {
68
+ label: '子值',
69
+ width: 100,
70
+ },
71
+ },
72
+ ]
73
+
74
+ const loadData = async (params: Record<string, any>) => {
75
+ console.log('Loading main table data with params:', params)
76
+ return new Promise((resolve) => {
77
+ setTimeout(() => {
78
+ const data = [
79
+ { id: '1', name: 'Parent 1', value: 1, children: true },
80
+ { id: '2', name: 'Parent 2', value: 0, children: true },
81
+ ]
82
+ resolve(data)
83
+ }, 500)
84
+ })
85
+ }
86
+
87
+ const loadChildren = async (record: Record<string, any>): Promise<any[]> => {
88
+ console.log('Loading children for record:', record)
89
+ // 模拟异步加载数据
90
+ return new Promise((resolve) => {
91
+ setTimeout(() => {
92
+ const children = [
93
+ { id: record.id + '-1', name: record.name + ' Child 1', value: Math.random() * 100 },
94
+ { id: record.id + '-2', name: record.name + ' Child 2', value: Math.random() * 100 },
95
+ ]
96
+ resolve(children)
97
+ }, 1000)
98
+ })
99
+ }
100
+ </script>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@a2simcode/ui",
3
- "version": "0.0.68",
3
+ "version": "0.0.70",
4
4
  "description": "A Vue 3 UI Component Library",
5
5
  "type": "module",
6
6
  "main": "./dist/simcode-ui.umd.js",