fix(web-antdv-next): sync shared UI fixes
parent
09970d89a4
commit
f6a8c6e652
|
|
@ -72,6 +72,7 @@ import {
|
||||||
Checkbox as CheckboxComponent,
|
Checkbox as CheckboxComponent,
|
||||||
CheckboxGroup as CheckboxGroupComponent,
|
CheckboxGroup as CheckboxGroupComponent,
|
||||||
DatePicker as DatePickerComponent,
|
DatePicker as DatePickerComponent,
|
||||||
|
DateRangePicker as RangePickerComponent,
|
||||||
Divider as DividerComponent,
|
Divider as DividerComponent,
|
||||||
Image as ImageComponent,
|
Image as ImageComponent,
|
||||||
ImagePreviewGroup,
|
ImagePreviewGroup,
|
||||||
|
|
@ -84,7 +85,6 @@ import {
|
||||||
notification,
|
notification,
|
||||||
Radio as RadioComponent,
|
Radio as RadioComponent,
|
||||||
RadioGroup as RadioGroupComponent,
|
RadioGroup as RadioGroupComponent,
|
||||||
DateRangePicker as RangePickerComponent,
|
|
||||||
Rate as RateComponent,
|
Rate as RateComponent,
|
||||||
Select as SelectComponent,
|
Select as SelectComponent,
|
||||||
Space as SpaceComponent,
|
Space as SpaceComponent,
|
||||||
|
|
@ -279,9 +279,9 @@ async function previewImage(
|
||||||
{
|
{
|
||||||
class: 'hidden',
|
class: 'hidden',
|
||||||
preview: {
|
preview: {
|
||||||
open: visible.value,
|
visible: visible.value,
|
||||||
current: currentIndex,
|
current: currentIndex,
|
||||||
onOpenChange: (value: boolean) => {
|
onVisibleChange: (value: boolean) => {
|
||||||
visible.value = value;
|
visible.value = value;
|
||||||
if (!value) {
|
if (!value) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|
@ -366,7 +366,7 @@ function cropImage(file: File, aspectRatio: string | undefined) {
|
||||||
closable: false,
|
closable: false,
|
||||||
cancelText: $t('common.cancel'),
|
cancelText: $t('common.cancel'),
|
||||||
okText: $t('ui.crop.confirm'),
|
okText: $t('ui.crop.confirm'),
|
||||||
destroyOnHidden: true,
|
destroyOnClose: true,
|
||||||
onOk: async () => {
|
onOk: async () => {
|
||||||
const cropper = cropperRef.value;
|
const cropper = cropperRef.value;
|
||||||
if (!cropper) {
|
if (!cropper) {
|
||||||
|
|
@ -625,7 +625,6 @@ export type ComponentType =
|
||||||
| 'Space'
|
| 'Space'
|
||||||
| 'Switch'
|
| 'Switch'
|
||||||
| 'TextArea'
|
| 'TextArea'
|
||||||
| 'TextArea'
|
|
||||||
| 'TimePicker'
|
| 'TimePicker'
|
||||||
| 'TimeRangePicker'
|
| 'TimeRangePicker'
|
||||||
| 'TreeSelect'
|
| 'TreeSelect'
|
||||||
|
|
@ -676,13 +675,13 @@ async function initComponentAdapter() {
|
||||||
fieldNames: { label: 'label', value: 'value', children: 'children' },
|
fieldNames: { label: 'label', value: 'value', children: 'children' },
|
||||||
loadingSlot: 'suffixIcon',
|
loadingSlot: 'suffixIcon',
|
||||||
modelPropName: 'value',
|
modelPropName: 'value',
|
||||||
visibleEvent: 'onOpenChange',
|
visibleEvent: 'onVisibleChange',
|
||||||
}),
|
}),
|
||||||
ApiSelect: withDefaultPlaceholder(ApiComponent, 'select', {
|
ApiSelect: withDefaultPlaceholder(ApiComponent, 'select', {
|
||||||
component: Select,
|
component: Select,
|
||||||
loadingSlot: 'suffixIcon',
|
loadingSlot: 'suffixIcon',
|
||||||
modelPropName: 'value',
|
modelPropName: 'value',
|
||||||
visibleEvent: 'onOpenChange',
|
visibleEvent: 'onVisibleChange',
|
||||||
}),
|
}),
|
||||||
ApiTreeSelect: withDefaultPlaceholder(ApiComponent, 'select', {
|
ApiTreeSelect: withDefaultPlaceholder(ApiComponent, 'select', {
|
||||||
component: TreeSelect,
|
component: TreeSelect,
|
||||||
|
|
@ -690,7 +689,7 @@ async function initComponentAdapter() {
|
||||||
loadingSlot: 'suffixIcon',
|
loadingSlot: 'suffixIcon',
|
||||||
modelPropName: 'value',
|
modelPropName: 'value',
|
||||||
optionsPropName: 'treeData',
|
optionsPropName: 'treeData',
|
||||||
visibleEvent: 'onOpenChange',
|
visibleEvent: 'onVisibleChange',
|
||||||
}),
|
}),
|
||||||
AutoComplete,
|
AutoComplete,
|
||||||
Cascader,
|
Cascader,
|
||||||
|
|
@ -744,7 +743,7 @@ async function initComponentAdapter() {
|
||||||
copyPreferencesSuccess: (title, content) => {
|
copyPreferencesSuccess: (title, content) => {
|
||||||
notification.success({
|
notification.success({
|
||||||
description: content,
|
description: content,
|
||||||
title,
|
message: title,
|
||||||
placement: 'bottomRight',
|
placement: 'bottomRight',
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -65,5 +65,6 @@ const useVbenForm = useForm<ComponentType, ComponentPropsMap>;
|
||||||
|
|
||||||
export { initSetupVbenForm, useVbenForm, z };
|
export { initSetupVbenForm, useVbenForm, z };
|
||||||
|
|
||||||
|
export type VbenFormApi = ReturnType<typeof useVbenForm>[1]; // add by 芋艿:用于 data.ts 表单 schema 内调用 setFieldValue
|
||||||
export type VbenFormSchema = FormSchema<ComponentType, ComponentPropsMap>;
|
export type VbenFormSchema = FormSchema<ComponentType, ComponentPropsMap>;
|
||||||
export type VbenFormProps = FormProps<ComponentType, ComponentPropsMap>;
|
export type VbenFormProps = FormProps<ComponentType, ComponentPropsMap>;
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ export function useAreaSelectRule() {
|
||||||
title: label,
|
title: label,
|
||||||
info: '',
|
info: '',
|
||||||
$required: false,
|
$required: false,
|
||||||
modelField: 'value', // 特殊:ele 里是 model-value,antd 里是 value
|
modelField: 'value', // Ant Design Vue 组件使用 value;web-ele 自定义组件使用默认 modelValue
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
props(_: any, { t }: any) {
|
props(_: any, { t }: any) {
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ export function useDictSelectRule() {
|
||||||
title: label,
|
title: label,
|
||||||
info: '',
|
info: '',
|
||||||
$required: false,
|
$required: false,
|
||||||
modelField: 'value', // 特殊:ele 里是 model-value,antd 里是 value
|
modelField: 'value', // Ant Design Vue 组件使用 value;web-ele 自定义组件使用默认 modelValue
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
props(_: any, { t }: any) {
|
props(_: any, { t }: any) {
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ export function useIframeRule() {
|
||||||
title: label,
|
title: label,
|
||||||
info: '',
|
info: '',
|
||||||
$required: false,
|
$required: false,
|
||||||
modelField: 'value', // 特殊:ele 里是 model-value,antd 里是 value
|
modelField: 'value', // Ant Design Vue 组件使用 value;web-ele 自定义组件使用默认 modelValue
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
props(_: any, { t }: any) {
|
props(_: any, { t }: any) {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,8 @@ import type { Dayjs } from 'dayjs';
|
||||||
|
|
||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
|
|
||||||
import { Radio, RadioGroup } from 'antdv-next';
|
import { DatePicker, Radio, RadioGroup } from 'antdv-next';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
import { getRangePickerDefaultProps } from '#/utils/rangePickerProps';
|
import { getRangePickerDefaultProps } from '#/utils/rangePickerProps';
|
||||||
|
|
||||||
|
|
@ -19,8 +20,20 @@ const times = ref<[Dayjs, Dayjs]>(); // 日期范围
|
||||||
const rangePickerProps = getRangePickerDefaultProps();
|
const rangePickerProps = getRangePickerDefaultProps();
|
||||||
const timeRangeOptions = [
|
const timeRangeOptions = [
|
||||||
rangePickerProps.presets[3]!, // 昨天
|
rangePickerProps.presets[3]!, // 昨天
|
||||||
rangePickerProps.presets[1]!, // 最近 7 天
|
{
|
||||||
rangePickerProps.presets[2]!, // 最近 30 天
|
label: rangePickerProps.presets[1]!.label,
|
||||||
|
value: [
|
||||||
|
dayjs().subtract(7, 'day').startOf('day'),
|
||||||
|
dayjs().subtract(1, 'day').endOf('day'),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: rangePickerProps.presets[2]!.label,
|
||||||
|
value: [
|
||||||
|
dayjs().subtract(30, 'day').startOf('day'),
|
||||||
|
dayjs().subtract(1, 'day').endOf('day'),
|
||||||
|
],
|
||||||
|
},
|
||||||
];
|
];
|
||||||
const timeRangeType = ref(timeRangeOptions[1]!.label); // 默认选中第一个选项
|
const timeRangeType = ref(timeRangeOptions[1]!.label); // 默认选中第一个选项
|
||||||
|
|
||||||
|
|
@ -75,7 +88,7 @@ onMounted(() => {
|
||||||
{{ option.label }}
|
{{ option.label }}
|
||||||
</Radio>
|
</Radio>
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
<DateRangePicker
|
<DatePicker.RangePicker
|
||||||
v-model:value="times"
|
v-model:value="times"
|
||||||
:format="rangePickerProps.format"
|
:format="rangePickerProps.format"
|
||||||
:value-format="rangePickerProps.valueFormat"
|
:value-format="rangePickerProps.valueFormat"
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { UploadFile, UploadProps } from 'antdv-next';
|
import type { UploadFile, UploadProps } from 'antdv-next';
|
||||||
|
import type { UploadRequestOption } from 'antdv-next/lib/vc-upload/interface';
|
||||||
|
|
||||||
import type { FileUploadProps } from './typing';
|
import type { FileUploadProps } from './typing';
|
||||||
|
|
||||||
|
|
@ -16,8 +17,6 @@ import { Button, message, Upload } from 'antdv-next';
|
||||||
import { UploadResultStatus } from './typing';
|
import { UploadResultStatus } from './typing';
|
||||||
import { useUpload, useUploadType } from './use-upload';
|
import { useUpload, useUploadType } from './use-upload';
|
||||||
|
|
||||||
type UploadRequestOption = any;
|
|
||||||
|
|
||||||
defineOptions({ name: 'FileUpload', inheritAttrs: false });
|
defineOptions({ name: 'FileUpload', inheritAttrs: false });
|
||||||
|
|
||||||
const props = withDefaults(defineProps<FileUploadProps>(), {
|
const props = withDefaults(defineProps<FileUploadProps>(), {
|
||||||
|
|
@ -33,6 +32,7 @@ const props = withDefaults(defineProps<FileUploadProps>(), {
|
||||||
multiple: false,
|
multiple: false,
|
||||||
api: undefined,
|
api: undefined,
|
||||||
resultField: '',
|
resultField: '',
|
||||||
|
returnText: false,
|
||||||
showDescription: false,
|
showDescription: false,
|
||||||
});
|
});
|
||||||
const emit = defineEmits([
|
const emit = defineEmits([
|
||||||
|
|
@ -148,9 +148,6 @@ function handleUploadError(error: any) {
|
||||||
* @returns 是否允许上传
|
* @returns 是否允许上传
|
||||||
*/
|
*/
|
||||||
async function beforeUpload(file: File) {
|
async function beforeUpload(file: File) {
|
||||||
const fileContent = await file.text();
|
|
||||||
emit('returnText', fileContent);
|
|
||||||
|
|
||||||
// 检查文件数量限制
|
// 检查文件数量限制
|
||||||
if (fileList.value!.length >= props.maxNumber) {
|
if (fileList.value!.length >= props.maxNumber) {
|
||||||
message.error($t('ui.upload.maxNumber', [props.maxNumber]));
|
message.error($t('ui.upload.maxNumber', [props.maxNumber]));
|
||||||
|
|
@ -177,6 +174,10 @@ async function beforeUpload(file: File) {
|
||||||
|
|
||||||
// 只有在验证通过后才增加计数器
|
// 只有在验证通过后才增加计数器
|
||||||
uploadNumber.value++;
|
uploadNumber.value++;
|
||||||
|
if (props.returnText) {
|
||||||
|
const fileContent = await file.text();
|
||||||
|
emit('returnText', fileContent);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ const textareaProps = computed(() => {
|
||||||
const fileUploadProps = computed(() => {
|
const fileUploadProps = computed(() => {
|
||||||
return {
|
return {
|
||||||
...props.fileUploadProps,
|
...props.fileUploadProps,
|
||||||
|
returnText: true,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ export interface FileUploadProps {
|
||||||
maxSize?: number; // 文件最大多少MB
|
maxSize?: number; // 文件最大多少MB
|
||||||
multiple?: boolean; // 是否支持多选
|
multiple?: boolean; // 是否支持多选
|
||||||
resultField?: string; // support xxx.xxx.xx
|
resultField?: string; // support xxx.xxx.xx
|
||||||
|
returnText?: boolean; // 是否返回文件文本内容
|
||||||
showDescription?: boolean; // 是否显示下面的描述
|
showDescription?: boolean; // 是否显示下面的描述
|
||||||
value?: string | string[];
|
value?: string | string[];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -202,6 +202,31 @@ onMounted(() => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const handleClick = (item: NotificationItem) => {
|
||||||
|
// 如果通知项有链接,点击时跳转
|
||||||
|
if (item.link) {
|
||||||
|
navigateTo(item.link, item.query, item.state);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function navigateTo(
|
||||||
|
link: string,
|
||||||
|
query?: Record<string, any>,
|
||||||
|
state?: Record<string, any>,
|
||||||
|
) {
|
||||||
|
if (link.startsWith('http://') || link.startsWith('https://')) {
|
||||||
|
// 外部链接,在新标签页打开
|
||||||
|
window.open(link, '_blank');
|
||||||
|
} else {
|
||||||
|
// 内部路由链接,支持 query 参数和 state
|
||||||
|
router.push({
|
||||||
|
path: link,
|
||||||
|
query: query || {},
|
||||||
|
state,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => ({
|
() => ({
|
||||||
enable: preferences.app.watermark,
|
enable: preferences.app.watermark,
|
||||||
|
|
@ -264,6 +289,7 @@ watch(
|
||||||
@view-all="handleNotificationViewAll"
|
@view-all="handleNotificationViewAll"
|
||||||
@open="handleNotificationOpen"
|
@open="handleNotificationOpen"
|
||||||
@read="handleNotificationRead"
|
@read="handleNotificationRead"
|
||||||
|
@on-click="handleClick"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #header-right-1>
|
<template #header-right-1>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue