parent
21fb121ab8
commit
3c633c2fcf
|
|
@ -0,0 +1 @@
|
|||
<svg t="1699574162110" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1543" width="200" height="200"><path d="M512 512m-512 0a512 512 0 1 0 1024 0 512 512 0 1 0-1024 0Z" fill="#FD8E66" p-id="1544"></path><path d="M377.745 354.306h63.05l-78.638 315.388h-63.05l78.638-315.388zM518.387 354.306h103.519c69.926 0 117.527 24.3 98.942 98.896-17.958 72.017-80.148 104.401-147.89 104.401H530.77L502.8 669.694h-63.05l78.637-315.388z m62.702 153.443c43.489 0 68.927-18.329 77.964-54.547 9.153-36.659-10.779-49.018-54.222-49.018h-35.823l-25.833 103.565h37.914z" fill="#FFFFFF" p-id="1545"></path></svg>
|
||||
|
After Width: | Height: | Size: 636 B |
|
|
@ -24,6 +24,7 @@ const fixedHeader = computed(() => settingsStore.fixedHeader);
|
|||
const showTagsView = computed(() => settingsStore.tagsView);
|
||||
const showSettings = computed(() => settingsStore.showSettings);
|
||||
const layout = computed(() => settingsStore.layout);
|
||||
const device = computed(() => appStore.device);
|
||||
|
||||
watchEffect(() => {
|
||||
if (width.value < WIDTH) {
|
||||
|
|
@ -43,7 +44,7 @@ watchEffect(() => {
|
|||
</script>
|
||||
<template>
|
||||
<div :class="{ hasTagsView: showTagsView }" class="main-container">
|
||||
<div :class="{ 'fixed-header': fixedHeader }">
|
||||
<div :class="{ 'fixed-header': fixedHeader, device: device }">
|
||||
<navbar v-if="layout === 'left'" />
|
||||
<tags-view v-if="showTagsView" />
|
||||
</div>
|
||||
|
|
@ -70,6 +71,10 @@ watchEffect(() => {
|
|||
width: calc(100% - 54px);
|
||||
}
|
||||
|
||||
.hideSidebar.mobile .fixed-header {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.isTop .fixed-header {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ const amountOutput = useTransition(amount, {
|
|||
});
|
||||
amount.value = 2000;
|
||||
|
||||
// 访问量
|
||||
// 访客数
|
||||
const visitCount = ref(0);
|
||||
const visitCountOutput = useTransition(visitCount, {
|
||||
duration: duration,
|
||||
|
|
@ -43,7 +43,7 @@ const visitCountOutput = useTransition(visitCount, {
|
|||
});
|
||||
visitCount.value = 2000;
|
||||
|
||||
// 留资数
|
||||
// IP数
|
||||
const dauCount = ref(0);
|
||||
const dauCountOutput = useTransition(dauCount, {
|
||||
duration: duration,
|
||||
|
|
@ -87,7 +87,7 @@ orderCount.value = 2000;
|
|||
<el-statistic :value="99">
|
||||
<template #title>
|
||||
<div class="flex items-center">
|
||||
<svg-icon icon-class="message" :size="16" />
|
||||
<svg-icon icon-class="message" :size="20" />
|
||||
<span class="text-[16px] ml-1">消息</span>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -96,7 +96,7 @@ orderCount.value = 2000;
|
|||
<el-statistic :value="50">
|
||||
<template #title>
|
||||
<div class="flex items-center">
|
||||
<svg-icon icon-class="todolist" :size="16" />
|
||||
<svg-icon icon-class="todolist" :size="20" />
|
||||
<span class="text-[16px] ml-1">待办</span>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -106,7 +106,7 @@ orderCount.value = 2000;
|
|||
<el-statistic :value="10">
|
||||
<template #title>
|
||||
<div class="flex items-center">
|
||||
<svg-icon icon-class="project" :size="16" />
|
||||
<svg-icon icon-class="project" :size="20" />
|
||||
<span class="text-[16px] ml-1">项目</span>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -117,12 +117,12 @@ orderCount.value = 2000;
|
|||
</el-card>
|
||||
|
||||
<!-- 数据卡片 -->
|
||||
<el-row :gutter="40" class="mt-3">
|
||||
<el-row :gutter="10" class="mt-3">
|
||||
<el-col :xs="24" :sm="12" :lg="6">
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-[var(--el-text-color-secondary)]">访问量</span>
|
||||
<span class="text-[var(--el-text-color-secondary)]">访客数</span>
|
||||
<el-tag type="success">日</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -137,7 +137,7 @@ orderCount.value = 2000;
|
|||
<div
|
||||
class="flex items-center justify-between mt-5 text-sm text-[var(--el-text-color-secondary)]"
|
||||
>
|
||||
<span> 总访问数 </span>
|
||||
<span> 总访客数 </span>
|
||||
<span> {{ Math.round(visitCountOutput * 15) }} </span>
|
||||
</div>
|
||||
</el-card>
|
||||
|
|
@ -148,7 +148,7 @@ orderCount.value = 2000;
|
|||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-[var(--el-text-color-secondary)]">留资数</span>
|
||||
<span class="text-[var(--el-text-color-secondary)]">IP数</span>
|
||||
<el-tag type="success">日</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -157,13 +157,13 @@ orderCount.value = 2000;
|
|||
<div class="text-lg text-right">
|
||||
{{ Math.round(dauCountOutput) }}
|
||||
</div>
|
||||
<svg-icon icon-class="message" size="2em" />
|
||||
<svg-icon icon-class="ip" size="2em" />
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="flex items-center justify-between mt-5 text-sm text-[var(--el-text-color-secondary)]"
|
||||
>
|
||||
<span> 总留资数 </span>
|
||||
<span> 总IP数 </span>
|
||||
<span> {{ Math.round(dauCountOutput) }} </span>
|
||||
</div>
|
||||
</el-card>
|
||||
|
|
@ -223,7 +223,7 @@ orderCount.value = 2000;
|
|||
</el-row>
|
||||
|
||||
<!-- Echarts 图表 -->
|
||||
<el-row :gutter="40" class="mt-3">
|
||||
<el-row :gutter="10" class="mt-3">
|
||||
<el-col :sm="24" :lg="8" class="mb-2">
|
||||
<BarChart
|
||||
id="barChart"
|
||||
|
|
|
|||
|
|
@ -117,12 +117,15 @@
|
|||
</el-card>
|
||||
|
||||
<!-- ICP备案 -->
|
||||
<div class="absolute bottom-1 text-[10px] text-center">
|
||||
<div
|
||||
class="absolute bottom-1 text-[10px] text-center"
|
||||
v-show="useAppStore().device == 'desktop'"
|
||||
>
|
||||
<p>
|
||||
Copyright © 2021 - 2023 youlai.tech All Rights Reserved. 有来技术
|
||||
版权所有
|
||||
</p>
|
||||
<p>ICP备案号:皖ICP备20006496号-3</p>
|
||||
<p>皖ICP备20006496号-3</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -146,15 +149,12 @@ import { getCaptchaApi } from "@/api/auth";
|
|||
import { LoginData } from "@/api/auth/types";
|
||||
import defaultSettings from "@/settings";
|
||||
|
||||
const appStore = useAppStore();
|
||||
/**
|
||||
* 明亮/暗黑主题切换
|
||||
*/
|
||||
const settingsStore = useSettingsStore();
|
||||
const userStore = useUserStore();
|
||||
const route = useRoute();
|
||||
|
||||
const isDark = ref<boolean>(settingsStore.theme === "dark");
|
||||
|
||||
const handleThemeChange = (isDark?: string | number | boolean) => {
|
||||
console.log("登录页面主题切换", isDark);
|
||||
const handleThemeChange = (isDark: any) => {
|
||||
useToggle(isDark);
|
||||
settingsStore.changeSetting({
|
||||
key: "theme",
|
||||
|
|
@ -163,26 +163,24 @@ const handleThemeChange = (isDark?: string | number | boolean) => {
|
|||
};
|
||||
|
||||
/**
|
||||
* 按钮loading
|
||||
* 根据屏幕宽度切换设备模式
|
||||
*/
|
||||
const loading = ref(false);
|
||||
/**
|
||||
* 是否大写锁定
|
||||
*/
|
||||
const isCapslock = ref(false);
|
||||
/**
|
||||
* 密码是否可见
|
||||
*/
|
||||
const passwordVisible = ref(false);
|
||||
/**
|
||||
* 验证码图片Base64字符串
|
||||
*/
|
||||
const captchaBase64 = ref();
|
||||
const appStore = useAppStore();
|
||||
const WIDTH = 992; // 响应式布局容器固定宽度 大屏(>=1200px) 中屏(>=992px) 小屏(>=768px)
|
||||
const { width } = useWindowSize();
|
||||
watchEffect(() => {
|
||||
if (width.value < WIDTH) {
|
||||
appStore.toggleDevice("mobile");
|
||||
} else {
|
||||
appStore.toggleDevice("desktop");
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 登录表单引用
|
||||
*/
|
||||
const loginFormRef = ref(ElForm);
|
||||
const loading = ref(false); // 按钮loading
|
||||
const isCapslock = ref(false); // 是否大写锁定
|
||||
const passwordVisible = ref(false); // 密码是否可见
|
||||
const captchaBase64 = ref(); // 验证码图片Base64字符串
|
||||
const loginFormRef = ref(ElForm); // 登录表单ref
|
||||
|
||||
const loginData = ref<LoginData>({
|
||||
username: "admin",
|
||||
|
|
@ -190,7 +188,6 @@ const loginData = ref<LoginData>({
|
|||
});
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const loginRules = computed(() => {
|
||||
const prefix = appStore.language === "en" ? "Please enter " : "请输入";
|
||||
return {
|
||||
|
|
@ -205,7 +202,13 @@ const loginRules = computed(() => {
|
|||
{
|
||||
required: true,
|
||||
trigger: "blur",
|
||||
validator: passwordValidator,
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
if (value.length < 6) {
|
||||
callback(new Error("The password can not be less than 6 digits"));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
message: `${prefix}${t("login.password")}`,
|
||||
},
|
||||
],
|
||||
|
|
@ -219,17 +222,6 @@ const loginRules = computed(() => {
|
|||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* 密码校验器
|
||||
*/
|
||||
function passwordValidator(rule: any, value: any, callback: any) {
|
||||
if (value.length < 6) {
|
||||
callback(new Error("The password can not be less than 6 digits"));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查输入大小写状态
|
||||
*/
|
||||
|
|
@ -252,6 +244,8 @@ function getCaptcha() {
|
|||
/**
|
||||
* 登录
|
||||
*/
|
||||
const route = useRoute();
|
||||
const userStore = useUserStore();
|
||||
function handleLogin() {
|
||||
loginFormRef.value.validate((valid: boolean) => {
|
||||
if (valid) {
|
||||
|
|
@ -355,7 +349,7 @@ onMounted(() => {
|
|||
}
|
||||
|
||||
input:-webkit-autofill {
|
||||
transition: background-color 5000s ease-in-out 0s; /* 通过延时渲染背景色变相去除背景颜色 */
|
||||
transition: background-color 1000s ease-in-out 0s; /* 通过延时渲染背景色变相去除背景颜色 */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue