mirror of
				https://github.com/soybeanjs/soybean-admin.git
				synced 2025-11-04 07:43:42 +08:00 
			
		
		
		
	refactor(projects): 文件夹位置规范
This commit is contained in:
		@@ -12,6 +12,24 @@ export function useDarkMode() {
 | 
			
		||||
  /** naive-ui暗黑主题 */
 | 
			
		||||
  const naiveTheme = computed(() => (theme.darkMode ? darkTheme : undefined));
 | 
			
		||||
 | 
			
		||||
  // windicss 暗黑模式
 | 
			
		||||
  const DARK_CLASS = 'dark';
 | 
			
		||||
  function getHtmlElement() {
 | 
			
		||||
    return document.querySelector('html');
 | 
			
		||||
  }
 | 
			
		||||
  function addDarkClass() {
 | 
			
		||||
    const html = getHtmlElement();
 | 
			
		||||
    if (html) {
 | 
			
		||||
      html.classList.add(DARK_CLASS);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  function removeDarkClass() {
 | 
			
		||||
    const html = getHtmlElement();
 | 
			
		||||
    if (html) {
 | 
			
		||||
      html.classList.remove(DARK_CLASS);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // 监听操作系统主题模式
 | 
			
		||||
  watch(
 | 
			
		||||
    osDark,
 | 
			
		||||
@@ -22,6 +40,18 @@ export function useDarkMode() {
 | 
			
		||||
      immediate: true
 | 
			
		||||
    }
 | 
			
		||||
  );
 | 
			
		||||
  // 监听主题的暗黑模式
 | 
			
		||||
  watch(
 | 
			
		||||
    () => theme.darkMode,
 | 
			
		||||
    newValue => {
 | 
			
		||||
      if (newValue) {
 | 
			
		||||
        addDarkClass();
 | 
			
		||||
      } else {
 | 
			
		||||
        removeDarkClass();
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    { immediate: true }
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
    naiveTheme
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										0
									
								
								src/config/business/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								src/config/business/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										2
									
								
								src/config/common/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								src/config/common/index.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
export * from './service';
 | 
			
		||||
export * from './map-sdk';
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
/** 百度地图sdk地址 */
 | 
			
		||||
export const BAIDU_MAP_SDK_URL =
 | 
			
		||||
  'https://api.map.baidu.com/getscript?v=3.0&ak=KSezYymXPth1DIGILRX3oYN9PxbOQQmU&services=&t=20210201100830&s=1';
 | 
			
		||||
 | 
			
		||||
/** 高德地图sdk地址 */
 | 
			
		||||
export const GAODE_MAP_SDK_URL = 'https://webapi.amap.com/maps?v=2.0&key=e7bd02bd504062087e6563daf4d6721d';
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1
									
								
								src/config/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/config/index.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
export * from './common';
 | 
			
		||||
@@ -3,13 +3,11 @@ import App from './App.vue';
 | 
			
		||||
import AppProvider from './AppProvider.vue';
 | 
			
		||||
import { setupStore } from './store';
 | 
			
		||||
import { setupRouter } from './router';
 | 
			
		||||
import { setupAssets, setupWindicssDarkMode } from './plugins';
 | 
			
		||||
import { setupAssets } from './plugins';
 | 
			
		||||
 | 
			
		||||
function setupPlugins() {
 | 
			
		||||
  /** 引入静态资源 */
 | 
			
		||||
  setupAssets();
 | 
			
		||||
  // 配置windicss暗黑主题
 | 
			
		||||
  setupWindicssDarkMode();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function setupApp() {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,36 +0,0 @@
 | 
			
		||||
import { watch } from 'vue';
 | 
			
		||||
import { useThemeStore } from '@/store';
 | 
			
		||||
 | 
			
		||||
export default function setupWindicssDarkMode() {
 | 
			
		||||
  const theme = useThemeStore();
 | 
			
		||||
 | 
			
		||||
  const DARK_CLASS = 'dark';
 | 
			
		||||
 | 
			
		||||
  function getHtmlElement() {
 | 
			
		||||
    return document.querySelector('html');
 | 
			
		||||
  }
 | 
			
		||||
  function addDarkClass() {
 | 
			
		||||
    const html = getHtmlElement();
 | 
			
		||||
    if (html) {
 | 
			
		||||
      html.classList.add(DARK_CLASS);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  function removeDarkClass() {
 | 
			
		||||
    const html = getHtmlElement();
 | 
			
		||||
    if (html) {
 | 
			
		||||
      html.classList.remove(DARK_CLASS);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  watch(
 | 
			
		||||
    () => theme.darkMode,
 | 
			
		||||
    newValue => {
 | 
			
		||||
      if (newValue) {
 | 
			
		||||
        addDarkClass();
 | 
			
		||||
      } else {
 | 
			
		||||
        removeDarkClass();
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    { immediate: true }
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
import setupAssets from './assets';
 | 
			
		||||
import setupWindicssDarkMode from './dark-mode';
 | 
			
		||||
 | 
			
		||||
export { setupAssets, setupWindicssDarkMode };
 | 
			
		||||
export { setupAssets };
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
import { requestMiddleware } from '@/utils';
 | 
			
		||||
import type { ResponseDictionary, Dictionary } from '@/interface';
 | 
			
		||||
import { request, resultMiddleware } from '../request';
 | 
			
		||||
import { request } from '../request';
 | 
			
		||||
import { fecthDictionaryMiddleware } from '../middleware';
 | 
			
		||||
 | 
			
		||||
// 接口示例
 | 
			
		||||
@@ -23,5 +24,5 @@ export async function fetchDictionaryWithMiddleware(keyword: string) {
 | 
			
		||||
    indiCatorName: keyword
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  return resultMiddleware<Dictionary[]>(fecthDictionaryMiddleware, [res]);
 | 
			
		||||
  return requestMiddleware<Dictionary[]>(fecthDictionaryMiddleware, [res]);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +0,0 @@
 | 
			
		||||
import type { AxiosRequestConfig } from 'axios';
 | 
			
		||||
import CustomAxiosInstance from './instance';
 | 
			
		||||
import Request from './request';
 | 
			
		||||
 | 
			
		||||
export function createRequest(axiosConfig: AxiosRequestConfig) {
 | 
			
		||||
  const customInstance = new CustomAxiosInstance(axiosConfig);
 | 
			
		||||
  return new Request(customInstance.instance);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
export * from './transform';
 | 
			
		||||
export * from './error';
 | 
			
		||||
export * from './handler';
 | 
			
		||||
@@ -1,9 +1,7 @@
 | 
			
		||||
import { createRequest } from './axios';
 | 
			
		||||
import { REQUEST_TIMEOUT } from './config';
 | 
			
		||||
import { REQUEST_TIMEOUT } from '@/config';
 | 
			
		||||
import { createRequest } from './request';
 | 
			
		||||
 | 
			
		||||
export const request = createRequest({
 | 
			
		||||
  baseURL: import.meta.env.VITE_HTTP_URL,
 | 
			
		||||
  timeout: REQUEST_TIMEOUT
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export { resultMiddleware } from './helpers';
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,7 @@
 | 
			
		||||
import axios from 'axios';
 | 
			
		||||
import type { AxiosRequestConfig, AxiosInstance, AxiosError, CancelTokenStatic } from 'axios';
 | 
			
		||||
import { getToken } from '@/utils';
 | 
			
		||||
import { getToken, transformRequestData, handleAxiosError, handleResponseError, handleBackendError } from '@/utils';
 | 
			
		||||
import type { BackendServiceResult } from '@/interface';
 | 
			
		||||
import { transformRequestData, handleAxiosError, handleResponseError, handleBackendError } from '../helpers';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 封装axios请求类
 | 
			
		||||
@@ -1,11 +1,12 @@
 | 
			
		||||
import type { AxiosRequestConfig, AxiosInstance, AxiosResponse } from 'axios';
 | 
			
		||||
import type { RequestServiceError, CustomSuccessRequestResult, CustomFailRequestResult } from '@/interface';
 | 
			
		||||
import CustomAxiosInstance from './instance';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 封装各个请求方法及结果处理的类
 | 
			
		||||
 * @author Soybean<honghuangdc@gmail.com>
 | 
			
		||||
 */
 | 
			
		||||
export default class Request {
 | 
			
		||||
export class Request {
 | 
			
		||||
  instance: AxiosInstance;
 | 
			
		||||
 | 
			
		||||
  constructor(instance: AxiosInstance) {
 | 
			
		||||
@@ -58,3 +59,8 @@ export default class Request {
 | 
			
		||||
      .catch(Request.failHandler);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function createRequest(axiosConfig: AxiosRequestConfig) {
 | 
			
		||||
  const customInstance = new CustomAxiosInstance(axiosConfig);
 | 
			
		||||
  return new Request(customInstance.instance);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,2 +1 @@
 | 
			
		||||
export * from './theme';
 | 
			
		||||
export * from './sdk';
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,3 @@
 | 
			
		||||
export * from './typeof';
 | 
			
		||||
 | 
			
		||||
export * from './color';
 | 
			
		||||
 | 
			
		||||
export * from './icon';
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
export * from './auth';
 | 
			
		||||
export * from './common';
 | 
			
		||||
export * from './storage';
 | 
			
		||||
export * from './router';
 | 
			
		||||
export * from './service';
 | 
			
		||||
export * from './package';
 | 
			
		||||
export * from './auth';
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@ import {
 | 
			
		||||
  REQUEST_TIMEOUT_CODE,
 | 
			
		||||
  REQUEST_TIMEOUT_MSG,
 | 
			
		||||
  ERROR_STATUS
 | 
			
		||||
} from '../config';
 | 
			
		||||
} from '@/config';
 | 
			
		||||
import { showErrorMsg } from './msg';
 | 
			
		||||
 | 
			
		||||
type ErrorStatus = keyof typeof ERROR_STATUS;
 | 
			
		||||
@@ -6,7 +6,7 @@ type ResultHandler<T> = (...arg: any) => T;
 | 
			
		||||
 * @param resultHandler - 处理函数
 | 
			
		||||
 * @param requests - 请求结果
 | 
			
		||||
 */
 | 
			
		||||
export function resultMiddleware<MiddlewareData>(
 | 
			
		||||
export function requestMiddleware<MiddlewareData>(
 | 
			
		||||
  resultHandler: ResultHandler<MiddlewareData>,
 | 
			
		||||
  requests: CustomRequestResult<any>[]
 | 
			
		||||
) {
 | 
			
		||||
@@ -1,121 +1,3 @@
 | 
			
		||||
import FormData from 'form-data';
 | 
			
		||||
import { isArray } from '../common';
 | 
			
		||||
 | 
			
		||||
type HandleFunc<T> = (...arg: any) => T;
 | 
			
		||||
type RequestError = any;
 | 
			
		||||
type RequestData = any;
 | 
			
		||||
type RequestResult = [RequestError, RequestData];
 | 
			
		||||
/**
 | 
			
		||||
 * 对请求的结果数据进行格式化的处理
 | 
			
		||||
 * @param handleFunc - 处理函数
 | 
			
		||||
 * @param requests - 请求结果
 | 
			
		||||
 */
 | 
			
		||||
export function handleResponse<T>(handleFunc: HandleFunc<T>, ...requests: RequestResult[]) {
 | 
			
		||||
  let handleData: any = null;
 | 
			
		||||
  let error: any = null;
 | 
			
		||||
  const hasError = requests.some(item => {
 | 
			
		||||
    const isError = Boolean(item[0]);
 | 
			
		||||
    if (isError) {
 | 
			
		||||
      [error] = item;
 | 
			
		||||
    }
 | 
			
		||||
    return isError;
 | 
			
		||||
  });
 | 
			
		||||
  if (!hasError) {
 | 
			
		||||
    handleData = handleFunc(...requests.map(item => item[1]));
 | 
			
		||||
  }
 | 
			
		||||
  return [error, handleData] as [any, T];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 接口为上传文件的类型时数据转换
 | 
			
		||||
 * @param file - 单文件或多文件
 | 
			
		||||
 * @param key - 文件的属性名
 | 
			
		||||
 */
 | 
			
		||||
export async function transformFile(file: File[] | File, key: string) {
 | 
			
		||||
  const formData = new FormData();
 | 
			
		||||
  if (isArray(file)) {
 | 
			
		||||
    await Promise.all(
 | 
			
		||||
      (file as File[]).map(item => {
 | 
			
		||||
        formData.append(key, item);
 | 
			
		||||
        return true;
 | 
			
		||||
      })
 | 
			
		||||
    );
 | 
			
		||||
  } else {
 | 
			
		||||
    await formData.append(key, file);
 | 
			
		||||
  }
 | 
			
		||||
  return formData;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const ERROR_STATUS = {
 | 
			
		||||
  400: '400: 请求出现语法错误',
 | 
			
		||||
  401: '401: 用户未授权~',
 | 
			
		||||
  403: '403: 服务器拒绝访问~',
 | 
			
		||||
  404: '404: 请求的资源不存在~',
 | 
			
		||||
  405: '405: 请求方法未允许~',
 | 
			
		||||
  408: '408: 网络请求超时~',
 | 
			
		||||
  500: '500: 服务器内部错误~',
 | 
			
		||||
  501: '501: 服务器未实现请求功能~',
 | 
			
		||||
  502: '502: 错误网关~',
 | 
			
		||||
  503: '503: 服务不可用~',
 | 
			
		||||
  504: '504: 网关超时~',
 | 
			
		||||
  505: '505: http版本不支持该请求~'
 | 
			
		||||
};
 | 
			
		||||
type ErrorStatus = keyof typeof ERROR_STATUS;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 网络请求错误状态处理
 | 
			
		||||
 * @param error - 错误
 | 
			
		||||
 */
 | 
			
		||||
export function errorHandler(error: any): void {
 | 
			
		||||
  const { $message: Message } = window;
 | 
			
		||||
  if (error.response) {
 | 
			
		||||
    const status = error.response.status as ErrorStatus;
 | 
			
		||||
    Message?.error(ERROR_STATUS[status]);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  if (error.code === 'ECONNABORTED' && error.message.includes('timeout')) {
 | 
			
		||||
    Message?.error('网络连接超时~');
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  if (!window.navigator.onLine || error.message === 'Network Error') {
 | 
			
		||||
    Message?.error('网络不可用~');
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  Message?.error('请求错误~');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 连续的请求错误依此显示
 | 
			
		||||
 * @param duration - 上一次弹出错误消息到下一次的时间(ms)
 | 
			
		||||
 */
 | 
			
		||||
export function continuousErrorHandler(duration: number) {
 | 
			
		||||
  let errorStacks: string[] = [];
 | 
			
		||||
  function pushError(id: string) {
 | 
			
		||||
    errorStacks.push(id);
 | 
			
		||||
  }
 | 
			
		||||
  function removeError(id: string) {
 | 
			
		||||
    errorStacks = errorStacks.filter(item => item !== id);
 | 
			
		||||
  }
 | 
			
		||||
  function handleError(id: string, callback: Function) {
 | 
			
		||||
    callback();
 | 
			
		||||
    setTimeout(() => {
 | 
			
		||||
      removeError(id);
 | 
			
		||||
    }, duration);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function handleContinuousError(callback: Function) {
 | 
			
		||||
    const id = Date.now().toString(36);
 | 
			
		||||
    const { length } = errorStacks;
 | 
			
		||||
    if (length > 0) {
 | 
			
		||||
      pushError(id);
 | 
			
		||||
      setTimeout(() => {
 | 
			
		||||
        handleError(id, callback);
 | 
			
		||||
      }, duration * length);
 | 
			
		||||
    } else {
 | 
			
		||||
      pushError(id);
 | 
			
		||||
      handleError(id, callback);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return handleContinuousError;
 | 
			
		||||
}
 | 
			
		||||
export * from './transform';
 | 
			
		||||
export * from './error';
 | 
			
		||||
export * from './handler';
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
import type { RequestServiceError } from '@/interface';
 | 
			
		||||
import { NO_ERROR_MSG_CODE, ERROR_MSG_DURATION } from '../config';
 | 
			
		||||
import { NO_ERROR_MSG_CODE, ERROR_MSG_DURATION } from '@/config';
 | 
			
		||||
 | 
			
		||||
/** 错误消息栈,防止同一错误同时出现 */
 | 
			
		||||
const errorMsgStack = new Map<string | number, string>([]);
 | 
			
		||||
@@ -5,7 +5,7 @@
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { ref, onMounted } from 'vue';
 | 
			
		||||
import { useScriptTag } from '@vueuse/core';
 | 
			
		||||
import { BAIDU_MAP_SDK_URL } from '@/settings';
 | 
			
		||||
import { BAIDU_MAP_SDK_URL } from '@/config';
 | 
			
		||||
 | 
			
		||||
const { load } = useScriptTag(BAIDU_MAP_SDK_URL);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { ref, onMounted } from 'vue';
 | 
			
		||||
import { useScriptTag } from '@vueuse/core';
 | 
			
		||||
import { GAODE_MAP_SDK_URL } from '@/settings';
 | 
			
		||||
import { GAODE_MAP_SDK_URL } from '@/config';
 | 
			
		||||
 | 
			
		||||
const { load } = useScriptTag(GAODE_MAP_SDK_URL);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { ref, onMounted } from 'vue';
 | 
			
		||||
import { useScriptTag } from '@vueuse/core';
 | 
			
		||||
import { TENCENT_MAP_SDK_URL } from '@/settings';
 | 
			
		||||
import { TENCENT_MAP_SDK_URL } from '@/config';
 | 
			
		||||
 | 
			
		||||
const { load } = useScriptTag(TENCENT_MAP_SDK_URL);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user