@xinlian-frontend/lui 0.0.1-beta.7 → 0.0.1-beta.8
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 +1360 -11
- package/assets/style.css +1 -1
- package/components/form-submit-page/form-submit-page.vue.d.ts +2 -7
- package/components/form-submit-page/type.d.ts +6 -0
- package/l-ui.es.js +539 -555
- package/package.json +1 -1
- package/type.d.ts +1 -0
- package/vue-office-docx.js +2 -2
- package/vue-office-excel.js +2 -2
- package/vue-office-pdf.js +4 -4
package/README.md
CHANGED
|
@@ -1,22 +1,1371 @@
|
|
|
1
|
-
# lui
|
|
2
1
|
|
|
3
|
-
lui 公共组件库,基于 Vue3 + Ant Design Vue。
|
|
4
2
|
|
|
5
|
-
|
|
3
|
+
# L-UI 组件库文档
|
|
6
4
|
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
> 基于 Ant Design Vue 封装的业务组件库,提供表单、表格、抽屉、弹窗等常用业务组件。
|
|
6
|
+
|
|
7
|
+
## 组件总览
|
|
8
|
+
|
|
9
|
+
| 组件 | 名称 | 说明 |
|
|
10
|
+
| ------------------------------------- | ------------ | ---------------------------------------------- |
|
|
11
|
+
| [LButton](#lbutton) | 按钮 | 基于 AButton 的简单封装 |
|
|
12
|
+
| [LPageTable](#lpagetable) | 分页表格 | 集成筛选、分页、列设置、全屏等功能的高级表格 |
|
|
13
|
+
| [LModal](#lmodal) | 弹窗 | 支持拖拽的模态框 |
|
|
14
|
+
| [LDrawer](#ldrawer) | 抽屉 | 可全屏、刷新的抽屉组件 |
|
|
15
|
+
| [LFilterPanel](#lfilterpanel) | 筛选面板 | 表单筛选组件,支持多种筛选项类型 |
|
|
16
|
+
| [LFormFooter](#lformfooter) | 表单底部栏 | 固定底部的操作按钮栏 |
|
|
17
|
+
| [LFormSubmitPage](#lformsubmitpage) | 表单提交页 | 表单提交页通用外壳,支持卡片/分区两种布局 |
|
|
18
|
+
| [LFormSectionPage](#lformsectionpage) | 分区表单页 | 固定为分区样式的表单提交页 |
|
|
19
|
+
| [LSectionBlock](#lsectionblock) | 区块容器 | 区块标题+内容的通用容器 |
|
|
20
|
+
| [LDetailLayout](#ldetaillayout) | 详情布局 | 详情页布局,含描述信息和 Tab 切换 |
|
|
21
|
+
| [LInfoLayout](#linfolayout) | 信息布局 | 滚动同步 Tab 锚点的信息展示布局 |
|
|
22
|
+
| [LFixedFooter](#lfixedfooter) | 固定底部 | 固定在页面底部的插槽容器 |
|
|
23
|
+
| [LSecondBar](#lsecondbar) | 二级标签栏 | 顶部二级 Tab 切换栏 |
|
|
24
|
+
| [LPageNotFound](#lpagenotfound) | 404 页面 | 404 错误页面 |
|
|
25
|
+
| [LApprovalSteps](#lapprovalsteps) | 审批流程 | 审批流程时间线展示组件 |
|
|
26
|
+
| [LRoleTree](#lroletree) | 角色菜单树 | 带复选框的菜单树形结构 |
|
|
27
|
+
| [LSignStatusFlow](#lsignstatusflow) | 签署状态流程 | 签署流程状态展示 |
|
|
28
|
+
| [LUploadFile](#luploadfile) | 文件上传 | 文件上传组件,支持附件上传和预览 |
|
|
29
|
+
| [LUploadImage](#luploadimage) | 图片上传 | 图片/视频上传组件,支持预览 |
|
|
30
|
+
| [LFilePreview](#lfilepreview) | 文件预览 | 支持图片、PDF、Word、Excel、视频等多种文件预览 |
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## LButton
|
|
35
|
+
|
|
36
|
+
### 介绍
|
|
37
|
+
|
|
38
|
+
基于 Ant Design Vue `AButton` 的简单封装。
|
|
39
|
+
|
|
40
|
+
### 基本用法
|
|
41
|
+
|
|
42
|
+
```vue
|
|
43
|
+
<LButton type="primary">主要按钮</LButton>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Props
|
|
47
|
+
|
|
48
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
49
|
+
| ---- | -------- | ------------ | ----------- |
|
|
50
|
+
| type | 按钮类型 | `ButtonType` | `'default'` |
|
|
51
|
+
|
|
52
|
+
### ButtonType 类型
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
type ButtonType =
|
|
56
|
+
| 'primary' // 主要按钮
|
|
57
|
+
| 'secondary' // 次要按钮
|
|
58
|
+
| 'tertiary' // 幽灵按钮
|
|
59
|
+
| 'ghost' // 幽灵按钮
|
|
60
|
+
| 'link' // 链接按钮
|
|
61
|
+
| 'text' // 文本按钮
|
|
62
|
+
| 'icon' // 图标按钮
|
|
63
|
+
| 'default' // 默认按钮
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
> 其他属性继承自 Ant Design Vue `AButton`。
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## LPageTable
|
|
71
|
+
|
|
72
|
+
### 介绍
|
|
73
|
+
|
|
74
|
+
基于 Ant Design Vue `Table` 封装的高级表格组件,集成了筛选、分页、列设置、全屏等功能,适用于数据展示和管理场景。
|
|
75
|
+
|
|
76
|
+
### 基础用法
|
|
77
|
+
|
|
78
|
+
```vue
|
|
79
|
+
<script setup lang="ts">
|
|
80
|
+
import { ref } from 'vue'
|
|
81
|
+
import {
|
|
82
|
+
type LFilterPanelItem,
|
|
83
|
+
LPageTable,
|
|
84
|
+
type LPageTableColumn,
|
|
85
|
+
type LPageTableRefresh,
|
|
86
|
+
type LPageType,
|
|
87
|
+
} from '@xinlian-frontend/lui'
|
|
88
|
+
|
|
89
|
+
const tableRef = ref<LPageTableRef>()
|
|
90
|
+
const data = ref<any[]>([])
|
|
91
|
+
const pageInfo = ref<LPageType>({ total: 0, pageNum: 1, pageSize: 10 })
|
|
92
|
+
const condition = ref<Record<string,any>>({})
|
|
93
|
+
|
|
94
|
+
const columns = ref<<LPageTableColumn[]>>([
|
|
95
|
+
{ title: '姓名', dataIndex: 'name', width: 120 },
|
|
96
|
+
{ title: '年龄', dataIndex: 'age', width: 80 },
|
|
97
|
+
{ title: '创建时间', dataIndex: 'createTime', formatType: 'DateTime', width: 180 },
|
|
98
|
+
{ title: '操作', dataIndex: 'options', fixed: 'right' },
|
|
99
|
+
])
|
|
100
|
+
|
|
101
|
+
const filterItems = ref<LFilterPanelItem[]>([
|
|
102
|
+
{ key: 'name', label: '姓名', type: 'input' },
|
|
103
|
+
{
|
|
104
|
+
key: 'status',
|
|
105
|
+
label: '状态',
|
|
106
|
+
type: 'select',
|
|
107
|
+
options: [
|
|
108
|
+
{ label: '全部', value: '' },
|
|
109
|
+
{ label: '启用', value: '1' },
|
|
110
|
+
],
|
|
111
|
+
},
|
|
112
|
+
])
|
|
113
|
+
|
|
114
|
+
const refresh: LPageTableRefresh = async done => {
|
|
115
|
+
try {
|
|
116
|
+
await mockApi({ ...condition.value, ...pageInfo.value })
|
|
117
|
+
} finally {
|
|
118
|
+
done()
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
</script>
|
|
122
|
+
|
|
123
|
+
<template>
|
|
124
|
+
<LPageTable
|
|
125
|
+
ref="tableRef"
|
|
126
|
+
v-model:page="pageInfo"
|
|
127
|
+
v-model:condition="condition"
|
|
128
|
+
v-model:columns="columns"
|
|
129
|
+
:data="data"
|
|
130
|
+
:filter-items="filterItems"
|
|
131
|
+
@refresh="refresh"
|
|
132
|
+
>
|
|
133
|
+
<template #action>
|
|
134
|
+
<a-button type="primary" @click="addRef?.open">添加</a-button>
|
|
135
|
+
</template>
|
|
136
|
+
<template #name="{ record }">
|
|
137
|
+
<a-button type="link" @click="detailRef?.open()">{{ record.name }}</a-button>
|
|
138
|
+
</template>
|
|
139
|
+
<template #options>
|
|
140
|
+
<a-button type="link">删除</a-button>
|
|
141
|
+
</template>
|
|
142
|
+
<template #name-header>
|
|
143
|
+
{{ '姓名(自定义表头)' }}
|
|
144
|
+
</template>
|
|
145
|
+
<template #filter-age>
|
|
146
|
+
{{ '自定义组件' }}
|
|
147
|
+
</template>
|
|
148
|
+
</LPageTable>
|
|
149
|
+
</template>
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Props
|
|
153
|
+
|
|
154
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
155
|
+
| ----------------- | ------------------ | ----------------------- | ------- |
|
|
156
|
+
| data | 表格数据 | `Record<string, any>[]` | `[]` |
|
|
157
|
+
| columns | 列配置 | `LPageTableColumn[]` | `[]` |
|
|
158
|
+
| filterItems | 筛选项配置 | `LFilterPanelItem[]` | `[]` |
|
|
159
|
+
| autoSearch | 是否自动发起搜索 | `boolean` | `true` |
|
|
160
|
+
| showFilter | 是否显示顶部筛选 | `boolean` | `true` |
|
|
161
|
+
| showRefresh | 是否显示刷新按钮 | `boolean` | `true` |
|
|
162
|
+
| showAction | 是否显示顶部操作列 | `boolean` | `true` |
|
|
163
|
+
| showRadio | 是否显示单选 | `boolean` | `false` |
|
|
164
|
+
| showSelection | 是否显示多选 | `boolean` | `false` |
|
|
165
|
+
| showPage | 是否显示分页 | `boolean` | `true` |
|
|
166
|
+
| showSetting | 是否显示列设置 | `boolean` | `true` |
|
|
167
|
+
| radioSelected | 单选选中项 | `number \| string` | `-` |
|
|
168
|
+
| selectionSelected | 多选选中项 | `(number \| string)[]` | `[]` |
|
|
169
|
+
| condition | 筛选条件 | `Record<string, any>` | `{}` |
|
|
170
|
+
| page | 分页信息 | `LPageType` | 见下文 |
|
|
171
|
+
| refreshLoading | 刷新加载状态 | `boolean` | `false` |
|
|
172
|
+
| card | 是否卡片布局 | `boolean` | `true` |
|
|
173
|
+
| bordered | 是否显示边框 | `boolean` | `true` |
|
|
174
|
+
| rowKey | 行标识字段 | `string` | `'id'` |
|
|
175
|
+
|
|
176
|
+
### LPageType 默认值
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
{
|
|
180
|
+
total: 0,
|
|
181
|
+
pageSize: 10,
|
|
182
|
+
pageNum: 1,
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Events
|
|
187
|
+
|
|
188
|
+
| 事件名 | 说明 | 参数 |
|
|
189
|
+
| ---------------- | ---------------------------------------------- | ------------------------------------------ |
|
|
190
|
+
| refresh | 刷新数据事件,参数 done 需在数据加载完成后调用 | `(done: Done) => void` |
|
|
191
|
+
| update:page | 分页变化事件 | `(page: LPageType) => void` |
|
|
192
|
+
| update:condition | 筛选条件变化事件 | `(condition: Record<string, any>) => void` |
|
|
193
|
+
| update:sortInfo | 排序信息变化事件 | `(sortInfo: LTableSortInfo) => void` |
|
|
194
|
+
| update:columns | 列配置变化事件 | `(columns: LPageTableColumn[]) => void` |
|
|
195
|
+
|
|
196
|
+
### Slots
|
|
197
|
+
|
|
198
|
+
| 插槽名 | 说明 |
|
|
199
|
+
| ------------------ | ----------------------------------------- |
|
|
200
|
+
| action | 顶部操作区域 |
|
|
201
|
+
| filter-{key} | 自定义筛选项,key 为 filterItems 中的 key |
|
|
202
|
+
| {dataIndex} | 自定义列内容 |
|
|
203
|
+
| {dataIndex}-header | 自定义列头 |
|
|
204
|
+
| expandedRowRender | 展开行内容 |
|
|
205
|
+
| expandColumnTitle | 展开列标题 |
|
|
206
|
+
| summary | 表格底部汇总 |
|
|
207
|
+
|
|
208
|
+
### 方法(通过 ref 调用)
|
|
209
|
+
|
|
210
|
+
| 方法名 | 说明 |
|
|
211
|
+
| ----------------- | ---------------- |
|
|
212
|
+
| refresh() | 刷新表格数据 |
|
|
213
|
+
| getRootTableRef() | 获取原生表格实例 |
|
|
214
|
+
|
|
215
|
+
### 类型定义
|
|
216
|
+
|
|
217
|
+
#### LPageTableColumn
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
interface LPageTableColumn<T> extends TableColumnProps {
|
|
221
|
+
dataIndex: T extends object ? keyof T : string
|
|
222
|
+
visible?: boolean // 是否显示列
|
|
223
|
+
promission?: boolean // 权限控制
|
|
224
|
+
formatType?: 'Date' | 'DateTime' | 'Money' // 格式化类型
|
|
225
|
+
require?: boolean // 是否必填(显示红色 *)
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
#### LFilterPanelItem
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
interface LFilterPanelItem {
|
|
233
|
+
key: string
|
|
234
|
+
label: string
|
|
235
|
+
type?: 'input' | 'select' | 'daterange' | 'datetimerange'
|
|
236
|
+
options?: { label: string; value: any; disabled?: boolean }[]
|
|
237
|
+
placeholder?: string
|
|
238
|
+
startPlaceholder?: string
|
|
239
|
+
endPlaceholder?: string
|
|
240
|
+
multiple?: boolean
|
|
241
|
+
hide?: boolean
|
|
242
|
+
change?: (...args: any[]) => void
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### 自定义列渲染示例
|
|
247
|
+
|
|
248
|
+
```vue
|
|
249
|
+
<LPageTable :data="data" :columns="columns">
|
|
250
|
+
<!-- 自定义状态列 -->
|
|
251
|
+
<template #status="{ record }">
|
|
252
|
+
<a-tag :color="record.status === 1 ? 'green' : 'red'">
|
|
253
|
+
{{ record.status === 1 ? '启用' : '禁用' }}
|
|
254
|
+
</a-tag>
|
|
255
|
+
</template>
|
|
256
|
+
|
|
257
|
+
<!-- 自定义操作列 -->
|
|
258
|
+
<template #operation="{ record }">
|
|
259
|
+
<a-space>
|
|
260
|
+
<a-button type="link" size="small" @click="handleEdit(record)">编辑</a-button>
|
|
261
|
+
<a-button type="link" size="small" danger @click="handleDelete(record)">删除</a-button>
|
|
262
|
+
</a-space>
|
|
263
|
+
</template>
|
|
264
|
+
</LPageTable>
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## LModal
|
|
270
|
+
|
|
271
|
+
### 介绍
|
|
272
|
+
|
|
273
|
+
基于 Ant Design Vue `Modal` 封装,支持拖拽移动的模态框组件。
|
|
274
|
+
|
|
275
|
+
### 基础用法
|
|
276
|
+
|
|
277
|
+
```vue
|
|
278
|
+
<template>
|
|
279
|
+
<LModal v-model:open="visible" title="弹窗标题">
|
|
280
|
+
<p>弹窗内容</p>
|
|
281
|
+
<template #footer>
|
|
282
|
+
<a-button @click="visible = false">取消</a-button>
|
|
283
|
+
<a-button type="primary" @click="handleOk">确定</a-button>
|
|
284
|
+
</template>
|
|
285
|
+
</LModal>
|
|
286
|
+
</template>
|
|
287
|
+
|
|
288
|
+
<script setup lang="ts">
|
|
289
|
+
import { ref } from 'vue'
|
|
290
|
+
|
|
291
|
+
const visible = ref(false)
|
|
292
|
+
</script>
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### Props
|
|
296
|
+
|
|
297
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
298
|
+
| -------------------- | -------- | --------- | ------- |
|
|
299
|
+
| modelValue (v-model) | 是否显示 | `boolean` | `false` |
|
|
300
|
+
| title | 弹窗标题 | `string` | `-` |
|
|
301
|
+
|
|
302
|
+
### Slots
|
|
303
|
+
|
|
304
|
+
| 插槽名 | 说明 |
|
|
305
|
+
| ------- | -------------- |
|
|
306
|
+
| default | 弹窗内容 |
|
|
307
|
+
| title | 自定义标题区域 |
|
|
308
|
+
| footer | 自定义底部 |
|
|
309
|
+
|
|
310
|
+
> 其他属性继承自 Ant Design Vue `AModal`。
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
## LDrawer
|
|
315
|
+
|
|
316
|
+
### 介绍
|
|
317
|
+
|
|
318
|
+
基于 Ant Design Vue `Drawer` 封装的抽屉组件,支持全屏切换、刷新、遮罩控制等功能。
|
|
319
|
+
|
|
320
|
+
### 基础用法
|
|
321
|
+
|
|
322
|
+
```vue
|
|
323
|
+
<template>
|
|
324
|
+
<LDrawer
|
|
325
|
+
v-model:open="visible"
|
|
326
|
+
title="抽屉标题"
|
|
327
|
+
:width="600"
|
|
328
|
+
placement="right"
|
|
329
|
+
@close="handleClose"
|
|
330
|
+
>
|
|
331
|
+
<p>抽屉内容</p>
|
|
332
|
+
<template #footer>
|
|
333
|
+
<a-space>
|
|
334
|
+
<a-button @click="visible = false">取消</a-button>
|
|
335
|
+
<a-button type="primary" @click="handleConfirm">确定</a-button>
|
|
336
|
+
</a-space>
|
|
337
|
+
</template>
|
|
338
|
+
</LDrawer>
|
|
339
|
+
</template>
|
|
340
|
+
|
|
341
|
+
<script setup lang="ts">
|
|
342
|
+
import { ref } from 'vue'
|
|
343
|
+
|
|
344
|
+
const visible = ref(false)
|
|
345
|
+
</script>
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### Props
|
|
349
|
+
|
|
350
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
351
|
+
| ----------- | ---------------------------- | ---------------------------------------- | --------- |
|
|
352
|
+
| mask | 是否显示遮罩 | `boolean` | `true` |
|
|
353
|
+
| placement | 抽屉方向 | `'top' \| 'right' \| 'bottom' \| 'left'` | `'right'` |
|
|
354
|
+
| width | 抽屉宽度 | `string \| number` | `'75%'` |
|
|
355
|
+
| title | 抽屉标题 | `string` | `-` |
|
|
356
|
+
| loading | 加载状态,显示 Spin | `boolean` | `false` |
|
|
357
|
+
| showRefresh | 是否显示刷新按钮 | `boolean` | `false` |
|
|
358
|
+
| page | 是否启用分页模式(预留功能) | `boolean` | `false` |
|
|
359
|
+
|
|
360
|
+
### Events
|
|
361
|
+
|
|
362
|
+
| 事件名 | 说明 |
|
|
363
|
+
| ------- | ------------------- |
|
|
364
|
+
| prev | 上一步(page 模式) |
|
|
365
|
+
| next | 下一步(page 模式) |
|
|
366
|
+
| refresh | 点击刷新按钮 |
|
|
367
|
+
| close | 关闭抽屉 |
|
|
368
|
+
|
|
369
|
+
### Slots
|
|
370
|
+
|
|
371
|
+
| 插槽名 | 说明 |
|
|
372
|
+
| ----------- | ------------------ |
|
|
373
|
+
| default | 抽屉内容 |
|
|
374
|
+
| footer | 自定义底部 |
|
|
375
|
+
| extra | 标题栏右侧扩展区域 |
|
|
376
|
+
| title | 自定义标题 |
|
|
377
|
+
| title-extra | 标题后方扩展 |
|
|
378
|
+
|
|
379
|
+
### 方法(通过 ref 调用)
|
|
380
|
+
|
|
381
|
+
| 方法名 | 说明 |
|
|
382
|
+
| ------- | ------------------------ |
|
|
383
|
+
| open() | 打开抽屉 |
|
|
384
|
+
| close() | 关闭抽屉 |
|
|
385
|
+
| visable | 抽屉可见性状态(响应式) |
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
389
|
+
## LFilterPanel
|
|
390
|
+
|
|
391
|
+
### 介绍
|
|
392
|
+
|
|
393
|
+
表单筛选面板组件,支持 input、select、日期范围等多种筛选项类型,自动处理查询/重置逻辑。
|
|
394
|
+
|
|
395
|
+
### 基础用法
|
|
396
|
+
|
|
397
|
+
```vue
|
|
398
|
+
<template>
|
|
399
|
+
<LFilterPanel
|
|
400
|
+
v-model="condition"
|
|
401
|
+
:filter-items="filterItems"
|
|
402
|
+
label-width="80px"
|
|
403
|
+
@search="handleSearch"
|
|
404
|
+
@reset="handleReset"
|
|
405
|
+
/>
|
|
406
|
+
</template>
|
|
407
|
+
|
|
408
|
+
<script setup lang="ts">
|
|
409
|
+
import { ref } from 'vue'
|
|
410
|
+
|
|
411
|
+
const condition = ref({})
|
|
412
|
+
const filterItems = [
|
|
413
|
+
{ key: 'name', label: '姓名', type: 'input', placeholder: '请输入姓名' },
|
|
414
|
+
{
|
|
415
|
+
key: 'status',
|
|
416
|
+
label: '状态',
|
|
417
|
+
type: 'select',
|
|
418
|
+
options: [
|
|
419
|
+
{ label: '全部', value: '' },
|
|
420
|
+
{ label: '启用', value: '1' },
|
|
421
|
+
],
|
|
422
|
+
},
|
|
423
|
+
{
|
|
424
|
+
key: 'date',
|
|
425
|
+
label: '日期',
|
|
426
|
+
type: 'daterange',
|
|
427
|
+
startPlaceholder: '开始日期',
|
|
428
|
+
endPlaceholder: '结束日期',
|
|
429
|
+
},
|
|
430
|
+
]
|
|
431
|
+
</script>
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
### Props
|
|
435
|
+
|
|
436
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
437
|
+
| -------------------- | ---------------- | --------------------- | -------- |
|
|
438
|
+
| modelValue (v-model) | 筛选条件双向绑定 | `Record<string, any>` | `{}` |
|
|
439
|
+
| filterItems | 筛选项配置数组 | `LFilterPanelItem[]` | `[]` |
|
|
440
|
+
| labelWidth | 表单标签宽度 | `number \| string` | `'80px'` |
|
|
441
|
+
| collapsible | 是否可折叠 | `boolean` | `false` |
|
|
442
|
+
| collapsedRows | 折叠时显示的行数 | `number` | `1` |
|
|
443
|
+
| searchText | 查询按钮文本 | `string` | `'查询'` |
|
|
444
|
+
| resetText | 重置按钮文本 | `string` | `'重置'` |
|
|
445
|
+
| expandText | 展开文本 | `string` | `'展开'` |
|
|
446
|
+
| collapseText | 收起文本 | `string` | `'收起'` |
|
|
447
|
+
| card | 是否显示卡片背景 | `boolean` | `true` |
|
|
448
|
+
|
|
449
|
+
### LFilterPanelItem
|
|
450
|
+
|
|
451
|
+
| 字段 | 说明 | 类型 |
|
|
452
|
+
| ---------------- | -------------------- | ------------------------------------------------------- |
|
|
453
|
+
| key | 字段标识 | `string` |
|
|
454
|
+
| label | 字段标签 | `string` |
|
|
455
|
+
| type | 筛选项类型 | `'input' \| 'select' \| 'daterange' \| 'datetimerange'` |
|
|
456
|
+
| options | select 选项列表 | `{ label: string; value: any; disabled?: boolean }[]` |
|
|
457
|
+
| placeholder | 输入框占位文本 | `string` |
|
|
458
|
+
| startPlaceholder | 日期范围开始占位文本 | `string` |
|
|
459
|
+
| endPlaceholder | 日期范围结束占位文本 | `string` |
|
|
460
|
+
| multiple | select 是否多选 | `boolean` |
|
|
461
|
+
| hide | 是否隐藏该筛选项 | `boolean` |
|
|
462
|
+
| change | 值变化时的回调 | `(...args: any[]) => void` |
|
|
463
|
+
|
|
464
|
+
### Events
|
|
465
|
+
|
|
466
|
+
| 事件名 | 说明 |
|
|
467
|
+
| ----------------- | ----------------------------- |
|
|
468
|
+
| update:modelValue | 筛选条件变化 |
|
|
469
|
+
| search | 点击查询按钮 |
|
|
470
|
+
| reset | 点击重置按钮 |
|
|
471
|
+
| toggle | 折叠/展开变化,参数为展开状态 |
|
|
472
|
+
|
|
473
|
+
---
|
|
474
|
+
|
|
475
|
+
## LFormFooter
|
|
476
|
+
|
|
477
|
+
### 介绍
|
|
478
|
+
|
|
479
|
+
固定在页面底部的操作按钮栏组件,支持自定义按钮配置。
|
|
480
|
+
|
|
481
|
+
### 基础用法
|
|
482
|
+
|
|
483
|
+
```vue
|
|
484
|
+
<template>
|
|
485
|
+
<LFormFooter
|
|
486
|
+
:loading="submitLoading"
|
|
487
|
+
@close="handleClose"
|
|
488
|
+
@save="handleSave"
|
|
489
|
+
@submit="handleSubmit"
|
|
490
|
+
/>
|
|
491
|
+
</template>
|
|
492
|
+
|
|
493
|
+
<script setup lang="ts">
|
|
494
|
+
const submitLoading = ref(false)
|
|
495
|
+
</script>
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
### Props
|
|
499
|
+
|
|
500
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
501
|
+
| ---------- | ------------------ | -------------------- | -------- |
|
|
502
|
+
| buttons | 自定义按钮配置列表 | `FormFooterButton[]` | `[]` |
|
|
503
|
+
| showClose | 是否显示关闭按钮 | `boolean` | `true` |
|
|
504
|
+
| showSave | 是否显示保存按钮 | `boolean` | `true` |
|
|
505
|
+
| showSubmit | 是否显示提交按钮 | `boolean` | `true` |
|
|
506
|
+
| loading | 全局 loading 状态 | `boolean` | `false` |
|
|
507
|
+
| closeText | 关闭按钮文本 | `string` | `'关闭'` |
|
|
508
|
+
| saveText | 保存按钮文本 | `string` | `'保存'` |
|
|
509
|
+
| submitText | 提交按钮文本 | `string` | `'提交'` |
|
|
510
|
+
|
|
511
|
+
### FormFooterButton
|
|
512
|
+
|
|
513
|
+
```typescript
|
|
514
|
+
interface FormFooterButton {
|
|
515
|
+
text: string // 按钮文本
|
|
516
|
+
type?: 'default' | 'primary' | 'dashed' | 'link' | 'text' // 按钮类型
|
|
517
|
+
loading?: boolean // loading 状态
|
|
518
|
+
disabled?: boolean // 是否禁用
|
|
519
|
+
onClick?: () => void | Promise<void> // 点击事件
|
|
520
|
+
}
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
### Events
|
|
524
|
+
|
|
525
|
+
| 事件名 | 说明 |
|
|
526
|
+
| -------- | ------------ |
|
|
527
|
+
| onClose | 点击关闭按钮 |
|
|
528
|
+
| onSave | 点击保存按钮 |
|
|
529
|
+
| onSubmit | 点击提交按钮 |
|
|
530
|
+
|
|
531
|
+
---
|
|
532
|
+
|
|
533
|
+
## LFormSubmitPage
|
|
534
|
+
|
|
535
|
+
### 介绍
|
|
536
|
+
|
|
537
|
+
表单提交页通用外壳组件,统一页面容器、表单布局与底部操作栏。支持 **卡片 (card)** 和 **分区 (section)** 两种布局形态,可通过 props 切换或用户手动切换(自动同步到 localStorage)。
|
|
538
|
+
|
|
539
|
+
### 基础用法
|
|
540
|
+
|
|
541
|
+
```vue
|
|
542
|
+
<template>
|
|
543
|
+
<LFormSubmitPage
|
|
544
|
+
ref="pageRef"
|
|
545
|
+
:model="formData"
|
|
546
|
+
:rules="rules"
|
|
547
|
+
:show-save="true"
|
|
548
|
+
@cancel="handleCancel"
|
|
549
|
+
@save="handleSave"
|
|
550
|
+
@submit="handleSubmit"
|
|
551
|
+
>
|
|
552
|
+
<a-card title="基础信息">
|
|
553
|
+
<a-form-item label="名称" name="name">
|
|
554
|
+
<a-input v-model:value="formData.name" />
|
|
555
|
+
</a-form-item>
|
|
556
|
+
</a-card>
|
|
557
|
+
</LFormSubmitPage>
|
|
558
|
+
</template>
|
|
559
|
+
|
|
560
|
+
<script setup lang="ts">
|
|
561
|
+
import { message } from 'ant-design-vue'
|
|
562
|
+
import { reactive, ref } from 'vue'
|
|
563
|
+
|
|
564
|
+
const pageRef = ref()
|
|
565
|
+
const formData = reactive({ name: '' })
|
|
566
|
+
const rules = { name: [{ required: true, message: '请输入名称', trigger: 'blur' }] }
|
|
567
|
+
|
|
568
|
+
async function handleSubmit() {
|
|
569
|
+
await pageRef.value?.formRef?.validate()
|
|
570
|
+
message.success('提交成功')
|
|
571
|
+
}
|
|
572
|
+
</script>
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
### Props
|
|
576
|
+
|
|
577
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
578
|
+
| ---------------- | -------------------- | ---------------------------------------- | -------------- |
|
|
579
|
+
| model | 表单绑定数据 | `Record<string, unknown>` | `-` |
|
|
580
|
+
| rules | 校验规则 | `Record<string, unknown>` | `-` |
|
|
581
|
+
| layout | 表单布局 | `'horizontal' \| 'vertical' \| 'inline'` | `'horizontal'` |
|
|
582
|
+
| variant | 展示形态 | `'card' \| 'section'` | `'section'` |
|
|
583
|
+
| showLayoutSwitch | 是否显示布局切换图标 | `boolean` | `true` |
|
|
584
|
+
| sections | 卡片区块配置 | `FormSubmitPageSection[]` | `-` |
|
|
585
|
+
| showSave | 是否显示保存按钮 | `boolean` | `true` |
|
|
586
|
+
| showSubmit | 是否显示提交按钮 | `boolean` | `true` |
|
|
587
|
+
| submitLoading | 提交按钮 loading | `boolean` | `false` |
|
|
588
|
+
| saveLoading | 保存按钮 loading | `boolean` | `false` |
|
|
589
|
+
| cancelText | 取消按钮文案 | `string` | `'取消'` |
|
|
590
|
+
| saveText | 保存按钮文案 | `string` | `'保存'` |
|
|
591
|
+
| submitText | 提交按钮文案 | `string` | `'提交'` |
|
|
592
|
+
|
|
593
|
+
### FormSubmitPageSection
|
|
594
|
+
|
|
595
|
+
```typescript
|
|
596
|
+
interface FormSubmitPageSection {
|
|
597
|
+
key: string // 区块唯一标识
|
|
598
|
+
title: string // 区块标题
|
|
599
|
+
desc?: string // 区块描述
|
|
600
|
+
}
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
### Events
|
|
604
|
+
|
|
605
|
+
| 事件名 | 说明 |
|
|
606
|
+
| -------------- | ------------ |
|
|
607
|
+
| cancel | 点击取消按钮 |
|
|
608
|
+
| save | 点击保存按钮 |
|
|
609
|
+
| submit | 点击提交按钮 |
|
|
610
|
+
| update:variant | 布局形态变化 |
|
|
611
|
+
|
|
612
|
+
### Slots
|
|
613
|
+
|
|
614
|
+
| 插槽名 | 说明 |
|
|
615
|
+
| ------------ | ------------------------------- |
|
|
616
|
+
| default | 表单内容区 |
|
|
617
|
+
| card-{key} | 按 section 配置渲染卡片区块内容 |
|
|
618
|
+
| footer | 整块自定义底部栏 |
|
|
619
|
+
| footer-left | 底部左侧扩展 |
|
|
620
|
+
| footer-right | 底部右侧扩展 |
|
|
621
|
+
|
|
622
|
+
### Expose
|
|
623
|
+
|
|
624
|
+
| 名称 | 类型 | 说明 |
|
|
625
|
+
| ------- | --------- | -------------------------------------------------------- |
|
|
626
|
+
| formRef | Form 实例 | ant-design-vue Form 实例,可调用 validate/resetFields 等 |
|
|
627
|
+
|
|
628
|
+
### 多区块使用示例
|
|
629
|
+
|
|
630
|
+
```vue
|
|
631
|
+
<template>
|
|
632
|
+
<LFormSubmitPage
|
|
633
|
+
ref="pageRef"
|
|
634
|
+
:model="formData"
|
|
635
|
+
:sections="[
|
|
636
|
+
{ key: 'basic', title: '基础信息' },
|
|
637
|
+
{ key: 'detail', title: '详细信息' },
|
|
638
|
+
]"
|
|
639
|
+
>
|
|
640
|
+
<template #card-basic>
|
|
641
|
+
<a-form-item label="名称" name="name">
|
|
642
|
+
<a-input v-model:value="formData.name" />
|
|
643
|
+
</a-form-item>
|
|
644
|
+
</template>
|
|
645
|
+
<template #card-detail>
|
|
646
|
+
<a-form-item label="描述" name="desc">
|
|
647
|
+
<a-textarea v-model:value="formData.desc" />
|
|
648
|
+
</a-form-item>
|
|
649
|
+
</template>
|
|
650
|
+
</LFormSubmitPage>
|
|
651
|
+
</template>
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
### 布局切换说明
|
|
655
|
+
|
|
656
|
+
开启 `showLayoutSwitch` 后,页面右上角会显示卡片/分区切换图标。切换结果会自动写入 `localStorage`(key: `l-form-submit-page-layout-variant`),所有开启此功能的页面会共用该状态,实现跨页面无缝同步。
|
|
657
|
+
|
|
658
|
+
---
|
|
659
|
+
|
|
660
|
+
## LFormSectionPage
|
|
661
|
+
|
|
662
|
+
### 介绍
|
|
663
|
+
|
|
664
|
+
固定为 **分区 (section)** 形态的表单提交页,用法与 `LFormSubmitPage` 完全一致,仅固定为分区布局。
|
|
665
|
+
|
|
666
|
+
```vue
|
|
667
|
+
<LFormSectionPage :model="formData" :rules="rules">
|
|
668
|
+
<a-form-item label="名称" name="name">
|
|
669
|
+
<a-input v-model:value="formData.name" />
|
|
670
|
+
</a-form-item>
|
|
671
|
+
</LFormSectionPage>
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
> 所有 Props、Slots、Events、Expose 与 LFormSubmitPage 保持一致。
|
|
675
|
+
|
|
676
|
+
---
|
|
677
|
+
|
|
678
|
+
## LSectionBlock
|
|
679
|
+
|
|
680
|
+
### 介绍
|
|
681
|
+
|
|
682
|
+
区块标题+内容的通用容器组件,仅负责结构复用,样式由使用方工程提供。
|
|
683
|
+
|
|
684
|
+
### 基础用法
|
|
685
|
+
|
|
686
|
+
```vue
|
|
687
|
+
<template>
|
|
688
|
+
<LSectionBlock title="基本信息">
|
|
689
|
+
<template #header-extra>
|
|
690
|
+
<a-button type="link">编辑</a-button>
|
|
691
|
+
</template>
|
|
692
|
+
<p>区块内容</p>
|
|
693
|
+
</LSectionBlock>
|
|
694
|
+
</template>
|
|
695
|
+
```
|
|
696
|
+
|
|
697
|
+
### Props
|
|
698
|
+
|
|
699
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
700
|
+
| ---------- | ---------------- | ----------- | ----------- |
|
|
701
|
+
| title | 标题文案 | `string` | `''` |
|
|
702
|
+
| blockClass | 最外层额外 class | `ClassType` | `undefined` |
|
|
703
|
+
| showHeader | 是否显示头部 | `boolean` | `true` |
|
|
704
|
+
| loading | 加载状态 | `boolean` | `false` |
|
|
705
|
+
|
|
706
|
+
### Slots
|
|
707
|
+
|
|
708
|
+
| 插槽名 | 说明 |
|
|
709
|
+
| ------------ | ---------------- |
|
|
710
|
+
| default | 区块内容 |
|
|
711
|
+
| title | 自定义标题 |
|
|
712
|
+
| header-extra | 标题右侧扩展区域 |
|
|
713
|
+
|
|
714
|
+
---
|
|
715
|
+
|
|
716
|
+
## LDetailLayout
|
|
717
|
+
|
|
718
|
+
### 介绍
|
|
719
|
+
|
|
720
|
+
详情页布局组件,包含顶部描述信息区域和下方 Tab 切换区域,内置 `FixedFooter` 固定底部栏。
|
|
721
|
+
|
|
722
|
+
### 基础用法
|
|
723
|
+
|
|
724
|
+
```vue
|
|
725
|
+
<template>
|
|
726
|
+
<LDetailLayout
|
|
727
|
+
title="详情"
|
|
728
|
+
:descriptions="descriptions"
|
|
729
|
+
:tabs="tabs"
|
|
730
|
+
@tab-change="handleTabChange"
|
|
731
|
+
>
|
|
732
|
+
<template #extra>
|
|
733
|
+
<a-space>
|
|
734
|
+
<a-button>编辑</a-button>
|
|
735
|
+
</a-space>
|
|
736
|
+
</template>
|
|
737
|
+
|
|
738
|
+
<template #tab-basic>
|
|
739
|
+
<p>基本信息内容</p>
|
|
740
|
+
</template>
|
|
741
|
+
<template #tab-record>
|
|
742
|
+
<p>记录信息内容</p>
|
|
743
|
+
</template>
|
|
744
|
+
|
|
745
|
+
<template #footer>
|
|
746
|
+
<a-button @click="goBack">返回</a-button>
|
|
747
|
+
<a-button type="primary">提交</a-button>
|
|
748
|
+
</template>
|
|
749
|
+
</LDetailLayout>
|
|
750
|
+
</template>
|
|
751
|
+
|
|
752
|
+
<script setup lang="ts">
|
|
753
|
+
const descriptions = [
|
|
754
|
+
{ label: '姓名', value: '张三' },
|
|
755
|
+
{ label: '状态', value: '启用' },
|
|
756
|
+
]
|
|
757
|
+
const tabs = [
|
|
758
|
+
{ key: 'basic', label: '基本信息' },
|
|
759
|
+
{ key: 'record', label: '记录信息' },
|
|
760
|
+
]
|
|
761
|
+
</script>
|
|
762
|
+
```
|
|
763
|
+
|
|
764
|
+
### Props
|
|
765
|
+
|
|
766
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
767
|
+
| ---------------- | -------------- | -------------------------- | ------------- |
|
|
768
|
+
| title | 页面标题 | `string` | `-` |
|
|
769
|
+
| descriptions | 顶部描述项配置 | `LDetailDescriptionItem[]` | `[]` |
|
|
770
|
+
| headerColumn | 描述信息列数 | `number` | `3` |
|
|
771
|
+
| tabs | Tab 配置列表 | `LDetailTabItem[]` | `[]` |
|
|
772
|
+
| defaultActiveKey | 默认激活的 Tab | `string` | `''` |
|
|
773
|
+
| tabSize | Tab 尺寸 | `'small' \| 'default'` | `'small'` |
|
|
774
|
+
| loading | 加载状态 | `boolean` | `false` |
|
|
775
|
+
| loadingTip | 加载提示文本 | `string` | `'加载中...'` |
|
|
776
|
+
|
|
777
|
+
### LDetailDescriptionItem
|
|
778
|
+
|
|
779
|
+
```typescript
|
|
780
|
+
interface LDetailDescriptionItem {
|
|
781
|
+
label: string // 标签
|
|
782
|
+
value: string | number | undefined | null // 值
|
|
783
|
+
span?: number // 跨列数
|
|
784
|
+
}
|
|
785
|
+
```
|
|
786
|
+
|
|
787
|
+
### LDetailTabItem
|
|
788
|
+
|
|
789
|
+
```typescript
|
|
790
|
+
interface LDetailTabItem {
|
|
791
|
+
key: string // Tab 唯一标识
|
|
792
|
+
label: string // Tab 显示文本
|
|
793
|
+
}
|
|
794
|
+
```
|
|
795
|
+
|
|
796
|
+
### Events
|
|
797
|
+
|
|
798
|
+
| 事件名 | 说明 | 参数 |
|
|
799
|
+
| --------- | ------------ | ------------- |
|
|
800
|
+
| tabChange | Tab 切换事件 | `key: string` |
|
|
801
|
+
|
|
802
|
+
### Slots
|
|
803
|
+
|
|
804
|
+
| 插槽名 | 说明 |
|
|
805
|
+
| ------------------- | ----------------------------- |
|
|
806
|
+
| extra | 右上角扩展区域 |
|
|
807
|
+
| description-{label} | 自定义描述项渲染,参数为 item |
|
|
808
|
+
| tab-{key} | Tab 内容区 |
|
|
809
|
+
| footer | 固定底部栏内容 |
|
|
810
|
+
|
|
811
|
+
---
|
|
812
|
+
|
|
813
|
+
## LInfoLayout
|
|
814
|
+
|
|
815
|
+
### 介绍
|
|
816
|
+
|
|
817
|
+
信息展示布局组件,左侧为可滚动的内容区,右侧为固定 Tab 导航,支持滚动时自动高亮对应 Tab。
|
|
818
|
+
|
|
819
|
+
### 基础用法
|
|
820
|
+
|
|
821
|
+
```vue
|
|
822
|
+
<template>
|
|
823
|
+
<LInfoLayout :items="items" :show-menu="true">
|
|
824
|
+
<template #base>
|
|
825
|
+
<p>基础信息内容...</p>
|
|
826
|
+
</template>
|
|
827
|
+
<template #detail>
|
|
828
|
+
<p>详细信息内容...</p>
|
|
829
|
+
</template>
|
|
830
|
+
</LInfoLayout>
|
|
831
|
+
</template>
|
|
832
|
+
|
|
833
|
+
<script setup lang="ts">
|
|
834
|
+
const items = [
|
|
835
|
+
{ label: '基础信息', value: 'base', show: true },
|
|
836
|
+
{ label: '详细信息', value: 'detail', show: true },
|
|
837
|
+
]
|
|
838
|
+
</script>
|
|
839
|
+
```
|
|
840
|
+
|
|
841
|
+
### Props
|
|
842
|
+
|
|
843
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
844
|
+
| -------- | ---------------------- | -------------------- | ------ |
|
|
845
|
+
| items | 导航项配置(双向绑定) | `LInfoLayoutItems[]` | `[]` |
|
|
846
|
+
| showMenu | 是否显示右侧 Tab 导航 | `boolean` | `true` |
|
|
847
|
+
|
|
848
|
+
### LInfoLayoutItems
|
|
849
|
+
|
|
850
|
+
```typescript
|
|
851
|
+
interface LInfoLayoutItems {
|
|
852
|
+
label: string // 导航标签
|
|
853
|
+
value: string // 导航值(对应插槽名)
|
|
854
|
+
show: boolean // 是否显示该项
|
|
855
|
+
hide?: boolean // 是否隐藏
|
|
856
|
+
}
|
|
857
|
+
```
|
|
858
|
+
|
|
859
|
+
### Events
|
|
860
|
+
|
|
861
|
+
| 事件名 | 说明 |
|
|
862
|
+
| ------------ | -------------- |
|
|
863
|
+
| update:items | items 变化事件 |
|
|
864
|
+
|
|
865
|
+
### Slots
|
|
866
|
+
|
|
867
|
+
| 插槽名 | 说明 |
|
|
868
|
+
| ------------- | ------------------ |
|
|
869
|
+
| {value} | 各导航项对应内容 |
|
|
870
|
+
| title-{value} | 各导航项自定义标题 |
|
|
871
|
+
| footer | 底部内容 |
|
|
872
|
+
|
|
873
|
+
---
|
|
874
|
+
|
|
875
|
+
## LFixedFooter
|
|
876
|
+
|
|
877
|
+
### 介绍
|
|
878
|
+
|
|
879
|
+
固定在页面底部的插槽容器,通过 `teleport` 挂载到指定容器中,适用于详情页底部操作栏。
|
|
880
|
+
|
|
881
|
+
### 基础用法
|
|
882
|
+
|
|
883
|
+
```vue
|
|
884
|
+
<template>
|
|
885
|
+
<LFixedFooter>
|
|
886
|
+
<template #footer>
|
|
887
|
+
<a-button @click="goBack">返回</a-button>
|
|
888
|
+
<a-button type="primary">提交</a-button>
|
|
889
|
+
</template>
|
|
890
|
+
</LFixedFooter>
|
|
891
|
+
</template>
|
|
892
|
+
```
|
|
893
|
+
|
|
894
|
+
> 组件通过 `teleport` 将内容挂载到 `#smartAdminMain` 容器中,配合 `LDetailLayout` 等布局组件使用效果更佳。
|
|
895
|
+
|
|
896
|
+
---
|
|
897
|
+
|
|
898
|
+
## LSecondBar
|
|
899
|
+
|
|
900
|
+
### 介绍
|
|
901
|
+
|
|
902
|
+
顶部二级 Tab 切换栏组件,适用于页面顶部的分类导航。
|
|
903
|
+
|
|
904
|
+
### 基础用法
|
|
905
|
+
|
|
906
|
+
```vue
|
|
907
|
+
<template>
|
|
908
|
+
<LSecondBar v-model="activeTab" :tabs="tabs" @change="handleChange" />
|
|
909
|
+
</template>
|
|
910
|
+
|
|
911
|
+
<script setup lang="ts">
|
|
912
|
+
const activeTab = ref('tab1')
|
|
913
|
+
const tabs = [
|
|
914
|
+
{ label: 'Tab 1', value: 'tab1' },
|
|
915
|
+
{ label: 'Tab 2', value: 'tab2' },
|
|
916
|
+
]
|
|
917
|
+
</script>
|
|
918
|
+
```
|
|
919
|
+
|
|
920
|
+
### Props
|
|
921
|
+
|
|
922
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
923
|
+
| -------------------- | ------------ | ------------------------------------ | ------ |
|
|
924
|
+
| modelValue (v-model) | 当前选中值 | `string` | `-` |
|
|
925
|
+
| tabs | Tab 配置列表 | `{ label: string; value: string }[]` | `[]` |
|
|
926
|
+
|
|
927
|
+
### Events
|
|
928
|
+
|
|
929
|
+
| 事件名 | 说明 | 参数 |
|
|
930
|
+
| ----------------- | ---------- | --------------- |
|
|
931
|
+
| update:modelValue | 值变化事件 | `value: string` |
|
|
932
|
+
| change | 切换事件 | `value: string` |
|
|
933
|
+
|
|
934
|
+
---
|
|
935
|
+
|
|
936
|
+
## LPageNotFound
|
|
937
|
+
|
|
938
|
+
### 介绍
|
|
939
|
+
|
|
940
|
+
404 错误页面组件,点击按钮返回首页。
|
|
941
|
+
|
|
942
|
+
### 基础用法
|
|
943
|
+
|
|
944
|
+
```vue
|
|
945
|
+
<LPageNotFound />
|
|
946
|
+
```
|
|
947
|
+
|
|
948
|
+
---
|
|
949
|
+
|
|
950
|
+
## LApprovalSteps
|
|
951
|
+
|
|
952
|
+
### 介绍
|
|
953
|
+
|
|
954
|
+
审批流程时间线展示组件,以树形结构展示父流程节点和子节点审批记录,支持文件附件预览。
|
|
955
|
+
|
|
956
|
+
### 基础用法
|
|
957
|
+
|
|
958
|
+
```vue
|
|
959
|
+
<template>
|
|
960
|
+
<LApprovalSteps :nodes="flowData" />
|
|
961
|
+
</template>
|
|
962
|
+
|
|
963
|
+
<script setup lang="ts">
|
|
964
|
+
import type { LFlowData } from '@xinlian-frontend/lui'
|
|
965
|
+
|
|
966
|
+
const flowData: LFlowData[] = [
|
|
967
|
+
{
|
|
968
|
+
nodeName: '审批1',
|
|
969
|
+
enterpriseName: '企业A',
|
|
970
|
+
nodeStatus: 'PASS',
|
|
971
|
+
subInstRecordList: [
|
|
972
|
+
{
|
|
973
|
+
actualUsers: [
|
|
974
|
+
{
|
|
975
|
+
assignee: { name: '张三' },
|
|
976
|
+
result: 1, // 1=同意
|
|
977
|
+
createTime: '2024-01-01 10:00:00',
|
|
978
|
+
},
|
|
979
|
+
],
|
|
980
|
+
},
|
|
981
|
+
],
|
|
982
|
+
},
|
|
983
|
+
]
|
|
984
|
+
</script>
|
|
985
|
+
```
|
|
986
|
+
|
|
987
|
+
### Props
|
|
988
|
+
|
|
989
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
990
|
+
| ----- | -------------- | ------------- | ------ |
|
|
991
|
+
| nodes | 父流程节点列表 | `LFlowData[]` | `[]` |
|
|
992
|
+
|
|
993
|
+
### LFlowData
|
|
994
|
+
|
|
995
|
+
```typescript
|
|
996
|
+
interface LFlowData {
|
|
997
|
+
approvalRole?: number // 审批身份
|
|
998
|
+
approvalRoleName?: string // 审批身份名称
|
|
999
|
+
createTime?: string // 创建时间
|
|
1000
|
+
enterpriseId?: number // 企业id
|
|
1001
|
+
enterpriseName?: string // 企业名称
|
|
1002
|
+
id?: number // 主键id
|
|
1003
|
+
nodeName?: string // 节点名
|
|
1004
|
+
nodeStatus?: string // 节点状态
|
|
1005
|
+
nodeStatusDesc?: string // 节点状态描述
|
|
1006
|
+
remark?: string // 备注
|
|
1007
|
+
subInstId?: string // 子流程实例id
|
|
1008
|
+
subInstRecordList?: FlowInstRecordVo[] // 子流程实例审批记录
|
|
1009
|
+
updateTime?: string // 更新时间
|
|
1010
|
+
}
|
|
1011
|
+
```
|
|
1012
|
+
|
|
1013
|
+
### 节点状态说明
|
|
1014
|
+
|
|
1015
|
+
| 状态值 | 说明 |
|
|
1016
|
+
| --------- | ------ |
|
|
1017
|
+
| `PASS` | 已通过 |
|
|
1018
|
+
| `RUNNING` | 进行中 |
|
|
1019
|
+
| `PENDING` | 待审批 |
|
|
1020
|
+
| `REFUSE` | 驳回 |
|
|
1021
|
+
| `REVOKED` | 已撤回 |
|
|
1022
|
+
| `DELETED` | 已删除 |
|
|
1023
|
+
|
|
1024
|
+
---
|
|
1025
|
+
|
|
1026
|
+
## LRoleTree
|
|
1027
|
+
|
|
1028
|
+
### 介绍
|
|
1029
|
+
|
|
1030
|
+
带复选框的角色菜单树形结构组件,支持多级菜单的勾选联动(向上向下级联),自动过滤按钮类型节点。
|
|
1031
|
+
|
|
1032
|
+
### 基础用法
|
|
1033
|
+
|
|
1034
|
+
```vue
|
|
1035
|
+
<template>
|
|
1036
|
+
<LRoleTree v-model="selectedMenus" :menu="menuTree" @update:model-value="handleChange" />
|
|
1037
|
+
</template>
|
|
1038
|
+
|
|
1039
|
+
<script setup lang="ts">
|
|
1040
|
+
import type { LMenuTreeOption } from '@xinlian-frontend/lui'
|
|
1041
|
+
|
|
1042
|
+
const selectedMenus = ref<Array<string | number>>([])
|
|
1043
|
+
|
|
1044
|
+
const menuTree: LMenuTreeOption[] = [
|
|
1045
|
+
{
|
|
1046
|
+
id: 1,
|
|
1047
|
+
label: '系统管理',
|
|
1048
|
+
menuName: '系统管理',
|
|
1049
|
+
parentId: 0,
|
|
1050
|
+
weight: 1,
|
|
1051
|
+
menuType: 'M',
|
|
1052
|
+
children: [
|
|
1053
|
+
{ id: 2, label: '用户管理', menuName: '用户管理', parentId: 1, weight: 1, menuType: 'C' },
|
|
1054
|
+
{ id: 3, label: '角色管理', menuName: '角色管理', parentId: 1, weight: 2, menuType: 'C' },
|
|
1055
|
+
],
|
|
1056
|
+
},
|
|
1057
|
+
]
|
|
1058
|
+
</script>
|
|
1059
|
+
```
|
|
1060
|
+
|
|
1061
|
+
### Props
|
|
1062
|
+
|
|
1063
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
1064
|
+
| -------------------- | -------------- | ------------------------- | ------ |
|
|
1065
|
+
| menu | 菜单树形数据 | `LMenuTreeOption[]` | `[]` |
|
|
1066
|
+
| modelValue (v-model) | 选中值 | `Array<string \| number>` | `[]` |
|
|
1067
|
+
| showCheckbox | 是否显示复选框 | `boolean` | `true` |
|
|
1068
|
+
|
|
1069
|
+
### LMenuTreeOption
|
|
1070
|
+
|
|
1071
|
+
```typescript
|
|
1072
|
+
interface LMenuTreeOption {
|
|
1073
|
+
id: string | number // 唯一标识
|
|
1074
|
+
label: string // 显示文本
|
|
1075
|
+
menuName: string // 菜单名称
|
|
1076
|
+
parentId: string | number // 父节点id
|
|
1077
|
+
weight: number // 权重
|
|
1078
|
+
menuType: 'M' | 'C' | 'F' // M=目录 C=菜单 F=按钮
|
|
1079
|
+
children?: LMenuTreeOption[] // 子节点
|
|
1080
|
+
}
|
|
1081
|
+
```
|
|
1082
|
+
|
|
1083
|
+
### Events
|
|
1084
|
+
|
|
1085
|
+
| 事件名 | 说明 | 参数 |
|
|
1086
|
+
| ----------------- | --------------------------------------------- | ------------------------- |
|
|
1087
|
+
| update:modelValue | 选中值变化,**包含全选节点和半选父节点的 id** | `Array<string \| number>` |
|
|
1088
|
+
|
|
1089
|
+
### 方法(通过 ref 调用)
|
|
1090
|
+
|
|
1091
|
+
| 方法名 | 说明 |
|
|
1092
|
+
| ------------- | ------------ |
|
|
1093
|
+
| expandAll() | 展开全部节点 |
|
|
1094
|
+
| collapseAll() | 收起全部节点 |
|
|
1095
|
+
|
|
1096
|
+
### 节点联动规则
|
|
1097
|
+
|
|
1098
|
+
- 勾选非按钮类型节点:自动勾选其所有后代非按钮类型节点
|
|
1099
|
+
- 取消勾选非按钮类型节点:自动取消勾选其所有后代非按钮类型节点
|
|
1100
|
+
- 按钮类型节点 (`menuType: 'F'`):不参与级联计算
|
|
1101
|
+
|
|
1102
|
+
---
|
|
1103
|
+
|
|
1104
|
+
## LSignStatusFlow
|
|
1105
|
+
|
|
1106
|
+
### 介绍
|
|
1107
|
+
|
|
1108
|
+
签署状态流程展示组件,以列表形式展示签署人及其签署状态。
|
|
1109
|
+
|
|
1110
|
+
### 基础用法
|
|
1111
|
+
|
|
1112
|
+
```vue
|
|
1113
|
+
<template>
|
|
1114
|
+
<LSignStatusFlow :items="signList" />
|
|
1115
|
+
</template>
|
|
1116
|
+
|
|
1117
|
+
<script setup lang="ts">
|
|
1118
|
+
const signList = [
|
|
1119
|
+
{ id: 1, psnName: '张三', orgName: '公司A', signResult: 2, operateTime: '2024-01-01 10:00' },
|
|
1120
|
+
{ id: 2, psnName: '李四', orgName: '公司B', signResult: 1, operateTime: '' },
|
|
1121
|
+
]
|
|
1122
|
+
</script>
|
|
1123
|
+
```
|
|
1124
|
+
|
|
1125
|
+
### Props
|
|
1126
|
+
|
|
1127
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
1128
|
+
| ----- | ------------ | ----------------------- | ------ |
|
|
1129
|
+
| items | 签署记录列表 | `LSignStatusFlowItem[]` | `[]` |
|
|
1130
|
+
|
|
1131
|
+
### LSignStatusFlowItem
|
|
1132
|
+
|
|
1133
|
+
```typescript
|
|
1134
|
+
interface LSignStatusFlowItem {
|
|
1135
|
+
id?: string | number // 唯一标识
|
|
1136
|
+
psnName?: string // 签署人姓名
|
|
1137
|
+
orgName?: string // 组织名称
|
|
1138
|
+
signResult?: string | number // 签署结果:2=已签署,4=已拒绝,其他=待签署
|
|
1139
|
+
operateTime?: string // 操作时间
|
|
1140
|
+
}
|
|
1141
|
+
```
|
|
1142
|
+
|
|
1143
|
+
### 签署状态说明
|
|
1144
|
+
|
|
1145
|
+
| signResult | 状态 | 标签颜色 |
|
|
1146
|
+
| ---------- | ------ | --------- |
|
|
1147
|
+
| `2` | 已签署 | `success` |
|
|
1148
|
+
| `4` | 已拒绝 | `error` |
|
|
1149
|
+
| 其他 | 待签署 | `warning` |
|
|
1150
|
+
|
|
1151
|
+
---
|
|
1152
|
+
|
|
1153
|
+
## LUploadFile
|
|
1154
|
+
|
|
1155
|
+
### 介绍
|
|
1156
|
+
|
|
1157
|
+
文件上传组件,基于 Ant Design Vue `Upload` 封装,支持附件上传、文件预览、只读模式。
|
|
1158
|
+
|
|
1159
|
+
### 基础用法
|
|
1160
|
+
|
|
1161
|
+
```vue
|
|
1162
|
+
<template>
|
|
1163
|
+
<LUploadFile
|
|
1164
|
+
v-model="fileList"
|
|
1165
|
+
:action="uploadUrl"
|
|
1166
|
+
:max-count="6"
|
|
1167
|
+
accept=".jpg,.png,.pdf,.docx"
|
|
1168
|
+
/>
|
|
1169
|
+
</template>
|
|
1170
|
+
|
|
1171
|
+
<script setup lang="ts">
|
|
1172
|
+
import type { LUploadFileList } from '@xinlian-frontend/lui'
|
|
1173
|
+
|
|
1174
|
+
const fileList = ref<LUploadFileList>([])
|
|
1175
|
+
const uploadUrl = '/api/upload'
|
|
1176
|
+
</script>
|
|
1177
|
+
```
|
|
1178
|
+
|
|
1179
|
+
### Props
|
|
1180
|
+
|
|
1181
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
1182
|
+
| -------------------- | ------------------------ | ---------------------- | --------------------------------------- |
|
|
1183
|
+
| modelValue (v-model) | 已上传文件列表 | `LUploadFileList` | `[]` |
|
|
1184
|
+
| type | 展示类型 | `'normal' \| 'inline'` | `'normal'` |
|
|
1185
|
+
| readonly | 只读模式(隐藏上传按钮) | `boolean` | `false` |
|
|
1186
|
+
| accept | 允许的文件类型 | `string` | `.jpg,.png,.jpeg,.docx,.pdf,.xls,.xlsx` |
|
|
1187
|
+
| hint | 提示文本 | `string` | `-` |
|
|
1188
|
+
| action | 上传地址 | `string` | `-` |
|
|
1189
|
+
| uploadText | 上传按钮文本 | `string` | `'上传附件'` |
|
|
1190
|
+
| headers | 请求头 | `any` | `-` |
|
|
1191
|
+
| maxCount | 最大上传数量 | `number` | `6` |
|
|
1192
|
+
| maxSizeMb | 单个文件大小限制(MB) | `number` | `-` |
|
|
1193
|
+
|
|
1194
|
+
### LUploadFileList
|
|
1195
|
+
|
|
1196
|
+
```typescript
|
|
1197
|
+
interface LUploadFileItem {
|
|
1198
|
+
fileId: string // 文件id
|
|
1199
|
+
url?: string // 文件地址
|
|
1200
|
+
fileUrl?: string // 文件地址(别名)
|
|
1201
|
+
originalFileName?: string // 原文件名
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
type LUploadFileList = LUploadFileItem[]
|
|
1205
|
+
```
|
|
1206
|
+
|
|
1207
|
+
### Events
|
|
1208
|
+
|
|
1209
|
+
| 事件名 | 说明 | 参数 |
|
|
1210
|
+
| ----------------- | ------------ | ----------------- |
|
|
1211
|
+
| update:modelValue | 文件列表变化 | `LUploadFileList` |
|
|
1212
|
+
|
|
1213
|
+
> 组件内部集成了 `LFilePreview`,上传后可直接点击文件进行预览。
|
|
1214
|
+
|
|
1215
|
+
### 完整使用示例
|
|
1216
|
+
|
|
1217
|
+
```vue
|
|
1218
|
+
<template>
|
|
1219
|
+
<LUploadFile
|
|
1220
|
+
v-model="fileList"
|
|
1221
|
+
action="/api/file/upload"
|
|
1222
|
+
:max-count="6"
|
|
1223
|
+
:max-size-mb="10"
|
|
1224
|
+
hint="支持 jpg、png、pdf、docx 格式,单个文件不超过 10MB"
|
|
1225
|
+
@change="handleFileChange"
|
|
1226
|
+
/>
|
|
1227
|
+
</template>
|
|
1228
|
+
|
|
1229
|
+
<script setup lang="ts">
|
|
1230
|
+
import type { LUploadFileList } from '@xinlian-frontend/lui'
|
|
1231
|
+
|
|
1232
|
+
const fileList = ref<LUploadFileList>([])
|
|
1233
|
+
|
|
1234
|
+
function handleFileChange(files: LUploadFileList) {
|
|
1235
|
+
console.log('当前文件列表:', files)
|
|
1236
|
+
}
|
|
1237
|
+
</script>
|
|
1238
|
+
```
|
|
1239
|
+
|
|
1240
|
+
---
|
|
1241
|
+
|
|
1242
|
+
## LUploadImage
|
|
1243
|
+
|
|
1244
|
+
### 介绍
|
|
1245
|
+
|
|
1246
|
+
图片/视频上传组件,基于 Ant Design Vue `Upload` 封装,使用卡片样式展示,支持预览。
|
|
1247
|
+
|
|
1248
|
+
### 基础用法
|
|
1249
|
+
|
|
1250
|
+
```vue
|
|
1251
|
+
<template>
|
|
1252
|
+
<LUploadImage v-model="imageList" :action="uploadUrl" :max-count="6" accept="image/*" />
|
|
1253
|
+
</template>
|
|
1254
|
+
|
|
1255
|
+
<script setup lang="ts">
|
|
1256
|
+
import type { LUploadFileList } from '@xinlian-frontend/lui'
|
|
1257
|
+
|
|
1258
|
+
const imageList = ref<LUploadFileList>([])
|
|
1259
|
+
const uploadUrl = '/api/upload'
|
|
1260
|
+
</script>
|
|
1261
|
+
```
|
|
1262
|
+
|
|
1263
|
+
### Props
|
|
1264
|
+
|
|
1265
|
+
| 参数 | 说明 | 类型 | 默认值 |
|
|
1266
|
+
| -------------------- | -------------- | ---------------------- | ----------------- |
|
|
1267
|
+
| modelValue (v-model) | 已上传文件列表 | `LUploadFileList` | `[]` |
|
|
1268
|
+
| type | 展示类型 | `'normal' \| 'inline'` | `'normal'` |
|
|
1269
|
+
| readonly | 只读模式 | `boolean` | `false` |
|
|
1270
|
+
| accept | 允许的文件类型 | `string` | `image/*,video/*` |
|
|
1271
|
+
| hint | 提示文本 | `string` | `-` |
|
|
1272
|
+
| action | 上传地址 | `string` | `-` |
|
|
1273
|
+
| uploadText | 上传按钮文本 | `string` | `'上传图片'` |
|
|
1274
|
+
| headers | 请求头 | `any` | `-` |
|
|
1275
|
+
| maxCount | 最大上传数量 | `number` | `6` |
|
|
1276
|
+
|
|
1277
|
+
> 类型定义与事件同 `LUploadFile`。
|
|
1278
|
+
|
|
1279
|
+
---
|
|
1280
|
+
|
|
1281
|
+
## LFilePreview
|
|
1282
|
+
|
|
1283
|
+
### 介绍
|
|
1284
|
+
|
|
1285
|
+
通用文件预览组件,支持图片、PDF、Word、Excel、视频等多种文件格式的在线预览。
|
|
1286
|
+
|
|
1287
|
+
### 基础用法
|
|
1288
|
+
|
|
1289
|
+
```vue
|
|
1290
|
+
<template>
|
|
1291
|
+
<LFilePreview ref="previewRef" />
|
|
1292
|
+
</template>
|
|
1293
|
+
|
|
1294
|
+
<script setup lang="ts">
|
|
1295
|
+
import { ref } from 'vue'
|
|
1296
|
+
|
|
1297
|
+
const previewRef = ref()
|
|
1298
|
+
|
|
1299
|
+
// 预览图片
|
|
1300
|
+
previewRef.value?.showDialog('https://example.com/image.jpg')
|
|
1301
|
+
|
|
1302
|
+
// 预览 PDF
|
|
1303
|
+
previewRef.value?.showDialog('https://example.com/document.pdf')
|
|
1304
|
+
|
|
1305
|
+
// 预览 Word
|
|
1306
|
+
previewRef.value?.showDialog('https://example.com/document.docx')
|
|
1307
|
+
|
|
1308
|
+
// 预览 Excel
|
|
1309
|
+
previewRef.value?.showDialog('https://example.com/spreadsheet.xlsx')
|
|
1310
|
+
|
|
1311
|
+
// 预览视频
|
|
1312
|
+
previewRef.value?.showDialog('https://example.com/video.mp4')
|
|
1313
|
+
</script>
|
|
1314
|
+
```
|
|
1315
|
+
|
|
1316
|
+
### 方法
|
|
1317
|
+
|
|
1318
|
+
| 方法名 | 说明 | 参数 |
|
|
1319
|
+
| ---------------------- | ------------ | ---------------------------------------------------------------------------- |
|
|
1320
|
+
| showDialog(url, type?) | 打开预览弹窗 | `url: string` 文件地址;`type?: string` 可选文件类型,不传则根据后缀自动识别 |
|
|
1321
|
+
|
|
1322
|
+
### 支持的文件类型
|
|
1323
|
+
|
|
1324
|
+
| 类型 | 扩展名 | 预览方式 |
|
|
1325
|
+
| ----- | --------------------------------------- | --------------------------------- |
|
|
1326
|
+
| 图片 | png、jpg、jpeg、gif、bmp、webp | Ant Design Vue Image 组件全屏预览 |
|
|
1327
|
+
| PDF | pdf | VueOfficePdf 组件 |
|
|
1328
|
+
| Word | doc、docx | VueOfficeDocx 组件 |
|
|
1329
|
+
| Excel | xls、xlsx | VueOfficeExcel 组件 |
|
|
1330
|
+
| 视频 | mp4、webm、ogg、avi、mov、wmv、flv、mkv | HTML5 video 标签 |
|
|
1331
|
+
| 其他 | - | 显示"暂不支持预览"提示 |
|
|
1332
|
+
|
|
1333
|
+
### 注意事项
|
|
1334
|
+
|
|
1335
|
+
- 图片预览不通过弹窗,直接以全屏方式展示
|
|
1336
|
+
- 文件地址需可直接访问(含权限、跨域配置等)
|
|
1337
|
+
- 组件内部通过 `showDialog` 方法暴露给外部调用
|
|
1338
|
+
|
|
1339
|
+
---
|
|
1340
|
+
|
|
1341
|
+
## 全局引入
|
|
1342
|
+
|
|
1343
|
+
```typescript
|
|
1344
|
+
// main.ts
|
|
1345
|
+
import { createApp } from 'vue'
|
|
1346
|
+
import App from './App.vue'
|
|
1347
|
+
import Lui from '@xinlian-frontend/lui'
|
|
1348
|
+
|
|
1349
|
+
const app = createApp(App)
|
|
1350
|
+
app.use(L Lui)
|
|
1351
|
+
app.mount('#app')
|
|
9
1352
|
```
|
|
10
1353
|
|
|
11
|
-
##
|
|
1354
|
+
## 按需引入
|
|
12
1355
|
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
import '@xinlian-frontend/lui/
|
|
1356
|
+
```typescript
|
|
1357
|
+
// 按需引入单个组件
|
|
1358
|
+
import LPageTable from '@xinlian-frontend/lui/es/page-table'
|
|
1359
|
+
import LDrawer from '@xinlian-frontend/lui/es/drawer'
|
|
16
1360
|
```
|
|
17
1361
|
|
|
1362
|
+
---
|
|
18
1363
|
|
|
1364
|
+
## 注意事项
|
|
19
1365
|
|
|
20
|
-
|
|
1366
|
+
1. 组件库基于 **Ant Design Vue** 封装,使用前请确保已正确安装 ant-design-vue
|
|
1367
|
+
2. 组件样式使用 **SCSS** 预处理器,支持主题变量覆盖
|
|
1368
|
+
3. 组件内部已处理大部分常见场景,如需深度定制可查看源码
|
|
1369
|
+
4. 所有涉及 `id` 的字段统一按 `string` 类型传递,避免长整型精度丢失
|
|
1370
|
+
5. 接口请求方法 `request` 的泛型无需嵌套 `ResponseData`
|
|
21
1371
|
|
|
22
|
-
MIT
|