c-admin-kit 1.0.0 → 1.0.1
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/LLMS.md +256 -0
- package/README.md +185 -108
- package/llms.txt +19 -0
- package/package.json +4 -2
package/LLMS.md
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
# C-Admin-Kit: AI Assistant Context & Guidelines
|
|
2
|
+
|
|
3
|
+
> This document is designed for AI Coding Assistants (Cursor, GitHub Copilot, Claude Code, Antigravity, Windsurf, etc.) to understand the architectural rules, coding standards, and golden patterns of `c-admin-kit`.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🤖 Role & Instruction for AI
|
|
8
|
+
|
|
9
|
+
When generating or refactoring Vue 3 + Element Plus admin pages using `c-admin-kit`:
|
|
10
|
+
1. **Mandatory Prefix**: All components **MUST ALWAYS** use the `c-` prefix in template (e.g., `<c-simple-table>`, `<c-search-box>`, `<c-async-button>`). Never use `<simple-table>` or `<search-box>`.
|
|
11
|
+
2. **Never Handwrite CRUD Glue Code**:
|
|
12
|
+
- Always use `useListPage` to manage search, reset, pagination, batch delete, state toggling, and routing.
|
|
13
|
+
- Always use `SearchFieldFactory` to declare search form fields. Do NOT manually construct verbose search option objects.
|
|
14
|
+
3. **Async Action Safety**: Always use `<c-async-button :on-click="fn">` or `useConfirmSubmit` for asynchronous operations to automatically handle loading states and prevent double-clicks.
|
|
15
|
+
4. **Style Import**: Ensure `import 'c-admin-kit/dist/c-admin-kit.css'` is present in `main.ts` or component.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 📦 Import Signatures
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import {
|
|
23
|
+
// Components
|
|
24
|
+
CSimpleTable,
|
|
25
|
+
CSearchBox,
|
|
26
|
+
CAsyncButton,
|
|
27
|
+
CCollapsibleContainer,
|
|
28
|
+
CCustomDrawer,
|
|
29
|
+
CImagePreview,
|
|
30
|
+
CDiff,
|
|
31
|
+
CSelectWithAll,
|
|
32
|
+
CSelectWithPage,
|
|
33
|
+
|
|
34
|
+
// Composables / Hooks
|
|
35
|
+
useListPage,
|
|
36
|
+
useForm,
|
|
37
|
+
useDownload,
|
|
38
|
+
useConfirmAction,
|
|
39
|
+
useConfirmSubmit,
|
|
40
|
+
useDialog,
|
|
41
|
+
|
|
42
|
+
// Utilities & Factories
|
|
43
|
+
SearchFieldFactory,
|
|
44
|
+
CommonSearchFields,
|
|
45
|
+
listToTree,
|
|
46
|
+
treeToList,
|
|
47
|
+
findTreeNode,
|
|
48
|
+
findParentNodes,
|
|
49
|
+
filterTree,
|
|
50
|
+
mapTree,
|
|
51
|
+
|
|
52
|
+
// Types
|
|
53
|
+
type TableColumn,
|
|
54
|
+
type SearchField
|
|
55
|
+
} from 'c-admin-kit'
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## 🌟 The Golden Standard Pattern (Standard CRUD Page)
|
|
61
|
+
|
|
62
|
+
AI should use this template as the standard blueprint for any admin list view:
|
|
63
|
+
|
|
64
|
+
```vue
|
|
65
|
+
<template>
|
|
66
|
+
<div class="page-container">
|
|
67
|
+
<!-- 1. Search Box -->
|
|
68
|
+
<c-search-box
|
|
69
|
+
:fields="searchFields"
|
|
70
|
+
@search="handleSearch"
|
|
71
|
+
@reset="handleReset"
|
|
72
|
+
/>
|
|
73
|
+
|
|
74
|
+
<!-- 2. Dynamic Adaptive Table -->
|
|
75
|
+
<c-simple-table
|
|
76
|
+
ref="tableRef"
|
|
77
|
+
:api="getUserListApi"
|
|
78
|
+
:columns="columns"
|
|
79
|
+
table-key="user_management_table"
|
|
80
|
+
auto-height
|
|
81
|
+
>
|
|
82
|
+
<!-- Header Action Bar -->
|
|
83
|
+
<template #headerLeft>
|
|
84
|
+
<c-async-button type="primary" :on-click="handleAdd">
|
|
85
|
+
新增用户
|
|
86
|
+
</c-async-button>
|
|
87
|
+
<el-button
|
|
88
|
+
type="danger"
|
|
89
|
+
:disabled="selectedRows.length === 0"
|
|
90
|
+
@click="handleBatchDelete(selectedRows)"
|
|
91
|
+
>
|
|
92
|
+
批量删除
|
|
93
|
+
</el-button>
|
|
94
|
+
</template>
|
|
95
|
+
|
|
96
|
+
<!-- Custom Actions Column Slot -->
|
|
97
|
+
<template #actions="{ row }">
|
|
98
|
+
<el-button link type="primary" @click="handleEdit(row)">编辑</el-button>
|
|
99
|
+
<el-button link type="warning" @click="changeState(row)">
|
|
100
|
+
{{ row.status === 1 ? '停用' : '启用' }}
|
|
101
|
+
</el-button>
|
|
102
|
+
<el-button link type="danger" @click="handleDelete(row)">删除</el-button>
|
|
103
|
+
</template>
|
|
104
|
+
</c-simple-table>
|
|
105
|
+
</div>
|
|
106
|
+
</template>
|
|
107
|
+
|
|
108
|
+
<script setup lang="ts">
|
|
109
|
+
import { ref, computed } from 'vue'
|
|
110
|
+
import {
|
|
111
|
+
CSimpleTable,
|
|
112
|
+
CSearchBox,
|
|
113
|
+
CAsyncButton,
|
|
114
|
+
SearchFieldFactory,
|
|
115
|
+
useListPage,
|
|
116
|
+
type TableColumn
|
|
117
|
+
} from 'c-admin-kit'
|
|
118
|
+
import {
|
|
119
|
+
getUserListApi,
|
|
120
|
+
deleteUserApi,
|
|
121
|
+
batchDeleteUserApi,
|
|
122
|
+
changeUserStatusApi
|
|
123
|
+
} from '@/api/user'
|
|
124
|
+
|
|
125
|
+
const selectedRows = ref<any[]>([])
|
|
126
|
+
|
|
127
|
+
// 1. Standard CRUD Workflow Hook
|
|
128
|
+
const {
|
|
129
|
+
tableRef,
|
|
130
|
+
handleSearch,
|
|
131
|
+
handleReset,
|
|
132
|
+
handleDelete,
|
|
133
|
+
handleBatchDelete,
|
|
134
|
+
changeState,
|
|
135
|
+
handleAdd,
|
|
136
|
+
handleEdit
|
|
137
|
+
} = useListPage({
|
|
138
|
+
apiList: getUserListApi,
|
|
139
|
+
apiDelete: deleteUserApi,
|
|
140
|
+
apiBatchDelete: batchDeleteUserApi,
|
|
141
|
+
apiChangeState: changeUserStatusApi,
|
|
142
|
+
addPath: '/user/add',
|
|
143
|
+
editPath: '/user/edit'
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
// 2. Search Fields Declaration via Factory
|
|
147
|
+
const searchFields = computed(() => [
|
|
148
|
+
SearchFieldFactory.input({ prop: 'keyword', label: '关键词' }),
|
|
149
|
+
SearchFieldFactory.select({
|
|
150
|
+
prop: 'status',
|
|
151
|
+
label: '状态',
|
|
152
|
+
options: [
|
|
153
|
+
{ label: '启用', value: 1 },
|
|
154
|
+
{ label: '停用', value: 0 }
|
|
155
|
+
]
|
|
156
|
+
}),
|
|
157
|
+
SearchFieldFactory.dateRange({ prop: 'createTime', label: '创建时间' })
|
|
158
|
+
])
|
|
159
|
+
|
|
160
|
+
// 3. Columns Declaration (Supports dot-path nested properties like 'dept.name')
|
|
161
|
+
const columns: TableColumn[] = [
|
|
162
|
+
{ type: 'selection' },
|
|
163
|
+
{ type: 'index', label: '序号' },
|
|
164
|
+
{ prop: 'username', label: '用户名' },
|
|
165
|
+
{ prop: 'department.name', label: '所属部门' },
|
|
166
|
+
{ prop: 'status', label: '状态', type: 'status' },
|
|
167
|
+
{ prop: 'createTime', label: '创建时间' },
|
|
168
|
+
{ label: '操作', slot: 'actions', width: 180, fixed: 'right' }
|
|
169
|
+
]
|
|
170
|
+
</script>
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## 🧩 Component API & Contracts
|
|
176
|
+
|
|
177
|
+
### 1. `CSimpleTable` (`<c-simple-table>`)
|
|
178
|
+
- **Props**:
|
|
179
|
+
- `api`: `(params: Record<string, any>) => Promise<any>` - The API function to load page data.
|
|
180
|
+
- `columns`: `TableColumn[]` - Column definitions.
|
|
181
|
+
- `tableKey`: `string` - Unique identifier for column settings persistence.
|
|
182
|
+
- `autoHeight`: `boolean` - Automatically stretch to fill the viewport without page scrollbars (default `false`).
|
|
183
|
+
- `emptyCellText`: `string` - Placeholder for empty cell values (default `"-"`).
|
|
184
|
+
- `dragSort`: `boolean` - Enable drag-and-drop row sorting.
|
|
185
|
+
- `showPagination`: `boolean` - (default `true`).
|
|
186
|
+
- `params`: `Record<string, any>` - Static query parameters merged into fetch requests.
|
|
187
|
+
- **Column Properties (`TableColumn`)**:
|
|
188
|
+
- `prop`: string (supports dot path like `"user.profile.name"`).
|
|
189
|
+
- `label`: string.
|
|
190
|
+
- `type`: `'selection' | 'index' | 'status' | 'drag'`.
|
|
191
|
+
- `slot`: string (custom cell slot name).
|
|
192
|
+
- `formatter`: `(row, col, value, index) => string`.
|
|
193
|
+
- `render`: `(row, col, index) => VNode`.
|
|
194
|
+
- **Slots**:
|
|
195
|
+
- `#headerLeft`: Content on top-left (e.g. Add, Batch Delete).
|
|
196
|
+
- `#headerRight`: Content on top-right (e.g. Export, Custom Buttons).
|
|
197
|
+
- `#[column.slot]`: Custom column body cell slot with `{ row, column, $index }`.
|
|
198
|
+
|
|
199
|
+
### 2. `CSearchBox` (`<c-search-box>`)
|
|
200
|
+
- **Props**:
|
|
201
|
+
- `fields`: `SearchField[]` generated by `SearchFieldFactory`.
|
|
202
|
+
- `fieldsPerRow`: `number` (default `4`).
|
|
203
|
+
- `defaultExpanded`: `boolean` (default `false`).
|
|
204
|
+
- **Events**:
|
|
205
|
+
- `@search`: `(params: Record<string, any>) => void`
|
|
206
|
+
- `@reset`: `(params: Record<string, any>) => void`
|
|
207
|
+
- `@field-change`: `({ prop, value, form }) => void`
|
|
208
|
+
|
|
209
|
+
### 3. `CAsyncButton` (`<c-async-button>`)
|
|
210
|
+
- **Props**:
|
|
211
|
+
- `:on-click`: `(e: MouseEvent) => Promise<any> | any` - When it returns a Promise or Thenable, the button automatically activates `loading` and disables itself until completion.
|
|
212
|
+
|
|
213
|
+
### 4. `CCollapsibleContainer` (`<c-collapsible-container>`)
|
|
214
|
+
- **Slots**: `#left`, `#right`.
|
|
215
|
+
- **Props**: `defaultWidth: number` (default 240), `minWidth: number`, `maxWidth: number`.
|
|
216
|
+
|
|
217
|
+
### 5. `CCustomDrawer` (`<c-custom-drawer>`)
|
|
218
|
+
- **Props**: `v-model: boolean`, `title: string`, `size: string`, `confirmLoading: boolean`, `showFooter: boolean`.
|
|
219
|
+
- **Events**: `@confirm`, `@cancel`, `@close`.
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## 🛠️ Composables Cheat Sheet
|
|
224
|
+
|
|
225
|
+
### `useListPage(options)`
|
|
226
|
+
- Automatically coordinates `CSearchBox` and `CSimpleTable`.
|
|
227
|
+
- Call `tableRef.value.refresh()` or `handleSearch()` to trigger reloads.
|
|
228
|
+
- Call `handleDelete(row)` to trigger a standard danger confirmation modal before calling `apiDelete`.
|
|
229
|
+
- Call `handleBatchDelete(rows)` with `apiBatchDelete` or `apiDelete.batch`.
|
|
230
|
+
|
|
231
|
+
### `useForm(options)`
|
|
232
|
+
- `submit(apiCall, successMsg, customTransform)`:
|
|
233
|
+
1. Validates form with `formRef.value.validate()`.
|
|
234
|
+
2. Blocks if validation fails.
|
|
235
|
+
3. Turns `loading.value = true`.
|
|
236
|
+
4. Calls `apiCall(formData)` and notifies success with `ElMessage.success`.
|
|
237
|
+
- `reset()`: Resets fields and validation states safely.
|
|
238
|
+
|
|
239
|
+
### `useDownload(apiFn, options)`
|
|
240
|
+
- `const { download, downloading } = useDownload(exportApi, { filename: 'Report' })`
|
|
241
|
+
- Automatically reads `content-disposition` from headers to name the download file.
|
|
242
|
+
- Exposes `downloading: Ref<boolean>` for button loading status.
|
|
243
|
+
|
|
244
|
+
### `treeManager`
|
|
245
|
+
- `listToTree(flatArray, { id: 'id', pid: 'parentId', children: 'children' })`: O(n) Hash Map converter.
|
|
246
|
+
- `treeToList(tree)`: Flattens hierarchical tree back to array.
|
|
247
|
+
- `findParentNodes(tree, targetId)`: Returns array of ancestor nodes from root down to matched item.
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## 🚫 Anti-Patterns (What AI Should NEVER Do)
|
|
252
|
+
|
|
253
|
+
- ❌ **DO NOT** use native `<el-table>` for standard CRUD pages when `c-simple-table` is available.
|
|
254
|
+
- ❌ **DO NOT** handwrite repetitive `pageSize`, `pageNum`, `currentPage` reactive variables; let `useListPage` and `c-simple-table` manage them.
|
|
255
|
+
- ❌ **DO NOT** bind plain `@click` with manual `loading = true / false` on buttons when `<c-async-button :on-click="...">` can handle it declaratively.
|
|
256
|
+
- ❌ **DO NOT** use un-prefixed tags like `<simple-table>`. Always prefix with `<c-simple-table>`.
|
package/README.md
CHANGED
|
@@ -1,110 +1,115 @@
|
|
|
1
|
-
# C-Admin-Kit
|
|
1
|
+
# C-Admin-Kit
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="https://img.shields.io/npm/v/c-admin-kit?color=409EFF&label=npm" alt="npm version" />
|
|
5
|
+
<img src="https://img.shields.io/npm/dm/c-admin-kit?color=67C23A&label=downloads" alt="downloads" />
|
|
6
|
+
<img src="https://img.shields.io/badge/Vue-3.3+-42b883?logo=vue.js" alt="vue" />
|
|
7
|
+
<img src="https://img.shields.io/badge/Element--Plus-2.3+-409EFF?logo=element" alt="element-plus" />
|
|
8
|
+
<img src="https://img.shields.io/badge/TypeScript-100%25-3178c6?logo=typescript" alt="typescript" />
|
|
9
|
+
<img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="license" />
|
|
10
|
+
</p>
|
|
4
11
|
|
|
5
|
-
|
|
12
|
+
`c-admin-kit` 是一套专为企业级中后台打造的高阶通用组件与 Hooks 套件。基于 **Vue 3 + Element Plus + TypeScript** 构建,提供成熟的标准 CRUD 流程封装、配置化高级表格、多条件搜索工厂、异步防重按钮、平滑拖拽分栏及常用树形数据工具函数。
|
|
13
|
+
|
|
14
|
+
> 📌 **团队规范约束**:为彻底避免多工程复用时的组件同名冲突,所有组件**统一且固定强制使用 `c-` / `C` 前缀**(如 `<c-simple-table>`、`<c-search-box>`),开箱即用,代码风格统一。
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## ✨ 核心特性
|
|
19
|
+
|
|
20
|
+
- 🛡️ **100% TypeScript**:源码全量 TS 编写,严格类型定义,类型提示精确到组件 Props、Emits、Slots 及 Hook 泛型。
|
|
21
|
+
- ⚡ **轻量纯净**:以 `peerDependencies` 消费宿主环境的 `vue`、`element-plus`,打包体积仅几十 KB,无多余冗余包,完美继承宿主主题变量。
|
|
22
|
+
- 🎯 **开箱即用**:自带企业级增删改查最佳实践,配合 `useListPage` 与 `SearchFieldFactory`,10 余行代码即可完成完整页面。
|
|
23
|
+
- 🌲 **Tree-Shaking**:支持全量安装与细粒度子路径按需导入,生产构建零多余冗余代码。
|
|
6
24
|
|
|
7
25
|
---
|
|
8
26
|
|
|
9
|
-
##
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
└── README.md
|
|
27
|
+
## 📥 安装
|
|
28
|
+
|
|
29
|
+
在您的 Vue 3 + Element Plus 工程中执行:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# 推荐使用 pnpm
|
|
33
|
+
pnpm add c-admin-kit
|
|
34
|
+
|
|
35
|
+
# 或者 npm / yarn
|
|
36
|
+
npm install c-admin-kit
|
|
37
|
+
yarn add c-admin-kit
|
|
21
38
|
```
|
|
22
39
|
|
|
40
|
+
> ⚠️ **前置依赖**:请确保项目已安装 `vue (>= 3.3.0)` 与 `element-plus (>= 2.3.0)`。
|
|
41
|
+
|
|
23
42
|
---
|
|
24
43
|
|
|
25
44
|
## 🚀 快速上手
|
|
26
45
|
|
|
27
|
-
### 1. 全局完整引入 (main.js)
|
|
46
|
+
### 1. 全局完整引入 (`main.ts` / `main.js`)
|
|
28
47
|
|
|
29
|
-
```
|
|
48
|
+
```typescript
|
|
30
49
|
import { createApp } from 'vue'
|
|
31
50
|
import ElementPlus from 'element-plus'
|
|
32
51
|
import 'element-plus/dist/index.css'
|
|
33
|
-
import App from './App.vue'
|
|
34
52
|
|
|
35
|
-
// 引入 c-admin-kit
|
|
36
53
|
import CAdminKit from 'c-admin-kit'
|
|
37
|
-
|
|
38
|
-
|
|
54
|
+
import 'c-admin-kit/dist/c-admin-kit.css'
|
|
55
|
+
|
|
56
|
+
import App from './App.vue'
|
|
39
57
|
|
|
40
58
|
const app = createApp(App)
|
|
41
59
|
app.use(ElementPlus)
|
|
42
|
-
app.use(CAdminKit) //
|
|
60
|
+
app.use(CAdminKit) // 自动全局注册所有 c- 开头组件
|
|
43
61
|
app.mount('#app')
|
|
44
62
|
```
|
|
45
63
|
|
|
46
|
-
### 2.
|
|
64
|
+
### 2. 按需局部引入 (推荐)
|
|
65
|
+
|
|
66
|
+
组件与 Hooks 均支持解构引入或子路径导入:
|
|
47
67
|
|
|
48
68
|
```vue
|
|
49
69
|
<template>
|
|
50
|
-
<c-search-box :fields="searchFields" @search="handleSearch" />
|
|
51
|
-
<c-simple-table ref="tableRef" :api="
|
|
70
|
+
<c-search-box :fields="searchFields" @search="handleSearch" @reset="handleReset" />
|
|
71
|
+
<c-simple-table ref="tableRef" :api="getUserListApi" :columns="columns" auto-height />
|
|
52
72
|
</template>
|
|
53
73
|
|
|
54
|
-
<script setup>
|
|
55
|
-
import { CSearchBox, CSimpleTable } from 'c-admin-kit'
|
|
56
|
-
import
|
|
57
|
-
import { useListPage } from 'c-admin-kit'
|
|
74
|
+
<script setup lang="ts">
|
|
75
|
+
import { CSearchBox, CSimpleTable, SearchFieldFactory, useListPage } from 'c-admin-kit'
|
|
76
|
+
import 'c-admin-kit/dist/c-admin-kit.css'
|
|
58
77
|
|
|
59
|
-
//
|
|
78
|
+
// 亦支持按子路径引用:
|
|
60
79
|
// import { CSimpleTable } from 'c-admin-kit/components'
|
|
61
|
-
// import { useListPage } from 'c-admin-kit/
|
|
80
|
+
// import { useListPage } from 'c-admin-kit/composables'
|
|
62
81
|
// import { SearchFieldFactory } from 'c-admin-kit/utils'
|
|
63
82
|
</script>
|
|
64
83
|
```
|
|
65
84
|
|
|
66
85
|
---
|
|
67
86
|
|
|
68
|
-
##
|
|
69
|
-
|
|
70
|
-
| 组件名 (PascalCase) | 模板标签 (kebab-case) | 功能描述 |
|
|
71
|
-
| :--- | :--- | :--- |
|
|
72
|
-
| **`CSimpleTable`** | `<c-simple-table>` | 800+ 行高级配置化表格:支持拖拽排序、列自定义显隐(本地缓存/API持久化)、动态自适应全屏高度、分页联动。 |
|
|
73
|
-
| **`CSearchBox`** | `<c-search-box>` | 高阶配置化多条件表单搜索栏:支持响应式栅格、展开/收起两行、级联依赖、回车搜索。 |
|
|
74
|
-
| **`CAsyncButton`** | `<c-async-button>` | 异步按钮:自动识别 Promise 并开启 loading,防止重复点击。 |
|
|
75
|
-
| **`CSelectWithAll`** | `<c-select-with-all>` | 支持全选/半选/反选与防抖远程搜索的增强下拉框。 |
|
|
76
|
-
| **`CSelectWithPage`**| `<c-select-with-page>`| 支持分页数据源、参数化键值对(`labelKey`/`valueKey`)与远程搜索的下拉框。 |
|
|
77
|
-
| **`CCollapsibleContainer`** | `<c-collapsible-container>` | 左右双栏布局容器:支持鼠标按住分隔线拖拽缩放宽度、一键收起折叠。 |
|
|
78
|
-
| **`CCustomDrawer`** | `<c-custom-drawer>` | 二次封装 el-drawer,标准化底部取消/确定按钮与事件流。 |
|
|
79
|
-
| **`CDiff`** | `<c-diff>` | 纯前端字符级与行级文本/代码 Diff 对比可视化组件。 |
|
|
80
|
-
| **`CImagePreview`** | `<c-image-preview>` | 缩略图展示与大图预览包装组件。 |
|
|
81
|
-
|
|
82
|
-
---
|
|
83
|
-
|
|
84
|
-
## 🌟 黄金组合:10行代码搞定企业级增删改查页
|
|
87
|
+
## 🌟 黄金组合:10 行代码实现企业级标准 CRUD 页面
|
|
85
88
|
|
|
86
|
-
结合 `SearchFieldFactory`、`useListPage` 与 `
|
|
89
|
+
结合 `SearchFieldFactory`、`useListPage`、`CSearchBox` 与 `CSimpleTable`,告别繁重重复模板:
|
|
87
90
|
|
|
88
91
|
```vue
|
|
89
92
|
<template>
|
|
90
93
|
<div class="page-container">
|
|
91
|
-
<!-- 1.
|
|
94
|
+
<!-- 1. 结构化搜索栏 -->
|
|
92
95
|
<c-search-box
|
|
93
96
|
:fields="searchFields"
|
|
94
97
|
@search="handleSearch"
|
|
95
98
|
@reset="handleReset"
|
|
96
99
|
/>
|
|
97
100
|
|
|
98
|
-
<!-- 2.
|
|
101
|
+
<!-- 2. 高阶自适应表格 -->
|
|
99
102
|
<c-simple-table
|
|
100
103
|
ref="tableRef"
|
|
101
104
|
:api="getUserListApi"
|
|
102
105
|
:columns="columns"
|
|
103
|
-
table-key="
|
|
106
|
+
table-key="user_management_table"
|
|
104
107
|
auto-height
|
|
105
108
|
>
|
|
109
|
+
<!-- 头部操作区 -->
|
|
106
110
|
<template #headerLeft>
|
|
107
111
|
<el-button type="primary" @click="handleAdd">新增用户</el-button>
|
|
112
|
+
<el-button type="danger" @click="handleBatchDelete">批量删除</el-button>
|
|
108
113
|
</template>
|
|
109
114
|
|
|
110
115
|
<!-- 操作列插槽 -->
|
|
@@ -116,117 +121,189 @@ import { useListPage } from 'c-admin-kit'
|
|
|
116
121
|
</div>
|
|
117
122
|
</template>
|
|
118
123
|
|
|
119
|
-
<script setup>
|
|
124
|
+
<script setup lang="ts">
|
|
120
125
|
import { computed } from 'vue'
|
|
121
|
-
import {
|
|
122
|
-
CSearchBox,
|
|
123
|
-
CSimpleTable,
|
|
124
|
-
SearchFieldFactory,
|
|
125
|
-
useListPage
|
|
126
|
+
import {
|
|
127
|
+
CSearchBox,
|
|
128
|
+
CSimpleTable,
|
|
129
|
+
SearchFieldFactory,
|
|
130
|
+
useListPage,
|
|
131
|
+
type TableColumn
|
|
126
132
|
} from 'c-admin-kit'
|
|
127
|
-
import {
|
|
128
|
-
|
|
129
|
-
|
|
133
|
+
import {
|
|
134
|
+
getUserListApi,
|
|
135
|
+
deleteUserApi,
|
|
136
|
+
batchDeleteUserApi,
|
|
137
|
+
changeUserStatusApi
|
|
138
|
+
} from '@/api/user'
|
|
139
|
+
|
|
140
|
+
// 1. 标准流程控制 Hook (集成搜索联动、分页维护、单条/批量删除、状态切换、详情/新增路由)
|
|
130
141
|
const {
|
|
131
142
|
tableRef,
|
|
132
143
|
handleSearch,
|
|
133
144
|
handleReset,
|
|
134
145
|
handleDelete,
|
|
146
|
+
handleBatchDelete,
|
|
135
147
|
handleAdd,
|
|
136
148
|
handleEdit
|
|
137
149
|
} = useListPage({
|
|
138
150
|
apiList: getUserListApi,
|
|
139
151
|
apiDelete: deleteUserApi,
|
|
152
|
+
apiBatchDelete: batchDeleteUserApi,
|
|
140
153
|
apiChangeState: changeUserStatusApi,
|
|
141
154
|
addPath: '/user/add',
|
|
142
155
|
editPath: '/user/edit'
|
|
143
156
|
})
|
|
144
157
|
|
|
145
|
-
//
|
|
158
|
+
// 2. 搜索字段快速配置工厂 (支持 input、select、dateRange、cascader、级联联动等)
|
|
146
159
|
const searchFields = computed(() => [
|
|
147
|
-
SearchFieldFactory.input({ prop: '
|
|
160
|
+
SearchFieldFactory.input({ prop: 'keyword', label: '关键词' }),
|
|
148
161
|
SearchFieldFactory.select({
|
|
149
162
|
prop: 'status',
|
|
150
163
|
label: '状态',
|
|
151
164
|
options: [
|
|
152
|
-
{ label: '
|
|
165
|
+
{ label: '启用', value: 1 },
|
|
153
166
|
{ label: '停用', value: 0 }
|
|
154
167
|
]
|
|
155
168
|
}),
|
|
156
169
|
SearchFieldFactory.dateRange({ prop: 'createTime', label: '创建时间' })
|
|
157
170
|
])
|
|
158
171
|
|
|
159
|
-
//
|
|
160
|
-
const columns = [
|
|
172
|
+
// 3. 表格列配置 (原生支持 user.name 深度路径取值、空值 '-' 占位、拖拽排序、自定义列持久化)
|
|
173
|
+
const columns: TableColumn[] = [
|
|
161
174
|
{ type: 'selection' },
|
|
162
175
|
{ type: 'index', label: '序号' },
|
|
163
176
|
{ prop: 'username', label: '用户名' },
|
|
177
|
+
{ prop: 'department.name', label: '所属部门' }, // 支持嵌套深度字段
|
|
164
178
|
{ prop: 'status', label: '状态', type: 'status' },
|
|
165
179
|
{ prop: 'createTime', label: '创建时间' },
|
|
166
|
-
{ label: '操作', slot: 'actions', width:
|
|
180
|
+
{ label: '操作', slot: 'actions', width: 150, fixed: 'right' }
|
|
167
181
|
]
|
|
168
182
|
</script>
|
|
169
183
|
```
|
|
170
184
|
|
|
171
185
|
---
|
|
172
186
|
|
|
173
|
-
##
|
|
187
|
+
## 🧩 组件清单 (Components)
|
|
188
|
+
|
|
189
|
+
| 组件名 | 标签名称 | 功能特性 |
|
|
190
|
+
| :--- | :--- | :--- |
|
|
191
|
+
| **`CSimpleTable`** | `<c-simple-table>` | **高阶企业级表格**:集成拖拽排序、列自定义显隐(本地缓存/API持久化)、动态视口全屏自适应高度、嵌套属性链式取值(`dept.name`)、空单元格占位、分页联动。 |
|
|
192
|
+
| **`CSearchBox`** | `<c-search-box>` | **配置化多条件搜索栏**:响应式栅格自适应、一键展开/收起、级联下拉异步联动、回车快捷搜索、自定义插槽扩展。 |
|
|
193
|
+
| **`CAsyncButton`** | `<c-async-button>` | **异步防重按钮**:自动感知 Promise / Thenable 异步任务并开启 loading,阻断连续点击,结束自动恢复。 |
|
|
194
|
+
| **`CCollapsibleContainer`** | `<c-collapsible-container>` | **左右双栏拖拽折叠布局**:支持鼠标拖拽分隔线缩放面板宽度(消除了微动效冲突,拖拽丝滑),支持一键折叠收起。 |
|
|
195
|
+
| **`CCustomDrawer`** | `<c-custom-drawer>` | **标准化企业级抽屉**:统一底部确定/取消操作栏,内置确定按钮 `confirmLoading` 状态与 `computed` 双向绑定。 |
|
|
196
|
+
| **`CImagePreview`** | `<c-image-preview>` | **缩略图与大图预览**:支持单图 URL、逗号分隔多图字符串及数组入参,内置安全容错清洗与缩略图悬浮动效。 |
|
|
197
|
+
| **`CDiff`** | `<c-diff>` | **文本代码 Diff 视图**:纯前端实现基于编辑距离与相似度的字符级与行级差异可视化高亮。 |
|
|
198
|
+
| **`CSelectWithAll`** | `<c-select-with-all>` | **全选下拉选择器**:支持一键全选/全不选、半选状态判断及防抖远程搜索。 |
|
|
199
|
+
| **`CSelectWithPage`**| `<c-select-with-page>`| **大数据分页下拉**:支持自定义键值字段、关键词远程搜索与海量选项分页加载。 |
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## 🛠️ 组合式函数 (Composables / Hooks)
|
|
204
|
+
|
|
205
|
+
### 1. `useListPage` (标准列表页流程控制)
|
|
206
|
+
管理列表搜索、刷新、分页、状态切换、单条/批量删除及路由跳转:
|
|
207
|
+
```typescript
|
|
208
|
+
const {
|
|
209
|
+
tableRef,
|
|
210
|
+
searchParams,
|
|
211
|
+
handleSearch,
|
|
212
|
+
handleReset,
|
|
213
|
+
handleDelete,
|
|
214
|
+
handleBatchDelete,
|
|
215
|
+
changeState,
|
|
216
|
+
exportExcel
|
|
217
|
+
} = useListPage({
|
|
218
|
+
apiList: getListApi,
|
|
219
|
+
apiDelete: deleteApi,
|
|
220
|
+
apiBatchDelete: batchDeleteApi, // 可选独立批量删除接口
|
|
221
|
+
apiChangeState: updateStatusApi,
|
|
222
|
+
apiExport: exportApi
|
|
223
|
+
})
|
|
224
|
+
```
|
|
174
225
|
|
|
175
|
-
###
|
|
176
|
-
|
|
177
|
-
```
|
|
178
|
-
const { formRef, formData, loading, submit, reset } = useForm({
|
|
179
|
-
initFormData: { name: '',
|
|
226
|
+
### 2. `useForm` (表单状态与提交流程)
|
|
227
|
+
封装表单数据响应式模型、自动校验拦截与提交状态:
|
|
228
|
+
```typescript
|
|
229
|
+
const { formRef, formData, loading, submit, reset, setFormData } = useForm({
|
|
230
|
+
initFormData: { name: '', roleId: null }
|
|
180
231
|
})
|
|
181
232
|
|
|
182
|
-
//
|
|
233
|
+
// 提交时自动触发 form.validate(),校验失败自动提示并阻断,成功触发 loading 并调用 API
|
|
183
234
|
await submit(async (data) => await saveApi(data), '保存成功')
|
|
184
235
|
```
|
|
185
236
|
|
|
186
|
-
###
|
|
187
|
-
|
|
188
|
-
```
|
|
189
|
-
const
|
|
237
|
+
### 3. `useDownload` (安全文件导出与下载)
|
|
238
|
+
安全导出二进制文件,导出 `downloading` 响应式状态,自动从响应头提取文件名:
|
|
239
|
+
```typescript
|
|
240
|
+
const { download, downloading } = useDownload(exportApi, {
|
|
241
|
+
filename: '用户报表'
|
|
242
|
+
})
|
|
243
|
+
|
|
244
|
+
// 外部按钮可直接绑定 loading
|
|
245
|
+
// <el-button :loading="downloading" @click="download({ deptId: 1 })">导出</el-button>
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### 4. `useConfirmAction` & `useConfirmSubmit` (操作二次确认)
|
|
249
|
+
消除重复的 `ElMessageBox.confirm` 模板代码:
|
|
250
|
+
```typescript
|
|
251
|
+
const handleRemove = useConfirmSubmit(
|
|
190
252
|
async (id) => await deleteApi(id),
|
|
191
253
|
() => tableRef.value.refresh(),
|
|
192
|
-
{ message: '
|
|
254
|
+
{ message: '确定要永久删除该记录吗?' }
|
|
193
255
|
)
|
|
194
256
|
```
|
|
195
257
|
|
|
196
|
-
###
|
|
197
|
-
|
|
198
|
-
```
|
|
199
|
-
const {
|
|
200
|
-
await download({ keyword: 'test' })
|
|
258
|
+
### 5. `useDialog` (弹窗显隐与上下文传递)
|
|
259
|
+
优雅管理模态弹窗的开启、关闭与行数据传递:
|
|
260
|
+
```typescript
|
|
261
|
+
const { visible, dialogData, openDialog, closeDialog } = useDialog()
|
|
201
262
|
```
|
|
202
263
|
|
|
203
264
|
---
|
|
204
265
|
|
|
205
|
-
##
|
|
266
|
+
## 🧰 实用工具库 (Utils)
|
|
267
|
+
|
|
268
|
+
### 1. `SearchFieldFactory` (搜索字段工厂)
|
|
269
|
+
规范化、声明式生成搜索栏配置:
|
|
270
|
+
```typescript
|
|
271
|
+
import { SearchFieldFactory, CommonSearchFields } from 'c-admin-kit'
|
|
272
|
+
|
|
273
|
+
const fields = [
|
|
274
|
+
SearchFieldFactory.input({ prop: 'title', label: '标题' }),
|
|
275
|
+
SearchFieldFactory.select({ prop: 'status', label: '状态', options: [...] }),
|
|
276
|
+
SearchFieldFactory.dateRange({ prop: 'createTime', label: '创建时间' }),
|
|
277
|
+
SearchFieldFactory.cascader({ prop: 'deptId', label: '部门', options: [...] }),
|
|
278
|
+
// 常用预设快捷字段
|
|
279
|
+
CommonSearchFields.keyword(),
|
|
280
|
+
CommonSearchFields.status([...])
|
|
281
|
+
]
|
|
282
|
+
```
|
|
206
283
|
|
|
207
|
-
|
|
284
|
+
### 2. `treeManager` (高性能树结构处理)
|
|
285
|
+
```typescript
|
|
286
|
+
import {
|
|
287
|
+
listToTree,
|
|
288
|
+
treeToList,
|
|
289
|
+
findTreeNode,
|
|
290
|
+
findParentNodes,
|
|
291
|
+
filterTree,
|
|
292
|
+
mapTree
|
|
293
|
+
} from 'c-admin-kit'
|
|
208
294
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
git init
|
|
215
|
-
git add .
|
|
216
|
-
git commit -m "feat: init c-admin-kit package"
|
|
217
|
-
|
|
218
|
-
# 3. 关联远程仓库并推送
|
|
219
|
-
git remote add origin https://your-git-server.com/frontend/c-admin-kit.git
|
|
220
|
-
git branch -M main
|
|
221
|
-
git push -u origin main
|
|
222
|
-
```
|
|
295
|
+
// 1. 扁平数组一键转树 (时间复杂度 O(n) Hash Map 算法)
|
|
296
|
+
const tree = listToTree(flatList, { id: 'id', pid: 'parentId', children: 'children' })
|
|
297
|
+
|
|
298
|
+
// 2. 根据节点 ID 查找包含自身和所有上级父节点的完整链条
|
|
299
|
+
const parentNodes = findParentNodes(tree, targetId)
|
|
223
300
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
{
|
|
227
|
-
"dependencies": {
|
|
228
|
-
"c-admin-kit": "git+https://your-git-server.com/frontend/c-admin-kit.git"
|
|
229
|
-
}
|
|
230
|
-
}
|
|
301
|
+
// 3. 树结构过滤(保留命中节点及其祖先链路)
|
|
302
|
+
const filteredTree = filterTree(tree, (node) => node.name.includes('技术部'))
|
|
231
303
|
```
|
|
232
|
-
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
## 📄 授权协议
|
|
308
|
+
|
|
309
|
+
[MIT License](file:///e:/售后项目/admin-kit/LICENSE) © 2026 [wllcyg](https://github.com/wllcyg)
|
package/llms.txt
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# c-admin-kit
|
|
2
|
+
> High-level enterprise admin UI suite & composables built on Vue 3 + Element Plus + TypeScript.
|
|
3
|
+
|
|
4
|
+
## Rules
|
|
5
|
+
- All components MUST be prefixed with `c-` in template (e.g. `<c-simple-table>`, `<c-search-box>`, `<c-async-button>`).
|
|
6
|
+
- Always prioritize `SearchFieldFactory` and `useListPage` to implement standard admin CRUD list pages.
|
|
7
|
+
- Use `<c-async-button :on-click="fn">` for declarative async actions with automatic loading states.
|
|
8
|
+
|
|
9
|
+
## Key Modules
|
|
10
|
+
- `CSimpleTable`: Advanced table with column settings, auto-height, and pagination.
|
|
11
|
+
- `CSearchBox`: Structured search form with responsive grid and cascade options.
|
|
12
|
+
- `SearchFieldFactory`: Declarative factory for search fields (`input`, `select`, `dateRange`).
|
|
13
|
+
- `useListPage`: Composable for search, pagination, delete, and route coordination.
|
|
14
|
+
- `useForm`: Composable for form submission, validation, and reset.
|
|
15
|
+
- `useDownload`: Composable for file export with `downloading` status and filename auto-detect.
|
|
16
|
+
- `treeManager`: Utilities for `listToTree` (O(n)), `treeToList`, and `findParentNodes`.
|
|
17
|
+
|
|
18
|
+
## Detailed Guidelines & Golden Pattern
|
|
19
|
+
See [LLMS.md](./LLMS.md) for full contracts, component API, and standard CRUD blueprints.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "c-admin-kit",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "基于 Vue 3 + Element Plus 的中后台企业级高阶通用组件与 Hooks 套件(强制使用 c- 前缀)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/c-admin-kit.umd.cjs",
|
|
@@ -37,7 +37,9 @@
|
|
|
37
37
|
"files": [
|
|
38
38
|
"dist",
|
|
39
39
|
"src",
|
|
40
|
-
"README.md"
|
|
40
|
+
"README.md",
|
|
41
|
+
"LLMS.md",
|
|
42
|
+
"llms.txt"
|
|
41
43
|
],
|
|
42
44
|
"keywords": [
|
|
43
45
|
"vue3",
|