版本更新
Some checks are pending
CI / Test (ubuntu-latest) (push) Waiting to run
CI / Test (windows-latest) (push) Waiting to run
CI / Lint (ubuntu-latest) (push) Waiting to run
CI / Lint (windows-latest) (push) Waiting to run
CI / Check (ubuntu-latest) (push) Waiting to run
CI / Check (windows-latest) (push) Waiting to run
CI / CI OK (push) Blocked by required conditions
CodeQL / Analyze (${{ matrix.language }}) (none, javascript-typescript) (push) Waiting to run
Deploy Website on push / Deploy Push Playground Ftp (push) Waiting to run
Deploy Website on push / Deploy Push Docs Ftp (push) Waiting to run
Deploy Website on push / Deploy Push Antd Ftp (push) Waiting to run
Deploy Website on push / Deploy Push Element Ftp (push) Waiting to run
Deploy Website on push / Deploy Push Naive Ftp (push) Waiting to run
Release Drafter / update_release_draft (push) Waiting to run

This commit is contained in:
hahwu 2025-07-29 17:45:55 +08:00
parent e664c1bb7c
commit d6ab60b5c9
40 changed files with 5320 additions and 564 deletions

View File

@ -1,4 +1,4 @@
<div align="center"> <a href="https://github.com/anncwb/vue-vben-admin"> <img alt="VbenAdmin Logo" width="215" src="https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp"> </a> <br> <br>
<div align="center"> <a href="https://github.com/anncwb/vue-vben-admin"> <img alt="VbenAdmin Logo" width="215" src=""> </a> <br> <br>
[![license](https://img.shields.io/github/license/anncwb/vue-vben-admin.svg)](LICENSE)

View File

@ -1,4 +1,4 @@
<div align="center"> <a href="https://github.com/anncwb/vue-vben-admin"> <img alt="VbenAdmin Logo" width="215" src="https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp"> </a> <br> <br>
<div align="center"> <a href="https://github.com/anncwb/vue-vben-admin"> <img alt="VbenAdmin Logo" width="215" src=""> </a> <br> <br>
[![license](https://img.shields.io/github/license/anncwb/vue-vben-admin.svg)](LICENSE)

View File

@ -1,4 +1,4 @@
<div align="center"> <a href="https://github.com/anncwb/vue-vben-admin"> <img alt="VbenAdmin Logo" width="215" src="https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp"> </a> <br> <br>
<div align="center"> <a href="https://github.com/anncwb/vue-vben-admin"> <img alt="VbenAdmin Logo" width="215" src=""> </a> <br> <br>
[![license](https://img.shields.io/github/license/anncwb/vue-vben-admin.svg)](LICENSE)

View File

@ -1,5 +1,6 @@
# 应用标题
VITE_APP_TITLE=Vben Admin Antd
VITE_APP_TITLE=喵喵喵之家
VITE_APP_LOGO='../public/favicon.ico' # Adjust the path as necessary
# 应用命名空间用于缓存、store等功能的前缀确保隔离
VITE_APP_NAMESPACE=vben-web-antd

View File

@ -5,7 +5,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="renderer" content="webkit" />
<meta name="description" content="A Modern Back-end Management System" />
<meta name="keywords" content="Vben Admin Vue3 Vite" />
<meta name="keywords" content="喵喵喵之家" />
<meta name="author" content="Vben" />
<meta
name="viewport"
@ -15,17 +15,7 @@
<title><%= VITE_APP_TITLE %></title>
<link rel="icon" href="/favicon.ico" />
<script>
// 生产环境下注入百度统计
if (window._VBEN_ADMIN_PRO_APP_CONF_) {
var _hmt = _hmt || [];
(function () {
var hm = document.createElement('script');
hm.src =
'https://hm.baidu.com/hm.js?b38e689f40558f20a9a686d7f6f33edf';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(hm, s);
})();
}
</script>
</head>
<body>

View File

@ -45,9 +45,11 @@
"cal-heatmap": "^4.2.4",
"dayjs": "catalog:",
"pinia": "catalog:",
"pixi.js": "8.11.0-main.efa7feb",
"prettier-eslint": "^16.4.2",
"vue": "catalog:",
"vue-router": "catalog:",
"vue3-pixi": "1.0.0-beta.3",
"vxe-table": "^4.6.25"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 451 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 527 KiB

View File

@ -0,0 +1,174 @@
cat.png
size: 2048,2048
format: RGBA8888
filter: Linear,Linear
repeat: none
1xiaomao_v3_shenti
rotate: false
xy: 2, 138
size: 429, 456
orig: 433, 484
offset: 4, 9
index: -1
xiaomao_v3_biyan1
rotate: false
xy: 2, 3
size: 146, 133
orig: 166, 143
offset: 20, 6
index: -1
xiaomao_v3_biyan2
rotate: true
xy: 690, 864
size: 158, 121
orig: 163, 121
offset: 5, 0
index: -1
xiaomao_v3_erduo1
rotate: false
xy: 435, 702
size: 159, 243
orig: 159, 253
offset: 0, 0
index: -1
xiaomao_v3_erduo2
rotate: false
xy: 433, 2
size: 164, 218
orig: 164, 218
offset: 0, 0
index: -1
xiaomao_v3_houtui
rotate: false
xy: 435, 947
size: 162, 246
orig: 190, 246
offset: 10, 0
index: -1
xiaomao_v3_huzi1
rotate: true
xy: 599, 11
size: 209, 150
orig: 218, 150
offset: 0, 0
index: -1
xiaomao_v3_huzi2
rotate: true
xy: 596, 713
size: 232, 92
orig: 244, 92
offset: 12, 0
index: -1
xiaomao_v3_kaixinlian
rotate: true
xy: 2, 1064
size: 466, 431
orig: 466, 431
offset: 0, 0
index: -1
xiaomao_v3_lian
rotate: true
xy: 2, 596
size: 466, 431
orig: 466, 431
offset: 0, 0
index: -1
xiaomao_v3_shangzuicun
rotate: true
xy: 599, 1024
size: 169, 95
orig: 169, 95
offset: 0, 0
index: -1
xiaomao_v3_shenti
rotate: false
xy: 2, 1532
size: 499, 505
orig: 499, 509
offset: 0, 0
index: -1
xiaomao_v3_weiba
rotate: false
xy: 435, 1195
size: 203, 335
orig: 203, 335
offset: 0, 0
index: -1
xiaomao_v3_xiaba
rotate: false
xy: 253, 13
size: 178, 123
orig: 178, 135
offset: 0, 12
index: -1
xiaomao_v3_xiongqianmao
rotate: true
xy: 503, 1738
size: 299, 276
orig: 299, 284
offset: 0, 8
index: -1
xiaomao_v3_yanba1
rotate: true
xy: 150, 12
size: 124, 101
orig: 124, 101
offset: 0, 0
index: -1
xiaomao_v3_yanbai2
rotate: true
xy: 690, 752
size: 110, 105
orig: 110, 105
offset: 0, 0
index: -1
xiaomao_v3_yanqiu1
rotate: false
xy: 435, 599
size: 101, 101
orig: 101, 101
offset: 0, 0
index: -1
xiaomao_v3_yanqiu2
rotate: false
xy: 538, 599
size: 101, 101
orig: 101, 101
offset: 0, 0
index: -1
xiaomao_v3_youshou
rotate: true
xy: 641, 597
size: 114, 90
orig: 114, 90
offset: 0, 0
index: -1
xiaomao_v3_youtui
rotate: false
xy: 781, 1790
size: 145, 247
orig: 145, 247
offset: 0, 0
index: -1
xiaomao_v3_youtui2
rotate: true
xy: 624, 1567
size: 169, 251
orig: 169, 251
offset: 0, 0
index: -1
xiaomao_v3_youtuizhedang
rotate: false
xy: 503, 1561
size: 119, 175
orig: 124, 175
offset: 0, 0
index: -1
xiaomao_v3_zuotui
rotate: false
xy: 433, 222
size: 236, 372
orig: 236, 372
offset: 0, 0
index: -1

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

@ -7,9 +7,7 @@ import '@vben/styles';
import '@vben/styles/antd';
import { useTitle } from '@vueuse/core';
import { $t, setupI18n } from '#/locales';
import { initComponentAdapter } from './adapter/component';
import App from './app.vue';
import { router } from './router';

View File

@ -1,19 +1,17 @@
<script lang="ts" setup>
import { AuthPageLayout } from '@vben/layouts';
import { $t } from '#/locales';
// const appName = computed(() => preferences.app.name);
const logo = '../../public/MMM_loading_logo1.png';
const appName = '喵喵喵之家';
import { computed } from 'vue';
import { preferences } from '@vben/preferences';
const appName = computed(() => preferences.app?.name);
const logo = computed(() => preferences.logo?.source);
//console.log('appName', preferences.app.name);
console.log('logo', preferences);
</script>
<template>
<AuthPageLayout
:app-name="appName"
:logo="logo"
:page-description="$t('authentication.pageDesc')"
:page-title="$t('authentication.pageTitle')"
>
<AuthPageLayout :app-name="appName" :logo="logo" :page-description="$t('authentication.pageDesc')"
:page-title="$t('authentication.pageTitle')">
<!-- 自定义工具栏 -->
<!-- <template #toolbar></template> -->
</AuthPageLayout>

View File

@ -125,28 +125,15 @@ watch(
<template>
<BasicLayout @clear-preferences-and-logout="handleLogout">
<template #user-dropdown>
<UserDropdown
:avatar
:menus
:text="userStore.userInfo?.realName"
description="ann.vben@gmail.com"
tag-text="Pro"
@logout="handleLogout"
/>
<UserDropdown :avatar :menus :text="userStore.userInfo?.realName" description="ann.vben@gmail.com" tag-text="Pro"
@logout="handleLogout" />
</template>
<template #notification>
<Notification
:dot="showDot"
:notifications="notifications"
@clear="handleNoticeClear"
@make-all="handleMakeAll"
/>
<Notification :dot="showDot" :notifications="notifications" @clear="handleNoticeClear"
@make-all="handleMakeAll" />
</template>
<template #extra>
<AuthenticationLoginExpiredModal
v-model:open="accessStore.loginExpired"
:avatar
>
<AuthenticationLoginExpiredModal v-model:open="accessStore.loginExpired" :avatar>
<LoginForm />
</AuthenticationLoginExpiredModal>
</template>

View File

@ -8,6 +8,24 @@ import { defineOverridesPreferences } from '@vben/preferences';
export const overridesPreferences = defineOverridesPreferences({
// overrides
app: {
name: import.meta.env.VITE_APP_TITLE,
name: "喵喵喵之家2",
defaultAvatar:'../public/favicon.ico', // Adjust the path as necessary
},
copyright: {
companyName: '厦门蹊径科技公司',
companySiteLink: 'https://bywaystudios.com',
},
footer: {
enable: true,
},
logo: {
source: import.meta.env.VITE_APP_LOGO || 'https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp',
},
theme: {
builtinType: 'yellow',
colorPrimary: 'hsl(42 84% 61%)',
mode: 'light',
},
});

View File

@ -13,14 +13,15 @@ const routes: RouteRecordRaw[] = [
authority:['super'],
},
name: 'Admin',
path: '/',
path: '/admin',
children: [
{
name: 'UserManagement',
path: '/user-management',
component: () => import('#/views/admin/user/index.vue'),
meta: {
affixTab: true,
authority: ['super', 'admin'],
affixTab: false,
icon: 'majesticons:user-box-line',
title: $t('page.admin.user'),
},

View File

@ -10,17 +10,17 @@ const routes: RouteRecordRaw[] = [
icon: 'lucide:layout-dashboard',
order: -1,
title: $t('page.dashboard.title'),
authority: ['super'],
authority: ['super', 'admin'],
},
name: 'Dashboard',
path: '/',
path: '/dashboard',
children: [
{
name: 'Analytics',
path: '/analytics',
component: () => import('#/views/dashboard/analytics/index.vue'),
meta: {
affixTab: true,
affixTab: false,
icon: 'lucide:area-chart',
title: $t('page.dashboard.analytics'),
},
@ -30,7 +30,7 @@ const routes: RouteRecordRaw[] = [
path: '/server-list',
component: () => import('#/views/dashboard/serverList/index.vue'),
meta: {
affixTab: true,
affixTab: false,
icon: 'lucide:gamepad',
title: $t('page.dashboard.server-list'),
},
@ -40,7 +40,7 @@ const routes: RouteRecordRaw[] = [
path: '/app-list',
component: () => import('#/views/dashboard/appList/index.vue'),
meta: {
affixTab: true,
affixTab: false,
icon: 'lucide:app-window',
title: $t('page.dashboard.app-list'),
},
@ -50,7 +50,7 @@ const routes: RouteRecordRaw[] = [
path: '/node-list',
component: () => import('#/views/dashboard/nodeList/index.vue'),
meta: {
affixTab: true,
affixTab: false,
icon: 'lucide:server',
title: $t('page.dashboard.node-list'),
},
@ -60,7 +60,7 @@ const routes: RouteRecordRaw[] = [
path: '/mysql-list',
component: () => import('#/views/dashboard/mysqlList/index.vue'),
meta: {
affixTab: true,
affixTab: false,
icon: 'lucide:database',
title: $t('page.dashboard.mysql-list'),
},

View File

@ -1,7 +1,7 @@
<script lang="ts" setup>
import type { VbenFormSchema } from '@vben/common-ui';
import type { Recordable } from '@vben/types';
import { getPhoneCodeApi, phoneLoginApi } from '#/api';
import { getPhoneCodeApi } from '#/api';
import { computed, ref } from 'vue';
import { AuthenticationCodeLogin, z } from '@vben/common-ui';

View File

@ -51,6 +51,7 @@ const [Form, FormApi] = useVbenForm({
defaultValue: 1,
componentProps: {
options: [
{ label: '超级管理员', value: 0 },
{ label: '管理员', value: 1 },
{ label: '普通用户', value: 2 },
],

View File

@ -10,7 +10,7 @@ import addUserModal from './addUser.vue';
const gridOptions: VxeGridProps<UserInfo> = {
columns: [
{ field: 'username', title: '用户名' },
{ field: 'username', title: '用户名', },
{ field: 'phone', title: '手机号' },
{ field: 'role', title: '角色' },
{ field: 'group', title: '用户组' },

View File

@ -120,11 +120,11 @@ const gridOptions: VxeGridProps<RowType> = {
columns: [
{ field: 'Uid', title: 'id' },
{ field: 'UserName', title: '登录名' },
{ field: 'Level', title: '等级' },
{ field: 'Exp', title: '经验', formatter: ({ cellValue }) => `${cellValue} XP` },
{ field: 'Diamond', title: '钻石', formatter: ({ cellValue }) => `${cellValue} 💎` },
{ field: 'Star', title: '星星', formatter: ({ cellValue }) => `${cellValue}` },
{ field: 'Energy', title: '能量', formatter: ({ cellValue }) => `${cellValue}` },
{ field: 'Level', title: '等级', formatter: ({ cellValue }) => `${cellValue}`, sortable: true, sortBy: 'Level' },
{ field: 'Exp', title: '经验', formatter: ({ cellValue }) => `${cellValue} XP`, sortable: true, sortBy: 'Exp' },
{ field: 'Diamond', title: '钻石', formatter: ({ cellValue }) => `${cellValue} 💎`, sortable: true, sortBy: 'Diamond' },
{ field: 'Star', title: '星星', formatter: ({ cellValue }) => `${cellValue}`, sortable: true, sortBy: 'Star' },
{ field: 'Energy', title: '能量', formatter: ({ cellValue }) => `${cellValue}`, sortable: true, sortBy: 'Energy' },
{ field: 'LoginTime', sortable: true, title: '登录时间', formatter: ({ cellValue }) => dayjs(cellValue * 1000).format('YYYY-MM-DD HH:mm:ss') },
{ field: 'Online', title: '在线状态', slots: { default: 'online' } },
],

View File

@ -1,7 +1,18 @@
import { defineConfig } from '@vben/vite-config';
import vue from '@vitejs/plugin-vue';
import { compilerOptions } from 'vue3-pixi';
export default defineConfig(async () => {
return {
plugins: [
vue({
template: {
// 移除未知元素警告
compilerOptions,
// 支持资源 URL 转换
},
}),
],
application: {},
vite: {
server: {

View File

@ -35,7 +35,7 @@ export const shared = defineConfig({
srcDir: 'src',
themeConfig: {
i18nRouting: true,
logo: 'https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp',
logo: '',
search: {
options: {
locales: {

View File

@ -12,7 +12,7 @@ export const VBEN_DOC_URL = 'https://doc.vben.pro';
* @zh_CN Vben Logo
*/
export const VBEN_LOGO_URL =
'https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp';
'https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.';
/**
* @zh_CN Vben Admin

View File

@ -50,7 +50,7 @@ exports[`defaultPreferences immutability test > should not modify the config obj
},
"logo": {
"enable": true,
"source": "https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp",
"source": "https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1",
},
"navigation": {
"accordion": true,

View File

@ -31,8 +31,8 @@ const defaultPreferences: Preferences = {
styleType: 'normal',
},
copyright: {
companyName: 'Vben',
companySiteLink: 'https://www.vben.pro',
companyName: '厦门蹊径科技有限公司',
companySiteLink: 'https:/bywaystudios.com',
date: '2024',
enable: true,
icp: '',
@ -40,7 +40,7 @@ const defaultPreferences: Preferences = {
settingShow: true,
},
footer: {
enable: false,
enable: true,
fixed: false,
},
header: {
@ -50,7 +50,7 @@ const defaultPreferences: Preferences = {
},
logo: {
enable: true,
source: 'https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp',
source: '../public/favicon.ico',
},
navigation: {
accordion: true,
@ -90,7 +90,7 @@ const defaultPreferences: Preferences = {
colorPrimary: 'hsl(212 100% 45%)',
colorSuccess: 'hsl(144 57% 58%)',
colorWarning: 'hsl(42 84% 61%)',
mode: 'dark',
mode: 'light',
radius: '0.5',
semiDarkHeader: false,
semiDarkSidebar: false,

View File

@ -16,7 +16,7 @@ defineOptions({
const props = withDefaults(defineProps<Props>(), {
description: '',
homePath: '/',
homePath: '/auth/login',
image: '',
showBack: true,
status: 'coming-soon',
@ -129,24 +129,14 @@ function refresh() {
<template>
<div class="flex size-full flex-col items-center justify-center duration-300">
<img v-if="image" :src="image" class="md:1/3 w-1/2 lg:w-1/4" />
<component
:is="fallbackIcon"
v-else-if="fallbackIcon"
class="md:1/3 h-1/3 w-1/2 lg:w-1/4"
/>
<component :is="fallbackIcon" v-else-if="fallbackIcon" class="md:1/3 h-1/3 w-1/2 lg:w-1/4" />
<div class="flex-col-center">
<slot v-if="$slots.title" name="title"></slot>
<p
v-else-if="titleText"
class="text-foreground mt-8 text-2xl md:text-3xl lg:text-4xl"
>
<p v-else-if="titleText" class="text-foreground mt-8 text-2xl md:text-3xl lg:text-4xl">
{{ titleText }}
</p>
<slot v-if="$slots.describe" name="describe"></slot>
<p
v-else-if="descText"
class="text-muted-foreground md:text-md my-4 lg:text-lg"
>
<p v-else-if="descText" class="text-muted-foreground md:text-md my-4 lg:text-lg">
{{ descText }}
</p>
<slot v-if="$slots.action" name="action"></slot>

View File

@ -20,6 +20,7 @@
}
},
"dependencies": {
"@esotericsoftware/spine-pixi-v8": "^4.2.87",
"@vben-core/composables": "workspace:*",
"@vben-core/form-ui": "workspace:*",
"@vben-core/layout-ui": "workspace:*",
@ -37,7 +38,10 @@
"@vben/types": "workspace:*",
"@vben/utils": "workspace:*",
"@vueuse/core": "catalog:",
"pixi-spine": "^4.0.6",
"pixi.js": "8.11.0-main.efa7feb",
"vue": "catalog:",
"vue-router": "catalog:"
"vue-router": "catalog:",
"vue3-pixi": "1.0.0-beta.3"
}
}

View File

@ -2,12 +2,12 @@
import type { ToolbarType } from './types';
import { preferences, usePreferences } from '@vben/preferences';
import { Copyright } from '../basic/copyright';
import AuthenticationFormView from './form.vue';
import SloganIcon from './icons/slogan.vue';
import { Application } from 'vue3-pixi';
//import SloganIcon from './icons/slogan.vue';
import Toolbar from './toolbar.vue';
import example from './icons/example.vue';
interface Props {
appName?: string;
logo?: string;
@ -18,18 +18,17 @@ interface Props {
copyright?: boolean;
toolbarList?: ToolbarType[];
}
withDefaults(defineProps<Props>(), {
appName: '',
copyright: true,
logo: '',
pageDescription: '',
pageTitle: '',
sloganImage: '',
sloganImage:
'https://mergeweb.bywaystudios.com/Limitedtime_pic_doumaoCWGD.png',
toolbar: true,
toolbarList: () => ['color', 'language', 'layout', 'theme'],
});
const { authPanelCenter, authPanelLeft, authPanelRight, isDark } =
usePreferences();
</script>
@ -83,10 +82,10 @@ const { authPanelCenter, authPanelLeft, authPanelRight, isDark } =
<img
:alt="appName"
:src="sloganImage"
class="animate-float h-64 w-2/5"
class="animate-float h-64 w-1/5"
/>
</template>
<SloganIcon v-else :alt="appName" class="animate-float h-64 w-2/5" />
<!-- <SloganIcon v-else :alt="appName" class="animate-float h-64 w-2/5" /> -->
<div class="text-1xl text-foreground mt-6 font-sans lg:text-2xl">
{{ pageTitle }}
</div>
@ -134,23 +133,100 @@ const { authPanelCenter, authPanelLeft, authPanelRight, isDark } =
<style scoped>
.login-background {
background: linear-gradient(
154deg,
#07070915 30%,
hsl(var(--primary) / 30%) 48%,
#07070915 64%
-45deg,
#ff0000,
#ff4500,
#ff7f00,
#ffa500,
#ffff00,
#ffd700,
#ff6347,
#ff1493,
#ff0000
);
background-size: 400% 400%;
animation: rainbow-flow 8s ease-in-out infinite;
filter: blur(100px);
}
.dark {
.login-background {
background: linear-gradient(
154deg,
#07070915 30%,
hsl(var(--primary) / 20%) 48%,
#07070915 64%
-45deg,
#ff000080,
#ff450080,
#ff7f0080,
#ffa50080,
#ffff0080,
#ffd70080,
#ff634780,
#ff149380,
#ff000080
);
background-size: 400% 400%;
animation: rainbow-flow 8s ease-in-out infinite;
filter: blur(100px);
}
}
@keyframes rainbow-flow {
0% {
background-position: 0% 50%;
}
25% {
background-position: 100% 50%;
}
50% {
background-position: 100% 100%;
}
75% {
background-position: 0% 100%;
}
100% {
background-position: 0% 50%;
}
}
/* 增强流光效果的版本 */
@keyframes rainbow-enhanced {
0% {
background-position: 0% 50%;
filter: blur(100px) brightness(1);
}
25% {
background-position: 100% 50%;
filter: blur(80px) brightness(1.2);
}
50% {
background-position: 100% 100%;
filter: blur(120px) brightness(0.8);
}
75% {
background-position: 0% 100%;
filter: blur(90px) brightness(1.1);
}
100% {
background-position: 0% 50%;
filter: blur(100px) brightness(1);
}
}
/* 可选:更炫酷的暖色调流光效果 */
.login-background.enhanced {
background: linear-gradient(
-45deg,
#ff006e,
#ff8500,
#ffb700,
#ff6b35,
#ff4081,
#ff5722,
#ff9800,
#ffc107,
#ffeb3b,
#ff006e
);
background-size: 1000% 1000%;
animation: rainbow-enhanced 12s ease-in-out infinite;
}
</style>

View File

@ -0,0 +1,84 @@
<script lang="ts" setup>
import { onMounted, onUnmounted } from 'vue';
import { Application, Container, Assets, Sprite } from 'pixi.js';
import { Spine } from '@esotericsoftware/spine-pixi-v8';
let app: Application;
let container: Container;
onMounted(async () => {
// PixiJS
app = new Application();
//
await app.init({
// background: '#1099bb',
width: 640,
height: 480,
backgroundAlpha: 0,
});
// document.body
const pixiContainer = document.getElementById('pixi-container');
if (pixiContainer) {
pixiContainer.appendChild(app.canvas);
}
try {
// 使
const resource = await Assets.load('/public/cat.json');
console.log(resource);
const data = { "skeletonData": resource };
const animation = new Spine(data);
//
animation.x = app.screen.width / 2;
animation.y = app.screen.height / 2;
app.stage.addChild(animation);
//
animation.state.setAnimation(0, 'run', true);
animation.state.timeScale = 0.1;
animation.autoUpdate = true;
} catch (error) {
console.error('Failed to load spine animation:', error);
}
//
container = new Container();
app.stage.addChild(container);
//
const texture = await Assets.load('https://pixijs.com/assets/bunny.png');
for (let i = 0; i < 25; i++) {
const bunny = new Sprite(texture);
bunny.x = (i % 5) * 40;
bunny.y = Math.floor(i / 5) * 40;
container.addChild(bunny);
}
//
container.x = app.screen.width / 2;
container.y = app.screen.height / 2;
container.pivot.x = container.width / 2;
container.pivot.y = container.height / 2;
//
app.ticker.add((time) => {
container.rotation -= 0.01 * time.deltaTime;
});
});
onUnmounted(() => {
// PixiJS
if (app) {
app.destroy(true, true);
}
});
</script>
<template>
<div id="pixi-container" style="width: 640px; height: 480px">
<!-- PixiJS 画布将被添加到这里 -->
</div>
</template>

View File

@ -0,0 +1,174 @@
cat.png
size: 2048,2048
format: RGBA8888
filter: Linear,Linear
repeat: none
1xiaomao_v3_shenti
rotate: false
xy: 2, 138
size: 429, 456
orig: 433, 484
offset: 4, 9
index: -1
xiaomao_v3_biyan1
rotate: false
xy: 2, 3
size: 146, 133
orig: 166, 143
offset: 20, 6
index: -1
xiaomao_v3_biyan2
rotate: true
xy: 690, 864
size: 158, 121
orig: 163, 121
offset: 5, 0
index: -1
xiaomao_v3_erduo1
rotate: false
xy: 435, 702
size: 159, 243
orig: 159, 253
offset: 0, 0
index: -1
xiaomao_v3_erduo2
rotate: false
xy: 433, 2
size: 164, 218
orig: 164, 218
offset: 0, 0
index: -1
xiaomao_v3_houtui
rotate: false
xy: 435, 947
size: 162, 246
orig: 190, 246
offset: 10, 0
index: -1
xiaomao_v3_huzi1
rotate: true
xy: 599, 11
size: 209, 150
orig: 218, 150
offset: 0, 0
index: -1
xiaomao_v3_huzi2
rotate: true
xy: 596, 713
size: 232, 92
orig: 244, 92
offset: 12, 0
index: -1
xiaomao_v3_kaixinlian
rotate: true
xy: 2, 1064
size: 466, 431
orig: 466, 431
offset: 0, 0
index: -1
xiaomao_v3_lian
rotate: true
xy: 2, 596
size: 466, 431
orig: 466, 431
offset: 0, 0
index: -1
xiaomao_v3_shangzuicun
rotate: true
xy: 599, 1024
size: 169, 95
orig: 169, 95
offset: 0, 0
index: -1
xiaomao_v3_shenti
rotate: false
xy: 2, 1532
size: 499, 505
orig: 499, 509
offset: 0, 0
index: -1
xiaomao_v3_weiba
rotate: false
xy: 435, 1195
size: 203, 335
orig: 203, 335
offset: 0, 0
index: -1
xiaomao_v3_xiaba
rotate: false
xy: 253, 13
size: 178, 123
orig: 178, 135
offset: 0, 12
index: -1
xiaomao_v3_xiongqianmao
rotate: true
xy: 503, 1738
size: 299, 276
orig: 299, 284
offset: 0, 8
index: -1
xiaomao_v3_yanba1
rotate: true
xy: 150, 12
size: 124, 101
orig: 124, 101
offset: 0, 0
index: -1
xiaomao_v3_yanbai2
rotate: true
xy: 690, 752
size: 110, 105
orig: 110, 105
offset: 0, 0
index: -1
xiaomao_v3_yanqiu1
rotate: false
xy: 435, 599
size: 101, 101
orig: 101, 101
offset: 0, 0
index: -1
xiaomao_v3_yanqiu2
rotate: false
xy: 538, 599
size: 101, 101
orig: 101, 101
offset: 0, 0
index: -1
xiaomao_v3_youshou
rotate: true
xy: 641, 597
size: 114, 90
orig: 114, 90
offset: 0, 0
index: -1
xiaomao_v3_youtui
rotate: false
xy: 781, 1790
size: 145, 247
orig: 145, 247
offset: 0, 0
index: -1
xiaomao_v3_youtui2
rotate: true
xy: 624, 1567
size: 169, 251
orig: 169, 251
offset: 0, 0
index: -1
xiaomao_v3_youtuizhedang
rotate: false
xy: 503, 1561
size: 119, 175
orig: 124, 175
offset: 0, 0
index: -1
xiaomao_v3_zuotui
rotate: false
xy: 433, 222
size: 236, 372
orig: 236, 372
offset: 0, 0
index: -1

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

View File

@ -135,23 +135,11 @@ if (enableShortcutKey.value) {
</script>
<template>
<LockModal
v-if="preferences.widget.lockScreen"
:avatar="avatar"
:text="text"
@submit="handleSubmitLock"
/>
<LockModal v-if="preferences.widget.lockScreen" :avatar="avatar" :text="text" @submit="handleSubmitLock" />
<LogoutModal
:cancel-text="$t('common.cancel')"
:confirm-text="$t('common.confirm')"
:fullscreen-button="false"
:title="$t('common.prompt')"
centered
content-class="px-8 min-h-10"
footer-class="border-none mb-3 mr-3"
header-class="border-none"
>
<LogoutModal :cancel-text="$t('common.cancel')" :confirm-text="$t('common.confirm')" :fullscreen-button="false"
:title="$t('common.prompt')" centered content-class="px-8 min-h-10" footer-class="border-none mb-3 mr-3"
header-class="border-none">
{{ $t('ui.widgets.logoutTip') }}
</LogoutModal>
@ -165,18 +153,11 @@ if (enableShortcutKey.value) {
</DropdownMenuTrigger>
<DropdownMenuContent class="mr-2 min-w-[240px] p-0 pb-1">
<DropdownMenuLabel class="flex items-center p-3">
<VbenAvatar
:alt="text"
:src="avatar"
class="size-12"
dot
dot-class="bottom-0 right-1 border-2 size-4 bg-green-500"
/>
<VbenAvatar :alt="text" :src="avatar" class="size-12" dot
dot-class="bottom-0 right-1 border-2 size-4 bg-green-500" />
<div class="ml-2 w-full">
<div
v-if="tagText || text || $slots.tagText"
class="text-foreground mb-1 flex items-center text-sm font-medium"
>
<div v-if="tagText || text || $slots.tagText"
class="text-foreground mb-1 flex items-center text-sm font-medium">
{{ text }}
<slot name="tagText">
<Badge v-if="tagText" class="ml-2 text-green-400">
@ -189,7 +170,7 @@ if (enableShortcutKey.value) {
</div>
</div>
</DropdownMenuLabel>
<DropdownMenuSeparator v-if="menus?.length" />
<!-- <DropdownMenuSeparator v-if="menus?.length" />
<DropdownMenuItem
v-for="menu in menus"
:key="menu.text"
@ -199,12 +180,9 @@ if (enableShortcutKey.value) {
<VbenIcon :icon="menu.icon" class="mr-2 size-4" />
{{ menu.text }}
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem
v-if="preferences.widget.lockScreen"
class="mx-1 flex cursor-pointer items-center rounded-sm py-1 leading-8"
@click="handleOpenLock"
>
<DropdownMenuSeparator /> -->
<DropdownMenuItem v-if="preferences.widget.lockScreen"
class="mx-1 flex cursor-pointer items-center rounded-sm py-1 leading-8" @click="handleOpenLock">
<LockKeyhole class="mr-2 size-4" />
{{ $t('ui.widgets.lockScreen.title') }}
<DropdownMenuShortcut v-if="enableLockScreenShortcutKey">
@ -212,10 +190,7 @@ if (enableShortcutKey.value) {
</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuSeparator v-if="preferences.widget.lockScreen" />
<DropdownMenuItem
class="mx-1 flex cursor-pointer items-center rounded-sm py-1 leading-8"
@click="handleLogout"
>
<DropdownMenuItem class="mx-1 flex cursor-pointer items-center rounded-sm py-1 leading-8" @click="handleLogout">
<LogOut class="mr-2 size-4" />
{{ $t('common.logout') }}
<DropdownMenuShortcut v-if="enableLogoutShortcutKey">

View File

@ -1,7 +1,7 @@
{
"welcomeBack": "欢迎回来",
"pageTitle": "开箱即用的大型中后台管理系统",
"pageDesc": "工程化、高性能、跨组件库的前端模版",
"pageTitle": "喵喵喵之家",
"pageDesc": "喵喵喵之家",
"loginSuccess": "登录成功",
"loginSuccessDesc": "欢迎回来",
"loginSubtitle": "请输入您的帐户信息以开始管理您的项目",

View File

@ -9,6 +9,15 @@ import type { DeepPartial } from '@vben-core/typings';
*/
function defineOverridesPreferences(preferences: DeepPartial<Preferences>) {
preferences = {
app: {
name: '喵喵喵之家',
defaultAvatar: '../public/favicon.ico', // Adjust the path as necessary
},
logo: {
source: import.meta.env.VITE_APP_LOGO || '../public/favicon.ico', // Adjust the path as necessary
},
}
return preferences;
}

View File

@ -34,8 +34,7 @@ import imageBase64 from './base64';
type="primary"
@click="
downloadFileFromImageUrl({
source:
'https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp',
source: 'https://unpkg.com/@vbenjs/static-source@0.1.7/source/',
fileName: 'vben-logo.png',
})
"

File diff suppressed because it is too large Load Diff