refactor(i18n): 移除多语言支持及相关组件,切换登录页文本为中文

- 删除英文和中文语言文件,去除国际化配置
- 移除语言切换组件 LangSwitch.vue
- 登录页中静态替换多语言文本为中文文本
- 站点头部登录、退出等文案替换为中文
- 更新 Nuxt 配置,移除 i18n 模块和相关配置
- 保持核心功能不变,只保留中文语言显示
This commit is contained in:
2026-04-26 02:39:43 +08:00
parent 2cbb77c4d1
commit 55f1cded6b
7 changed files with 41 additions and 717 deletions

Binary file not shown.

View File

@@ -1,53 +0,0 @@
<template>
<a-dropdown :trigger="['click']" placement="bottomRight">
<a-button type="text" class="lang-btn">
<template #icon>
<GlobalOutlined />
</template>
<span class="current-lang">{{ currentLocaleName }}</span>
<DownOutlined class="ml-1" />
</a-button>
<template #overlay>
<a-menu @click="switchLocale">
<a-menu-item v-for="loc in availableLocales" :key="loc.code">
<div class="flex items-center justify-between gap-4">
<span>{{ loc.name }}</span>
<CheckOutlined v-if="loc.code === currentLocale" class="text-green-500" />
</div>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</template>
<script setup lang="ts">
import { GlobalOutlined, DownOutlined, CheckOutlined } from '@ant-design/icons-vue'
const { locale: currentLocale, locales, setLocale } = useI18n()
const availableLocales = computed(() => {
return (locales.value as Array<{ code: string; name: string }>).map((l) => ({
code: l.code,
name: l.name
}))
})
const currentLocaleName = computed(() => {
const found = availableLocales.value.find((l) => l.code === currentLocale.value)
return found?.name || currentLocale.value
})
async function switchLocale({ key }: { key: string }) {
await setLocale(key)
}
</script>
<style scoped>
.lang-btn {
@apply text-gray-300 hover:text-white;
}
.current-lang {
@apply text-sm;
}
</style>

View File

@@ -44,7 +44,7 @@
<!-- PC 登录/头像 --> <!-- PC 登录/头像 -->
<div class="hidden md:flex items-center gap-3"> <div class="hidden md:flex items-center gap-3">
<template v-if="!isAuthed"> <template v-if="!isAuthed">
<a-button type="primary" @click="navigateTo('/login')">{{ $t('nav.login') }}</a-button> <a-button type="primary" @click="navigateTo('/login')">{{ '登录' }}</a-button>
</template> </template>
<template v-else> <template v-else>
<!-- 用户头像 --> <!-- 用户头像 -->
@@ -66,7 +66,7 @@
<a-menu-item key="admin"> 后台管理</a-menu-item> <a-menu-item key="admin"> 后台管理</a-menu-item>
</template> </template>
<a-menu-divider /> <a-menu-divider />
<a-menu-item key="logout">{{ $t('nav.logout') }}</a-menu-item> <a-menu-item key="logout">{{ '退出登录' }}</a-menu-item>
</a-menu> </a-menu>
</template> </template>
</a-dropdown> </a-dropdown>
@@ -84,7 +84,7 @@
</a-layout-header> </a-layout-header>
</a-affix> </a-affix>
<a-drawer v-model:open="open" :title="$t('nav.navigation') || '导航'" placement="right"> <a-drawer v-model:open="open" :title="'导航' || '导航'" placement="right">
<a-menu mode="inline" :selected-keys="selectedKeys"> <a-menu mode="inline" :selected-keys="selectedKeys">
<template v-for="item in nav" :key="item.key"> <template v-for="item in nav" :key="item.key">
<a-sub-menu v-if="item.children && item.children.length" :key="item.key"> <a-sub-menu v-if="item.children && item.children.length" :key="item.key">
@@ -103,11 +103,11 @@
</template> </template>
</a-menu> </a-menu>
<div class="mt-4"> <div class="mt-4">
<a-button v-if="!isAuthed" block type="primary" @click="onNav('/login')">{{ $t('nav.login') || '登录' }}</a-button> <a-button v-if="!isAuthed" block type="primary" @click="onNav('/login')">{{ '登录' || '登录' }}</a-button>
<template v-else> <template v-else>
<a-button block type="primary" class="mb-2" @click="onNav('/profile')">个人中心</a-button> <a-button block type="primary" class="mb-2" @click="onNav('/profile')">个人中心</a-button>
<a-button v-if="isSuperAdmin" block @click="onNav('/admin')"> 后台管理</a-button> <a-button v-if="isSuperAdmin" block @click="onNav('/admin')"> 后台管理</a-button>
<a-button block danger class="mt-2" @click="logout">{{ $t('nav.logout') || '退出登录' }}</a-button> <a-button block danger class="mt-2" @click="logout">{{ '退出登录' || '退出登录' }}</a-button>
</template> </template>
</div> </div>
</a-drawer> </a-drawer>

View File

@@ -57,8 +57,8 @@
<!-- 登录卡片头部 --> <!-- 登录卡片头部 -->
<div class="form-header"> <div class="form-header">
<h2 class="form-title">{{ $t('login.welcomeBack') }}</h2> <h2 class="form-title">{{ '欢迎回来' }}</h2>
<p class="form-subtitle">{{ $t('login.loginToContinue') }}</p> <p class="form-subtitle">{{ '请登录您的账号以继续' }}</p>
</div> </div>
<!-- 切换标签 --> <!-- 切换标签 -->
@@ -69,7 +69,7 @@
@click="setLoginType('scan')" @click="setLoginType('scan')"
> >
<QrcodeOutlined /> <QrcodeOutlined />
{{ $t('login.scanLogin') }} {{ '扫码登录' }}
</button> </button>
<button <button
class="login-tab" class="login-tab"
@@ -77,7 +77,7 @@
@click="setLoginType('sms')" @click="setLoginType('sms')"
> >
<MobileOutlined /> <MobileOutlined />
{{ $t('login.phoneLogin') }} {{ '手机号登录' }}
</button> </button>
</div> </div>
@@ -91,7 +91,7 @@
size="large" size="large"
allow-clear allow-clear
:maxlength="11" :maxlength="11"
:placeholder="$t('login.phonePlaceholder')" :placeholder="'请输入手机号码'"
class="form-input" class="form-input"
> >
<template #prefix> <template #prefix>
@@ -108,7 +108,7 @@
size="large" size="large"
allow-clear allow-clear
:maxlength="6" :maxlength="6"
:placeholder="$t('login.smsCodePlaceholder')" :placeholder="'请输入验证码'"
class="form-input" class="form-input"
@press-enter="submitSms" @press-enter="submitSms"
/> />
@@ -118,8 +118,8 @@
:class="{ disabled: countdown > 0 }" :class="{ disabled: countdown > 0 }"
@click.prevent="openImgCodeModal" @click.prevent="openImgCodeModal"
> >
<span v-if="countdown <= 0">{{ $t('login.sendCode') }}</span> <span v-if="countdown <= 0">{{ '发送验证码' }}</span>
<span v-else>{{ countdown }}{{ $t('login.resendAfter') }}</span> <span v-else>{{ countdown }}{{ 's 后重发' }}</span>
</button> </button>
</div> </div>
</a-form-item> </a-form-item>
@@ -128,10 +128,10 @@
<div class="agreement-row"> <div class="agreement-row">
<a-checkbox v-model:checked="form.agreement"> <a-checkbox v-model:checked="form.agreement">
<span class="agreement-text"> <span class="agreement-text">
{{ $t('login.agreeTerms') }} {{ '我已阅读并同意' }}
<NuxtLink to="/agreement" target="_blank" class="agreement-link" @click.stop>{{ $t('login.registerAgreement') }}</NuxtLink> <NuxtLink to="/agreement" target="_blank" class="agreement-link" @click.stop>{{ '注册协议' }}</NuxtLink>
{{ $t('common.and') || '' }} {{ '' || '' }}
<NuxtLink to="/privacy" target="_blank" class="agreement-link" @click.stop>{{ $t('login.privacyPolicy') }}</NuxtLink> <NuxtLink to="/privacy" target="_blank" class="agreement-link" @click.stop>{{ '隐私政策' }}</NuxtLink>
</span> </span>
</a-checkbox> </a-checkbox>
</div> </div>
@@ -145,7 +145,7 @@
class="submit-btn" class="submit-btn"
@click="submitSms" @click="submitSms"
> >
{{ loading ? $t('login.loggingIn') : $t('login.loginNow') }} {{ loading ? '登录中…' : '立即登录' }}
</a-button> </a-button>
</a-form-item> </a-form-item>
</template> </template>
@@ -161,39 +161,39 @@
<button class="switch-scan-btn" @click="toggleScan"> <button class="switch-scan-btn" @click="toggleScan">
<QrcodeOutlined v-if="loginType !== 'scan'" /> <QrcodeOutlined v-if="loginType !== 'scan'" />
<MobileOutlined v-else /> <MobileOutlined v-else />
{{ loginType === 'scan' ? $t('login.switchToPhone') : $t('login.switchToScan') }} {{ loginType === 'scan' ? '切换到手机号登录' : '切换到扫码登录' }}
</button> </button>
</div> </div>
</div> </div>
</div> </div>
<!-- 图形验证码弹窗发送短信用 --> <!-- 图形验证码弹窗发送短信用 -->
<a-modal v-model:open="imgCodeModalOpen" :width="360" :footer="null" :title="$t('login.securityVerify')"> <a-modal v-model:open="imgCodeModalOpen" :width="360" :footer="null" :title="'安全验证'">
<p class="modal-tip">{{ $t('login.completeVerifyFirst') }}</p> <p class="modal-tip">{{ '请先完成图形验证码验证' }}</p>
<div class="captcha-row modal-captcha"> <div class="captcha-row modal-captcha">
<a-input <a-input
v-model:value="imgCode" v-model:value="imgCode"
size="large" size="large"
allow-clear allow-clear
:maxlength="5" :maxlength="5"
:placeholder="$t('login.enterImgCode')" :placeholder="'请输入图形验证码'"
@press-enter="sendSmsCode" @press-enter="sendSmsCode"
/> />
<button class="captcha-img-btn" @click.prevent="changeCaptcha" :title="$t('login.clickRefresh')"> <button class="captcha-img-btn" @click.prevent="changeCaptcha" :title="'点击刷新'">
<img alt="captcha" :src="captcha" /> <img alt="captcha" :src="captcha" />
</button> </button>
</div> </div>
<a-button block size="large" type="primary" :loading="sendingSms" class="submit-btn" @click="sendSmsCode"> <a-button block size="large" type="primary" :loading="sendingSms" class="submit-btn" @click="sendSmsCode">
{{ $t('login.sendCode') }} {{ '发送验证码' }}
</a-button> </a-button>
</a-modal> </a-modal>
<!-- 选择账号弹窗 --> <!-- 选择账号弹窗 -->
<a-modal v-model:open="selectUserOpen" :width="520" :footer="null" :title="$t('login.selectAccount')"> <a-modal v-model:open="selectUserOpen" :width="520" :footer="null" :title="'选择账号登录'">
<a-list item-layout="horizontal" :data-source="admins"> <a-list item-layout="horizontal" :data-source="admins">
<template #renderItem="{ item }"> <template #renderItem="{ item }">
<a-list-item class="list-item" @click="selectUser(item)"> <a-list-item class="list-item" @click="selectUser(item)">
<a-list-item-meta :description="`${$t('login.tenantId')}: ${item.tenantId}`"> <a-list-item-meta :description="`${'租户ID'}: ${item.tenantId}`">
<template #title>{{ item.tenantName || item.username }}</template> <template #title>{{ item.tenantName || item.username }}</template>
<template #avatar> <template #avatar>
<a-avatar :src="item.avatar" /> <a-avatar :src="item.avatar" />
@@ -225,8 +225,6 @@ import { getUserInfo } from '@/api/layout'
import { TEMPLATE_ID } from '@/config/setting' import { TEMPLATE_ID } from '@/config/setting'
import { setToken } from '@/utils/token-util' import { setToken } from '@/utils/token-util'
import type { QrCodeStatusResponse } from '@/api/passport/qrLogin' import type { QrCodeStatusResponse } from '@/api/passport/qrLogin'
const { t } = useI18n()
definePageMeta({ layout: false }) definePageMeta({ layout: false })
const route = useRoute() const route = useRoute()
@@ -260,10 +258,10 @@ const form = reactive<LoginParam & { smsCode?: string; agreement?: boolean }>({
const phoneReg = /^1[3-9]\d{9}$/ const phoneReg = /^1[3-9]\d{9}$/
const rules = reactive({ const rules = reactive({
phone: [ phone: [
{ required: true, message: t('login.enterPhone'), type: 'string' }, { required: true, message: '请输入手机号码', type: 'string' },
{ pattern: phoneReg, message: t('login.phoneFormatError'), trigger: 'blur' } { pattern: phoneReg, message: '手机号格式不正确', trigger: 'blur' }
], ],
smsCode: [{ required: true, message: t('login.enterSmsCode'), type: 'string' }] smsCode: [{ required: true, message: '请输入短信验证码', type: 'string' }]
}) })
const bgStyle = computed(() => { const bgStyle = computed(() => {
@@ -292,27 +290,27 @@ async function changeCaptcha() {
captcha.value = data.base64 captcha.value = data.base64
captchaText.value = data.text captchaText.value = data.text
} catch (e: unknown) { } catch (e: unknown) {
message.error(e instanceof Error ? e.message : t('login.loginFailed')) message.error(e instanceof Error ? e.message : '登录失败')
} }
} }
function openImgCodeModal() { function openImgCodeModal() {
if (!form.phone) return message.error(t('login.enterPhone')) if (!form.phone) return message.error('请输入手机号码')
imgCode.value = '' imgCode.value = ''
changeCaptcha() changeCaptcha()
imgCodeModalOpen.value = true imgCodeModalOpen.value = true
} }
async function sendSmsCode() { async function sendSmsCode() {
if (!imgCode.value) return message.error(t('login.enterImgCode')) if (!imgCode.value) return message.error('请输入图形验证码')
if (captchaText.value && imgCode.value.toLowerCase() !== captchaText.value.toLowerCase()) { if (captchaText.value && imgCode.value.toLowerCase() !== captchaText.value.toLowerCase()) {
return message.error(t('login.imgCodeIncorrect')) return message.error('图形验证码不正确')
} }
sendingSms.value = true sendingSms.value = true
try { try {
await sendSmsCaptcha({ phone: form.phone }) await sendSmsCaptcha({ phone: form.phone })
message.success(t('login.smsSentSuccess')) message.success('短信验证码发送成功,请注意查收')
imgCodeModalOpen.value = false imgCodeModalOpen.value = false
countdown.value = 30 countdown.value = 30
stopCountdown() stopCountdown()
@@ -322,7 +320,7 @@ async function sendSmsCode() {
if (countdown.value <= 0) stopCountdown() if (countdown.value <= 0) stopCountdown()
}, 1000) }, 1000)
} catch (e: unknown) { } catch (e: unknown) {
message.error(e instanceof Error ? e.message : t('login.sendFailed')) message.error(e instanceof Error ? e.message : '发送失败')
} finally { } finally {
sendingSms.value = false sendingSms.value = false
} }
@@ -360,7 +358,7 @@ async function submitSms() {
if (!formRef.value) return if (!formRef.value) return
// 校验协议勾选 // 校验协议勾选
if (!form.agreement) { if (!form.agreement) {
return message.error(t('login.agreeRequired')) return message.error('请先阅读并同意《注册协议》和《隐私政策》')
} }
loading.value = true loading.value = true
try { try {
@@ -381,11 +379,11 @@ async function submitSms() {
return return
} }
message.success(msg || t('login.loginSuccess')) message.success(msg || '登录成功')
await ensureUserIdPersisted() await ensureUserIdPersisted()
await goAfterLogin() await goAfterLogin()
} catch (e: unknown) { } catch (e: unknown) {
message.error(e instanceof Error ? e.message : t('login.loginFailed')) message.error(e instanceof Error ? e.message : '登录失败')
} finally { } finally {
loading.value = false loading.value = false
} }
@@ -406,12 +404,12 @@ async function onQrLoginSuccess(payload: QrCodeStatusResponse) {
? (payload.userInfo as { userId?: unknown }).userId ? (payload.userInfo as { userId?: unknown }).userId
: undefined : undefined
await ensureUserIdPersisted(seedUserId) await ensureUserIdPersisted(seedUserId)
message.success(t('login.scanLoginSuccess')) message.success('扫码登录成功')
await goAfterLogin() await goAfterLogin()
} }
function onQrLoginError(error: string) { function onQrLoginError(error: string) {
message.error(error || t('login.scanLoginFailed')) message.error(error || '扫码登录失败')
} }
onMounted(async () => { onMounted(async () => {

View File

@@ -1,302 +0,0 @@
// English language file
export default {
// Common
common: {
loading: 'Loading...',
confirm: 'Confirm',
cancel: 'Cancel',
save: 'Save',
delete: 'Delete',
edit: 'Edit',
add: 'Add',
search: 'Search',
reset: 'Reset',
submit: 'Submit',
back: 'Back',
next: 'Next',
prev: 'Previous',
success: 'Success',
error: 'Error',
warning: 'Warning',
info: 'Info',
yes: 'Yes',
no: 'No',
and: 'and',
required: 'Required',
optional: 'Optional',
all: 'All',
noData: 'No Data',
viewMore: 'View More',
viewAll: 'View All',
contact: 'Contact Us',
learnMore: 'Learn More',
goNow: 'Go Now',
tryNow: 'Try Now',
processing: 'Processing...',
devEnv: 'Dev Environment',
prodEnv: 'Production Environment'
},
// Home page
home: {
// Hero section
heroTag: 'OpenClaw Official Partner Platform',
heroTitle: 'AI-Native Application Development Platform: Next-Gen AI Agent Platform Integrated with OpenClaw Ecosystem',
heroDesc: 'For AI-era business scenarios like websites, e-commerce, and mini-programs. Deeply integrated with OpenClaw open-source AI Agent framework; built-in AI agent engine supporting knowledge base Q&A, intelligent customer service, content generation, automated workflows and multi-platform integration. Automatically create tenants, initialize modules and data after customer payment - "Pay to Activate, AI Ready to Use".',
bookDemo: 'Book Demo',
viewFlow: 'View Activation Flow',
deploy: 'Private Deployment',
// OpenClaw ecosystem
openclawTitle: 'Deep Integration with OpenClaw Open-Source Framework',
openclawSubtitle: 'AI Agent Ecosystem',
openclawDesc: 'MIT open-source licensed, 315K+ GitHub stars, giving AI "hands" to execute complex tasks',
// AI capability cards
multiPlatform: 'Multi-Platform Seamless Integration',
multiPlatformDesc: 'Support 20+ communication platforms including WhatsApp, Telegram, Discord, Feishu, WeChat - one AI serving multiple channels simultaneously',
multiModel: 'Flexible Multi-Model Switching',
multiModelDesc: 'Support 25+ LLMs including Claude, GPT, DeepSeek, Ollama - local deployment for data privacy',
autoWorkflow: 'Automated Workflows',
autoWorkflowDesc: 'Scheduled tasks, skill systems, MCP tool extensions - upgrade AI from "can talk" to "can do"',
experienceAI: 'Experience AI Agent',
// Product matrix
productMatrix: 'Product Matrix',
productMatrixDesc: 'Marketable products for different business scenarios, supporting package sales, pay-to-activate, template/plugin add-ons and private deployment.',
recommend: 'Recommended',
// Core capabilities
coreCapabilities: 'Core Capabilities',
coreCapabilitiesDesc: 'Cover product sales, delivery activation, operational upgrades and ecosystem monetization with one platform.',
// OpenClaw AI Agent
openclawAI: 'OpenClaw AI Agent',
openclawAIDesc: 'Deep integration with OpenClaw framework, support 20+ platform access, 25+ model switching - let AI truly execute tasks.',
// RAG Knowledge Base
ragKnowledge: 'RAG Knowledge Base',
ragKnowledgeDesc: 'Enterprise-grade RAG solution with document parsing, vector storage, intelligent retrieval and Q&A - greatly improve AI response quality.',
// SaaS Multi-tenant
saasMultiTenant: 'SaaS Multi-Tenant Platform',
saasMultiTenantDesc: 'Tenant isolation, organization and permission system, configuration center and audit capabilities - unified foundation for multiple business lines.',
// Private Deployment
privateDeploy: 'Private Deployment',
privateDeployDesc: 'Support local/private cloud deployment with deployment documentation, acceptance checklist and upgrade strategy - meet security compliance.',
// Template Market
templateMarket: 'Template Market',
templateMarketDesc: 'Industry templates one-click apply with default configs and init scripts - more standardized delivery, faster launch.',
// Auto Activation
autoActivate: 'Auto Activation Chain',
autoActivateDesc: 'After payment: auto-create tenant, initialize modules/menus/data, and deliver access.',
// Pay to activate
payToActivate: 'Pay to Activate',
payToActivateDesc: 'After customer selects and pays for a product, the platform automatically: creates tenant, initializes modules, writes default configs and data, generates admin account and delivers access.',
viewFullFlow: 'View Full Flow',
// Activation flow steps
selectProduct: 'Select Product/Package',
selectProductDesc: 'Support product matrix, template/plugin add-ons, value-added items',
placeOrder: 'Place Order & Pay',
placeOrderDesc: 'Payment success triggers activation task orchestration',
createTenant: 'Create Tenant',
createTenantDesc: 'Tenant isolation, domain/app info binding, admin generation',
initModules: 'Initialize Modules',
initModulesDesc: 'Load modules and menu permissions per purchased product, write base/sample data',
deliverOnline: 'Deliver & Go Live',
deliverOnlineDesc: 'SaaS ready to use; private deployment delivers images/docs/acceptance checklist',
// Templates and Plugins
templatePluginEcosystem: 'Template & Plugin Ecosystem',
templatePluginDesc: 'Accelerate delivery with templates, extend capabilities with plugins; support purchase, authorization, updates and version management.',
template: 'Template',
plugin: 'Plugin',
industryTemplate: 'Industry Templates',
industryTemplateDesc: 'Complete pages and configs by industry/scenario, support one-click apply, secondary editing and multi-version management.',
deliveryStandard: 'Delivery Standardization',
deliveryStandardDesc: 'Templates paired with init scripts make "post-activation default site" directly acceptable.',
capabilityExtend: 'Capability Extension',
capabilityExtendDesc: 'Payment, membership, marketing, tickets, data analytics - add capabilities on demand, use immediately.',
upgradeAuth: 'Upgrade & Authorization',
upgradeAuthDesc: 'Support version upgrades, authorization verification, renewal and canary release.',
exploreMarket: 'Explore Template/Plugin Market',
// CTA
ctaTitle: 'Want to quickly build and deliver an operational product?',
ctaDesc: 'Book a demo and we\'ll provide a solution and quote based on your business scenario.',
viewProducts: 'View Product Matrix',
contactNow: 'Contact Now',
// Video
videoNotSupported: 'Your browser does not support video playback'
},
// Login page
login: {
// Left brand area
aiPlatform: 'Guangxi Decision Consulting Center',
buildNextGen: 'Expert Wisdom\nServing Government Decisions',
lowcodeAccess: 'Expert Think Tank · Policy Research · Decision Consulting',
fromIdeaToOnline: 'From Research to Practice, Professional Support Throughout',
developers: 'Certified Experts',
aiApps: 'Member Organizations',
uptime: 'Suggestions',
// Right form
aiAppPlatform: 'Guangxi Decision Consulting Network',
// QR scan login
scanLogin: 'Scan to Login',
scanLoginDesc: 'Use the App to scan QR code for quick login',
// Welcome back
welcomeBack: 'Welcome Back',
loginToContinue: 'Please login to continue',
// Login methods
phoneLogin: 'Phone Login',
accountLogin: 'Account Login',
// Input placeholders
accountPlaceholder: 'Account / User ID',
passwordPlaceholder: 'Password',
captchaPlaceholder: 'Captcha Code',
phonePlaceholder: 'Enter phone number',
smsCodePlaceholder: 'Enter SMS code',
// Actions
rememberLogin: 'Remember Login',
clickRefresh: 'Click to refresh',
clickGet: 'Click to get',
sendCode: 'Send Code',
resendAfter: 's to resend',
loginNow: 'Login Now',
loggingIn: 'Logging in...',
// Agreement
agreeTerms: 'I have read and agree to',
registerAgreement: 'Terms of Service',
privacyPolicy: 'Privacy Policy',
agreeRequired: 'Please read and agree to the Terms of Service and Privacy Policy',
// Switch
switchToPhone: 'Switch to Phone Login',
switchToScan: 'Scan Login',
// Security verification modal
securityVerify: 'Security Verification',
completeVerifyFirst: 'Please complete the captcha verification first',
enterImgCode: 'Enter captcha code',
imgCodeIncorrect: 'Incorrect captcha code',
// Select account
selectAccount: 'Select Account',
tenantId: 'Tenant ID',
// Error messages
enterAccount: 'Please enter account',
enterPassword: 'Please enter password',
enterCaptcha: 'Please enter captcha',
enterPhone: 'Please enter phone number',
phoneFormatError: 'Invalid phone number format',
enterSmsCode: 'Please enter SMS code',
// Messages
smsSentSuccess: 'SMS code sent successfully, please check',
sendFailed: 'Send failed',
loginSuccess: 'Login successful',
loginFailed: 'Login failed',
scanLoginSuccess: 'Scan login successful',
scanLoginFailed: 'Scan login failed'
},
// Navigation
nav: {
home: 'Home',
products: 'Products',
pricing: 'Pricing',
docs: 'Docs',
blog: 'Blog',
about: 'About',
contact: 'Contact',
login: 'Login',
register: 'Register',
dashboard: 'Dashboard',
userCenter: 'Account',
logout: 'Logout',
language: 'Language',
navigation: 'Navigation',
orders: 'My Orders',
developer: 'Developer Center',
admin: 'Admin'
},
// Developer Center
developer: {
title: 'Developer Center',
overview: 'Overview',
myApps: 'My Apps',
resources: 'Resources',
git: 'Git Binding',
permissionRequests: 'Permission Requests',
apiDocs: 'API Docs',
settings: 'Settings'
},
// Resource Center
resources: {
title: 'Resource Center',
servers: 'Servers',
databases: 'Databases',
storage: 'Storage',
domains: 'Domains',
ssl: 'SSL Certificates',
addResource: 'Add Resource',
resourceType: 'Resource Type',
resourceName: 'Resource Name',
status: 'Status',
createTime: 'Create Time',
expireTime: 'Expire Time',
actions: 'Actions',
active: 'Active',
stopped: 'Stopped',
expired: 'Expired'
},
// Permission
permission: {
title: 'Permission Requests',
applyNew: 'Apply for New Permission',
myRequests: 'My Requests',
repository: 'Repository',
permission: 'Permission',
status: 'Status',
applyTime: 'Apply Time',
pending: 'Pending',
approved: 'Approved',
rejected: 'Rejected',
applyReason: 'Reason',
submit: 'Submit Request'
},
// Page Titles
pageTitle: {
// Home SEO
homeTitle: 'AI-Native Application Development Platform - Next-Gen AI Agent Platform Integrated with OpenClaw',
homeDescription: 'Deep integration with OpenClaw open-source framework (315K+ GitHub Stars), providing SaaS multi-tenant, AI agents, RAG knowledge base and private deployment. Support 20+ platform access, 25+ model switching - let AI truly execute complex tasks.',
// Login
loginTitle: 'Login',
// Developer Center
developerCenter: 'Developer Center',
// Resource Center
resourceCenter: 'Resource Center',
// Permission Request
permissionRequest: 'Permission Request'
}
}

View File

@@ -1,302 +0,0 @@
// 中文语言文件
export default {
// 通用
common: {
loading: '加载中...',
confirm: '确认',
cancel: '取消',
save: '保存',
delete: '删除',
edit: '编辑',
add: '添加',
search: '搜索',
reset: '重置',
submit: '提交',
back: '返回',
next: '下一步',
prev: '上一步',
success: '成功',
error: '失败',
warning: '警告',
info: '提示',
yes: '是',
no: '否',
and: '和',
required: '必填',
optional: '选填',
all: '全部',
noData: '暂无数据',
viewMore: '查看更多',
viewAll: '查看全部',
contact: '联系我们',
learnMore: '了解更多',
goNow: '立即前往',
tryNow: '立即体验',
processing: '处理中...',
devEnv: '开发环境',
prodEnv: '生产环境'
},
// 首页
home: {
// Hero 区域
heroTag: 'OpenClaw 官方合作平台',
heroTitle: 'AI-Native 应用开发平台:集成 OpenClaw 生态的下一代 AI 智能体平台',
heroDesc: '面向 AI 时代的官网、电商、小程序等业务场景,深度集成 OpenClaw 开源 AI Agent 框架;内置 AI 智能体引擎,支持知识库问答、智能客服、内容生成、自动化工作流与多平台接入。客户下单后自动创建租户、初始化模块与基础数据,实现"支付即开通,开箱即用 AI"。',
bookDemo: '预约演示',
viewFlow: '查看开通流程',
deploy: '私有化部署',
// OpenClaw 生态
openclawTitle: '深度集成 OpenClaw 开源框架',
openclawSubtitle: 'AI 智能体生态',
openclawDesc: '源自 MIT 开源协议315K+ GitHub 星标认证,让 AI 拥有"双手"执行复杂任务',
// AI 能力卡片
multiPlatform: '多平台无感接入',
multiPlatformDesc: '支持 WhatsApp、Telegram、Discord、飞书、微信等 20+ 通讯平台,一个 AI 同时服务多渠道',
multiModel: '多模型灵活切换',
multiModelDesc: '支持 Claude、GPT、DeepSeek、Ollama 等 25+ 大模型,本地部署保护数据隐私',
autoWorkflow: '自动化工作流',
autoWorkflowDesc: '定时任务、技能系统、MCP 工具扩展,让 AI 从"能说"升级为"能做"',
experienceAI: '体验 AI 智能体',
// 产品矩阵
productMatrix: '产品矩阵',
productMatrixDesc: '面向不同业务场景的可售卖产品,支持套餐化售卖、支付即开通、模板/插件加购与私有化交付。',
recommend: '推荐',
// 核心能力
coreCapabilities: '核心能力',
coreCapabilitiesDesc: '用一套平台能力,覆盖产品售卖、交付开通、运营升级与生态变现。',
// OpenClaw AI 智能体
openclawAI: 'OpenClaw AI 智能体',
openclawAIDesc: '深度集成 OpenClaw 开源框架,支持 20+ 平台接入、25+ 模型切换,让 AI 真正执行任务。',
// RAG 知识库
ragKnowledge: 'RAG 知识库',
ragKnowledgeDesc: '企业级 RAG 方案,支持文档解析、向量化存储、智能检索与问答,大幅提升 AI 回复质量。',
// SaaS 多租户
saasMultiTenant: 'SaaS 多租户平台',
saasMultiTenantDesc: '租户隔离、组织与权限体系、配置中心与审计能力,为多业务线统一底座。',
// 私有化部署
privateDeploy: '私有化部署',
privateDeployDesc: '支持本地/专有云部署,提供部署文档、验收清单与升级策略,满足安全合规。',
// 模板市场
templateMarket: '模板市场',
templateMarketDesc: '行业模板一键套用,默认配置与初始化脚本配套,交付更标准、上线更快。',
// 自动开通
autoActivate: '自动开通链路',
autoActivateDesc: '选品支付后自动创建租户、初始化模块/菜单/基础数据,并交付访问入口。',
// 支付即开通
payToActivate: '支付即开通',
payToActivateDesc: '客户选择产品并支付后,平台自动完成:创建租户、初始化模块、写入默认配置与基础数据、生成管理员账号并交付访问入口。',
viewFullFlow: '查看全流程',
// 开通流程步骤
selectProduct: '选择产品/套餐',
selectProductDesc: '支持产品矩阵、模板/插件加购、增值项',
placeOrder: '下单支付',
placeOrderDesc: '支付成功触发开通任务编排',
createTenant: '创建租户',
createTenantDesc: '租户隔离、域名/应用信息绑定、管理员生成',
initModules: '模块初始化',
initModulesDesc: '按所购产品加载模块与菜单权限,写入基础数据/示例数据',
deliverOnline: '交付上线',
deliverOnlineDesc: 'SaaS 直接可用;私有化交付镜像/部署文档/验收清单',
// 模板与插件
templatePluginEcosystem: '模板与插件生态',
templatePluginDesc: '通过模板加速交付,通过插件扩展能力;支持购买、授权、更新与版本管理。',
template: '模板',
plugin: '插件',
industryTemplate: '行业模板',
industryTemplateDesc: '按行业/场景提供成套页面与配置,支持一键套用、二次编辑与多版本管理。',
deliveryStandard: '交付标准化',
deliveryStandardDesc: '模板与初始化脚本配套,让"开通后的默认站点"可直接验收。',
capabilityExtend: '能力扩展',
capabilityExtendDesc: '支付、会员、营销、工单、数据统计等能力按需加购,随买随用。',
upgradeAuth: '升级与授权',
upgradeAuthDesc: '支持版本升级、授权校验、到期续费与灰度发布。',
exploreMarket: '了解模板/插件市场',
// CTA
ctaTitle: '想快速搭建并交付一个可运营的产品?',
ctaDesc: '预约演示,我们将按你的业务场景给出方案与报价。',
viewProducts: '看产品矩阵',
contactNow: '马上联系',
// 视频
videoNotSupported: '您的浏览器不支持视频播放'
},
// 登录页
login: {
// 左侧品牌区
aiPlatform: '广西决策咨询中心',
buildNextGen: '汇聚专家智慧\n服务政府决策',
lowcodeAccess: '专家智库 · 政策研究 · 决策咨询',
fromIdeaToOnline: '从研究到实践,全程专业支持',
developers: '认证专家',
aiApps: '会员单位',
uptime: '建言献策',
// 右侧表单
aiAppPlatform: '广西决策咨询网',
// 扫码登录
scanLogin: '扫码登录',
scanLoginDesc: '使用 App 扫描二维码快速登录',
// 欢迎回来
welcomeBack: '欢迎回来',
loginToContinue: '请登录您的账号以继续',
// 登录方式
phoneLogin: '手机号登录',
accountLogin: '账号登录',
// 输入提示
accountPlaceholder: '账号 / 用户ID',
passwordPlaceholder: '登录密码',
captchaPlaceholder: '图形验证码',
phonePlaceholder: '请输入手机号码',
smsCodePlaceholder: '请输入验证码',
// 操作
rememberLogin: '记住登录',
clickRefresh: '点击刷新',
clickGet: '点击获取',
sendCode: '发送验证码',
resendAfter: 's 后重发',
loginNow: '立即登录',
loggingIn: '登录中…',
// 协议
agreeTerms: '我已阅读并同意',
registerAgreement: '《注册协议》',
privacyPolicy: '《隐私政策》',
agreeRequired: '请先阅读并同意《注册协议》和《隐私政策》',
// 切换
switchToPhone: '切换到手机号登录',
switchToScan: '扫码登录',
// 安全验证弹窗
securityVerify: '安全验证',
completeVerifyFirst: '请先完成图形验证码验证',
enterImgCode: '请输入图形验证码',
imgCodeIncorrect: '图形验证码不正确',
// 选择账号
selectAccount: '选择账号登录',
tenantId: '租户ID',
// 错误提示
enterAccount: '请输入账号',
enterPassword: '请输入密码',
enterCaptcha: '请输入验证码',
enterPhone: '请输入手机号码',
phoneFormatError: '手机号格式不正确',
enterSmsCode: '请输入短信验证码',
// 消息
smsSentSuccess: '短信验证码发送成功,请注意查收',
sendFailed: '发送失败',
loginSuccess: '登录成功',
loginFailed: '登录失败',
scanLoginSuccess: '扫码登录成功',
scanLoginFailed: '扫码登录失败'
},
// 导航
nav: {
home: '首页',
products: '产品',
pricing: '价格',
docs: '文档',
blog: '博客',
about: '关于我们',
contact: '联系我们',
login: '登录',
register: '注册',
dashboard: '控制台',
userCenter: '账户信息',
logout: '退出登录',
language: '语言',
navigation: '导航',
orders: '我的订单',
developer: '开发者中心',
admin: '后台管理'
},
// 开发者中心
developer: {
title: '开发者中心',
overview: '概览',
myApps: '我的应用',
resources: '资源管理',
git: 'Git 绑定',
permissionRequests: '权限申请',
apiDocs: 'API 文档',
settings: '设置'
},
// 资源中心
resources: {
title: '资源中心',
servers: '服务器',
databases: '数据库',
storage: '存储',
domains: '域名',
ssl: 'SSL证书',
addResource: '添加资源',
resourceType: '资源类型',
resourceName: '资源名称',
status: '状态',
createTime: '创建时间',
expireTime: '过期时间',
actions: '操作',
active: '运行中',
stopped: '已停止',
expired: '已过期'
},
// 权限申请
permission: {
title: '权限申请',
applyNew: '申请新权限',
myRequests: '我的申请',
repository: '仓库',
permission: '权限',
status: '状态',
applyTime: '申请时间',
pending: '待审核',
approved: '已通过',
rejected: '已拒绝',
applyReason: '申请理由',
submit: '提交申请'
},
// 页面标题
pageTitle: {
// 首页 SEO
homeTitle: 'AI-Native 应用开发平台 - 集成 OpenClaw 生态的下一代 AI 智能体平台',
homeDescription: '深度集成 OpenClaw 开源框架 (315K+ GitHub Stars),提供 SaaS 多租户、AI 智能体、RAG 知识库与私有化部署能力。支持 20+ 平台接入、25+ 模型切换,让 AI 真正执行复杂任务。',
// 登录
loginTitle: '登录',
// 开发者中心
developerCenter: '开发者中心',
// 资源管理
resourceCenter: '资源中心',
// 权限申请
permissionRequest: '权限申请'
}
}

View File

@@ -45,7 +45,7 @@ const WATCH_IGNORED = [
export default defineNuxtConfig({ export default defineNuxtConfig({
compatibilityDate: '2025-07-15', compatibilityDate: '2025-07-15',
devtools: { enabled: true }, devtools: { enabled: true },
modules: ['@nuxt/content', '@nuxtjs/tailwindcss', '@nuxtjs/i18n', './modules/fix-tailwind-postcss'], modules: ['@nuxt/content', '@nuxtjs/tailwindcss', './modules/fix-tailwind-postcss'],
app: { app: {
head: { head: {
titleTemplate: '%s - 决策咨询网', titleTemplate: '%s - 决策咨询网',
@@ -63,23 +63,6 @@ export default defineNuxtConfig({
}, },
experimental: { appManifest: false }, experimental: { appManifest: false },
// i18n 配置
i18n: {
locales: [
{ code: 'zh-CN', name: '简体中文', file: 'zh-CN.ts' },
{ code: 'en', name: 'English', file: 'en.ts' }
],
defaultLocale: 'zh-CN',
langDir: '../locales',
strategy: 'no_prefix',
detectBrowserLanguage: {
useCookie: true,
cookieKey: 'i18n_locale',
redirectOn: 'root',
alwaysRedirect: true,
fallbackLocale: 'zh-CN'
}
},
runtimeConfig: { runtimeConfig: {
public: { public: {
tenantId, tenantId,