Explorar o código

build: 删除合并多余文件

laiqi hai 11 meses
pai
achega
f5e766ff4d

+ 0 - 15
apps/backend-mock/api/system/dept/.post.ts

@@ -1,15 +0,0 @@
-import { verifyAccessToken } from '~/utils/jwt-utils';
-import {
-  sleep,
-  unAuthorizedResponse,
-  useResponseSuccess,
-} from '~/utils/response';
-
-export default eventHandler(async (event) => {
-  const userinfo = verifyAccessToken(event);
-  if (!userinfo) {
-    return unAuthorizedResponse(event);
-  }
-  await sleep(600);
-  return useResponseSuccess(null);
-});

+ 0 - 15
apps/backend-mock/api/system/dept/[id].delete.ts

@@ -1,15 +0,0 @@
-import { verifyAccessToken } from '~/utils/jwt-utils';
-import {
-  sleep,
-  unAuthorizedResponse,
-  useResponseSuccess,
-} from '~/utils/response';
-
-export default eventHandler(async (event) => {
-  const userinfo = verifyAccessToken(event);
-  if (!userinfo) {
-    return unAuthorizedResponse(event);
-  }
-  await sleep(1000);
-  return useResponseSuccess(null);
-});

+ 0 - 15
apps/backend-mock/api/system/dept/[id].put.ts

@@ -1,15 +0,0 @@
-import { verifyAccessToken } from '~/utils/jwt-utils';
-import {
-  sleep,
-  unAuthorizedResponse,
-  useResponseSuccess,
-} from '~/utils/response';
-
-export default eventHandler(async (event) => {
-  const userinfo = verifyAccessToken(event);
-  if (!userinfo) {
-    return unAuthorizedResponse(event);
-  }
-  await sleep(2000);
-  return useResponseSuccess(null);
-});

+ 0 - 61
apps/backend-mock/api/system/dept/list.ts

@@ -1,61 +0,0 @@
-import { faker } from '@faker-js/faker';
-import { verifyAccessToken } from '~/utils/jwt-utils';
-import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response';
-
-const formatterCN = new Intl.DateTimeFormat('zh-CN', {
-  timeZone: 'Asia/Shanghai',
-  year: 'numeric',
-  month: '2-digit',
-  day: '2-digit',
-  hour: '2-digit',
-  minute: '2-digit',
-  second: '2-digit',
-});
-
-function generateMockDataList(count: number) {
-  const dataList = [];
-
-  for (let i = 0; i < count; i++) {
-    const dataItem: Record<string, any> = {
-      id: faker.string.uuid(),
-      pid: 0,
-      name: faker.commerce.department(),
-      status: faker.helpers.arrayElement([0, 1]),
-      createTime: formatterCN.format(
-        faker.date.between({ from: '2021-01-01', to: '2022-12-31' }),
-      ),
-      remark: faker.lorem.sentence(),
-    };
-    if (faker.datatype.boolean()) {
-      dataItem.children = Array.from(
-        { length: faker.number.int({ min: 1, max: 5 }) },
-        () => ({
-          id: faker.string.uuid(),
-          pid: dataItem.id,
-          name: faker.commerce.department(),
-          status: faker.helpers.arrayElement([0, 1]),
-          createTime: formatterCN.format(
-            faker.date.between({ from: '2023-01-01', to: '2023-12-31' }),
-          ),
-          remark: faker.lorem.sentence(),
-        }),
-      );
-    }
-    dataList.push(dataItem);
-  }
-
-  return dataList;
-}
-
-const mockData = generateMockDataList(10);
-
-export default eventHandler(async (event) => {
-  const userinfo = verifyAccessToken(event);
-  if (!userinfo) {
-    return unAuthorizedResponse(event);
-  }
-
-  const listData = structuredClone(mockData);
-
-  return useResponseSuccess(listData);
-});

+ 0 - 12
apps/backend-mock/api/system/menu/list.ts

@@ -1,12 +0,0 @@
-import { verifyAccessToken } from '~/utils/jwt-utils';
-import { MOCK_MENU_LIST } from '~/utils/mock-data';
-import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response';
-
-export default eventHandler(async (event) => {
-  const userinfo = verifyAccessToken(event);
-  if (!userinfo) {
-    return unAuthorizedResponse(event);
-  }
-
-  return useResponseSuccess(MOCK_MENU_LIST);
-});

+ 0 - 28
apps/backend-mock/api/system/menu/name-exists.ts

@@ -1,28 +0,0 @@
-import { verifyAccessToken } from '~/utils/jwt-utils';
-import { MOCK_MENU_LIST } from '~/utils/mock-data';
-import { unAuthorizedResponse } from '~/utils/response';
-
-const namesMap: Record<string, any> = {};
-
-function getNames(menus: any[]) {
-  menus.forEach((menu) => {
-    namesMap[menu.name] = String(menu.id);
-    if (menu.children) {
-      getNames(menu.children);
-    }
-  });
-}
-getNames(MOCK_MENU_LIST);
-
-export default eventHandler(async (event) => {
-  const userinfo = verifyAccessToken(event);
-  if (!userinfo) {
-    return unAuthorizedResponse(event);
-  }
-  const { id, name } = getQuery(event);
-
-  return (name as string) in namesMap &&
-    (!id || namesMap[name as string] !== String(id))
-    ? useResponseSuccess(true)
-    : useResponseSuccess(false);
-});

+ 0 - 28
apps/backend-mock/api/system/menu/path-exists.ts

@@ -1,28 +0,0 @@
-import { verifyAccessToken } from '~/utils/jwt-utils';
-import { MOCK_MENU_LIST } from '~/utils/mock-data';
-import { unAuthorizedResponse } from '~/utils/response';
-
-const pathMap: Record<string, any> = { '/': 0 };
-
-function getPaths(menus: any[]) {
-  menus.forEach((menu) => {
-    pathMap[menu.path] = String(menu.id);
-    if (menu.children) {
-      getPaths(menu.children);
-    }
-  });
-}
-getPaths(MOCK_MENU_LIST);
-
-export default eventHandler(async (event) => {
-  const userinfo = verifyAccessToken(event);
-  if (!userinfo) {
-    return unAuthorizedResponse(event);
-  }
-  const { id, path } = getQuery(event);
-
-  return (path as string) in pathMap &&
-    (!id || pathMap[path as string] !== String(id))
-    ? useResponseSuccess(true)
-    : useResponseSuccess(false);
-});

+ 0 - 83
apps/backend-mock/api/system/role/list.ts

@@ -1,83 +0,0 @@
-import { faker } from '@faker-js/faker';
-import { verifyAccessToken } from '~/utils/jwt-utils';
-import { getMenuIds, MOCK_MENU_LIST } from '~/utils/mock-data';
-import { unAuthorizedResponse, usePageResponseSuccess } from '~/utils/response';
-
-const formatterCN = new Intl.DateTimeFormat('zh-CN', {
-  timeZone: 'Asia/Shanghai',
-  year: 'numeric',
-  month: '2-digit',
-  day: '2-digit',
-  hour: '2-digit',
-  minute: '2-digit',
-  second: '2-digit',
-});
-
-const menuIds = getMenuIds(MOCK_MENU_LIST);
-
-function generateMockDataList(count: number) {
-  const dataList = [];
-
-  for (let i = 0; i < count; i++) {
-    const dataItem: Record<string, any> = {
-      id: faker.string.uuid(),
-      name: faker.commerce.product(),
-      status: faker.helpers.arrayElement([0, 1]),
-      createTime: formatterCN.format(
-        faker.date.between({ from: '2022-01-01', to: '2025-01-01' }),
-      ),
-      permissions: faker.helpers.arrayElements(menuIds),
-      remark: faker.lorem.sentence(),
-    };
-
-    dataList.push(dataItem);
-  }
-
-  return dataList;
-}
-
-const mockData = generateMockDataList(100);
-
-export default eventHandler(async (event) => {
-  const userinfo = verifyAccessToken(event);
-  if (!userinfo) {
-    return unAuthorizedResponse(event);
-  }
-
-  const {
-    page = 1,
-    pageSize = 20,
-    name,
-    id,
-    remark,
-    startTime,
-    endTime,
-    status,
-  } = getQuery(event);
-  let listData = structuredClone(mockData);
-  if (name) {
-    listData = listData.filter((item) =>
-      item.name.toLowerCase().includes(String(name).toLowerCase()),
-    );
-  }
-  if (id) {
-    listData = listData.filter((item) =>
-      item.id.toLowerCase().includes(String(id).toLowerCase()),
-    );
-  }
-  if (remark) {
-    listData = listData.filter((item) =>
-      item.remark?.toLowerCase()?.includes(String(remark).toLowerCase()),
-    );
-  }
-  if (startTime) {
-    listData = listData.filter((item) => item.createTime >= startTime);
-  }
-  if (endTime) {
-    listData = listData.filter((item) => item.createTime <= endTime);
-  }
-  if (['0', '1'].includes(status as string)) {
-    listData = listData.filter((item) => item.status === Number(status));
-  }
-  return usePageResponseSuccess(page as string, pageSize as string, listData);
-});

+ 0 - 13
apps/backend-mock/api/upload.ts

@@ -1,13 +0,0 @@
-import { verifyAccessToken } from '~/utils/jwt-utils';
-import { unAuthorizedResponse } from '~/utils/response';
-
-export default eventHandler((event) => {
-  const userinfo = verifyAccessToken(event);
-  if (!userinfo) {
-    return unAuthorizedResponse(event);
-  }
-  return useResponseSuccess({
-    url: 'https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp',
-  });
-  // return useResponseError("test")
-});

+ 0 - 166
docs/src/components/common-ui/vben-alert.md

@@ -1,166 +0,0 @@
----
-outline: deep
----
-
-# Vben Alert 轻量提示框
-
-框架提供的一些用于轻量提示的弹窗,仅使用js代码即可快速动态创建提示而不需要在template写任何代码。
-
-::: info 应用场景
-
-Alert提供的功能与Modal类似,但只适用于简单应用场景。例如临时性、动态地弹出模态确认框、输入框等。如果对弹窗有更复杂的需求,请使用VbenModal
-
-:::
-
-::: tip 注意
-
-Alert提供的快捷方法alert、confirm、prompt动态创建的弹窗在已打开的情况下,不支持HMR(热更新),代码变更后需要关闭这些弹窗后重新打开。
-
-:::
-
-::: tip README
-
-下方示例代码中的,存在一些主题色未适配、样式缺失的问题,这些问题只在文档内会出现,实际使用并不会有这些问题,可忽略,不必纠结。
-
-:::
-
-## 基础用法
-
-使用 `alert` 创建只有一个确认按钮的提示框。
-
-<DemoPreview dir="demos/vben-alert/alert" />
-
-使用 `confirm` 创建有确认和取消按钮的提示框。
-
-<DemoPreview dir="demos/vben-alert/confirm" />
-
-使用 `prompt` 创建有确认和取消按钮、接受用户输入的提示框。
-
-<DemoPreview dir="demos/vben-alert/prompt" />
-
-## useAlertContext
-
-当弹窗的content、footer、icon使用自定义组件时,在这些组件中可以使用 `useAlertContext` 获取当前弹窗的上下文对象,用来主动控制弹窗。
-
-::: tip 注意
-
-`useAlertContext`只能用在setup或者函数式组件中。
-
-:::
-
-### Methods
-
-| 方法      | 描述               | 类型     | 版本要求 |
-| --------- | ------------------ | -------- | -------- |
-| doConfirm | 调用弹窗的确认操作 | ()=>void | >5.5.4   |
-| doCancel  | 调用弹窗的取消操作 | ()=>void | >5.5.4   |
-
-## 类型说明
-
-```ts
-/** 预置的图标类型 */
-export type IconType = 'error' | 'info' | 'question' | 'success' | 'warning';
-
-export type BeforeCloseScope = {
-  /** 是否为点击确认按钮触发的关闭 */
-  isConfirm: boolean;
-};
-
-/**
- * alert 属性
- */
-export type AlertProps = {
-  /** 关闭前的回调,如果返回false,则终止关闭 */
-  beforeClose?: (
-    scope: BeforeCloseScope,
-  ) => boolean | Promise<boolean | undefined> | undefined;
-  /** 边框 */
-  bordered?: boolean;
-  /** 按钮对齐方式 */
-  buttonAlign?: 'center' | 'end' | 'start';
-  /** 取消按钮的标题 */
-  cancelText?: string;
-  /** 是否居中显示 */
-  centered?: boolean;
-  /** 确认按钮的标题 */
-  confirmText?: string;
-  /** 弹窗容器的额外样式 */
-  containerClass?: string;
-  /** 弹窗提示内容 */
-  content: Component | string;
-  /** 弹窗内容的额外样式 */
-  contentClass?: string;
-  /** 执行beforeClose回调期间,在内容区域显示一个loading遮罩*/
-  contentMasking?: boolean;
-  /** 弹窗底部内容(与按钮在同一个容器中) */
-  footer?: Component | string;
-  /** 弹窗的图标(在标题的前面) */
-  icon?: Component | IconType;
-  /**
-   * 弹窗遮罩模糊效果
-   */
-  overlayBlur?: number;
-  /** 是否显示取消按钮 */
-  showCancel?: boolean;
-  /** 弹窗标题 */
-  title?: string;
-};
-
-/** prompt 属性 */
-export type PromptProps<T = any> = {
-  /** 关闭前的回调,如果返回false,则终止关闭 */
-  beforeClose?: (scope: {
-    isConfirm: boolean;
-    value: T | undefined;
-  }) => boolean | Promise<boolean | undefined> | undefined;
-  /** 用于接受用户输入的组件 */
-  component?: Component;
-  /** 输入组件的属性 */
-  componentProps?: Recordable<any>;
-  /** 输入组件的插槽 */
-  componentSlots?: Recordable<Component>;
-  /** 默认值 */
-  defaultValue?: T;
-  /** 输入组件的值属性名 */
-  modelPropName?: string;
-} & Omit<AlertProps, 'beforeClose'>;
-
-/**
- * 函数签名
- * alert和confirm的函数签名相同。
- * confirm默认会显示取消按钮,而alert默认只有一个按钮
- *  */
-export function alert(options: AlertProps): Promise<void>;
-export function alert(
-  message: string,
-  options?: Partial<AlertProps>,
-): Promise<void>;
-export function alert(
-  message: string,
-  title?: string,
-  options?: Partial<AlertProps>,
-): Promise<void>;
-
-/**
- * 弹出输入框的函数签名。
- * beforeClose的参数会传入用户当前输入的值
- * component指定接受用户输入的组件,默认为Input
- * componentProps 为输入组件设置的属性数据
- * defaultValue 默认的值
- * modelPropName 输入组件的值属性名称。默认为modelValue
- */
-export async function prompt<T = any>(
-  options: Omit<AlertProps, 'beforeClose'> & {
-    beforeClose?: (
-      scope: BeforeCloseScope & {
-        /** 输入组件的当前值 */
-        value: T;
-      },
-    ) => boolean | Promise<boolean | undefined> | undefined;
-    component?: Component;
-    componentProps?: Recordable<any>;
-    defaultValue?: T;
-    modelPropName?: string;
-  },
-): Promise<T | undefined>;
-```

+ 0 - 36
docs/src/demos/vben-alert/alert/index.vue

@@ -1,36 +0,0 @@
-<script lang="ts" setup>
-import { h } from 'vue';
-
-import { alert, VbenButton } from '@vben/common-ui';
-
-import { Result } from 'ant-design-vue';
-
-function showAlert() {
-  alert('This is an alert message');
-}
-
-function showIconAlert() {
-  alert({
-    content: 'This is an alert message with icon',
-    icon: 'success',
-  });
-}
-
-function showCustomAlert() {
-  alert({
-    buttonAlign: 'center',
-    content: h(Result, {
-      status: 'success',
-      subTitle: '已成功创建订单。订单ID:2017182818828182881',
-      title: '操作成功',
-    }),
-  });
-}
-</script>
-<template>
-  <div class="flex gap-4">
-    <VbenButton @click="showAlert">Alert</VbenButton>
-    <VbenButton @click="showIconAlert">Alert With Icon</VbenButton>
-    <VbenButton @click="showCustomAlert">Alert With Custom Content</VbenButton>
-  </div>
-</template>

+ 0 - 75
docs/src/demos/vben-alert/confirm/index.vue

@@ -1,75 +0,0 @@
-<script lang="ts" setup>
-import { h, ref } from 'vue';
-
-import { alert, confirm, VbenButton } from '@vben/common-ui';
-
-import { Checkbox, message } from 'ant-design-vue';
-
-function showConfirm() {
-  confirm('This is an alert message')
-    .then(() => {
-      alert('Confirmed');
-    })
-    .catch(() => {
-      alert('Canceled');
-    });
-}
-
-function showIconConfirm() {
-  confirm({
-    content: 'This is an alert message with icon',
-    icon: 'success',
-  });
-}
-
-function showfooterConfirm() {
-  const checked = ref(false);
-  confirm({
-    cancelText: '不要虾扯蛋',
-    confirmText: '是的,我们都是NPC',
-    content:
-      '刚才发生的事情,为什么我似乎早就经历过一般?\n我甚至能在事情发生过程中潜意识里预知到接下来会发生什么。\n\n听起来挺玄乎的,你有过这种感觉吗?',
-    footer: () =>
-      h(
-        Checkbox,
-        {
-          checked: checked.value,
-          class: 'flex-1',
-          'onUpdate:checked': (v) => (checked.value = v),
-        },
-        '不再提示',
-      ),
-    icon: 'question',
-    title: '未解之谜',
-  }).then(() => {
-    if (checked.value) {
-      message.success('我不会再拿这个问题烦你了');
-    } else {
-      message.info('下次还要继续问你哟');
-    }
-  });
-}
-
-function showAsyncConfirm() {
-  confirm({
-    beforeClose({ isConfirm }) {
-      if (isConfirm) {
-        // 这里可以执行一些异步操作。如果最终返回了false,将阻止关闭弹窗
-        return new Promise((resolve) => setTimeout(resolve, 2000));
-      }
-    },
-    content: 'This is an alert message with async confirm',
-    icon: 'success',
-  }).then(() => {
-    alert('Confirmed');
-  });
-}
-</script>
-<template>
-  <div class="flex gap-4">
-    <VbenButton @click="showConfirm">Confirm</VbenButton>
-    <VbenButton @click="showIconConfirm">Confirm With Icon</VbenButton>
-    <VbenButton @click="showfooterConfirm">Confirm With Footer</VbenButton>
-    <VbenButton @click="showAsyncConfirm">Async Confirm</VbenButton>
-  </div>
-</template>

+ 0 - 118
docs/src/demos/vben-alert/prompt/index.vue

@@ -1,118 +0,0 @@
-<script lang="ts" setup>
-import { h } from 'vue';
-
-import { alert, prompt, useAlertContext, VbenButton } from '@vben/common-ui';
-
-import { Input, RadioGroup, Select } from 'ant-design-vue';
-import { BadgeJapaneseYen } from 'lucide-vue-next';
-
-function showPrompt() {
-  prompt({
-    content: '请输入一些东西',
-  })
-    .then((val) => {
-      alert(`已收到你的输入:${val}`);
-    })
-    .catch(() => {
-      alert('Canceled');
-    });
-}
-
-function showSlotsPrompt() {
-  prompt({
-    component: () => {
-      // 获取弹窗上下文。注意:只能在setup或者函数式组件中调用
-      const { doConfirm } = useAlertContext();
-      return h(
-        Input,
-        {
-          onKeydown(e: KeyboardEvent) {
-            if (e.key === 'Enter') {
-              e.preventDefault();
-              // 调用弹窗提供的确认方法
-              doConfirm();
-            }
-          },
-          placeholder: '请输入',
-          prefix: '充值金额:',
-          type: 'number',
-        },
-        {
-          addonAfter: () => h(BadgeJapaneseYen),
-        },
-      );
-    },
-    content:
-      '此弹窗演示了如何使用自定义插槽,并且可以使用useAlertContext获取到弹窗的上下文。\n在输入框中按下回车键会触发确认操作。',
-    icon: 'question',
-    modelPropName: 'value',
-  }).then((val) => {
-    if (val) alert(`你输入的是${val}`);
-  });
-}
-
-function showSelectPrompt() {
-  prompt({
-    component: Select,
-    componentProps: {
-      options: [
-        { label: 'Option A', value: 'Option A' },
-        { label: 'Option B', value: 'Option B' },
-        { label: 'Option C', value: 'Option C' },
-      ],
-      placeholder: '请选择',
-      // 弹窗会设置body的pointer-events为none,这回影响下拉框的点击事件
-      popupClassName: 'pointer-events-auto',
-    },
-    content: '此弹窗演示了如何使用component传递自定义组件',
-    icon: 'question',
-    modelPropName: 'value',
-  }).then((val) => {
-    if (val) {
-      alert(`你选择了${val}`);
-    }
-  });
-}
-
-function sleep(ms: number) {
-  return new Promise((resolve) => setTimeout(resolve, ms));
-}
-
-function showAsyncPrompt() {
-  prompt({
-    async beforeClose(scope) {
-      if (scope.isConfirm) {
-        if (scope.value) {
-          // 模拟异步操作,如果不成功,可以返回false
-          await sleep(2000);
-        } else {
-          alert('请选择一个选项');
-          return false;
-        }
-      }
-    },
-    component: RadioGroup,
-    componentProps: {
-      class: 'flex flex-col',
-      options: [
-        { label: 'Option 1', value: 'option1' },
-        { label: 'Option 2', value: 'option2' },
-        { label: 'Option 3', value: 'option3' },
-      ],
-    },
-    content: '选择一个选项后再点击[确认]',
-    icon: 'question',
-    modelPropName: 'value',
-  }).then((val) => {
-    alert(`${val} 已设置。`);
-  });
-}
-</script>
-<template>
-  <div class="flex gap-4">
-    <VbenButton @click="showPrompt">Prompt</VbenButton>
-    <VbenButton @click="showSlotsPrompt"> Prompt With slots </VbenButton>
-    <VbenButton @click="showSelectPrompt">Prompt With Select</VbenButton>
-    <VbenButton @click="showAsyncPrompt">Prompt With Async</VbenButton>
-  </div>
-</template>

+ 0 - 19
playground/src/api/examples/params.ts

@@ -1,19 +0,0 @@
-import type { Recordable } from '@vben/types';
-
-import { requestClient } from '#/api/request';
-
-/**
- * 发起数组请求
- */
-async function getParamsData(
-  params: Recordable<any>,
-  type: 'brackets' | 'comma' | 'indices' | 'repeat',
-) {
-  return requestClient.get('/status', {
-    params,
-    paramsSerializer: type,
-    responseReturn: 'raw',
-  });
-}
-
-export { getParamsData };

+ 0 - 25
playground/src/api/examples/upload.ts

@@ -1,25 +0,0 @@
-import { requestClient } from '#/api/request';
-
-interface UploadFileParams {
-  file: File;
-  onError?: (error: Error) => void;
-  onProgress?: (progress: { percent: number }) => void;
-  onSuccess?: (data: any, file: File) => void;
-}
-export async function upload_file({
-  file,
-  onError,
-  onProgress,
-  onSuccess,
-}: UploadFileParams) {
-  try {
-    onProgress?.({ percent: 0 });
-
-    const data = await requestClient.upload('/upload', { file });
-
-    onProgress?.({ percent: 100 });
-    onSuccess?.(data, file);
-  } catch (error) {
-    onError?.(error instanceof Error ? error : new Error(String(error)));
-  }
-}

+ 0 - 61
playground/src/views/demos/features/request-params-serializer/index.vue

@@ -1,61 +0,0 @@
-<script lang="ts" setup>
-import { computed, ref, watchEffect } from 'vue';
-
-import { Page } from '@vben/common-ui';
-
-import { Card, Radio, RadioGroup } from 'ant-design-vue';
-
-import { getParamsData } from '#/api/examples/params';
-
-const params = { ids: [2512, 3241, 4255] };
-const paramsSerializer = ref<'brackets' | 'comma' | 'indices' | 'repeat'>(
-  'brackets',
-);
-const response = ref('');
-const paramsStr = computed(() => {
-  // 写一段代码,从完整的URL中提取参数部分
-  const url = response.value;
-  return new URL(url).searchParams.toString();
-});
-
-watchEffect(() => {
-  getParamsData(params, paramsSerializer.value).then((res) => {
-    response.value = res.request.responseURL;
-  });
-});
-</script>
-<template>
-  <Page
-    title="请求参数序列化"
-    description="不同的后台接口可能对数组类型的GET参数的解析方式不同,我们预置了几种数组序列化方式,通过配置 paramsSerializer 来实现不同的序列化方式"
-  >
-    <Card>
-      <RadioGroup v-model:value="paramsSerializer" name="paramsSerializer">
-        <Radio value="brackets">brackets</Radio>
-        <Radio value="comma">comma</Radio>
-        <Radio value="indices">indices</Radio>
-        <Radio value="repeat">repeat</Radio>
-      </RadioGroup>
-      <div class="mt-4 flex flex-col gap-4">
-        <div>
-          <h3>需要提交的参数</h3>
-          <div>{{ JSON.stringify(params, null, 2) }}</div>
-        </div>
-        <template v-if="response">
-          <div>
-            <h3>访问地址</h3>
-            <pre>{{ response }}</pre>
-          </div>
-          <div>
-            <h3>参数字符串</h3>
-            <pre>{{ paramsStr }}</pre>
-          </div>
-          <div>
-            <h3>参数解码</h3>
-            <pre>{{ decodeURIComponent(paramsStr) }}</pre>
-          </div>
-        </template>
-      </div>
-    </Card>
-  </Page>
-</template>

+ 0 - 61
playground/src/views/demos/features/vue-query/concurrency-caching.vue

@@ -1,61 +0,0 @@
-<script lang="ts" setup>
-import type { Recordable } from '@vben/types';
-
-import { useQuery } from '@tanstack/vue-query';
-
-import { useVbenForm } from '#/adapter/form';
-import { getMenuList } from '#/api';
-
-const queryKey = ['demo', 'api', 'options'];
-const count = 4;
-
-const { dataUpdatedAt, promise: fetchDataFn } = useQuery({
-  // 在组件渲染期间预取数据
-  experimental_prefetchInRender: true,
-  // 获取接口数据的函数
-  queryFn: getMenuList,
-  queryKey,
-  // 每次组件挂载时都重新获取数据。如果不需要每次都重新获取就不要设置为always
-  refetchOnMount: 'always',
-  // 缓存时间
-  staleTime: 1000 * 60 * 5,
-});
-
-async function fetchOptions() {
-  return await fetchDataFn.value;
-}
-
-const schema = [];
-
-for (let i = 0; i < count; i++) {
-  schema.push({
-    component: 'ApiSelect',
-    componentProps: {
-      api: fetchOptions,
-      class: 'w-full',
-      filterOption: (input: string, option: Recordable<any>) => {
-        return option.label.toLowerCase().includes(input.toLowerCase());
-      },
-      labelField: 'name',
-      showSearch: true,
-      valueField: 'id',
-    },
-    fieldName: `field${i}`,
-    label: `Select ${i}`,
-  });
-}
-
-const [Form] = useVbenForm({
-  schema,
-  showDefaultActions: false,
-});
-</script>
-<template>
-  <div>
-    <div class="mb-2 flex gap-2">
-      <div>以下{{ count }}个组件共用一个数据源。</div>
-      <div>缓存更新时间:{{ new Date(dataUpdatedAt).toLocaleString() }}</div>
-    </div>
-    <Form />
-  </div>
-</template>