diff --git a/src/components/Designer/src/types/index.ts b/src/components/Designer/src/types/index.ts
index 7316cb5..8347cd7 100644
--- a/src/components/Designer/src/types/index.ts
+++ b/src/components/Designer/src/types/index.ts
@@ -121,6 +121,9 @@ export const basicComponents = [
typeName: t('计数组件'),
type: 'number',
options: {
+ labelWidthMode: 'fix',
+ labelFixWidth: 120,
+ responsive: false,
width: '100%',
span: '',
defaultValue: 0,
@@ -1165,6 +1168,9 @@ export const infoComponents = [
typeName: t('人员选择'),
type: 'user',
options: {
+ labelWidthMode: 'fix',
+ labelFixWidth: 120,
+ responsive: false,
span: '',
width: '100%',
defaultValue: '',
diff --git a/src/components/MultiplePopup/src/MultiplePopup.vue b/src/components/MultiplePopup/src/MultiplePopup.vue
index 9e0c695..02dd58d 100644
--- a/src/components/MultiplePopup/src/MultiplePopup.vue
+++ b/src/components/MultiplePopup/src/MultiplePopup.vue
@@ -1,206 +1,212 @@
-
+
diff --git a/src/utils/http/axios/Axios.ts b/src/utils/http/axios/Axios.ts
index 7ad65f1..af23e83 100644
--- a/src/utils/http/axios/Axios.ts
+++ b/src/utils/http/axios/Axios.ts
@@ -310,11 +310,7 @@ export class VAxios {
})
.catch((e: Error | AxiosError) => {
if (e.message.includes('timeout') || e.message.includes('Network Error')) {
- const userStore = useUserStore();
- userStore.setToken(undefined);
- userStore.setSessionTimeout(false);
- userStore.setUserInfo(null);
- router.push(PageEnum.BASE_LOGIN);
+ // 太极端了,这里没必要给人踢回登录页面
}
if (requestCatchHook && isFunction(requestCatchHook)) {
reject(requestCatchHook(e, opt));
diff --git a/src/utils/http/axios/index.ts b/src/utils/http/axios/index.ts
index 283aa98..62a7ad6 100644
--- a/src/utils/http/axios/index.ts
+++ b/src/utils/http/axios/index.ts
@@ -20,245 +20,255 @@ import { useUserStoreWithOut } from '/@/store/modules/user';
import { AxiosRetry } from '/@/utils/http/axios/axiosRetry';
import { useGo } from '/@/hooks/web/usePage';
import { validateScript } from '/@/utils/event/design';
+import { notification } from 'ant-design-vue';
+import { throttle } from 'lodash-es';
const globSetting = useGlobSetting();
const urlPrefix = globSetting.urlPrefix;
const { createMessage, createErrorModal } = useMessage();
+const showNetworkError = function() {
+ notification.error({
+ message: '网络超时,请检查本地网络是否正常,或者稍后再试',
+ placement: 'topRight',
+ duration: 3
+ });
+};
+
+const trNetworkError = throttle(showNetworkError, 5000, { trailing: false });
+
/**
* @description: 数据处理,方便区分多种处理方式
*/
const transform: AxiosTransform = {
- /**
- * @description: 处理请求数据。如果数据不是预期格式,可直接抛出错误
- */
- transformRequestHook: (res: AxiosResponse, options: RequestOptions) => {
- const { t } = useI18n();
- const { isTransformResponse, isReturnNativeResponse } = options;
- // 是否返回原生响应头 比如:需要获取响应头时使用该属性
- if (isReturnNativeResponse) {
- return res;
- }
- // 不进行任何处理,直接返回
- // 用于页面代码可能需要直接获取code,data,message这些信息时开启
- if (!isTransformResponse) {
- return res.data;
- }
- // 错误的时候返回
-
- const { data: result } = res;
- if (!result) {
- // return '[HTTP] Request has no return value';
- throw new Error(t('请求出错,请稍候重试'));
- }
- // 这里 code,result,message为 后台统一的字段,需要在 types.ts内修改为项目自己的接口返回格式
- const { code, data, msg } = result;
-
- // 这里逻辑可以根据项目进行修改
- const hasSuccess = code === ResultEnum.SUCCESS;
- if (hasSuccess) {
- return data;
- }
-
- // 在此处根据自己项目的实际情况对不同的code执行不同的操作
- // 如果不希望中断当前请求,请return数据,否则直接抛出异常即可
- let timeoutMsg = '';
- switch (code) {
- case ResultEnum.UNAUTHRAZATION:
- timeoutMsg = t('登录超时,请重新登录!');
- const userStore = useUserStoreWithOut();
- userStore.setToken(undefined);
- userStore.logout(true);
- const go = useGo();
- go('/login');
- break;
- default:
- if (msg) {
- timeoutMsg = msg;
+ /**
+ * @description: 处理请求数据。如果数据不是预期格式,可直接抛出错误
+ */
+ transformRequestHook: (res: AxiosResponse, options: RequestOptions) => {
+ const { t } = useI18n();
+ const { isTransformResponse, isReturnNativeResponse } = options;
+ // 是否返回原生响应头 比如:需要获取响应头时使用该属性
+ if (isReturnNativeResponse) {
+ return res;
}
- }
-
- // errorMessageMode=‘modal’的时候会显示modal错误弹窗,而不是消息提示,用于一些比较重要的错误
- // errorMessageMode='none' 一般是调用时明确表示不希望自动弹出错误提示
- if (options.errorMessageMode === 'modal') {
- createErrorModal({ title: t('错误提示'), content: timeoutMsg });
- } else if (options.errorMessageMode === 'message') {
- createMessage.error(timeoutMsg);
- }
-
- throw new Error(timeoutMsg || t('请求出错,请稍候重试'));
- },
-
- // 请求之前处理config
- beforeRequestHook: (config, options) => {
- const { apiUrl, joinPrefix, joinParamsToUrl, formatDate, joinTime = true, urlPrefix } = options;
-
- if (joinPrefix) {
- config.url = `${urlPrefix}${config.url}`;
- }
-
- if (apiUrl && isString(apiUrl)) {
- config.url = `${apiUrl}${config.url}`;
- }
- const params = config.params || {};
- const data = config.data || false;
- formatDate && data && !isString(data) && formatRequestDate(data);
- if (config.method?.toUpperCase() === RequestEnum.GET) {
- if (!isString(params)) {
- // 给 get 请求加上时间戳参数,避免从缓存中拿数据。
- config.params = Object.assign(params || {}, joinTimestamp(joinTime, false));
- } else {
- validateScript(params);
- // 兼容restful风格
- config.url = config.url + params + `${joinTimestamp(joinTime, true)}`;
- config.params = undefined;
- }
- } else {
- if (!isString(params)) {
- formatDate && formatRequestDate(params);
- if (Reflect.has(config, 'data') && config.data && Object.keys(config.data).length > 0) {
- config.data = data;
- config.params = params;
- } else {
- // 非GET请求如果没有提供data,则将params视为data
- config.data = params;
- config.params = undefined;
+ // 不进行任何处理,直接返回
+ // 用于页面代码可能需要直接获取code,data,message这些信息时开启
+ if (!isTransformResponse) {
+ return res.data;
}
- if (isBoolean(joinParamsToUrl) && joinParamsToUrl) {
- config.url = setObjToUrlParams(
- config.url as string,
- Object.assign({}, config.params, config.data),
- );
- }
- } else {
- // 兼容restful风格
- config.url = config.url + params;
- config.params = undefined;
- }
- }
- return config;
- },
+ // 错误的时候返回
+
+ const { data: result } = res;
+ if (!result) {
+ // return '[HTTP] Request has no return value';
+ throw new Error(t('请求出错,请稍候重试'));
+ }
+ // 这里 code,result,message为 后台统一的字段,需要在 types.ts内修改为项目自己的接口返回格式
+ const { code, data, msg } = result;
+
+ // 这里逻辑可以根据项目进行修改
+ const hasSuccess = code === ResultEnum.SUCCESS;
+ if (hasSuccess) {
+ return data;
+ }
+
+ // 在此处根据自己项目的实际情况对不同的code执行不同的操作
+ // 如果不希望中断当前请求,请return数据,否则直接抛出异常即可
+ let timeoutMsg = '';
+ switch (code) {
+ case ResultEnum.UNAUTHRAZATION:
+ timeoutMsg = t('登录超时,请重新登录!');
+ const userStore = useUserStoreWithOut();
+ userStore.setToken(undefined);
+ userStore.logout(true);
+ const go = useGo();
+ go('/login');
+ break;
+ default:
+ if (msg) {
+ timeoutMsg = msg;
+ }
+ }
+
+ // errorMessageMode=‘modal’的时候会显示modal错误弹窗,而不是消息提示,用于一些比较重要的错误
+ // errorMessageMode='none' 一般是调用时明确表示不希望自动弹出错误提示
+ if (options.errorMessageMode === 'modal') {
+ createErrorModal({ title: t('错误提示'), content: timeoutMsg });
+ } else if (options.errorMessageMode === 'message') {
+ createMessage.error(timeoutMsg);
+ }
+
+ throw new Error(timeoutMsg || t('请求出错,请稍候重试'));
+ },
- /**
- * @description: 请求拦截器处理
- */
- requestInterceptors: (config, options) => {
// 请求之前处理config
- const token = getToken();
- if (token && (config as Recordable)?.requestOptions?.withToken !== false) {
- // jwt token
- (config as Recordable).headers.Authorization = options.authenticationScheme
- ? `${options.authenticationScheme} ${token}`
- : token;
- }
- return config;
- },
+ beforeRequestHook: (config, options) => {
+ const { apiUrl, joinPrefix, joinParamsToUrl, formatDate, joinTime = true, urlPrefix } = options;
- /**
- * @description: 响应拦截器处理
- */
- responseInterceptors: (res: AxiosResponse) => {
- return res;
- },
-
- /**
- * @description: 响应错误处理
- */
- responseInterceptorsCatch: (axiosInstance: AxiosResponse, error: any) => {
- const { t } = useI18n();
- const errorLogStore = useErrorLogStoreWithOut();
- errorLogStore.addAjaxErrorInfo(error);
- const { response, code, message, config } = error || {};
- const errorMessageMode = config?.requestOptions?.errorMessageMode || 'none';
- const msg: string = response?.data?.error?.message ?? '';
- const err: string = error?.toString?.() ?? '';
- let errMessage = '';
-
- try {
- if (code === 'ECONNABORTED' && message.indexOf('timeout') !== -1) {
- errMessage = t('接口请求超时,请刷新页面重试!');
- }
- if (err?.includes('Network Error')) {
- errMessage = t('网络异常,请检查您的网络连接是否正常!');
- }
-
- if (errMessage) {
- if (errorMessageMode === 'modal') {
- createErrorModal({ title: t('错误提示'), content: errMessage });
- } else if (errorMessageMode === 'message') {
- createMessage.error(errMessage);
+ if (joinPrefix) {
+ config.url = `${urlPrefix}${config.url}`;
}
+
+ if (apiUrl && isString(apiUrl)) {
+ config.url = `${apiUrl}${config.url}`;
+ }
+ const params = config.params || {};
+ const data = config.data || false;
+ formatDate && data && !isString(data) && formatRequestDate(data);
+ if (config.method?.toUpperCase() === RequestEnum.GET) {
+ if (!isString(params)) {
+ // 给 get 请求加上时间戳参数,避免从缓存中拿数据。
+ config.params = Object.assign(params || {}, joinTimestamp(joinTime, false));
+ } else {
+ validateScript(params);
+ // 兼容restful风格
+ config.url = config.url + params + `${joinTimestamp(joinTime, true)}`;
+ config.params = undefined;
+ }
+ } else {
+ if (!isString(params)) {
+ formatDate && formatRequestDate(params);
+ if (Reflect.has(config, 'data') && config.data && Object.keys(config.data).length > 0) {
+ config.data = data;
+ config.params = params;
+ } else {
+ // 非GET请求如果没有提供data,则将params视为data
+ config.data = params;
+ config.params = undefined;
+ }
+ if (isBoolean(joinParamsToUrl) && joinParamsToUrl) {
+ config.url = setObjToUrlParams(
+ config.url as string,
+ Object.assign({}, config.params, config.data)
+ );
+ }
+ } else {
+ // 兼容restful风格
+ config.url = config.url + params;
+ config.params = undefined;
+ }
+ }
+ return config;
+ },
+
+ /**
+ * @description: 请求拦截器处理
+ */
+ requestInterceptors: (config, options) => {
+ // 请求之前处理config
+ const token = getToken();
+ if (token && (config as Recordable)?.requestOptions?.withToken !== false) {
+ // jwt token
+ (config as Recordable).headers.Authorization = options.authenticationScheme
+ ? `${options.authenticationScheme} ${token}`
+ : token;
+ }
+ return config;
+ },
+
+ /**
+ * @description: 响应拦截器处理
+ */
+ responseInterceptors: (res: AxiosResponse) => {
+ return res;
+ },
+
+ /**
+ * @description: 响应错误处理
+ */
+ responseInterceptorsCatch: (axiosInstance: AxiosResponse, error: any) => {
+ const { t } = useI18n();
+ const errorLogStore = useErrorLogStoreWithOut();
+ errorLogStore.addAjaxErrorInfo(error);
+ const { response, code, message, config } = error || {};
+ const errorMessageMode = config?.requestOptions?.errorMessageMode || 'none';
+ const msg: string = response?.data?.error?.message ?? '';
+ const err: string = error?.toString?.() ?? '';
+ let errMessage = '';
+
+ try {
+ if (code === 'ECONNABORTED' && message.indexOf('timeout') !== -1) {
+ trNetworkError();
+ } else if (err?.includes('Network Error')) {
+ trNetworkError();
+ } else if (errMessage) {
+ if (errorMessageMode === 'modal') {
+ createErrorModal({ title: t('错误提示'), content: errMessage });
+ } else if (errorMessageMode === 'message') {
+ createMessage.error(errMessage);
+ }
+ return Promise.reject(error);
+ }
+ } catch (error) {
+ throw new Error(error as unknown as string);
+ }
+
+ checkStatus(error?.response?.status, msg, errorMessageMode);
+
+ // 添加自动重试机制 保险起见 只针对GET请求
+ const retryRequest = new AxiosRetry();
+ const { isOpenRetry } = config.requestOptions?.retryRequest;
+ config.method?.toUpperCase() === RequestEnum.GET &&
+ isOpenRetry &&
+ // @ts-ignore
+ retryRequest.retry(axiosInstance, error);
return Promise.reject(error);
- }
- } catch (error) {
- throw new Error(error as unknown as string);
}
-
- checkStatus(error?.response?.status, msg, errorMessageMode);
-
- // 添加自动重试机制 保险起见 只针对GET请求
- const retryRequest = new AxiosRetry();
- const { isOpenRetry } = config.requestOptions?.retryRequest;
- config.method?.toUpperCase() === RequestEnum.GET &&
- isOpenRetry &&
- // @ts-ignore
- retryRequest.retry(axiosInstance, error);
- return Promise.reject(error);
- },
};
function createAxios(opt?: Partial) {
- return new VAxios(
- deepMerge(
- {
- // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#authentication_schemes
- // authentication schemes,e.g: Bearer
- // authenticationScheme: 'Bearer',
- authenticationScheme: 'Bearer',
- timeout: 10 * 1000,
- // 基础接口地址
- // baseURL: globSetting.apiUrl,
+ return new VAxios(
+ deepMerge(
+ {
+ // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#authentication_schemes
+ // authentication schemes,e.g: Bearer
+ // authenticationScheme: 'Bearer',
+ authenticationScheme: 'Bearer',
+ timeout: 10 * 1000,
+ // 基础接口地址
+ // baseURL: globSetting.apiUrl,
- headers: { 'Content-Type': ContentTypeEnum.JSON },
- // 如果是form-data格式
- // headers: { 'Content-Type': ContentTypeEnum.FORM_URLENCODED },
- // 数据处理方式
- transform: clone(transform),
- // 配置项,下面的选项都可以在独立的接口请求中覆盖
- requestOptions: {
- // 默认将prefix 添加到url
- joinPrefix: true,
- // 是否返回原生响应头 比如:需要获取响应头时使用该属性
- isReturnNativeResponse: false,
- // 需要对返回数据进行处理
- isTransformResponse: true,
- // post请求的时候添加参数到url
- joinParamsToUrl: false,
- // 格式化提交参数时间
- formatDate: true,
- // 消息提示类型
- errorMessageMode: 'message',
- // 接口地址
- apiUrl: globSetting.apiUrl,
- // 接口拼接地址
- urlPrefix: urlPrefix,
- // 是否加入时间戳
- joinTime: true,
- // 忽略重复请求
- ignoreCancelToken: true,
- // 是否携带token
- withToken: true,
- retryRequest: {
- isOpenRetry: false,
- count: 5,
- waitTime: 100,
- },
- },
- },
- opt || {},
- ),
- );
+ headers: { 'Content-Type': ContentTypeEnum.JSON },
+ // 如果是form-data格式
+ // headers: { 'Content-Type': ContentTypeEnum.FORM_URLENCODED },
+ // 数据处理方式
+ transform: clone(transform),
+ // 配置项,下面的选项都可以在独立的接口请求中覆盖
+ requestOptions: {
+ // 默认将prefix 添加到url
+ joinPrefix: true,
+ // 是否返回原生响应头 比如:需要获取响应头时使用该属性
+ isReturnNativeResponse: false,
+ // 需要对返回数据进行处理
+ isTransformResponse: true,
+ // post请求的时候添加参数到url
+ joinParamsToUrl: false,
+ // 格式化提交参数时间
+ formatDate: true,
+ // 消息提示类型
+ errorMessageMode: 'message',
+ // 接口地址
+ apiUrl: globSetting.apiUrl,
+ // 接口拼接地址
+ urlPrefix: urlPrefix,
+ // 是否加入时间戳
+ joinTime: true,
+ // 忽略重复请求
+ ignoreCancelToken: true,
+ // 是否携带token
+ withToken: true,
+ retryRequest: {
+ isOpenRetry: false,
+ count: 5,
+ waitTime: 100
+ }
+ }
+ },
+ opt || {}
+ )
+ );
}
+
export const defHttp = createAxios();
// other api url