@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 CHANGED
@@ -1,22 +1,1371 @@
1
- # lui
2
1
 
3
- lui 公共组件库,基于 Vue3 + Ant Design Vue。
4
2
 
5
- ## 安装
3
+ # L-UI 组件库文档
6
4
 
7
- ```bash
8
- npm install @xinlian-frontend/lui
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
- ```js
14
- import { LPageTable } from '@xinlian-frontend/lui'
15
- import '@xinlian-frontend/lui/style.css'
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
- ## License
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