@dt-frames/ui 1.0.8 → 1.0.11
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/es/components/curd/src/components/dialog.d.ts +1 -0
- package/es/components/forms/src/components/formIcon.d.ts +1 -1
- package/es/components/forms/src/types/form.type.d.ts +3 -3
- package/es/components/index.d.ts +3 -2
- package/es/components/modal/src/types/modal.type.d.ts +1 -1
- package/es/components/source/src/hooks/useFetch.d.ts +2 -2
- package/es/components/source/src/hooks/useSource.d.ts +8 -8
- package/es/components/source/src/types/table.type.d.ts +1 -1
- package/es/components/table/src/components/TableActions.d.ts +2 -2
- package/es/components/table/src/components/TableHeader.d.ts +2 -2
- package/es/components/table/src/components/editable/CellComponent.d.ts +14 -0
- package/es/components/table/src/components/editable/EditTableCell.d.ts +88 -0
- package/es/components/table/src/components/editable/componentMap.d.ts +4 -0
- package/es/components/table/src/components/editable/index.d.ts +9 -0
- package/es/components/table/src/components/setting/Download.d.ts +2 -2
- package/es/components/table/src/components/setting/Size.d.ts +2 -2
- package/es/components/table/src/index.d.ts +9 -5
- package/es/components/table/src/props.d.ts +1 -1
- package/es/components/table/src/types/table.type.d.ts +16 -0
- package/es/components/tree/index.d.ts +2 -0
- package/es/components/tree/src/hooks/useTree.d.ts +14 -0
- package/es/components/tree/src/props.d.ts +101 -0
- package/es/components/tree/src/type/tree.d.ts +85 -0
- package/es/components/tree/src/utils/tree.d.ts +5 -0
- package/es/components/upload/index.d.ts +3 -0
- package/es/components/upload/src/helper.d.ts +4 -0
- package/es/components/upload/src/index.d.ts +2788 -0
- package/es/components/upload/src/props.d.ts +40 -0
- package/es/components/upload/src/upload.d.ts +1634 -0
- package/es/index.js +2035 -308
- package/es/style/components/table/index.less +8 -2
- package/es/style/components/tree/index.less +41 -0
- package/es/style/components/upload/index.less +43 -0
- package/es/style/theme/header/index.less +1 -1
- package/es/theme/sider/components/basic-menu/basic-menu.d.ts +3 -3
- package/es/theme/tabs/components/TabContent.d.ts +2 -2
- package/package.json +2 -1
- package/src/components/curd/src/components/dialog.vue +4 -2
- package/src/components/curd/src/hooks/useCurd.tsx +1 -1
- package/src/components/forms/src/components/formItem.vue +15 -2
- package/src/components/forms/src/hooks/useFormEvents.ts +4 -3
- package/src/components/forms/src/hooks/useFormValues.ts +1 -1
- package/src/components/forms/src/types/form.type.ts +3 -3
- package/src/components/index.ts +9 -3
- package/src/components/modal/src/hooks/useModal.ts +5 -3
- package/src/components/modal/src/index.vue +2 -2
- package/src/components/modal/src/types/modal.type.ts +1 -1
- package/src/components/source/src/hooks/useFetch.ts +10 -6
- package/src/components/source/src/hooks/useSource.ts +32 -11
- package/src/components/source/src/types/table.type.ts +1 -1
- package/src/components/table/index.less +8 -2
- package/src/components/table/src/components/TableHeader.vue +2 -2
- package/src/components/table/src/components/TableRender.vue +1 -3
- package/src/components/table/src/components/editable/CellComponent.ts +57 -0
- package/src/components/table/src/components/editable/EditTableCell.vue +181 -0
- package/src/components/table/src/components/editable/componentMap.ts +18 -0
- package/src/components/table/src/components/editable/index.ts +58 -0
- package/src/components/table/src/hooks/useColumns.ts +15 -8
- package/src/components/table/src/hooks/useDataSource.ts +0 -13
- package/src/components/table/src/hooks/useTableHeader.ts +2 -2
- package/src/components/table/src/index.vue +6 -1
- package/src/components/table/src/props.ts +1 -1
- package/src/components/table/src/types/table.type.ts +28 -1
- package/src/components/tree/index.less +41 -0
- package/src/components/tree/index.ts +5 -0
- package/src/components/tree/src/components/TreeHeader.vue +97 -0
- package/src/components/tree/src/hooks/useTree.ts +239 -0
- package/src/components/tree/src/index.vue +392 -0
- package/src/components/tree/src/props.ts +133 -0
- package/src/components/tree/src/type/tree.ts +105 -0
- package/src/components/tree/src/utils/tree.ts +73 -0
- package/src/components/upload/index.less +43 -0
- package/src/components/upload/index.ts +7 -0
- package/src/components/upload/src/helper.ts +32 -0
- package/src/components/upload/src/index.vue +38 -0
- package/src/components/upload/src/props.ts +48 -0
- package/src/components/upload/src/upload.vue +166 -0
- package/src/theme/header/helper/menu-tree.ts +2 -2
- package/src/theme/header/index.less +1 -1
- package/src/theme/sider/helper/split-menu.ts +2 -2
- package/es/components/dialog/index.d.ts +0 -2
- package/es/components/dialog/src/hooks/useDialog.d.ts +0 -3
- package/src/components/dialog/index.ts +0 -5
- package/src/components/dialog/src/hooks/useDialog.ts +0 -85
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { Recordable } from "@dt-frames/core";
|
|
2
|
+
import { TreeDataItem } from "ant-design-vue/lib/tree";
|
|
3
|
+
import { PropType } from "vue";
|
|
4
|
+
import { CheckKeys, ContextMenuItem, FieldNames, TreeActionItem, TreeItem } from "./type/tree"
|
|
5
|
+
|
|
6
|
+
export const BasicProps = {
|
|
7
|
+
loading: {
|
|
8
|
+
type: Boolean,
|
|
9
|
+
default: false,
|
|
10
|
+
},
|
|
11
|
+
// 粘性选择
|
|
12
|
+
checkStrictly: Boolean,
|
|
13
|
+
// 展开的key值
|
|
14
|
+
expandedKeys: {
|
|
15
|
+
type: Array as PropType<KeyType[]>,
|
|
16
|
+
default: () => []
|
|
17
|
+
},
|
|
18
|
+
// 设置选中的key
|
|
19
|
+
selectedKeys: {
|
|
20
|
+
type: Array as PropType<KeyType[]>,
|
|
21
|
+
default: () => []
|
|
22
|
+
},
|
|
23
|
+
// 选中的节点
|
|
24
|
+
checkedKeys: {
|
|
25
|
+
type: Array as PropType<CheckKeys>,
|
|
26
|
+
default: () => []
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
// 定义树节点的lable title children 名称
|
|
30
|
+
fieldNames: {
|
|
31
|
+
type: Object as PropType<FieldNames>,
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
beforeRightClick: {
|
|
35
|
+
type: Function as PropType<(...arg: any) => ContextMenuItem[]>,
|
|
36
|
+
default: undefined,
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
rightMenuList: {
|
|
40
|
+
type: Array as PropType<ContextMenuItem[]>,
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
//
|
|
44
|
+
renderIcon: {
|
|
45
|
+
type: Function as PropType<(params: Recordable) => string>,
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
// 高亮搜索值,仅高亮具体匹配值(通过title)值为true时使用默认色值,值为#xxx时使用此值替代且高亮开启
|
|
49
|
+
highlight: {
|
|
50
|
+
type: [Boolean, String] as PropType<Boolean | String>,
|
|
51
|
+
default: false,
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
actionList: {
|
|
55
|
+
type: Array as PropType<TreeActionItem[]>,
|
|
56
|
+
default: () => [],
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
clickRowToExpand: {
|
|
60
|
+
type: Boolean,
|
|
61
|
+
default: false,
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
searchValue: {
|
|
65
|
+
type: String,
|
|
66
|
+
default: ''
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
filterFn: {
|
|
70
|
+
type: Function as PropType< (searchValue: any, node: TreeItem, fieldNames: FieldNames) => boolean >,
|
|
71
|
+
default: undefined,
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
checkable: Boolean,
|
|
75
|
+
|
|
76
|
+
// 搜索完成时自动展开结果
|
|
77
|
+
expandOnSearch: Boolean,
|
|
78
|
+
|
|
79
|
+
// 搜索完成自动选中所有结果,当且仅当 checkable===true 时生效
|
|
80
|
+
checkOnSearch: Boolean,
|
|
81
|
+
|
|
82
|
+
// 搜索完成自动select所有结果
|
|
83
|
+
selectedOnSearch: Boolean,
|
|
84
|
+
|
|
85
|
+
// 树数据
|
|
86
|
+
treeData: {
|
|
87
|
+
type: Array as PropType<TreeDataItem[]>
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
value: {
|
|
91
|
+
type: [Object, Array] as PropType<KeyType[] | CheckKeys>
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
title: {
|
|
95
|
+
type: String,
|
|
96
|
+
default: '',
|
|
97
|
+
},
|
|
98
|
+
|
|
99
|
+
toolbar: Boolean,
|
|
100
|
+
search: Boolean,
|
|
101
|
+
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export const searchProps = {
|
|
105
|
+
title: {
|
|
106
|
+
type: String,
|
|
107
|
+
default: '',
|
|
108
|
+
},
|
|
109
|
+
toolbar: {
|
|
110
|
+
type: Boolean,
|
|
111
|
+
default: false,
|
|
112
|
+
},
|
|
113
|
+
checkable: {
|
|
114
|
+
type: Boolean,
|
|
115
|
+
default: false,
|
|
116
|
+
},
|
|
117
|
+
search: {
|
|
118
|
+
type: Boolean,
|
|
119
|
+
default: false,
|
|
120
|
+
},
|
|
121
|
+
searchText: {
|
|
122
|
+
type: String,
|
|
123
|
+
default: '',
|
|
124
|
+
},
|
|
125
|
+
checkAll: {
|
|
126
|
+
type: Function,
|
|
127
|
+
default: undefined,
|
|
128
|
+
},
|
|
129
|
+
expandAll: {
|
|
130
|
+
type: Function,
|
|
131
|
+
default: undefined,
|
|
132
|
+
},
|
|
133
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { Recordable } from "@dt-frames/core";
|
|
2
|
+
import { Fn } from "@vueuse/core"
|
|
3
|
+
import { TreeDataItem } from "ant-design-vue/lib/tree"
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
export enum ToolbarEnum {
|
|
7
|
+
SELECT_ALL,
|
|
8
|
+
UN_SELECT_ALL,
|
|
9
|
+
EXPAND_ALL,
|
|
10
|
+
UN_EXPAND_ALL,
|
|
11
|
+
CHECK_STRICTLY,
|
|
12
|
+
CHECK_UN_STRICTLY,
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type KeyType = string | number
|
|
16
|
+
|
|
17
|
+
export type CheckKeys =
|
|
18
|
+
| KeyType[]
|
|
19
|
+
| {
|
|
20
|
+
checked: string[] | number[];
|
|
21
|
+
halfChecked: string[] | number[]
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface TreeState {
|
|
25
|
+
expandedKeys: KeyType[]
|
|
26
|
+
selectedKeys: KeyType[]
|
|
27
|
+
checkedKeys: CheckKeys
|
|
28
|
+
checkStrictly: boolean
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface FieldNames {
|
|
32
|
+
children?: string
|
|
33
|
+
title?: string
|
|
34
|
+
key?: string
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface TreeItem extends TreeDataItem {
|
|
38
|
+
icon?: any
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface CreateContextOptions {
|
|
42
|
+
event: MouseEvent
|
|
43
|
+
icon?: string
|
|
44
|
+
styles?: any
|
|
45
|
+
items?: ContextMenuItem[]
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface InsertNodeParams {
|
|
49
|
+
parentKey: string | null
|
|
50
|
+
node: TreeDataItem
|
|
51
|
+
list?: TreeDataItem[]
|
|
52
|
+
push?: 'push' | 'unshift'
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface ContextMenuItem {
|
|
56
|
+
label: string
|
|
57
|
+
icon?: string
|
|
58
|
+
hidden?: boolean
|
|
59
|
+
disabled?: boolean
|
|
60
|
+
handler?: Fn
|
|
61
|
+
divider?: boolean
|
|
62
|
+
children?: ContextMenuItem[]
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface TreeActionItem {
|
|
66
|
+
render: (record: Recordable) => any
|
|
67
|
+
show?: boolean | ((record: Recordable) => boolean)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface InsertNodeParams {
|
|
71
|
+
parentKey: string | null
|
|
72
|
+
node: TreeDataItem
|
|
73
|
+
list?: TreeDataItem[]
|
|
74
|
+
push?: 'push' | 'unshift'
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export interface TreeHelperConfig {
|
|
78
|
+
id: string;
|
|
79
|
+
children: string;
|
|
80
|
+
pid: string;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface TreeActionType {
|
|
84
|
+
checkAll: (checkAll: boolean) => void
|
|
85
|
+
expandAll: (expandAll: boolean) => void
|
|
86
|
+
setExpandedKeys: (keys: KeyType[]) => void
|
|
87
|
+
getExpandedKeys: () => KeyType[]
|
|
88
|
+
setSelectedKeys: (keys: KeyType[]) => void
|
|
89
|
+
getSelectedKeys: () => KeyType[]
|
|
90
|
+
setCheckedKeys: (keys: CheckKeys) => void
|
|
91
|
+
getCheckedKeys: () => CheckKeys
|
|
92
|
+
filterByLevel: (level: number) => void
|
|
93
|
+
insertNodeByKey: (opt: InsertNodeParams) => void
|
|
94
|
+
insertNodesByKey: (opt: InsertNodeParams) => void
|
|
95
|
+
deleteNodeByKey: (key: string) => void
|
|
96
|
+
updateNodeByKey: (key: string, node: Omit<TreeDataItem, 'key'>) => void
|
|
97
|
+
setSearchValue: (value: string) => void
|
|
98
|
+
getSearchValue: () => string
|
|
99
|
+
onStrictlyChange: ( strictly: boolean ) => void
|
|
100
|
+
getSelectedNode: (
|
|
101
|
+
key: KeyType,
|
|
102
|
+
treeList?: TreeItem[],
|
|
103
|
+
selectNode?: TreeItem | null,
|
|
104
|
+
) => TreeItem | null
|
|
105
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { TreeHelperConfig } from "../type/tree"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 递归遍历树结构
|
|
5
|
+
* @param treeDatas 树数据
|
|
6
|
+
* @param callBack 回调
|
|
7
|
+
* @param parentNode 父节点
|
|
8
|
+
*/
|
|
9
|
+
export function eachTree(treeDatas: any[], callBack: Function, parentNode = {}) {
|
|
10
|
+
treeDatas.forEach( el => {
|
|
11
|
+
const newNode = callBack(el, parentNode) || el
|
|
12
|
+
|
|
13
|
+
if (el.children) {
|
|
14
|
+
eachTree( el.children, callBack, newNode )
|
|
15
|
+
}
|
|
16
|
+
} )
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
// 返回true就终止遍历,避免大量节点场景下无意义循环,引起浏览器卡顿
|
|
21
|
+
export function forEach<T = any>(
|
|
22
|
+
tree: T[],
|
|
23
|
+
func: (n: T) => any,
|
|
24
|
+
config: Partial<TreeHelperConfig> = {},
|
|
25
|
+
): void {
|
|
26
|
+
const list: any[] = [...tree]
|
|
27
|
+
const { children = 'children' } = config
|
|
28
|
+
|
|
29
|
+
for (let i = 0; i < list.length; i++) {
|
|
30
|
+
if (func(list[i])) {
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
children && list[i][children] && list.splice(i + 1, 0, ...list[i][children])
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function filter<T = any>(
|
|
38
|
+
tree: T[],
|
|
39
|
+
func: (n: T) => boolean,
|
|
40
|
+
config: Partial<TreeHelperConfig> = {},
|
|
41
|
+
): T[] {
|
|
42
|
+
// 获取配置
|
|
43
|
+
const children = config.children as string || 'children';
|
|
44
|
+
|
|
45
|
+
function listFilter(list: T[]) {
|
|
46
|
+
return list
|
|
47
|
+
.map((node: any) => ({ ...node }))
|
|
48
|
+
.filter((node) => {
|
|
49
|
+
|
|
50
|
+
// 递归调用 对含有children项 进行再次调用自身函数 listFilter
|
|
51
|
+
node[children] = node[children] && listFilter(node[children]);
|
|
52
|
+
|
|
53
|
+
// 执行传入的回调 func 进行过滤
|
|
54
|
+
return func(node) || (node[children] && node[children].length);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return listFilter(tree);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function treeToList<T = any>(tree: any, config: Partial<TreeHelperConfig> = {}): T {
|
|
62
|
+
const { children = 'children' } = config
|
|
63
|
+
|
|
64
|
+
const result: any = [...tree]
|
|
65
|
+
|
|
66
|
+
for (let i = 0; i < result.length; i++) {
|
|
67
|
+
if (!result[i][children!]) continue
|
|
68
|
+
result.splice(i + 1, 0, ...result[i][children!])
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return result
|
|
72
|
+
}
|
|
73
|
+
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
.dt-upload-wrap{
|
|
2
|
+
height: 350px;
|
|
3
|
+
padding: 10px 20px;
|
|
4
|
+
display: flex;
|
|
5
|
+
flex-direction: column;
|
|
6
|
+
|
|
7
|
+
.ant-table-wrapper{
|
|
8
|
+
flex: 1;
|
|
9
|
+
.ant-table-body{
|
|
10
|
+
border-bottom: 1px solid #e7e7e7;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.file-header{
|
|
16
|
+
display: flex;
|
|
17
|
+
flex-direction: row;
|
|
18
|
+
justify-content: space-between;
|
|
19
|
+
&>div{
|
|
20
|
+
display: flex;
|
|
21
|
+
flex-direction: row;
|
|
22
|
+
button{
|
|
23
|
+
margin-right: 10px;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.file-type-tips{
|
|
29
|
+
line-height: 24px;
|
|
30
|
+
padding: 5px 10px;
|
|
31
|
+
font-size: 12px;
|
|
32
|
+
display: flex;
|
|
33
|
+
margin: 10px 0;
|
|
34
|
+
border: 1px dashed @primary-color;
|
|
35
|
+
cursor: inherit;
|
|
36
|
+
span i{
|
|
37
|
+
color: @primary-color;
|
|
38
|
+
margin-right: 7px;
|
|
39
|
+
}
|
|
40
|
+
i{
|
|
41
|
+
color: #666;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { computed, Ref, unref } from "vue"
|
|
2
|
+
|
|
3
|
+
export function useHelpers(
|
|
4
|
+
acceptRef: Ref<string[]>,
|
|
5
|
+
helpTextRef: Ref<string>,
|
|
6
|
+
maxNumberRef: Ref<number>,
|
|
7
|
+
maxSizeRef: Ref<number>
|
|
8
|
+
) {
|
|
9
|
+
// 文件类型
|
|
10
|
+
const getAccept = computed(() => {
|
|
11
|
+
const accept = unref(acceptRef);
|
|
12
|
+
if (accept && accept.length > 0) {
|
|
13
|
+
return accept;
|
|
14
|
+
}
|
|
15
|
+
return [];
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
const getStringAccept = computed(() => {
|
|
19
|
+
return unref(getAccept)
|
|
20
|
+
.map((item) => {
|
|
21
|
+
if (item.indexOf('/') > 0 || item.startsWith('.')) {
|
|
22
|
+
return item
|
|
23
|
+
}
|
|
24
|
+
return `.${item}`
|
|
25
|
+
})
|
|
26
|
+
.join(',')
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
getStringAccept
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<DtModal
|
|
3
|
+
@save="handleSave()"
|
|
4
|
+
@register="register"
|
|
5
|
+
>
|
|
6
|
+
<div class="dt-upload-wrap">
|
|
7
|
+
<DtUpload ref="uploadRef" :defaultFiles="defaultFiles">
|
|
8
|
+
111
|
|
9
|
+
</DtUpload>
|
|
10
|
+
</div>
|
|
11
|
+
</DtModal>
|
|
12
|
+
</template>
|
|
13
|
+
|
|
14
|
+
<script lang="ts" setup>
|
|
15
|
+
import { ref } from 'vue'
|
|
16
|
+
import { DtModal, useModal } from '../../modal'
|
|
17
|
+
import DtUpload from './upload.vue'
|
|
18
|
+
|
|
19
|
+
const uploadRef = ref(null)
|
|
20
|
+
const emites = defineEmits(['register'])
|
|
21
|
+
|
|
22
|
+
// 注册弹框
|
|
23
|
+
const [register] = useModal({
|
|
24
|
+
width: '700px',
|
|
25
|
+
title: '文件上传',
|
|
26
|
+
maskClosable: false,
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
const defaultFiles = [
|
|
30
|
+
{ fileName: '叮咚发票667.09.pdf', fileId: '1' }
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
// 保存
|
|
34
|
+
function handleSave() {
|
|
35
|
+
console.log(uploadRef.value.allFilesRef)
|
|
36
|
+
alert("s-s-s-")
|
|
37
|
+
}
|
|
38
|
+
</script>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Fn } from "@vueuse/core"
|
|
2
|
+
import { PropType } from "vue"
|
|
3
|
+
|
|
4
|
+
export type FileType = {
|
|
5
|
+
fileName: String
|
|
6
|
+
[key: string]: any
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const basicUploadProps = {
|
|
10
|
+
// 是否显示模板下载
|
|
11
|
+
showTemplateDownload: {
|
|
12
|
+
type: Boolean,
|
|
13
|
+
default: false,
|
|
14
|
+
},
|
|
15
|
+
// 模板下载
|
|
16
|
+
templateDownload: {
|
|
17
|
+
type: Function as PropType<Fn>,
|
|
18
|
+
default: () => {}
|
|
19
|
+
},
|
|
20
|
+
helpText: {
|
|
21
|
+
type: String as PropType<string>,
|
|
22
|
+
default: '',
|
|
23
|
+
},
|
|
24
|
+
// 是否支持批量上传
|
|
25
|
+
multiple: {
|
|
26
|
+
type: Boolean as PropType<boolean>,
|
|
27
|
+
default: true,
|
|
28
|
+
},
|
|
29
|
+
// 文件支持的类型
|
|
30
|
+
accept: {
|
|
31
|
+
type: Array as PropType<string[]>,
|
|
32
|
+
default: () => [],
|
|
33
|
+
},
|
|
34
|
+
// 文件最大多少MB
|
|
35
|
+
maxSize: {
|
|
36
|
+
type: Number as PropType<number>,
|
|
37
|
+
default: 2,
|
|
38
|
+
},
|
|
39
|
+
// 最大数量的文件,Infinity不限制
|
|
40
|
+
maxNumber: {
|
|
41
|
+
type: Number as PropType<number>,
|
|
42
|
+
default: Infinity,
|
|
43
|
+
},
|
|
44
|
+
defaultFiles: {
|
|
45
|
+
type: Array as PropType<FileType[]>,
|
|
46
|
+
default: []
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="file-header">
|
|
3
|
+
<div>
|
|
4
|
+
<Upload
|
|
5
|
+
:accept="getStringAccept"
|
|
6
|
+
:multiple="multiple"
|
|
7
|
+
:before-upload="beforeUpload"
|
|
8
|
+
:show-upload-list="false"
|
|
9
|
+
>
|
|
10
|
+
<Button type="primary">
|
|
11
|
+
<span v-icon="'ic:baseline-file-upload'"></span>
|
|
12
|
+
文件上传
|
|
13
|
+
</Button>
|
|
14
|
+
</Upload>
|
|
15
|
+
<Button type="primary" v-if="showTemplateDownload" @click="templateDownload">
|
|
16
|
+
<span v-icon="'ic:baseline-file-download'"></span>
|
|
17
|
+
模板下载
|
|
18
|
+
</Button>
|
|
19
|
+
</div>
|
|
20
|
+
<slot></slot>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<div class="file-type-tips ant-alert-info">
|
|
24
|
+
<span v-icon="'ant-design:info-circle-outlined'"></span>
|
|
25
|
+
<i>请上传pptx、doc、jpg、jpeg、png、bmp、gif、xls、xlsx、txt、rar、zip、7z、tar、gz格式文件</i>
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
<DtTable @register="registerTable"></DtTable>
|
|
29
|
+
|
|
30
|
+
<Image
|
|
31
|
+
:width="200"
|
|
32
|
+
:style="{ display: 'none' }"
|
|
33
|
+
:preview="{
|
|
34
|
+
visible: imgVisable,
|
|
35
|
+
onVisibleChange: setImgVisible,
|
|
36
|
+
}"
|
|
37
|
+
src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png"
|
|
38
|
+
></Image>
|
|
39
|
+
|
|
40
|
+
</template>
|
|
41
|
+
|
|
42
|
+
<script lang="ts" setup>
|
|
43
|
+
import { h, ref, toRefs, watchEffect } from 'vue'
|
|
44
|
+
import { Button, Upload, Image } from 'ant-design-vue'
|
|
45
|
+
import { DtTable, useTable } from '../../table'
|
|
46
|
+
import { basicUploadProps } from './props'
|
|
47
|
+
import { useHelpers } from './helper'
|
|
48
|
+
import { useMessage } from '@dt-frames/core'
|
|
49
|
+
import * as SparkMD5 from 'spark-md5'
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
const { message } = useMessage()
|
|
53
|
+
|
|
54
|
+
const filesRef = ref([])
|
|
55
|
+
const historyFilesRef = ref([])
|
|
56
|
+
const allFilesRef = ref([])
|
|
57
|
+
|
|
58
|
+
// 控制图片预览显示隐藏
|
|
59
|
+
const imgVisable = ref( false )
|
|
60
|
+
const setImgVisible = (value) => imgVisable.value = value
|
|
61
|
+
|
|
62
|
+
const props = defineProps( basicUploadProps )
|
|
63
|
+
|
|
64
|
+
const { accept, helpText, maxNumber, maxSize } = toRefs(props)
|
|
65
|
+
const { getStringAccept } = useHelpers( accept, helpText, maxNumber, maxSize )
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
const [registerTable, { }] = useTable({
|
|
69
|
+
tableSetting: false,
|
|
70
|
+
pagination: false,
|
|
71
|
+
dataSource: allFilesRef,
|
|
72
|
+
columns: [
|
|
73
|
+
{ title: '文件名称', dataIndex: 'fileName' },
|
|
74
|
+
{ title: '上传状态', dataIndex: 'fileStatue', render(row) {
|
|
75
|
+
return h('span', {
|
|
76
|
+
style: `color: ${ row.status === 0 ? 'orange' : 'green' }`,
|
|
77
|
+
}, row.fileStatue)
|
|
78
|
+
} },
|
|
79
|
+
],
|
|
80
|
+
operations: {
|
|
81
|
+
expand: true,
|
|
82
|
+
btns: [
|
|
83
|
+
{ title: '预览', icon: 'ic:baseline-remove-red-eye',
|
|
84
|
+
ifShow(row) {
|
|
85
|
+
const supportFileTypes = ['pdf', 'jpg', 'jpeg', 'png', 'bmp', 'gif']
|
|
86
|
+
return supportFileTypes.includes( row.fileName.split('.').pop() )
|
|
87
|
+
},
|
|
88
|
+
action: () => {
|
|
89
|
+
setImgVisible(true)
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
{ title: '编辑', icon: 'mdi:text-box-edit-outline' },
|
|
93
|
+
{ title: '删除', icon: 'mdi:delete-outline' }
|
|
94
|
+
]
|
|
95
|
+
}
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
watchEffect(() => {
|
|
100
|
+
historyFilesRef.value = props.defaultFiles.map(file => {
|
|
101
|
+
return {
|
|
102
|
+
...file,
|
|
103
|
+
fileName: file.fileName,
|
|
104
|
+
status: 0,
|
|
105
|
+
fileStatue: '历史上传'
|
|
106
|
+
}
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
allFilesRef.value = [...historyFilesRef.value, ...filesRef.value]
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
function beforeUpload(file: File) {
|
|
114
|
+
const { maxSize } = props
|
|
115
|
+
|
|
116
|
+
if( maxSize && file.size / 1024 / 1024 >= maxSize ) {
|
|
117
|
+
message.error(`只能上传不超过${ maxSize }MB的文件!`)
|
|
118
|
+
return false
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
addFile( file )
|
|
122
|
+
|
|
123
|
+
return false
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// 添加文件
|
|
127
|
+
function addFile(file: File) {
|
|
128
|
+
let blobSlice = File.prototype.slice || (File.prototype as any).mozSlice || (File.prototype as any).webkitSlice
|
|
129
|
+
let chunkSize = 2097152,
|
|
130
|
+
chunks = Math.ceil(file.size / chunkSize),
|
|
131
|
+
currentChunk = 0,
|
|
132
|
+
spark = new SparkMD5.ArrayBuffer(),
|
|
133
|
+
fileReader = new FileReader()
|
|
134
|
+
|
|
135
|
+
fileReader.onload = function (e) {
|
|
136
|
+
spark.append(e.target['result']);
|
|
137
|
+
currentChunk++;
|
|
138
|
+
|
|
139
|
+
if (currentChunk < chunks) {
|
|
140
|
+
loadNext();
|
|
141
|
+
} else {
|
|
142
|
+
filesRef.value.push({
|
|
143
|
+
fileName: file.name,
|
|
144
|
+
fileId: spark.end(),
|
|
145
|
+
file,
|
|
146
|
+
status: 1,
|
|
147
|
+
fileStatue: '待上传'
|
|
148
|
+
})
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function loadNext() {
|
|
153
|
+
var start = currentChunk * chunkSize,
|
|
154
|
+
end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize
|
|
155
|
+
|
|
156
|
+
fileReader.readAsArrayBuffer(blobSlice.call(file, start, end))
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
loadNext()
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
defineExpose({
|
|
164
|
+
allFilesRef
|
|
165
|
+
})
|
|
166
|
+
</script>
|
|
@@ -13,7 +13,7 @@ function deleteChildrenProp( menu: any ) {
|
|
|
13
13
|
|
|
14
14
|
// 获取当前路由的面包屑
|
|
15
15
|
export function getBreadCrumb(path: string, menus?: Menus[]) {
|
|
16
|
-
const _menus = menus || DtCache.getLocal(CacheKey.MENUS) || []
|
|
16
|
+
const _menus = menus || DtCache.getLocal(CacheKey.MENUS)?.children || []
|
|
17
17
|
|
|
18
18
|
let routes: Menus[] = []
|
|
19
19
|
|
|
@@ -58,7 +58,7 @@ export function getFilterMenu( filter: string = '', flag: boolean = false) {
|
|
|
58
58
|
} )
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
getTargetMenus( DtCache.getLocal(CacheKey.MENUS) );
|
|
61
|
+
getTargetMenus( DtCache.getLocal(CacheKey.MENUS)?.children );
|
|
62
62
|
|
|
63
63
|
return _menus;
|
|
64
64
|
}
|
|
@@ -67,7 +67,7 @@ export function useSplitMenu( splitType: Ref<MenuSplitTye> ) {
|
|
|
67
67
|
|
|
68
68
|
async function getMenus() {
|
|
69
69
|
if (unref(normalType)) {
|
|
70
|
-
menusRef.value = DtCache.getLocal(CacheKey.MENUS)
|
|
70
|
+
menusRef.value = DtCache.getLocal(CacheKey.MENUS)?.children
|
|
71
71
|
return;
|
|
72
72
|
}
|
|
73
73
|
|
|
@@ -85,7 +85,7 @@ export function useSplitMenu( splitType: Ref<MenuSplitTye> ) {
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
|
|
88
|
-
async function getMenus() { return DtCache.getLocal(CacheKey.MENUS) }
|
|
88
|
+
async function getMenus() { return DtCache.getLocal(CacheKey.MENUS)?.children }
|
|
89
89
|
|
|
90
90
|
function getFirstMenuPath(item: Menus) {
|
|
91
91
|
let isFind = false, path = ''
|