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