@peng_kai/kit 0.2.0-beta.3 → 0.2.0-beta.30
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/admin/adminPlugin.ts +11 -1
- package/admin/components/filter/src/FilterDrawer.vue +153 -153
- package/admin/components/filter/src/FilterParam.vue +1 -1
- package/admin/components/filter/src/FilterReset.vue +12 -9
- package/admin/components/rich-text/index.ts +1 -1
- package/admin/components/rich-text/src/RichText.new.vue +164 -0
- package/admin/components/rich-text/src/RichText.vue +3 -6
- package/admin/components/rich-text/src/editorConfig.ts +126 -0
- package/admin/components/rich-text/src/imageUploader.ts +20 -18
- package/admin/components/scroll-nav/index.ts +1 -1
- package/admin/components/scroll-nav/src/ScrollNav.vue +1 -1
- package/admin/components/settings/index.ts +1 -0
- package/admin/components/settings/src/Settings.vue +333 -0
- package/admin/components/text/index.ts +13 -13
- package/admin/components/text/src/Amount.vue +121 -121
- package/admin/components/text/src/Datetime.vue +1 -1
- package/admin/components/text/src/Duration.vue +26 -26
- package/admin/components/text/src/Hash.vue +51 -51
- package/admin/components/text/src/createTagGetter.ts +13 -13
- package/admin/components/upload/index.ts +1 -0
- package/admin/components/upload/src/PictureCardUpload.vue +1 -1
- package/admin/components/upload/src/helpers.ts +37 -0
- package/admin/defines/route/defineRoute.ts +2 -4
- package/admin/defines/route/getRoutes.ts +4 -4
- package/admin/defines/route/index.ts +1 -1
- package/admin/defines/route-guard/defineRouteGuard.ts +1 -4
- package/admin/defines/route-guard/getRouteGuards.ts +5 -7
- package/admin/defines/startup/defineStartup.ts +1 -3
- package/admin/defines/startup/runStartup.ts +4 -6
- package/admin/layout/large/Breadcrumb.vue +2 -2
- package/admin/layout/large/Content.vue +2 -2
- package/admin/layout/large/Menu.vue +2 -2
- package/admin/layout/large/PageTab.vue +2 -2
- package/admin/permission/routerGuard.ts +1 -1
- package/admin/permission/vuePlugin.ts +1 -0
- package/admin/route-guards/index.ts +3 -3
- package/admin/route-guards/pageProgress.ts +27 -27
- package/admin/stores/createUsePageStore.ts +1 -3
- package/admin/styles/classCover.scss +107 -0
- package/admin/styles/globalCover.scss +54 -54
- package/admin/styles/index.scss +14 -12
- package/antd/components/InputNumberRange.vue +59 -59
- package/antd/directives/formLabelAlign.ts +36 -36
- package/antd/hooks/useAntdDrawer.ts +73 -73
- package/antd/hooks/useAntdForm.ts +1 -1
- package/antd/hooks/useAntdModal.ts +4 -1
- package/antd/hooks/useAntdTable.ts +2 -1
- package/libs/dayjs.ts +7 -0
- package/libs/echarts.ts +1 -1
- package/libs/vue-i18n.ts +21 -0
- package/package.json +36 -35
- package/request/helpers.ts +68 -68
- package/request/interceptors/returnResultType.ts +3 -3
- package/request/interceptors/toLogin.ts +43 -26
- package/request/request.ts +0 -3
- package/request/type.d.ts +92 -92
- package/stylelint.config.cjs +7 -7
- package/tsconfig.json +50 -50
- package/utils/LocaleManager.ts +125 -0
- package/utils/date.ts +1 -9
- package/vite/index.mjs +34 -8
- package/vue/components/infinite-query/index.ts +1 -1
- package/vue/components/infinite-query/src/InfiniteQuery.vue +199 -199
- package/vue/components/infinite-query/src/useCreateTrigger.ts +39 -39
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
export const defaultConfig: Record<string, any> = {
|
|
2
|
+
language: {
|
|
3
|
+
ui: 'zh-cn',
|
|
4
|
+
},
|
|
5
|
+
removePlugins: ['ImportWord', 'ExportWord', 'RevisionHistory', 'RealTimeCollaborativeEditing', 'RealTimeCollaborativeComments', 'RealTimeCollaborativeRevisionHistory', 'RealTimeCollaborativeTrackChanges', 'PresenceList', 'WProofreader', 'DocumentOutline', 'Comments', 'TrackChanges', 'TrackChangesData', 'TableOfContents', 'SlashCommand', 'PasteFromOfficeEnhanced', 'ContentTemplates', 'FormatPainter', 'Mentions', 'PageBreak', 'Pagination', 'AIAssistant', 'CaseChange', 'Template'],
|
|
6
|
+
toolbar: {
|
|
7
|
+
items: [
|
|
8
|
+
'undo',
|
|
9
|
+
'redo',
|
|
10
|
+
'|',
|
|
11
|
+
'showBlocks',
|
|
12
|
+
'selectAll',
|
|
13
|
+
'|',
|
|
14
|
+
'heading',
|
|
15
|
+
'|',
|
|
16
|
+
'fontSize',
|
|
17
|
+
'fontFamily',
|
|
18
|
+
'fontColor',
|
|
19
|
+
'fontBackgroundColor',
|
|
20
|
+
'|',
|
|
21
|
+
'bold',
|
|
22
|
+
'italic',
|
|
23
|
+
'underline',
|
|
24
|
+
{
|
|
25
|
+
label: 'Formatting',
|
|
26
|
+
icon: 'text',
|
|
27
|
+
items: ['strikethrough', 'subscript', 'superscript', 'code', 'horizontalLine', '|', 'removeFormat'],
|
|
28
|
+
},
|
|
29
|
+
'|',
|
|
30
|
+
'link',
|
|
31
|
+
'uploadImage',
|
|
32
|
+
'insertTable',
|
|
33
|
+
{
|
|
34
|
+
label: 'Insert',
|
|
35
|
+
icon: 'plus',
|
|
36
|
+
items: ['highlight', 'blockQuote', 'mediaEmbed', 'codeBlock', 'htmlEmbed'],
|
|
37
|
+
},
|
|
38
|
+
'|',
|
|
39
|
+
'alignment',
|
|
40
|
+
'|',
|
|
41
|
+
'bulletedList',
|
|
42
|
+
'numberedList',
|
|
43
|
+
'todoList',
|
|
44
|
+
'outdent',
|
|
45
|
+
'indent',
|
|
46
|
+
'|',
|
|
47
|
+
'sourceEditing',
|
|
48
|
+
],
|
|
49
|
+
shouldNotGroupWhenFull: true,
|
|
50
|
+
},
|
|
51
|
+
htmlSupport: {
|
|
52
|
+
allow: [
|
|
53
|
+
{
|
|
54
|
+
name: /^.*$/,
|
|
55
|
+
styles: true,
|
|
56
|
+
attributes: true,
|
|
57
|
+
classes: true,
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
},
|
|
61
|
+
fontSize: {
|
|
62
|
+
options: [10, 12, 14, 'default', 18, 20, 22],
|
|
63
|
+
supportAllValues: true,
|
|
64
|
+
},
|
|
65
|
+
image: {
|
|
66
|
+
styles: [
|
|
67
|
+
'alignCenter',
|
|
68
|
+
'alignLeft',
|
|
69
|
+
'alignRight',
|
|
70
|
+
],
|
|
71
|
+
resizeOptions: [
|
|
72
|
+
{ name: 'resizeImage:original', label: 'Original', value: null },
|
|
73
|
+
{ name: 'resizeImage:25', label: '25%', value: '25' },
|
|
74
|
+
{ name: 'resizeImage:50', label: '50%', value: '50' },
|
|
75
|
+
{ name: 'resizeImage:75', label: '75%', value: '75' },
|
|
76
|
+
],
|
|
77
|
+
toolbar: [
|
|
78
|
+
'imageTextAlternative',
|
|
79
|
+
'toggleImageCaption',
|
|
80
|
+
'|',
|
|
81
|
+
'imageStyle:inline',
|
|
82
|
+
'imageStyle:wrapText',
|
|
83
|
+
'imageStyle:breakText',
|
|
84
|
+
'imageStyle:side',
|
|
85
|
+
'|',
|
|
86
|
+
'resizeImage',
|
|
87
|
+
],
|
|
88
|
+
resizeUnit: 'px',
|
|
89
|
+
},
|
|
90
|
+
list: {
|
|
91
|
+
properties: {
|
|
92
|
+
styles: true,
|
|
93
|
+
startIndex: true,
|
|
94
|
+
reversed: true,
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
link: {
|
|
98
|
+
addTargetToExternalLinks: true,
|
|
99
|
+
defaultProtocol: 'https://',
|
|
100
|
+
decorators: {
|
|
101
|
+
toggleDownloadable: {
|
|
102
|
+
mode: 'manual',
|
|
103
|
+
label: 'Downloadable',
|
|
104
|
+
attributes: {
|
|
105
|
+
download: 'file',
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
table: {
|
|
111
|
+
contentToolbar: [
|
|
112
|
+
'tableColumn',
|
|
113
|
+
'tableRow',
|
|
114
|
+
'mergeTableCells',
|
|
115
|
+
'tableProperties',
|
|
116
|
+
'tableCellProperties',
|
|
117
|
+
'toggleTableCaption',
|
|
118
|
+
],
|
|
119
|
+
},
|
|
120
|
+
htmlEmbed: {
|
|
121
|
+
showPreviews: true,
|
|
122
|
+
},
|
|
123
|
+
wordCount: {
|
|
124
|
+
displayWords: true,
|
|
125
|
+
},
|
|
126
|
+
};
|
|
@@ -5,30 +5,32 @@ export { createImageUploaderForAws3 };
|
|
|
5
5
|
|
|
6
6
|
function createImageUploaderForAws3(awsS3: AwsS3, rootDir?: string): PluginConstructor {
|
|
7
7
|
return function (editor) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
setTimeout(() => {
|
|
9
|
+
editor.plugins.get('FileRepository').createUploadAdapter = (loader) => {
|
|
10
|
+
return {
|
|
11
|
+
async upload() {
|
|
12
|
+
const file = await loader.file;
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
if (file) {
|
|
15
|
+
const { uploader, fileURL } = await awsS3.upload(file, rootDir);
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
uploader.on('httpUploadProgress', (progress) => {
|
|
18
|
+
loader.uploadTotal = progress.total ?? null;
|
|
19
|
+
loader.uploaded = progress.loaded ?? 0;
|
|
20
|
+
});
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
await uploader.done();
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
return { default: fileURL };
|
|
25
|
+
}
|
|
25
26
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
return {};
|
|
28
|
+
},
|
|
29
|
+
abort() {
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
},
|
|
32
|
+
};
|
|
31
33
|
};
|
|
32
|
-
};
|
|
34
|
+
});
|
|
33
35
|
};
|
|
34
36
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default as ScrollNav } from './src/ScrollNav.vue';
|
|
1
|
+
export { default as ScrollNav } from './src/ScrollNav.vue';
|
|
@@ -10,7 +10,7 @@ const $content = document.querySelector(props.selector) as HTMLElement;
|
|
|
10
10
|
const $contentParent = $content.parentElement;
|
|
11
11
|
const { height: contentParentH } = useElementSize($contentParent);
|
|
12
12
|
const { height: contentH } = useElementSize($content);
|
|
13
|
-
const visible = computed(() => contentParentH.value *
|
|
13
|
+
const visible = computed(() => contentParentH.value * 1.5 < contentH.value);
|
|
14
14
|
|
|
15
15
|
function scrollTo(top: number) {
|
|
16
16
|
$contentParent?.scrollTo({ top });
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Settings } from './src/Settings.vue';
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { reactiveComputed } from '@vueuse/core';
|
|
3
|
+
import { cloneDeep, mapKeys, mapValues } from 'lodash-es';
|
|
4
|
+
import dayjs from 'dayjs';
|
|
5
|
+
import { Button, Card, CheckboxGroup, DatePicker, type DatePickerProps, Form, FormItem, Input, InputNumber, RadioGroup, RangePicker, Select, Textarea } from 'ant-design-vue';
|
|
6
|
+
import { computed, ref, toRef } from 'vue';
|
|
7
|
+
import { useMutation, useQuery, useQueryClient } from '@tanstack/vue-query';
|
|
8
|
+
import { type ItemSchema, useAntdForm } from '../../../../antd';
|
|
9
|
+
|
|
10
|
+
interface IConfigDetail {
|
|
11
|
+
category_id: number
|
|
12
|
+
data_type: string
|
|
13
|
+
form_type: number
|
|
14
|
+
key: string
|
|
15
|
+
label: string
|
|
16
|
+
options: any
|
|
17
|
+
required: number
|
|
18
|
+
sort: number
|
|
19
|
+
status: number
|
|
20
|
+
summary: string
|
|
21
|
+
value: any
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
enum FormTypes {
|
|
25
|
+
/** 数字输入框 */
|
|
26
|
+
NUMBER_INPUT = 0,
|
|
27
|
+
/** 文本输入框 */
|
|
28
|
+
TEXT_INPUT = 1,
|
|
29
|
+
/** 多行文本输入框 */
|
|
30
|
+
TEXTAREA = 2,
|
|
31
|
+
/** 开关 */
|
|
32
|
+
SWITCH = 3,
|
|
33
|
+
/** 单选框 */
|
|
34
|
+
RADIO = 4,
|
|
35
|
+
/** 多选框 */
|
|
36
|
+
CHECKBOX = 5,
|
|
37
|
+
/** 单选下拉选择器 */
|
|
38
|
+
SINGLE_SELECT = 6,
|
|
39
|
+
/** 多选下拉选择器 */
|
|
40
|
+
MULTIPLE_SELECT = 7,
|
|
41
|
+
/** 单一日期选择器 */
|
|
42
|
+
SINGLE_DATE_PICKER = 13,
|
|
43
|
+
/** 日期范围选择器 */
|
|
44
|
+
RANGE_DATE_PICKER = 14,
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const antdPropsResolvers: Record<number, (config: IConfigDetail) => IConfigDetail> = {
|
|
48
|
+
[FormTypes.SWITCH](config) {
|
|
49
|
+
const props: any = {};
|
|
50
|
+
|
|
51
|
+
if (config.options) {
|
|
52
|
+
props.options = config.options.split(',').map((item: any) => {
|
|
53
|
+
const [label, value] = item.split(':');
|
|
54
|
+
return { value, label };
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
props.options = [{ value: '1', label: '是' }, { value: '0', label: '否' }];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
config.options = props;
|
|
62
|
+
|
|
63
|
+
return config;
|
|
64
|
+
},
|
|
65
|
+
[FormTypes.RADIO](config) {
|
|
66
|
+
return this[FormTypes.SWITCH](config);
|
|
67
|
+
},
|
|
68
|
+
[FormTypes.CHECKBOX](config) {
|
|
69
|
+
const props: any = {};
|
|
70
|
+
props.options = config.options.split(',').map((item: any) => {
|
|
71
|
+
const [label, value] = item.split(':');
|
|
72
|
+
return { value, label };
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
config.value = config.value.split(',');
|
|
76
|
+
config.options = props;
|
|
77
|
+
|
|
78
|
+
return config;
|
|
79
|
+
},
|
|
80
|
+
[FormTypes.SINGLE_SELECT](config) {
|
|
81
|
+
return this[FormTypes.SWITCH](config);
|
|
82
|
+
},
|
|
83
|
+
[FormTypes.MULTIPLE_SELECT](config) {
|
|
84
|
+
return this[FormTypes.CHECKBOX](config);
|
|
85
|
+
},
|
|
86
|
+
[FormTypes.SINGLE_DATE_PICKER](config) {
|
|
87
|
+
const props: DatePickerProps = {};
|
|
88
|
+
|
|
89
|
+
if (config.options) {
|
|
90
|
+
const [minDate, maxDate] = (config.options || '/').split('/').map(dayjs);
|
|
91
|
+
props.disabledDate = (current) => {
|
|
92
|
+
return current.isBefore(minDate) || current.isAfter(maxDate);
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
config.value = config.value === '' ? undefined : dayjs(config.value);
|
|
97
|
+
config.options = props;
|
|
98
|
+
|
|
99
|
+
return config;
|
|
100
|
+
},
|
|
101
|
+
[FormTypes.RANGE_DATE_PICKER](config) {
|
|
102
|
+
const props: DatePickerProps = {};
|
|
103
|
+
|
|
104
|
+
if (config.options) {
|
|
105
|
+
const [minDate, maxDate] = (config.options || '/').split('/').map(dayjs);
|
|
106
|
+
props.disabledDate = (current) => {
|
|
107
|
+
return current.isBefore(minDate) || current.isAfter(maxDate);
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (config.value === '')
|
|
112
|
+
config.value = [undefined, undefined];
|
|
113
|
+
else
|
|
114
|
+
config.value = (config.value || '/').split('/').map(dayjs);
|
|
115
|
+
|
|
116
|
+
config.options = props;
|
|
117
|
+
|
|
118
|
+
return config;
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
const antdValueResolvers: Record<number, (value: any) => any> = {
|
|
122
|
+
[FormTypes.NUMBER_INPUT](value) {
|
|
123
|
+
return String(value);
|
|
124
|
+
},
|
|
125
|
+
[FormTypes.CHECKBOX](value) {
|
|
126
|
+
if (Array.isArray(value))
|
|
127
|
+
return value.join(',');
|
|
128
|
+
|
|
129
|
+
return value;
|
|
130
|
+
},
|
|
131
|
+
[FormTypes.MULTIPLE_SELECT](value) {
|
|
132
|
+
if (Array.isArray(value))
|
|
133
|
+
return value.join(',');
|
|
134
|
+
|
|
135
|
+
return value;
|
|
136
|
+
},
|
|
137
|
+
[FormTypes.SINGLE_DATE_PICKER](value) {
|
|
138
|
+
if (dayjs.isDayjs(value))
|
|
139
|
+
return value.format('YYYY-MM-DD');
|
|
140
|
+
|
|
141
|
+
return value;
|
|
142
|
+
},
|
|
143
|
+
[FormTypes.RANGE_DATE_PICKER](value) {
|
|
144
|
+
if (dayjs.isDayjs(value[0]) && dayjs.isDayjs(value[1]))
|
|
145
|
+
return [value[0].format('YYYY-MM-DD'), value[1].format('YYYY-MM-DD')].join('/');
|
|
146
|
+
|
|
147
|
+
return value;
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
</script>
|
|
151
|
+
|
|
152
|
+
<script setup lang="ts">
|
|
153
|
+
const props = defineProps<{
|
|
154
|
+
categoryApi: Api.Request
|
|
155
|
+
configApi: Api.Request
|
|
156
|
+
updateApi: Api.Request
|
|
157
|
+
}>();
|
|
158
|
+
|
|
159
|
+
const queryClient = useQueryClient();
|
|
160
|
+
|
|
161
|
+
/* 配置分类 */
|
|
162
|
+
const categoryId = ref(1);
|
|
163
|
+
const categoryQuerier = useQuery({
|
|
164
|
+
queryKey: [props.categoryApi.id],
|
|
165
|
+
queryFn: () => props.categoryApi(undefined),
|
|
166
|
+
});
|
|
167
|
+
const categoryList = computed(() => categoryQuerier.data.value?.map((item: any) => ({ key: String(item.type), tab: item.label })));
|
|
168
|
+
|
|
169
|
+
/* 当前分类下的配置 */
|
|
170
|
+
const configQuerier = useQuery<IConfigDetail[] | undefined>({
|
|
171
|
+
enabled: computed(() => !!categoryQuerier.data.value),
|
|
172
|
+
queryKey: [props.configApi.id, categoryId],
|
|
173
|
+
queryFn: () => props.configApi({ category_id: categoryId.value }),
|
|
174
|
+
});
|
|
175
|
+
const configList = computed(() => {
|
|
176
|
+
const list = cloneDeep(configQuerier.data.value);
|
|
177
|
+
|
|
178
|
+
if (!list?.length)
|
|
179
|
+
return;
|
|
180
|
+
|
|
181
|
+
for (let i = 0; i < list.length; i++) {
|
|
182
|
+
const config = { ...list[i] };
|
|
183
|
+
list[i] = antdPropsResolvers[config.form_type]?.(config) ?? config;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return list;
|
|
187
|
+
});
|
|
188
|
+
const configMap = computed(() => mapKeys(cloneDeep(configQuerier.data.value ?? []), 'key'));
|
|
189
|
+
|
|
190
|
+
/* 配置表单 */
|
|
191
|
+
const settingMutator = useMutation({
|
|
192
|
+
mutationKey: [props.updateApi.id],
|
|
193
|
+
mutationFn: props.updateApi.setDefaultConfig({ successMessage: '更新成功' }),
|
|
194
|
+
onSuccess() {
|
|
195
|
+
configQuerier.refetch();
|
|
196
|
+
queryClient.invalidateQueries({ queryKey: [props.configApi.id], exact: false });
|
|
197
|
+
},
|
|
198
|
+
});
|
|
199
|
+
const formSchema = reactiveComputed(() => {
|
|
200
|
+
const _configList = configList.value ?? [];
|
|
201
|
+
const entries = _configList.map(config => [
|
|
202
|
+
config.key,
|
|
203
|
+
{
|
|
204
|
+
value: cloneDeep(config.value),
|
|
205
|
+
rules: config.required ? [{ required: true }] : undefined,
|
|
206
|
+
},
|
|
207
|
+
] as [string, ItemSchema]);
|
|
208
|
+
const schema = Object.fromEntries(entries);
|
|
209
|
+
|
|
210
|
+
return schema;
|
|
211
|
+
});
|
|
212
|
+
const settingForm = useAntdForm(formSchema, {
|
|
213
|
+
transform(state) {
|
|
214
|
+
return mapValues(state, (v, k) => {
|
|
215
|
+
const formType = configMap.value[k].form_type;
|
|
216
|
+
const resolver = antdValueResolvers[formType];
|
|
217
|
+
|
|
218
|
+
return resolver ? resolver(v) : v;
|
|
219
|
+
});
|
|
220
|
+
},
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
/** 提交表单内容 */
|
|
224
|
+
async function submitSetting() {
|
|
225
|
+
const body = await settingForm.$form.validate?.().catch(() => {});
|
|
226
|
+
|
|
227
|
+
if (body)
|
|
228
|
+
await settingMutator.mutateAsync({ requestBody: settingForm.stateTF });
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/** 重置表单内容 */
|
|
232
|
+
function resetSetting() {
|
|
233
|
+
configList.value?.forEach(config => settingForm.state[config.key] = cloneDeep(config.value));
|
|
234
|
+
settingForm.$form.clearValidate?.();
|
|
235
|
+
}
|
|
236
|
+
</script>
|
|
237
|
+
|
|
238
|
+
<template>
|
|
239
|
+
<Card
|
|
240
|
+
class="antd-cover__actions-right-align"
|
|
241
|
+
:activeTabKey="String(categoryId)"
|
|
242
|
+
:tabList="categoryList"
|
|
243
|
+
:loading="configQuerier.isPending.value"
|
|
244
|
+
@tabChange="key => categoryId = Number(key)"
|
|
245
|
+
>
|
|
246
|
+
<Form
|
|
247
|
+
v-bind="settingForm.props"
|
|
248
|
+
class="ant-cover__col2-form"
|
|
249
|
+
layout="vertical"
|
|
250
|
+
:disabled="settingMutator.isPending.value"
|
|
251
|
+
>
|
|
252
|
+
<template v-for="item of configList" :key="item.key">
|
|
253
|
+
<FormItem v-bind="settingForm.itemProps[item.key]" :label="item.label" :extra="item.summary">
|
|
254
|
+
<slot
|
|
255
|
+
v-if="$slots[item.key]"
|
|
256
|
+
:name="item.key"
|
|
257
|
+
:state="toRef(settingForm.state, item.key)"
|
|
258
|
+
:config="item"
|
|
259
|
+
:orginConfig="configMap[item.key]"
|
|
260
|
+
/>
|
|
261
|
+
<template v-else>
|
|
262
|
+
<slot v-if="item.form_type === FormTypes.NUMBER_INPUT" :name="FormTypes.NUMBER_INPUT">
|
|
263
|
+
<InputNumber v-model:value="settingForm.state[item.key]" class="w-full" />
|
|
264
|
+
</slot>
|
|
265
|
+
|
|
266
|
+
<slot v-else-if="item.form_type === FormTypes.TEXT_INPUT" :name="FormTypes.TEXT_INPUT">
|
|
267
|
+
<Input v-model:value="settingForm.state[item.key]" allowClear />
|
|
268
|
+
</slot>
|
|
269
|
+
|
|
270
|
+
<slot v-else-if="item.form_type === FormTypes.TEXTAREA" :name="FormTypes.TEXTAREA">
|
|
271
|
+
<Textarea v-model:value="settingForm.state[item.key]" :rows="4" />
|
|
272
|
+
</slot>
|
|
273
|
+
|
|
274
|
+
<slot v-else-if="item.form_type === FormTypes.SWITCH" :name="FormTypes.SWITCH">
|
|
275
|
+
<RadioGroup
|
|
276
|
+
v-model:value="settingForm.state[item.key]"
|
|
277
|
+
v-bind="item.options"
|
|
278
|
+
buttonStyle="solid"
|
|
279
|
+
optionType="button"
|
|
280
|
+
/>
|
|
281
|
+
</slot>
|
|
282
|
+
|
|
283
|
+
<slot v-else-if="item.form_type === FormTypes.RADIO" :name="FormTypes.RADIO">
|
|
284
|
+
<RadioGroup
|
|
285
|
+
v-model:value="settingForm.state[item.key]"
|
|
286
|
+
buttonStyle="solid"
|
|
287
|
+
v-bind="item.options"
|
|
288
|
+
/>
|
|
289
|
+
</slot>
|
|
290
|
+
|
|
291
|
+
<slot v-else-if="item.form_type === FormTypes.CHECKBOX" :name="FormTypes.CHECKBOX">
|
|
292
|
+
<CheckboxGroup v-model:value="settingForm.state[item.key]" v-bind="item.options" />
|
|
293
|
+
</slot>
|
|
294
|
+
|
|
295
|
+
<slot v-else-if="item.form_type === FormTypes.SINGLE_SELECT" :name="FormTypes.SINGLE_SELECT">
|
|
296
|
+
<Select v-model:value="settingForm.state[item.key]" v-bind="item.options" />
|
|
297
|
+
</slot>
|
|
298
|
+
|
|
299
|
+
<slot v-else-if="item.form_type === FormTypes.MULTIPLE_SELECT" :name="FormTypes.MULTIPLE_SELECT">
|
|
300
|
+
<Select v-model:value="settingForm.state[item.key]" v-bind="item.options" mode="multiple" />
|
|
301
|
+
</slot>
|
|
302
|
+
|
|
303
|
+
<slot v-else-if="item.form_type === FormTypes.SINGLE_DATE_PICKER" :name="FormTypes.SINGLE_DATE_PICKER">
|
|
304
|
+
<DatePicker v-model:value="settingForm.state[item.key]" v-bind="item.options" />
|
|
305
|
+
</slot>
|
|
306
|
+
|
|
307
|
+
<slot v-else-if="item.form_type === FormTypes.RANGE_DATE_PICKER" :name="FormTypes.RANGE_DATE_PICKER">
|
|
308
|
+
<RangePicker v-model:value="settingForm.state[item.key]" v-bind="item.options" />
|
|
309
|
+
</slot>
|
|
310
|
+
|
|
311
|
+
<span v-else class="text-red">没有找到预设 form_type:{{ item.form_type }},可以通过 {{ item.key }} 插槽自定义</span>
|
|
312
|
+
</template>
|
|
313
|
+
</FormItem>
|
|
314
|
+
</template>
|
|
315
|
+
</Form>
|
|
316
|
+
|
|
317
|
+
<template #actions>
|
|
318
|
+
<Button :disabled="settingMutator.isPending.value" @click="resetSetting()">
|
|
319
|
+
重置
|
|
320
|
+
</Button>
|
|
321
|
+
<Button type="primary" :loading="settingMutator.isPending.value" @click="submitSetting()">
|
|
322
|
+
提交
|
|
323
|
+
</Button>
|
|
324
|
+
</template>
|
|
325
|
+
</Card>
|
|
326
|
+
</template>
|
|
327
|
+
|
|
328
|
+
<style lang="scss" scoped>
|
|
329
|
+
.ant-cover__col2-form :deep(.ant-form-item-label > label) {
|
|
330
|
+
// padding-left: 0.5em;
|
|
331
|
+
// border-left: 2px solid #2361d0;
|
|
332
|
+
}
|
|
333
|
+
</style>
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import Hash from './src/Hash.vue';
|
|
2
|
-
import Amount from './src/Amount.vue';
|
|
3
|
-
import Datetime from './src/Datetime.vue';
|
|
4
|
-
import Duration from './src/Duration.vue';
|
|
5
|
-
|
|
6
|
-
export { createTagGetter } from './src/createTagGetter';
|
|
7
|
-
|
|
8
|
-
export const Text = {
|
|
9
|
-
Hash,
|
|
10
|
-
Amount,
|
|
11
|
-
Datetime,
|
|
12
|
-
Duration,
|
|
13
|
-
};
|
|
1
|
+
import Hash from './src/Hash.vue';
|
|
2
|
+
import Amount from './src/Amount.vue';
|
|
3
|
+
import Datetime from './src/Datetime.vue';
|
|
4
|
+
import Duration from './src/Duration.vue';
|
|
5
|
+
|
|
6
|
+
export { createTagGetter } from './src/createTagGetter';
|
|
7
|
+
|
|
8
|
+
export const Text = {
|
|
9
|
+
Hash,
|
|
10
|
+
Amount,
|
|
11
|
+
Datetime,
|
|
12
|
+
Duration,
|
|
13
|
+
};
|