@dt-frames/ui 1.0.9 → 1.0.12
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 +8 -3
- package/es/components/forms/src/components/formIcon.d.ts +1 -1
- package/es/components/forms/src/components/formInputUseDialog.d.ts +903 -0
- package/es/components/forms/src/types/form.type.d.ts +6 -4
- package/es/components/index.d.ts +3 -2
- package/es/components/modal/src/types/modal.type.d.ts +5 -2
- 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/hooks/useCustomRow.d.ts +19 -0
- package/es/components/table/src/index.d.ts +29 -6
- package/es/components/table/src/props.d.ts +5 -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 +2807 -0
- package/es/components/upload/src/props.d.ts +40 -0
- package/es/components/upload/src/upload.d.ts +1653 -0
- package/es/index.js +2113 -270
- package/es/style/components/forms/index.less +23 -0
- 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 +7 -4
- package/src/components/curd/src/hooks/useCurd.tsx +1 -1
- package/src/components/forms/index.less +23 -0
- package/src/components/forms/src/componentMap.ts +2 -0
- package/src/components/forms/src/components/formInputUseDialog.vue +43 -0
- package/src/components/forms/src/components/formItem.vue +25 -12
- 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 +9 -3
- package/src/components/index.ts +9 -3
- package/src/components/modal/src/hooks/useModal.ts +12 -4
- package/src/components/modal/src/index.vue +2 -2
- package/src/components/modal/src/types/modal.type.ts +5 -2
- package/src/components/source/src/hooks/useFetch.ts +10 -6
- package/src/components/source/src/hooks/useSource.ts +33 -12
- 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/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/useCustomRow.ts +86 -0
- 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 +20 -3
- package/src/components/table/src/props.ts +4 -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
|
@@ -1,23 +1,27 @@
|
|
|
1
|
-
import { http, isString, JsonResult, Recordable, ApiType } from "@dt-frames/core";
|
|
1
|
+
import { http, isString, JsonResult, Recordable, ApiType, isObject } from "@dt-frames/core";
|
|
2
2
|
|
|
3
3
|
export function useFetch(api: string | ApiType, baseUrl: string = '') {
|
|
4
4
|
/**
|
|
5
5
|
* 发送请求
|
|
6
6
|
* handleParams 记录返回的值
|
|
7
7
|
*/
|
|
8
|
-
function fetch(params:
|
|
9
|
-
let type, header = { }, model = {}
|
|
8
|
+
function fetch(params: any) {
|
|
9
|
+
let type, header = { }, model = {}
|
|
10
10
|
if(isString( api )) {
|
|
11
|
-
|
|
11
|
+
api = baseUrl + api
|
|
12
12
|
} else {
|
|
13
13
|
type = api.type
|
|
14
|
-
|
|
14
|
+
if( api.api.indexOf(baseUrl) === -1 ) {
|
|
15
|
+
api.api = `${baseUrl}${api.api}`
|
|
16
|
+
}
|
|
15
17
|
header = api.header
|
|
16
18
|
model = api.model
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
return new Promise(( resolve, reject ) => {
|
|
20
|
-
|
|
22
|
+
let param = isObject(params) ? Object.assign({}, model, params) : params
|
|
23
|
+
|
|
24
|
+
http[type || 'post']( api, param, {
|
|
21
25
|
...header,
|
|
22
26
|
...{ onlyData: false }
|
|
23
27
|
}).then(
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ref, reactive, toRaw, Ref } from 'vue'
|
|
2
|
-
import { isString, Recordable, useMessage } from "@dt-frames/core"
|
|
2
|
+
import { isFunction, isString, Recordable, useMessage } from "@dt-frames/core"
|
|
3
3
|
import { BaseDataType, SourceType } from "../types/source.type"
|
|
4
4
|
import { useFetch } from './useFetch'
|
|
5
5
|
import { TableParamsType } from '../types/table.type'
|
|
@@ -19,11 +19,22 @@ export function useSource(opt: SourceType) {
|
|
|
19
19
|
|
|
20
20
|
const { message } = useMessage()
|
|
21
21
|
const apiFul: Recordable = {}
|
|
22
|
+
const apiPath: Recordable = {}
|
|
22
23
|
|
|
23
24
|
// 定义加载状态
|
|
24
25
|
for( let it in api ) {
|
|
25
26
|
loading['on' + it.slice(0,1).toUpperCase() + it.slice(1).toLowerCase()] = ref(false)
|
|
26
|
-
|
|
27
|
+
|
|
28
|
+
if( isString(api[it] )) {
|
|
29
|
+
apiFul[it] = baseUrl + api[it]
|
|
30
|
+
} else {
|
|
31
|
+
apiFul[it] = {
|
|
32
|
+
...(api[it] as ApiType),
|
|
33
|
+
api: baseUrl + (api[it] as ApiType).api
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
apiPath[it] = baseUrl + (isString(api[it]) ? api[it] : (api[it] as ApiType).api)
|
|
27
38
|
}
|
|
28
39
|
|
|
29
40
|
// 定义分页数据
|
|
@@ -48,7 +59,7 @@ export function useSource(opt: SourceType) {
|
|
|
48
59
|
/**
|
|
49
60
|
* 分页查询
|
|
50
61
|
*/
|
|
51
|
-
function onSearch(model: Recordable) {
|
|
62
|
+
function onSearch(model: Recordable = {}) {
|
|
52
63
|
baseData.entityDTO = { ...model }
|
|
53
64
|
baseData.pageDTO.pageNo = 0
|
|
54
65
|
loading.onSearch.value = true
|
|
@@ -71,15 +82,23 @@ export function useSource(opt: SourceType) {
|
|
|
71
82
|
* 如果为首次 则为数据初始化 不需要查询
|
|
72
83
|
*/
|
|
73
84
|
function onTableChange( params: TableParamsType, needSearch: boolean = true ) {
|
|
74
|
-
const { pagination, showBtnLoading, sort
|
|
85
|
+
const { pagination, showBtnLoading, sort, filter } = params
|
|
75
86
|
|
|
76
87
|
baseData.pageDTO = {
|
|
77
88
|
pageNo: pagination.current - 1,
|
|
78
89
|
pageSize: pagination.pageSize
|
|
79
90
|
}
|
|
80
91
|
|
|
81
|
-
|
|
82
|
-
|
|
92
|
+
const { field, order } = sort
|
|
93
|
+
|
|
94
|
+
if( field ) {
|
|
95
|
+
baseData.orderDTOs = [{
|
|
96
|
+
propertyName: field,
|
|
97
|
+
dir: order === 'ascend' ? 'asc' : 'desc'
|
|
98
|
+
}]
|
|
99
|
+
} else {
|
|
100
|
+
baseData.orderDTOs = []
|
|
101
|
+
}
|
|
83
102
|
|
|
84
103
|
if( needSearch ) search()
|
|
85
104
|
}
|
|
@@ -115,7 +134,7 @@ export function useSource(opt: SourceType) {
|
|
|
115
134
|
function onAdd(model: Recordable) {
|
|
116
135
|
const { fetch } = useFetch(add, baseUrl)
|
|
117
136
|
|
|
118
|
-
fetch(model).then( (rsp: any) => {
|
|
137
|
+
return fetch(model).then( (rsp: any) => {
|
|
119
138
|
message.success('新增成功')
|
|
120
139
|
search()
|
|
121
140
|
} )
|
|
@@ -132,7 +151,7 @@ export function useSource(opt: SourceType) {
|
|
|
132
151
|
// 修改
|
|
133
152
|
function onUpdate(model: Recordable) {
|
|
134
153
|
const { fetch } = useFetch(update, baseUrl)
|
|
135
|
-
fetch(model).then( (rsp: any) => {
|
|
154
|
+
return fetch(model).then( (rsp: any) => {
|
|
136
155
|
message.success('更新数据成功')
|
|
137
156
|
search()
|
|
138
157
|
} )
|
|
@@ -143,7 +162,8 @@ export function useSource(opt: SourceType) {
|
|
|
143
162
|
function onDeletes(ids: any) {
|
|
144
163
|
const { fetch } = useFetch(deletes, baseUrl)
|
|
145
164
|
|
|
146
|
-
fetch(ids).then( (rsp: any) => {
|
|
165
|
+
fetch(toRaw(ids)).then( (rsp: any) => {
|
|
166
|
+
message.success(`${ ids.length > 1 ? '批量' : '' } 删除成功!`)
|
|
147
167
|
search()
|
|
148
168
|
} )
|
|
149
169
|
}
|
|
@@ -176,8 +196,8 @@ export function useSource(opt: SourceType) {
|
|
|
176
196
|
}
|
|
177
197
|
|
|
178
198
|
return {
|
|
179
|
-
api,
|
|
180
|
-
|
|
199
|
+
api: apiFul,
|
|
200
|
+
apiPath,
|
|
181
201
|
form,
|
|
182
202
|
table,
|
|
183
203
|
curd,
|
|
@@ -188,6 +208,7 @@ export function useSource(opt: SourceType) {
|
|
|
188
208
|
onUpdate,
|
|
189
209
|
onTableChange,
|
|
190
210
|
onDownload,
|
|
191
|
-
onSearch
|
|
211
|
+
onSearch,
|
|
212
|
+
|
|
192
213
|
}
|
|
193
214
|
}
|
|
@@ -77,8 +77,8 @@
|
|
|
77
77
|
display: inline-block;
|
|
78
78
|
vertical-align: middle;
|
|
79
79
|
cursor: pointer;
|
|
80
|
-
|
|
81
|
-
|
|
80
|
+
i{
|
|
81
|
+
color: @primary-color;
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
84
|
|
|
@@ -171,3 +171,9 @@
|
|
|
171
171
|
color: #333;
|
|
172
172
|
}
|
|
173
173
|
}
|
|
174
|
+
|
|
175
|
+
.edit-cell-rule-popover .ant-popover-inner-content{
|
|
176
|
+
padding: 4px 8px;
|
|
177
|
+
color: #ed6f6f;
|
|
178
|
+
border-radius: 2px;
|
|
179
|
+
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
<slot name="toolbar"></slot>
|
|
10
10
|
</div>
|
|
11
11
|
|
|
12
|
-
<div class="dt-table-header-actions__right">
|
|
12
|
+
<div class="dt-table-header-actions__right" v-if="tableTools">
|
|
13
13
|
<TableSettinCom
|
|
14
14
|
:setting="tableTools"
|
|
15
15
|
@columns-change="handleColumnChange"
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
},
|
|
43
43
|
props: {
|
|
44
44
|
tableTools: {
|
|
45
|
-
type: Object as PropType<TableSetting>
|
|
45
|
+
type: [Object, Boolean] as PropType<TableSetting | boolean>
|
|
46
46
|
},
|
|
47
47
|
toolbar: {
|
|
48
48
|
type: Array as PropType<BtnsType[]>,
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Recordable } from "@dt-frames/core"
|
|
2
|
+
import { Popover } from "ant-design-vue"
|
|
3
|
+
import { DefineComponent, FunctionalComponent, h, Ref } from "vue"
|
|
4
|
+
import { ComponentType } from "../../types/table.type"
|
|
5
|
+
import { componentMap } from "./componentMap"
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
type ComponentProps = {
|
|
9
|
+
component: ComponentType
|
|
10
|
+
rule: boolean
|
|
11
|
+
popoverVisible: boolean
|
|
12
|
+
ruleMessage: string
|
|
13
|
+
getPopupContainer?: any
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type EditRecordRow<T = Recordable> = Partial<
|
|
17
|
+
{
|
|
18
|
+
onEdit: (editable: boolean, submit?: boolean) => Promise<boolean>;
|
|
19
|
+
onValid: () => Promise<boolean>;
|
|
20
|
+
editable: boolean;
|
|
21
|
+
onCancel: Function;
|
|
22
|
+
onSubmit: Function;
|
|
23
|
+
submitCbs: Function[];
|
|
24
|
+
cancelCbs: Function[];
|
|
25
|
+
validCbs: Function[];
|
|
26
|
+
editValueRefs: Recordable<Ref>;
|
|
27
|
+
} & T
|
|
28
|
+
>
|
|
29
|
+
|
|
30
|
+
export const CellComponent: FunctionalComponent = ({
|
|
31
|
+
component = 'Input',
|
|
32
|
+
rule = true,
|
|
33
|
+
ruleMessage,
|
|
34
|
+
popoverVisible,
|
|
35
|
+
getPopupContainer
|
|
36
|
+
}: ComponentProps,
|
|
37
|
+
{ attrs }
|
|
38
|
+
) => {
|
|
39
|
+
const Comp = componentMap.get(component) as DefineComponent
|
|
40
|
+
|
|
41
|
+
const DefaultComp = h(Comp, attrs)
|
|
42
|
+
|
|
43
|
+
if (!rule) return DefaultComp
|
|
44
|
+
|
|
45
|
+
return h(
|
|
46
|
+
Popover,
|
|
47
|
+
{
|
|
48
|
+
overlayClassName: 'edit-cell-rule-popover',
|
|
49
|
+
visible: !!popoverVisible,
|
|
50
|
+
...(getPopupContainer ? { getPopupContainer } : {}),
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
default: () => DefaultComp,
|
|
54
|
+
content: () => ruleMessage,
|
|
55
|
+
},
|
|
56
|
+
)
|
|
57
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="editable-cell">
|
|
3
|
+
<CellComponent
|
|
4
|
+
ref="elRef"
|
|
5
|
+
v-bind="getComponentProps"
|
|
6
|
+
:component = "column?.editComponent"
|
|
7
|
+
:popoverVisible = "getRuleVisible"
|
|
8
|
+
:rule = "editRule"
|
|
9
|
+
:ruleMessage = "ruleMessage"
|
|
10
|
+
:class = "getWrapperClass"
|
|
11
|
+
:onChange = "handleChange"
|
|
12
|
+
:onOptionsChange = "handleOptionsChange"
|
|
13
|
+
>
|
|
14
|
+
</CellComponent>
|
|
15
|
+
</div>
|
|
16
|
+
</template>
|
|
17
|
+
|
|
18
|
+
<script lang="tsx">
|
|
19
|
+
import { DtEvent, isBoolean, isNumber, isString, Recordable } from "@dt-frames/core"
|
|
20
|
+
import { isFunction } from "@vueuse/core"
|
|
21
|
+
import { omit } from 'lodash-es'
|
|
22
|
+
import { Spin } from "ant-design-vue"
|
|
23
|
+
import { defineComponent, PropType, ref, unref, computed, toRaw } from "vue"
|
|
24
|
+
import { BasicColumn, ComponentType, LableValOptions } from "../../types/table.type"
|
|
25
|
+
import { CellComponent, EditRecordRow } from "./CellComponent"
|
|
26
|
+
import { getTableInstance } from "../../hooks/useTableInstance"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
export default defineComponent({
|
|
30
|
+
name: 'EditableCell',
|
|
31
|
+
components: {
|
|
32
|
+
Spin,
|
|
33
|
+
CellComponent
|
|
34
|
+
},
|
|
35
|
+
props: {
|
|
36
|
+
value: {
|
|
37
|
+
type: [String, Number, Boolean, Object] as PropType<string | number | boolean | Recordable>,
|
|
38
|
+
default: ''
|
|
39
|
+
},
|
|
40
|
+
record: {
|
|
41
|
+
type: Object as PropType<EditRecordRow>,
|
|
42
|
+
},
|
|
43
|
+
column: {
|
|
44
|
+
type: Object as PropType<BasicColumn>,
|
|
45
|
+
default: ():BasicColumn => ({}),
|
|
46
|
+
},
|
|
47
|
+
index: Number
|
|
48
|
+
},
|
|
49
|
+
setup(props) {
|
|
50
|
+
const table = getTableInstance()
|
|
51
|
+
const elRef = ref()
|
|
52
|
+
|
|
53
|
+
const { editRule, align = 'left' } = props.column
|
|
54
|
+
|
|
55
|
+
const ruleMessage = ref('')
|
|
56
|
+
const ruleVisible = ref(false)
|
|
57
|
+
|
|
58
|
+
const optionsRef = ref<LableValOptions>([])
|
|
59
|
+
const currentValueRef = ref<any>(props.value)
|
|
60
|
+
|
|
61
|
+
const getComponent = computed(() => props.column?.editComponent || 'Input')
|
|
62
|
+
|
|
63
|
+
// 提示信息是否可见
|
|
64
|
+
const getRuleVisible = computed(() => {
|
|
65
|
+
return unref( ruleMessage ) && unref( ruleVisible )
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
const getWrapperClass = computed(() => {
|
|
69
|
+
return `edit-cell-align-${align}`
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
const getIsCheckComp = computed(() => {
|
|
73
|
+
const component = unref(getComponent);
|
|
74
|
+
return ['Checkbox', 'Switch'].includes(component);
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
const createPlaceholderMessage = ( component: ComponentType ) => {
|
|
78
|
+
if( component.includes('Input') ) {
|
|
79
|
+
return '请输入'
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return '请选择'
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// 设置表格属性
|
|
86
|
+
const getComponentProps = computed(() => {
|
|
87
|
+
const isCheckValue = unref(getIsCheckComp)
|
|
88
|
+
const valueField = isCheckValue ? 'checked' : 'value'
|
|
89
|
+
|
|
90
|
+
const val = unref(currentValueRef)
|
|
91
|
+
const value = isCheckValue ? (isNumber(val) && isBoolean(val) ? val : !!val) : val
|
|
92
|
+
|
|
93
|
+
let compProps = props.column?.editComponentProps ?? {}
|
|
94
|
+
|
|
95
|
+
const { record, column, index } = props
|
|
96
|
+
if (isFunction(compProps)) {
|
|
97
|
+
compProps = compProps({ text: val, record, column, index }) ?? {}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return {
|
|
101
|
+
size: 'small',
|
|
102
|
+
getPopupContainer: () => document.body,
|
|
103
|
+
placeholder: createPlaceholderMessage(unref(getComponent)),
|
|
104
|
+
...omit(compProps, 'onChange'),
|
|
105
|
+
[valueField]: value
|
|
106
|
+
}
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
async function handleChange( e: any ) {
|
|
111
|
+
const component = unref(getComponent)
|
|
112
|
+
|
|
113
|
+
if( !e ) {
|
|
114
|
+
currentValueRef.value = e
|
|
115
|
+
} else if (component === 'Checkbox') {
|
|
116
|
+
currentValueRef.value = (e as DtEvent).target.checked
|
|
117
|
+
} else if (component === 'Switch') {
|
|
118
|
+
currentValueRef.value = e
|
|
119
|
+
} else if (e?.target && Reflect.has(e.target, 'value')) {
|
|
120
|
+
currentValueRef.value = (e as DtEvent).target.value
|
|
121
|
+
} else if (isString(e) || isBoolean(e) || isNumber(e)) {
|
|
122
|
+
currentValueRef.value = e
|
|
123
|
+
}
|
|
124
|
+
const onChange = unref(getComponentProps)?.onChange
|
|
125
|
+
if (onChange && isFunction(onChange)) onChange(...arguments)
|
|
126
|
+
|
|
127
|
+
table.emit?.('edit-change', {
|
|
128
|
+
column: props.column,
|
|
129
|
+
value: unref(currentValueRef),
|
|
130
|
+
record: toRaw(props.record),
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
handleSubmitRule()
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
async function handleSubmitRule() {
|
|
138
|
+
const { column, record } = props
|
|
139
|
+
const { editRule } = column
|
|
140
|
+
const currentValue = unref(currentValueRef)
|
|
141
|
+
|
|
142
|
+
if ( editRule ) {
|
|
143
|
+
if( isBoolean(editRule) && !currentValue && !isNumber(currentValue) ) {
|
|
144
|
+
ruleVisible.value = true
|
|
145
|
+
const component = unref(getComponent)
|
|
146
|
+
ruleMessage.value = createPlaceholderMessage(component)
|
|
147
|
+
return false
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if( isFunction(editRule) ) {
|
|
151
|
+
const res = await editRule(currentValue, record as Recordable)
|
|
152
|
+
|
|
153
|
+
if (!!res) {
|
|
154
|
+
ruleMessage.value = res;
|
|
155
|
+
ruleVisible.value = true;
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
ruleMessage.value = ''
|
|
162
|
+
return true
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function handleOptionsChange(options: LableValOptions) {
|
|
166
|
+
optionsRef.value = options
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return {
|
|
170
|
+
props,
|
|
171
|
+
getComponentProps,
|
|
172
|
+
getRuleVisible,
|
|
173
|
+
editRule,
|
|
174
|
+
ruleMessage,
|
|
175
|
+
getWrapperClass,
|
|
176
|
+
handleChange,
|
|
177
|
+
handleOptionsChange
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
})
|
|
181
|
+
</script>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Input, Select, Checkbox, DatePicker, InputNumber, Switch, TimePicker, TreeSelect } from 'ant-design-vue'
|
|
2
|
+
import { Component } from 'vue'
|
|
3
|
+
import { ComponentType } from '../../types/table.type'
|
|
4
|
+
|
|
5
|
+
const componentMap = new Map<ComponentType, Component>()
|
|
6
|
+
|
|
7
|
+
componentMap.set('Input', Input)
|
|
8
|
+
componentMap.set('InputNumber', InputNumber)
|
|
9
|
+
componentMap.set('Select', Select)
|
|
10
|
+
componentMap.set('TreeSelect', TreeSelect)
|
|
11
|
+
componentMap.set('Switch', Switch)
|
|
12
|
+
componentMap.set('Checkbox', Checkbox)
|
|
13
|
+
componentMap.set('DatePicker', DatePicker)
|
|
14
|
+
componentMap.set('TimePicker', TimePicker)
|
|
15
|
+
|
|
16
|
+
export {
|
|
17
|
+
componentMap
|
|
18
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { isArray } from '@dt-frames/core'
|
|
2
|
+
import { h } from 'vue'
|
|
3
|
+
import { BasicColumn } from "../../types/table.type"
|
|
4
|
+
import EditableCell from './EditTableCell.vue'
|
|
5
|
+
|
|
6
|
+
function renderEditCell(column: BasicColumn) {
|
|
7
|
+
return ({text: value, record, index}) => {
|
|
8
|
+
// 触发校验
|
|
9
|
+
record.onValid = async () => {
|
|
10
|
+
if ( isArray( record?.validCbs ) ) {
|
|
11
|
+
const validFns = (record?.validCbs || []).map((fn) => fn())
|
|
12
|
+
const res = await Promise.all( validFns )
|
|
13
|
+
return res.every((item) => !!item)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return false
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// 触发修改
|
|
20
|
+
record.onEdit = async (edit: boolean, submit = false) => {
|
|
21
|
+
if (!submit) {
|
|
22
|
+
record.editable = edit;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// 提交
|
|
26
|
+
if (!edit && submit) {
|
|
27
|
+
if ( !(await record.onValid()) ) return false
|
|
28
|
+
|
|
29
|
+
const res = await record.onSubmitEdit?.()
|
|
30
|
+
|
|
31
|
+
if (res) {
|
|
32
|
+
record.editable = false
|
|
33
|
+
return true
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return false
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// 取消
|
|
40
|
+
if (!edit && !submit) {
|
|
41
|
+
record.onCancelEdit?.()
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return true
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return h(EditableCell, {
|
|
48
|
+
value,
|
|
49
|
+
record,
|
|
50
|
+
column,
|
|
51
|
+
index,
|
|
52
|
+
})
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export {
|
|
57
|
+
renderEditCell
|
|
58
|
+
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { PaginationProps } from 'ant-design-vue/lib/pagination'
|
|
2
|
-
import { computed, ComputedRef, Ref, ref, unref, toRaw, watch, h } from "vue"
|
|
3
|
-
import { cloneDeep, isEqual } from 'lodash-es'
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
2
|
+
import { computed, ComputedRef, Ref, ref, unref, toRaw, watch, h } from "vue"
|
|
3
|
+
import { cloneDeep, isEqual, omit } from 'lodash-es'
|
|
4
|
+
import { renderEditCell } from '../components/editable'
|
|
5
|
+
import { BasicColumn, BasicTableProps } from "../types/table.type"
|
|
6
|
+
import { SetColumnsParams } from '../types/tableHeader.type'
|
|
7
|
+
import { isArray, isBoolean, isFunction, isObject, isString, Recordable, useAppStore, getDictValueByCode } from '@dt-frames/core'
|
|
7
8
|
import TableAction from '../components/TableActions.vue'
|
|
8
9
|
|
|
9
10
|
// 索引列及操作列标识
|
|
@@ -157,12 +158,11 @@ function handleActionColumn(propsRef: ComputedRef<BasicTableProps>, columns: Bas
|
|
|
157
158
|
customRender: ({ record, index}) => {
|
|
158
159
|
return h(
|
|
159
160
|
TableAction as any,
|
|
160
|
-
{
|
|
161
|
+
omit({
|
|
161
162
|
...columnObj,
|
|
162
163
|
record,
|
|
163
|
-
align: null,
|
|
164
164
|
index
|
|
165
|
-
}
|
|
165
|
+
}, 'align')
|
|
166
166
|
)
|
|
167
167
|
}
|
|
168
168
|
})
|
|
@@ -211,6 +211,13 @@ export function useColumns(
|
|
|
211
211
|
|
|
212
212
|
return columns
|
|
213
213
|
.filter( column => isIfShow(column) )
|
|
214
|
+
.map(column => {
|
|
215
|
+
if( column.edit ) {
|
|
216
|
+
column.customRender = renderEditCell(column)
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return column
|
|
220
|
+
})
|
|
214
221
|
|
|
215
222
|
})
|
|
216
223
|
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { DtEvent, Recordable } from "@dt-frames/core"
|
|
2
|
+
import { ComputedRef, unref } from "vue"
|
|
3
|
+
import { BasicTableProps } from "../types/table.type"
|
|
4
|
+
|
|
5
|
+
interface Options {
|
|
6
|
+
setSelectedRowKeys: (keys: string[]) => void
|
|
7
|
+
getSelectRowKeys: () => string[]
|
|
8
|
+
clearSelectedRowKeys: () => void
|
|
9
|
+
emit: any
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function useCustomRow(
|
|
13
|
+
propsRef: ComputedRef<BasicTableProps>,
|
|
14
|
+
{ setSelectedRowKeys, getSelectRowKeys, clearSelectedRowKeys, emit }: Options
|
|
15
|
+
) {
|
|
16
|
+
const customRow = (record: Recordable, index: number) => {
|
|
17
|
+
return {
|
|
18
|
+
onClick: (e) => {
|
|
19
|
+
e?.stopPropagation()
|
|
20
|
+
|
|
21
|
+
function handleClick() {
|
|
22
|
+
const { rowSelection, rowKey, clickToRowSelect } = unref(propsRef)
|
|
23
|
+
if (!rowSelection || !clickToRowSelect) return
|
|
24
|
+
|
|
25
|
+
const keys = getSelectRowKeys()
|
|
26
|
+
const key = record[rowKey]
|
|
27
|
+
if (!key) return
|
|
28
|
+
|
|
29
|
+
const isCheckbox = rowSelection.type === 'checkbox'
|
|
30
|
+
if (isCheckbox) {
|
|
31
|
+
const tr: HTMLElement = (e as MouseEvent)
|
|
32
|
+
.composedPath?.()
|
|
33
|
+
.find((dom: HTMLElement) => dom.tagName === 'TR') as HTMLElement;
|
|
34
|
+
if (!tr) return
|
|
35
|
+
|
|
36
|
+
const checkBox = tr.querySelector('input[type=checkbox]')
|
|
37
|
+
|
|
38
|
+
if (!checkBox || checkBox.hasAttribute('disabled')) return
|
|
39
|
+
|
|
40
|
+
if (!keys.includes(key)) {
|
|
41
|
+
setSelectedRowKeys([...keys, key])
|
|
42
|
+
return
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const keyIndex = keys.findIndex((item) => item === key)
|
|
46
|
+
keys.splice(keyIndex, 1)
|
|
47
|
+
setSelectedRowKeys(keys)
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const isRadio = rowSelection.type === 'radio'
|
|
52
|
+
|
|
53
|
+
if (isRadio) {
|
|
54
|
+
if (!keys.includes(key)) {
|
|
55
|
+
if (keys.length) {
|
|
56
|
+
clearSelectedRowKeys()
|
|
57
|
+
}
|
|
58
|
+
setSelectedRowKeys([key])
|
|
59
|
+
return
|
|
60
|
+
}
|
|
61
|
+
clearSelectedRowKeys()
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
handleClick()
|
|
66
|
+
emit('row-click', record, index, e)
|
|
67
|
+
},
|
|
68
|
+
onDblclick: (event: Event) => {
|
|
69
|
+
emit('row-dbClick', record, index, event);
|
|
70
|
+
},
|
|
71
|
+
onContextmenu: (event: Event) => {
|
|
72
|
+
emit('row-contextmenu', record, index, event);
|
|
73
|
+
},
|
|
74
|
+
onMouseenter: (event: Event) => {
|
|
75
|
+
emit('row-mouseenter', record, index, event);
|
|
76
|
+
},
|
|
77
|
+
onMouseleave: (event: Event) => {
|
|
78
|
+
emit('row-mouseleave', record, index, event);
|
|
79
|
+
},
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
customRow,
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -24,19 +24,6 @@ export function useDataSource(
|
|
|
24
24
|
// 拷贝一份表格数据 然后再做数据处理
|
|
25
25
|
const dataSourceRef = ref<Recordable[]>([])
|
|
26
26
|
|
|
27
|
-
// const { defSort, onTableChange } = unref( propsRef )
|
|
28
|
-
// const { appConf } = useAppStore()
|
|
29
|
-
|
|
30
|
-
// onTableChange({
|
|
31
|
-
// pagination: {
|
|
32
|
-
// current: 1,
|
|
33
|
-
// pageSize: appConf.ui.table.defaultPageSize
|
|
34
|
-
// },
|
|
35
|
-
// sort:defSort,
|
|
36
|
-
// filter: null,
|
|
37
|
-
// showBtnLoading: false
|
|
38
|
-
// }, false)
|
|
39
|
-
|
|
40
27
|
watch(
|
|
41
28
|
() => unref(propsRef).dataSource,
|
|
42
29
|
(dataSource) => {
|
|
@@ -9,10 +9,10 @@ export function useTableHeader(
|
|
|
9
9
|
handlers: { onColumnsChange: (data: ColumnChangeParam[]) => void }
|
|
10
10
|
) {
|
|
11
11
|
const getHeaderProps = computed((): Recordable => {
|
|
12
|
-
const { tableSetting, toolbar } = unref(propsRef)
|
|
12
|
+
const { tableSetting, toolbar = [] } = unref(propsRef)
|
|
13
13
|
|
|
14
14
|
const { getSlot } = useSlots()
|
|
15
|
-
const hideTitle = !slots.toolbar && !slots.headerTop && !tableSetting
|
|
15
|
+
const hideTitle = !toolbar.length && !slots.toolbar && !slots.headerTop && !tableSetting
|
|
16
16
|
|
|
17
17
|
return {
|
|
18
18
|
title: hideTitle
|