mirror of https://github.com/halo-dev/halo-admin
parent
ad10465da2
commit
9c9a2ea5c4
|
@ -82,6 +82,7 @@ function handleClose() {
|
||||||
class="modal-content transform transition-all"
|
class="modal-content transform transition-all"
|
||||||
>
|
>
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
|
<slot name="header">
|
||||||
<div class="modal-header-title">{{ title }}</div>
|
<div class="modal-header-title">{{ title }}</div>
|
||||||
<div class="modal-header-actions flex flex-row">
|
<div class="modal-header-actions flex flex-row">
|
||||||
<slot name="actions"></slot>
|
<slot name="actions"></slot>
|
||||||
|
@ -89,6 +90,7 @@ function handleClose() {
|
||||||
<IconClose />
|
<IconClose />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
<div :class="bodyClass" class="modal-body">
|
<div :class="bodyClass" class="modal-body">
|
||||||
<slot />
|
<slot />
|
||||||
|
|
|
@ -1,3 +1,26 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { VRoutesMenu } from "@/components/base/menu";
|
||||||
|
import { VTag } from "@/components/base/tag";
|
||||||
|
import { VModal } from "@/components/base/modal";
|
||||||
|
import { VInput } from "@/components/base/input";
|
||||||
|
import { menus, minimenus } from "@/router/menus.config";
|
||||||
|
import logo from "@/assets/logo.svg";
|
||||||
|
import { IconMore, IconSearch, IconUserSettings } from "@/core/icons";
|
||||||
|
import { RouterView, useRoute, useRouter } from "vue-router";
|
||||||
|
import { ref } from "vue";
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const moreMenuVisible = ref(false);
|
||||||
|
const moreMenuRootVisible = ref(false);
|
||||||
|
const spotlight = ref(false);
|
||||||
|
|
||||||
|
const handleRouteToProfile = () => {
|
||||||
|
router.push({ name: "Profile" });
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="flex h-full">
|
<div class="flex h-full">
|
||||||
<aside
|
<aside
|
||||||
|
@ -10,6 +33,7 @@
|
||||||
<div class="px-3">
|
<div class="px-3">
|
||||||
<div
|
<div
|
||||||
class="flex cursor-pointer items-center rounded bg-gray-100 p-2 text-gray-400 transition-all hover:text-gray-900"
|
class="flex cursor-pointer items-center rounded bg-gray-100 p-2 text-gray-400 transition-all hover:text-gray-900"
|
||||||
|
@click="spotlight = true"
|
||||||
>
|
>
|
||||||
<span class="mr-3">
|
<span class="mr-3">
|
||||||
<IconSearch />
|
<IconSearch />
|
||||||
|
@ -135,27 +159,13 @@
|
||||||
</Teleport>
|
</Teleport>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<VModal v-model:visible="spotlight" :width="600">
|
||||||
|
<template #header>
|
||||||
|
<VInput placeholder="全局搜索" size="lg"></VInput>
|
||||||
|
</template>
|
||||||
|
</VModal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { VRoutesMenu } from "@/components/base/menu";
|
|
||||||
import { VTag } from "@/components/base/tag";
|
|
||||||
import { menus, minimenus } from "@/router/menus.config";
|
|
||||||
import logo from "@/assets/logo.svg";
|
|
||||||
import { IconMore, IconSearch, IconUserSettings } from "@/core/icons";
|
|
||||||
import { RouterView, useRoute, useRouter } from "vue-router";
|
|
||||||
import { ref } from "vue";
|
|
||||||
|
|
||||||
const route = useRoute();
|
|
||||||
const router = useRouter();
|
|
||||||
|
|
||||||
const moreMenuVisible = ref(false);
|
|
||||||
const moreMenuRootVisible = ref(false);
|
|
||||||
|
|
||||||
const handleRouteToProfile = () => {
|
|
||||||
router.push({ name: "Profile" });
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.navbar {
|
.navbar {
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import { BasicLayout } from "@/layouts";
|
import { BasicLayout } from "@/layouts";
|
||||||
import { VPageHeader } from "@/components/base/header";
|
import { VPageHeader } from "@/components/base/header";
|
||||||
import { VButton } from "@/components/base/button";
|
import { VButton } from "@/components/base/button";
|
||||||
|
import { VCard } from "@/components/base/card";
|
||||||
import { VTabbar } from "@/components/base/tabs";
|
import { VTabbar } from "@/components/base/tabs";
|
||||||
import { IconSettings } from "@/core/icons";
|
import { IconSettings } from "@/core/icons";
|
||||||
import { onMounted, ref } from "vue";
|
import { onMounted, ref } from "vue";
|
||||||
|
@ -49,17 +50,19 @@ const handleTabChange = (id: string) => {
|
||||||
</template>
|
</template>
|
||||||
</VPageHeader>
|
</VPageHeader>
|
||||||
|
|
||||||
<div class="p-4">
|
<div class="m-0 md:m-4">
|
||||||
|
<VCard>
|
||||||
|
<template #header>
|
||||||
<VTabbar
|
<VTabbar
|
||||||
v-model:active-id="activeTab"
|
v-model:active-id="activeTab"
|
||||||
:items="SettingTabs"
|
:items="SettingTabs"
|
||||||
|
class="w-full !rounded-none"
|
||||||
type="outline"
|
type="outline"
|
||||||
@change="handleTabChange"
|
@change="handleTabChange"
|
||||||
></VTabbar>
|
></VTabbar>
|
||||||
|
</template>
|
||||||
<div>
|
|
||||||
<RouterView></RouterView>
|
<RouterView></RouterView>
|
||||||
</div>
|
</VCard>
|
||||||
</div>
|
</div>
|
||||||
</BasicLayout>
|
</BasicLayout>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -90,7 +90,7 @@ export const menus: MenuGroupType[] = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "设置",
|
name: "设置",
|
||||||
path: "/settings/general",
|
path: "/settings",
|
||||||
icon: IconSettings,
|
icon: IconSettings,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -13,7 +13,7 @@ import AttachmentList from "../views/contents/attachments/AttachmentList.vue";
|
||||||
|
|
||||||
import ThemeDetail from "../views/interface/themes/ThemeDetail.vue";
|
import ThemeDetail from "../views/interface/themes/ThemeDetail.vue";
|
||||||
import MenuList from "../views/interface/menus/MenuList.vue";
|
import MenuList from "../views/interface/menus/MenuList.vue";
|
||||||
import Visual from "../views/interface/visual/Visual.vue";
|
import Visual from "../views/interface/themes/Visual.vue";
|
||||||
|
|
||||||
import PluginList from "../views/system/plugins/PluginList.vue";
|
import PluginList from "../views/system/plugins/PluginList.vue";
|
||||||
import PluginDetail from "../views/system/plugins/PluginDetail.vue";
|
import PluginDetail from "../views/system/plugins/PluginDetail.vue";
|
||||||
|
|
|
@ -34,7 +34,7 @@ const handleChangeTheme = (theme: any) => {
|
||||||
v-model:visible="changeTheme"
|
v-model:visible="changeTheme"
|
||||||
:body-class="['!p-0']"
|
:body-class="['!p-0']"
|
||||||
:width="888"
|
:width="888"
|
||||||
title="切换主题"
|
title="已安装的主题"
|
||||||
>
|
>
|
||||||
<ul class="flex flex-col divide-y divide-gray-100" role="list">
|
<ul class="flex flex-col divide-y divide-gray-100" role="list">
|
||||||
<li
|
<li
|
||||||
|
|
|
@ -0,0 +1,277 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { VButton } from "@/components/base/button";
|
||||||
|
import { VModal } from "@/components/base/modal";
|
||||||
|
import { VCard } from "@/components/base/card";
|
||||||
|
import { VOption, VSelect } from "@/components/base/select";
|
||||||
|
import { VInput } from "@/components/base/input";
|
||||||
|
import { VTextarea } from "@/components/base/textarea";
|
||||||
|
import { VSpace } from "@/components/base/space";
|
||||||
|
import { VTabbar, VTabItem, VTabs } from "@/components/base/tabs";
|
||||||
|
import { computed, onMounted, ref } from "vue";
|
||||||
|
import {
|
||||||
|
IconComputer,
|
||||||
|
IconPhone,
|
||||||
|
IconSave,
|
||||||
|
IconSettings,
|
||||||
|
IconTablet,
|
||||||
|
} from "@/core/icons";
|
||||||
|
|
||||||
|
const activeId = ref("general");
|
||||||
|
const deviceActiveId = ref("desktop");
|
||||||
|
const attachmentSelectVisible = ref(false);
|
||||||
|
const settingRootVisible = ref(false);
|
||||||
|
const settingVisible = ref(false);
|
||||||
|
const devices = ref([
|
||||||
|
{
|
||||||
|
id: "desktop",
|
||||||
|
icon: IconComputer,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "tablet",
|
||||||
|
icon: IconTablet,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "phone",
|
||||||
|
icon: IconPhone,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const iframeClasses = computed(() => {
|
||||||
|
if (deviceActiveId.value === "desktop") {
|
||||||
|
return "w-full h-full";
|
||||||
|
}
|
||||||
|
if (deviceActiveId.value === "tablet") {
|
||||||
|
return "w-2/3 h-2/3";
|
||||||
|
}
|
||||||
|
// phone
|
||||||
|
return "w-96 h-[50rem]";
|
||||||
|
});
|
||||||
|
|
||||||
|
const attachments = Array.from(new Array(50), (_, index) => index).map(
|
||||||
|
(index) => {
|
||||||
|
return {
|
||||||
|
id: index,
|
||||||
|
name: `attachment-${index}`,
|
||||||
|
url: `https://picsum.photos/1000/700?random=${index}`,
|
||||||
|
size: "1.2MB",
|
||||||
|
type: "image/png",
|
||||||
|
strategy: "本地存储",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
window.addEventListener(
|
||||||
|
"message",
|
||||||
|
function receiveMessageFromIframePage(event) {
|
||||||
|
if (event.data === "select_image") {
|
||||||
|
attachmentSelectVisible.value = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
false
|
||||||
|
);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<VModal
|
||||||
|
v-model:visible="attachmentSelectVisible"
|
||||||
|
:width="1240"
|
||||||
|
title="选择附件"
|
||||||
|
>
|
||||||
|
<div class="w-full">
|
||||||
|
<ul
|
||||||
|
class="grid grid-cols-2 gap-x-2 gap-y-3 sm:grid-cols-3 md:grid-cols-2 xl:grid-cols-8 2xl:grid-cols-8"
|
||||||
|
role="list"
|
||||||
|
>
|
||||||
|
<li
|
||||||
|
v-for="(attachment, index) in attachments"
|
||||||
|
:key="index"
|
||||||
|
class="relative"
|
||||||
|
>
|
||||||
|
<VCard :body-class="['!p-0']">
|
||||||
|
<div
|
||||||
|
class="group aspect-w-10 aspect-h-7 block w-full cursor-pointer overflow-hidden bg-gray-100"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
:src="attachment.url"
|
||||||
|
alt=""
|
||||||
|
class="pointer-events-none object-cover group-hover:opacity-75"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<p
|
||||||
|
class="pointer-events-none block truncate px-2 py-1 text-sm font-medium text-gray-700"
|
||||||
|
>
|
||||||
|
{{ attachment.name }}
|
||||||
|
</p>
|
||||||
|
</VCard>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<VButton type="secondary">确定</VButton>
|
||||||
|
</template>
|
||||||
|
</VModal>
|
||||||
|
<div class="flex h-screen">
|
||||||
|
<div class="flex-1">
|
||||||
|
<div
|
||||||
|
class="grid h-16 grid-cols-2 items-center bg-white py-2 px-4 drop-shadow-sm sm:grid-cols-3"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<h2 class="truncate text-xl font-bold text-gray-800">
|
||||||
|
<span>Anatole</span>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<div class="hidden justify-center sm:flex">
|
||||||
|
<VTabbar
|
||||||
|
v-model:active-id="deviceActiveId"
|
||||||
|
:items="devices"
|
||||||
|
type="outline"
|
||||||
|
></VTabbar>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-end">
|
||||||
|
<VSpace>
|
||||||
|
<VButton type="default" @click="settingVisible = true">
|
||||||
|
<template #icon>
|
||||||
|
<IconSettings class="h-full w-full" />
|
||||||
|
</template>
|
||||||
|
设置
|
||||||
|
</VButton>
|
||||||
|
<VButton type="secondary">
|
||||||
|
<template #icon>
|
||||||
|
<IconSave class="h-full w-full" />
|
||||||
|
</template>
|
||||||
|
保存
|
||||||
|
</VButton>
|
||||||
|
</VSpace>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="flex h-full items-center justify-center"
|
||||||
|
style="height: calc(100vh - 4rem)"
|
||||||
|
>
|
||||||
|
<iframe
|
||||||
|
:class="iframeClasses"
|
||||||
|
class="border-none transition-all duration-300"
|
||||||
|
src="http://localhost:8090"
|
||||||
|
></iframe>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Teleport to="body">
|
||||||
|
<div
|
||||||
|
v-show="settingRootVisible"
|
||||||
|
class="drawer-wrapper fixed top-0 left-0 z-[99999] flex h-full w-full flex-row items-end justify-center"
|
||||||
|
>
|
||||||
|
<transition
|
||||||
|
enter-active-class="ease-out duration-200"
|
||||||
|
enter-from-class="opacity-0"
|
||||||
|
enter-to-class="opacity-100"
|
||||||
|
leave-active-class="ease-in duration-100"
|
||||||
|
leave-from-class="opacity-100"
|
||||||
|
leave-to-class="opacity-0"
|
||||||
|
@before-enter="settingRootVisible = true"
|
||||||
|
@after-leave="settingRootVisible = false"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-show="settingVisible"
|
||||||
|
class="drawer-layer absolute top-0 left-0 h-full w-full flex-none bg-gray-500 bg-opacity-75 transition-opacity"
|
||||||
|
@click="settingVisible = false"
|
||||||
|
></div>
|
||||||
|
</transition>
|
||||||
|
<transition
|
||||||
|
enter-active-class="transform transition ease-in-out duration-300"
|
||||||
|
enter-from-class="translate-y-full"
|
||||||
|
enter-to-class="translate-y-0"
|
||||||
|
leave-active-class="transform transition ease-in-out duration-300"
|
||||||
|
leave-from-class="translate-y-0"
|
||||||
|
leave-to-class="translate-y-full"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-show="settingVisible"
|
||||||
|
class="drawer-content relative flex h-3/4 w-screen flex-col items-stretch overflow-y-auto rounded-t-md bg-white shadow-xl"
|
||||||
|
>
|
||||||
|
<div class="drawer-body">
|
||||||
|
<div class="h-full w-full overflow-y-auto bg-white drop-shadow-sm">
|
||||||
|
<VTabs v-model:active-id="activeId" type="outline">
|
||||||
|
<VTabItem id="general" class="p-3" label="基础设置">
|
||||||
|
<form>
|
||||||
|
<div
|
||||||
|
class="space-y-8 divide-y divide-gray-200 sm:space-y-5"
|
||||||
|
>
|
||||||
|
<div class="space-y-6 sm:space-y-5">
|
||||||
|
<div class="space-y-2">
|
||||||
|
<label
|
||||||
|
class="block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2"
|
||||||
|
for="first-name"
|
||||||
|
>
|
||||||
|
Halo 当前版本:
|
||||||
|
</label>
|
||||||
|
<div class="mt-1 sm:col-span-2 sm:mt-0">
|
||||||
|
<VInput model-value="1.5.3"></VInput>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="space-y-2">
|
||||||
|
<label
|
||||||
|
class="block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2"
|
||||||
|
for="last-name"
|
||||||
|
>
|
||||||
|
首页图片:
|
||||||
|
</label>
|
||||||
|
<div class="mt-1 sm:col-span-2 sm:mt-0">
|
||||||
|
<VInput
|
||||||
|
model-value="https://halo.run/upload/2022/03/support-team.svg"
|
||||||
|
></VInput>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</VTabItem>
|
||||||
|
<VTabItem id="style" class="p-3" label="样式设置">
|
||||||
|
<form>
|
||||||
|
<div
|
||||||
|
class="space-y-8 divide-y divide-gray-200 sm:space-y-5"
|
||||||
|
>
|
||||||
|
<div class="space-y-6 sm:space-y-5">
|
||||||
|
<div class="space-y-2">
|
||||||
|
<label
|
||||||
|
class="block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2"
|
||||||
|
for="first-name"
|
||||||
|
>
|
||||||
|
文章代码高亮语言:
|
||||||
|
</label>
|
||||||
|
<div class="mt-1 sm:col-span-2 sm:mt-0">
|
||||||
|
<VTextarea></VTextarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="space-y-2">
|
||||||
|
<label
|
||||||
|
class="block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2"
|
||||||
|
for="last-name"
|
||||||
|
>
|
||||||
|
文章代码高亮主题:
|
||||||
|
</label>
|
||||||
|
<div class="mt-1 sm:col-span-2 sm:mt-0">
|
||||||
|
<VSelect>
|
||||||
|
<VOption value="java">Java</VOption>
|
||||||
|
<VOption value="c">C</VOption>
|
||||||
|
<VOption value="go">Go</VOption>
|
||||||
|
<VOption value="javascript">JavaScript</VOption>
|
||||||
|
</VSelect>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</VTabItem>
|
||||||
|
</VTabs>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</div>
|
||||||
|
</Teleport>
|
||||||
|
</template>
|
|
@ -1,211 +0,0 @@
|
||||||
<script lang="ts" setup>
|
|
||||||
import { VButton } from "@/components/base/button";
|
|
||||||
import { VInput } from "@/components/base/input";
|
|
||||||
import { VOption, VSelect } from "@/components/base/select";
|
|
||||||
import { VModal } from "@/components/base/modal";
|
|
||||||
import { VTextarea } from "@/components/base/textarea";
|
|
||||||
import { VCard } from "@/components/base/card";
|
|
||||||
import { VTabbar, VTabItem, VTabs } from "@/components/base/tabs";
|
|
||||||
import { computed, onMounted, ref } from "vue";
|
|
||||||
import { IconComputer, IconPhone, IconTablet } from "@/core/icons";
|
|
||||||
|
|
||||||
const activeId = ref("general");
|
|
||||||
const deviceActiveId = ref("desktop");
|
|
||||||
const attachmentSelectVisible = ref(false);
|
|
||||||
const devices = ref([
|
|
||||||
{
|
|
||||||
id: "desktop",
|
|
||||||
icon: IconComputer,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "tablet",
|
|
||||||
icon: IconTablet,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "phone",
|
|
||||||
icon: IconPhone,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
const iframeClasses = computed(() => {
|
|
||||||
if (deviceActiveId.value === "desktop") {
|
|
||||||
return "w-full h-full";
|
|
||||||
}
|
|
||||||
if (deviceActiveId.value === "tablet") {
|
|
||||||
return "w-2/3 h-2/3";
|
|
||||||
}
|
|
||||||
// phone
|
|
||||||
return "w-96 h-[50rem]";
|
|
||||||
});
|
|
||||||
|
|
||||||
const attachments = Array.from(new Array(50), (_, index) => index).map(
|
|
||||||
(index) => {
|
|
||||||
return {
|
|
||||||
id: index,
|
|
||||||
name: `attachment-${index}`,
|
|
||||||
url: `https://picsum.photos/1000/700?random=${index}`,
|
|
||||||
size: "1.2MB",
|
|
||||||
type: "image/png",
|
|
||||||
strategy: "本地存储",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
window.addEventListener(
|
|
||||||
"message",
|
|
||||||
function receiveMessageFromIframePage(event) {
|
|
||||||
if (event.data === "select_image") {
|
|
||||||
attachmentSelectVisible.value = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
false
|
|
||||||
);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<template>
|
|
||||||
<VModal
|
|
||||||
v-model:visible="attachmentSelectVisible"
|
|
||||||
:width="1240"
|
|
||||||
title="选择附件"
|
|
||||||
>
|
|
||||||
<div class="w-full">
|
|
||||||
<ul
|
|
||||||
class="grid grid-cols-2 gap-x-2 gap-y-3 sm:grid-cols-3 md:grid-cols-2 xl:grid-cols-8 2xl:grid-cols-8"
|
|
||||||
role="list"
|
|
||||||
>
|
|
||||||
<li
|
|
||||||
v-for="(attachment, index) in attachments"
|
|
||||||
:key="index"
|
|
||||||
class="relative"
|
|
||||||
>
|
|
||||||
<VCard :body-class="['!p-0']">
|
|
||||||
<div
|
|
||||||
class="group aspect-w-10 aspect-h-7 block w-full cursor-pointer overflow-hidden bg-gray-100"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
:src="attachment.url"
|
|
||||||
alt=""
|
|
||||||
class="pointer-events-none object-cover group-hover:opacity-75"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<p
|
|
||||||
class="pointer-events-none block truncate px-2 py-1 text-sm font-medium text-gray-700"
|
|
||||||
>
|
|
||||||
{{ attachment.name }}
|
|
||||||
</p>
|
|
||||||
</VCard>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<template #footer>
|
|
||||||
<VButton type="secondary">确定</VButton>
|
|
||||||
</template>
|
|
||||||
</VModal>
|
|
||||||
<div class="flex h-screen">
|
|
||||||
<div class="h-full w-96 overflow-y-auto bg-white drop-shadow-sm">
|
|
||||||
<VTabs v-model:active-id="activeId" type="outline">
|
|
||||||
<VTabItem id="general" class="p-3" label="基础设置">
|
|
||||||
<form>
|
|
||||||
<div class="space-y-8 divide-y divide-gray-200 sm:space-y-5">
|
|
||||||
<div class="space-y-6 sm:space-y-5">
|
|
||||||
<div class="space-y-2">
|
|
||||||
<label
|
|
||||||
class="block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2"
|
|
||||||
for="first-name"
|
|
||||||
>
|
|
||||||
Halo 当前版本:
|
|
||||||
</label>
|
|
||||||
<div class="mt-1 sm:col-span-2 sm:mt-0">
|
|
||||||
<VInput model-value="1.5.3"></VInput>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="space-y-2">
|
|
||||||
<label
|
|
||||||
class="block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2"
|
|
||||||
for="last-name"
|
|
||||||
>
|
|
||||||
首页图片:
|
|
||||||
</label>
|
|
||||||
<div class="mt-1 sm:col-span-2 sm:mt-0">
|
|
||||||
<VInput
|
|
||||||
model-value="https://halo.run/upload/2022/03/support-team.svg"
|
|
||||||
></VInput>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</VTabItem>
|
|
||||||
<VTabItem id="style" class="p-3" label="样式设置">
|
|
||||||
<form>
|
|
||||||
<div class="space-y-8 divide-y divide-gray-200 sm:space-y-5">
|
|
||||||
<div class="space-y-6 sm:space-y-5">
|
|
||||||
<div class="space-y-2">
|
|
||||||
<label
|
|
||||||
class="block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2"
|
|
||||||
for="first-name"
|
|
||||||
>
|
|
||||||
文章代码高亮语言:
|
|
||||||
</label>
|
|
||||||
<div class="mt-1 sm:col-span-2 sm:mt-0">
|
|
||||||
<VTextarea></VTextarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="space-y-2">
|
|
||||||
<label
|
|
||||||
class="block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2"
|
|
||||||
for="last-name"
|
|
||||||
>
|
|
||||||
文章代码高亮主题:
|
|
||||||
</label>
|
|
||||||
<div class="mt-1 sm:col-span-2 sm:mt-0">
|
|
||||||
<VSelect>
|
|
||||||
<VOption value="java">Java</VOption>
|
|
||||||
<VOption value="c">C</VOption>
|
|
||||||
<VOption value="go">Go</VOption>
|
|
||||||
<VOption value="javascript">JavaScript</VOption>
|
|
||||||
</VSelect>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</VTabItem>
|
|
||||||
</VTabs>
|
|
||||||
</div>
|
|
||||||
<div class="flex-1">
|
|
||||||
<div
|
|
||||||
class="flex h-16 items-center justify-between bg-white p-2 drop-shadow-sm"
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
<h2 class="truncate text-xl font-bold text-gray-800">
|
|
||||||
<span>Anatole</span>
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<VTabbar
|
|
||||||
v-model:active-id="deviceActiveId"
|
|
||||||
:items="devices"
|
|
||||||
type="outline"
|
|
||||||
></VTabbar>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<VButton type="secondary">保存</VButton>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="flex h-full items-center justify-center"
|
|
||||||
style="height: calc(100vh - 4rem)"
|
|
||||||
>
|
|
||||||
<iframe
|
|
||||||
:class="iframeClasses"
|
|
||||||
class="border-none transition-all duration-200"
|
|
||||||
src="http://localhost:8090"
|
|
||||||
></iframe>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
Loading…
Reference in New Issue