build(projects): 依赖升级,规范目录

This commit is contained in:
Soybean
2021-08-13 14:22:35 +08:00
parent d680e7d931
commit a0ec84588a
29 changed files with 857 additions and 561 deletions

0
src/enum/business.ts Normal file
View File

6
src/enum/common.ts Normal file
View File

@ -0,0 +1,6 @@
/** 请求头的content-type类型 */
export enum ContentType {
json = 'application/json',
formUrlencoded = 'application/x-www-form-urlencoded',
formData = 'multipart/form-data'
}

1
src/enum/index.ts Normal file
View File

@ -0,0 +1 @@
export { ContentType } from './common';

0
src/hooks/index.ts Normal file
View File

View File

@ -0,0 +1,9 @@
/** 用户信息 */
export interface UserInfo {
/** 用户id */
userId: string;
/** 用户名 */
userName: string;
/** 用户手机号 */
userPhone: string;
}

1
src/interface/index.ts Normal file
View File

@ -0,0 +1 @@
export { UserInfo } from './business';

0
src/layouts/index.ts Normal file
View File

View File

@ -4,8 +4,8 @@ import { setupSmoothScroll, setupElementPlus } from './plugins';
import 'virtual:windi.css';
import './styles/css/global.css';
setupSmoothScroll();
const app = createApp(App);
setupSmoothScroll();
setupElementPlus(app);
app.mount('#app');

0
src/router/index.ts Normal file
View File

View File

@ -14,10 +14,7 @@ const ERROR_STATUS = {
504: '504: 网关超时~',
505: '505: http版本不支持该请求~'
};
type ErrorStatus = 400 | 401 | 403 | 404 | 405 | 408 | 500 | 501 | 502 | 503 | 504 | 505;
/** 错误信息显示时间 */
export const errorDuration = 3000 / 1000;
type ErrorStatus = keyof typeof ERROR_STATUS;
/**
* 网络请求错误状态处理
@ -37,7 +34,7 @@ export function errorHandler(error: any): void {
ElMessage.error('网络不可用~');
return;
}
ElMessage.error('未知错误~');
ElMessage.error('请求错误~');
}
/**

View File

@ -1,10 +1,6 @@
import { createRequest } from './request';
import { REQUEST_TIMEOUT, ContentType } from './config';
import { REQUEST_TIMEOUT } from './config';
export { handleResponse } from './request';
export { ContentType };
// emoss-admin
export const adminRequest = createRequest({
baseURL: import.meta.env.VITE_HTTP_URL_EMOSS_ADMIN as string,
timeout: REQUEST_TIMEOUT

View File

@ -1,9 +1,11 @@
import axios from 'axios';
import qs from 'qs';
import { getStorageToken } from '@/utils';
import { ElMessage } from 'element-plus';
import type { AxiosRequestConfig, AxiosInstance } from 'axios';
import { ContentType } from '@/enum';
import { getStorageToken } from '@/utils';
import { errorHandler } from './errorHandler';
import { transformFile } from '../utils';
export interface StatusConfig {
/** 表明请求状态的属性key */
@ -37,15 +39,20 @@ export default class CustomAxiosInstance {
/** 设置请求拦截器 */
setInterceptor(statusConfig: StatusConfig): void {
this.instance.interceptors.request.use(
config => {
async config => {
const handleConfig = { ...config };
// content-type为application/x-www-form-urlencoded类型的data参数需要序列化
if (handleConfig.headers['Content-Type'] === 'application/x-www-form-urlencoded') {
// form类型转换
if (handleConfig.headers['Content-Type'] === ContentType.formUrlencoded) {
handleConfig.data = qs.stringify(handleConfig.data);
}
// 文件类型转换
if (handleConfig.headers['Content-Type'] === ContentType.formData) {
const key = Object.keys(handleConfig.data)[0];
const file = handleConfig.data[key];
handleConfig.data = await transformFile(file, key);
}
// 设置token
handleConfig.headers.Authorization = getStorageToken();
return handleConfig;
},
error => {

View File

@ -49,18 +49,3 @@ export function createRequest(axiosConfig: AxiosRequestConfig, statusConfig?: St
const request = new Request(customInstance.instance);
return request;
}
/**
* 对请求的结果数据进行格式化的处理
* @param handleFunc - 处理函数
* @param errors - 接收多个请求的错误
* @param datas - 接收多个请求的数据
*/
export function handleResponse<T>(handleFunc: Function, errors: any[], datas: any[]) {
let handleData = null;
if (errors.every(error => !error)) {
handleData = handleFunc(...datas);
}
const resError = errors.find(error => Boolean(error));
return [resError, handleData] as [any, T];
}

View File

@ -0,0 +1,45 @@
import FormData from 'form-data';
import { isArray } from '@/utils';
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];
}
/**
* 接口为上传文件的类型时数据转换
*/
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;
}

View File

@ -1,10 +1,10 @@
import type { App } from 'vue';
import { createAuthStore, useAuthStore } from './modules/auth';
import { createAsideStore, useAsideStore } from './modules/aside';
import { createPinia } from 'pinia';
export function createStore(app: App) {
createAuthStore(app);
createAsideStore(app);
export const store = createPinia();
export function setupStore(app: App) {
app.use(store);
}
export { useAuthStore, useAsideStore };
export { useAppStore, useAuthStore } from './modules';

View File

@ -0,0 +1,26 @@
import { defineStore } from 'pinia';
import { store } from '../../index';
interface AppState {
/** 侧边栏折叠 */
asideCollapse: boolean;
}
const appStore = defineStore({
id: 'app-store',
state: (): AppState => ({
asideCollapse: false
}),
actions: {
handleAsideCollapse(collapse: boolean) {
this.asideCollapse = collapse;
},
toggleAside() {
this.asideCollapse = !this.asideCollapse;
}
}
});
export default function useAppStore() {
return appStore(store);
}

View File

@ -1,33 +0,0 @@
import { inject, reactive } from 'vue';
import type { App, InjectionKey } from 'vue';
interface AsideState {
collapse: boolean;
}
interface AsideStore {
/** aside状态 */
asideState: AsideState;
/** 切换collapse */
toggle: () => void;
}
const injectKey: InjectionKey<AsideStore> = Symbol('aside-store');
export function createAsideStore(app: App) {
const state = reactive<AsideState>({
collapse: false
});
function toggle() {
state.collapse = !state.collapse;
}
const provideData: AsideStore = {
asideState: state,
toggle
};
app.provide(injectKey, provideData);
}
export function useAsideStore() {
return inject(injectKey)!;
}

View File

@ -1,44 +1,40 @@
import { computed, inject, reactive } from 'vue';
import type { ComputedRef, App, InjectionKey } from 'vue';
interface UserInfo {
userId: string;
userName: string;
userPhone: string;
}
import { defineStore } from 'pinia';
import type { UserInfo } from '@/interface';
import { store } from '../../index';
interface AuthState {
/** 用户token */
token: string;
/** 用户信息 */
userInfo: UserInfo;
}
interface AuthStore {
/** auth状态 */
authState: AuthState;
/** 是否登录 */
isLogin: ComputedRef<boolean>;
}
const injectKey: InjectionKey<AuthStore> = Symbol('auth-store');
export function createAuthStore(app: App) {
const state = reactive<AuthState>({
token: '',
userInfo: {
userId: '',
userName: '',
userPhone: ''
const authStore = defineStore({
/** 区分不通状态的唯一标识 */
id: 'auth-store',
/** 状态 */
state: (): AuthState => {
return {
token: '',
userInfo: {
userId: '',
userName: '',
userPhone: ''
}
};
},
getters: {
/** 是否登录 */
isLogin: state => Boolean(state.token)
},
actions: {
/** 重置auth状态 */
resetAuthState() {
this.$reset();
}
});
const isLogin = computed(() => Boolean(state.token));
}
});
const provideData: AuthStore = {
authState: state,
isLogin
};
app.provide(injectKey, provideData);
}
export function useAuthStore() {
return inject(injectKey)!;
export default function useAuthStore() {
return authStore(store);
}

View File

@ -0,0 +1,4 @@
import useAppStore from './app';
import useAuthStore from './auth';
export { useAppStore, useAuthStore };

13
src/utils/common/index.ts Normal file
View File

@ -0,0 +1,13 @@
export {
isNumber,
isString,
isBoolean,
isNull,
isUndefined,
isObject,
isArray,
isDate,
isRegExp,
isSet,
isMap
} from './typeof';

View File

@ -0,0 +1,47 @@
enum DataType {
number = '[object Number]',
string = '[object String]',
boolean = '[object Object]',
null = '[object Null]',
undefined = '[object Undefined]',
object = '[object Object]',
array = '[object Array]',
date = '[object Date]',
regexp = '[object RegExp]',
set = '[object Set]',
map = '[object Map]'
}
export function isNumber(data: any) {
return Object.prototype.toString.call(data) === DataType.number;
}
export function isString(data: any) {
return Object.prototype.toString.call(data) === DataType.string;
}
export function isBoolean(data: any) {
return Object.prototype.toString.call(data) === DataType.boolean;
}
export function isNull(data: any) {
return Object.prototype.toString.call(data) === DataType.null;
}
export function isUndefined(data: any) {
return Object.prototype.toString.call(data) === DataType.undefined;
}
export function isObject(data: any) {
return Object.prototype.toString.call(data) === DataType.object;
}
export function isArray(data: any) {
return Object.prototype.toString.call(data) === DataType.array;
}
export function isDate(data: any) {
return Object.prototype.toString.call(data) === DataType.date;
}
export function isRegExp(data: any) {
return Object.prototype.toString.call(data) === DataType.regexp;
}
export function isSet(data: any) {
return Object.prototype.toString.call(data) === DataType.set;
}
export function isMap(data: any) {
return Object.prototype.toString.call(data) === DataType.map;
}

View File

@ -1 +1,14 @@
export { getStorageToken, getStorageUserInfo } from './auth';
export {
isNumber,
isString,
isBoolean,
isNull,
isUndefined,
isObject,
isArray,
isDate,
isRegExp,
isSet,
isMap
} from './common';

View File

View File