Browse Source

Merge branch 'main' into fix

pull/6997/head
Jin Mao 2 weeks ago
committed by GitHub
parent
commit
b9224fc379
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 12
      apps/web-antd/src/adapter/component/index.ts
  2. 12
      packages/@core/base/shared/src/utils/dom.ts
  3. 9
      packages/@core/ui-kit/popup-ui/src/modal/use-modal.ts
  4. 6
      packages/@core/ui-kit/shadcn-ui/src/components/spinner/loading.vue
  5. 34
      packages/effects/plugins/src/echarts/use-echarts.ts
  6. 12
      playground/src/adapter/component/index.ts
  7. 13
      playground/src/store/auth.ts

12
apps/web-antd/src/adapter/component/index.ts

@ -17,6 +17,7 @@ import type { BaseFormComponentType } from '@vben/common-ui';
import type { Recordable } from '@vben/types'; import type { Recordable } from '@vben/types';
import { import {
computed,
defineAsyncComponent, defineAsyncComponent,
defineComponent, defineComponent,
h, h,
@ -383,12 +384,17 @@ const withPreviewUpload = () => {
attrs?.fileList || attrs?.['file-list'] || [], attrs?.fileList || attrs?.['file-list'] || [],
); );
const maxSize = computed(() => attrs?.maxSize ?? attrs?.['max-size']);
const aspectRatio = computed(
() => attrs?.aspectRatio ?? attrs?.['aspect-ratio'],
);
const handleBeforeUpload = async ( const handleBeforeUpload = async (
file: UploadFile, file: UploadFile,
originFileList: Array<File>, originFileList: Array<File>,
) => { ) => {
if (attrs.maxSize && (file.size || 0) / 1024 / 1024 > attrs.maxSize) { if (maxSize.value && (file.size || 0) / 1024 / 1024 > maxSize.value) {
message.error($t('ui.formRules.sizeLimit', [attrs.maxSize])); message.error($t('ui.formRules.sizeLimit', [maxSize.value]));
file.status = 'removed'; file.status = 'removed';
return false; return false;
} }
@ -401,7 +407,7 @@ const withPreviewUpload = () => {
) { ) {
file.status = 'removed'; file.status = 'removed';
// antd Upload组件问题 file参数获取的是UploadFile类型对象无法取到File类型 所以通过originFileList[0]获取 // antd Upload组件问题 file参数获取的是UploadFile类型对象无法取到File类型 所以通过originFileList[0]获取
const blob = await cropImage(originFileList[0], attrs.aspectRatio); const blob = await cropImage(originFileList[0], aspectRatio.value);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (!blob) { if (!blob) {
return reject(new Error($t('ui.crop.errorTip'))); return reject(new Error($t('ui.crop.errorTip')));

12
packages/@core/base/shared/src/utils/dom.ts

@ -41,6 +41,18 @@ export function getElementVisibleRect(
const left = Math.max(rect.left, 0); const left = Math.max(rect.left, 0);
const right = Math.min(rect.right, viewWidth); const right = Math.min(rect.right, viewWidth);
// 如果元素完全不可见,则返回一个空的矩形
if (top >= viewHeight || bottom <= 0 || left >= viewWidth || right <= 0) {
return {
bottom: 0,
height: 0,
left: 0,
right: 0,
top: 0,
width: 0,
};
}
return { return {
bottom, bottom,
height: Math.max(0, bottom - top), height: Math.max(0, bottom - top),

9
packages/@core/ui-kit/popup-ui/src/modal/use-modal.ts

@ -41,6 +41,7 @@ export function useVbenModal<TParentModalProps extends ModalProps = ModalProps>(
// 不能用 Object.assign,会丢失 api 的原型函数 // 不能用 Object.assign,会丢失 api 的原型函数
Object.setPrototypeOf(extendedApi, api); Object.setPrototypeOf(extendedApi, api);
}, },
consumed: false,
options, options,
async reCreateModal() { async reCreateModal() {
isModalReady.value = false; isModalReady.value = false;
@ -73,7 +74,13 @@ export function useVbenModal<TParentModalProps extends ModalProps = ModalProps>(
return [Modal, extendedApi as ExtendedModalApi] as const; return [Modal, extendedApi as ExtendedModalApi] as const;
} }
const injectData = inject<any>(USER_MODAL_INJECT_KEY, {}); let injectData = inject<any>(USER_MODAL_INJECT_KEY, {});
// 这个数据已经被使用了,说明这个弹窗是嵌套的弹窗,不应该merge上层的配置
if (injectData.consumed) {
injectData = {};
} else {
injectData.consumed = true;
}
const mergedOptions = { const mergedOptions = {
...DEFAULT_MODAL_PROPS, ...DEFAULT_MODAL_PROPS,

6
packages/@core/ui-kit/shadcn-ui/src/components/spinner/loading.vue

@ -32,19 +32,19 @@ const props = withDefaults(defineProps<Props>(), {
// const startTime = ref(0); // const startTime = ref(0);
const showSpinner = ref(false); const showSpinner = ref(false);
const renderSpinner = ref(false); const renderSpinner = ref(false);
const timer = ref<ReturnType<typeof setTimeout>>(); let timer: ReturnType<typeof setTimeout> | undefined;
watch( watch(
() => props.spinning, () => props.spinning,
(show) => { (show) => {
if (!show) { if (!show) {
showSpinner.value = false; showSpinner.value = false;
clearTimeout(timer.value); timer && clearTimeout(timer);
return; return;
} }
// startTime.value = performance.now(); // startTime.value = performance.now();
timer.value = setTimeout(() => { timer = setTimeout(() => {
// const loadingTime = performance.now() - startTime.value; // const loadingTime = performance.now() - startTime.value;
showSpinner.value = true; showSpinner.value = true;

34
packages/effects/plugins/src/echarts/use-echarts.ts

@ -92,7 +92,8 @@ function useEcharts(chartRef: Ref<EchartsUIType>) {
return; return;
} }
useTimeoutFn(() => { useTimeoutFn(() => {
if (!chartInstance) { if (!chartInstance || chartInstance?.getDom() !== el) {
chartInstance?.dispose();
const instance = initCharts(); const instance = initCharts();
if (!instance) return; if (!instance) return;
} }
@ -104,6 +105,36 @@ function useEcharts(chartRef: Ref<EchartsUIType>) {
}); });
}; };
const updateDate = (
option: EChartsOption,
notMerge = false, // false = 合并(保留动画),true = 完全替换
lazyUpdate = false, // true 时不立即重绘,适合短时间内多次调用
): Promise<echarts.ECharts | null> => {
return new Promise((resolve) => {
nextTick(() => {
if (!chartInstance) {
// 还没初始化 → 当作首次渲染
renderEcharts(option).then(resolve);
return;
}
// 合并你原有的全局配置(比如 backgroundColor)
const finalOption = {
...option,
...getOptions.value,
};
chartInstance.setOption(finalOption, {
notMerge,
lazyUpdate,
// silent: true, // 如果追求极致性能可开启(关闭所有事件)
});
resolve(chartInstance);
});
});
};
function resize() { function resize() {
const el = getChartEl(); const el = getChartEl();
if (isElHidden(el)) { if (isElHidden(el)) {
@ -139,6 +170,7 @@ function useEcharts(chartRef: Ref<EchartsUIType>) {
return { return {
renderEcharts, renderEcharts,
resize, resize,
updateDate,
getChartInstance: () => chartInstance, getChartInstance: () => chartInstance,
}; };
} }

12
playground/src/adapter/component/index.ts

@ -17,6 +17,7 @@ import type { BaseFormComponentType } from '@vben/common-ui';
import type { Recordable } from '@vben/types'; import type { Recordable } from '@vben/types';
import { import {
computed,
defineAsyncComponent, defineAsyncComponent,
defineComponent, defineComponent,
h, h,
@ -383,12 +384,17 @@ const withPreviewUpload = () => {
attrs?.fileList || attrs?.['file-list'] || [], attrs?.fileList || attrs?.['file-list'] || [],
); );
const maxSize = computed(() => attrs?.maxSize ?? attrs?.['max-size']);
const aspectRatio = computed(
() => attrs?.aspectRatio ?? attrs?.['aspect-ratio'],
);
const handleBeforeUpload = async ( const handleBeforeUpload = async (
file: UploadFile, file: UploadFile,
originFileList: Array<File>, originFileList: Array<File>,
) => { ) => {
if (attrs.maxSize && (file.size || 0) / 1024 / 1024 > attrs.maxSize) { if (maxSize.value && (file.size || 0) / 1024 / 1024 > maxSize.value) {
message.error($t('ui.formRules.sizeLimit', [attrs.maxSize])); message.error($t('ui.formRules.sizeLimit', [maxSize.value]));
file.status = 'removed'; file.status = 'removed';
return false; return false;
} }
@ -401,7 +407,7 @@ const withPreviewUpload = () => {
) { ) {
file.status = 'removed'; file.status = 'removed';
// antd Upload组件问题 file参数获取的是UploadFile类型对象无法取到File类型 所以通过originFileList[0]获取 // antd Upload组件问题 file参数获取的是UploadFile类型对象无法取到File类型 所以通过originFileList[0]获取
const blob = await cropImage(originFileList[0], attrs.aspectRatio); const blob = await cropImage(originFileList[0], aspectRatio.value);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (!blob) { if (!blob) {
return reject(new Error($t('ui.crop.errorTip'))); return reject(new Error($t('ui.crop.errorTip')));

13
playground/src/store/auth.ts

@ -78,15 +78,22 @@ export const useAuthStore = defineStore('auth', () => {
}; };
} }
const isLoggingOut = ref(false); // 正在 logout 标识, 防止 /logout 死循环.
async function logout(redirect: boolean = true) { async function logout(redirect: boolean = true) {
if (isLoggingOut.value) return; // 正在登出中, 说明已进入循环, 直接返回.
isLoggingOut.value = true; // 设置 标识
try { try {
await logoutApi(); await logoutApi();
} catch { } catch {
// 不做任何处理 // 不做任何处理
} } finally {
isLoggingOut.value = false; // 重置 标识
resetAllStores(); resetAllStores();
accessStore.setLoginExpired(false); accessStore.setLoginExpired(false);
}
// 回登录页带上当前路由地址 // 回登录页带上当前路由地址
await router.replace({ await router.replace({

Loading…
Cancel
Save