c-admin-kit 1.0.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.
- package/README.md +232 -0
- package/dist/c-admin-kit.css +1 -0
- package/dist/c-admin-kit.js +2482 -0
- package/dist/c-admin-kit.umd.cjs +10 -0
- package/dist/components/AsyncButton/index.vue.d.ts +48 -0
- package/dist/components/CollapsibleContainer/index.vue.d.ts +73 -0
- package/dist/components/CustomDrawer/index.vue.d.ts +149 -0
- package/dist/components/ImagePreview/index.vue.d.ts +34 -0
- package/dist/components/SearchBox/index.vue.d.ts +122 -0
- package/dist/components/SelectWithAll/index.vue.d.ts +169 -0
- package/dist/components/SelectWithPage/index.vue.d.ts +78 -0
- package/dist/components/SimpleTable/index.vue.d.ts +337 -0
- package/dist/components/SimpleTable/useTableColumnConfig.d.ts +5 -0
- package/dist/components/diff/index.vue.d.ts +33 -0
- package/dist/components/index.d.ts +12 -0
- package/dist/composables/index.d.ts +6 -0
- package/dist/composables/useConfirmAction.d.ts +5 -0
- package/dist/composables/useConfirmSubmit.d.ts +5 -0
- package/dist/composables/useDialog.d.ts +5 -0
- package/dist/composables/useDownload.d.ts +5 -0
- package/dist/composables/useForm.d.ts +5 -0
- package/dist/composables/useListPage.d.ts +5 -0
- package/dist/index.d.ts +9 -0
- package/dist/types.d.ts +282 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/scroll-to.d.ts +7 -0
- package/dist/utils/searchFieldFactory.d.ts +34 -0
- package/dist/utils/treeManager.d.ts +64 -0
- package/dist/utils/validate.d.ts +30 -0
- package/package.json +86 -0
- package/src/components/AsyncButton/index.vue +58 -0
- package/src/components/CollapsibleContainer/index.vue +240 -0
- package/src/components/CustomDrawer/index.vue +167 -0
- package/src/components/ImagePreview/index.vue +88 -0
- package/src/components/SearchBox/index.vue +582 -0
- package/src/components/SelectWithAll/index.vue +281 -0
- package/src/components/SelectWithPage/index.vue +204 -0
- package/src/components/SimpleTable/index.vue +781 -0
- package/src/components/SimpleTable/useTableColumnConfig.ts +139 -0
- package/src/components/diff/index.vue +265 -0
- package/src/components/index.ts +35 -0
- package/src/composables/index.ts +6 -0
- package/src/composables/useConfirmAction.ts +62 -0
- package/src/composables/useConfirmSubmit.ts +68 -0
- package/src/composables/useDialog.ts +48 -0
- package/src/composables/useDownload.ts +83 -0
- package/src/composables/useForm.ts +114 -0
- package/src/composables/useListPage.ts +243 -0
- package/src/env.d.ts +7 -0
- package/src/index.ts +44 -0
- package/src/types.ts +344 -0
- package/src/utils/index.ts +4 -0
- package/src/utils/scroll-to.ts +60 -0
- package/src/utils/searchFieldFactory.ts +302 -0
- package/src/utils/treeManager.ts +218 -0
- package/src/utils/validate.ts +64 -0
package/README.md
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# C-Admin-Kit (企业级中后台组件与通用工具套件)
|
|
2
|
+
|
|
3
|
+
`c-admin-kit` 是一套基于 **Vue 3 + Element Plus** 深度解耦的中后台高阶通用组件、配置工厂与 Hooks 工具套件。
|
|
4
|
+
|
|
5
|
+
> 📌 **团队命名规范**:为了彻底杜绝多项目复用时的全局组件同名冲突,所有组件**统一且固定强制使用 `c-` / `C` 前缀**(例如 `<c-simple-table>`, `<c-search-box>`),不支持自定义配置,保持团队代码规范高度统一。
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 📦 目录结构
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
packages/admin-kit/
|
|
13
|
+
├── src/
|
|
14
|
+
│ ├── components/ # UI 通用组件 (CSimpleTable, CSearchBox 等)
|
|
15
|
+
│ ├── composables/ # 通用 Hooks (useListPage, useForm 等)
|
|
16
|
+
│ ├── utils/ # 工具函数 (SearchFieldFactory, treeManager 等)
|
|
17
|
+
│ └── index.js # 统一主入口
|
|
18
|
+
├── package.json
|
|
19
|
+
├── vite.config.js
|
|
20
|
+
└── README.md
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 🚀 快速上手
|
|
26
|
+
|
|
27
|
+
### 1. 全局完整引入 (main.js)
|
|
28
|
+
|
|
29
|
+
```javascript
|
|
30
|
+
import { createApp } from 'vue'
|
|
31
|
+
import ElementPlus from 'element-plus'
|
|
32
|
+
import 'element-plus/dist/index.css'
|
|
33
|
+
import App from './App.vue'
|
|
34
|
+
|
|
35
|
+
// 引入 c-admin-kit
|
|
36
|
+
import CAdminKit from 'c-admin-kit'
|
|
37
|
+
// 如已打包,可引入样式
|
|
38
|
+
// import 'c-admin-kit/dist/style.css'
|
|
39
|
+
|
|
40
|
+
const app = createApp(App)
|
|
41
|
+
app.use(ElementPlus)
|
|
42
|
+
app.use(CAdminKit) // 自动注册所有 c- 开头组件
|
|
43
|
+
app.mount('#app')
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 2. 局部按需引入 (推荐)
|
|
47
|
+
|
|
48
|
+
```vue
|
|
49
|
+
<template>
|
|
50
|
+
<c-search-box :fields="searchFields" @search="handleSearch" />
|
|
51
|
+
<c-simple-table ref="tableRef" :api="apiList" :columns="columns" />
|
|
52
|
+
</template>
|
|
53
|
+
|
|
54
|
+
<script setup>
|
|
55
|
+
import { CSearchBox, CSimpleTable } from 'c-admin-kit'
|
|
56
|
+
import { SearchFieldFactory } from 'c-admin-kit'
|
|
57
|
+
import { useListPage } from 'c-admin-kit'
|
|
58
|
+
|
|
59
|
+
// 或细粒度引入:
|
|
60
|
+
// import { CSimpleTable } from 'c-admin-kit/components'
|
|
61
|
+
// import { useListPage } from 'c-admin-kit/hooks'
|
|
62
|
+
// import { SearchFieldFactory } from 'c-admin-kit/utils'
|
|
63
|
+
</script>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
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行代码搞定企业级增删改查页
|
|
85
|
+
|
|
86
|
+
结合 `SearchFieldFactory`、`useListPage` 与 `CSearchBox`、`CSimpleTable`:
|
|
87
|
+
|
|
88
|
+
```vue
|
|
89
|
+
<template>
|
|
90
|
+
<div class="page-container">
|
|
91
|
+
<!-- 1. 搜索表单 -->
|
|
92
|
+
<c-search-box
|
|
93
|
+
:fields="searchFields"
|
|
94
|
+
@search="handleSearch"
|
|
95
|
+
@reset="handleReset"
|
|
96
|
+
/>
|
|
97
|
+
|
|
98
|
+
<!-- 2. 数据表格 -->
|
|
99
|
+
<c-simple-table
|
|
100
|
+
ref="tableRef"
|
|
101
|
+
:api="getUserListApi"
|
|
102
|
+
:columns="columns"
|
|
103
|
+
table-key="user_list_table"
|
|
104
|
+
auto-height
|
|
105
|
+
>
|
|
106
|
+
<template #headerLeft>
|
|
107
|
+
<el-button type="primary" @click="handleAdd">新增用户</el-button>
|
|
108
|
+
</template>
|
|
109
|
+
|
|
110
|
+
<!-- 操作列插槽 -->
|
|
111
|
+
<template #actions="{ row }">
|
|
112
|
+
<el-button link type="primary" @click="handleEdit(row)">编辑</el-button>
|
|
113
|
+
<el-button link type="danger" @click="handleDelete(row)">删除</el-button>
|
|
114
|
+
</template>
|
|
115
|
+
</c-simple-table>
|
|
116
|
+
</div>
|
|
117
|
+
</template>
|
|
118
|
+
|
|
119
|
+
<script setup>
|
|
120
|
+
import { computed } from 'vue'
|
|
121
|
+
import {
|
|
122
|
+
CSearchBox,
|
|
123
|
+
CSimpleTable,
|
|
124
|
+
SearchFieldFactory,
|
|
125
|
+
useListPage
|
|
126
|
+
} from 'c-admin-kit'
|
|
127
|
+
import { getUserListApi, deleteUserApi, changeUserStatusApi } from '@/api/user'
|
|
128
|
+
|
|
129
|
+
// 标准 CRUD 流控制
|
|
130
|
+
const {
|
|
131
|
+
tableRef,
|
|
132
|
+
handleSearch,
|
|
133
|
+
handleReset,
|
|
134
|
+
handleDelete,
|
|
135
|
+
handleAdd,
|
|
136
|
+
handleEdit
|
|
137
|
+
} = useListPage({
|
|
138
|
+
apiList: getUserListApi,
|
|
139
|
+
apiDelete: deleteUserApi,
|
|
140
|
+
apiChangeState: changeUserStatusApi,
|
|
141
|
+
addPath: '/user/add',
|
|
142
|
+
editPath: '/user/edit'
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
// 搜索字段快速定义 (SearchFieldFactory)
|
|
146
|
+
const searchFields = computed(() => [
|
|
147
|
+
SearchFieldFactory.input({ prop: 'username', label: '用户名' }),
|
|
148
|
+
SearchFieldFactory.select({
|
|
149
|
+
prop: 'status',
|
|
150
|
+
label: '状态',
|
|
151
|
+
options: [
|
|
152
|
+
{ label: '正常', value: 1 },
|
|
153
|
+
{ label: '停用', value: 0 }
|
|
154
|
+
]
|
|
155
|
+
}),
|
|
156
|
+
SearchFieldFactory.dateRange({ prop: 'createTime', label: '创建时间' })
|
|
157
|
+
])
|
|
158
|
+
|
|
159
|
+
// 列配置
|
|
160
|
+
const columns = [
|
|
161
|
+
{ type: 'selection' },
|
|
162
|
+
{ type: 'index', label: '序号' },
|
|
163
|
+
{ prop: 'username', label: '用户名' },
|
|
164
|
+
{ prop: 'status', label: '状态', type: 'status' },
|
|
165
|
+
{ prop: 'createTime', label: '创建时间' },
|
|
166
|
+
{ label: '操作', slot: 'actions', width: 160, fixed: 'right' }
|
|
167
|
+
]
|
|
168
|
+
</script>
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## 🛠️ 组合式函数 (Hooks) 说明
|
|
174
|
+
|
|
175
|
+
### 1. `useForm`
|
|
176
|
+
管理表单数据与验证提交:
|
|
177
|
+
```javascript
|
|
178
|
+
const { formRef, formData, loading, submit, reset } = useForm({
|
|
179
|
+
initFormData: { name: '', email: '' }
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
// 提交自动开启 loading 并执行表单校验
|
|
183
|
+
await submit(async (data) => await saveApi(data), '保存成功')
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### 2. `useConfirmSubmit` & `useConfirmAction`
|
|
187
|
+
操作二次确认弹窗:
|
|
188
|
+
```javascript
|
|
189
|
+
const handleDelete = useConfirmSubmit(
|
|
190
|
+
async (id) => await deleteApi(id),
|
|
191
|
+
() => tableRef.value.refresh(),
|
|
192
|
+
{ message: '确定要永久删除该项吗?' }
|
|
193
|
+
)
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### 3. `useDownload`
|
|
197
|
+
安全下载导出文件(支持 Blob 异常解析):
|
|
198
|
+
```javascript
|
|
199
|
+
const { download } = useDownload(exportApi, { filename: '用户数据导出' })
|
|
200
|
+
await download({ keyword: 'test' })
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## 🚀 独立成 Git 仓库指南
|
|
206
|
+
|
|
207
|
+
若需要将 `packages/admin-kit` 作为一个独立的 Git 仓库推送到公司代码托管平台(如 GitLab/Gitee/GitHub):
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
# 1. 进入包目录
|
|
211
|
+
cd packages/admin-kit
|
|
212
|
+
|
|
213
|
+
# 2. 初始化独立 git 仓库
|
|
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
|
+
```
|
|
223
|
+
|
|
224
|
+
其他项目可通过 Git 依赖直接安装使用:
|
|
225
|
+
```json
|
|
226
|
+
{
|
|
227
|
+
"dependencies": {
|
|
228
|
+
"c-admin-kit": "git+https://your-git-server.com/frontend/c-admin-kit.git"
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
或在公司内部私有 NPM 源执行 `npm publish` 即可!
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.select-all-option[data-v-904634e0]{border-bottom:1px solid #e4e7ed;font-weight:600}[data-v-904634e0] .el-checkbox{width:100%}.empty-text[data-v-904634e0]{padding:10px 0;margin:0;text-align:center;color:#999;font-size:14px}.remote-select-wrapper[data-v-dea4bdcf]{width:100%}.loading-text[data-v-dea4bdcf]{display:flex;align-items:center;justify-content:center;gap:8px;color:#909399;font-size:14px;padding:10px}.no-data-text[data-v-dea4bdcf]{text-align:center;color:#c0c4cc;font-size:14px;padding:10px}.search-box[data-v-760b27aa]{border-radius:4px;margin-bottom:16px;padding-bottom:12px}.search-form[data-v-760b27aa],.search-fields[data-v-760b27aa]{width:100%}.field-col[data-v-760b27aa]{margin-bottom:12px}.action-col[data-v-760b27aa]{display:flex;justify-content:flex-end;align-items:center}.search-form[data-v-760b27aa] .el-form-item{margin-bottom:0;display:flex;align-items:center;width:100%}.search-form[data-v-760b27aa] .el-form-item__label{flex-shrink:0;font-weight:500;color:#606266;line-height:32px;min-width:var(--v7dbee7c4);width:var(--v7dbee7c4);padding-right:12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.search-form[data-v-760b27aa] .el-form-item__content{flex:1;line-height:32px;min-width:0;width:100%}.is-required[data-v-760b27aa] .el-form-item__label:before{content:"*";color:#f56c6c;margin-right:4px}.button-group[data-v-760b27aa]{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.toggle-btn[data-v-760b27aa]{padding:8px 15px;color:#409eff;display:inline-flex;align-items:center;gap:4px}.toggle-btn[data-v-760b27aa]:hover{color:#66b1ff}.toggle-icon[data-v-760b27aa]{font-size:12px;transition:transform .3s}.search-form[data-v-760b27aa] .el-input,.search-form[data-v-760b27aa] .el-select,.search-form[data-v-760b27aa] .el-date-editor,.search-form[data-v-760b27aa] .el-input-number,.search-form[data-v-760b27aa] .el-cascader{width:100%;flex:1}@media(max-width:768px){.search-box[data-v-760b27aa]{padding:16px}.search-form[data-v-760b27aa] .el-form-item{flex-direction:column;align-items:flex-start}.search-form[data-v-760b27aa] .el-form-item__label{line-height:20px;margin-bottom:8px;width:100%;min-width:auto;white-space:normal}.action-col[data-v-760b27aa]{justify-content:flex-start}.button-group[data-v-760b27aa]{width:100%;flex-direction:column}.button-group .el-button[data-v-760b27aa]{width:100%}.toggle-btn[data-v-760b27aa]{width:100%;justify-content:center}}.collapsible-container[data-v-d7447c42]{display:grid;grid-template-columns:var(--v5dad642c);height:var(--v1c2deffa);width:100%;background:#f5f7fa;overflow:hidden}.left-panel[data-v-d7447c42]{background:#fff;border-right:1px solid #e4e7ed;display:flex;flex-direction:column;overflow:hidden;max-width:var(--v72e9676c);min-width:var(--v72e9676c);position:relative;will-change:max-width,min-width}.left-panel[data-v-d7447c42]:not(.resizing){transition:all .3s ease-in-out}.left-content[data-v-d7447c42]{height:100%;padding:16px;overflow-y:auto;min-width:0;transition:opacity .2s ease-in-out;opacity:1}.left-panel.collapsed .left-content[data-v-d7447c42]{opacity:0}.right-panel[data-v-d7447c42]{background:#fff;transition:all .3s ease-in-out;max-width:100%;overflow:hidden}.toggle-btn[data-v-d7447c42]{width:48px;height:48px;display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;transition:transform .3s ease-in-out}.toggle-btn[data-v-d7447c42]:hover{background-color:#f5f7fa}.right-content[data-v-d7447c42]{height:100%;padding:16px;overflow-y:auto;max-width:100%;box-sizing:border-box}.resize-handle[data-v-d7447c42]{position:absolute;right:0;top:0;width:4px;height:100%;cursor:col-resize;background:transparent;transition:background .2s ease;z-index:10;will-change:background;padding:0 4px;margin:0 -4px}.resize-handle[data-v-d7447c42]:hover{background:#409eff}.resize-handle[data-v-d7447c42]:active{background:#337ecc}.collapsible-container[data-v-d7447c42]:has(.resize-handle:active){transition:none}.left-panel[data-v-d7447c42]:has(.resize-handle:active){transition:none}.drawer-content[data-v-4f318c2b]{height:100%}.drawer-footer[data-v-4f318c2b]{display:flex;justify-content:flex-end;gap:12px}.c-simple-table[data-v-c7177925]{width:100%}.table-header[data-v-c7177925]{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;min-height:32px}.header-left[data-v-c7177925]{flex:1;display:flex;align-items:center;gap:12px}.header-right[data-v-c7177925]{display:flex;align-items:center;gap:12px}.table-pagination[data-v-c7177925]{margin-top:16px;display:flex;justify-content:flex-end}.drag-handle[data-v-c7177925]{display:inline-flex;align-items:center;justify-content:center;cursor:move;padding:4px;transition:all .2s}.drag-handle[data-v-c7177925]:hover{transform:scale(1.1)}[data-v-c7177925] .sortable-ghost{opacity:.4;background:#f5f7fa}[data-v-c7177925] .sortable-chosen{background:#ecf5ff}[data-v-c7177925] .sortable-drag{opacity:.8;background:#fff;box-shadow:0 2px 12px #0000001a}[data-v-c7177925] .el-table__body-wrapper{overflow-y:auto!important}.c-diff-container[data-v-29510e70]{font-family:monospace;font-size:14px;line-height:1.6;white-space:pre-wrap;word-break:break-word;color:#333}.diff-removed[data-v-29510e70]{background-color:#fee2e2;color:#991b1b;text-decoration:line-through;text-decoration-color:#dc2626;text-decoration-thickness:2px}.diff-added[data-v-29510e70]{background-color:#dcfce7;color:#166534;font-weight:600}.el-image[data-v-cd23dea8]{border-radius:5px;background-color:#ebeef5;box-shadow:0 0 5px 1px #ccc}[data-v-cd23dea8] .el-image__inner{transition:all .3s;cursor:pointer}[data-v-cd23dea8] .el-image__inner:hover{transform:scale(1.08)}[data-v-cd23dea8] .image-slot{display:flex;justify-content:center;align-items:center;width:100%;height:100%;color:#909399;font-size:24px}
|