This commit is contained in:
dap
2025-05-25 11:48:58 +08:00
24 changed files with 357 additions and 66 deletions

View File

@@ -48,8 +48,12 @@
"@vueuse/core": "catalog:",
"ant-design-vue": "catalog:",
"dayjs": "catalog:",
"json-bigint": "catalog:",
"pinia": "catalog:",
"vue": "catalog:",
"vue-router": "catalog:"
},
"devDependencies": {
"@types/json-bigint": "catalog:"
}
}

View File

@@ -8,38 +8,40 @@ import type { ComponentType } from './component';
import { setupVbenForm, useVbenForm as useForm, z } from '@vben/common-ui';
import { $t } from '@vben/locales';
setupVbenForm<ComponentType>({
config: {
// ant design vue组件库默认都是 v-model:value
baseModelPropName: 'value',
// 一些组件是 v-model:checked 或者 v-model:fileList
modelPropNameMap: {
Checkbox: 'checked',
Radio: 'checked',
Switch: 'checked',
Upload: 'fileList',
async function initSetupVbenForm() {
setupVbenForm<ComponentType>({
config: {
// ant design vue组件库默认都是 v-model:value
baseModelPropName: 'value',
// 一些组件是 v-model:checked 或者 v-model:fileList
modelPropNameMap: {
Checkbox: 'checked',
Radio: 'checked',
Switch: 'checked',
Upload: 'fileList',
},
},
},
defineRules: {
// 输入项目必填国际化适配
required: (value, _params, ctx) => {
if (value === undefined || value === null || value.length === 0) {
return $t('ui.formRules.required', [ctx.label]);
}
return true;
defineRules: {
// 输入项目必填国际化适配
required: (value, _params, ctx) => {
if (value === undefined || value === null || value.length === 0) {
return $t('ui.formRules.required', [ctx.label]);
}
return true;
},
// 选择项目必填国际化适配
selectRequired: (value, _params, ctx) => {
if (value === undefined || value === null) {
return $t('ui.formRules.selectRequired', [ctx.label]);
}
return true;
},
},
// 选择项目必填国际化适配
selectRequired: (value, _params, ctx) => {
if (value === undefined || value === null) {
return $t('ui.formRules.selectRequired', [ctx.label]);
}
return true;
},
},
});
});
}
const useVbenForm = useForm<ComponentType>;
export { useVbenForm, z };
export { initSetupVbenForm, useVbenForm, z };
export type VbenFormSchema = FormSchema<ComponentType>;
export type { VbenFormProps };

View File

@@ -0,0 +1,10 @@
import { requestClient } from '#/api/request';
/**
* 发起请求
*/
async function getBigIntData() {
return requestClient.get('/demo/bigint');
}
export { getBigIntData };

View File

@@ -1,7 +1,7 @@
/**
* 该文件可自行根据业务逻辑进行调整
*/
import type { RequestClientOptions } from '@vben/request';
import type { AxiosResponseHeaders, RequestClientOptions } from '@vben/request';
import { useAppConfig } from '@vben/hooks';
import { preferences } from '@vben/preferences';
@@ -12,8 +12,10 @@ import {
RequestClient,
} from '@vben/request';
import { useAccessStore } from '@vben/stores';
import { cloneDeep } from '@vben/utils';
import { message } from 'ant-design-vue';
import JSONBigInt from 'json-bigint';
import { useAuthStore } from '#/store';
@@ -25,6 +27,14 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
const client = new RequestClient({
...options,
baseURL,
transformResponse: (data: any, header: AxiosResponseHeaders) => {
// storeAsString指示将BigInt存储为字符串设为false则会存储为内置的BigInt类型
return header.getContentType()?.toString().includes('application/json')
? cloneDeep(
JSONBigInt({ storeAsString: true, strict: true }).parse(data),
)
: data;
},
});
/**

View File

@@ -13,12 +13,16 @@ import { $t, setupI18n } from '#/locales';
import { router } from '#/router';
import { initComponentAdapter } from './adapter/component';
import { initSetupVbenForm } from './adapter/form';
import App from './app.vue';
async function bootstrap(namespace: string) {
// 初始化组件适配器
await initComponentAdapter();
// 初始化表单组件
await initSetupVbenForm();
// 设置弹窗的默认配置
// setDefaultModalProps({
// fullscreenButton: false,

View File

@@ -255,6 +255,16 @@ const routes: RouteRecordRaw[] = [
title: $t('demos.features.requestParamsSerializer'),
},
},
{
name: 'BigIntDemo',
path: '/demos/features/json-bigint',
component: () =>
import('#/views/demos/features/json-bigint/index.vue'),
meta: {
icon: 'lucide:grape',
title: 'JSON BigInt',
},
},
],
},
// 面包屑导航

View File

@@ -0,0 +1,39 @@
<script lang="ts" setup>
import { ref } from 'vue';
import { Page } from '@vben/common-ui';
import { Alert, Button, Card } from 'ant-design-vue';
import { getBigIntData } from '#/api/examples/json-bigint';
const response = ref('');
function fetchData() {
getBigIntData().then((res) => {
response.value = res;
});
}
</script>
<template>
<Page
title="JSON BigInt Support"
description="解析后端返回的长整数long/bigInt。代码位置playground/src/api/request.ts中的transformResponse"
>
<Card>
<Alert>
<template #message>
有些后端接口返回的ID是长整数但javascript原生的JSON解析是不支持超过2^53-1的长整数的
这种情况可以建议后端返回数据前将长整数转换为字符串类型如果后端不接受我们的建议😡
<br />
下面的按钮点击后会发起请求接口返回的JSON数据中的id字段是超出整数范围的数字已自动将其解析为字符串
</template>
</Alert>
<Button class="mt-4" type="primary" @click="fetchData">发起请求</Button>
<div>
<pre>
{{ response }}
</pre>
</div>
</Card>
</Page>
</template>