feat: 优化路由加载
parent
43487136fb
commit
943ec54aed
2
.env
2
.env
|
|
@ -30,3 +30,5 @@ VITE_PROXY = https://appnify.app.juetan.cn/
|
||||||
VITE_OPENAPI = http://127.0.0.1:3030/openapi.json
|
VITE_OPENAPI = http://127.0.0.1:3030/openapi.json
|
||||||
# 文件后缀 说明:设为dev时会优先加载index.dev.vue文件,否则回退至index.vue文件
|
# 文件后缀 说明:设为dev时会优先加载index.dev.vue文件,否则回退至index.vue文件
|
||||||
VITE_EXTENSION = dev
|
VITE_EXTENSION = dev
|
||||||
|
# 是否以离线模式启动,跳过登录
|
||||||
|
VITE_OFFLINE = true
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import { Button, ButtonInstance, FormInstance, Message, Modal } from '@arco-design/web-vue';
|
import { Button, ButtonInstance, FormInstance, Message, Modal } from '@arco-design/web-vue';
|
||||||
|
import { useVModel } from '@vueuse/core';
|
||||||
import { InjectionKey, PropType, Ref } from 'vue';
|
import { InjectionKey, PropType, Ref } from 'vue';
|
||||||
|
import { getModel, setModel } from '../utils/useFormModel';
|
||||||
import { AnForm, AnFormInstance, AnFormSubmit } from './Form';
|
import { AnForm, AnFormInstance, AnFormSubmit } from './Form';
|
||||||
import { AnFormItemProps } from './FormItem';
|
import { AnFormItemProps } from './FormItem';
|
||||||
import { useVModel } from '@vueuse/core';
|
|
||||||
import { getModel, setModel } from '../utils/useFormModel';
|
|
||||||
|
|
||||||
export interface AnFormModalContext {
|
export interface AnFormModalContext {
|
||||||
visible: Ref<boolean>;
|
visible: Ref<boolean>;
|
||||||
|
|
@ -210,6 +210,8 @@ export const AnFormModal = defineComponent({
|
||||||
<Modal
|
<Modal
|
||||||
titleAlign="start"
|
titleAlign="start"
|
||||||
closable={false}
|
closable={false}
|
||||||
|
maskAnimationName=""
|
||||||
|
modalAnimationName=""
|
||||||
{...this.modalProps}
|
{...this.modalProps}
|
||||||
v-model:visible={this.visible}
|
v-model:visible={this.visible}
|
||||||
class="an-form-modal"
|
class="an-form-modal"
|
||||||
|
|
|
||||||
|
|
@ -154,7 +154,7 @@ function useTableButtonColumn(column: TableButtonColumn & TableColumnData) {
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{index !== 0 && <Divider direction="vertical" margin={2} />}
|
{index !== 0 && <Divider direction="vertical" margin={4} />}
|
||||||
<Link {...item.buttonProps} disabled={item.disable?.(props)} onClick={() => item.onClick?.(props)}>
|
<Link {...item.buttonProps} disabled={item.disable?.(props)} onClick={() => item.onClick?.(props)}>
|
||||||
{{
|
{{
|
||||||
default: () => item.text,
|
default: () => item.text,
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
</div>
|
</div>
|
||||||
<slot name="content">
|
<slot name="content">
|
||||||
<a-scrollbar outer-class="h-full overflow-hidden" class="h-full overflow-auto" type="track">
|
<a-scrollbar outer-class="h-full overflow-hidden" class="h-full overflow-auto" type="track">
|
||||||
<div class="m-4 p-4 bg-white rounded overflow-hidden">
|
<div class="m-4 bg-white rounded overflow-hidden" :class="{ 'p-4': contentPadding }">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
</a-scrollbar>
|
</a-scrollbar>
|
||||||
|
|
@ -19,7 +19,14 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import BreadCrumb from "./bread-crumb.vue";
|
import BreadCrumb from './bread-crumb.vue';
|
||||||
|
|
||||||
|
defineProps({
|
||||||
|
contentPadding: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,12 @@
|
||||||
<template>
|
<template>
|
||||||
<a-modal v-model:visible="show" :fullscreen="true" :footer="false" class="ani-modal">
|
<a-modal
|
||||||
|
v-model:visible="show"
|
||||||
|
mask-animation-name=""
|
||||||
|
modal-animation-name=""
|
||||||
|
:fullscreen="true"
|
||||||
|
:footer="false"
|
||||||
|
class="ani-modal"
|
||||||
|
>
|
||||||
<div class="w-full h-full bg-slate-100 grid grid-rows-[auto_1fr] select-none">
|
<div class="w-full h-full bg-slate-100 grid grid-rows-[auto_1fr] select-none">
|
||||||
<div class="h-13 bg-white border-b border-slate-200 z-10">
|
<div class="h-13 bg-white border-b border-slate-200 z-10">
|
||||||
<EditorHeader
|
<EditorHeader
|
||||||
|
|
@ -41,17 +48,17 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { delConfirm, sleep } from '@/utils';
|
||||||
|
import { Message } from '@arco-design/web-vue';
|
||||||
|
import { useVModel } from '@vueuse/core';
|
||||||
import { Block, ContextMenuItem, EditorKey, useEditor } from '../core';
|
import { Block, ContextMenuItem, EditorKey, useEditor } from '../core';
|
||||||
|
import ContextMenu from './ContextMenu.vue';
|
||||||
|
import EditorSetting from './EditorConfig.vue';
|
||||||
import EditorHeader from './EditorHeader.vue';
|
import EditorHeader from './EditorHeader.vue';
|
||||||
import EditorLeft from './EditorLeft.vue';
|
import EditorLeft from './EditorLeft.vue';
|
||||||
import EditorMain from './EditorMain.vue';
|
import EditorMain from './EditorMain.vue';
|
||||||
import EditorRight from './EditorRight.vue';
|
|
||||||
import EditorPreview from './EditorPreview.vue';
|
import EditorPreview from './EditorPreview.vue';
|
||||||
import EditorSetting from './EditorConfig.vue';
|
import EditorRight from './EditorRight.vue';
|
||||||
import ContextMenu from './ContextMenu.vue';
|
|
||||||
import { delConfirm, sleep } from '@/utils';
|
|
||||||
import { useVModel } from '@vueuse/core';
|
|
||||||
import { Message } from '@arco-design/web-vue';
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
visible: {
|
visible: {
|
||||||
|
|
@ -85,7 +92,7 @@ const blockMenuItems: ContextMenuItem[] = [
|
||||||
await delConfirm({
|
await delConfirm({
|
||||||
content: '确定删除该组件吗?',
|
content: '确定删除该组件吗?',
|
||||||
okText: '确定删除',
|
okText: '确定删除',
|
||||||
})
|
});
|
||||||
if (blockMenu.block) {
|
if (blockMenu.block) {
|
||||||
rmBlock(blockMenu.block);
|
rmBlock(blockMenu.block);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,17 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="h-full flex items-center justify-between pl-2 pr-4">
|
<div class="h-full flex items-center justify-between pl-2 pr-4">
|
||||||
<div class="text-base group">
|
<div class="text-base flex items-center group">
|
||||||
<a-link @click="emit('exit')">
|
<a-link @click="emit('exit')">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<i class="icon-park-outline-left"></i>
|
<i class="icon-park-outline-left"></i>
|
||||||
</template>
|
</template>
|
||||||
返回
|
返回
|
||||||
</a-link>
|
</a-link>
|
||||||
<a-divider :direction="'vertical'" :margin="4"></a-divider>
|
<a-divider :direction="'vertical'" :margin="8"></a-divider>
|
||||||
<a-tag :color="container.id ? 'blue' : 'green'" class="mr-2 ml-1">
|
|
||||||
{{ container.id ? '修改' : '新增' }}
|
|
||||||
</a-tag>
|
|
||||||
<ani-texter v-model="container.title"></ani-texter>
|
<ani-texter v-model="container.title"></ani-texter>
|
||||||
|
<!-- <a-tag :color="container.id ? 'blue' : 'green'" class="mr-2 ml-1">
|
||||||
|
{{ container.id ? '修改' : '新增' }}
|
||||||
|
</a-tag> -->
|
||||||
</div>
|
</div>
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<a-button @click="emit('preview')">
|
<a-button @click="emit('preview')">
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
<template>
|
<template>
|
||||||
<span v-if="!descEditing">
|
<span v-if="!descEditing" class="inline-block leading-[32px] h-8">
|
||||||
{{ modelValue }}
|
{{ modelValue }}
|
||||||
<i
|
<a-button type="text" size="small" shape="round" class="!hidden !group-hover:inline-block !text-gray-500" @click="onDescEdit">
|
||||||
class="!hidden !group-hover:inline-block icon-park-outline-edit text-gray-400 hover:text-gray-700 ml-1 cursor-pointer"
|
<template #icon>
|
||||||
@click="onDescEdit"
|
<i class="icon-park-outline-edit"></i>
|
||||||
></i>
|
</template>
|
||||||
|
</a-button>
|
||||||
</span>
|
</span>
|
||||||
<span v-else class="inline-flex items-center">
|
<span v-else class="inline-flex items-center">
|
||||||
<a-input size="small" v-model="descContent" class="!w-96" v-bind="inputProps"></a-input>
|
<a-input size="small" v-model="descContent" class="!w-96" v-bind="inputProps"></a-input>
|
||||||
|
|
@ -22,8 +23,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { PropType } from "vue";
|
|
||||||
import { Input } from "@arco-design/web-vue";
|
import { Input } from "@arco-design/web-vue";
|
||||||
|
import { PropType } from "vue";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {
|
modelValue: {
|
||||||
|
|
|
||||||
|
|
@ -25,29 +25,15 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from 'vue-router';
|
||||||
import Image404 from "./image-404.svg?raw";
|
import Image404 from './image-404.svg?raw';
|
||||||
|
|
||||||
defineOptions({ name: "AllUncatchedPage" });
|
defineOptions({ name: 'AllUncatchedPage' });
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped></style>
|
||||||
.slide-in-bottom {
|
|
||||||
animation: slide-in-bottom 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
|
|
||||||
}
|
|
||||||
@keyframes slide-in-bottom {
|
|
||||||
0% {
|
|
||||||
transform: translateY(100px);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: translateY(0);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<route lang="json">
|
<route lang="json">
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
<script lang="tsx">
|
<script lang="tsx">
|
||||||
import { MenuItem } from "@/router";
|
import { MenuItem } from '@/router';
|
||||||
import { useMenuStore } from "@/store/menu";
|
import { useMenuStore } from '@/store/menu';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "LayoutMenu",
|
name: 'LayoutMenu',
|
||||||
setup() {
|
setup() {
|
||||||
const selectedKeys = ref<string[]>([]);
|
const selectedKeys = ref<string[]>([]);
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
|
@ -13,21 +13,21 @@ export default defineComponent({
|
||||||
watch(
|
watch(
|
||||||
() => route.path,
|
() => route.path,
|
||||||
() => {
|
() => {
|
||||||
selectedKeys.value = route.matched.map((i) => i.path);
|
selectedKeys.value = route.matched.map(i => i.path);
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
function goto(route: MenuItem) {
|
function goto(route: MenuItem) {
|
||||||
if (route.external) {
|
if (route.external) {
|
||||||
window.open(route.path, "_blank");
|
window.open(route.path, '_blank');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
router.push(route.path);
|
router.push(route.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderItem(routes: MenuItem[]) {
|
function renderItem(routes: MenuItem[]) {
|
||||||
return routes.map((route) => {
|
return routes.map(route => {
|
||||||
const icon = route.icon ? () => <i class={route.icon} /> : null;
|
const icon = route.icon ? () => <i class={route.icon} /> : null;
|
||||||
const node: any = route.children?.length ? (
|
const node: any = route.children?.length ? (
|
||||||
<>
|
<>
|
||||||
|
|
@ -38,8 +38,13 @@ export default defineComponent({
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<a-menu-item key={route.path} v-slots={{ icon }} onClick={() => goto(route)}>
|
<a-menu-item key={route.path} v-slots={{ icon }} onClick={() => goto(route)}>
|
||||||
{route.title}
|
<div class="flex items-center justify-between gap-2 pr-4">
|
||||||
{false && <span class="text-xs text-slate-400 ml-2">({route.sort})</span>}
|
<div>{route.title}</div>
|
||||||
|
<div class="text-xs text-gray-400">
|
||||||
|
{/* <a-badge count={8}>8</a-badge> */}
|
||||||
|
{ route.only === 'dev' ? '仅开发' : null }
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</a-menu-item>
|
</a-menu-item>
|
||||||
);
|
);
|
||||||
return node;
|
return node;
|
||||||
|
|
@ -47,7 +52,7 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
|
|
||||||
return () => (
|
return () => (
|
||||||
<a-menu style={{ width: "100%" }} selectedKeys={selectedKeys.value} autoOpenSelected={true} levelIndent={0}>
|
<a-menu style={{ width: '100%' }} selectedKeys={selectedKeys.value} autoOpenSelected={true} levelIndent={0}>
|
||||||
{renderItem(menuStore.menus)}
|
{renderItem(menuStore.menus)}
|
||||||
</a-menu>
|
</a-menu>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@
|
||||||
<a-divider :margin="4"></a-divider>
|
<a-divider :margin="4"></a-divider>
|
||||||
<a-doption @click="logout">
|
<a-doption @click="logout">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<i class="icon-park-outline-logout"></i>
|
<i class="icon-park-outline-power"></i>
|
||||||
</template>
|
</template>
|
||||||
退出
|
退出
|
||||||
</a-doption>
|
</a-doption>
|
||||||
|
|
@ -75,7 +75,7 @@ const logout = async () => {
|
||||||
const { component: PasswordModal, open } = useFormModal({
|
const { component: PasswordModal, open } = useFormModal({
|
||||||
title: '修改密码',
|
title: '修改密码',
|
||||||
trigger: false,
|
trigger: false,
|
||||||
width: 452,
|
width: 500,
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
field: 'password',
|
field: 'password',
|
||||||
|
|
@ -84,6 +84,7 @@ const { component: PasswordModal, open } = useFormModal({
|
||||||
setterProps: {
|
setterProps: {
|
||||||
placeholder: '请输入原密码',
|
placeholder: '请输入原密码',
|
||||||
},
|
},
|
||||||
|
required: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'password1',
|
field: 'password1',
|
||||||
|
|
@ -92,14 +93,16 @@ const { component: PasswordModal, open } = useFormModal({
|
||||||
setterProps: {
|
setterProps: {
|
||||||
placeholder: '请输入新密码',
|
placeholder: '请输入新密码',
|
||||||
},
|
},
|
||||||
|
required: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'password2',
|
field: 'password2',
|
||||||
label: '确认密码',
|
label: '确认新密码',
|
||||||
setter: 'input',
|
setter: 'input',
|
||||||
setterProps: {
|
setterProps: {
|
||||||
placeholder: '请再次输入新密码',
|
placeholder: '请再次输入新密码',
|
||||||
},
|
},
|
||||||
|
required: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,18 @@
|
||||||
class="h-13 overflow-hidden flex justify-between items-center gap-4 px-2 pr-4 border-b border-slate-200 bg-white dark:bg-slate-800 dark:border-slate-700"
|
class="h-13 overflow-hidden flex justify-between items-center gap-4 px-2 pr-4 border-b border-slate-200 bg-white dark:bg-slate-800 dark:border-slate-700"
|
||||||
>
|
>
|
||||||
<div class="h-13 flex items-center">
|
<div class="h-13 flex items-center">
|
||||||
|
<!-- <a-button size="small" @click="isCollapsed = !isCollapsed">
|
||||||
|
<template #icon>
|
||||||
|
<i class="icon-park-outline-hamburger-button text-base"></i>
|
||||||
|
</template>
|
||||||
|
</a-button> -->
|
||||||
<router-link to="/" class="px-2 flex items-center gap-2 text-slate-700">
|
<router-link to="/" class="px-2 flex items-center gap-2 text-slate-700">
|
||||||
<img src="/favicon.ico" alt="" width="24" height="24" class="" />
|
<img src="/favicon.ico" alt="" width="24" height="24" class="" />
|
||||||
<h1 class="relative text-[22px] leading-[22px] dark:text-white m-0 p-0 font-normal">
|
<h1 class="relative text-[18px] leading-[22px] dark:text-white m-0 p-0 font-normal">
|
||||||
{{ appStore.title }}
|
{{ appStore.title }}
|
||||||
<span class="absolute -right-10 -top-1 font-normal text-xs text-gray-400"> v0.0.1 </span>
|
<span class="absolute -right-10 -top-1 font-normal text-xs text-gray-400"> v0.0.1 </span>
|
||||||
</h1>
|
</h1>
|
||||||
|
<!-- <span class="text-gray-400">{{ appStore.subtitle }}</span> -->
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
|
|
@ -41,7 +47,7 @@
|
||||||
<a-layout-sider
|
<a-layout-sider
|
||||||
class="h-full overflow-hidden dark:bg-slate-800 border-r border-slate-200 dark:border-slate-700"
|
class="h-full overflow-hidden dark:bg-slate-800 border-r border-slate-200 dark:border-slate-700"
|
||||||
:width="224"
|
:width="224"
|
||||||
:collapsed-width="52"
|
:collapsed-width="49"
|
||||||
:collapsible="true"
|
:collapsible="true"
|
||||||
:collapsed="isCollapsed"
|
:collapsed="isCollapsed"
|
||||||
:hide-trigger="false"
|
:hide-trigger="false"
|
||||||
|
|
@ -112,6 +118,13 @@ const buttons = [
|
||||||
window.open('https://github.com/appnify/starter-vue', '_blank');
|
window.open('https://github.com/appnify/starter-vue', '_blank');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
icon: 'icon-park-outline-info',
|
||||||
|
tooltip: '关于',
|
||||||
|
onClick: () => {
|
||||||
|
window.open('https://github.com/appnify/starter-vue', '_blank');
|
||||||
|
},
|
||||||
|
},
|
||||||
];
|
];
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ const updateFileCategories = async () => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
const res = await api.fileCategory.getFileCategorys({ size: 0 });
|
const res = await api.fileCategory.getFileCategorys({ size: 0 });
|
||||||
list.value = res.data.data ?? [];
|
list.value = res.data.data ?? [];
|
||||||
list.value.length && emit('change', list.value[0]);
|
list.value.length && emit('change', {});
|
||||||
} catch {
|
} catch {
|
||||||
// nothing to do
|
// nothing to do
|
||||||
} finally {
|
} finally {
|
||||||
|
|
|
||||||
|
|
@ -14,15 +14,15 @@
|
||||||
<a-modal v-model:visible="show" :footer="false"></a-modal>
|
<a-modal v-model:visible="show" :footer="false"></a-modal>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<a-modal v-model:visible="show" title="预览" title-align="start" :closable="false" :width="420">
|
<a-modal v-model:visible="show" title="预览" title-align="start" mask-animation-name="" modal-animation-name="" :closable="false" :width="420">
|
||||||
抱歉,此文件类型暂不支持预览!
|
抱歉,此文件类型暂不支持预览!
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { PropType } from 'vue';
|
|
||||||
import { useVModel } from '@vueuse/core';
|
import { useVModel } from '@vueuse/core';
|
||||||
|
import { PropType } from 'vue';
|
||||||
|
|
||||||
type FileType = 'text' | 'audio' | 'image' | 'video' | 'unknown';
|
type FileType = 'text' | 'audio' | 'image' | 'video' | 'unknown';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,9 @@
|
||||||
title="上传文件"
|
title="上传文件"
|
||||||
title-align="start"
|
title-align="start"
|
||||||
v-model:visible="visible"
|
v-model:visible="visible"
|
||||||
:width="940"
|
mask-animation-name=""
|
||||||
|
modal-animation-name=""
|
||||||
|
:width="960"
|
||||||
:mask-closable="false"
|
:mask-closable="false"
|
||||||
:on-before-cancel="onBeforeCancel"
|
:on-before-cancel="onBeforeCancel"
|
||||||
@close="onClose"
|
@close="onClose"
|
||||||
|
|
@ -27,7 +29,12 @@
|
||||||
@error="onUploadError"
|
@error="onUploadError"
|
||||||
>
|
>
|
||||||
<template #upload-button>
|
<template #upload-button>
|
||||||
<a-button type="primary"> 选择文件 </a-button>
|
<a-button type="primary">
|
||||||
|
<template #icon>
|
||||||
|
<i class="icon-park-outline-upload-one"></i>
|
||||||
|
</template>
|
||||||
|
选择
|
||||||
|
</a-button>
|
||||||
</template>
|
</template>
|
||||||
</a-upload>
|
</a-upload>
|
||||||
<div class="flex-1 flex items-center text-gray-400">
|
<div class="flex-1 flex items-center text-gray-400">
|
||||||
|
|
@ -38,7 +45,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="h-[424px] border-t border-b border-zinc-100 mt-3">
|
<div class="h-[424px] border-t border-b border-zinc-100 mt-4">
|
||||||
<ul v-if="fileList.length" class="overflow-hidden p-0 m-0">
|
<ul v-if="fileList.length" class="overflow-hidden p-0 m-0">
|
||||||
<a-scrollbar outer-class="h-full overflow-hidden" class="h-full overflow-auto pr-[20px] divide-y">
|
<a-scrollbar outer-class="h-full overflow-hidden" class="h-full overflow-auto pr-[20px] divide-y">
|
||||||
<li v-for="item in fileList" :key="item.uid" class="flex items-center gap-4 py-3">
|
<li v-for="item in fileList" :key="item.uid" class="flex items-center gap-4 py-3">
|
||||||
|
|
@ -99,7 +106,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="flex justify-between gap-2 items-center">
|
<div class="flex justify-between gap-2 items-center">
|
||||||
<div class="text-gray-400">已上传 {{ stat.doneCount }}/{{ fileList.length }} 项</div>
|
<div class="text-gray-400">已上传 {{ stat.doneCount }}/{{ fileList.length }} 项</div>
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,8 @@ import { useCreateColumn, useTable, useTableDelete, useUpdateColumn } from '@/co
|
||||||
import { Message } from '@arco-design/web-vue';
|
import { Message } from '@arco-design/web-vue';
|
||||||
import numeral from 'numeral';
|
import numeral from 'numeral';
|
||||||
import AnGroup from './components/AnGroup.vue';
|
import AnGroup from './components/AnGroup.vue';
|
||||||
import AnUpload from './components/AnUpload.vue';
|
|
||||||
import AnPreview from './components/AnPreview.vue';
|
import AnPreview from './components/AnPreview.vue';
|
||||||
|
import AnUpload from './components/AnUpload.vue';
|
||||||
import { getIcon } from './components/util';
|
import { getIcon } from './components/util';
|
||||||
|
|
||||||
const current = ref<FileCategory>();
|
const current = ref<FileCategory>();
|
||||||
|
|
@ -111,10 +111,12 @@ const {
|
||||||
onClick: props => {
|
onClick: props => {
|
||||||
window.open(props.record.path, '_blank');
|
window.open(props.record.path, '_blank');
|
||||||
},
|
},
|
||||||
|
icon: 'icon-park-outline-download',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'modify',
|
type: 'modify',
|
||||||
text: '修改',
|
text: '修改',
|
||||||
|
icon: 'icon-park-outline-edit',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'delete',
|
type: 'delete',
|
||||||
|
|
@ -138,6 +140,41 @@ const {
|
||||||
categoryId: undefined,
|
categoryId: undefined,
|
||||||
},
|
},
|
||||||
items: [
|
items: [
|
||||||
|
{
|
||||||
|
field: 'type',
|
||||||
|
label: '类型',
|
||||||
|
setter: 'select',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: '视频',
|
||||||
|
value: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '音频',
|
||||||
|
value: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '图片',
|
||||||
|
value: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '文本',
|
||||||
|
value: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '其他',
|
||||||
|
value: 5,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
setterProps: {
|
||||||
|
style: {
|
||||||
|
width: '100px',
|
||||||
|
},
|
||||||
|
triggerProps: {
|
||||||
|
autoFitPopupMinWidth: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
field: 'name',
|
field: 'name',
|
||||||
label: '素材名称',
|
label: '素材名称',
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
{
|
{
|
||||||
"only": "dev",
|
"only": "dev",
|
||||||
"meta": {
|
"meta": {
|
||||||
"sort": 20010,
|
"sort": 120010,
|
||||||
"title": "开发相关",
|
"title": "开发相关",
|
||||||
"icon": "icon-park-outline-home"
|
"icon": "icon-park-outline-home"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
{
|
{
|
||||||
"only": "dev",
|
"only": "dev",
|
||||||
"meta": {
|
"meta": {
|
||||||
"sort": 20010,
|
"sort": 120010,
|
||||||
"title": "接口文档",
|
"title": "接口文档",
|
||||||
"icon": "icon-park-outline-api"
|
"icon": "icon-park-outline-api"
|
||||||
}
|
}
|
||||||
|
|
@ -7,8 +7,8 @@
|
||||||
|
|
||||||
<script setup lang="tsx">
|
<script setup lang="tsx">
|
||||||
import { api } from '@/api';
|
import { api } from '@/api';
|
||||||
import { TableColumnRender, useCreateColumn, useTable, useUpdateColumn } from '@/components/AnTable';
|
|
||||||
import { useFormModal } from '@/components/AnForm';
|
import { useFormModal } from '@/components/AnForm';
|
||||||
|
import { TableColumnRender, useCreateColumn, useTable, useUpdateColumn } from '@/components/AnTable';
|
||||||
|
|
||||||
defineOptions({ name: 'SystemUserPage' });
|
defineOptions({ name: 'SystemUserPage' });
|
||||||
|
|
||||||
|
|
@ -37,7 +37,7 @@ const usernameRender: TableColumnRender = ({ record }) => (
|
||||||
</a-avatar>
|
</a-avatar>
|
||||||
<div class="w-full flex-1 overflow-hidden">
|
<div class="w-full flex-1 overflow-hidden">
|
||||||
<div>
|
<div>
|
||||||
<span>{record.nickname}</span>
|
<span class="cursor-pointer hover:text-brand-500">{record.nickname}</span>
|
||||||
<span class="text-gray-400 text-xs truncate ml-2">@{record.username}</span>
|
<span class="text-gray-400 text-xs truncate ml-2">@{record.username}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full text-gray-400 space-x-4 text-xs">
|
<div class="w-full text-gray-400 space-x-4 text-xs">
|
||||||
|
|
@ -71,6 +71,7 @@ const { component: UserTable } = useTable({
|
||||||
title: '操作',
|
title: '操作',
|
||||||
type: 'button',
|
type: 'button',
|
||||||
width: 200,
|
width: 200,
|
||||||
|
align: 'right',
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
text: '重置密码',
|
text: '重置密码',
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
<template>
|
<template>
|
||||||
<BreadPage>
|
<BreadPage :content-padding="false">
|
||||||
<template #content>
|
<section class="my-page bg-white">
|
||||||
<section class="my-page m-5 py-4 pr-4 h-full bg-white">
|
<a-tabs size="large">
|
||||||
<a-tabs direction="vertical">
|
|
||||||
<a-tab-pane key="1" title="基本设置">
|
<a-tab-pane key="1" title="基本设置">
|
||||||
<template #title>
|
<a-form
|
||||||
<i class="icon-park-outline-config"></i>
|
:model="user"
|
||||||
基本设置
|
:label-col-props="{ span: 3 }"
|
||||||
</template>
|
label-align="left"
|
||||||
<a-form :model="user" layout="vertical">
|
class="px-6 divide-y divide-gray-100"
|
||||||
<a-form-item label="个人头像">
|
>
|
||||||
|
<a-form-item label="用户头像">
|
||||||
<a-avatar :size="64">
|
<a-avatar :size="64">
|
||||||
<img src="https://github.com/juetan.png" alt="" />
|
<img src="https://github.com/juetan.png" alt="" />
|
||||||
<template #trigger-icon>
|
<template #trigger-icon>
|
||||||
|
|
@ -23,12 +23,13 @@
|
||||||
v-model="user.nickname"
|
v-model="user.nickname"
|
||||||
placeholder="请输入"
|
placeholder="请输入"
|
||||||
class="!w-[432px]"
|
class="!w-[432px]"
|
||||||
|
allow-clear
|
||||||
:max-length="24"
|
:max-length="24"
|
||||||
:show-word-limit="true"
|
:show-word-limit="true"
|
||||||
></a-input>
|
></a-input>
|
||||||
<template #help> 用作系统内显示的名称,可在后台修改 </template>
|
<template #help> 用作系统内显示的名称,可在后台修改 </template>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="个人描述">
|
<a-form-item label="用户描述">
|
||||||
<a-textarea
|
<a-textarea
|
||||||
v-model="user.description"
|
v-model="user.description"
|
||||||
placeholder="请输入"
|
placeholder="请输入"
|
||||||
|
|
@ -47,15 +48,42 @@
|
||||||
<a-form-item label="出生日期">
|
<a-form-item label="出生日期">
|
||||||
<a-date-picker v-model="user.birth"></a-date-picker>
|
<a-date-picker v-model="user.birth"></a-date-picker>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-button type="primary">保存修改</a-button>
|
<a-form-item>
|
||||||
|
<a-button type="primary">保存修改</a-button>
|
||||||
|
</a-form-item>
|
||||||
</a-form>
|
</a-form>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
<a-tab-pane key="5" title="消息推送">
|
<a-tab-pane key="5" title="消息推送">
|
||||||
<template #title>
|
<a-form :model="user" :label-col-props="{ span: 3 }" label-align="left" class="px-6 divide-y divide-gray-100">
|
||||||
<i class="icon-park-outline-message"></i>
|
<a-form-item label="站点LOGO">
|
||||||
消息通知
|
<a-avatar :size="64">
|
||||||
</template>
|
<img :src="appStore.logo" alt="" />
|
||||||
<a-form :model="user" layout="vertical">
|
<template #trigger-icon>
|
||||||
|
<i class="icon-park-outline-edit"></i>
|
||||||
|
</template>
|
||||||
|
</a-avatar>
|
||||||
|
<template #help> 支持 5MB 以内大小, png 或 jpg 格式的图片 </template>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="站点名称">
|
||||||
|
<a-input
|
||||||
|
v-model="appStore.title"
|
||||||
|
placeholder="请输入"
|
||||||
|
class="!w-[432px]"
|
||||||
|
allow-clear
|
||||||
|
:max-length="24"
|
||||||
|
:show-word-limit="true"
|
||||||
|
></a-input>
|
||||||
|
<template #help> 用作系统内显示的名称,可在后台修改 </template>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="站点描述">
|
||||||
|
<a-textarea
|
||||||
|
v-model="appStore.subtitle"
|
||||||
|
placeholder="请输入"
|
||||||
|
class="!w-[432px] h-24"
|
||||||
|
:max-length="140"
|
||||||
|
:show-word-limit="true"
|
||||||
|
></a-textarea>
|
||||||
|
</a-form-item>
|
||||||
<a-form-item label="消息推送">
|
<a-form-item label="消息推送">
|
||||||
<div>
|
<div>
|
||||||
<a-checkbox-group direction="vertical" v-model="user.msg">
|
<a-checkbox-group direction="vertical" v-model="user.msg">
|
||||||
|
|
@ -67,60 +95,41 @@
|
||||||
</div>
|
</div>
|
||||||
<template elp> 用作系统内显示的名称,可在后台修改 </template>
|
<template elp> 用作系统内显示的名称,可在后台修改 </template>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="邮箱账号">
|
<a-form-item label="默认主题">
|
||||||
<a-input v-model="user.email" placeholder="请输入" class="!w-[432px]"></a-input>
|
<div>
|
||||||
|
<a-radio-group v-model="user.theme" direction="vertical">
|
||||||
|
<a-radio value="dark">
|
||||||
|
黑曜深空
|
||||||
|
<div class="text-gray-400 mt-1">浅绿色主题,包含深林、绿叶、河流等内容</div>
|
||||||
|
</a-radio>
|
||||||
|
<a-radio value="light">
|
||||||
|
天空之城
|
||||||
|
<div class="text-gray-400 mt-1">浅绿色主题,包含深林、绿叶、河流等内容</div>
|
||||||
|
</a-radio>
|
||||||
|
</a-radio-group>
|
||||||
|
</div>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="SMTP地址">
|
||||||
|
<a-input v-model="user.smtpIp" allow-clear placeholder="请输入" class="!w-[314px]"></a-input>
|
||||||
|
<span class="inline-block px-2">:</span>
|
||||||
|
<a-input-number v-model="user.smtpPort" :min="0" :max="65535" class="w-24!"></a-input-number>
|
||||||
<template #help> 推荐使用主流邮箱, 例如: gmail.com, qq.com, 163.com等后缀 </template>
|
<template #help> 推荐使用主流邮箱, 例如: gmail.com, qq.com, 163.com等后缀 </template>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
<a-form-item label="SMTP账号">
|
||||||
|
<a-input v-model="user.smtpUser" placeholder="请输入" class="!w-[432px]"></a-input>
|
||||||
|
<template #help> 例如: gmail.com, qq.com, 163.com等后缀 </template>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="SMTP密钥">
|
||||||
|
<a-input v-model="user.smtpPass" placeholder="请输入" class="!w-[432px]"></a-input>
|
||||||
|
<template #help> 测试 </template>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item>
|
||||||
|
<a-button type="primary"> 保存修改 </a-button>
|
||||||
|
</a-form-item>
|
||||||
</a-form>
|
</a-form>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
<a-tab-pane key="8" title="账号密码">
|
|
||||||
<template #title>
|
|
||||||
<i class="icon-park-outline-lock"></i>
|
|
||||||
账号密码
|
|
||||||
</template>
|
|
||||||
<a-form :model="user" layout="vertical">
|
|
||||||
<a-form-item label="原密码">
|
|
||||||
<a-input placeholder="请输入原密码"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item label="新密码">
|
|
||||||
<a-input placeholder="请输入新密码"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item label="确认新密码">
|
|
||||||
<a-input placeholder="请再次输入新密码"></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
<a-button type="primary">修改密码</a-button>
|
|
||||||
</a-form>
|
|
||||||
</a-tab-pane>
|
|
||||||
<a-tab-pane key="2" title="主题偏好">
|
|
||||||
<template #title>
|
|
||||||
<i class="icon-park-outline-theme"></i>
|
|
||||||
主题设置
|
|
||||||
</template>
|
|
||||||
<div class="flex-1">
|
|
||||||
<a-form :model="user" layout="vertical">
|
|
||||||
<a-form-item label="主题">
|
|
||||||
<div>
|
|
||||||
<a-radio-group v-model="user.theme" direction="vertical">
|
|
||||||
<a-radio value="dark">
|
|
||||||
黑曜深空
|
|
||||||
<div class="text-gray-400 mt-1">浅绿色主题,包含深林、绿叶、河流等内容</div>
|
|
||||||
</a-radio>
|
|
||||||
<a-radio value="light">
|
|
||||||
天空之城
|
|
||||||
<div class="text-gray-400 mt-1">浅绿色主题,包含深林、绿叶、河流等内容</div>
|
|
||||||
</a-radio>
|
|
||||||
</a-radio-group>
|
|
||||||
</div>
|
|
||||||
</a-form-item>
|
|
||||||
</a-form>
|
|
||||||
</div>
|
|
||||||
</a-tab-pane>
|
|
||||||
<a-tab-pane key="3" title="额外功能">
|
<a-tab-pane key="3" title="额外功能">
|
||||||
<template #title>
|
<div class="flex-1 grid px-6">
|
||||||
<i class="icon-park-outline-shield"></i>
|
|
||||||
基本设置
|
|
||||||
</template>
|
|
||||||
<div class="flex-1 grid">
|
|
||||||
<div class="mb-3">功能列表</div>
|
<div class="mb-3">功能列表</div>
|
||||||
<div v-for="i in 3" class="border-t py-4 flex justify-between items-center gap-4">
|
<div v-for="i in 3" class="border-t py-4 flex justify-between items-center gap-4">
|
||||||
<div class="flex gap-3 items-center">
|
<div class="flex gap-3 items-center">
|
||||||
|
|
@ -180,13 +189,15 @@
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
|
||||||
</BreadPage>
|
</BreadPage>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="tsx">
|
<script setup lang="tsx">
|
||||||
|
import { useAppStore } from '@/store';
|
||||||
import { reactive } from 'vue';
|
import { reactive } from 'vue';
|
||||||
|
|
||||||
|
const appStore = useAppStore()
|
||||||
|
|
||||||
const user = reactive({
|
const user = reactive({
|
||||||
nickname: '绝弹',
|
nickname: '绝弹',
|
||||||
description: '选择在公开个人资料中显示私有项目的贡献,但不显示任何项目,仓库或组织信息',
|
description: '选择在公开个人资料中显示私有项目的贡献,但不显示任何项目,仓库或组织信息',
|
||||||
|
|
@ -195,11 +206,21 @@ const user = reactive({
|
||||||
msg: [2],
|
msg: [2],
|
||||||
gender: 1,
|
gender: 1,
|
||||||
birth: '1988-12-18',
|
birth: '1988-12-18',
|
||||||
|
smtpPort: 25,
|
||||||
|
smtpIp: '10.10.10.30',
|
||||||
|
smtpUser: '952222@163.com',
|
||||||
|
smtpPass: 'xxxxx',
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
.my-page {
|
.my-page {
|
||||||
|
.arco-form-item-label {
|
||||||
|
color: var(--color-text-3);
|
||||||
|
}
|
||||||
|
.arco-tabs-nav-type-line .arco-tabs-tab {
|
||||||
|
height: 52px;
|
||||||
|
}
|
||||||
.arco-form-item.arco-form-item-error,
|
.arco-form-item.arco-form-item-error,
|
||||||
.arco-form-item.arco-form-item-has-help {
|
.arco-form-item.arco-form-item-has-help {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
|
|
@ -220,6 +241,9 @@ const user = reactive({
|
||||||
.arco-radio-icon-hover {
|
.arco-radio-icon-hover {
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
}
|
}
|
||||||
|
.arco-form-item:not(:first-child) {
|
||||||
|
padding: 20px 0 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
@ -228,8 +252,7 @@ const user = reactive({
|
||||||
"meta": {
|
"meta": {
|
||||||
"sort": 30401,
|
"sort": 30401,
|
||||||
"title": "个人设置",
|
"title": "个人设置",
|
||||||
"icon": "icon-park-outline-config",
|
"icon": "icon-park-outline-config"
|
||||||
"auth": ["1"]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</route>
|
</route>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { api } from '@/api';
|
import { api } from '@/api';
|
||||||
|
import { env } from '@/config/env';
|
||||||
import { store, useUserStore } from '@/store';
|
import { store, useUserStore } from '@/store';
|
||||||
import { useMenuStore } from '@/store/menu';
|
import { useMenuStore } from '@/store/menu';
|
||||||
import { treeEach, treeFilter, treeFind } from '@/utils/listToTree';
|
import { treeEach, treeFilter, treeFind } from '@/utils/listToTree';
|
||||||
|
|
@ -7,7 +8,6 @@ import { Router } from 'vue-router';
|
||||||
import { menus } from '../menus';
|
import { menus } from '../menus';
|
||||||
import { APP_HOME_NAME } from '../routes/base';
|
import { APP_HOME_NAME } from '../routes/base';
|
||||||
import { APP_ROUTE_NAME, routes } from '../routes/page';
|
import { APP_ROUTE_NAME, routes } from '../routes/page';
|
||||||
import { env } from '@/config/env';
|
|
||||||
|
|
||||||
const WHITE_LIST = ['/:all(.*)*'];
|
const WHITE_LIST = ['/:all(.*)*'];
|
||||||
const UNSIGNIN_LIST = ['/login'];
|
const UNSIGNIN_LIST = ['/login'];
|
||||||
|
|
@ -27,7 +27,6 @@ export function useAuthGuard(router: Router) {
|
||||||
};
|
};
|
||||||
|
|
||||||
router.beforeEach(async function (to, from) {
|
router.beforeEach(async function (to, from) {
|
||||||
console.log(to);
|
|
||||||
const userStore = useUserStore(store);
|
const userStore = useUserStore(store);
|
||||||
const menuStore = useMenuStore(store);
|
const menuStore = useMenuStore(store);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ export interface MenuItem {
|
||||||
icon?: string;
|
icon?: string;
|
||||||
external?: boolean;
|
external?: boolean;
|
||||||
name?: string;
|
name?: string;
|
||||||
|
only?: undefined | 'none' | 'dev';
|
||||||
keepAlive: boolean;
|
keepAlive: boolean;
|
||||||
children?: MenuItem[];
|
children?: MenuItem[];
|
||||||
}
|
}
|
||||||
|
|
@ -25,13 +26,13 @@ function routesToItems(routes: RouteRecordRaw[]): MenuItem[] {
|
||||||
const items: MenuItem[] = [];
|
const items: MenuItem[] = [];
|
||||||
|
|
||||||
for (const route of routes) {
|
for (const route of routes) {
|
||||||
const { meta = {}, parentMeta, path } = route as any;
|
const { meta = {}, parentMeta, only, path } = route as any;
|
||||||
const { title, sort, icon, keepAlive = false, name } = meta;
|
const { title, sort, icon, keepAlive = false, name } = meta;
|
||||||
let id = path;
|
let id = path;
|
||||||
let paths = route.path.split('/');
|
let paths = route.path.split('/');
|
||||||
let parentId = paths.slice(0, -1).join('/');
|
let parentId = paths.slice(0, -1).join('/');
|
||||||
if (parentMeta) {
|
if (parentMeta) {
|
||||||
const { title, icon, sort } = parentMeta;
|
const { title, icon, sort, only } = parentMeta;
|
||||||
id = `${path}/index`;
|
id = `${path}/index`;
|
||||||
parentId = path;
|
parentId = path;
|
||||||
items.push({
|
items.push({
|
||||||
|
|
@ -39,6 +40,7 @@ function routesToItems(routes: RouteRecordRaw[]): MenuItem[] {
|
||||||
icon,
|
icon,
|
||||||
sort,
|
sort,
|
||||||
path,
|
path,
|
||||||
|
only,
|
||||||
id: path,
|
id: path,
|
||||||
keepAlive: false,
|
keepAlive: false,
|
||||||
parentId: paths.slice(0, -1).join('/'),
|
parentId: paths.slice(0, -1).join('/'),
|
||||||
|
|
@ -49,7 +51,7 @@ function routesToItems(routes: RouteRecordRaw[]): MenuItem[] {
|
||||||
parentId = p;
|
parentId = p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
items.push({ id, title, parentId, path, icon, sort, keepAlive, name });
|
items.push({ id, title, parentId, path, icon, sort, only, keepAlive, name });
|
||||||
}
|
}
|
||||||
|
|
||||||
return items;
|
return items;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
import generatedRoutes from 'virtual:generated-pages';
|
import generatedRoutes from 'virtual:generated-pages';
|
||||||
import { RouteRecordRaw } from 'vue-router';
|
import { RouteRecordRaw } from 'vue-router';
|
||||||
|
import { routes as vroutes } from 'vue-router/auto/routes';
|
||||||
|
|
||||||
|
console.log({vroutes, generatedRoutes});
|
||||||
|
|
||||||
export const TOP_ROUTE_PREF = '_';
|
export const TOP_ROUTE_PREF = '_';
|
||||||
export const APP_ROUTE_NAME = '_layout';
|
export const APP_ROUTE_NAME = '_layout';
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ export const useAppStore = defineStore({
|
||||||
state: (): AppStore => ({
|
state: (): AppStore => ({
|
||||||
isDarkMode: false,
|
isDarkMode: false,
|
||||||
title: env.title,
|
title: env.title,
|
||||||
|
logo: "/favicon.ico",
|
||||||
subtitle: env.subtitle,
|
subtitle: env.subtitle,
|
||||||
pageLoding: false,
|
pageLoding: false,
|
||||||
pageTags: [],
|
pageTags: [],
|
||||||
|
|
@ -74,6 +75,7 @@ export const useAppStore = defineStore({
|
||||||
});
|
});
|
||||||
|
|
||||||
interface AppStore {
|
interface AppStore {
|
||||||
|
logo: string;
|
||||||
/**
|
/**
|
||||||
* 是否为暗模式
|
* 是否为暗模式
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,7 @@ body {
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ani-form-modal .arco-modal-body {
|
.an-form-modal .arco-modal-body {
|
||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ declare module '@vue/runtime-core' {
|
||||||
ADoption: typeof import('@arco-design/web-vue')['Doption']
|
ADoption: typeof import('@arco-design/web-vue')['Doption']
|
||||||
ADrawer: typeof import('@arco-design/web-vue')['Drawer']
|
ADrawer: typeof import('@arco-design/web-vue')['Drawer']
|
||||||
ADropdown: typeof import('@arco-design/web-vue')['Dropdown']
|
ADropdown: typeof import('@arco-design/web-vue')['Dropdown']
|
||||||
ADropdownButton: typeof import('@arco-design/web-vue')['DropdownButton']
|
|
||||||
AEmpty: typeof import('@arco-design/web-vue')['Empty']
|
AEmpty: typeof import('@arco-design/web-vue')['Empty']
|
||||||
AForm: typeof import('@arco-design/web-vue')['Form']
|
AForm: typeof import('@arco-design/web-vue')['Form']
|
||||||
AFormItem: typeof import('@arco-design/web-vue')['FormItem']
|
AFormItem: typeof import('@arco-design/web-vue')['FormItem']
|
||||||
|
|
@ -43,7 +42,6 @@ declare module '@vue/runtime-core' {
|
||||||
AnEmpty: typeof import('./../components/AnEmpty/AnEmpty.vue')['default']
|
AnEmpty: typeof import('./../components/AnEmpty/AnEmpty.vue')['default']
|
||||||
AnForbidden: typeof import('./../components/AnForbidden/AnForbidden.vue')['default']
|
AnForbidden: typeof import('./../components/AnForbidden/AnForbidden.vue')['default']
|
||||||
AnToast: typeof import('./../components/AnToast/AnToast.vue')['default']
|
AnToast: typeof import('./../components/AnToast/AnToast.vue')['default']
|
||||||
AOption: typeof import('@arco-design/web-vue')['Option']
|
|
||||||
APagination: typeof import('@arco-design/web-vue')['Pagination']
|
APagination: typeof import('@arco-design/web-vue')['Pagination']
|
||||||
APopover: typeof import('@arco-design/web-vue')['Popover']
|
APopover: typeof import('@arco-design/web-vue')['Popover']
|
||||||
AProgress: typeof import('@arco-design/web-vue')['Progress']
|
AProgress: typeof import('@arco-design/web-vue')['Progress']
|
||||||
|
|
@ -73,7 +71,6 @@ declare module '@vue/runtime-core' {
|
||||||
EditorLeft: typeof import('./../components/editor/components/EditorLeft.vue')['default']
|
EditorLeft: typeof import('./../components/editor/components/EditorLeft.vue')['default']
|
||||||
EditorMain: typeof import('./../components/editor/components/EditorMain.vue')['default']
|
EditorMain: typeof import('./../components/editor/components/EditorMain.vue')['default']
|
||||||
EditorMainBlock: typeof import('./../components/editor/components/EditorMainBlock.vue')['default']
|
EditorMainBlock: typeof import('./../components/editor/components/EditorMainBlock.vue')['default']
|
||||||
EditorMainConfig: typeof import('./../components/editor/components/EditorMainConfig.vue')['default']
|
|
||||||
EditorMainHeader: typeof import('./../components/editor/components/EditorMainHeader.vue')['default']
|
EditorMainHeader: typeof import('./../components/editor/components/EditorMainHeader.vue')['default']
|
||||||
EditorPreview: typeof import('./../components/editor/components/EditorPreview.vue')['default']
|
EditorPreview: typeof import('./../components/editor/components/EditorPreview.vue')['default']
|
||||||
EditorRight: typeof import('./../components/editor/components/EditorRight.vue')['default']
|
EditorRight: typeof import('./../components/editor/components/EditorRight.vue')['default']
|
||||||
|
|
@ -84,13 +81,6 @@ declare module '@vue/runtime-core' {
|
||||||
InputTexter: typeof import('./../components/editor/components/InputTexter.vue')['default']
|
InputTexter: typeof import('./../components/editor/components/InputTexter.vue')['default']
|
||||||
Marquee: typeof import('./../components/editor/blocks/text/marquee.vue')['default']
|
Marquee: typeof import('./../components/editor/blocks/text/marquee.vue')['default']
|
||||||
Option: typeof import('./../components/editor/blocks/date/option.vue')['default']
|
Option: typeof import('./../components/editor/blocks/date/option.vue')['default']
|
||||||
PanelHeader: typeof import('./../components/editor/components/PanelHeader.vue')['default']
|
|
||||||
PanelLeft: typeof import('./../components/editor/components/PanelLeft.vue')['default']
|
|
||||||
PanelMain: typeof import('./../components/editor/components/PanelMain.vue')['default']
|
|
||||||
PanelMainBlock: typeof import('./../components/editor/components/PanelMainBlock.vue')['default']
|
|
||||||
PanelMainConfig: typeof import('./../components/editor/components/PanelMainConfig.vue')['default']
|
|
||||||
PanelMainHeader: typeof import('./../components/editor/components/PanelMainHeader.vue')['default']
|
|
||||||
PanelRight: typeof import('./../components/editor/components/PanelRight.vue')['default']
|
|
||||||
Render: typeof import('./../components/editor/blocks/date/render.vue')['default']
|
Render: typeof import('./../components/editor/blocks/date/render.vue')['default']
|
||||||
RouterLink: typeof import('vue-router')['RouterLink']
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
RouterView: typeof import('vue-router')['RouterView']
|
RouterView: typeof import('vue-router')['RouterView']
|
||||||
|
|
|
||||||
|
|
@ -42,25 +42,24 @@ declare module 'vue-router/auto/routes' {
|
||||||
'/_layout/': RouteRecordInfo<'/_layout/', '/_layout', Record<never, never>, Record<never, never>>,
|
'/_layout/': RouteRecordInfo<'/_layout/', '/_layout', Record<never, never>, Record<never, never>>,
|
||||||
'/_login/': RouteRecordInfo<'/_login/', '/_login', Record<never, never>, Record<never, never>>,
|
'/_login/': RouteRecordInfo<'/_login/', '/_login', Record<never, never>, Record<never, never>>,
|
||||||
'/[..._all]/': RouteRecordInfo<'/[..._all]/', '/:_all(.*)', { _all: ParamValue<true> }, { _all: ParamValue<false> }>,
|
'/[..._all]/': RouteRecordInfo<'/[..._all]/', '/:_all(.*)', { _all: ParamValue<true> }, { _all: ParamValue<false> }>,
|
||||||
'/dev/openapi': RouteRecordInfo<'/dev/openapi', '/dev/openapi', Record<never, never>, Record<never, never>>,
|
'/content/': RouteRecordInfo<'/content/', '/content', Record<never, never>, Record<never, never>>,
|
||||||
'/home/demo': RouteRecordInfo<'/home/demo', '/home/demo', Record<never, never>, Record<never, never>>,
|
'/content/category/': RouteRecordInfo<'/content/category/', '/content/category', Record<never, never>, Record<never, never>>,
|
||||||
'/home/home': RouteRecordInfo<'/home/home', '/home/home', Record<never, never>, Record<never, never>>,
|
'/content/comment/': RouteRecordInfo<'/content/comment/', '/content/comment', Record<never, never>, Record<never, never>>,
|
||||||
'/home/test': RouteRecordInfo<'/home/test', '/home/test', Record<never, never>, Record<never, never>>,
|
'/content/material/': RouteRecordInfo<'/content/material/', '/content/material', Record<never, never>, Record<never, never>>,
|
||||||
'/my/': RouteRecordInfo<'/my/', '/my', Record<never, never>, Record<never, never>>,
|
'/content/post/': RouteRecordInfo<'/content/post/', '/content/post', Record<never, never>, Record<never, never>>,
|
||||||
'/my/dev': RouteRecordInfo<'/my/dev', '/my/dev', Record<never, never>, Record<never, never>>,
|
'/dev/': RouteRecordInfo<'/dev/', '/dev', Record<never, never>, Record<never, never>>,
|
||||||
'/my/editor': RouteRecordInfo<'/my/editor', '/my/editor', Record<never, never>, Record<never, never>>,
|
'/dev/editor/': RouteRecordInfo<'/dev/editor/', '/dev/editor', Record<never, never>, Record<never, never>>,
|
||||||
'/post/': RouteRecordInfo<'/post/', '/post', Record<never, never>, Record<never, never>>,
|
'/dev/openapi/': RouteRecordInfo<'/dev/openapi/', '/dev/openapi', Record<never, never>, Record<never, never>>,
|
||||||
'/post/category/': RouteRecordInfo<'/post/category/', '/post/category', Record<never, never>, Record<never, never>>,
|
'/home/': RouteRecordInfo<'/home/', '/home', Record<never, never>, Record<never, never>>,
|
||||||
'/post/comment/': RouteRecordInfo<'/post/comment/', '/post/comment', Record<never, never>, Record<never, never>>,
|
'/log/': RouteRecordInfo<'/log/', '/log', Record<never, never>, Record<never, never>>,
|
||||||
'/post/media/': RouteRecordInfo<'/post/media/', '/post/media', Record<never, never>, Record<never, never>>,
|
'/log/login/': RouteRecordInfo<'/log/login/', '/log/login', Record<never, never>, Record<never, never>>,
|
||||||
'/post/post/': RouteRecordInfo<'/post/post/', '/post/post', Record<never, never>, Record<never, never>>,
|
'/log/operation/': RouteRecordInfo<'/log/operation/', '/log/operation', Record<never, never>, Record<never, never>>,
|
||||||
'/system/': RouteRecordInfo<'/system/', '/system', Record<never, never>, Record<never, never>>,
|
'/system/': RouteRecordInfo<'/system/', '/system', Record<never, never>, Record<never, never>>,
|
||||||
'/system/login-log/': RouteRecordInfo<'/system/login-log/', '/system/login-log', Record<never, never>, Record<never, never>>,
|
'/system/dict/': RouteRecordInfo<'/system/dict/', '/system/dict', Record<never, never>, Record<never, never>>,
|
||||||
'/system/menu/': RouteRecordInfo<'/system/menu/', '/system/menu', Record<never, never>, Record<never, never>>,
|
'/system/menu/': RouteRecordInfo<'/system/menu/', '/system/menu', Record<never, never>, Record<never, never>>,
|
||||||
'/system/operation-log/': RouteRecordInfo<'/system/operation-log/', '/system/operation-log', Record<never, never>, Record<never, never>>,
|
|
||||||
'/system/permission/': RouteRecordInfo<'/system/permission/', '/system/permission', Record<never, never>, Record<never, never>>,
|
|
||||||
'/system/role/': RouteRecordInfo<'/system/role/', '/system/role', Record<never, never>, Record<never, never>>,
|
'/system/role/': RouteRecordInfo<'/system/role/', '/system/role', Record<never, never>, Record<never, never>>,
|
||||||
'/system/user/': RouteRecordInfo<'/system/user/', '/system/user', Record<never, never>, Record<never, never>>,
|
'/system/user/': RouteRecordInfo<'/system/user/', '/system/user', Record<never, never>, Record<never, never>>,
|
||||||
|
'/user/': RouteRecordInfo<'/user/', '/user', Record<never, never>, Record<never, never>>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@ import { merge } from 'lodash-es';
|
||||||
export type DelOptions = string | Partial<Omit<ModalConfig, 'onOk' | 'onCancel'>>;
|
export type DelOptions = string | Partial<Omit<ModalConfig, 'onOk' | 'onCancel'>>;
|
||||||
|
|
||||||
export const delOptions: ModalConfig = {
|
export const delOptions: ModalConfig = {
|
||||||
|
maskAnimationName: '',
|
||||||
|
modalAnimationName: '',
|
||||||
title: '提示',
|
title: '提示',
|
||||||
titleAlign: 'start',
|
titleAlign: 'start',
|
||||||
width: 432,
|
width: 432,
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,19 @@
|
||||||
import Vue from "@vitejs/plugin-vue";
|
import Vue from '@vitejs/plugin-vue';
|
||||||
import VueJsx from "@vitejs/plugin-vue-jsx";
|
import VueJsx from '@vitejs/plugin-vue-jsx';
|
||||||
import { resolve } from "path";
|
import { resolve } from 'path';
|
||||||
import { visualizer } from "rollup-plugin-visualizer";
|
import { visualizer } from 'rollup-plugin-visualizer';
|
||||||
import { presetIcons, presetUno } from "unocss";
|
import { presetIcons, presetUno } from 'unocss';
|
||||||
import Unocss from "unocss/vite";
|
import Unocss from 'unocss/vite';
|
||||||
import AutoImport from "unplugin-auto-import/vite";
|
import AutoImport from 'unplugin-auto-import/vite';
|
||||||
import { ArcoResolver } from "unplugin-vue-components/resolvers";
|
import { ArcoResolver } from 'unplugin-vue-components/resolvers';
|
||||||
import AutoComponent from "unplugin-vue-components/vite";
|
import AutoComponent from 'unplugin-vue-components/vite';
|
||||||
import { defineConfig, loadEnv } from "vite";
|
import router from 'unplugin-vue-router/vite';
|
||||||
import Page from "vite-plugin-pages";
|
import { defineConfig, loadEnv } from 'vite';
|
||||||
import { arcoToUnoColor } from "./scripts/vite/color";
|
import Page from 'vite-plugin-pages';
|
||||||
import iconFile from "./scripts/vite/file.json";
|
import { arcoToUnoColor } from './scripts/vite/color';
|
||||||
import iconFmt from "./scripts/vite/fmt.json";
|
import iconFile from './scripts/vite/file.json';
|
||||||
import plugin from "./scripts/vite/plugin";
|
import iconFmt from './scripts/vite/fmt.json';
|
||||||
|
import plugin from './scripts/vite/plugin';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* vite 配置
|
* vite 配置
|
||||||
|
|
@ -20,12 +21,21 @@ import plugin from "./scripts/vite/plugin";
|
||||||
*/
|
*/
|
||||||
export default defineConfig(({ mode }) => {
|
export default defineConfig(({ mode }) => {
|
||||||
const env = loadEnv(mode, process.cwd());
|
const env = loadEnv(mode, process.cwd());
|
||||||
const base = env.VITE_BASE ?? "/";
|
const base = env.VITE_BASE ?? '/';
|
||||||
const host = env.VITE_HOST ?? "0.0.0.0";
|
const host = env.VITE_HOST ?? '0.0.0.0';
|
||||||
const port = Number(env.VITE_PORT ?? 3020);
|
const port = Number(env.VITE_PORT ?? 3020);
|
||||||
return {
|
return {
|
||||||
base,
|
base,
|
||||||
plugins: [
|
plugins: [
|
||||||
|
/**
|
||||||
|
* 提供路由自动生成
|
||||||
|
* @see https://github.com/posva/unplugin-vue-router
|
||||||
|
*/
|
||||||
|
router({
|
||||||
|
dts: 'src/types/auto-router.d.ts',
|
||||||
|
exclude: ['**/components/*'],
|
||||||
|
}),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 提供 Vue 3 单文件组件支持
|
* 提供 Vue 3 单文件组件支持
|
||||||
* @see https://github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue
|
* @see https://github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue
|
||||||
|
|
@ -47,9 +57,9 @@ export default defineConfig(({ mode }) => {
|
||||||
* @see https://github.com/antfu/unplugin-auto-import#readme
|
* @see https://github.com/antfu/unplugin-auto-import#readme
|
||||||
*/
|
*/
|
||||||
AutoImport({
|
AutoImport({
|
||||||
imports: ["vue", "vue-router"],
|
dts: 'src/types/auto-import.d.ts',
|
||||||
|
imports: ['vue', 'vue-router'],
|
||||||
resolvers: [ArcoResolver()],
|
resolvers: [ArcoResolver()],
|
||||||
dts: "./src/types/auto-import.d.ts",
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -57,8 +67,8 @@ export default defineConfig(({ mode }) => {
|
||||||
* @see https://github.com/antfu/unplugin-vue-components
|
* @see https://github.com/antfu/unplugin-vue-components
|
||||||
*/
|
*/
|
||||||
AutoComponent({
|
AutoComponent({
|
||||||
|
dts: 'src/types/auto-component.d.ts',
|
||||||
resolvers: [ArcoResolver({ sideEffect: false })],
|
resolvers: [ArcoResolver({ sideEffect: false })],
|
||||||
dts: "./src/types/auto-component.d.ts",
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -66,13 +76,13 @@ export default defineConfig(({ mode }) => {
|
||||||
* @see https://github.com/hannoeru/vite-plugin-pages
|
* @see https://github.com/hannoeru/vite-plugin-pages
|
||||||
*/
|
*/
|
||||||
Page({
|
Page({
|
||||||
exclude: ["**/components/*", "**/*.*.*"],
|
exclude: ['**/components/*', '**/*.*.*'],
|
||||||
importMode: "async",
|
importMode: 'async',
|
||||||
onRoutesGenerated(routes) {
|
onRoutesGenerated(routes) {
|
||||||
// if (env.DEV) {
|
if (mode === 'development') {
|
||||||
// return routes;
|
return routes.filter(route => route.only !== 'none');
|
||||||
// }
|
}
|
||||||
return routes.filter((route) => route.only !== "dev");
|
return routes.filter(route => !['none', 'dev'].includes(route.only));
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
@ -83,17 +93,17 @@ export default defineConfig(({ mode }) => {
|
||||||
Unocss({
|
Unocss({
|
||||||
theme: {
|
theme: {
|
||||||
colors: {
|
colors: {
|
||||||
brand: arcoToUnoColor("primary"),
|
brand: arcoToUnoColor('primary'),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
include: ["src/**/*.{vue,ts,tsx,css,scss,sass,less,styl}"],
|
include: ['src/**/*.{vue,ts,tsx,css,scss,sass,less,styl}'],
|
||||||
presets: [
|
presets: [
|
||||||
presetUno(),
|
presetUno(),
|
||||||
presetIcons({
|
presetIcons({
|
||||||
prefix: "",
|
prefix: '',
|
||||||
collections: {
|
collections: {
|
||||||
"icon-file": iconFile,
|
'icon-file': iconFile,
|
||||||
"icon-fmt": iconFmt,
|
'icon-fmt': iconFmt,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
|
@ -105,7 +115,7 @@ export default defineConfig(({ mode }) => {
|
||||||
*/
|
*/
|
||||||
visualizer({
|
visualizer({
|
||||||
title: `构建统计 | ${env.VITE_SUBTITLE}`,
|
title: `构建统计 | ${env.VITE_SUBTITLE}`,
|
||||||
filename: ".gitea/stat.html",
|
filename: '.gitea/stat.html',
|
||||||
}),
|
}),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -117,8 +127,8 @@ export default defineConfig(({ mode }) => {
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: [
|
alias: [
|
||||||
{
|
{
|
||||||
find: "@",
|
find: '@',
|
||||||
replacement: "/src",
|
replacement: '/src',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
@ -126,10 +136,10 @@ export default defineConfig(({ mode }) => {
|
||||||
host,
|
host,
|
||||||
port,
|
port,
|
||||||
proxy: {
|
proxy: {
|
||||||
"/api": {
|
'/api': {
|
||||||
target: env.VITE_PROXY,
|
target: env.VITE_PROXY,
|
||||||
},
|
},
|
||||||
"/upload": {
|
'/upload': {
|
||||||
target: env.VITE_PROXY,
|
target: env.VITE_PROXY,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -139,8 +149,8 @@ export default defineConfig(({ mode }) => {
|
||||||
less: {
|
less: {
|
||||||
javascriptEnabled: true,
|
javascriptEnabled: true,
|
||||||
modifyVars: {
|
modifyVars: {
|
||||||
hack: `true; @import (reference) "${resolve("src/styles/css-arco.less")}";`,
|
hack: `true; @import (reference) "${resolve('src/styles/css-arco.less')}";`,
|
||||||
arcoblue: "#66f",
|
arcoblue: '#66f',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue