refactor(projects): 文件夹位置规范

This commit is contained in:
Soybean 2021-11-23 10:52:30 +08:00
parent 3fb7a5f709
commit f5a5f44a2b
26 changed files with 60 additions and 192 deletions

View File

@ -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

View File

View File

@ -0,0 +1,2 @@
export * from './service';
export * from './map-sdk';

View File

@ -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
View File

@ -0,0 +1 @@
export * from './common';

View File

@ -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() {

View File

@ -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 }
);
}

View File

@ -1,4 +1,3 @@
import setupAssets from './assets';
import setupWindicssDarkMode from './dark-mode';
export { setupAssets, setupWindicssDarkMode };
export { setupAssets };

View File

@ -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]);
}

View File

@ -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);
}

View File

@ -1,3 +0,0 @@
export * from './transform';
export * from './error';
export * from './handler';

View File

@ -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';

View File

@ -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请求类

View File

@ -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);
}

View File

@ -1,2 +1 @@
export * from './theme';
export * from './sdk';

View File

@ -1,5 +1,3 @@
export * from './typeof';
export * from './color';
export * from './icon';

View File

@ -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';

View File

@ -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;

View File

@ -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>[]
) {

View File

@ -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';

View File

@ -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>([]);

View File

@ -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);

View File

@ -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);

View File

@ -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);