feat: 优化登陆状态

master
luoer 2023-10-12 17:38:06 +08:00
parent be45f03006
commit c9d63cde28
32 changed files with 272 additions and 243 deletions

View File

@ -5,12 +5,13 @@
<component v-else :is="Component"></component> <component v-else :is="Component"></component>
</router-view> </router-view>
</a-config-provider> </a-config-provider>
<!-- <div> <div v-if="false">
<my-editor></my-editor> <my-editor></my-editor>
</div> --> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import MyEditor from "@/components/editor/index.vue";
</script> </script>
<style scoped></style> <style scoped></style>

View File

@ -4,13 +4,12 @@ import { Font } from "./interface";
export * from "./interface"; export * from "./interface";
export const FontRender = Render; export const FontRender = Render;
export const FontOption = Option; export const FontOption = Option;
export const font: Font = { export const font: Font = {
content: "请输入文字", content: "请输入文字",
family: "microsoft yahei", family: "microsoft yahei",
size: 14, size: 24,
color: "#000000", color: "#000000",
bold: false, bold: false,
italic: false, italic: false,

View File

@ -1,6 +1,6 @@
<template> <template>
<div> <div>
<slot name="content"> <slot>
<a-form-item label="内容"> <a-form-item label="内容">
<a-textarea v-model="data.content" placeholder="输入内容..."></a-textarea> <a-textarea v-model="data.content" placeholder="输入内容..."></a-textarea>
</a-form-item> </a-form-item>
@ -15,7 +15,7 @@
<a-select v-model="data.family" :options="FontFamilyOptions" class="w-full overflow-hidden"> </a-select> <a-select v-model="data.family" :options="FontFamilyOptions" class="w-full overflow-hidden"> </a-select>
</a-form-item> </a-form-item>
<a-form-item label="大小"> <a-form-item label="大小">
<a-input-number v-model="data.size" :min="12"> </a-input-number> <a-input-number v-model="data.size" :min="12" :step="2"> </a-input-number>
</a-form-item> </a-form-item>
</div> </div>
@ -57,7 +57,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { PropType } from "vue"; import { PropType } from "vue";
import InputColor from "../../components/InputColor.vue"; import InputColor from "../../../components/InputColor.vue";
import { AlignOptions, Font, FontFamilyOptions } from "./interface"; import { AlignOptions, Font, FontFamilyOptions } from "./interface";
defineProps({ defineProps({

View File

@ -1,9 +1,10 @@
import { defineBlocker } from "../../config"; import { defineBlocker } from "../../config";
import { DateData } from "./interface"; import { Date } from "./interface";
import { font } from "../components/font";
import Option from "./option.vue"; import Option from "./option.vue";
import Render from "./render.vue"; import Render from "./render.vue";
export default defineBlocker<DateData>({ export default defineBlocker<Date>({
type: "date", type: "date",
icon: "icon-park-outline-calendar", icon: "icon-park-outline-calendar",
title: "日期组件", title: "日期组件",
@ -25,18 +26,9 @@ export default defineBlocker<DateData>({
actived: false, actived: false,
resizable: true, resizable: true,
draggable: true, draggable: true,
data: { params: {
format: "YYYY-MM-DD", format: "YYYY-MM-DD",
fontCh: { fontCh: { ...font, content: "YYYY-MM-DD" },
content: "请输入文字",
family: "微软雅黑",
size: 14,
color: "#000000",
bold: false,
italic: false,
underline: false,
align: 3,
},
}, },
}, },
}); });

View File

@ -1,9 +1,20 @@
import { Font } from "../font"; import { Block } from "../../config";
import { Font } from "../components/font";
export interface DateData { export interface DatePrams {
/** /**
* *
*/ */
format: 'YYYY-MM-DD' | 'YYYY年MM月DD日'; format: 'YYYY-MM-DD' | 'YYYY年MM月DD日';
fontCh: Font; fontCh: Font;
} }
/**
*
*/
export type Date = Block<DatePrams>;
/**
*
*/
export const FomatSuguestions = ['YYYY-MM-DD', 'YYYY年MM月DD日'];

View File

@ -1,18 +1,38 @@
<template> <template>
<base-option :data="data"></base-option> <base-option :data="data"></base-option>
<font-option :data="data.data.fontCh"></font-option> <a-divider></a-divider>
<font-option :data="data.params.fontCh">
<a-form-item label="日期格式">
<a-auto-complete
v-model="data.params.fontCh.content"
:data="FomatSuguestions"
:allow-clear="true"
placeholder="例如 HH:mm:ss"
>
<template #suffix>
<a-popover>
<i class="icon-park-outline-info text-gray-400 cursor-pointer"></i>
<template #content>
<p>YYYY 4位数的年数, 例如 2020</p>
<p>MM 2位数的月份, 例如 01</p>
<p>DD 2位数的天数, 例如 02</p>
</template>
</a-popover>
</template>
</a-auto-complete>
</a-form-item>
</font-option>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { PropType } from "vue"; import { PropType } from "vue";
import BaseOption from "../../components/BaseOption.vue"; import BaseOption from "../../components/BaseOption.vue";
import { Block } from "../../config"; import { FontOption } from "../components/font";
import { FontOption } from "../font"; import { Date, FomatSuguestions } from "./interface";
import { DateData } from "./interface";
defineProps({ defineProps({
data: { data: {
type: Object as PropType<Block<DateData>>, type: Object as PropType<Date>,
required: true, required: true,
}, },
}); });
@ -25,3 +45,4 @@ defineProps({
} }
} }
</style> </style>
../components/font

View File

@ -1,22 +1,22 @@
<template> <template>
<font-render :data="data.data.fontCh"> <font-render :data="data.params.fontCh">
{{ dayjs().format(data.data.format) }} {{ dayjs().format(data.params.fontCh.content) }}
</font-render> </font-render>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { dayjs } from '@/libs/dayjs'; import { dayjs } from "@/libs/dayjs";
import { PropType } from "vue"; import { PropType } from "vue";
import { Block } from "../../config"; import { FontRender } from "../components/font";
import { FontRender } from "../font"; import { Date } from "./interface";
import { DateData } from "./interface";
const props = defineProps({ defineProps({
data: { data: {
type: Object as PropType<Block<DateData>>, type: Object as PropType<Date>,
required: true, required: true,
}, },
}); });
</script> </script>
<style scoped></style> <style scoped></style>
../components/font

View File

@ -1,15 +1,14 @@
import Date from './date'; import { Blocker } from "../config";
import Text from "./text";
import Time from "./time";
export const BlockerMap = { const blockers: Record<string, Blocker> = import.meta.glob("./*/index.ts", { eager: true, import: "default" });
[Text.type]: Text, const BlockerMap: Record<string, Blocker> = {};
[Date.type]: Date,
[Time.type]: Time,
};
export const getBlockerRender = (type: string) => { for (const blocker of Object.values(blockers)) {
BlockerMap[blocker.type] = blocker;
}
const getBlockerRender = (type: string) => {
return BlockerMap[type].render; return BlockerMap[type].render;
}; };
export default BlockerMap; export { BlockerMap, getBlockerRender };

View File

@ -1,9 +1,10 @@
import { defineBlocker } from "../../config"; import { defineBlocker } from "../../config";
import Render from "./render.vue"; import Render from "./render.vue";
import Option from "./option.vue"; import Option from "./option.vue";
import { TextData } from "./interface"; import { Text } from "./interface";
import { font } from "../components/font";
export default defineBlocker<TextData>({ export default defineBlocker<Text>({
type: "text", type: "text",
icon: "icon-park-outline-text", icon: "icon-park-outline-text",
title: "文本组件", title: "文本组件",
@ -25,19 +26,14 @@ export default defineBlocker<TextData>({
actived: false, actived: false,
resizable: true, resizable: true,
draggable: true, draggable: true,
data: { params: {
marquee: false, marquee: false,
marqueeSpeed: 1, speed: 100,
marqueeDirection: "left", direction: "left",
fontCh: { fontCh: {
content: "请输入文字", ...font,
family: "微软雅黑", content:
size: 14, "温馨提示:乘客您好,进站检票时,持票卡的乘客请在右侧闸机上方感应区内验票,扫码过闸的乘客请将乘车码对准闸机扫码口,扇门打开后依次进闸。乘车过程中请妥善保管好车票,以免丢失。",
color: "#000000",
bold: false,
italic: false,
underline: false,
align: 3,
}, },
}, },
}, },

View File

@ -1,6 +1,7 @@
import { Font } from "../font"; import { Block } from "../../config";
import { Font } from "../components/font";
export interface TextData { export interface TextPrams {
/** /**
* *
*/ */
@ -8,17 +9,25 @@ export interface TextData {
/** /**
* *
*/ */
marqueeSpeed?: number; speed?: number;
/** /**
* *
*/ */
marqueeDirection?: "left" | "right" | "up" | "down"; direction?: "left" | "right" | "up" | "down";
/** /**
* () * ()
*/ */
fontCh: Font; fontCh: Font;
} }
/**
*
*/
export type Text = Block<TextPrams>;
/**
*
*/
export const DirectionOptions = [ export const DirectionOptions = [
{ {
icon: "icon-park-outline-arrow-left", icon: "icon-park-outline-arrow-left",

View File

@ -2,47 +2,42 @@
<div> <div>
<base-option :data="data"></base-option> <base-option :data="data"></base-option>
</div> </div>
<a-divider></a-divider>
<div> <div>
<a-divider></a-divider>
<div class="muti-form-item grid grid-cols-2 gap-x-4"> <div class="muti-form-item grid grid-cols-2 gap-x-4">
<a-form-item label="是否滚动"> <a-form-item label="是否滚动">
<a-radio-group type="button" v-model="data.data.marquee" class="!w-full"> <a-radio-group type="button" v-model="data.params.marquee" class="!w-full">
<a-radio :value="false"></a-radio> <a-radio :value="false"></a-radio>
<a-radio :value="true"></a-radio> <a-radio :value="true"></a-radio>
</a-radio-group> </a-radio-group>
</a-form-item> </a-form-item>
<a-form-item v-if="data.data.marquee" label="滚动速度"> <a-form-item :disabled="!data.params.marquee" label="滚动速度">
<a-input-number v-model="data.data.marqueeSpeed" :min="10" :step="10"></a-input-number> <a-input-number v-model="data.params.speed" :min="10" :step="10"></a-input-number>
</a-form-item> </a-form-item>
</div> </div>
<a-form-item v-if="data.data.marquee" label="滚动方向"> <a-form-item :disabled="!data.params.marquee" label="滚动方向">
<a-radio-group type="button" v-model="data.data.marqueeDirection" class="!w-full"> <a-radio-group type="button" v-model="data.params.direction" class="!w-full">
<a-radio v-for="item in DirectionOptions" :key="item.value" :value="item.value" class="dir-radio"> <a-radio v-for="item in DirectionOptions" :key="item.value" :value="item.value" class="dir-radio">
<i :class="item.icon"></i> <i :class="item.icon"></i>
</a-radio> </a-radio>
</a-radio-group> </a-radio-group>
</a-form-item> </a-form-item>
</div> </div>
<a-divider :margin="0"></a-divider> <a-divider></a-divider>
<div> <div>
<div class="my-4 leading-0"> <font-option :data="data.params.fontCh"></font-option>
<i class="icon-park-outline-text-style"></i>
内容(中文)
</div>
<font-option :data="data.data.fontCh"></font-option>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { PropType } from "vue"; import { PropType } from "vue";
import BaseOption from "../../components/BaseOption.vue"; import BaseOption from "../../components/BaseOption.vue";
import { Block } from "../../config"; import { FontOption } from "../components/font";
import { FontOption } from "../font"; import { DirectionOptions, Text } from "./interface";
import { DirectionOptions, TextData } from "./interface";
defineProps({ defineProps({
data: { data: {
type: Object as PropType<Block<TextData>>, type: Object as PropType<Text>,
required: true, required: true,
}, },
}); });
@ -55,3 +50,4 @@ defineProps({
} }
} }
</style> </style>
../components/font

View File

@ -1,32 +1,27 @@
<template> <template>
<ani-marquee <ani-marquee v-if="data.params.marquee" :style="style" :speed="data.params.speed" :direction="data.params.direction">
v-if="data.data.marquee" {{ data.params.fontCh.content }}
:style="style"
:speed="data.data.marqueeSpeed"
:direction="data.data.marqueeDirection"
>
{{ data.data.fontCh.content }}
</ani-marquee> </ani-marquee>
<font-render v-else :data="data.data.fontCh"></font-render> <font-render v-else :data="data.params.fontCh"></font-render>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { PropType } from "vue"; import { PropType } from "vue";
import { FontRender, getFontStyle } from "../font"; import { FontRender, getFontStyle } from "../components/font";
import { Block } from "../../config"; import { Text } from "./interface";
import { TextData } from "./interface";
import AniMarquee from "./marquee.vue"; import AniMarquee from "./marquee.vue";
const props = defineProps({ const props = defineProps({
data: { data: {
type: Object as PropType<Block<TextData>>, type: Object as PropType<Text>,
required: true, required: true,
}, },
}); });
const style = computed(() => { const style = computed(() => {
return getFontStyle(props.data.data.fontCh); return getFontStyle(props.data.params.fontCh);
}); });
</script> </script>
<style scoped></style> <style scoped></style>
../components/font

View File

@ -1,9 +1,10 @@
import { defineBlocker } from "../../config"; import { defineBlocker } from "../../config";
import { TimeData } from "./interface"; import { Time } from "./interface";
import Option from "./option.vue"; import Option from "./option.vue";
import Render from "./render.vue"; import Render from "./render.vue";
import { font } from "../components/font";
export default defineBlocker<TimeData>({ export default defineBlocker<Time>({
type: "time", type: "time",
icon: "icon-park-outline-time", icon: "icon-park-outline-time",
title: "时间组件", title: "时间组件",
@ -25,18 +26,8 @@ export default defineBlocker<TimeData>({
actived: false, actived: false,
resizable: true, resizable: true,
draggable: true, draggable: true,
data: { params: {
format: "HH:mm:ss", fontCh: { ...font, content: "HH:mm:ss" },
fontCh: {
content: "请输入文字",
family: "微软雅黑",
size: 14,
color: "#000000",
bold: false,
italic: false,
underline: false,
align: 3,
},
}, },
}, },
}); });

View File

@ -1,9 +1,19 @@
import { Font } from "../font"; import { Block } from "../../config";
import { Font } from "../components/font";
export interface TimeData { export interface TimeParams {
/** /**
* *
*/ */
format: string;
fontCh: Font; fontCh: Font;
} }
/**
*
*/
export type Time = Block<TimeParams>;
/**
*
*/
export const FomatSuguestions = ["HH:mm:ss", "HH:mm", "HH时mm分ss秒", "HH时mm分"];

View File

@ -1,25 +1,38 @@
<template> <template>
<base-option :data="data"></base-option> <base-option :data="data"></base-option>
<a-divider></a-divider> <a-divider></a-divider>
<font-option :data="data.data.fontCh"> <font-option :data="data.params.fontCh">
<template #content> <a-form-item label="时间格式">
<a-form-item label="时间格式"> <a-auto-complete
<a-input v-model="data.data.fontCh.content" placeholder="例如 HH:mm:ss"></a-input> v-model="data.params.fontCh.content"
</a-form-item> :data="FomatSuguestions"
</template> :allow-clear="true"
placeholder="例如 HH:mm:ss"
>
<template #suffix>
<a-popover>
<i class="icon-park-outline-info text-gray-400 cursor-pointer"></i>
<template #content>
<p>HH 两位数的小时, 01 24</p>
<p>mm 两位数的分钟, 00 59</p>
<p>ss 两位数的秒数, 00 59</p>
</template>
</a-popover>
</template>
</a-auto-complete>
</a-form-item>
</font-option> </font-option>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { PropType } from "vue"; import { PropType } from "vue";
import BaseOption from "../../components/BaseOption.vue"; import BaseOption from "../../components/BaseOption.vue";
import { Block } from "../../config"; import { FontOption } from "../components/font";
import { FontOption } from "../font"; import { Time, FomatSuguestions } from "./interface";
import { TimeData } from "./interface";
defineProps({ defineProps({
data: { data: {
type: Object as PropType<Block<TimeData>>, type: Object as PropType<Time>,
required: true, required: true,
}, },
}); });
@ -32,3 +45,4 @@ defineProps({
} }
} }
</style> </style>
../components/font

View File

@ -1,29 +1,29 @@
<template> <template>
<font-render :data="data.data.fontCh"> <font-render :data="data.params.fontCh">
{{ currentTime }} {{ time }}
</font-render> </font-render>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { dayjs } from "@/libs/dayjs"; import { dayjs } from "@/libs/dayjs";
import { PropType, onMounted, onUnmounted, ref } from "vue"; import { PropType, onMounted, onUnmounted, ref } from "vue";
import { Block } from "../../config"; import { FontRender } from "../components/font";
import { FontRender } from "../font"; import { Time } from "./interface";
import { TimeData } from "./interface";
const props = defineProps({ const props = defineProps({
data: { data: {
type: Object as PropType<Block<TimeData>>, type: Object as PropType<Time>,
required: true, required: true,
}, },
}); });
const currentTime = ref(""); const format = computed(() => props.data.params.fontCh.content || "HH:mm:ss");
const timer: any = null; const time = ref(dayjs().format(format.value));
let timer: any = null;
onMounted(() => { onMounted(() => {
const timer = setInterval(() => { timer = setInterval(() => {
currentTime.value = dayjs().format(props.data.data.format); time.value = dayjs().format(format.value);
}, 1000); }, 1000);
}); });
@ -33,3 +33,4 @@ onUnmounted(() => {
</script> </script>
<style scoped></style> <style scoped></style>
../components/font

View File

@ -278,6 +278,7 @@ const gradient = (startColor: string, endColor: string, step: number) => {
transition: all 0.3s ease; transition: all 0.3s ease;
box-sizing: content-box; box-sizing: content-box;
z-index: 99999; z-index: 99999;
right: 0;
h3 { h3 {
margin: 0; margin: 0;
font-size: 14px; font-size: 14px;

View File

@ -27,7 +27,7 @@
></a-input-search> ></a-input-search>
</div> </div>
</div> </div>
<a-spin :loading="loading" :dot="true" tip="正在加载中,请稍等..." class="h-[450px] w-full"> <a-spin :loading="loading" :dot="true" tip="加载中..." class="h-[450px] w-full">
<div class="h-[450px] grid grid-cols-5 grid-rows-2 items-start justify-between gap-4 mt-2"> <div class="h-[450px] grid grid-cols-5 grid-rows-2 items-start justify-between gap-4 mt-2">
<div <div
v-for="item in images" v-for="item in images"
@ -40,10 +40,10 @@
<img :src="item.url" class="w-full aspect-video object-cover rounded hover:opacity-80" /> <img :src="item.url" class="w-full aspect-video object-cover rounded hover:opacity-80" />
</div> </div>
<div class="mt-2 flex items-center gap-2"> <div class="mt-2 flex items-center gap-2">
<div class="flex-1 truncate"> <div class="flex-1 truncate text-gray-600" :class="{ 'text-brand-500': selectedKeys.includes(item.id) }">
{{ item.title }} {{ item.title }}(<span class="text-xs text-gray-400">1280 * 800</span>)
</div> </div>
<div class="text-xs text-gray-400">1280 * 800</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,6 +1,6 @@
<template> <template>
<a-input v-model="model"> <a-input v-model="model" placeholder="例如:#0099ff">
<template #prefix> <template #suffix>
<color-picker v-model="model"></color-picker> <color-picker v-model="model"></color-picker>
</template> </template>
</a-input> </a-input>

View File

@ -1,6 +1,6 @@
<template> <template>
<a-input v-model="model" class="group w-full" allow-clear placeholder="暂无"> <a-input v-model="model" class="group w-full" allow-clear placeholder="例如: a.com/b.png">
<template #prefix> <template #suffix>
<a-link @click="visible = true">选择</a-link> <a-link @click="visible = true">选择</a-link>
</template> </template>
</a-input> </a-input>

View File

@ -9,27 +9,9 @@ export interface Block<T = any> {
yFixed: boolean; yFixed: boolean;
bgImage?: string; bgImage?: string;
bgColor?: string; bgColor?: string;
data: T; actived: boolean;
resizable: boolean;
draggable: boolean;
meta: Record<string, any>; meta: Record<string, any>;
actived: boolean, params: T;
resizable: boolean,
draggable: boolean,
} }
export const DefaultBlock: Block = {
id: "",
type: "",
x: 0,
y: 0,
w: 50,
h: 50,
xFixed: false,
yFixed: false,
bgImage: "",
bgColor: "",
data: {},
meta: {},
actived: false,
resizable: true,
draggable: true,
};

View File

@ -1,7 +1,7 @@
import { Component } from "vue"; import { Component } from "vue";
import { Block } from "./block"; import { Block } from "./block";
interface Blocker<T = any> { export interface Blocker<T = any> {
/** /**
* *
*/ */
@ -21,7 +21,7 @@ interface Blocker<T = any> {
/** /**
* *
*/ */
initial: Block<T>; initial: T;
/** /**
* *
*/ */

View File

@ -1,13 +1,42 @@
export interface Container { export interface Container {
/**
* id
*/
id: number | string; id: number | string;
/**
* X
*/
x: number; x: number;
/**
* Y
*/
y: number; y: number;
/**
*
*/
zoom: number; zoom: number;
/**
*
*/
title: string; title: string;
/**
*
*/
description: string; description: string;
/**
*
*/
width: number; width: number;
/**
*
*/
height: number; height: number;
/**
*
*/
bgImage: string; bgImage: string;
/**
*
*/
bgColor: string; bgColor: string;
} }

View File

@ -3,14 +3,38 @@ import { Block } from "./block";
import { Container } from "./container"; import { Container } from "./container";
export interface Context { export interface Context {
/**
*
*/
current: Ref<{ current: Ref<{
block: Block | null; block: Block | null;
rightPanelCollapsed: boolean;
}>; }>;
/**
*
*/
blocks: Ref<Block[]>; blocks: Ref<Block[]>;
/**
*
*/
container: Ref<Container>; container: Ref<Container>;
/**
*
* @param block
* @returns
*/
setCurrentBlock: (block: Block | null) => void; setCurrentBlock: (block: Block | null) => void;
/**
*
*/
setContainerOrigin: () => void; setContainerOrigin: () => void;
/**
*
*/
saveData: () => void; saveData: () => void;
/**
*
*/
loadData: () => void; loadData: () => void;
} }

View File

@ -5,13 +5,13 @@
<panel-header></panel-header> <panel-header></panel-header>
</div> </div>
<div class="grid grid-cols-[auto_1fr_auto]"> <div class="grid grid-cols-[auto_1fr_auto]">
<div class="bg-white shadow-[2px_0_6px_rgba(0,0,0,.05)] z-10"> <div class="h-full overflow-hidden bg-white shadow-[2px_0_6px_rgba(0,0,0,.05)] z-10">
<panel-left></panel-left> <panel-left></panel-left>
</div> </div>
<div class="w-full h-full"> <div class="w-full h-full">
<panel-main></panel-main> <panel-main></panel-main>
</div> </div>
<div class="bg-white shadow-[-2px_0_6px_rgba(0,0,0,.05)]"> <div class="h-full overflow-hidden bg-white shadow-[-2px_0_6px_rgba(0,0,0,.05)]">
<panel-right></panel-right> <panel-right></panel-right>
</div> </div>
</div> </div>
@ -31,6 +31,7 @@ import PanelRight from "./panel-right/index.vue";
*/ */
const current = ref({ const current = ref({
block: null as Block | null, block: null as Block | null,
rightPanelCollapsed: false,
}); });
/** /**

View File

@ -1,5 +1,5 @@
<template> <template>
<div class="h-full flex items-center justify-between gap-4 px-4 bg-white"> <div class="h-full flex items-center justify-between gap-4 pl-4 pr-2 bg-white">
<div class="flex-1"> <div class="flex-1">
<div class="group"> <div class="group">
<span class="text-gray-400">描述: </span> <span class="text-gray-400">描述: </span>
@ -58,6 +58,16 @@
</a-form> </a-form>
</template> </template>
</a-popover> </a-popover>
<a-tooltip :content="current.rightPanelCollapsed ? '展开' : '折叠'" position="bottom">
<a-button type="text" @click="current.rightPanelCollapsed = !current.rightPanelCollapsed">
<template #icon>
<i
class="text-base !text-gray-600"
:class="current.rightPanelCollapsed ? 'icon-park-outline-expand-right' : 'icon-park-outline-expand-left'"
></i>
</template>
</a-button>
</a-tooltip>
</div> </div>
</div> </div>
</template> </template>
@ -68,7 +78,7 @@ import InputImage from "../../components/InputImage.vue";
import { ContextKey } from "../../config"; import { ContextKey } from "../../config";
import AniTexter from "./texter.vue"; import AniTexter from "./texter.vue";
const { container, blocks, setContainerOrigin } = inject(ContextKey)!; const { container, blocks, current, setContainerOrigin } = inject(ContextKey)!;
</script> </script>
<style scoped></style> <style scoped></style>

View File

@ -23,7 +23,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import BlockerMap from "../blocks"; import { BlockerMap } from "../blocks";
import { ContextKey } from "../config"; import { ContextKey } from "../config";
import AniBlock from "./components/block.vue"; import AniBlock from "./components/block.vue";
import AniHeader from "./components/header.vue"; import AniHeader from "./components/header.vue";
@ -32,10 +32,10 @@ import { cloneDeep } from "lodash-es";
const { blocks, container, setCurrentBlock } = inject(ContextKey)!; const { blocks, container, setCurrentBlock } = inject(ContextKey)!;
const onClick = (e: Event) => { const onClick = (e: Event) => {
if(e.target === e.currentTarget) { if (e.target === e.currentTarget) {
setCurrentBlock(null); setCurrentBlock(null);
} }
} };
const isStart = ref(false); const isStart = ref(false);
const position = ref({ const position = ref({

View File

@ -1,57 +1,27 @@
<template> <template>
<div class="w-[248px] overflow-hidden p-3"> <div class="h-full w-[248px] overflow-hidden" :style="`display: ${current.rightPanelCollapsed ? 'none' : 'block'}`">
<a-radio-group type="button" class="w-full mb-2"> <div v-if="current.block" class="p-3">
<a-radio value="1">基本</a-radio> <a-radio-group type="button" default-value="1" class="w-full mb-2">
<a-radio value="2">文本</a-radio> <a-radio value="1">属性</a-radio>
</a-radio-group> <a-radio value="2">文本</a-radio>
<a-form :model="block" layout="vertical"> </a-radio-group>
<div v-if="current.block" class="muti-form-item mt-2"> <a-form :model="{}" layout="vertical">
<component :is="BlockerMap[current.block.type].option" :data="current.block" /> <div class="muti-form-item mt-2">
</div> <component :is="BlockerMap[current.block.type].option" :data="current.block" />
<a-empty v-else :description="'选择组件后显示'" class="mt-8"></a-empty> </div>
</a-form> </a-form>
</div>
<div v-else class="w-full h-full flex justify-center items-center">
<a-empty :description="'选择组件后显示'" class="mt-8"></a-empty>
</div>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { BlockerMap } from "../blocks"; import { BlockerMap } from "../blocks";
import { ContextKey } from "../config"; import { ContextKey } from "../config";
import TextAttr from "./text-attr.vue";
const { current } = inject(ContextKey)!; const { current } = inject(ContextKey)!;
const item = ref<any>({
x: 0,
y: 0,
w: 200,
h: 100,
bgColor: "#0099ff",
xFixed: false,
yFixed: false,
resizable: true,
draggable: true,
});
const block = ref({
x: 10,
y: 19,
w: 20,
h: 5,
volume: 39,
textStyle: {
family: "simsun",
bold: false,
italic: false,
underline: false,
size: 14,
color: "#33cc99",
align: 3,
},
meta: {
vFixed: false,
hFixed: false,
},
});
</script> </script>
<style scoped></style> <style scoped></style>

View File

@ -22,14 +22,14 @@
<div class="text-2xl">欢迎登陆</div> <div class="text-2xl">欢迎登陆</div>
<div class="text-base text-gray-500 mt-2">{{ meridiem }}欢迎登陆{{ appStore.title }}!</div> <div class="text-base text-gray-500 mt-2">{{ meridiem }}欢迎登陆{{ appStore.title }}!</div>
<a-form ref="formRef" :model="model" :rules="formRules" layout="vertical" class="mt-8"> <a-form ref="formRef" :model="model" :rules="formRules" layout="vertical" class="mt-8">
<a-form-item field="username" label="账号" hide-asterisk> <a-form-item field="username" label="账号" :disabled="loading" hide-asterisk>
<a-input v-model="model.username" placeholder="请输入账号/手机号/邮箱" allow-clear> <a-input v-model="model.username" placeholder="请输入账号/手机号/邮箱" allow-clear>
<template #prefix> <template #prefix>
<i class="icon-park-outline-user" /> <i class="icon-park-outline-user" />
</template> </template>
</a-input> </a-input>
</a-form-item> </a-form-item>
<a-form-item field="password" label="密码" hide-asterisk> <a-form-item field="password" label="密码" :disabled="loading" hide-asterisk>
<a-input-password v-model="model.password" placeholder="请输入密码" allow-clear> <a-input-password v-model="model.password" placeholder="请输入密码" allow-clear>
<template #prefix> <template #prefix>
<i class="icon-park-outline-lock" /> <i class="icon-park-outline-lock" />
@ -38,11 +38,11 @@
</a-form-item> </a-form-item>
<a-space :size="16" direction="vertical"> <a-space :size="16" direction="vertical">
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<a-checkbox checked="rememberPassword">记住我</a-checkbox> <a-checkbox checked="rememberPassword" :disabled="loading">记住我</a-checkbox>
<a-link @click="onForgetPassword">?</a-link> <a-link @click="onForgetPassword">?</a-link>
</div> </div>
<a-button type="primary" html-type="submit" long class="mt-2" :loading="loading" @click="onSubmitForm"> <a-button type="primary" html-type="submit" long class="mt-2" :loading="loading" @click="onSubmitForm">
立即登录 {{ loading ? '登陆中' : '立即登录' }}
</a-button> </a-button>
<p type="text" long class="text-gray-400 text-center m-0">暂不支持其他方式登录</p> <p type="text" long class="text-gray-400 text-center m-0">暂不支持其他方式登录</p>
</a-space> </a-space>

View File

@ -7,57 +7,34 @@ export {}
declare module '@vue/runtime-core' { declare module '@vue/runtime-core' {
export interface GlobalComponents { export interface GlobalComponents {
AAlert: typeof import('@arco-design/web-vue')['Alert'] AAutoComplete: typeof import('@arco-design/web-vue')['AutoComplete']
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'] AButton: typeof import('@arco-design/web-vue')['Button']
ACard: typeof import('@arco-design/web-vue')['Card']
ACheckbox: typeof import('@arco-design/web-vue')['Checkbox'] ACheckbox: typeof import('@arco-design/web-vue')['Checkbox']
ACheckboxGroup: typeof import('@arco-design/web-vue')['CheckboxGroup']
AConfigProvider: typeof import('@arco-design/web-vue')['ConfigProvider'] AConfigProvider: typeof import('@arco-design/web-vue')['ConfigProvider']
ADatePicker: typeof import('@arco-design/web-vue')['DatePicker']
ADivider: typeof import('@arco-design/web-vue')['Divider'] ADivider: typeof import('@arco-design/web-vue')['Divider']
ADoption: typeof import('@arco-design/web-vue')['Doption'] ADoption: typeof import('@arco-design/web-vue')['Doption']
ADrawer: typeof import('@arco-design/web-vue')['Drawer']
ADropdown: typeof import('@arco-design/web-vue')['Dropdown']
ADropdownButton: typeof import('@arco-design/web-vue')['DropdownButton'] 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']
AImage: typeof import('@arco-design/web-vue')['Image']
AInput: typeof import('@arco-design/web-vue')['Input'] AInput: typeof import('@arco-design/web-vue')['Input']
AInputNumber: typeof import('@arco-design/web-vue')['InputNumber'] AInputNumber: typeof import('@arco-design/web-vue')['InputNumber']
AInputPassword: typeof import('@arco-design/web-vue')['InputPassword'] AInputPassword: typeof import('@arco-design/web-vue')['InputPassword']
AInputSearch: typeof import('@arco-design/web-vue')['InputSearch'] AInputSearch: typeof import('@arco-design/web-vue')['InputSearch']
ALayout: typeof import('@arco-design/web-vue')['Layout']
ALayoutContent: typeof import('@arco-design/web-vue')['LayoutContent']
ALayoutHeader: typeof import('@arco-design/web-vue')['LayoutHeader']
ALayoutSider: typeof import('@arco-design/web-vue')['LayoutSider']
ALink: typeof import('@arco-design/web-vue')['Link'] 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'] AMenu: typeof import('@arco-design/web-vue')['Menu']
AMenuItem: typeof import('@arco-design/web-vue')['MenuItem'] AMenuItem: typeof import('@arco-design/web-vue')['MenuItem']
AMenuItemGroup: typeof import('@arco-design/web-vue')['MenuItemGroup']
AModal: typeof import('@arco-design/web-vue')['Modal'] AModal: typeof import('@arco-design/web-vue')['Modal']
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']
ARadio: typeof import('@arco-design/web-vue')['Radio'] ARadio: typeof import('@arco-design/web-vue')['Radio']
ARadioGroup: typeof import('@arco-design/web-vue')['RadioGroup'] ARadioGroup: typeof import('@arco-design/web-vue')['RadioGroup']
AScrollbar: typeof import('@arco-design/web-vue')['Scrollbar']
ASelect: typeof import('@arco-design/web-vue')['Select'] ASelect: typeof import('@arco-design/web-vue')['Select']
ASpace: typeof import('@arco-design/web-vue')['Space'] ASpace: typeof import('@arco-design/web-vue')['Space']
ASpin: typeof import('@arco-design/web-vue')['Spin'] ASpin: typeof import('@arco-design/web-vue')['Spin']
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'] ATag: typeof import('@arco-design/web-vue')['Tag']
ATextarea: typeof import('@arco-design/web-vue')['Textarea'] ATextarea: typeof import('@arco-design/web-vue')['Textarea']
ATooltip: typeof import('@arco-design/web-vue')['Tooltip'] ATooltip: typeof import('@arco-design/web-vue')['Tooltip']
ATree: typeof import('@arco-design/web-vue')['Tree']
AUpload: typeof import('@arco-design/web-vue')['Upload']
BaseOption: typeof import('./../components/editor/components/BaseOption.vue')['default'] BaseOption: typeof import('./../components/editor/components/BaseOption.vue')['default']
Block: typeof import('./../components/editor/panel-main/components/block.vue')['default'] Block: typeof import('./../components/editor/panel-main/components/block.vue')['default']
BreadCrumb: typeof import('./../components/breadcrumb/bread-crumb.vue')['default'] BreadCrumb: typeof import('./../components/breadcrumb/bread-crumb.vue')['default']