Compare commits
4 Commits
7d501d33ab
...
55f1cded6b
| Author | SHA1 | Date | |
|---|---|---|---|
| 55f1cded6b | |||
| 2cbb77c4d1 | |||
| 5571c9c8f3 | |||
| 1cbb841444 |
Binary file not shown.
@@ -24,5 +24,5 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"lastUpdated": 1777141054743
|
"lastUpdated": 1777141862851
|
||||||
}
|
}
|
||||||
@@ -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>
|
|
||||||
@@ -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>
|
||||||
|
|||||||
@@ -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 () => {
|
||||||
|
|||||||
303
locales/en.ts
303
locales/en.ts
@@ -1,303 +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',
|
|
||||||
copyrightYear: '© {{ year }}',
|
|
||||||
copyright: '@:login.copyrightYear Guangxi Decision Consulting Center · Professional · Authoritative · Efficient',
|
|
||||||
|
|
||||||
// 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'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
303
locales/zh-CN.ts
303
locales/zh-CN.ts
@@ -1,303 +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: '建言献策',
|
|
||||||
copyrightYear: '© {{ year }}',
|
|
||||||
copyright: '@:login.copyrightYear 广西决策咨询中心 · 专业 · 权威 · 高效',
|
|
||||||
|
|
||||||
// 右侧表单
|
|
||||||
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: '权限申请'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user