chore: update project files

This commit is contained in:
AIGC Developer
2025-11-13 17:01:39 +08:00
parent 83bf064bb2
commit 2961d2b0d0
344 changed files with 11549 additions and 15941 deletions

View File

@@ -101,6 +101,10 @@

View File

@@ -0,0 +1,71 @@
<template>
<button class="language-switcher" @click="toggleLanguage" :title="currentLanguage === 'zh' ? '切换到英文' : 'Switch to Chinese'">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none">
<path d="M4.16602 12.4998V14.1665C4.16602 15.0452 4.84592 15.765 5.7083 15.8286L5.83268 15.8332H8.33268V17.4998H5.83268C3.99173 17.4998 2.49935 16.0074 2.49935 14.1665V12.4998H4.16602ZM14.9993 8.33317L18.666 17.4998H16.8702L15.8694 14.9998H12.461L11.4618 17.4998H9.66685L13.3327 8.33317H14.9993ZM14.166 10.7375L13.1268 13.3332H15.2035L14.166 10.7375ZM6.66602 1.6665V3.33317H9.99935V9.1665H6.66602V11.6665H4.99935V9.1665H1.66602V3.33317H4.99935V1.6665H6.66602ZM14.166 2.49984C16.0069 2.49984 17.4993 3.99222 17.4993 5.83317V7.49984H15.8327V5.83317C15.8327 4.9127 15.0865 4.1665 14.166 4.1665H11.666V2.49984H14.166ZM4.99935 4.99984H3.33268V7.49984H4.99935V4.99984ZM8.33268 4.99984H6.66602V7.49984H8.33268V4.99984Z" fill="currentColor"/>
</svg>
<span class="lang-text">{{ currentLanguage === 'zh' ? '中' : 'EN' }}</span>
</button>
</template>
<script setup>
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
const { locale } = useI18n()
const currentLanguage = computed(() => locale.value)
const toggleLanguage = () => {
console.log('[LanguageSwitcher] 当前语言:', locale.value)
// 切换语言
const newLang = locale.value === 'zh' ? 'en' : 'zh'
console.log('[LanguageSwitcher] 切换到:', newLang)
// 直接更新 locale响应式切换
locale.value = newLang
// 保存到 localStorage 以便下次刷新时使用
localStorage.setItem('language', newLang)
console.log('[LanguageSwitcher] localStorage 已保存:', localStorage.getItem('language'))
console.log('[LanguageSwitcher] 语言切换完成(无刷新)')
}
</script>
<style scoped>
.language-switcher {
height: 36px;
padding: 0 12px;
border-radius: 18px;
background: rgba(255, 255, 255, 0.12);
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
border: none;
cursor: pointer;
transition: all 0.2s ease;
color: white;
}
.language-switcher:hover {
background: rgba(255, 255, 255, 0.2);
transform: scale(1.05);
}
.language-switcher:active {
transform: scale(0.95);
}
.language-switcher svg {
width: 20px;
height: 20px;
flex-shrink: 0;
}
.lang-text {
font-size: 13px;
font-weight: 500;
letter-spacing: 0.5px;
}
</style>

View File

@@ -4,7 +4,7 @@
<!-- Logo -->
<div class="navbar-brand">
<router-link to="/" class="brand-link">
<span class="brand-text">AIGC Demo</span>
<img src="/images/backgrounds/logo.svg" alt="Logo" class="brand-logo" />
</router-link>
</div>
@@ -19,31 +19,31 @@
@select="handleMenuSelect"
>
<el-menu-item index="/welcome">
<span>欢迎页</span>
<span>{{ $t('common.welcome') }}</span>
</el-menu-item>
<el-menu-item index="/home">
<span>首页</span>
<span>{{ $t('common.home') }}</span>
</el-menu-item>
<el-menu-item v-if="userStore.isAuthenticated" index="/profile">
<span>个人主页</span>
<span>{{ $t('common.profile') }}</span>
</el-menu-item>
<el-menu-item v-if="userStore.isAuthenticated" index="/orders">
<span>订单管理</span>
<span>{{ $t('common.orders') }}</span>
</el-menu-item>
<el-menu-item v-if="userStore.isAuthenticated" index="/payments">
<span>支付记录</span>
<span>{{ $t('common.payments') }}</span>
</el-menu-item>
<el-menu-item v-if="userStore.isAdmin" index="/admin/orders">
<span>后台管理</span>
<span>{{ $t('common.adminPanel') }}</span>
</el-menu-item>
<el-menu-item v-if="userStore.isAdmin" index="/admin/dashboard">
<span>数据仪表盘</span>
<span>{{ $t('dashboard.title') }}</span>
</el-menu-item>
</el-menu>
@@ -57,38 +57,40 @@
<!-- 用户菜单 -->
<div class="navbar-user">
<template v-if="userStore.isAuthenticated">
<LanguageSwitcher />
<el-dropdown @command="handleUserCommand">
<span class="user-dropdown">
<span>{{ userStore.username }}</span>
<el-tag v-if="userStore.user?.points" size="small" type="success" class="points-tag">
{{ userStore.user.points }}积分
<el-tag v-if="userStore.availablePoints > 0" size="small" type="success" class="points-tag">
{{ userStore.availablePoints }}{{ $t('common.points') }}
</el-tag>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="profile">
个人资料
{{ $t('common.userProfile') }}
</el-dropdown-item>
<el-dropdown-item v-if="userStore.isAdmin" command="admin">
后台管理
{{ $t('common.adminPanel') }}
</el-dropdown-item>
<el-dropdown-item command="settings">
设置
{{ $t('common.settings') }}
</el-dropdown-item>
<el-dropdown-item divided command="logout">
退出登录
{{ $t('common.logout') }}
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>
<template v-else>
<LanguageSwitcher />
<el-button type="primary" plain @click="$router.push('/login')">
登录
{{ $t('common.login') }}
</el-button>
<el-button type="success" plain @click="$router.push('/register')">
注册
{{ $t('common.register') }}
</el-button>
</template>
</div>
@@ -100,8 +102,11 @@
import { ref, onMounted, onUnmounted } from 'vue'
import { useUserStore } from '@/stores/user'
import { useRouter } from 'vue-router'
import { useI18n } from 'vue-i18n'
import { ElMessage, ElMessageBox } from 'element-plus'
import LanguageSwitcher from './LanguageSwitcher.vue'
const { t } = useI18n()
const userStore = useUserStore()
const router = useRouter()
@@ -130,29 +135,29 @@ const handleMenuSelect = (index) => {
const handleUserCommand = async (command) => {
switch (command) {
case 'profile':
ElMessage.info('个人资料功能开发中')
ElMessage.info(t('common.profileDevMsg'))
break
case 'admin':
// 检查管理员权限
if (userStore.isAdmin) {
router.push('/admin/dashboard')
} else {
ElMessage.warning('权限不足,只有管理员才能访问后台管理')
ElMessage.warning(t('common.noPermissionMsg'))
}
break
case 'settings':
ElMessage.info('设置功能开发中')
ElMessage.info(t('common.settingsDevMsg'))
break
case 'logout':
try {
await ElMessageBox.confirm('确定要退出登录吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
await ElMessageBox.confirm(t('common.logoutConfirm'), t('common.tip'), {
confirmButtonText: t('common.confirm'),
cancelButtonText: t('common.cancel'),
type: 'warning'
})
await userStore.logoutUser()
ElMessage.success('退出登录成功')
ElMessage.success(t('common.logoutSuccess'))
router.push('/')
} catch (error) {
// 用户取消
@@ -191,6 +196,11 @@ const handleUserCommand = async (command) => {
font-weight: bold;
}
.brand-logo {
height: 40px;
width: auto;
}
.brand-icon {
margin-right: 8px;
font-size: 24px;

View File

@@ -43,7 +43,7 @@
</div>
</div>
</div>
<div class="qr-tip">支付前请阅读XX 付费服务协议</div>
<div class="qr-tip">支付前请阅读Vionow支付服务条款</div>
</div>
<!-- 支付提示 -->
@@ -76,7 +76,7 @@
<!-- 底部链接 -->
<div class="footer-link">
<a href="#" @click.prevent="showAgreement">XX 付费服务协议</a>
<a href="#" @click.prevent="showAgreement">Vionow支付服务条款</a>
</div>
</div>
</el-dialog>
@@ -84,6 +84,7 @@
<script setup>
import { ref, watch, onUnmounted } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { CreditCard } from '@element-plus/icons-vue'
import { createPayment, createAlipayPayment, getPaymentById, testPaymentComplete } from '@/api/payments'
@@ -109,6 +110,7 @@ const props = defineProps({
const emit = defineEmits(['update:modelValue', 'pay-success', 'pay-error'])
const router = useRouter()
const visible = ref(false)
const selectedMethod = ref('alipay')
const loading = ref(false)
@@ -388,7 +390,7 @@ const handleTestPaymentComplete = async () => {
// 显示协议
const showAgreement = () => {
ElMessage.info('服务协议页面')
router.push('/terms-of-service')
}
</script>