feat: 优化目录结构

master
绝弹 2023-09-05 20:05:14 +08:00
parent 822ec89eb4
commit 47fc92ebc7
27 changed files with 108 additions and 130 deletions

View File

@ -42,7 +42,6 @@
"typescript": "^4.6.4",
"unocss": "^0.49.4",
"unplugin-auto-import": "^0.13.0",
"unplugin-icons": "^0.15.2",
"unplugin-vue-components": "^0.23.0",
"vite": "^4.3.9",
"vite-plugin-mock": "^3.0.0",

View File

@ -67,43 +67,25 @@ export default function plugin(): Plugin {
configResolved(resolvedConfig) {
config = resolvedConfig;
const defaultExt = config.mode === "development" ? "dev" : "prod";
extension = config.env.VITE_EXTENTION || defaultExt;
extension = config.env.VITE_EXTENTION ?? config.isProduction ? "prod" : "dev";
},
async transformIndexHtml(html) {
async transformIndexHtml() {
const script = await getBuildInfo();
const replacedHtml = html.replace(/__((\w|_|-)+)__/g, (match, p1) => {
return config.env[`VITE_${p1}`] || "";
});
return {
html: replacedHtml,
tags: [
return [
{
tag: "script",
injectTo: "body",
children: script,
},
],
};
},
async resolveId(id, importer, options) {
if (!extension || !id.startsWith("/src")) {
return;
}
const resolution = await this.resolve(id, importer, { skipSelf: true, ...options });
const targetPath = resolution?.id.replace(/\.([^.]*?)$/, `.${extension}.$1`);
if (targetPath && fs.existsSync(targetPath)) {
return targetPath;
}
];
},
load(id) {
if (!extension || !id.includes("src")) {
return;
}
if (id.includes("?")) {
if (id.includes("?vue")) {
return;
}
const targetPath = id.replace(/\.([^.]*?)$/, `.${extension}.$1`);

View File

@ -1,7 +1,7 @@
<template>
<a-config-provider>
<router-view v-slot="{ Component }">
<page-403 v-if="Math.random() > 0.99"></page-403>
<page-403 v-if="Math.random() > 0.999"></page-403>
<component v-else :is="Component"></component>
</router-view>
</a-config-provider>

View File

@ -1,9 +1,9 @@
import { extendEnum } from "@/utils";
import { Constant } from "@/utils";
/**
*
*/
enum GenderEnum {
enum Gender {
/**
*
*/
@ -21,22 +21,23 @@ enum GenderEnum {
/**
*
*/
const GenderDict = extendEnum(GenderEnum, [
const GenderDict = Constant.from([
{
value: GenderEnum.Man,
value: Gender.Man,
label: "男",
color: "blue",
},
{
value: GenderEnum.Famale,
value: Gender.Famale,
label: "女",
color: "pink",
},
{
value: GenderEnum.Secret,
value: Gender.Secret,
label: "保密",
color: "gray",
},
]);
export { GenderEnum, GenderDict };
export { Gender, GenderDict };

View File

@ -84,10 +84,11 @@ const isCollapsed = ref(false);
const route = useRoute();
const router = useRouter();
const themeConfig = ref({ visible: false });
const isDev = import.meta.env.DEV
const onCollapse = (val: boolean) => {
isCollapsed.value = val;
};
const isDev = import.meta.env.DEV
const buttons = [
{

View File

@ -56,7 +56,7 @@
<script lang="ts" setup>
import { api } from "@/api";
import { dayjs } from "@/plugins";
import { dayjs } from "@/libs";
import { useAppStore, useUserStore } from "@/store";
import { FieldRule, Form, Message, Modal } from "@arco-design/web-vue";
import { reactive } from "vue";

View File

@ -7,7 +7,7 @@
<script setup lang="tsx">
import { ContentType, api } from "@/api";
import { Table, useTable } from "@/components";
import { dayjs } from "@/plugins";
import { dayjs } from "@/libs/dayjs";
import { Avatar } from "@arco-design/web-vue";
const url = ref<any>(null);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 381 KiB

View File

@ -54,9 +54,6 @@
</template>
<script setup lang="tsx" name="PostPage">
import { api } from "@/api";
import { Table, useTable } from "@/components";
import { dayjs } from "@/plugins";
</script>
<style lang="less">

View File

@ -26,7 +26,7 @@
<div
v-for="item in exportTypes"
@click="model.exportType = item.name"
class="w-full flex justify-between items-center gap-4 rounded py-2 px-4 border border-transparent cursor-pointer"
class="w-full flex justify-between items-center gap-4 rounded py-2 px-4 border cursor-pointer border-slate-200"
:class="{
'!border-brand-500': model.exportType === item.name,
}"
@ -53,9 +53,7 @@
</a-form>
</a-modal>
<a-modal title="导入文件" :visible="false" title-align="start">
<a-alert>
请按照 <a-link>上传模板</a-link>
</a-alert>
<a-alert> 请按照 <a-link>上传模板</a-link> </a-alert>
<a-upload draggable class="mt-4"></a-upload>
</a-modal>
</div>
@ -64,7 +62,7 @@
<script setup lang="tsx" name="PostPage">
import { api } from "@/api";
import { Table, useTable } from "@/components";
import { dayjs } from "@/plugins";
import { dayjs } from "@/libs";
const table = useTable({
data: async (model, paging) => {

View File

@ -7,7 +7,7 @@
<script setup lang="tsx">
import { api } from "@/api";
import { Table, useTable } from "@/components";
import { dayjs } from "@/plugins";
import { dayjs } from "@/libs";
import { Avatar, Button } from "@arco-design/web-vue";
const table = useTable({

View File

@ -7,7 +7,7 @@
<script setup lang="tsx">
import { api } from "@/api";
import { Table, useTable } from "@/components";
import { dayjs } from "@/plugins";
import { dayjs } from "@/libs";
const table = useTable({
data: async (model, paging) => {

View File

@ -7,7 +7,7 @@
<script setup lang="tsx">
import { api } from "@/api";
import { Table, useTable } from "@/components";
import { dayjs } from "@/plugins";
import { dayjs } from "@/libs";
const table = useTable({
data: async (model, paging) => {

View File

@ -14,8 +14,8 @@
<script setup lang="tsx">
import { api } from "@/api";
import { Table, useTable } from "@/components";
import { dayjs } from "@/plugins";
import { Avatar, Button } from "@arco-design/web-vue";
import { dayjs } from "@/libs";
import { Avatar } from "@arco-design/web-vue";
const table = useTable({
data: async (model, paging) => {

View File

@ -1,4 +1,4 @@
import { NProgress } from "@/plugins";
import { NProgress } from "@/libs/nprogress";
import { NavigationGuardWithThis, NavigationHookAfter } from "vue-router";
const before: NavigationGuardWithThis<undefined> = function () {

View File

@ -1,7 +1,7 @@
import generatedRoutes from "virtual:generated-pages";
import { RouteRecordRaw } from "vue-router";
const APP_ROUTE_NAME = "_app";
const APP_ROUTE_NAME = "_layout";
/**
* _

View File

@ -38,12 +38,14 @@ export const useUserStore = defineStore({
setToken(token: string) {
this.accessToken = token;
},
/**
*
*/
clearUser() {
this.$reset()
},
/**
*
*/

View File

@ -7,15 +7,22 @@ export {}
declare module '@vue/runtime-core' {
export interface GlobalComponents {
AAlert: typeof import('@arco-design/web-vue')['Alert']
AAvatar: typeof import('@arco-design/web-vue')['Avatar']
ABreadcrumb: typeof import('@arco-design/web-vue')['Breadcrumb']
ABreadcrumbItem: typeof import('@arco-design/web-vue')['BreadcrumbItem']
AButton: typeof import('@arco-design/web-vue')['Button']
ACard: typeof import('@arco-design/web-vue')['Card']
ACheckbox: typeof import('@arco-design/web-vue')['Checkbox']
ACheckboxGroup: typeof import('@arco-design/web-vue')['CheckboxGroup']
AConfigProvider: typeof import('@arco-design/web-vue')['ConfigProvider']
ADatePicker: typeof import('@arco-design/web-vue')['DatePicker']
ADoption: typeof import('@arco-design/web-vue')['Doption']
ADrawer: typeof import('@arco-design/web-vue')['Drawer']
ADropdown: typeof import('@arco-design/web-vue')['Dropdown']
AForm: typeof import('@arco-design/web-vue')['Form']
AFormItem: typeof import('@arco-design/web-vue')['FormItem']
AImage: typeof import('@arco-design/web-vue')['Image']
AInput: typeof import('@arco-design/web-vue')['Input']
AInputPassword: typeof import('@arco-design/web-vue')['InputPassword']
ALayout: typeof import('@arco-design/web-vue')['Layout']
@ -23,12 +30,25 @@ declare module '@vue/runtime-core' {
ALayoutHeader: typeof import('@arco-design/web-vue')['LayoutHeader']
ALayoutSider: typeof import('@arco-design/web-vue')['LayoutSider']
ALink: typeof import('@arco-design/web-vue')['Link']
AList: typeof import('@arco-design/web-vue')['List']
AListItem: typeof import('@arco-design/web-vue')['ListItem']
AListItemMeta: typeof import('@arco-design/web-vue')['ListItemMeta']
AMenu: typeof import('@arco-design/web-vue')['Menu']
AMenuItem: typeof import('@arco-design/web-vue')['MenuItem']
AMenuItemGroup: typeof import('@arco-design/web-vue')['MenuItemGroup']
AModal: typeof import('@arco-design/web-vue')['Modal']
APagination: typeof import('@arco-design/web-vue')['Pagination']
ARadio: typeof import('@arco-design/web-vue')['Radio']
ARadioGroup: typeof import('@arco-design/web-vue')['RadioGroup']
ASpace: typeof import('@arco-design/web-vue')['Space']
ASwitch: typeof import('@arco-design/web-vue')['Switch']
ATabPane: typeof import('@arco-design/web-vue')['TabPane']
ATabs: typeof import('@arco-design/web-vue')['Tabs']
ATag: typeof import('@arco-design/web-vue')['Tag']
ATextarea: typeof import('@arco-design/web-vue')['Textarea']
ATooltip: typeof import('@arco-design/web-vue')['Tooltip']
ATree: typeof import('@arco-design/web-vue')['Tree']
AUpload: typeof import('@arco-design/web-vue')['Upload']
BreadCrumb: typeof import('./../components/breadcrumb/bread-crumb.vue')['default']
BreadPage: typeof import('./../components/breadcrumb/bread-page.vue')['default']
Page403: typeof import('./../components/error/page-403.vue')['default']

49
src/utils/constant.ts Normal file
View File

@ -0,0 +1,49 @@
interface Item {
label: string;
value: any;
[key: string]: any;
}
class Constant<T extends Item[]> {
constructor(public raw: T) {}
/**
*
* @param value
* @param key label
* @returns
*/
fmt<K extends T[number]["value"]>(value: K, key?: keyof T[number]) {
return this.raw.find((item) => item.value === value)?.[key ?? ("label" as any)];
}
/**
*
* @param key value
* @returns
*/
val<K extends keyof T[number]>(key?: K) {
return this.raw.map((item) => item[key ?? ("value" as any)]);
}
/**
*
* @param value
* @returns
*/
get(value: any) {
return this.raw.find((item) => item.value === value);
}
/**
*
* @param items
* @returns
*/
static from<T extends Item[]>(items: T) {
return new Constant(items);
}
}
export { Constant };

View File

@ -1,71 +0,0 @@
type MergeIntersection<A> = A extends infer T ? { [Key in keyof T]: T[Key] } : never;
interface Item {
label: string;
value: any;
[key: string]: any;
}
interface ProtoInterface<T extends readonly Item[]> {
/**
*
* @param value
* @param key `label`
*/
fmt<K extends T[number]["value"]>(value: K, key?: keyof T[number]): any;
/**
*
* @description value
*/
val<K extends keyof T[number]>(key: K): T[number][K][];
/**
*
*/
raw(): T;
/**
*
*/
map(): {
[k in T[number] as k["value"]]: k;
};
}
class Proto implements ProtoInterface<Item[]> {
_raw: Item[] = [];
fmt(value: any, key = "label") {
return this._raw.find((item) => item.value === value)?.[key];
}
val(key: any = "value") {
return this._raw.map((item) => item[key]);
}
raw() {
return this._raw;
}
map() {
return this._raw.reduce((acc, cur) => {
acc[cur.value] = cur;
return acc;
}, {} as any);
}
}
type EnumType<T extends Object, R extends readonly Item[]> = MergeIntersection<T & ProtoInterface<R>>;
/**
*
* @param target
* @param items
* @returns
*/
export function extendEnum<T extends Object, I extends readonly Item[]>(target: T, items: I): EnumType<T, I> {
Object.assign(target, { _raw: items });
Object.setPrototypeOf(target, Proto.prototype);
return target as any;
}

View File

@ -1,2 +1,3 @@
export * from "./extendEnum";
export * from "./constant";
export * from "./delConfirm";

View File

@ -15,10 +15,9 @@ import plugin from "./scripts/vite/plugin";
* @see https://cn.vitejs.dev/config/
*/
export default defineConfig(({ mode }) => {
// 加载顺序,后者优先级高:.env .env.locale .env.[mode] .env.[mode].locale
const env = loadEnv(mode, process.cwd());
const host = env.VITE_HOST || "0.0.0.0";
const port = Number(env.VITE_PORT || 3020);
const host = env.VITE_HOST ?? "0.0.0.0";
const port = Number(env.VITE_PORT ?? 3020);
return {
base: "./",