easybill-ui 1.3.5 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/CurdForm/src/CurdForm.vue +9 -10
- package/components/CurdForm/src/FormItem.vue +2 -2
- package/components/CurdForm/src/FormTooltip.vue +4 -5
- package/components/CurdForm/src/components/schema-form-date-picker.vue +2 -2
- package/components/CurdForm/src/components/schema-form-input-number.vue +1 -1
- package/components/CurdForm/src/components/schema-form-time-picker.vue +2 -2
- package/components/CurdForm/src/types.ts +25 -24
- package/components/CurdGroupForm/src/hooks/useFormHook.ts +5 -5
- package/components/CurdTable/src/CurdTable.vue +8 -5
- package/components/CurdTable/src/STableItem.vue +5 -2
- package/components/CurdTable/src/types.ts +7 -5
- package/components/DetailInfo/src/types.ts +2 -2
- package/components/FormDialog/src/FormDialog.vue +6 -5
- package/components/FormDialog/src/types.ts +13 -8
- package/components/TableFilter/types.ts +8 -2
- package/package.json +56 -1
- package/utils/hooks/useLocal.ts +12 -10
|
@@ -28,15 +28,7 @@
|
|
|
28
28
|
|
|
29
29
|
<!-- 其他类型使用 el-form-item 包裹 -->
|
|
30
30
|
<template v-else>
|
|
31
|
-
<el-form-item
|
|
32
|
-
v-if="!$slots[formItem.prop + 'Item']"
|
|
33
|
-
:required="rules && rules[formItem.prop]?.find((a) => a.hasOwnProperty('required'))?.required"
|
|
34
|
-
:label="formItem.label"
|
|
35
|
-
:prop="formItem.prop"
|
|
36
|
-
:label-width="formItem.labelWidth"
|
|
37
|
-
:class="getFormItemStyle(formItem)"
|
|
38
|
-
v-bind="getFormItemProps(formItem)"
|
|
39
|
-
>
|
|
31
|
+
<el-form-item v-if="!$slots[formItem.prop + 'Item']" :required="hasRequiredRule(formItem.prop)" :label="formItem.label" :prop="formItem.prop" :label-width="formItem.labelWidth" :class="getFormItemStyle(formItem)" v-bind="getFormItemProps(formItem)">
|
|
40
32
|
<template v-for="(item, key) in getFormItemProps(formItem)?.slots || {}" :key="key" #[key]="row">
|
|
41
33
|
<component :is="item" v-bind="row" />
|
|
42
34
|
</template>
|
|
@@ -65,7 +57,7 @@
|
|
|
65
57
|
</template>
|
|
66
58
|
|
|
67
59
|
<script lang="ts" setup>
|
|
68
|
-
import { ElForm, type FormRules } from "element-plus"
|
|
60
|
+
import { ElForm, type FormItemRule, type FormRules } from "element-plus"
|
|
69
61
|
import { computed, getCurrentInstance, onMounted, provide, reactive, ref, triggerRef, watch, type PropType } from "vue"
|
|
70
62
|
import FormItem from "./FormItem.vue"
|
|
71
63
|
import type { CurdFormOptionItem, Fields, FormContext, FormItemProvider, FormItemSearchResult, FormItem as FormItemType, FormSchema } from "./types"
|
|
@@ -272,6 +264,13 @@ const rules = computed(() => {
|
|
|
272
264
|
|
|
273
265
|
return mergedRules
|
|
274
266
|
})
|
|
267
|
+
const normalizeFormItemRules = (rule: FormItemRule | FormItemRule[] | undefined) => {
|
|
268
|
+
if (!rule) return []
|
|
269
|
+
return Array.isArray(rule) ? rule : [rule]
|
|
270
|
+
}
|
|
271
|
+
const hasRequiredRule = (prop: string) => {
|
|
272
|
+
return normalizeFormItemRules(rules.value[prop] as FormItemRule | FormItemRule[] | undefined).some((rule) => Object.prototype.hasOwnProperty.call(rule, "required") && rule.required)
|
|
273
|
+
}
|
|
275
274
|
|
|
276
275
|
/**
|
|
277
276
|
* 递归查找表单项
|
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
<slot name="prefix"></slot>
|
|
6
6
|
<component :is="comp" v-if="comp" v-model="modelRef[props.formItem.prop || '']" :form-item="props.formItem" :form-model="modelRef" :props="formItemProps" :event-object="eventObject">
|
|
7
7
|
<template v-for="(item, key) in formItemProps.slots" :key="key" #[key]="slotScope">
|
|
8
|
-
<component :is="item" v-model="modelRef[props.formItem.prop || '']" :form-item="props.formItem" :form-model="modelRef" :props="formItemProps" :event-object="eventObject" />
|
|
8
|
+
<component :is="item" v-model="modelRef[props.formItem.prop || '']" v-bind="slotScope" :form-item="props.formItem" :form-model="modelRef" :props="formItemProps" :event-object="eventObject" />
|
|
9
9
|
</template>
|
|
10
10
|
</component>
|
|
11
11
|
<component :is="props.formItem.type" v-else v-model="modelRef[props.formItem.prop || '']" v-bind="formItemProps" v-on="eventObject">
|
|
12
12
|
<template v-for="(item, key) in formItemProps.slots" :key="key" #[key]="slotScope">
|
|
13
|
-
<component :is="item" v-model="modelRef[props.formItem.prop || '']" :form-item="props.formItem" :form-model="modelRef" :props="formItemProps" :event-object="eventObject" />
|
|
13
|
+
<component :is="item" v-model="modelRef[props.formItem.prop || '']" v-bind="slotScope" :form-item="props.formItem" :form-model="modelRef" :props="formItemProps" :event-object="eventObject" />
|
|
14
14
|
</template>
|
|
15
15
|
</component>
|
|
16
16
|
|
|
@@ -10,12 +10,11 @@
|
|
|
10
10
|
</template>
|
|
11
11
|
<script lang="ts" setup>
|
|
12
12
|
import { Warning } from "@element-plus/icons-vue"
|
|
13
|
-
import { type ElTooltipProps } from "element-plus"
|
|
14
13
|
import { type PropType, computed } from "vue"
|
|
15
|
-
import type { Fields, FormItem } from "./types"
|
|
14
|
+
import type { Fields, FormItem, TooltipProps } from "./types"
|
|
16
15
|
const props = defineProps({
|
|
17
16
|
tooltip: {
|
|
18
|
-
type: [String, Function] as PropType<string | ((formModel: Fields, formItem: FormItem) => Partial<
|
|
17
|
+
type: [String, Function, Object] as PropType<string | ((formModel: Fields, formItem: FormItem) => Partial<TooltipProps> | string) | Partial<TooltipProps>>,
|
|
19
18
|
default: null,
|
|
20
19
|
},
|
|
21
20
|
formItem: {
|
|
@@ -40,11 +39,11 @@ const tooltipModel = computed(() => {
|
|
|
40
39
|
return getTooltip(tooltip)
|
|
41
40
|
})
|
|
42
41
|
// 获取组件tooltip内容
|
|
43
|
-
const getTooltip = (tooltip: Partial<
|
|
42
|
+
const getTooltip = (tooltip: Partial<TooltipProps> | string): Partial<TooltipProps> => {
|
|
44
43
|
if (!tooltip) {
|
|
45
44
|
return { content: "" }
|
|
46
45
|
}
|
|
47
|
-
let t: Partial<
|
|
46
|
+
let t: Partial<TooltipProps> = {}
|
|
48
47
|
if (typeof tooltip == "string") {
|
|
49
48
|
t = { content: tooltip }
|
|
50
49
|
} else {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<el-date-picker v-model="model" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD" v-bind="props" v-on="eventObject">
|
|
3
|
-
<template v-for="(item, key) in props.
|
|
4
|
-
<component :is="item" v-model="model" :form-item="
|
|
3
|
+
<template v-for="(item, key) in props.slots" :key="key" #[key]="slotScope">
|
|
4
|
+
<component :is="item" v-model="model" v-bind="slotScope" :form-item="formItem" :form-model="formModel" :props="props" :event-object="eventObject" />
|
|
5
5
|
</template>
|
|
6
6
|
</el-date-picker>
|
|
7
7
|
</template>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<el-input-number v-model="model" v-bind="props.props" v-on="eventObject">
|
|
3
3
|
<template v-for="(item, key) in props.props?.slots" :key="key" #[key]="slotScope">
|
|
4
|
-
<component :is="item" v-model="model" :form-item="props.formItem" :form-model="props.formModel" :props="props.props" :event-object="eventObject" />
|
|
4
|
+
<component :is="item" v-model="model" v-bind="slotScope" :form-item="props.formItem" :form-model="props.formModel" :props="props.props" :event-object="eventObject" />
|
|
5
5
|
</template>
|
|
6
6
|
</el-input-number>
|
|
7
7
|
</template>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<el-time-picker v-model="model" v-bind="props" v-on="eventObject">
|
|
3
|
-
<template v-for="(item, key) in props.
|
|
4
|
-
<component :is="item" v-model="model" :form-item="formItem" :form-model="formModel" :props="
|
|
3
|
+
<template v-for="(item, key) in props.slots" :key="key" #[key]="slotScope">
|
|
4
|
+
<component :is="item" v-model="model" v-bind="slotScope" :form-item="formItem" :form-model="formModel" :props="props" :event-object="eventObject" />
|
|
5
5
|
</template>
|
|
6
6
|
</el-time-picker>
|
|
7
7
|
</template>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ElForm, type FormItemRule, type FormRules
|
|
1
|
+
import { ElForm, type FormItemRule, type FormRules } from "element-plus"
|
|
2
2
|
import type { Arrayable } from "element-plus/es/utils"
|
|
3
3
|
import { defineComponent, type PropType, type VNode } from "vue"
|
|
4
4
|
import type { OptionItem } from "../../ConstantStatus"
|
|
@@ -32,7 +32,7 @@ export interface FormItem {
|
|
|
32
32
|
hidden?: boolean | ((model: Fields) => boolean)
|
|
33
33
|
rules?: Arrayable<FormItemRule>
|
|
34
34
|
props?: FormItemPropObject | ((formModel: Fields, formItem: FormItem) => FormItemPropObject)
|
|
35
|
-
formItemProps?: FormItemPropObject | ((formModel: Fields, formItem: FormItem) =>
|
|
35
|
+
formItemProps?: FormItemPropObject | ((formModel: Fields, formItem: FormItem) => FormItemPropObject)
|
|
36
36
|
labelWidth?: string | number
|
|
37
37
|
labelPosition?: "left" | "right" | "top" | string
|
|
38
38
|
span?: number
|
|
@@ -47,28 +47,28 @@ export interface FormItem {
|
|
|
47
47
|
export type FormItemTypeEmun = "input" | "select" | "radio" | "checkbox" | "input-number" | "switch" | "file" | "date-picker" | "time-picker" | "color-picker" | "value" | "tree-select" | "autocomplete" | "choose"
|
|
48
48
|
export interface FormItemPropObject extends Fields {
|
|
49
49
|
slots?: Record<string, (props?: FormItemPropObject) => VNode | VNode[] | string | null>
|
|
50
|
-
all?: boolean |
|
|
50
|
+
all?: boolean | OptionItem
|
|
51
51
|
empty?: string | VNode
|
|
52
52
|
noDataText?: string
|
|
53
53
|
style?: Record<string, string> | string
|
|
54
54
|
}
|
|
55
|
-
export interface TooltipProps {
|
|
56
|
-
effect
|
|
57
|
-
content
|
|
58
|
-
rawContent
|
|
59
|
-
placement
|
|
60
|
-
disabled
|
|
61
|
-
offset
|
|
62
|
-
transition
|
|
63
|
-
popperOptions
|
|
64
|
-
showAfter
|
|
65
|
-
showArrow
|
|
66
|
-
hideAfter
|
|
67
|
-
autoClose
|
|
68
|
-
popperClass
|
|
69
|
-
enterable
|
|
70
|
-
teleported
|
|
71
|
-
trigger
|
|
55
|
+
export interface TooltipProps extends Record<string, unknown> {
|
|
56
|
+
effect?: "dark" | "light" | string
|
|
57
|
+
content?: string
|
|
58
|
+
rawContent?: boolean
|
|
59
|
+
placement?: string
|
|
60
|
+
disabled?: boolean
|
|
61
|
+
offset?: number
|
|
62
|
+
transition?: string
|
|
63
|
+
popperOptions?: unknown
|
|
64
|
+
showAfter?: number
|
|
65
|
+
showArrow?: boolean
|
|
66
|
+
hideAfter?: number
|
|
67
|
+
autoClose?: number
|
|
68
|
+
popperClass?: string
|
|
69
|
+
enterable?: boolean
|
|
70
|
+
teleported?: boolean
|
|
71
|
+
trigger?: string | string[]
|
|
72
72
|
}
|
|
73
73
|
export interface FormContext {
|
|
74
74
|
loadOptions: (prop: string, config?: unknown) => void | Promise<CurdFormOptionItem[]> | CurdFormOptionItem[]
|
|
@@ -109,10 +109,11 @@ export interface FormItemSearchResult {
|
|
|
109
109
|
// interface EventObjectDefault {
|
|
110
110
|
// change?: (formModel: Fields, formItem: FormItem, proxy: any) => void
|
|
111
111
|
// }
|
|
112
|
+
export type EventObjectHandler = (formModel: Fields, formItem: FormItem, context?: FormContext, ...args: unknown[]) => void | boolean
|
|
112
113
|
export interface EventObject {
|
|
113
|
-
change?:
|
|
114
|
-
optionLoaded?:
|
|
115
|
-
[key: string]:
|
|
114
|
+
change?: EventObjectHandler
|
|
115
|
+
optionLoaded?: EventObjectHandler
|
|
116
|
+
[key: string]: EventObjectHandler | undefined
|
|
116
117
|
}
|
|
117
118
|
// export interface OptionItem {
|
|
118
119
|
// label: string
|
|
@@ -135,7 +136,7 @@ export const FormItemProps = {
|
|
|
135
136
|
default: () => ({}),
|
|
136
137
|
},
|
|
137
138
|
eventObject: {
|
|
138
|
-
type: Object as PropType<
|
|
139
|
+
type: Object as PropType<EventObject>,
|
|
139
140
|
default: () => ({}),
|
|
140
141
|
},
|
|
141
142
|
modelValue: {
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import { CurdForm } from "easybill-ui"
|
|
2
2
|
import { ref, type Ref } from "vue"
|
|
3
|
-
import type {
|
|
3
|
+
import type { CurdGroupFormSchema, CurdGroupFormSchemaItem } from "../../types"
|
|
4
4
|
|
|
5
5
|
export const useFormHook = (): {
|
|
6
6
|
form: Ref<Record<string, unknown>>
|
|
7
7
|
formRef: Ref<Record<string, InstanceType<typeof CurdForm>>>
|
|
8
8
|
submit: () => void
|
|
9
|
-
schema: Ref<
|
|
9
|
+
schema: Ref<CurdGroupFormSchema | undefined>
|
|
10
10
|
validate: (callback: (valid: boolean) => void) => void
|
|
11
11
|
loading: Ref<boolean>
|
|
12
|
-
schemaItemHidden: (item:
|
|
12
|
+
schemaItemHidden: (item: CurdGroupFormSchemaItem) => boolean
|
|
13
13
|
} => {
|
|
14
14
|
const formRef = ref<Record<string, InstanceType<typeof CurdForm>>>({})
|
|
15
15
|
const form = ref<Record<string, unknown>>({})
|
|
16
|
-
const schema = ref<
|
|
16
|
+
const schema = ref<CurdGroupFormSchema>()
|
|
17
17
|
const loading = ref(false)
|
|
18
|
-
const schemaItemHidden = (item:
|
|
18
|
+
const schemaItemHidden = (item: CurdGroupFormSchemaItem) => {
|
|
19
19
|
if (item?.hidden && item?.hidden instanceof Function) {
|
|
20
20
|
return item.hidden(form.value, item)
|
|
21
21
|
}
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
<el-table-column v-else-if="item.type == 'selection'" type="selection" v-bind="item" />
|
|
22
22
|
<STableItem v-else :ref="getTableItemRef(item.prop)" :schema="item" :is-slot="!!$slots[item.prop]" :is-slot-header="!!$slots[item.prop + 'Header']" :option="option" @search="onItemChange">
|
|
23
23
|
<template v-for="(_slot, key) in $slots" :key="key" #[key]="scopeChild">
|
|
24
|
-
<slot :name="key" v-bind="scopeChild"></slot>
|
|
24
|
+
<slot :name="key" v-bind="normalizeSlotScope(scopeChild)"></slot>
|
|
25
25
|
</template>
|
|
26
26
|
</STableItem>
|
|
27
27
|
</template>
|
|
@@ -133,12 +133,12 @@ const props = defineProps({
|
|
|
133
133
|
},
|
|
134
134
|
// 自定义创建函数
|
|
135
135
|
fetchCreate: {
|
|
136
|
-
type: Function as PropType<(formModel: Fields) => Promise<void>>,
|
|
136
|
+
type: Function as PropType<(formModel: Fields) => void | boolean | Promise<void | boolean>>,
|
|
137
137
|
default: null,
|
|
138
138
|
},
|
|
139
139
|
// 自定义编辑函数
|
|
140
140
|
fetchEdit: {
|
|
141
|
-
type: Function as PropType<(
|
|
141
|
+
type: Function as PropType<(formModel: Fields, row: Record<string, unknown>, index?: number) => void | boolean | Promise<void | boolean>>,
|
|
142
142
|
|
|
143
143
|
default: null,
|
|
144
144
|
},
|
|
@@ -248,6 +248,7 @@ const fetchData = async (opt?: FetchDataOpt) => {
|
|
|
248
248
|
}
|
|
249
249
|
}
|
|
250
250
|
const tableItemRefs: Ref<Record<string, InstanceType<typeof STableItem>>> = ref({})
|
|
251
|
+
const normalizeSlotScope = (scope: unknown) => (scope && typeof scope === "object" ? scope : {})
|
|
251
252
|
const getTableItemRef = (prop: string) => {
|
|
252
253
|
return (el: unknown) => {
|
|
253
254
|
if (el) {
|
|
@@ -404,8 +405,10 @@ const create = (row?: Record<string, unknown>, index?: number) => {
|
|
|
404
405
|
fields: row as Fields,
|
|
405
406
|
width: formAttrs?.width || 600,
|
|
406
407
|
handleOk: async (modelRef: Fields) => {
|
|
407
|
-
|
|
408
|
-
|
|
408
|
+
if (row) {
|
|
409
|
+
return await props.fetchEdit?.(modelRef, row, index)
|
|
410
|
+
}
|
|
411
|
+
return await props.fetchCreate?.(modelRef)
|
|
409
412
|
},
|
|
410
413
|
...eoptions,
|
|
411
414
|
})
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
<template v-for="item in props.schema.children" :key="item.label">
|
|
15
15
|
<STableItem :ref="(el) => (tableItemRefs[item.prop] = el)" :schema="item" :is-slot="!!$slots[item.prop]" :is-slot-header="!!$slots[item.prop + 'Header']" :option="option" @search="onItemChange">
|
|
16
16
|
<template v-for="(_slot, key) in $slots" :key="key" #[key]="scopeChild">
|
|
17
|
-
<slot :name="key" v-bind="scopeChild"></slot>
|
|
17
|
+
<slot :name="key" v-bind="normalizeSlotScope(scopeChild)"></slot>
|
|
18
18
|
</template>
|
|
19
19
|
</STableItem>
|
|
20
20
|
</template>
|
|
@@ -44,6 +44,7 @@ import { useLocale } from "easybill-ui"
|
|
|
44
44
|
import { ElMessage } from "element-plus"
|
|
45
45
|
import { computed, inject, type PropType, ref, type Ref } from "vue"
|
|
46
46
|
import ConstantStatus from "../../ConstantStatus"
|
|
47
|
+
import type { Fields } from "../../CurdForm"
|
|
47
48
|
import type { ParamsItem } from "../../TableFilter"
|
|
48
49
|
import { copy } from "../utils/common"
|
|
49
50
|
import STableItemFilter from "./STableItemFilter.vue"
|
|
@@ -72,6 +73,7 @@ const props = defineProps({
|
|
|
72
73
|
default: () => ({}),
|
|
73
74
|
},
|
|
74
75
|
})
|
|
76
|
+
defineSlots<Record<string, (scope: Record<string, unknown>) => unknown>>()
|
|
75
77
|
const selectParams = inject<Ref<Array<ParamsItem>>>("selectParams")
|
|
76
78
|
const filterSchema = computed(() => {
|
|
77
79
|
let result = selectParams?.value.filter((a) => a.prop == props.schema.filter?.prop || a.prop == props.schema.prop) //getFilterFromColumn(props.schema)
|
|
@@ -94,7 +96,7 @@ const copyValue = async (value: unknown) => {
|
|
|
94
96
|
ElMessage.success(t("el.table.clickCopySuccess"))
|
|
95
97
|
}
|
|
96
98
|
const emits = defineEmits(["search"])
|
|
97
|
-
const search = inject("search")
|
|
99
|
+
const search = inject<Fields>("search", {})
|
|
98
100
|
const getColumnHidden = computed(() => {
|
|
99
101
|
if (props.schema.hidden && props.schema.hidden instanceof Function) {
|
|
100
102
|
return props.schema.hidden(props.schema, search)
|
|
@@ -109,6 +111,7 @@ const onSearch = (opt: { listQuery: Record<string, unknown> }) => {
|
|
|
109
111
|
if (tableItemFilterRef.value) tableItemFilterRef.value.search(opt)
|
|
110
112
|
}
|
|
111
113
|
const tableItemRefs: Ref<Record<string, unknown>> = ref({})
|
|
114
|
+
const normalizeSlotScope = (scope: unknown) => (scope && typeof scope === "object" ? scope : {})
|
|
112
115
|
const onItemChange = (prop: string, value: string) => {
|
|
113
116
|
emits("search", prop, value, filterSchema.value)
|
|
114
117
|
}
|
|
@@ -8,6 +8,8 @@ import type { EventObject, FormSchema } from "./../../CurdForm/src/types"
|
|
|
8
8
|
import type { VNode } from "vue"
|
|
9
9
|
import type { FormDialogOptions } from "../../FormDialog/src/types"
|
|
10
10
|
|
|
11
|
+
export type MaybePromise<T> = T | Promise<T>
|
|
12
|
+
|
|
11
13
|
export interface CurdTableProps<T = unknown> extends Partial<TableProps<T>> {
|
|
12
14
|
rowKey?: string
|
|
13
15
|
data?: T[]
|
|
@@ -15,22 +17,22 @@ export interface CurdTableProps<T = unknown> extends Partial<TableProps<T>> {
|
|
|
15
17
|
pageOptions?: { pageIndex?: number; pageSize?: number; total?: number } & Fields
|
|
16
18
|
option?: Partial<PropOption>
|
|
17
19
|
fetchData?: (opt: FeachDataParam) => Promise<{ total?: number; list?: T[] } | void>
|
|
18
|
-
fetchCreate?: (formModel: Fields) =>
|
|
19
|
-
fetchEdit?: (row: T) =>
|
|
20
|
-
fetchRemove?: (row: T) => Promise<void>
|
|
20
|
+
fetchCreate?: (formModel: Fields) => MaybePromise<void | boolean>
|
|
21
|
+
fetchEdit?: (formModel: Fields, row: T, index?: number) => MaybePromise<void | boolean>
|
|
22
|
+
fetchRemove?: (row: T, index: number) => Promise<void>
|
|
21
23
|
}
|
|
22
24
|
// extends Partial<TableColumnCtx<T>>
|
|
23
25
|
export interface ColumnItemCtx<T> extends Partial<TableColumnCtx<T>> {
|
|
24
26
|
prop: string
|
|
25
27
|
label: string
|
|
26
28
|
type?: string
|
|
27
|
-
hidden?: boolean | ((item: ColumnItemCtx<T>,
|
|
29
|
+
hidden?: boolean | ((item: ColumnItemCtx<T>, query: Fields) => boolean)
|
|
28
30
|
neverShow?: boolean // 表示不在列控制器里
|
|
29
31
|
children?: ColumnItem<T>[]
|
|
30
32
|
options?: Array<OptionItem> //数据字典
|
|
31
33
|
asyncOptions?: () => Promise<OptionItem[]>
|
|
32
34
|
eventObject?: EventObject
|
|
33
|
-
form?: Partial<FormItemType> | ((
|
|
35
|
+
form?: Partial<FormItemType> | ((column: ColumnItemCtx<T>, row: T, query: Fields) => Partial<FormItemType>)
|
|
34
36
|
filter?: ColumnItemFilter
|
|
35
37
|
empty?: string | unknown
|
|
36
38
|
detail?: ColumnItemDetail
|
|
@@ -14,8 +14,8 @@ export interface DetailDataItem extends Record<string, unknown> {
|
|
|
14
14
|
labelWidth?: number | string
|
|
15
15
|
props?: Record<string, string>
|
|
16
16
|
slot?: string
|
|
17
|
-
tooltip?: string |
|
|
18
|
-
labelPosition?:
|
|
17
|
+
tooltip?: string | ElTooltipProps
|
|
18
|
+
labelPosition?: string | "left" | "right" | "center" | "top"
|
|
19
19
|
labelStyle?: string | Record<string, string | number>
|
|
20
20
|
showOverflowTooltip?: boolean | string | Partial<ElTooltipProps>
|
|
21
21
|
rawContent?: boolean
|
|
@@ -28,10 +28,11 @@
|
|
|
28
28
|
|
|
29
29
|
<script lang="ts">
|
|
30
30
|
import { CurdForm, CurdGroupForm, type CurdGroupFormSchema, useLocale } from "easybill-ui"
|
|
31
|
-
import { computed, defineComponent, type PropType, provide, reactive, ref, type Ref, toRefs, useAttrs } from "vue"
|
|
31
|
+
import { type Component, computed, defineComponent, type PropType, provide, reactive, ref, type Ref, toRefs, useAttrs } from "vue"
|
|
32
32
|
import { type Fields, type FormSchema } from "../../CurdForm"
|
|
33
33
|
import { useStepList } from "./hooks/useStepList"
|
|
34
34
|
import { useStepNavigation } from "./hooks/useStepNavigation"
|
|
35
|
+
import type { FormDialogHandleOk } from "./types"
|
|
35
36
|
export default defineComponent({
|
|
36
37
|
name: "FormDialog",
|
|
37
38
|
components: {
|
|
@@ -69,7 +70,7 @@ export default defineComponent({
|
|
|
69
70
|
},
|
|
70
71
|
// 点击确定
|
|
71
72
|
handleOk: {
|
|
72
|
-
type: Function
|
|
73
|
+
type: Function as PropType<FormDialogHandleOk>,
|
|
73
74
|
default: null,
|
|
74
75
|
},
|
|
75
76
|
// 关闭的回调,通过类型判断是点取消按钮还是右上角关闭按钮
|
|
@@ -99,11 +100,11 @@ export default defineComponent({
|
|
|
99
100
|
default: "dialog",
|
|
100
101
|
},
|
|
101
102
|
stepComponent: {
|
|
102
|
-
type: Object
|
|
103
|
+
type: Object as PropType<Component>,
|
|
103
104
|
default: null,
|
|
104
105
|
},
|
|
105
106
|
footerComponent: {
|
|
106
|
-
type: Object
|
|
107
|
+
type: Object as PropType<Component>,
|
|
107
108
|
default: null,
|
|
108
109
|
},
|
|
109
110
|
},
|
|
@@ -151,7 +152,7 @@ export default defineComponent({
|
|
|
151
152
|
state.confirmLoading = false
|
|
152
153
|
return
|
|
153
154
|
}
|
|
154
|
-
const pass = await (props.handleOk
|
|
155
|
+
const pass = await Promise.resolve(props.handleOk?.(form.value, state)).finally(() => (state.confirmLoading = false))
|
|
155
156
|
if (typeof pass == "undefined" || pass) {
|
|
156
157
|
state.visible = false
|
|
157
158
|
onCancel()
|
|
@@ -1,32 +1,37 @@
|
|
|
1
1
|
import type { DialogProps, StepProps } from "element-plus"
|
|
2
|
+
import type { Component, Ref } from "vue"
|
|
2
3
|
import type { Fields, FormContext, FormSchema } from "../../CurdForm"
|
|
3
4
|
import type { CurdGroupFormSchema } from "../../CurdGroupForm/types"
|
|
4
5
|
import type { StepItem } from "./hooks/useStepList"
|
|
5
6
|
|
|
7
|
+
export interface FormDialogState {
|
|
8
|
+
visible: boolean
|
|
9
|
+
confirmLoading: boolean
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export type FormDialogHandleOk = (modelRef: Fields, state: FormDialogState) => void | boolean | Promise<void | boolean>
|
|
13
|
+
|
|
6
14
|
export interface FormDialogOptions extends Partial<DialogProps> {
|
|
7
15
|
title?: string
|
|
8
16
|
width?: string | number
|
|
9
17
|
fields?: Fields
|
|
10
18
|
formSchema?: FormSchema
|
|
11
19
|
groupSchema?: CurdGroupFormSchema
|
|
12
|
-
handleOk?:
|
|
20
|
+
handleOk?: FormDialogHandleOk
|
|
13
21
|
handleClose?: (e: "close" | "cancel") => void
|
|
14
|
-
setForm?: (form: Fields) => void
|
|
22
|
+
setForm?: (form: Ref<Fields>) => void
|
|
15
23
|
stepProps?: Partial<StepProps & Fields>
|
|
16
24
|
extendContext?: Partial<FormContext>
|
|
17
25
|
confirmBtnText?: string
|
|
18
26
|
cancelBtnText?: string
|
|
19
|
-
stepComponent?:
|
|
20
|
-
footerComponent?:
|
|
27
|
+
stepComponent?: Component
|
|
28
|
+
footerComponent?: Component
|
|
21
29
|
mode?: "dialog" | "drawer"
|
|
22
30
|
}
|
|
23
31
|
|
|
24
32
|
export interface FormDialogContext {
|
|
25
33
|
form: Fields
|
|
26
|
-
state:
|
|
27
|
-
visible: boolean
|
|
28
|
-
confirmLoading: boolean
|
|
29
|
-
}
|
|
34
|
+
state: FormDialogState
|
|
30
35
|
stepList: StepItem[]
|
|
31
36
|
activeStep: { value: number }
|
|
32
37
|
loadOptions: (prop: string, config?: unknown) => void
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineComponent } from "vue"
|
|
2
|
-
import type { FormContext, FormItem, FormItemTypeEmun } from "../CurdForm"
|
|
2
|
+
import type { CurdFormOptionItem, FormContext, FormItem, FormItemTypeEmun } from "../CurdForm"
|
|
3
3
|
export interface ParamsItem extends FormItem {
|
|
4
4
|
type?: FormItemTypeEmun | ReturnType<typeof defineComponent>
|
|
5
5
|
tableKey?: Array<string>
|
|
@@ -9,10 +9,16 @@ export interface ParamsItem extends FormItem {
|
|
|
9
9
|
tagNames?: string
|
|
10
10
|
}
|
|
11
11
|
export type FilterItem = ParamsItem
|
|
12
|
-
export interface TableFilterContext
|
|
12
|
+
export interface TableFilterContext {
|
|
13
13
|
loadOptions: (prop: string, config?: unknown) => void
|
|
14
|
+
setOptions: (prop: string, options: CurdFormOptionItem[], config?: unknown) => void
|
|
14
15
|
setValue: (prop: string, value: unknown) => void
|
|
15
16
|
search: () => void
|
|
17
|
+
formModel: ListQuery
|
|
18
|
+
components: FormContext["components"]
|
|
19
|
+
change: FormContext["change"]
|
|
20
|
+
formRef?: FormContext["formRef"]
|
|
21
|
+
formSchema?: FormContext["formSchema"]
|
|
16
22
|
}
|
|
17
23
|
|
|
18
24
|
export interface ListQuery {
|
package/package.json
CHANGED
|
@@ -1,11 +1,66 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "easybill-ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "A component library for easybill",
|
|
5
5
|
"author": "tuchongyang <779311998@qq.com>",
|
|
6
6
|
"private": false,
|
|
7
7
|
"license": "ISC",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"typecheck": "vue-tsc -p tsconfig.typecheck.json --noEmit --skipLibCheck"
|
|
10
|
+
},
|
|
8
11
|
"main": "index.ts",
|
|
12
|
+
"types": "index.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./index.ts",
|
|
16
|
+
"import": "./index.ts",
|
|
17
|
+
"default": "./index.ts"
|
|
18
|
+
},
|
|
19
|
+
"./index": {
|
|
20
|
+
"types": "./index.ts",
|
|
21
|
+
"import": "./index.ts",
|
|
22
|
+
"default": "./index.ts"
|
|
23
|
+
},
|
|
24
|
+
"./index.ts": {
|
|
25
|
+
"types": "./index.ts",
|
|
26
|
+
"import": "./index.ts",
|
|
27
|
+
"default": "./index.ts"
|
|
28
|
+
},
|
|
29
|
+
"./components/CurdForm/src/types": {
|
|
30
|
+
"types": "./components/CurdForm/src/types.ts",
|
|
31
|
+
"import": "./components/CurdForm/src/types.ts",
|
|
32
|
+
"default": "./components/CurdForm/src/types.ts"
|
|
33
|
+
},
|
|
34
|
+
"./components/*": {
|
|
35
|
+
"types": "./components/*",
|
|
36
|
+
"import": "./components/*",
|
|
37
|
+
"default": "./components/*"
|
|
38
|
+
},
|
|
39
|
+
"./utils/*": {
|
|
40
|
+
"types": "./utils/*",
|
|
41
|
+
"import": "./utils/*",
|
|
42
|
+
"default": "./utils/*"
|
|
43
|
+
},
|
|
44
|
+
"./locale/*": {
|
|
45
|
+
"types": "./locale/*",
|
|
46
|
+
"import": "./locale/*",
|
|
47
|
+
"default": "./locale/*"
|
|
48
|
+
},
|
|
49
|
+
"./theme-chalk/*": {
|
|
50
|
+
"types": "./theme-chalk/*",
|
|
51
|
+
"import": "./theme-chalk/*",
|
|
52
|
+
"default": "./theme-chalk/*"
|
|
53
|
+
},
|
|
54
|
+
"./package.json": "./package.json"
|
|
55
|
+
},
|
|
56
|
+
"files": [
|
|
57
|
+
"index.ts",
|
|
58
|
+
"components",
|
|
59
|
+
"utils",
|
|
60
|
+
"locale",
|
|
61
|
+
"theme-chalk",
|
|
62
|
+
"README.md"
|
|
63
|
+
],
|
|
9
64
|
"peerDependencies": {
|
|
10
65
|
"@element-plus/icons-vue": "^2.0.6",
|
|
11
66
|
"element-plus": "^2.7.0",
|
package/utils/hooks/useLocal.ts
CHANGED
|
@@ -1,23 +1,25 @@
|
|
|
1
|
-
import { computed, isRef, ref,
|
|
1
|
+
import { computed, isRef, ref, type ComputedRef, type Ref } from "vue"
|
|
2
2
|
import en from "../../locale/lang/en"
|
|
3
3
|
|
|
4
|
-
import type { MaybeRef } from "@vueuse/core"
|
|
5
4
|
import { useGlobalConfig } from "easybill-ui"
|
|
6
|
-
import type { Ref } from "vue"
|
|
7
5
|
import type { Language } from "../../locale"
|
|
8
6
|
|
|
9
7
|
export type TranslatorOption = Record<string, string | number> | string[]
|
|
10
8
|
export type Translator = (path: string, option?: TranslatorOption) => string
|
|
9
|
+
export type LocaleSource = Language | Ref<Language> | ComputedRef<Language>
|
|
10
|
+
export type LocaleRef = Ref<Language> | ComputedRef<Language>
|
|
11
11
|
export type LocaleContext = {
|
|
12
|
-
locale:
|
|
13
|
-
lang:
|
|
12
|
+
locale: LocaleRef
|
|
13
|
+
lang: ComputedRef<string>
|
|
14
14
|
t: Translator
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
const resolveLocale = (locale: LocaleSource): Language => (isRef(locale) ? locale.value : locale)
|
|
18
|
+
|
|
17
19
|
export const buildTranslator =
|
|
18
|
-
(locale:
|
|
20
|
+
(locale: LocaleSource): Translator =>
|
|
19
21
|
(path, option) =>
|
|
20
|
-
translate(path, option,
|
|
22
|
+
translate(path, option, resolveLocale(locale))
|
|
21
23
|
|
|
22
24
|
export const translate = (path: string, option: undefined | TranslatorOption, locale: Language): string => {
|
|
23
25
|
const value = get(locale, path, path) as string
|
|
@@ -27,9 +29,9 @@ export const translate = (path: string, option: undefined | TranslatorOption, lo
|
|
|
27
29
|
return value.replace(/\{(\w+)\}/g, (_, key) => `${option?.[key] ?? `{${key}}`}`)
|
|
28
30
|
}
|
|
29
31
|
|
|
30
|
-
export const buildLocaleContext = (locale:
|
|
31
|
-
const
|
|
32
|
-
const
|
|
32
|
+
export const buildLocaleContext = (locale: LocaleSource): LocaleContext => {
|
|
33
|
+
const localeRef = (isRef(locale) ? locale : ref(locale)) as LocaleRef
|
|
34
|
+
const lang = computed(() => localeRef.value.name)
|
|
33
35
|
return {
|
|
34
36
|
lang,
|
|
35
37
|
locale: localeRef,
|