Commit 0b6110a8fc92a11df6501346e093246a5abe2b0e

Authored by vben
1 parent 4ddee05d

feat(form-page): add form page demo

Showing 43 changed files with 1389 additions and 116 deletions
CHANGELOG.zh_CN.md
@@ -4,6 +4,9 @@ @@ -4,6 +4,9 @@
4 4
5 - 新增 base64 文件流下载 5 - 新增 base64 文件流下载
6 - 优化上传组件及示例 6 - 优化上传组件及示例
  7 +- 新增可编辑行示例
  8 +- 新增个人页
  9 +- 新增表单页
7 10
8 ### 🎫 Chores 11 ### 🎫 Chores
9 12
README.md
@@ -232,6 +232,8 @@ yarn clean:lib # 删除node_modules,兼容window系统 @@ -232,6 +232,8 @@ yarn clean:lib # 删除node_modules,兼容window系统
232 232
233 ## 正在开发的功能 233 ## 正在开发的功能
234 234
  235 +- [ ] 新分支全局国家化
  236 +- [ ] 示例 page 页面
235 - [ ] 主题配置 237 - [ ] 主题配置
236 - [ ] 黑暗主题 238 - [ ] 黑暗主题
237 - [ ] 打包 CDN 239 - [ ] 打包 CDN
package.json
@@ -23,7 +23,7 @@ @@ -23,7 +23,7 @@
23 "dependencies": { 23 "dependencies": {
24 "@iconify/iconify": "^2.0.0-rc.2", 24 "@iconify/iconify": "^2.0.0-rc.2",
25 "@vueuse/core": "^4.0.0-beta.41", 25 "@vueuse/core": "^4.0.0-beta.41",
26 - "ant-design-vue": "^2.0.0-rc.1", 26 + "ant-design-vue": "^2.0.0-beta.15",
27 "apexcharts": "3.22.0", 27 "apexcharts": "3.22.0",
28 "axios": "^0.21.0", 28 "axios": "^0.21.0",
29 "echarts": "^4.9.0", 29 "echarts": "^4.9.0",
src/components/Basic/src/BasicHelp.vue
@@ -48,6 +48,10 @@ @@ -48,6 +48,10 @@
48 bottom: 0, 48 bottom: 0,
49 }), 49 }),
50 }, 50 },
  51 + placement: {
  52 + type: String as PropType<string>,
  53 + defualt: 'right',
  54 + },
51 }, 55 },
52 setup(props, { slots }) { 56 setup(props, { slots }) {
53 const getOverlayStyleRef = computed(() => { 57 const getOverlayStyleRef = computed(() => {
@@ -97,7 +101,7 @@ @@ -97,7 +101,7 @@
97 overlayClassName: 'base-help__wrap', 101 overlayClassName: 'base-help__wrap',
98 autoAdjustOverflow: true, 102 autoAdjustOverflow: true,
99 overlayStyle: unref(getOverlayStyleRef), 103 overlayStyle: unref(getOverlayStyleRef),
100 - placement: 'right', 104 + placement: props.placement,
101 getPopupContainer: () => getPopupContainer(), 105 getPopupContainer: () => getPopupContainer(),
102 }, 106 },
103 { 107 {
src/components/Footer/index.ts 0 → 100644
  1 +export { default as AppFooter } from './src/index.vue';
src/components/Footer/src/index.vue 0 → 100644
  1 +<template>
  2 + <div class="app-footer" :style="{ width: getWidth }">
  3 + <div class="app-footer__left">
  4 + <slot name="left" />
  5 + </div>
  6 + <div class="app-footer__right">
  7 + <slot name="right" />
  8 + </div>
  9 + </div>
  10 +</template>
  11 +<script lang="ts">
  12 + import { defineComponent, computed, unref } from 'vue';
  13 + import { SIDE_BAR_MINI_WIDTH, SIDE_BAR_SHOW_TIT_MINI_WIDTH } from '/@/enums/appEnum';
  14 + import { appStore } from '/@/store/modules/app';
  15 + import { menuStore } from '/@/store/modules/menu';
  16 + export default defineComponent({
  17 + name: 'AppFooter',
  18 + setup() {
  19 + const getMiniWidth = computed(() => {
  20 + const {
  21 + menuSetting: { collapsedShowTitle },
  22 + } = appStore.getProjectConfig;
  23 + return collapsedShowTitle ? SIDE_BAR_SHOW_TIT_MINI_WIDTH : SIDE_BAR_MINI_WIDTH;
  24 + });
  25 +
  26 + const getWidth = computed(() => {
  27 + const { getCollapsedState, getMenuWidthState } = menuStore;
  28 + const width = getCollapsedState ? unref(getMiniWidth) : getMenuWidthState;
  29 + return `calc(100% - ${width}px)`;
  30 + });
  31 +
  32 + return { getWidth };
  33 + },
  34 + });
  35 +</script>
  36 +<style lang="less" scoped>
  37 + .app-footer {
  38 + position: fixed;
  39 + right: 0;
  40 + bottom: 0;
  41 + z-index: 99;
  42 + display: flex;
  43 + width: 100%;
  44 + align-items: center;
  45 + padding: 0 24px;
  46 + line-height: 44px;
  47 + background: #fff;
  48 + border-top: 1px solid #f0f0f0;
  49 + box-shadow: 0 -6px 16px -8px rgba(0, 0, 0, 0.08), 0 -9px 28px 0 rgba(0, 0, 0, 0.05),
  50 + 0 -12px 48px 16px rgba(0, 0, 0, 0.03);
  51 + transition: width 0.3s;
  52 +
  53 + &__left {
  54 + flex: 1 1;
  55 + }
  56 + }
  57 +</style>
src/components/Form/src/BasicForm.vue
1 <template> 1 <template>
2 - <Form v-bind="$attrs" ref="formElRef" :model="formModel"> 2 + <Form v-bind="{ ...$attrs, ...$props }" ref="formElRef" :model="formModel">
3 <Row :class="getProps.compact ? 'compact-form-row' : ''"> 3 <Row :class="getProps.compact ? 'compact-form-row' : ''">
4 <slot name="formHeader" /> 4 <slot name="formHeader" />
5 <template v-for="schema in getSchema" :key="schema.field"> 5 <template v-for="schema in getSchema" :key="schema.field">
@@ -54,8 +54,8 @@ @@ -54,8 +54,8 @@
54 const formModel = reactive({}); 54 const formModel = reactive({});
55 55
56 const actionState = reactive({ 56 const actionState = reactive({
57 - resetAction: () => {},  
58 - submitAction: () => {}, 57 + resetAction: {},
  58 + submitAction: {},
59 }); 59 });
60 60
61 const advanceState = reactive<AdvanceState>({ 61 const advanceState = reactive<AdvanceState>({
@@ -67,7 +67,7 @@ @@ -67,7 +67,7 @@
67 67
68 const defaultValueRef = ref<any>({}); 68 const defaultValueRef = ref<any>({});
69 const propsRef = ref<Partial<FormProps>>({}); 69 const propsRef = ref<Partial<FormProps>>({});
70 - const schemaRef = ref<FormSchema[] | null>(null); 70 + const schemaRef = ref<Nullable<FormSchema[]>>(null);
71 const formElRef = ref<Nullable<FormActionType>>(null); 71 const formElRef = ref<Nullable<FormActionType>>(null);
72 72
73 const getMergePropsRef = computed( 73 const getMergePropsRef = computed(
@@ -98,7 +98,15 @@ @@ -98,7 +98,15 @@
98 for (const schema of schemas) { 98 for (const schema of schemas) {
99 const { defaultValue, component } = schema; 99 const { defaultValue, component } = schema;
100 if (defaultValue && dateItemType.includes(component!)) { 100 if (defaultValue && dateItemType.includes(component!)) {
101 - schema.defaultValue = moment(defaultValue); 101 + if (!Array.isArray(defaultValue)) {
  102 + schema.defaultValue = moment(defaultValue);
  103 + } else {
  104 + const def: moment.Moment[] = [];
  105 + defaultValue.forEach((item) => {
  106 + def.push(moment(item));
  107 + });
  108 + schema.defaultValue = def;
  109 + }
102 } 110 }
103 } 111 }
104 return schemas as FormSchema[]; 112 return schemas as FormSchema[];
@@ -139,8 +147,8 @@ @@ -139,8 +147,8 @@
139 formModel, 147 formModel,
140 getSchema, 148 getSchema,
141 defaultValueRef, 149 defaultValueRef,
142 - formElRef: formElRef as any,  
143 - schemaRef: schemaRef as any, 150 + formElRef: formElRef as Ref<FormActionType>,
  151 + schemaRef: schemaRef as Ref<FormSchema[]>,
144 handleFormValues, 152 handleFormValues,
145 actionState, 153 actionState,
146 }); 154 });
@@ -156,6 +164,13 @@ @@ -156,6 +164,13 @@
156 } 164 }
157 ); 165 );
158 166
  167 + watch(
  168 + () => getSchema.value,
  169 + () => {
  170 + initDefault();
  171 + }
  172 + );
  173 +
159 /** 174 /**
160 * @description:设置表单 175 * @description:设置表单
161 */ 176 */
src/components/Form/src/FormItem.tsx
@@ -250,14 +250,21 @@ export default defineComponent({ @@ -250,14 +250,21 @@ export default defineComponent({
250 } 250 }
251 251
252 function renderLabelHelpMessage() { 252 function renderLabelHelpMessage() {
253 - const { label, helpMessage, helpComponentProps } = props.schema; 253 + const { label, helpMessage, helpComponentProps, subLabel } = props.schema;
  254 + const renderLabel = subLabel ? (
  255 + <span>
  256 + {label} <span style="color:#00000073">{subLabel}</span>
  257 + </span>
  258 + ) : (
  259 + label
  260 + );
254 if (!helpMessage || (Array.isArray(helpMessage) && helpMessage.length === 0)) { 261 if (!helpMessage || (Array.isArray(helpMessage) && helpMessage.length === 0)) {
255 - return label; 262 + return renderLabel;
256 } 263 }
257 return ( 264 return (
258 <span> 265 <span>
259 - {label}  
260 - <BasicHelp class="mx-1" text={helpMessage} {...helpComponentProps} /> 266 + {renderLabel}
  267 + <BasicHelp placement="top" class="mx-1" text={helpMessage} {...helpComponentProps} />
261 </span> 268 </span>
262 ); 269 );
263 } 270 }
@@ -291,6 +298,7 @@ export default defineComponent({ @@ -291,6 +298,7 @@ export default defineComponent({
291 const { colProps = {}, colSlot, renderColContent, component } = props.schema; 298 const { colProps = {}, colSlot, renderColContent, component } = props.schema;
292 if (!componentMap.has(component)) return null; 299 if (!componentMap.has(component)) return null;
293 const { baseColProps = {} } = props.formProps; 300 const { baseColProps = {} } = props.formProps;
  301 +
294 const realColProps = { ...baseColProps, ...colProps }; 302 const realColProps = { ...baseColProps, ...colProps };
295 const { isIfShow, isShow } = getShow(); 303 const { isIfShow, isShow } = getShow();
296 const getContent = () => { 304 const getContent = () => {
src/components/Form/src/helper.ts
@@ -7,7 +7,7 @@ export function createPlaceholderMessage(component: ComponentType) { @@ -7,7 +7,7 @@ export function createPlaceholderMessage(component: ComponentType) {
7 if (component.includes('Input') || component.includes('Complete')) { 7 if (component.includes('Input') || component.includes('Complete')) {
8 return '请输入'; 8 return '请输入';
9 } 9 }
10 - if (component.includes('Picker') && !component.includes('Range')) { 10 + if (component.includes('Picker')) {
11 return '请选择'; 11 return '请选择';
12 } 12 }
13 if ( 13 if (
src/components/Form/src/hooks/useLabelWidth.ts
@@ -25,19 +25,26 @@ export function useItemLabelWidth(schemaItemRef: Ref&lt;FormSchema&gt;, propsRef: Ref&lt; @@ -25,19 +25,26 @@ export function useItemLabelWidth(schemaItemRef: Ref&lt;FormSchema&gt;, propsRef: Ref&lt;
25 const { labelCol = {}, wrapperCol = {} } = schemaItem.itemProps || {}; 25 const { labelCol = {}, wrapperCol = {} } = schemaItem.itemProps || {};
26 const { labelWidth, disabledLabelWidth } = schemaItem; 26 const { labelWidth, disabledLabelWidth } = schemaItem;
27 27
28 - const { labelWidth: globalLabelWidth } = unref(propsRef) as any; 28 + const {
  29 + labelWidth: globalLabelWidth,
  30 + labelCol: globalLabelCol,
  31 + wrapperCol: globWrapperCol,
  32 + } = unref(propsRef) as any;
  33 +
29 // 如果全局有设置labelWidth, 则所有item使用 34 // 如果全局有设置labelWidth, 则所有item使用
30 - if ((!globalLabelWidth && !labelWidth) || disabledLabelWidth) { 35 + if ((!globalLabelWidth && !labelWidth && !globalLabelCol) || disabledLabelWidth) {
31 return { labelCol, wrapperCol }; 36 return { labelCol, wrapperCol };
32 } 37 }
33 let width = labelWidth || globalLabelWidth; 38 let width = labelWidth || globalLabelWidth;
  39 + const col = { ...globalLabelCol, ...labelCol };
  40 + const wrapCol = { ...globWrapperCol, ...wrapperCol };
34 41
35 if (width) { 42 if (width) {
36 width = isNumber(width) ? `${width}px` : width; 43 width = isNumber(width) ? `${width}px` : width;
37 } 44 }
38 return { 45 return {
39 - labelCol: { style: { width }, ...labelCol },  
40 - wrapperCol: { style: { width: `calc(100% - ${width})` }, ...wrapperCol }, 46 + labelCol: { style: { width }, ...col },
  47 + wrapperCol: { style: { width: `calc(100% - ${width})` }, ...wrapCol },
41 }; 48 };
42 }); 49 });
43 } 50 }
src/components/Form/src/types/form.ts
@@ -41,6 +41,7 @@ export type RegisterFn = (formInstance: FormActionType) =&gt; void; @@ -41,6 +41,7 @@ export type RegisterFn = (formInstance: FormActionType) =&gt; void;
41 export type UseFormReturnType = [RegisterFn, FormActionType]; 41 export type UseFormReturnType = [RegisterFn, FormActionType];
42 42
43 export interface FormProps { 43 export interface FormProps {
  44 + // layout?: 'vertical' | 'inline' | 'horizontal';
44 // 表单值 45 // 表单值
45 model?: any; 46 model?: any;
46 // 整个表单所有项宽度 47 // 整个表单所有项宽度
@@ -108,6 +109,8 @@ export interface FormSchema { @@ -108,6 +109,8 @@ export interface FormSchema {
108 valueField?: string; 109 valueField?: string;
109 // 标签名 110 // 标签名
110 label: string; 111 label: string;
  112 + // 辅助文本
  113 + subLabel?: string;
111 // 文本右侧帮助文本 114 // 文本右侧帮助文本
112 helpMessage?: string | string[]; 115 helpMessage?: string | string[];
113 // BaseHelp组件props 116 // BaseHelp组件props
src/components/Menu/src/BasicMenu.tsx
@@ -136,9 +136,9 @@ export default defineComponent({ @@ -136,9 +136,9 @@ export default defineComponent({
136 const flag = await beforeClickFn(menu); 136 const flag = await beforeClickFn(menu);
137 if (!flag) return; 137 if (!flag) return;
138 } 138 }
  139 + emit('menuClick', menu);
139 const { path } = menu; 140 const { path } = menu;
140 menuState.selectedKeys = [path]; 141 menuState.selectedKeys = [path];
141 - emit('menuClick', menu);  
142 } 142 }
143 143
144 function handleMenuChange() { 144 function handleMenuChange() {
@@ -219,7 +219,6 @@ export default defineComponent({ @@ -219,7 +219,6 @@ export default defineComponent({
219 : {}; 219 : {};
220 return ( 220 return (
221 <Menu 221 <Menu
222 - forceSubMenuRender={props.isAppMenu}  
223 selectedKeys={selectedKeys} 222 selectedKeys={selectedKeys}
224 defaultSelectedKeys={defaultSelectedKeys} 223 defaultSelectedKeys={defaultSelectedKeys}
225 mode={mode} 224 mode={mode}
src/components/Table/index.ts
1 export { default as BasicTable } from './src/BasicTable.vue'; 1 export { default as BasicTable } from './src/BasicTable.vue';
2 export { default as TableAction } from './src/components/TableAction'; 2 export { default as TableAction } from './src/components/TableAction';
3 export { default as TableImg } from './src/components/TableImg.vue'; 3 export { default as TableImg } from './src/components/TableImg.vue';
4 -export { renderEditableCell } from './src/components/renderEditableCell'; 4 +export { renderEditableCell, renderEditableRow } from './src/components/renderEditable';
5 export { default as EditTableHeaderIcon } from './src/components/EditTableHeaderIcon.vue'; 5 export { default as EditTableHeaderIcon } from './src/components/EditTableHeaderIcon.vue';
6 6
7 export * from './src/types/table'; 7 export * from './src/types/table';
@@ -11,3 +11,5 @@ export * from &#39;./src/types/tableAction&#39;; @@ -11,3 +11,5 @@ export * from &#39;./src/types/tableAction&#39;;
11 export { useTable } from './src/hooks/useTable'; 11 export { useTable } from './src/hooks/useTable';
12 12
13 export type { FormSchema, FormProps } from '/@/components/Form/src/types/form'; 13 export type { FormSchema, FormProps } from '/@/components/Form/src/types/form';
  14 +
  15 +export type { EditRecordRow } from './src/components/renderEditable';
src/components/Table/src/components/TableAction.tsx
@@ -32,7 +32,7 @@ export default defineComponent({ @@ -32,7 +32,7 @@ export default defineComponent({
32 disabled={disabled} 32 disabled={disabled}
33 color={color} 33 color={color}
34 {...action} 34 {...action}
35 - key={index} 35 + key={`${index}-${label}`}
36 > 36 >
37 {() => ( 37 {() => (
38 <> 38 <>
@@ -60,7 +60,7 @@ export default defineComponent({ @@ -60,7 +60,7 @@ export default defineComponent({
60 } = popConfirm; 60 } = popConfirm;
61 return ( 61 return (
62 <Popconfirm 62 <Popconfirm
63 - key={`P-${index}`} 63 + key={`p-${index}-${title}`}
64 title={title} 64 title={title}
65 onConfirm={confirm} 65 onConfirm={confirm}
66 onCancel={cancel} 66 onCancel={cancel}
src/components/Table/src/components/renderEditableCell.tsx renamed to src/components/Table/src/components/renderEditable.tsx
1 -import { defineComponent, PropType, ref, unref, nextTick } from 'vue';  
2 -import { injectTable } from '../hooks/useProvinceTable'; 1 +import { defineComponent, PropType, ref, unref, nextTick, watchEffect } from 'vue';
3 import ClickOutSide from '/@/components/ClickOutSide/index.vue'; 2 import ClickOutSide from '/@/components/ClickOutSide/index.vue';
4 3
5 import { RenderEditableCellParams } from '../types/table'; 4 import { RenderEditableCellParams } from '../types/table';
6 import { ComponentType } from '../types/componentType'; 5 import { ComponentType } from '../types/componentType';
7 6
8 import { componentMap } from '../componentMap'; 7 import { componentMap } from '../componentMap';
9 -import '../style/editable-cell.less';  
10 import { isString, isBoolean } from '/@/utils/is'; 8 import { isString, isBoolean } from '/@/utils/is';
11 import { FormOutlined, CloseOutlined, CheckOutlined } from '@ant-design/icons-vue'; 9 import { FormOutlined, CloseOutlined, CheckOutlined } from '@ant-design/icons-vue';
12 10
  11 +import '../style/editable-cell.less';
  12 +
13 const prefixCls = 'editable-cell'; 13 const prefixCls = 'editable-cell';
14 const EditableCell = defineComponent({ 14 const EditableCell = defineComponent({
15 name: 'EditableCell', 15 name: 'EditableCell',
@@ -37,14 +37,35 @@ const EditableCell = defineComponent({ @@ -37,14 +37,35 @@ const EditableCell = defineComponent({
37 type: String as PropType<ComponentType>, 37 type: String as PropType<ComponentType>,
38 default: 'Input', 38 default: 'Input',
39 }, 39 },
  40 + editable: {
  41 + type: Boolean as PropType<boolean>,
  42 + default: false,
  43 + },
  44 + editRow: {
  45 + type: Boolean as PropType<boolean>,
  46 + default: false,
  47 + },
  48 + record: {
  49 + type: Object as PropType<EditRecordRow>,
  50 + },
  51 + placeholder: {
  52 + type: String as PropType<string>,
  53 + },
40 }, 54 },
41 emits: ['submit', 'cancel'], 55 emits: ['submit', 'cancel'],
42 setup(props, { attrs, emit }) { 56 setup(props, { attrs, emit }) {
43 - const table = injectTable();  
44 const elRef = ref<any>(null); 57 const elRef = ref<any>(null);
45 58
46 const isEditRef = ref(false); 59 const isEditRef = ref(false);
47 const currentValueRef = ref<string | boolean>(props.value); 60 const currentValueRef = ref<string | boolean>(props.value);
  61 + const defaultValueRef = ref<string | boolean>(props.value);
  62 +
  63 + watchEffect(() => {
  64 + defaultValueRef.value = props.value;
  65 + if (isBoolean(props.editable)) {
  66 + isEditRef.value = props.editable;
  67 + }
  68 + });
48 69
49 function handleChange(e: any) { 70 function handleChange(e: any) {
50 if (e && e.target && Reflect.has(e.target, 'value')) { 71 if (e && e.target && Reflect.has(e.target, 'value')) {
@@ -65,37 +86,55 @@ const EditableCell = defineComponent({ @@ -65,37 +86,55 @@ const EditableCell = defineComponent({
65 86
66 function handleCancel() { 87 function handleCancel() {
67 isEditRef.value = false; 88 isEditRef.value = false;
  89 + currentValueRef.value = defaultValueRef.value;
68 emit('cancel'); 90 emit('cancel');
69 } 91 }
70 92
  93 + if (props.record) {
  94 + /* eslint-disable */
  95 + props.record.onCancel = handleCancel;
  96 + /* eslint-disable */
  97 + props.record.onSubmit = handleSubmit;
  98 + }
  99 +
71 function handleSubmit() { 100 function handleSubmit() {
72 const { dataKey, dataIndex } = props; 101 const { dataKey, dataIndex } = props;
73 - if (!dataKey || !dataIndex) {  
74 - return;  
75 - }  
76 - isEditRef.value = false; 102 + if (!dataKey || !dataIndex) return;
77 103
78 - const { getDataSource } = table;  
79 - const dataSource = getDataSource();  
80 - const target = dataSource.find((item) => item.key === dataKey);  
81 - if (target) {  
82 - target[dataIndex] = unref(currentValueRef);  
83 - emit('submit', { dataKey, dataIndex, value: unref(currentValueRef) }); 104 + if (props.record) {
  105 + /* eslint-disable */
  106 + props.record[dataIndex] = unref(currentValueRef) as string;
84 } 107 }
  108 + isEditRef.value = false;
85 } 109 }
86 110
87 function onClickOutside() { 111 function onClickOutside() {
  112 + if (props.editRow) return;
88 const { component } = props; 113 const { component } = props;
89 114
90 if (component && component.includes('Input')) { 115 if (component && component.includes('Input')) {
91 handleCancel(); 116 handleCancel();
92 } 117 }
93 } 118 }
  119 +
  120 + function renderValue() {
  121 + const { value } = props;
  122 + if (props.editRow) {
  123 + return !unref(isEditRef) ? value : null;
  124 + }
  125 + return (
  126 + !unref(isEditRef) && (
  127 + <div class={`${prefixCls}__normal`} onClick={handleEdit}>
  128 + {value}
  129 + <FormOutlined class={`${prefixCls}__normal-icon`} />
  130 + </div>
  131 + )
  132 + );
  133 + }
94 return () => { 134 return () => {
95 - const { value, component, componentProps = {} } = props; 135 + const { component, componentProps = {} } = props;
96 136
97 const Comp = componentMap.get(component!) as any; 137 const Comp = componentMap.get(component!) as any;
98 - // const propsData: any = {};  
99 return ( 138 return (
100 <div class={prefixCls}> 139 <div class={prefixCls}>
101 {unref(isEditRef) && ( 140 {unref(isEditRef) && (
@@ -103,6 +142,7 @@ const EditableCell = defineComponent({ @@ -103,6 +142,7 @@ const EditableCell = defineComponent({
103 {() => ( 142 {() => (
104 <div class={`${prefixCls}__wrapper`}> 143 <div class={`${prefixCls}__wrapper`}>
105 <Comp 144 <Comp
  145 + placeholder={props.placeholder}
106 {...{ 146 {...{
107 ...attrs, 147 ...attrs,
108 ...componentProps, 148 ...componentProps,
@@ -114,21 +154,20 @@ const EditableCell = defineComponent({ @@ -114,21 +154,20 @@ const EditableCell = defineComponent({
114 onChange={handleChange} 154 onChange={handleChange}
115 onPressEnter={handleSubmit} 155 onPressEnter={handleSubmit}
116 /> 156 />
117 - <div class={`${prefixCls}__action`}>  
118 - <CheckOutlined class={[`${prefixCls}__icon`, 'mx-2']} onClick={handleSubmit} />  
119 - <CloseOutlined class={[`${prefixCls}__icon `]} onClick={handleCancel} />  
120 - </div> 157 + {!props.editRow && (
  158 + <div class={`${prefixCls}__action`}>
  159 + <CheckOutlined
  160 + class={[`${prefixCls}__icon`, 'mx-2']}
  161 + onClick={handleSubmit}
  162 + />
  163 + <CloseOutlined class={[`${prefixCls}__icon `]} onClick={handleCancel} />
  164 + </div>
  165 + )}
121 </div> 166 </div>
122 )} 167 )}
123 </ClickOutSide> 168 </ClickOutSide>
124 )} 169 )}
125 -  
126 - {!unref(isEditRef) && (  
127 - <div class={`${prefixCls}__normal`} onClick={handleEdit}>  
128 - {value}  
129 - <FormOutlined class={`${prefixCls}__normal-icon`} />  
130 - </div>  
131 - )} 170 + {renderValue()}
132 </div> 171 </div>
133 ); 172 );
134 }; 173 };
@@ -138,15 +177,16 @@ const EditableCell = defineComponent({ @@ -138,15 +177,16 @@ const EditableCell = defineComponent({
138 export function renderEditableCell({ 177 export function renderEditableCell({
139 dataIndex, 178 dataIndex,
140 component, 179 component,
141 - componentOn = {},  
142 componentProps = {}, 180 componentProps = {},
  181 + placeholder,
143 }: RenderEditableCellParams) { 182 }: RenderEditableCellParams) {
144 - return ({ text, record }: { text: string; record: any }) => { 183 + return ({ text, record }: { text: string; record: EditRecordRow }) => {
145 return ( 184 return (
146 <EditableCell 185 <EditableCell
147 - {...componentOn}  
148 {...componentProps} 186 {...componentProps}
  187 + placeholder={placeholder}
149 value={text} 188 value={text}
  189 + record={record}
150 dataKey={record.key} 190 dataKey={record.key}
151 dataIndex={dataIndex} 191 dataIndex={dataIndex}
152 component={component} 192 component={component}
@@ -154,3 +194,32 @@ export function renderEditableCell({ @@ -154,3 +194,32 @@ export function renderEditableCell({
154 ); 194 );
155 }; 195 };
156 } 196 }
  197 +
  198 +export function renderEditableRow({
  199 + dataIndex,
  200 + component,
  201 + componentProps = {},
  202 + placeholder,
  203 +}: RenderEditableCellParams) {
  204 + return ({ text, record }: { text: string; record: EditRecordRow }) => {
  205 + return (
  206 + <EditableCell
  207 + {...componentProps}
  208 + value={text}
  209 + placeholder={placeholder}
  210 + editRow={true}
  211 + editable={record.editable}
  212 + dataKey={record.key}
  213 + record={record}
  214 + dataIndex={dataIndex}
  215 + component={component}
  216 + />
  217 + );
  218 + };
  219 +}
  220 +
  221 +export type EditRecordRow<T = { [key: string]: any }> = {
  222 + editable: boolean;
  223 + onCancel: Fn;
  224 + onSubmit: Fn;
  225 +} & T;
src/components/Table/src/types/table.ts
@@ -68,8 +68,8 @@ export interface SorterResult { @@ -68,8 +68,8 @@ export interface SorterResult {
68 export interface RenderEditableCellParams { 68 export interface RenderEditableCellParams {
69 dataIndex: string; 69 dataIndex: string;
70 component?: ComponentType; 70 component?: ComponentType;
71 - componentOn?: { [key: string]: Fn };  
72 componentProps?: any; 71 componentProps?: any;
  72 + placeholder?: string;
73 } 73 }
74 74
75 export interface FetchParams { 75 export interface FetchParams {
@@ -88,15 +88,15 @@ export type SizeType = &#39;default&#39; | &#39;middle&#39; | &#39;small&#39; | &#39;large&#39;; @@ -88,15 +88,15 @@ export type SizeType = &#39;default&#39; | &#39;middle&#39; | &#39;small&#39; | &#39;large&#39;;
88 88
89 export interface TableActionType { 89 export interface TableActionType {
90 reload: (opt?: FetchParams) => Promise<void>; 90 reload: (opt?: FetchParams) => Promise<void>;
91 - getSelectRows: () => any[]; 91 + getSelectRows: <T = any>() => T[];
92 clearSelectedRowKeys: () => void; 92 clearSelectedRowKeys: () => void;
93 getSelectRowKeys: () => string[]; 93 getSelectRowKeys: () => string[];
94 deleteSelectRowByKey: (key: string) => void; 94 deleteSelectRowByKey: (key: string) => void;
95 setPagination: (info: Partial<PaginationProps>) => void; 95 setPagination: (info: Partial<PaginationProps>) => void;
96 - setTableData: (values: any[]) => void; 96 + setTableData: <T = any>(values: T[]) => void;
97 getColumns: (opt?: GetColumnsParams) => BasicColumn[]; 97 getColumns: (opt?: GetColumnsParams) => BasicColumn[];
98 setColumns: (columns: BasicColumn[] | string[]) => void; 98 setColumns: (columns: BasicColumn[] | string[]) => void;
99 - getDataSource: () => any[]; 99 + getDataSource: <T = any>() => T[];
100 setLoading: (loading: boolean) => void; 100 setLoading: (loading: boolean) => void;
101 setProps: (props: Partial<BasicTableProps>) => void; 101 setProps: (props: Partial<BasicTableProps>) => void;
102 redoHeight: () => void; 102 redoHeight: () => void;
src/components/Table/src/types/tableAction.ts
1 export interface ActionItem { 1 export interface ActionItem {
2 - on?: any;  
3 onClick?: any; 2 onClick?: any;
4 label: string; 3 label: string;
5 disabled?: boolean; 4 disabled?: boolean;
src/components/registerGlobComp.ts
1 import Icon from './Icon/index'; 1 import Icon from './Icon/index';
2 import Button from './Button/index.vue'; 2 import Button from './Button/index.vue';
  3 +import { AppFooter } from './Footer';
3 import { 4 import {
4 // Need 5 // Need
5 Button as AntButton, 6 Button as AntButton,
@@ -28,10 +29,12 @@ import { @@ -28,10 +29,12 @@ import {
28 Upload, 29 Upload,
29 Transfer, 30 Transfer,
30 Steps, 31 Steps,
  32 + PageHeader,
  33 + Result,
31 } from 'ant-design-vue'; 34 } from 'ant-design-vue';
32 import { getApp } from '/@/useApp'; 35 import { getApp } from '/@/useApp';
33 36
34 -const compList = [Icon, Button, AntButton.Group]; 37 +const compList = [Icon, Button, AntButton.Group, AppFooter];
35 38
36 // Fix hmr multiple registered components 39 // Fix hmr multiple registered components
37 let registered = false; 40 let registered = false;
@@ -70,5 +73,7 @@ export function registerGlobComp() { @@ -70,5 +73,7 @@ export function registerGlobComp() {
70 .use(Upload) 73 .use(Upload)
71 .use(Transfer) 74 .use(Transfer)
72 .use(Steps) 75 .use(Steps)
  76 + .use(PageHeader)
  77 + .use(Result)
73 .use(Tabs); 78 .use(Tabs);
74 } 79 }
src/design/ant/index.less
@@ -109,18 +109,21 @@ @@ -109,18 +109,21 @@
109 content: ''; 109 content: '';
110 } 110 }
111 111
  112 +.ant-form-item-with-help {
  113 + margin-bottom: 0;
  114 +}
  115 +
112 .ant-form-item { 116 .ant-form-item {
113 &-label label::after { 117 &-label label::after {
114 margin: 0 6px 0 2px; 118 margin: 0 6px 0 2px;
115 } 119 }
  120 +}
116 121
117 - &-control {  
118 - line-height: 36px;  
119 - } 122 +.ant-form-item:not(.ant-form-item-with-help) {
  123 + margin-bottom: 20px;
120 } 124 }
121 125
122 .ant-form-explain { 126 .ant-form-explain {
123 - margin-bottom: 2px;  
124 font-size: 14px; 127 font-size: 14px;
125 } 128 }
126 129
src/design/index.less
@@ -13,6 +13,14 @@ @@ -13,6 +13,14 @@
13 box-sizing: border-box; 13 box-sizing: border-box;
14 } 14 }
15 15
  16 +input:-webkit-autofill {
  17 + -webkit-box-shadow: 0 0 0 1000px white inset !important;
  18 +}
  19 +
  20 +:-webkit-autofill {
  21 + transition: background-color 5000s ease-in-out 0s !important;
  22 +}
  23 +
16 // Background color setting in full screen state in each browser 24 // Background color setting in full screen state in each browser
17 ::backdrop, 25 ::backdrop,
18 html, 26 html,
src/design/transition/base.less
1 .transition-default() { 1 .transition-default() {
2 &-enter-active, 2 &-enter-active,
3 &-leave-active { 3 &-leave-active {
4 - transition: 0.2s cubic-bezier(0.25, 0.8, 0.5, 1) !important; 4 + transition: 0.1s cubic-bezier(0.25, 0.8, 0.5, 1) !important;
5 } 5 }
6 6
7 &-move { 7 &-move {
8 - transition: transform 0.5s; 8 + transition: transform 0.2s;
9 } 9 }
10 } 10 }
11 11
src/design/transition/fade.less
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 /* fade-slide */ 11 /* fade-slide */
12 .fade-slide-leave-active, 12 .fade-slide-leave-active,
13 .fade-slide-enter-active { 13 .fade-slide-enter-active {
14 - transition: all 0.5s; 14 + transition: all 0.2s;
15 } 15 }
16 16
17 .fade-slide-enter-from { 17 .fade-slide-enter-from {
src/design/var/index.less
@@ -16,4 +16,4 @@ @@ -16,4 +16,4 @@
16 @page-loading-z-index: 10000; 16 @page-loading-z-index: 10000;
17 17
18 // left-menu 18 // left-menu
19 -@app-menu-item-height: 44px; 19 +@app-menu-item-height: 46px;
src/layouts/default/menu/LayoutMenu.tsx
@@ -154,12 +154,12 @@ export default defineComponent({ @@ -154,12 +154,12 @@ export default defineComponent({
154 function handleMenuClick(menu: Menu) { 154 function handleMenuClick(menu: Menu) {
155 const { path } = menu; 155 const { path } = menu;
156 if (path) { 156 if (path) {
  157 + push(path);
157 const { splitType } = props; 158 const { splitType } = props;
158 // split mode top 159 // split mode top
159 if (splitType === MenuSplitTyeEnum.TOP) { 160 if (splitType === MenuSplitTyeEnum.TOP) {
160 menuStore.commitCurrentTopSplitMenuPathState(path); 161 menuStore.commitCurrentTopSplitMenuPathState(path);
161 } 162 }
162 - push(path);  
163 } 163 }
164 } 164 }
165 165
src/router/menus/modules/demo/form.ts
@@ -14,7 +14,7 @@ const menu: MenuModule = { @@ -14,7 +14,7 @@ const menu: MenuModule = {
14 name: '基础表单', 14 name: '基础表单',
15 tag: { 15 tag: {
16 type: 'warn', 16 type: 'warn',
17 - content: 'updated', 17 + dot: true,
18 }, 18 },
19 }, 19 },
20 { 20 {
@@ -34,7 +34,7 @@ const menu: MenuModule = { @@ -34,7 +34,7 @@ const menu: MenuModule = {
34 name: '表单校验', 34 name: '表单校验',
35 tag: { 35 tag: {
36 type: 'warn', 36 type: 'warn',
37 - content: 'updated', 37 + dot: true,
38 }, 38 },
39 }, 39 },
40 { 40 {
@@ -42,7 +42,7 @@ const menu: MenuModule = { @@ -42,7 +42,7 @@ const menu: MenuModule = {
42 name: '动态表单', 42 name: '动态表单',
43 tag: { 43 tag: {
44 type: 'warn', 44 type: 'warn',
45 - content: 'updated', 45 + dot: true,
46 }, 46 },
47 }, 47 },
48 { 48 {
@@ -50,7 +50,7 @@ const menu: MenuModule = { @@ -50,7 +50,7 @@ const menu: MenuModule = {
50 name: '自定义组件', 50 name: '自定义组件',
51 tag: { 51 tag: {
52 type: 'warn', 52 type: 'warn',
53 - content: 'updated', 53 + dot: true,
54 }, 54 },
55 }, 55 },
56 ], 56 ],
src/router/menus/modules/demo/page.ts
@@ -16,6 +16,27 @@ const menu: MenuModule = { @@ -16,6 +16,27 @@ const menu: MenuModule = {
16 }, 16 },
17 children: [ 17 children: [
18 { 18 {
  19 + path: 'form',
  20 + name: '表单页',
  21 + tag: {
  22 + content: 'new',
  23 + },
  24 + children: [
  25 + {
  26 + path: 'basic',
  27 + name: '基础表单',
  28 + },
  29 + {
  30 + path: 'step',
  31 + name: '分步表单',
  32 + },
  33 + {
  34 + path: 'high',
  35 + name: '高级表单',
  36 + },
  37 + ],
  38 + },
  39 + {
19 path: 'result', 40 path: 'result',
20 name: '结果页', 41 name: '结果页',
21 tag: { 42 tag: {
src/router/menus/modules/demo/table.ts
@@ -4,6 +4,9 @@ const menu: MenuModule = { @@ -4,6 +4,9 @@ const menu: MenuModule = {
4 menu: { 4 menu: {
5 path: '/table', 5 path: '/table',
6 name: 'Table', 6 name: 'Table',
  7 + tag: {
  8 + dot: true,
  9 + },
7 children: [ 10 children: [
8 { 11 {
9 path: 'basic', 12 path: 'basic',
@@ -61,6 +64,13 @@ const menu: MenuModule = { @@ -61,6 +64,13 @@ const menu: MenuModule = {
61 path: 'editCellTable', 64 path: 'editCellTable',
62 name: '可编辑单元格', 65 name: '可编辑单元格',
63 }, 66 },
  67 + {
  68 + path: 'editRowTable',
  69 + name: '可编辑行',
  70 + tag: {
  71 + content: 'new',
  72 + },
  73 + },
64 ], 74 ],
65 }, 75 },
66 }; 76 };
src/router/routes/modules/demo/page.ts
@@ -15,6 +15,43 @@ const page: AppRouteModule = { @@ -15,6 +15,43 @@ const page: AppRouteModule = {
15 title: '页面', 15 title: '页面',
16 }, 16 },
17 children: [ 17 children: [
  18 + // =============================form start=============================
  19 + {
  20 + path: '/form',
  21 + name: 'FormPage',
  22 + redirect: '/page-demo/form/basic',
  23 + meta: {
  24 + title: '表单页',
  25 + },
  26 + children: [
  27 + {
  28 + path: 'basic',
  29 + name: 'FormBasicPage',
  30 + component: () => import('/@/views/demo/page/form/basic/index.vue'),
  31 + meta: {
  32 + title: '基础表单',
  33 + },
  34 + },
  35 + {
  36 + path: 'step',
  37 + name: 'FormStepPage',
  38 + component: () => import('/@/views/demo/page/form/step/index.vue'),
  39 + meta: {
  40 + title: '分步表单',
  41 + },
  42 + },
  43 + {
  44 + path: 'high',
  45 + name: 'FormHightPage',
  46 + component: () => import('/@/views/demo/page/form/high/index.vue'),
  47 + meta: {
  48 + title: '高级表单',
  49 + },
  50 + },
  51 + ],
  52 + },
  53 + // =============================form end=============================
  54 +
18 // =============================result start============================= 55 // =============================result start=============================
19 { 56 {
20 path: '/result', 57 path: '/result',
src/router/routes/modules/demo/table.ts
@@ -127,6 +127,14 @@ const table: AppRouteModule = { @@ -127,6 +127,14 @@ const table: AppRouteModule = {
127 title: '可编辑单元格', 127 title: '可编辑单元格',
128 }, 128 },
129 }, 129 },
  130 + {
  131 + path: '/editRowTable',
  132 + name: 'EditRowTableDemo',
  133 + component: () => import('/@/views/demo/table/EditRowTable.vue'),
  134 + meta: {
  135 + title: '可编辑行',
  136 + },
  137 + },
130 ], 138 ],
131 }; 139 };
132 140
src/views/demo/page/account/center/Project.vue
@@ -51,7 +51,6 @@ @@ -51,7 +51,6 @@
51 51
52 img { 52 img {
53 width: 100%; 53 width: 100%;
54 - height: 100px;  
55 } 54 }
56 55
57 &-title { 56 &-title {
src/views/demo/page/form/basic/data.ts 0 → 100644
  1 +import { FormSchema } from '/@/components/Form';
  2 +
  3 +export const schemas: FormSchema[] = [
  4 + {
  5 + field: 'title',
  6 + component: 'Input',
  7 + label: '标题',
  8 + componentProps: {
  9 + placeholder: '给目标起个名字',
  10 + },
  11 + required: true,
  12 + },
  13 + {
  14 + field: 'time',
  15 + component: 'RangePicker',
  16 + label: '起止日期',
  17 + required: true,
  18 + },
  19 + {
  20 + field: 'target',
  21 + component: 'InputTextArea',
  22 + label: '目标描述',
  23 + componentProps: {
  24 + placeholder: '请输入你的阶段性工作目标',
  25 + rows: 4,
  26 + },
  27 + required: true,
  28 + },
  29 + {
  30 + field: 'metrics',
  31 + component: 'InputTextArea',
  32 + label: '衡量标准',
  33 + componentProps: {
  34 + placeholder: '请输入衡量标准',
  35 + rows: 4,
  36 + },
  37 + required: true,
  38 + },
  39 + {
  40 + field: 'client',
  41 + component: 'Input',
  42 + label: '客户',
  43 + helpMessage: '目标的服务对象',
  44 + subLabel: '( 选填 )',
  45 + componentProps: {
  46 + placeholder: '请描述你服务的客户,内部客户直接 @姓名/工号',
  47 + },
  48 + },
  49 + {
  50 + field: 'inviteer',
  51 + component: 'Input',
  52 + label: '邀评人',
  53 + subLabel: '( 选填 )',
  54 + componentProps: {
  55 + placeholder: '请直接 @姓名/工号,最多可邀请 5 人',
  56 + },
  57 + },
  58 + {
  59 + field: 'weights',
  60 + component: 'InputNumber',
  61 + label: '权重',
  62 + subLabel: '( 选填 )',
  63 + componentProps: {
  64 + formatter: (value: string) => (value ? `${value}%` : ''),
  65 + parser: (value: string) => value.replace('%', ''),
  66 + placeholder: '请输入',
  67 + },
  68 + },
  69 + {
  70 + field: 'disclosure',
  71 + component: 'RadioGroup',
  72 + label: '目标公开',
  73 + itemProps: {
  74 + extra: '客户、邀评人默认被分享',
  75 + },
  76 + componentProps: {
  77 + options: [
  78 + {
  79 + label: '公开',
  80 + value: '1',
  81 + },
  82 + {
  83 + label: '部分公开',
  84 + value: '2',
  85 + },
  86 + {
  87 + label: '不公开',
  88 + value: '3',
  89 + },
  90 + ],
  91 + },
  92 + },
  93 + {
  94 + field: 'disclosurer',
  95 + component: 'Select',
  96 + label: ' ',
  97 + show: ({ model }) => {
  98 + return model.disclosure === '2';
  99 + },
  100 + componentProps: {
  101 + placeholder: '公开给',
  102 + mode: 'multiple',
  103 + options: [
  104 + {
  105 + label: '同事1',
  106 + value: '1',
  107 + },
  108 + {
  109 + label: '同事2',
  110 + value: '2',
  111 + },
  112 + {
  113 + label: '同事3',
  114 + value: '3',
  115 + },
  116 + ],
  117 + },
  118 + },
  119 +];
src/views/demo/page/form/basic/index.vue 0 → 100644
  1 +<template>
  2 + <div>
  3 + <a-page-header title="基础表单" :ghost="false">
  4 + 表单页用于向用户收集或验证信息,基础表单常见于数据项较少的表单场景。
  5 + </a-page-header>
  6 +
  7 + <div class="m-5 form-wrap">
  8 + <BasicForm @register="register" />
  9 + </div>
  10 + </div>
  11 +</template>
  12 +<script lang="ts">
  13 + import { BasicForm, useForm } from '/@/components/Form';
  14 + import { defineComponent } from 'vue';
  15 + import { schemas } from './data';
  16 + import { useMessage } from '/@/hooks/web/useMessage';
  17 + export default defineComponent({
  18 + components: { BasicForm },
  19 + setup() {
  20 + const { createMessage } = useMessage();
  21 + const [register, { validate, setProps }] = useForm({
  22 + labelCol: {
  23 + span: 7,
  24 + },
  25 + wrapperCol: {
  26 + span: 10,
  27 + },
  28 + schemas: schemas,
  29 + actionColOptions: {
  30 + offset: 8,
  31 + },
  32 + submitButtonOptions: {
  33 + text: '提交',
  34 + },
  35 + submitFunc: customSubmitFunc,
  36 + });
  37 +
  38 + async function customSubmitFunc() {
  39 + try {
  40 + await validate();
  41 + setProps({
  42 + submitButtonOptions: {
  43 + loading: true,
  44 + },
  45 + });
  46 + setTimeout(() => {
  47 + setProps({
  48 + submitButtonOptions: {
  49 + loading: false,
  50 + },
  51 + });
  52 + createMessage.success('提交成功!');
  53 + }, 2000);
  54 + } catch (error) {}
  55 + }
  56 +
  57 + return { register };
  58 + },
  59 + });
  60 +</script>
  61 +<style lang="less" scoped>
  62 + .form-wrap {
  63 + padding: 24px;
  64 + background: #fff;
  65 + }
  66 +</style>
src/views/demo/page/form/high/PersonTable.vue 0 → 100644
  1 +<template>
  2 + <div>
  3 + <BasicTable @register="registerTable">
  4 + <template #action="{ record, column }">
  5 + <TableAction :actions="createActions(record, column)" />
  6 + </template>
  7 + </BasicTable>
  8 + <a-button block class="mt-5" type="dashed" @click="handleAdd">新增成员</a-button>
  9 + </div>
  10 +</template>
  11 +<script lang="ts">
  12 + import { defineComponent } from 'vue';
  13 + import {
  14 + BasicTable,
  15 + useTable,
  16 + TableAction,
  17 + BasicColumn,
  18 + ActionItem,
  19 + renderEditableRow,
  20 + EditTableHeaderIcon,
  21 + EditRecordRow,
  22 + } from '/@/components/Table';
  23 +
  24 + const columns: BasicColumn[] = [
  25 + {
  26 + title: '成员姓名',
  27 + dataIndex: 'name',
  28 + customRender: renderEditableRow({ dataIndex: 'name', placeholder: '请输入成员姓名' }),
  29 + },
  30 + {
  31 + title: '工号',
  32 + dataIndex: 'no',
  33 + customRender: renderEditableRow({ dataIndex: 'no', placeholder: '请输入工号' }),
  34 + },
  35 + {
  36 + title: '所属部门',
  37 + dataIndex: 'dept',
  38 + customRender: renderEditableRow({ dataIndex: 'dept', placeholder: '请输入所属部门' }),
  39 + },
  40 + ];
  41 +
  42 + const data: any[] = [
  43 + {
  44 + name: 'John Brown',
  45 + no: '00001',
  46 + dept: 'New York No. 1 Lake Park',
  47 + },
  48 + {
  49 + name: 'John Brown2',
  50 + no: '00002',
  51 + dept: 'New York No. 2 Lake Park',
  52 + },
  53 + {
  54 + name: 'John Brown3',
  55 + no: '00003',
  56 + dept: 'New York No. 3Lake Park',
  57 + },
  58 + ];
  59 + export default defineComponent({
  60 + components: { BasicTable, EditTableHeaderIcon, TableAction },
  61 + setup() {
  62 + const [registerTable, { getDataSource }] = useTable({
  63 + columns: columns,
  64 + showIndexColumn: false,
  65 + dataSource: data,
  66 + actionColumn: {
  67 + width: 160,
  68 + title: '操作',
  69 + dataIndex: 'action',
  70 + slots: { customRender: 'action' },
  71 + },
  72 + pagination: false,
  73 + });
  74 +
  75 + function handleEdit(record: EditRecordRow) {
  76 + record.editable = true;
  77 + }
  78 +
  79 + function handleCancel(record: EditRecordRow) {
  80 + record.editable = false;
  81 + record.onCancel && record.onCancel();
  82 + if (record.isNew) {
  83 + const data = getDataSource();
  84 + const index = data.findIndex((item) => item.key === record.key);
  85 + data.splice(index, 1);
  86 + }
  87 + }
  88 +
  89 + function handleSave(record: EditRecordRow) {
  90 + record.editable = false;
  91 + record.onSubmit && record.onSubmit();
  92 + }
  93 +
  94 + function handleAdd() {
  95 + const data = getDataSource();
  96 + const addRow: EditRecordRow = {
  97 + name: '',
  98 + no: '',
  99 + dept: '',
  100 + editable: true,
  101 + isNew: true,
  102 + };
  103 + data.push(addRow);
  104 + }
  105 +
  106 + function createActions(record: EditRecordRow, column: BasicColumn): ActionItem[] {
  107 + if (!record.editable) {
  108 + return [
  109 + {
  110 + label: '编辑',
  111 + onClick: handleEdit.bind(null, record),
  112 + },
  113 + {
  114 + label: '删除',
  115 + },
  116 + ];
  117 + }
  118 + return [
  119 + {
  120 + label: '保存',
  121 + onClick: handleSave.bind(null, record, column),
  122 + },
  123 + {
  124 + label: '取消',
  125 + popConfirm: {
  126 + title: '是否取消编辑',
  127 + confirm: handleCancel.bind(null, record, column),
  128 + },
  129 + },
  130 + ];
  131 + }
  132 +
  133 + return {
  134 + registerTable,
  135 + handleEdit,
  136 + createActions,
  137 + handleAdd,
  138 + getDataSource,
  139 + };
  140 + },
  141 + });
  142 +</script>
src/views/demo/page/form/high/data.ts 0 → 100644
  1 +import { FormSchema } from '/@/components/Form';
  2 +
  3 +const basicOptions: SelectOptions = [
  4 + {
  5 + label: '付晓晓',
  6 + value: '1',
  7 + },
  8 + {
  9 + label: '周毛毛',
  10 + value: '2',
  11 + },
  12 +];
  13 +
  14 +const storeTypeOptions: SelectOptions = [
  15 + {
  16 + label: '私密',
  17 + value: '1',
  18 + },
  19 + {
  20 + label: '公开',
  21 + value: '2',
  22 + },
  23 +];
  24 +
  25 +export const schemas: FormSchema[] = [
  26 + {
  27 + field: 'f1',
  28 + component: 'Input',
  29 + label: '仓库名',
  30 + required: true,
  31 + },
  32 + {
  33 + field: 'f2',
  34 + component: 'Input',
  35 + label: '仓库域名',
  36 + required: true,
  37 + componentProps: {
  38 + addonBefore: 'http://',
  39 + addonAfter: 'com',
  40 + },
  41 + colProps: {
  42 + offset: 2,
  43 + },
  44 + },
  45 + {
  46 + field: 'f3',
  47 + component: 'Select',
  48 + label: '仓库管理员',
  49 + componentProps: {
  50 + options: basicOptions,
  51 + },
  52 + required: true,
  53 + colProps: {
  54 + offset: 2,
  55 + },
  56 + },
  57 + {
  58 + field: 'f4',
  59 + component: 'Select',
  60 + label: '审批人',
  61 + componentProps: {
  62 + options: basicOptions,
  63 + },
  64 + required: true,
  65 + },
  66 + {
  67 + field: 'f5',
  68 + component: 'RangePicker',
  69 + label: '生效日期',
  70 + required: true,
  71 + colProps: {
  72 + offset: 2,
  73 + },
  74 + },
  75 + {
  76 + field: 'f6',
  77 + component: 'Select',
  78 + label: '仓库类型',
  79 + componentProps: {
  80 + options: storeTypeOptions,
  81 + },
  82 + required: true,
  83 + colProps: {
  84 + offset: 2,
  85 + },
  86 + },
  87 +];
  88 +export const taskSchemas: FormSchema[] = [
  89 + {
  90 + field: 't1',
  91 + component: 'Input',
  92 + label: '任务名',
  93 + required: true,
  94 + },
  95 + {
  96 + field: 't2',
  97 + component: 'Input',
  98 + label: '任务描述',
  99 + required: true,
  100 + colProps: {
  101 + offset: 2,
  102 + },
  103 + },
  104 + {
  105 + field: 't3',
  106 + component: 'Select',
  107 + label: '执行人',
  108 + componentProps: {
  109 + options: basicOptions,
  110 + },
  111 + required: true,
  112 + colProps: {
  113 + offset: 2,
  114 + },
  115 + },
  116 + {
  117 + field: 't4',
  118 + component: 'Select',
  119 + label: '责任人',
  120 + componentProps: {
  121 + options: basicOptions,
  122 + },
  123 + required: true,
  124 + },
  125 + {
  126 + field: 't5',
  127 + component: 'TimePicker',
  128 + label: '生效日期',
  129 + required: true,
  130 + componentProps: {
  131 + style: { width: '100%' },
  132 + },
  133 + colProps: {
  134 + offset: 2,
  135 + },
  136 + },
  137 + {
  138 + field: 't6',
  139 + component: 'Select',
  140 + label: '任务类型',
  141 + componentProps: {
  142 + options: storeTypeOptions,
  143 + },
  144 + required: true,
  145 + colProps: {
  146 + offset: 2,
  147 + },
  148 + },
  149 +];
src/views/demo/page/form/high/index.vue 0 → 100644
  1 +<template>
  2 + <div class="high-form">
  3 + <a-page-header title="高级表单" :ghost="false">
  4 + 高级表单常见于一次性输入和提交大批量数据的场景。
  5 + </a-page-header>
  6 +
  7 + <div class="m-5">
  8 + <a-card title="仓库管理" :bordered="false">
  9 + <BasicForm @register="register" layout="vertical" />
  10 + </a-card>
  11 + <a-card title="任务管理" :bordered="false" class="mt-5">
  12 + <BasicForm @register="registerTask" layout="vertical" />
  13 + </a-card>
  14 + <a-card title="成员管理" :bordered="false" class="mt-5">
  15 + <PersonTable ref="tableRef" />
  16 + </a-card>
  17 + </div>
  18 +
  19 + <app-footer>
  20 + <template #right>
  21 + <a-button type="primary" @click="submitAll">提交</a-button>
  22 + </template>
  23 + </app-footer>
  24 + </div>
  25 +</template>
  26 +<script lang="ts">
  27 + import { BasicForm, useForm } from '/@/components/Form';
  28 + import { defineComponent, ref } from 'vue';
  29 + import PersonTable from './PersonTable.vue';
  30 + import { schemas, taskSchemas } from './data';
  31 +
  32 + export default defineComponent({
  33 + components: { BasicForm, PersonTable },
  34 + setup() {
  35 + const tableRef = ref<{ getDataSource: () => any } | null>(null);
  36 +
  37 + const [register, { validate }] = useForm({
  38 + baseColProps: {
  39 + span: 6,
  40 + },
  41 + schemas: schemas,
  42 + showActionButtonGroup: false,
  43 + });
  44 +
  45 + const [registerTask, { validate: validateTaskForm }] = useForm({
  46 + baseColProps: {
  47 + span: 6,
  48 + },
  49 + schemas: taskSchemas,
  50 + showActionButtonGroup: false,
  51 + });
  52 +
  53 + async function submitAll() {
  54 + try {
  55 + if (tableRef.value) {
  56 + console.log('table data:', tableRef.value.getDataSource());
  57 + }
  58 +
  59 + const [values, taskValues] = await Promise.all([validate(), validateTaskForm()]);
  60 + console.log('form data:', values, taskValues);
  61 + } catch (error) {}
  62 + }
  63 +
  64 + return { register, registerTask, submitAll, tableRef };
  65 + },
  66 + });
  67 +</script>
  68 +<style lang="less" scoped>
  69 + .high-form {
  70 + padding-bottom: 48px;
  71 + }
  72 +</style>
src/views/demo/page/form/step/Step1.vue 0 → 100644
  1 +<template>
  2 + <div class="step1">
  3 + <div class="step1-form">
  4 + <BasicForm @register="register">
  5 + <template #fac="{ model, field }">
  6 + <a-input-group compact>
  7 + <a-select v-model:value="model['pay']" class="pay-select">
  8 + <a-select-option value="zfb"> 支付宝 </a-select-option>
  9 + <a-select-option value="yl"> 银联 </a-select-option>
  10 + </a-select>
  11 + <a-input class="pay-input" v-model:value="model[field]" />
  12 + </a-input-group>
  13 + </template>
  14 + </BasicForm>
  15 + </div>
  16 + <a-divider />
  17 + <h3>说明</h3>
  18 + <h4>转账到支付宝账户</h4>
  19 + <p>
  20 + 如果需要,这里可以放一些关于产品的常见问题说明。如果需要,这里可以放一些关于产品的常见问题说明。如果需要,这里可以放一些关于产品的常见问题说明。
  21 + </p>
  22 +
  23 + <h4>转账到银行卡</h4>
  24 + <p>
  25 + 如果需要,这里可以放一些关于产品的常见问题说明。如果需要,这里可以放一些关于产品的常见问题说明。如果需要,这里可以放一些关于产品的常见问题说明。
  26 + </p>
  27 + </div>
  28 +</template>
  29 +<script lang="ts">
  30 + import { defineComponent } from 'vue';
  31 + import { BasicForm, useForm } from '/@/components/Form';
  32 + import { step1Schemas } from './data';
  33 +
  34 + export default defineComponent({
  35 + components: { BasicForm },
  36 + emits: ['next'],
  37 + setup(_, { emit }) {
  38 + const [register, { validate }] = useForm({
  39 + labelWidth: 100,
  40 + schemas: step1Schemas,
  41 + actionColOptions: {
  42 + span: 14,
  43 + },
  44 + showResetButton: false,
  45 + submitButtonOptions: {
  46 + text: '下一步',
  47 + },
  48 + submitFunc: customSubmitFunc,
  49 + });
  50 +
  51 + async function customSubmitFunc() {
  52 + try {
  53 + const values = await validate();
  54 + emit('next', values);
  55 + } catch (error) {}
  56 + }
  57 +
  58 + return { register };
  59 + },
  60 + });
  61 +</script>
  62 +<style lang="less" scoped>
  63 + .step1 {
  64 + &-form {
  65 + width: 450px;
  66 + margin: 0 auto;
  67 + }
  68 +
  69 + h3 {
  70 + margin: 0 0 12px;
  71 + font-size: 16px;
  72 + line-height: 32px;
  73 + color: rgba(0, 0, 0, 0.45);
  74 + }
  75 +
  76 + h4 {
  77 + margin: 0 0 4px;
  78 + font-size: 14px;
  79 + line-height: 22px;
  80 + color: rgba(0, 0, 0, 0.45);
  81 + }
  82 +
  83 + p {
  84 + color: rgba(0, 0, 0, 0.45);
  85 + }
  86 + }
  87 +
  88 + .pay-select {
  89 + width: 20%;
  90 + }
  91 +
  92 + .pay-input {
  93 + width: 70%;
  94 + }
  95 +</style>
src/views/demo/page/form/step/Step2.vue 0 → 100644
  1 +<template>
  2 + <div class="step2">
  3 + <a-alert message="确认转账后,资金将直接打入对方账户,无法退回。" show-icon />
  4 + <a-descriptions :column="1" class="mt-5">
  5 + <a-descriptions-item label="付款账户"> ant-design@alipay.com </a-descriptions-item>
  6 + <a-descriptions-item label="收款账户"> test@example.com </a-descriptions-item>
  7 + <a-descriptions-item label="收款人姓名"> Vben </a-descriptions-item>
  8 + <a-descriptions-item label="转账金额"> 500元 </a-descriptions-item>
  9 + </a-descriptions>
  10 + <a-divider />
  11 + <BasicForm @register="register" />
  12 + </div>
  13 +</template>
  14 +<script lang="ts">
  15 + import { defineComponent } from 'vue';
  16 + import { BasicForm, useForm } from '/@/components/Form';
  17 + import { step2Schemas } from './data';
  18 +
  19 + export default defineComponent({
  20 + components: { BasicForm },
  21 + emits: ['next', 'prev'],
  22 + setup(_, { emit }) {
  23 + const [register, { validate, setProps }] = useForm({
  24 + labelWidth: 80,
  25 + schemas: step2Schemas,
  26 + actionColOptions: {
  27 + span: 14,
  28 + },
  29 + resetButtonOptions: {
  30 + text: '上一步',
  31 + },
  32 + submitButtonOptions: {
  33 + text: '提交',
  34 + },
  35 + resetFunc: customResetFunc,
  36 + submitFunc: customSubmitFunc,
  37 + });
  38 +
  39 + async function customResetFunc() {
  40 + emit('prev');
  41 + }
  42 +
  43 + async function customSubmitFunc() {
  44 + try {
  45 + const values = await validate();
  46 + setProps({
  47 + submitButtonOptions: {
  48 + loading: true,
  49 + },
  50 + });
  51 + setTimeout(() => {
  52 + setProps({
  53 + submitButtonOptions: {
  54 + loading: false,
  55 + },
  56 + });
  57 + emit('next', values);
  58 + }, 1500);
  59 + } catch (error) {}
  60 + }
  61 +
  62 + return { register };
  63 + },
  64 + });
  65 +</script>
  66 +<style lang="less" scoped>
  67 + .step2 {
  68 + width: 450px;
  69 + margin: 0 auto;
  70 + }
  71 +</style>
src/views/demo/page/form/step/Step3.vue 0 → 100644
  1 +<template>
  2 + <div class="step3">
  3 + <a-result status="success" title="操作成功" sub-title="预计两小时内到账">
  4 + <template #extra>
  5 + <a-button type="primary" @click="redo">再转一笔 </a-button>
  6 + <a-button> 查看账单 </a-button>
  7 + </template>
  8 + </a-result>
  9 + <div class="desc-wrap">
  10 + <a-descriptions :column="1" class="mt-5">
  11 + <a-descriptions-item label="付款账户"> ant-design@alipay.com </a-descriptions-item>
  12 + <a-descriptions-item label="收款账户"> test@example.com </a-descriptions-item>
  13 + <a-descriptions-item label="收款人姓名"> Vben </a-descriptions-item>
  14 + <a-descriptions-item label="转账金额"> 500元 </a-descriptions-item>
  15 + </a-descriptions>
  16 + </div>
  17 + </div>
  18 +</template>
  19 +<script lang="ts">
  20 + import { defineComponent } from 'vue';
  21 +
  22 + export default defineComponent({
  23 + components: {},
  24 + emits: ['redo'],
  25 + setup(_, { emit }) {
  26 + return {
  27 + redo: () => {
  28 + emit('redo');
  29 + },
  30 + };
  31 + },
  32 + });
  33 +</script>
  34 +<style lang="less" scoped>
  35 + .step3 {
  36 + width: 600px;
  37 + margin: 0 auto;
  38 + }
  39 +
  40 + .desc-wrap {
  41 + padding: 24px 40px;
  42 + margin-top: 24px;
  43 + background: #fafafa;
  44 + }
  45 +</style>
src/views/demo/page/form/step/data.tsx 0 → 100644
  1 +import { FormSchema } from '/@/components/Form';
  2 +
  3 +export const step1Schemas: FormSchema[] = [
  4 + {
  5 + field: 'account',
  6 + component: 'Select',
  7 + label: '付款账户',
  8 + required: true,
  9 + defaultValue: '1',
  10 + componentProps: {
  11 + options: [
  12 + {
  13 + label: 'anncwb@126.com',
  14 + value: '1',
  15 + },
  16 + ],
  17 + },
  18 + },
  19 + {
  20 + field: 'fac',
  21 + component: 'InputGroup',
  22 + label: '收款账户',
  23 + required: true,
  24 + defaultValue: 'test@example.com',
  25 + slot: 'fac',
  26 + },
  27 + {
  28 + field: 'pay',
  29 + component: 'Input',
  30 + label: '',
  31 + defaultValue: 'zfb',
  32 + show: false,
  33 + },
  34 + {
  35 + field: 'payeeName',
  36 + component: 'Input',
  37 + label: '收款人姓名',
  38 + defaultValue: 'Vben',
  39 + required: true,
  40 + },
  41 + {
  42 + field: 'money',
  43 + component: 'Input',
  44 + label: '转账金额',
  45 + defaultValue: '500',
  46 + required: true,
  47 + renderComponentContent: () => {
  48 + return {
  49 + prefix: () => '¥',
  50 + };
  51 + },
  52 + },
  53 +];
  54 +
  55 +export const step2Schemas: FormSchema[] = [
  56 + {
  57 + field: 'pwd',
  58 + component: 'InputPassword',
  59 + label: '支付密码',
  60 + required: true,
  61 + defaultValue: '123456',
  62 + },
  63 +];
src/views/demo/page/form/step/index.vue 0 → 100644
  1 +<template>
  2 + <div>
  3 + <a-page-header title="分步表单" :ghost="false">
  4 + 将一个冗长或用户不熟悉的表单任务分成多个步骤,指导用户完成。
  5 + </a-page-header>
  6 +
  7 + <div class="m-5 step-form-content">
  8 + <div class="step-form-form">
  9 + <a-steps :current="current">
  10 + <a-step title="填写转账信息"> </a-step>
  11 + <a-step title="确认转账信息"> </a-step>
  12 + <a-step title="完成"> </a-step>
  13 + </a-steps>
  14 + </div>
  15 + <div class="mt-5">
  16 + <Step1 @next="handleStep1Next" v-show="current === 0" />
  17 + <Step2
  18 + @prev="handleStepPrev"
  19 + @next="handleStep2Next"
  20 + v-show="current === 1"
  21 + v-if="initSetp2"
  22 + />
  23 + <Step3 v-show="current === 2" @redo="handleRedo" v-if="initSetp3" />
  24 + </div>
  25 + </div>
  26 + </div>
  27 +</template>
  28 +<script lang="ts">
  29 + import { defineComponent, ref, reactive, toRefs } from 'vue';
  30 + import Step1 from './Step1.vue';
  31 + import Step2 from './Step2.vue';
  32 + import Step3 from './Step3.vue';
  33 + export default defineComponent({
  34 + components: { Step1, Step2, Step3 },
  35 + setup() {
  36 + const current = ref(0);
  37 +
  38 + const state = reactive({
  39 + initSetp2: false,
  40 + initSetp3: false,
  41 + });
  42 +
  43 + function handleStep1Next(step1Values: any) {
  44 + current.value++;
  45 + state.initSetp2 = true;
  46 + console.log(step1Values);
  47 + }
  48 +
  49 + function handleStepPrev() {
  50 + current.value--;
  51 + }
  52 +
  53 + function handleStep2Next(step2Values: any) {
  54 + current.value++;
  55 + state.initSetp3 = true;
  56 + console.log(step2Values);
  57 + }
  58 +
  59 + function handleRedo() {
  60 + current.value = 0;
  61 + state.initSetp2 = false;
  62 + state.initSetp3 = false;
  63 + }
  64 +
  65 + return {
  66 + current,
  67 + handleStep1Next,
  68 + handleStep2Next,
  69 + handleRedo,
  70 + handleStepPrev,
  71 + ...toRefs(state),
  72 + };
  73 + },
  74 + });
  75 +</script>
  76 +<style lang="less" scoped>
  77 + .step-form-content {
  78 + padding: 24px;
  79 + background: #fff;
  80 + }
  81 +
  82 + .step-form-form {
  83 + width: 750px;
  84 + margin: 0 auto;
  85 + }
  86 +</style>
src/views/demo/table/EditRowTable.vue 0 → 100644
  1 +<template>
  2 + <div class="p-4">
  3 + <BasicTable @register="registerTable">
  4 + <template #action="{ record, column }">
  5 + <TableAction :actions="createActions(record, column)" />
  6 + </template>
  7 + </BasicTable>
  8 + </div>
  9 +</template>
  10 +<script lang="ts">
  11 + import { defineComponent, ref } from 'vue';
  12 + import {
  13 + BasicTable,
  14 + useTable,
  15 + TableAction,
  16 + BasicColumn,
  17 + ActionItem,
  18 + renderEditableRow,
  19 + EditTableHeaderIcon,
  20 + EditRecordRow,
  21 + } from '/@/components/Table';
  22 +
  23 + import { demoListApi } from '/@/api/demo/table';
  24 + const columns: BasicColumn[] = [
  25 + {
  26 + title: 'ID',
  27 + dataIndex: 'id',
  28 + customRender: renderEditableRow({ dataIndex: 'id' }),
  29 + },
  30 + {
  31 + title: '姓名',
  32 + dataIndex: 'name',
  33 + customRender: renderEditableRow({
  34 + dataIndex: 'name',
  35 + }),
  36 + },
  37 + ];
  38 + export default defineComponent({
  39 + components: { BasicTable, EditTableHeaderIcon, TableAction },
  40 + setup() {
  41 + const currentEditKeyRef = ref('');
  42 +
  43 + const [registerTable] = useTable({
  44 + title: '可编辑行示例',
  45 + api: demoListApi,
  46 + columns: columns,
  47 + showIndexColumn: false,
  48 + actionColumn: {
  49 + width: 160,
  50 + title: 'Action',
  51 + dataIndex: 'action',
  52 + slots: { customRender: 'action' },
  53 + },
  54 + });
  55 +
  56 + function handleEdit(record: EditRecordRow) {
  57 + currentEditKeyRef.value = record.key;
  58 + record.editable = true;
  59 + }
  60 +
  61 + function handleCancel(record: EditRecordRow) {
  62 + currentEditKeyRef.value = '';
  63 + record.editable = false;
  64 + record.onCancel && record.onCancel();
  65 + }
  66 +
  67 + function handleSave(record: EditRecordRow) {
  68 + currentEditKeyRef.value = '';
  69 + record.editable = false;
  70 + record.onSubmit && record.onSubmit();
  71 + }
  72 +
  73 + function createActions(record: EditRecordRow, column: BasicColumn): ActionItem[] {
  74 + if (!record.editable) {
  75 + return [
  76 + {
  77 + label: '编辑',
  78 + disabled: currentEditKeyRef.value ? currentEditKeyRef.value !== record.key : false,
  79 + onClick: handleEdit.bind(null, record),
  80 + },
  81 + ];
  82 + }
  83 + return [
  84 + {
  85 + label: '保存',
  86 + onClick: handleSave.bind(null, record, column),
  87 + },
  88 + {
  89 + label: '取消',
  90 + popConfirm: {
  91 + title: '是否取消编辑',
  92 + confirm: handleCancel.bind(null, record, column),
  93 + },
  94 + },
  95 + ];
  96 + }
  97 +
  98 + return {
  99 + registerTable,
  100 + handleEdit,
  101 + createActions,
  102 + };
  103 + },
  104 + });
  105 +</script>
src/views/demo/table/FixedColumn.vue
1 <template> 1 <template>
2 <div class="p-4"> 2 <div class="p-4">
3 <BasicTable @register="registerTable"> 3 <BasicTable @register="registerTable">
4 - <template #action> 4 + <template #action="{ record }">
5 <TableAction 5 <TableAction
6 :actions="[ 6 :actions="[
7 { 7 {
8 label: '删除', 8 label: '删除',
9 - onClick: handleDelete, 9 + onClick: handleDelete.bind(null, record),
10 }, 10 },
11 ]" 11 ]"
12 :dropDownActions="[ 12 :dropDownActions="[
13 { 13 {
14 label: '启用', 14 label: '启用',
15 - onClick: handleOpen, 15 + onClick: handleOpen.bind(null, record),
16 }, 16 },
17 ]" 17 ]"
18 /> 18 />
@@ -73,11 +73,11 @@ @@ -73,11 +73,11 @@
73 slots: { customRender: 'action' }, 73 slots: { customRender: 'action' },
74 }, 74 },
75 }); 75 });
76 - function handleDelete() {  
77 - console.log('点击了删除'); 76 + function handleDelete(record: any) {
  77 + console.log('点击了删除', record);
78 } 78 }
79 - function handleOpen() {  
80 - console.log('点击了启用'); 79 + function handleOpen(record: any) {
  80 + console.log('点击了启用', record);
81 } 81 }
82 return { 82 return {
83 registerTable, 83 registerTable,
yarn.lock
@@ -1051,9 +1051,9 @@ @@ -1051,9 +1051,9 @@
1051 integrity sha512-BybEHU5/I9EQ0CcwKAqmreZ2bMnAXrqLCTptAc6vPetHMbrXdZfejP5mt57e/8PNSt/qE7BHniU5PCYA+PGIHw== 1051 integrity sha512-BybEHU5/I9EQ0CcwKAqmreZ2bMnAXrqLCTptAc6vPetHMbrXdZfejP5mt57e/8PNSt/qE7BHniU5PCYA+PGIHw==
1052 1052
1053 "@iconify/json@^1.1.258": 1053 "@iconify/json@^1.1.258":
1054 - version "1.1.258"  
1055 - resolved "https://registry.npmjs.org/@iconify/json/-/json-1.1.258.tgz#392064ae8fd4c6d542c21bb4d0d57d5860f38abb"  
1056 - integrity sha512-x5DKhRrg8v1NWmClWa8zA80gWQ9xevivsUAF4s8CyAl/ZplBsEE1funKuuVcIKjexyE1UXb7uFWrUKt1fB5n1A== 1054 + version "1.1.259"
  1055 + resolved "https://registry.npmjs.org/@iconify/json/-/json-1.1.259.tgz#433ccff8572e42c3abab1cdbac872af0e8340419"
  1056 + integrity sha512-tDL4IgKtj3LA2lI+IoZfylBtKWNpV5I9BLj7WGMI/SvGkkYo+9DUap3Ho6iUbQLtu9GmHwpE/cA8mwEBkj/otw==
1057 1057
1058 "@koa/cors@^3.1.0": 1058 "@koa/cors@^3.1.0":
1059 version "3.1.0" 1059 version "3.1.0"
@@ -1236,9 +1236,9 @@ @@ -1236,9 +1236,9 @@
1236 unist-util-find-all-after "^3.0.1" 1236 unist-util-find-all-after "^3.0.1"
1237 1237
1238 "@surma/rollup-plugin-off-main-thread@^1.1.1": 1238 "@surma/rollup-plugin-off-main-thread@^1.1.1":
1239 - version "1.4.1"  
1240 - resolved "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-1.4.1.tgz#bf1343e5a926e5a1da55e3affd761dda4ce143ef"  
1241 - integrity sha512-ZPBWYQDdO4JZiTmTP3DABsHhIPA7bEJk9Znk7tZsrbPGanoGo8YxMv//WLx5Cvb+lRgS42+6yiOIYYHCKDmkpQ== 1239 + version "1.4.2"
  1240 + resolved "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-1.4.2.tgz#e6786b6af5799f82f7ab3a82e53f6182d2b91a58"
  1241 + integrity sha512-yBMPqmd1yEJo/280PAMkychuaALyQ9Lkb5q1ck3mjJrFuEobIfhnQ4J3mbvBoISmR3SWMWV+cGB/I0lCQee79A==
1242 dependencies: 1242 dependencies:
1243 ejs "^2.6.1" 1243 ejs "^2.6.1"
1244 magic-string "^0.25.0" 1244 magic-string "^0.25.0"
@@ -1850,7 +1850,7 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: @@ -1850,7 +1850,7 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0:
1850 dependencies: 1850 dependencies:
1851 color-convert "^2.0.1" 1851 color-convert "^2.0.1"
1852 1852
1853 -ant-design-vue@^2.0.0-rc.1: 1853 +ant-design-vue@^2.0.0-beta.15:
1854 version "2.0.0-rc.1" 1854 version "2.0.0-rc.1"
1855 resolved "https://registry.npmjs.org/ant-design-vue/-/ant-design-vue-2.0.0-rc.1.tgz#2ef02475f3aa4c1474f2fe3cf44a52c34787be02" 1855 resolved "https://registry.npmjs.org/ant-design-vue/-/ant-design-vue-2.0.0-rc.1.tgz#2ef02475f3aa4c1474f2fe3cf44a52c34787be02"
1856 integrity sha512-iKXkFtTHarvLHV7LWmYh6g/Cmkv+xK+vS621A1Qvg37Z6lCGg3K9BGAizmklAYzOTiPz0Ltt63eSiNqYMGh52g== 1856 integrity sha512-iKXkFtTHarvLHV7LWmYh6g/Cmkv+xK+vS621A1Qvg37Z6lCGg3K9BGAizmklAYzOTiPz0Ltt63eSiNqYMGh52g==
@@ -1982,9 +1982,9 @@ astral-regex@^2.0.0: @@ -1982,9 +1982,9 @@ astral-regex@^2.0.0:
1982 integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== 1982 integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==
1983 1983
1984 async-validator@^3.3.0, async-validator@^3.4.0: 1984 async-validator@^3.3.0, async-validator@^3.4.0:
1985 - version "3.4.0"  
1986 - resolved "https://registry.npmjs.org/async-validator/-/async-validator-3.4.0.tgz#871b3e594124bf4c4eb7bcd1a9e78b44f3b09cae"  
1987 - integrity sha512-VrFk4eYiJAWKskEz115iiuCf9O0ftnMMPXrOFMqyzGH2KxO7YwncKyn/FgOOP+0MDHMfXL7gLExagCutaZGigA== 1985 + version "3.5.0"
  1986 + resolved "https://registry.npmjs.org/async-validator/-/async-validator-3.5.0.tgz#f6791ee7217cde8036941591bc3754f7c26bbf89"
  1987 + integrity sha512-jMDcDHrH618eznoO4/3afJG5+I4HE/ipQd7y4mhPJmCaoHCSPOJfjpWgjFoxma2h8irL+zGe+qwyptDrR37Vhg==
1988 1988
1989 async@^2.6.2: 1989 async@^2.6.2:
1990 version "2.6.3" 1990 version "2.6.3"
@@ -2079,9 +2079,9 @@ balanced-match@^1.0.0: @@ -2079,9 +2079,9 @@ balanced-match@^1.0.0:
2079 integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= 2079 integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
2080 2080
2081 base64-js@^1.3.1: 2081 base64-js@^1.3.1:
2082 - version "1.5.0"  
2083 - resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.0.tgz#2d03045876d9e2b68a7a0f87d6bd163595e3b6af"  
2084 - integrity sha512-Jrdy04F2EKcNggUDfubMUPNAZg2vMquLQSm8sKLYJvz40ClFL1S8GKyDshGkNsbNNE5Z+fQavzU7nSK1I9JUGA== 2082 + version "1.5.1"
  2083 + resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
  2084 + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
2085 2085
2086 base@^0.11.1: 2086 base@^0.11.1:
2087 version "0.11.2" 2087 version "0.11.2"
@@ -2297,9 +2297,9 @@ camelcase@^5.0.0, camelcase@^5.3.1: @@ -2297,9 +2297,9 @@ camelcase@^5.0.0, camelcase@^5.3.1:
2297 integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== 2297 integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
2298 2298
2299 caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001157: 2299 caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001157:
2300 - version "1.0.30001157"  
2301 - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001157.tgz#2d11aaeb239b340bc1aa730eca18a37fdb07a9ab"  
2302 - integrity sha512-gOerH9Wz2IRZ2ZPdMfBvyOi3cjaz4O4dgNwPGzx8EhqAs4+2IL/O+fJsbt+znSigujoZG8bVcIAUM/I/E5K3MA== 2300 + version "1.0.30001158"
  2301 + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001158.tgz#fce86d321369603c2bc855ee0e901a7f49f8310b"
  2302 + integrity sha512-s5loVYY+yKpuVA3HyW8BarzrtJvwHReuzugQXlv1iR3LKSReoFXRm86mT6hT7PEF5RxW+XQZg+6nYjlywYzQ+g==
2303 2303
2304 ccount@^1.0.0: 2304 ccount@^1.0.0:
2305 version "1.1.0" 2305 version "1.1.0"
@@ -2940,9 +2940,9 @@ cssesc@^3.0.0: @@ -2940,9 +2940,9 @@ cssesc@^3.0.0:
2940 integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== 2940 integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
2941 2941
2942 csstype@^2.6.8: 2942 csstype@^2.6.8:
2943 - version "2.6.13"  
2944 - resolved "https://registry.npmjs.org/csstype/-/csstype-2.6.13.tgz#a6893015b90e84dd6e85d0e3b442a1e84f2dbe0f"  
2945 - integrity sha512-ul26pfSQTZW8dcOnD2iiJssfXw0gdNVX9IJDH/X3K5DGPfj+fUYe3kB+swUY6BF3oZDxaID3AJt+9/ojSAE05A== 2943 + version "2.6.14"
  2944 + resolved "https://registry.npmjs.org/csstype/-/csstype-2.6.14.tgz#004822a4050345b55ad4dcc00be1d9cf2f4296de"
  2945 + integrity sha512-2mSc+VEpGPblzAxyeR+vZhJKgYg0Og0nnRi7pmRXFYYxSfnOnW8A5wwQb4n4cE2nIOzqKOAzLCaEX6aBmNEv8A==
2946 2946
2947 currently-unhandled@^0.4.1: 2947 currently-unhandled@^0.4.1:
2948 version "0.4.1" 2948 version "0.4.1"
@@ -3263,9 +3263,9 @@ ejs@^2.6.1: @@ -3263,9 +3263,9 @@ ejs@^2.6.1:
3263 integrity sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA== 3263 integrity sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==
3264 3264
3265 electron-to-chromium@^1.3.591: 3265 electron-to-chromium@^1.3.591:
3266 - version "1.3.592"  
3267 - resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.592.tgz#4621521b223bf6e5469373528321e185d3c24670"  
3268 - integrity sha512-kGNowksvqQiPb1pUSQKpd8JFoGPLxYOwduNRCqCxGh/2Q1qE2JdmwouCW41lUzDxOb/2RIV4lR0tVIfboWlO9A== 3266 + version "1.3.596"
  3267 + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.596.tgz#c7ed98512c7ff36ddcbfed9e54e6355335c35257"
  3268 + integrity sha512-nLO2Wd2yU42eSoNJVQKNf89CcEGqeFZd++QsnN2XIgje1s/19AgctfjLIbPORlvcCO8sYjLwX4iUgDdusOY8Sg==
3269 3269
3270 emoji-regex@^7.0.1: 3270 emoji-regex@^7.0.1:
3271 version "7.0.3" 3271 version "7.0.3"
@@ -6931,9 +6931,9 @@ rollup@^1.31.1: @@ -6931,9 +6931,9 @@ rollup@^1.31.1:
6931 acorn "^7.1.0" 6931 acorn "^7.1.0"
6932 6932
6933 rollup@^2.32.1: 6933 rollup@^2.32.1:
6934 - version "2.33.1"  
6935 - resolved "https://registry.npmjs.org/rollup/-/rollup-2.33.1.tgz#802795164164ee63cd47769d8879c33ec8ae0c40"  
6936 - integrity sha512-uY4O/IoL9oNW8MMcbA5hcOaz6tZTMIh7qJHx/tzIJm+n1wLoY38BLn6fuy7DhR57oNFLMbDQtDeJoFURt5933w== 6934 + version "2.33.2"
  6935 + resolved "https://registry.npmjs.org/rollup/-/rollup-2.33.2.tgz#c4c76cd405a7605e6ebe90976398c46d4c2ea166"
  6936 + integrity sha512-QPQ6/fWCrzHtSXkI269rhKaC7qXGghYBwXU04b1JsDZ6ibZa3DJ9D1SFAYRMgx1inDg0DaTbb3N4Z1NK/r3fhw==
6937 optionalDependencies: 6937 optionalDependencies:
6938 fsevents "~2.1.2" 6938 fsevents "~2.1.2"
6939 6939
@@ -7874,9 +7874,9 @@ type-fest@^0.13.1: @@ -7874,9 +7874,9 @@ type-fest@^0.13.1:
7874 integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg== 7874 integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==
7875 7875
7876 type-fest@^0.18.0: 7876 type-fest@^0.18.0:
7877 - version "0.18.0"  
7878 - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.18.0.tgz#2edfa6382d48653707344f7fccdb0443d460e8d6"  
7879 - integrity sha512-fbDukFPnJBdn2eZ3RR+5mK2slHLFd6gYHY7jna1KWWy4Yr4XysHuCdXRzy+RiG/HwG4WJat00vdC2UHky5eKiQ== 7877 + version "0.18.1"
  7878 + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz#db4bc151a4a2cf4eebf9add5db75508db6cc841f"
  7879 + integrity sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==
7880 7880
7881 type-fest@^0.3.1: 7881 type-fest@^0.3.1:
7882 version "0.3.1" 7882 version "0.3.1"
@@ -7919,9 +7919,9 @@ typescript@^4.0.5: @@ -7919,9 +7919,9 @@ typescript@^4.0.5:
7919 integrity sha512-ywmr/VrTVCmNTJ6iV2LwIrfG1P+lv6luD8sUJs+2eI9NLGigaN+nUQc13iHqisq7bra9lnmUSYqbJvegraBOPQ== 7919 integrity sha512-ywmr/VrTVCmNTJ6iV2LwIrfG1P+lv6luD8sUJs+2eI9NLGigaN+nUQc13iHqisq7bra9lnmUSYqbJvegraBOPQ==
7920 7920
7921 uglify-js@^3.1.4: 7921 uglify-js@^3.1.4:
7922 - version "3.11.5"  
7923 - resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.11.5.tgz#d6788bc83cf35ff18ea78a65763e480803409bc6"  
7924 - integrity sha512-btvv/baMqe7HxP7zJSF7Uc16h1mSfuuSplT0/qdjxseesDU+yYzH33eHBH+eMdeRXwujXspaCTooWHQVVBh09w== 7922 + version "3.11.6"
  7923 + resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.11.6.tgz#144b50d3e05eadd3ad4dd047c60ca541a8cd4e9c"
  7924 + integrity sha512-oASI1FOJ7BBFkSCNDZ446EgkSuHkOZBuqRFrwXIKWCoXw8ZXQETooTQjkAcBS03Acab7ubCKsXnwuV2svy061g==
7925 7925
7926 unherit@^1.0.4: 7926 unherit@^1.0.4:
7927 version "1.1.3" 7927 version "1.1.3"
@@ -8581,7 +8581,7 @@ y18n@^4.0.0: @@ -8581,7 +8581,7 @@ y18n@^4.0.0:
8581 resolved "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" 8581 resolved "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
8582 integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== 8582 integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==
8583 8583
8584 -y18n@^5.0.2: 8584 +y18n@^5.0.5:
8585 version "5.0.5" 8585 version "5.0.5"
8586 resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz#8769ec08d03b1ea2df2500acef561743bbb9ab18" 8586 resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz#8769ec08d03b1ea2df2500acef561743bbb9ab18"
8587 integrity sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg== 8587 integrity sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==
@@ -8656,16 +8656,16 @@ yargs@^15.0.0, yargs@^15.1.0: @@ -8656,16 +8656,16 @@ yargs@^15.0.0, yargs@^15.1.0:
8656 yargs-parser "^18.1.2" 8656 yargs-parser "^18.1.2"
8657 8657
8658 yargs@^16.0.3, yargs@^16.1.0: 8658 yargs@^16.0.3, yargs@^16.1.0:
8659 - version "16.1.0"  
8660 - resolved "https://registry.npmjs.org/yargs/-/yargs-16.1.0.tgz#fc333fe4791660eace5a894b39d42f851cd48f2a"  
8661 - integrity sha512-upWFJOmDdHN0syLuESuvXDmrRcWd1QafJolHskzaw79uZa7/x53gxQKiR07W59GWY1tFhhU/Th9DrtSfpS782g== 8659 + version "16.1.1"
  8660 + resolved "https://registry.npmjs.org/yargs/-/yargs-16.1.1.tgz#5a4a095bd1ca806b0a50d0c03611d38034d219a1"
  8661 + integrity sha512-hAD1RcFP/wfgfxgMVswPE+z3tlPFtxG8/yWUrG2i17sTWGCGqWnxKcLTF4cUKDUK8fzokwsmO9H0TDkRbMHy8w==
8662 dependencies: 8662 dependencies:
8663 cliui "^7.0.2" 8663 cliui "^7.0.2"
8664 escalade "^3.1.1" 8664 escalade "^3.1.1"
8665 get-caller-file "^2.0.5" 8665 get-caller-file "^2.0.5"
8666 require-directory "^2.1.1" 8666 require-directory "^2.1.1"
8667 string-width "^4.2.0" 8667 string-width "^4.2.0"
8668 - y18n "^5.0.2" 8668 + y18n "^5.0.5"
8669 yargs-parser "^20.2.2" 8669 yargs-parser "^20.2.2"
8670 8670
8671 ylru@^1.2.0: 8671 ylru@^1.2.0: