@agile-team/wl-skills-kit 2.4.2 → 2.5.0

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.
@@ -81,6 +81,8 @@
81
81
  </div>
82
82
  <BaseTable
83
83
  ref="itemTableRef"
84
+ render-type="agGrid"
85
+ :cid="ITEM_TABLE_CID"
84
86
  :data="itemList"
85
87
  :columns="itemColumns"
86
88
  showToolbar
@@ -110,6 +112,7 @@ import {
110
112
  itemList,
111
113
  itemColumns,
112
114
  itemPage,
115
+ ITEM_TABLE_CID,
113
116
  formRef,
114
117
  itemTableRef,
115
118
  handleSave,
@@ -136,6 +139,9 @@ import { ElMessage } from "element-plus";
136
139
  import type { FormInstance, FormRules } from "element-plus";
137
140
  import type { TableColumnDesc } from "@/types/page";
138
141
  import envConfig from "@jhlc/common-core/src/store/env-config";
142
+ import { defineColumns, renderOps } from "@agile-team/wk-skills-ui/runtime";
143
+
144
+ export const ITEM_TABLE_CID = "[pageAbbr]-[base36Timestamp]-sub1";
139
145
 
140
146
  export const API_CONFIG = {
141
147
  getById: "/[服务缩写]/[主资源]/getById",
@@ -184,22 +190,25 @@ export const itemTableRef = ref();
184
190
  export const itemList = ref<any[]>([]);
185
191
  export const itemPage = reactive({ current: 1, size: 10, total: 0 });
186
192
 
187
- export const itemColumns: TableColumnDesc<any>[] = [
188
- { type: "index", width: 55 },
189
- { label: "[子项字段]", name: "[fieldName]", minWidth: 120 },
193
+ export const itemColumns: TableColumnDesc<any>[] = defineColumns([
194
+ { type: "index", label: "序号", width: 60, align: "center" },
195
+ {
196
+ label: "[子项字段]",
197
+ name: "[fieldName]",
198
+ cid: `${ITEM_TABLE_CID}-[fieldName]`,
199
+ minWidth: 120,
200
+ },
190
201
  {
191
202
  label: "操作",
203
+ name: "_action",
204
+ cid: `${ITEM_TABLE_CID}-action`,
192
205
  width: 100,
193
206
  fixed: "right",
194
- operations: [
195
- {
196
- name: "remove",
197
- label: "删除",
198
- onClick: (row: any) => removeItem(row),
199
- },
200
- ],
207
+ align: "center",
208
+ defaultSlot: ({ row }: any) =>
209
+ renderOps([{ type: "del", onClick: () => removeItem(row) }]),
201
210
  },
202
- ];
211
+ ] as any) as TableColumnDesc<any>[];
203
212
 
204
213
  // ===== 数据加载 =====
205
214
  export async function loadItems() {
@@ -453,7 +462,14 @@ defineExpose({ open });
453
462
  @reset="select"
454
463
  />
455
464
  <BaseToolbar :items="toolbars" />
456
- <BaseTable ref="tableRef" :data="list" :columns="columns" showToolbar />
465
+ <BaseTable
466
+ ref="tableRef"
467
+ render-type="agGrid"
468
+ :cid="TABLE_CID"
469
+ :data="list"
470
+ :columns="columns"
471
+ showToolbar
472
+ />
457
473
  <jh-pagination
458
474
  v-show="page.total && page.total > 0"
459
475
  :total="page.total || 0"
@@ -468,7 +484,7 @@ defineExpose({ open });
468
484
  </template>
469
485
 
470
486
  <script setup lang="ts">
471
- import { createPage } from "./data";
487
+ import { createPage, TABLE_CID } from "./data";
472
488
  import AddModal from "./components/addModal.vue";
473
489
 
474
490
  const addModalRef = ref();
@@ -547,22 +563,44 @@ let _editModalRef: any = null;
547
563
 
548
564
  /** 管理视角列定义 */
549
565
  export function managementColumns(): TableColumnDesc<any>[] {
550
- return [
551
- { type: "selection" },
552
- { type: "index" },
566
+ return defineColumns([
567
+ { type: "selection", width: 55, fixed: "left", align: "center", headerAlign: "center" },
568
+ { type: "index", label: "序号", width: 60, align: "center" },
553
569
  // ... 管理视角列(按原型顺序)
554
- { label: "操作", width: 100, fixed: "right", operations: [...] }
555
- ];
570
+ {
571
+ label: "操作",
572
+ name: "_action",
573
+ cid: `${TABLE_CID}-management-action`,
574
+ width: 120,
575
+ fixed: "right",
576
+ align: "center",
577
+ defaultSlot: ({ row }: any) => renderOps([
578
+ { type: "edit", onClick: () => _editModalRef?.value?.open(row.id) },
579
+ { type: "del", onClick: () => Page?.remove(row.id) }
580
+ ])
581
+ }
582
+ ] as any) as TableColumnDesc<any>[];
556
583
  }
557
584
 
558
585
  /** 使用视角列定义(含业务明细字段) */
559
586
  export function usageColumns(): TableColumnDesc<any>[] {
560
- return [
561
- { type: "selection" },
562
- { type: "index" },
587
+ return defineColumns([
588
+ { type: "selection", width: 55, fixed: "left", align: "center", headerAlign: "center" },
589
+ { type: "index", label: "序号", width: 60, align: "center" },
563
590
  // ... 使用视角列(按原型顺序,通常比管理视角多出业务字段)
564
- { label: "操作", width: 100, fixed: "right", operations: [...] }
565
- ];
591
+ {
592
+ label: "操作",
593
+ name: "_action",
594
+ cid: `${TABLE_CID}-usage-action`,
595
+ width: 120,
596
+ fixed: "right",
597
+ align: "center",
598
+ defaultSlot: ({ row }: any) => renderOps([
599
+ { type: "edit", onClick: () => _editModalRef?.value?.open(row.id) },
600
+ { type: "del", onClick: () => Page?.remove(row.id) }
601
+ ])
602
+ }
603
+ ] as any) as TableColumnDesc<any>[];
566
604
  }
567
605
 
568
606
  let Page: any = null;
@@ -756,18 +794,20 @@ export function createPage() {
756
794
  ];
757
795
  }
758
796
  columnsDef() {
759
- return [
797
+ return defineColumns([
760
798
  // ...
761
799
  {
762
- label: "操作", fixed: "right",
763
- operations: [
764
- {
765
- name: "edit", label: "编辑",
766
- onClick: (row: any) => navigateToForm({ id: row.id })
767
- }
768
- ]
800
+ label: "操作",
801
+ name: "_action",
802
+ cid: `${TABLE_CID}-action`,
803
+ fixed: "right",
804
+ align: "center",
805
+ defaultSlot: ({ row }: any) =>
806
+ renderOps([
807
+ { type: "edit", onClick: () => navigateToForm({ id: row.id }) }
808
+ ])
769
809
  }
770
- ];
810
+ ] as any) as TableColumnDesc<any>[];
771
811
  }
772
812
  }
773
813
  ```
@@ -846,22 +886,14 @@ onMounted(() => {
846
886
  ### 实现方式
847
887
 
848
888
  ```vue
849
- <!-- 表格列:v-if mode 控制 -->
850
- <el-table-column v-if="isChange" label="使用组织" prop="useOrg" />
851
- <el-table-column
852
- v-if="!isChange && !isView"
853
- label="免息天数"
854
- prop="interestFreeDays"
889
+ <!-- 表格列:按 mode data.ts 中切换 columns,仍使用 BaseTable + AGGrid -->
890
+ <BaseTable
891
+ render-type="agGrid"
892
+ :cid="DETAIL_TABLE_CID"
893
+ :data="list"
894
+ :columns="isChange ? changeColumns : addColumns"
855
895
  />
856
896
 
857
- <!-- 操作列:变更模式多一个编辑按钮 -->
858
- <el-table-column v-if="!isView" label="操作" :width="isChange ? 120 : 80">
859
- <template #default="{ row, $index }">
860
- <el-button v-if="isChange" type="primary" link @click="editRow(row, $index)">编辑</el-button>
861
- <el-button type="danger" link @click="list.splice($index, 1)">删除</el-button>
862
- </template>
863
- </el-table-column>
864
-
865
897
  <!-- 底部新增行链接(变更模式) -->
866
898
  <div
867
899
  v-if="isChange && !isView"
@@ -1000,7 +1032,7 @@ spec.features.hiddenMenu === true:
1000
1032
  ✅ query: spec 12 项 = code 12 项,顺序一致
1001
1033
  ✅ columns: spec 16 项 = code 16 项,顺序一致
1002
1034
  ✅ toolbar: spec 7 项 = code 7 项,顺序一致,颜色正确
1003
- operations: spec 3 项 = code 3 项,顺序一致
1035
+ rowActions: spec 3 项 = code 3 项,顺序一致
1004
1036
  ✅ tabs: spec 3 项 = code 3 项,顺序一致
1005
1037
  ✅ subTables: businessInfo(editable) — 有新增/删除
1006
1038
  ✅ dict 字段: 8 个全部配置 logicType
@@ -1013,7 +1045,7 @@ spec.features.hiddenMenu === true:
1013
1045
  ```
1014
1046
  ❌ columns: spec 35 项 ≠ code 34 项 — 缺少 customerName 列 → 已补全
1015
1047
  ❌ toolbar 顺序: spec [新增申请, 删除, 启用] ≠ code [新增, 启用, 删除] → 已调整
1016
- operations: spec [查看, 编辑, 删除] ≠ code [编辑, 删除] — 缺少"查看" → 已补全
1048
+ rowActions: spec [查看, 编辑, 删除] ≠ code [编辑, 删除] — 缺少"查看" → 已补全
1017
1049
  ```
1018
1050
 
1019
1051
  ---
@@ -2,7 +2,6 @@
2
2
 
3
3
  > 见 SKILL.md 主文件(约束 + 按钮规则 + Mock 规范等共用规则)。
4
4
 
5
-
6
5
  > 复杂表单(多 Tab、多子表、独立布局)使用独立路由而非弹窗。
7
6
  > 表单页 `data.ts` **不继承 `AbstractPageQueryHook`**,改为导出 `useXxx` Composable。
8
7
  > 需在 `pages.ts` 单独注册路由,路径规则见"FORM_ROUTE 表单页"章节。
@@ -74,7 +73,9 @@ export function use[PageName]Form(tabsRef: any) {
74
73
  <div class="page-header">
75
74
  <span class="page-title">[页面标题]</span>
76
75
  <span class="page-tag page-tag--add">新增</span>
77
- <el-checkbox v-model="onlyRequired" class="only-required-check">只看必填项</el-checkbox>
76
+ <el-checkbox v-model="onlyRequired" class="only-required-check"
77
+ >只看必填项</el-checkbox
78
+ >
78
79
  </div>
79
80
  <div class="page-toolbar">
80
81
  <el-button type="primary" @click="handleSave">保存</el-button>
@@ -118,6 +119,10 @@ onMounted(() => {
118
119
  import { getAction, postAction } from "@jhlc/common-core/src/api/action";
119
120
  import { ElMessage, ElMessageBox } from "element-plus";
120
121
  import { useRouter } from "vue-router";
122
+ import type { TableColumnDesc } from "@/types/page";
123
+ import { defineColumns, renderOps } from "@agile-team/wk-skills-ui/runtime";
124
+
125
+ export const DETAIL_TABLE_CID = "[pageAbbr]-[base36Timestamp]-sub1";
121
126
 
122
127
  export const API_CONFIG = {
123
128
  getById: "/sale/[业务名]/getById",
@@ -130,6 +135,25 @@ export const OPTS = {
130
135
  // [字段名]: [{ label: "显示文本", value: "值" }]
131
136
  };
132
137
 
138
+ export function createDetailColumns(removeRecord: (row: any) => void): TableColumnDesc<any>[] {
139
+ return defineColumns([
140
+ { type: "index", label: "序号", width: 60, align: "center" },
141
+ { label: "[明细字段]", name: "[detailField]", cid: `${DETAIL_TABLE_CID}-[detailField]`, minWidth: 120 },
142
+ {
143
+ label: "操作",
144
+ name: "_action",
145
+ cid: `${DETAIL_TABLE_CID}-action`,
146
+ width: 100,
147
+ fixed: "right",
148
+ align: "center",
149
+ defaultSlot: ({ row }: any) =>
150
+ renderOps([
151
+ { type: "del", onClick: () => removeRecord(row) }
152
+ ])
153
+ }
154
+ ] as any) as TableColumnDesc<any>[];
155
+ }
156
+
133
157
  export interface [PageName]Form {
134
158
  id: string;
135
159
  // ...所有字段
@@ -148,6 +172,16 @@ export function use[PageName]Detail() {
148
172
  const loading = ref(false);
149
173
  const form = reactive<[PageName]Form>(createMockData());
150
174
 
175
+ function addRecord() {
176
+ form.[列表字段].push({ id: `temp_${Date.now()}` });
177
+ }
178
+
179
+ function removeRecord(row: any) {
180
+ form.[列表字段] = form.[列表字段].filter((item: any) => item.id !== row.id);
181
+ }
182
+
183
+ const detailColumns = createDetailColumns(removeRecord);
184
+
151
185
  async function loadDetail(id: string) {
152
186
  loading.value = true;
153
187
  try {
@@ -170,7 +204,7 @@ export function use[PageName]Detail() {
170
204
 
171
205
  function handleCancel() { router.back(); }
172
206
 
173
- return { loading, form, loadDetail, handleSave, handleCancel };
207
+ return { loading, form, detailColumns, addRecord, loadDetail, handleSave, handleCancel };
174
208
  }
175
209
  ```
176
210
 
@@ -182,7 +216,12 @@ export function use[PageName]Detail() {
182
216
  <!-- 标题栏 -->
183
217
  <div class="title-bar">
184
218
  <span class="customer-name">{{ form.[标题字段] }}</span>
185
- <el-tag type="warning" effect="plain" size="small">{{ form.[状态字段] }}</el-tag>
219
+ <el-tag
220
+ type="warning"
221
+ effect="plain"
222
+ size="small"
223
+ >{{ form.[状态字段] }}</el-tag
224
+ >
186
225
  </div>
187
226
 
188
227
  <!-- 工具栏 -->
@@ -221,16 +260,13 @@ export function use[PageName]Detail() {
221
260
  <!-- 子表格 Section(如跟进记录) -->
222
261
  <div class="form-section">
223
262
  <div class="section-title">[表格标题]</div>
224
- <el-table :data="form.[列表字段]" border size="small">
225
- <el-table-column type="index" label="序号" width="55" align="center" />
226
- <!-- ...更多列 -->
227
- <el-table-column label="操作" width="100" fixed="right">
228
- <template #default="{ $index }">
229
- <el-button type="primary" link size="small">编辑</el-button>
230
- <el-button type="danger" link size="small" @click="removeRecord($index)">删除</el-button>
231
- </template>
232
- </el-table-column>
233
- </el-table>
263
+ <BaseTable
264
+ render-type="agGrid"
265
+ :cid="DETAIL_TABLE_CID"
266
+ :data="form.[列表字段]"
267
+ :columns="detailColumns"
268
+ :height="300"
269
+ />
234
270
  <div class="add-row-btn" @click="addRecord">+ 新增行</div>
235
271
  </div>
236
272
  </el-form>
@@ -239,10 +275,18 @@ export function use[PageName]Detail() {
239
275
 
240
276
  <script setup lang="ts">
241
277
  import { useRoute } from "vue-router";
242
- import { use[PageName]Detail, OPTS } from "./data";
278
+ import { use[PageName]Detail, OPTS, DETAIL_TABLE_CID } from "./data";
243
279
 
244
280
  const route = useRoute();
245
- const { loading, form, loadDetail, handleSave, handleCancel } = use[PageName]Detail();
281
+ const {
282
+ loading,
283
+ form,
284
+ detailColumns,
285
+ addRecord,
286
+ loadDetail,
287
+ handleSave,
288
+ handleCancel
289
+ } = use[PageName]Detail();
246
290
 
247
291
  onMounted(() => {
248
292
  const id = route.query.id as string;
@@ -264,15 +308,37 @@ onMounted(() => {
264
308
  flex-direction: column;
265
309
  overflow: hidden;
266
310
 
267
- .title-bar { /* 标题 + 状态 Tag,灰色背景 */ }
268
- .page-toolbar { /* 按钮行,白底,底部边框 */ }
269
- .detail-form { flex: 1; overflow-y: auto; padding: 0 16px 16px; }
270
- .header-info { padding: 12px 0 4px; border-bottom: 1px solid #f0f2f5; }
271
- .form-section { margin-top: 16px;
272
- .section-title { border-left: 3px solid var(--el-color-primary); padding-left: 10px; font-weight: 600; }
311
+ .title-bar {
312
+ /* 标题 + 状态 Tag,灰色背景 */
313
+ }
314
+ .page-toolbar {
315
+ /* 按钮行,白底,底部边框 */
316
+ }
317
+ .detail-form {
318
+ flex: 1;
319
+ overflow-y: auto;
320
+ padding: 0 16px 16px;
321
+ }
322
+ .header-info {
323
+ padding: 12px 0 4px;
324
+ border-bottom: 1px solid #f0f2f5;
325
+ }
326
+ .form-section {
327
+ margin-top: 16px;
328
+ .section-title {
329
+ border-left: 3px solid var(--el-color-primary);
330
+ padding-left: 10px;
331
+ font-weight: 600;
332
+ }
333
+ }
334
+ .add-row-btn {
335
+ color: #409eff;
336
+ cursor: pointer;
337
+ margin-top: 8px;
338
+ }
339
+ .el-form-item {
340
+ margin-bottom: 10px;
273
341
  }
274
- .add-row-btn { color: #409eff; cursor: pointer; margin-top: 8px; }
275
- .el-form-item { margin-bottom: 10px; }
276
342
  }
277
343
  ```
278
344
 
@@ -284,26 +350,27 @@ onMounted(() => {
284
350
  > 典型页面:精整实绩(抛丸/倒棱/矫直/酸洗/剥皮/检验/包装)、加热管理(装炉/出炉)、剔钢操作。
285
351
  >
286
352
  > 项目中已有两种落地方式:
353
+ >
287
354
  > - **配置驱动模板组件**:`FinishingAchievementTemplate`(7 个精整页面共用)
288
355
  > - **独立页面编排**:`mmwr-heating-management`、`mmwr-steel-stripping-operations`
289
356
 
290
357
  ### D-0 核心特征
291
358
 
292
- | 特征 | 说明 |
293
- |---|---|
294
- | **多 AbstractPageQueryHook 实例** | 每个表格区域一个实例,各自管理 `list/page/queryParam/columns` |
295
- | **主从联动** | 选中上表行 → 调用下表实例的 `selectByPlan(row)` 驱动查询 |
296
- | **可拖拽分隔** | `<jh-drag-row :top-height="N">` 上下分隔,可嵌套 |
297
- | **Tab 切换** | `<el-tabs type="border-card">` 或 `<jh-tabs>` 切换录入/查询视角 |
298
- | **操作区** | 在上下表之间放置 `BaseForm` + 按钮,或 `BaseToolbar` |
299
- | **懒加载** | Tab 切换时才加载对应数据,避免首次全量查询 |
359
+ | 特征 | 说明 |
360
+ | --------------------------------- | --------------------------------------------------------------- |
361
+ | **多 AbstractPageQueryHook 实例** | 每个表格区域一个实例,各自管理 `list/page/queryParam/columns` |
362
+ | **主从联动** | 选中上表行 → 调用下表实例的 `selectByPlan(row)` 驱动查询 |
363
+ | **可拖拽分隔** | `<jh-drag-row :top-height="N">` 上下分隔,可嵌套 |
364
+ | **Tab 切换** | `<el-tabs type="border-card">` 或 `<jh-tabs>` 切换录入/查询视角 |
365
+ | **操作区** | 在上下表之间放置 `BaseForm` + 按钮,或 `BaseToolbar` |
366
+ | **懒加载** | Tab 切换时才加载对应数据,避免首次全量查询 |
300
367
 
301
368
  ### D-1 判断何时使用配置驱动 vs 独立编排
302
369
 
303
- | 条件 | 方式 |
304
- |---|---|
305
- | 3+ 页面布局完全相同,仅 API/工序代码/列不同 | 提取 `src/components/template/XxxTemplate/`,页面仅传 config |
306
- | 页面布局有显著差异(不同 Tab 结构、不同表数量) | 独立页面,在 data.ts 中定义多个 `createXxxPage()` |
370
+ | 条件 | 方式 |
371
+ | ----------------------------------------------- | ------------------------------------------------------------ |
372
+ | 3+ 页面布局完全相同,仅 API/工序代码/列不同 | 提取 `src/components/template/XxxTemplate/`,页面仅传 config |
373
+ | 页面布局有显著差异(不同 Tab 结构、不同表数量) | 独立页面,在 data.ts 中定义多个 `createXxxPage()` |
307
374
 
308
375
  ### D-2 配置驱动模板组件结构(参考 FinishingAchievementTemplate)
309
376
 
@@ -321,17 +388,27 @@ src/views/.../[page-name]/
321
388
  ```
322
389
 
323
390
  **types.ts 要点**:
391
+
324
392
  ```typescript
325
393
  export interface XxxTemplateConfig {
326
- api: Record<string, string>; // 各表格 API 端点
327
- processCode: string; // 工序标识,用于查询参数
328
- query?: { plan?: { items: BaseQueryItemDesc<any>[]; defaultParams?: Record<string, any> } };
329
- columns?: { planColumns: TableColumnDesc<any>[]; detailColumns: TableColumnDesc<any>[] };
330
- ui?: Partial<UiConfig>; // 可选 UI 覆盖(Tab 标题、区域标题等)
394
+ api: Record<string, string>; // 各表格 API 端点
395
+ processCode: string; // 工序标识,用于查询参数
396
+ query?: {
397
+ plan?: {
398
+ items: BaseQueryItemDesc<any>[];
399
+ defaultParams?: Record<string, any>;
400
+ };
401
+ };
402
+ columns?: {
403
+ planColumns: TableColumnDesc<any>[];
404
+ detailColumns: TableColumnDesc<any>[];
405
+ };
406
+ ui?: Partial<UiConfig>; // 可选 UI 覆盖(Tab 标题、区域标题等)
331
407
  }
332
408
  ```
333
409
 
334
410
  **页面 data.ts 要点**(仅配置,不写逻辑):
411
+
335
412
  ```typescript
336
413
  import type { XxxTemplateConfig } from "@/components/template/XxxTemplate/types";
337
414
 
@@ -345,6 +422,7 @@ export const xxxConfig: XxxTemplateConfig = {
345
422
  ### D-3 独立编排页面结构(参考 mmwr-steel-stripping-operations)
346
423
 
347
424
  **data.ts 要点**(多个 createPage 工厂函数):
425
+
348
426
  ```typescript
349
427
  // 上表
350
428
  export function createEntryPage() {
@@ -375,6 +453,7 @@ export function createEntryBottomPage(rejectForm: any) {
375
453
  ```
376
454
 
377
455
  **index.vue 要点**:
456
+
378
457
  ```vue
379
458
  <template>
380
459
  <div class="app-container app-page-container [page-class]">
@@ -383,12 +462,21 @@ export function createEntryBottomPage(rejectForm: any) {
383
462
  <jh-drag-row :top-height="420">
384
463
  <template #top>
385
464
  <BaseQuery :form="..." :items="..." @select="..." @reset="..." />
386
- <BaseTable ref="..." :data="..." :columns="..." highlight-current-row @current-change="handleRowClick" />
465
+ <BaseTable
466
+ ref="..."
467
+ :data="..."
468
+ :columns="..."
469
+ highlight-current-row
470
+ @current-change="handleRowClick"
471
+ />
387
472
  <jh-pagination ... />
388
473
  </template>
389
474
  <template #bottom>
390
475
  <BaseToolbar v-if="selectedRow" :items="..." />
391
- <el-empty v-if="!selectedRow" description="请先在上方列表中选择一行数据" />
476
+ <el-empty
477
+ v-if="!selectedRow"
478
+ description="请先在上方列表中选择一行数据"
479
+ />
392
480
  <BaseTable v-else ref="..." :data="..." :columns="..." />
393
481
  <jh-pagination ... />
394
482
  </template>
@@ -402,16 +490,26 @@ export function createEntryBottomPage(rejectForm: any) {
402
490
  </template>
403
491
 
404
492
  <script setup lang="ts">
405
- import { createEntryPage, createEntryBottomPage, createQueryPage } from "./data";
493
+ import {
494
+ createEntryPage,
495
+ createEntryBottomPage,
496
+ createQueryPage,
497
+ } from "./data";
406
498
 
407
499
  const activeTab = ref("entry");
408
500
  const selectedRow = ref(null);
409
501
 
410
502
  const EntryPage = createEntryPage();
411
- const { tableRef, page, queryParam, list, queryItems, columns, select } = EntryPage;
503
+ const { tableRef, page, queryParam, list, queryItems, columns, select } =
504
+ EntryPage;
412
505
 
413
506
  const BottomPage = createEntryBottomPage();
414
- const { list: bottomList, columns: bottomColumns, select: bottomSelect, selectByPlan } = BottomPage;
507
+ const {
508
+ list: bottomList,
509
+ columns: bottomColumns,
510
+ select: bottomSelect,
511
+ selectByPlan,
512
+ } = BottomPage;
415
513
 
416
514
  const handleRowClick = (row: any) => {
417
515
  selectedRow.value = row;
@@ -419,7 +517,9 @@ const handleRowClick = (row: any) => {
419
517
  };
420
518
 
421
519
  onMounted(() => select());
422
- watch(activeTab, (tab) => { if (tab === "query") QueryPage.select(); });
520
+ watch(activeTab, (tab) => {
521
+ if (tab === "query") QueryPage.select();
522
+ });
423
523
  </script>
424
524
  ```
425
525
 
@@ -427,14 +527,42 @@ watch(activeTab, (tab) => { if (tab === "query") QueryPage.select(); });
427
527
 
428
528
  ```scss
429
529
  .[page-class] {
430
- .section-header { display: flex; align-items: center; gap: 6px; margin: 8px 0; }
431
- .section-header .title-bar { width: 3px; height: 14px; background: var(--el-color-primary); border-radius: 1px; }
432
- .section-header .section-title { font-size: 14px; font-weight: 600; margin: 0; }
433
- .empty-tip { padding: 40px 0; }
434
- .operation-area { padding: 8px 0; }
435
- .operation-buttons { display: flex; gap: 8px; margin: 8px 0; }
436
- .results-container { display: flex; gap: 16px; /* 左右分栏时 */ }
437
- .results-container .section { flex: 1; min-width: 0; }
530
+ .section-header {
531
+ display: flex;
532
+ align-items: center;
533
+ gap: 6px;
534
+ margin: 8px 0;
535
+ }
536
+ .section-header .title-bar {
537
+ width: 3px;
538
+ height: 14px;
539
+ background: var(--el-color-primary);
540
+ border-radius: 1px;
541
+ }
542
+ .section-header .section-title {
543
+ font-size: 14px;
544
+ font-weight: 600;
545
+ margin: 0;
546
+ }
547
+ .empty-tip {
548
+ padding: 40px 0;
549
+ }
550
+ .operation-area {
551
+ padding: 8px 0;
552
+ }
553
+ .operation-buttons {
554
+ display: flex;
555
+ gap: 8px;
556
+ margin: 8px 0;
557
+ }
558
+ .results-container {
559
+ display: flex;
560
+ gap: 16px; /* 左右分栏时 */
561
+ }
562
+ .results-container .section {
563
+ flex: 1;
564
+ min-width: 0;
565
+ }
438
566
  }
439
567
  ```
440
568