mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2026-09-22 16:00:51 +00:00
feat: add router expires alert (#12855)
This commit is contained in:
@@ -106,7 +106,7 @@ func OperationLog() gin.HandlerFunc {
|
||||
writer := responseBodyWriter{
|
||||
ResponseWriter: c.Writer,
|
||||
body: &bytes.Buffer{},
|
||||
captureBody: shouldCaptureResponseBody(c.Request.URL.Path),
|
||||
captureBody: !strings.Contains(strings.ToLower(c.Request.URL.Path), "download"),
|
||||
}
|
||||
c.Writer = &writer
|
||||
now := time.Now()
|
||||
@@ -272,16 +272,8 @@ func (r *responseBodyWriter) Write(b []byte) (int, error) {
|
||||
return r.ResponseWriter.Write(b)
|
||||
}
|
||||
|
||||
func shouldCaptureResponseBody(reqPath string) bool {
|
||||
reqPath = strings.ToLower(reqPath)
|
||||
if strings.Contains(reqPath, "download") {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func loadLogInfo(path string) string {
|
||||
path = replaceStr(path, "/api/v2", "/core", "/xpack")
|
||||
path = replaceStr(path, "/api/v2", "/core", "/xpack", "/enterprise")
|
||||
if !strings.Contains(path, "/") {
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -1,25 +1,44 @@
|
||||
<template>
|
||||
<el-card class="router_card p-1 sm:p-0">
|
||||
<div class="flex w-full flex-col justify-start sm:items-center items-start sm:justify-between sm:flex-row">
|
||||
<el-radio-group v-model="activeName" @change="handleChange">
|
||||
<el-radio-button
|
||||
class="router_card_button"
|
||||
:label="button.label"
|
||||
:value="button.label"
|
||||
v-for="(button, index) in buttonArray"
|
||||
size="large"
|
||||
:key="index"
|
||||
>
|
||||
<el-badge :value="button.count" v-if="button.count" is-dot>
|
||||
<span>{{ button.label }}</span>
|
||||
</el-badge>
|
||||
</el-radio-button>
|
||||
</el-radio-group>
|
||||
<div class="flex flex-col gap-2 sm:flex-row">
|
||||
<slot name="route-button"></slot>
|
||||
<div>
|
||||
<el-card class="router_card p-1 sm:p-0">
|
||||
<div class="flex w-full flex-col justify-start sm:items-center items-start sm:justify-between sm:flex-row">
|
||||
<el-radio-group v-model="activeName" @change="handleChange">
|
||||
<el-radio-button
|
||||
class="router_card_button"
|
||||
:label="button.label"
|
||||
:value="button.label"
|
||||
v-for="(button, index) in buttonArray"
|
||||
size="large"
|
||||
:key="index"
|
||||
>
|
||||
<el-badge :value="button.count" v-if="button.count" is-dot>
|
||||
<span>{{ button.label }}</span>
|
||||
</el-badge>
|
||||
</el-radio-button>
|
||||
</el-radio-group>
|
||||
<div class="flex flex-col gap-2 sm:flex-row">
|
||||
<slot name="route-button"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
<div class="mt-3" v-if="showExpiresAt && expiresAlertVisible && productProExpires && productProExpires !== 0">
|
||||
<el-alert type="warning" @close="handleExpiresAlertClose">
|
||||
<template #title>
|
||||
<div class="text-xs">
|
||||
<div class="flex flex-col gap-2 items-center justify-center w-full sm:flex-row">
|
||||
<span>
|
||||
{{ $t(expiresAlertKey, [expiresInfo]) }}
|
||||
</span>
|
||||
<span @click="goXpack" class="flex items-center justify-center gap-0.5 jump">
|
||||
<el-icon><Position /></el-icon>
|
||||
{{ $t('firewall.quickJump') }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-alert>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
@@ -27,6 +46,7 @@ import { routerToNameWithQuery, routerToPathWithQuery } from '@/utils/router';
|
||||
import { computed, onMounted, ref, watch } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { hasPermissionMetaAccess, hasRouteAccess } from '@/utils/rbac';
|
||||
import { useGlobalStore } from '@/composables/useGlobalStore';
|
||||
|
||||
defineOptions({ name: 'RouterButton' });
|
||||
|
||||
@@ -35,9 +55,14 @@ const props = defineProps({
|
||||
type: Array<RouterButton>,
|
||||
required: true,
|
||||
},
|
||||
showExpiresAt: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
const router = useRouter();
|
||||
const { isEnterprise, isIntl, productProExpires } = useGlobalStore();
|
||||
const buttonArray = computed(() => {
|
||||
return props.buttons.filter((button) => {
|
||||
if (!hasPermissionMetaAccess(button.permission)) {
|
||||
@@ -52,6 +77,9 @@ const buttonArray = computed(() => {
|
||||
});
|
||||
|
||||
const activeName = ref('');
|
||||
const expiresInfo = ref(0);
|
||||
const expiresAlertVisible = ref(false);
|
||||
const expiresAlertKey = computed(() => (isEnterprise.value ? 'xpack.expiresEnterpriseAlert' : 'xpack.expiresProAlert'));
|
||||
|
||||
const handleChange = (label: string) => {
|
||||
const btn = buttonArray.value.find((btn) => btn.label === label);
|
||||
@@ -63,6 +91,7 @@ const handleChange = (label: string) => {
|
||||
|
||||
onMounted(() => {
|
||||
syncActiveName();
|
||||
loadExpiresAlert();
|
||||
});
|
||||
|
||||
watch(
|
||||
@@ -72,6 +101,13 @@ watch(
|
||||
},
|
||||
);
|
||||
|
||||
watch(
|
||||
() => [props.showExpiresAt, productProExpires.value],
|
||||
() => {
|
||||
loadExpiresAlert();
|
||||
},
|
||||
);
|
||||
|
||||
function syncActiveName() {
|
||||
if (!buttonArray.value.length) {
|
||||
activeName.value = '';
|
||||
@@ -91,6 +127,52 @@ function syncActiveName() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getExpiresAlertDateKey() {
|
||||
const newDate = new Date();
|
||||
return newDate.getFullYear() + '-' + newDate.getMonth() + '-' + newDate.getDate();
|
||||
}
|
||||
|
||||
function loadExpiresAlert() {
|
||||
const expires = productProExpires.value;
|
||||
if (!props.showExpiresAt || !expires || expires === 0) {
|
||||
expiresInfo.value = 0;
|
||||
expiresAlertVisible.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (getExpiresAlertDateKey() === localStorage.getItem('xpack-expires-alert')) {
|
||||
expiresInfo.value = 0;
|
||||
expiresAlertVisible.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const currentTimestamp = Date.now() / 1000;
|
||||
if (expires < currentTimestamp) {
|
||||
expiresInfo.value = 0;
|
||||
expiresAlertVisible.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const daySeconds = 24 * 60 * 60;
|
||||
const diffSeconds = Math.abs(expires - currentTimestamp);
|
||||
expiresInfo.value = Math.floor(diffSeconds / daySeconds) + 1;
|
||||
expiresAlertVisible.value = expiresInfo.value <= 15;
|
||||
}
|
||||
|
||||
function goXpack() {
|
||||
if (isIntl.value && !isEnterprise.value) {
|
||||
window.open('https://1panel.hk/pricing', '_blank', 'noopener,noreferrer');
|
||||
return;
|
||||
}
|
||||
const url = isEnterprise.value ? 'https://1panel.cn/enterprise.html' : 'https://www.lxware.cn/1panel';
|
||||
window.open(url, '_blank', 'noopener,noreferrer');
|
||||
}
|
||||
|
||||
function handleExpiresAlertClose() {
|
||||
localStorage.setItem('xpack-expires-alert', getExpiresAlertDateKey());
|
||||
loadExpiresAlert();
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -2003,6 +2003,8 @@ const message = {
|
||||
nodes: 'Node',
|
||||
commands: 'Quick Commands',
|
||||
opsReport: 'Ops Report',
|
||||
users: 'User Management',
|
||||
auth: 'Login Authentication',
|
||||
},
|
||||
websiteLog: 'Website logs',
|
||||
runLog: 'Run logs',
|
||||
@@ -3954,10 +3956,10 @@ const message = {
|
||||
noFail: 'Mount failure does not affect system startup',
|
||||
},
|
||||
xpack: {
|
||||
expiresTrialAlert:
|
||||
'Friendly reminder: Your Commercial Edition trial will expire in {0} days, and all Commercial Edition features will no longer be accessible. Please renew or upgrade to the full version in a timely manner.',
|
||||
expiresAlert:
|
||||
'Friendly reminder: Your Commercial Edition license will expire in {0} days, and all Commercial Edition features will no longer be accessible. Please renew promptly to ensure continued usage.',
|
||||
expiresEnterpriseAlert:
|
||||
'Friendly reminder: Your Enterprise Edition license will expire in {0} days, and all Enterprise Edition features will no longer be accessible. Please renew promptly to ensure continued usage.',
|
||||
expiresProAlert:
|
||||
'Friendly reminder: Your Pro Edition license will expire in {0} days, and all Pro Edition features will no longer be accessible. Please renew promptly to ensure continued usage.',
|
||||
menu: 'Pro',
|
||||
upage: 'AI Website Builder',
|
||||
proAlert: 'Upgrade to Commercial Edition to use this feature',
|
||||
|
||||
@@ -2054,6 +2054,8 @@ const message = {
|
||||
nodes: 'Nodo',
|
||||
commands: 'Comandos rápidos',
|
||||
opsReport: 'Informe de operaciones',
|
||||
users: 'Gestión de usuarios',
|
||||
auth: 'Autenticación de inicio de sesión',
|
||||
},
|
||||
websiteLog: 'Logs de sitio web',
|
||||
runLog: 'Logs de ejecución',
|
||||
@@ -4012,10 +4014,10 @@ const message = {
|
||||
noFail: 'El fallo de montaje no afecta al inicio del sistema',
|
||||
},
|
||||
xpack: {
|
||||
expiresTrialAlert:
|
||||
'Aviso: Tu prueba de la edición comercial expirará en {0} días y todas las funciones comerciales dejarán de estar disponibles. Renueva o actualiza a la versión completa a tiempo.',
|
||||
expiresAlert:
|
||||
'Aviso: Tu licencia la edición comercial expirará en {0} días y todas las funciones comerciales dejarán de estar disponibles. Renueva pronto para asegurar el uso continuo.',
|
||||
expiresEnterpriseAlert:
|
||||
'Aviso: Tu licencia de Enterprise Edition expirará en {0} días y todas las funciones de Enterprise Edition dejarán de estar disponibles. Renueva pronto para asegurar el uso continuo.',
|
||||
expiresProAlert:
|
||||
'Aviso: Tu licencia de Pro Edition expirará en {0} días y todas las funciones de Pro Edition dejarán de estar disponibles. Renueva pronto para asegurar el uso continuo.',
|
||||
menu: 'Pro',
|
||||
upage: 'Constructor Web con IA',
|
||||
proAlert: 'Actualiza a la edición comercial para usar esta función',
|
||||
|
||||
@@ -2025,6 +2025,8 @@ const message = {
|
||||
nodes: 'ノード',
|
||||
commands: 'クイックコマンド',
|
||||
opsReport: '運用レポート',
|
||||
users: 'ユーザー管理',
|
||||
auth: 'ログイン認証',
|
||||
},
|
||||
websiteLog: 'ウェブサイトログ',
|
||||
runLog: 'ログを実行します',
|
||||
@@ -3994,10 +3996,10 @@ const message = {
|
||||
noFail: 'マウント失敗はシステム起動に影響しません',
|
||||
},
|
||||
xpack: {
|
||||
expiresTrialAlert:
|
||||
'ご注意: あなたの商用版トライアルは{0}日後に終了し、すべての商用版機能が使用できなくなります。適時に更新またはフルバージョンにアップグレードしてください。',
|
||||
expiresAlert:
|
||||
'ご注意: あなたの商用版ライセンスは{0}日後に終了し、すべての商用版機能が使用できなくなります。継続的な使用のために速やかに更新してください。',
|
||||
expiresEnterpriseAlert:
|
||||
'ご注意: あなたのEnterprise Editionライセンスは{0}日後に終了し、すべてのEnterprise Edition機能が使用できなくなります。継続的な使用のために速やかに更新してください。',
|
||||
expiresProAlert:
|
||||
'ご注意: あなたのPro Editionライセンスは{0}日後に終了し、すべてのPro Edition機能が使用できなくなります。継続的な使用のために速やかに更新してください。',
|
||||
menu: 'Рro',
|
||||
upage: 'AIウェブサイトビルダー',
|
||||
proAlert: 'この機能を使用するには商用版にアップグレードしてください',
|
||||
|
||||
@@ -1982,6 +1982,8 @@ const message = {
|
||||
nodes: '노드',
|
||||
commands: '빠른 명령',
|
||||
opsReport: '운영 보고서',
|
||||
users: '사용자 관리',
|
||||
auth: '로그인 인증',
|
||||
},
|
||||
websiteLog: '웹사이트 로그',
|
||||
runLog: '실행 로그',
|
||||
@@ -3906,10 +3908,10 @@ const message = {
|
||||
noFail: '마운트 실패는 시스템 시작에 영향을 미치지 않습니다',
|
||||
},
|
||||
xpack: {
|
||||
expiresTrialAlert:
|
||||
'친절한 알림: 귀하의 상용 버전 체험판이 {0}일 후 만료되며, 모든 상용 버전 기능에 더 이상 접근할 수 없습니다. 제때 갱신하거나 전체 버전으로 업그레이드하시기 바랍니다.',
|
||||
expiresAlert:
|
||||
'친절한 알림: 귀하의 상용 버전 라이선스가 {0}일 후 만료되며, 모든 상용 버전 기능에 더 이상 접근할 수 없습니다. 지속적인 사용을 위해 신속하게 갱신하시기 바랍니다.',
|
||||
expiresEnterpriseAlert:
|
||||
'친절한 알림: 귀하의 Enterprise Edition 라이선스가 {0}일 후 만료되며, 모든 Enterprise Edition 기능에 더 이상 접근할 수 없습니다. 지속적인 사용을 위해 신속하게 갱신하시기 바랍니다.',
|
||||
expiresProAlert:
|
||||
'친절한 알림: 귀하의 Pro Edition 라이선스가 {0}일 후 만료되며, 모든 Pro Edition 기능에 더 이상 접근할 수 없습니다. 지속적인 사용을 위해 신속하게 갱신하시기 바랍니다.',
|
||||
menu: 'Pro',
|
||||
upage: 'AI 웹사이트 빌더',
|
||||
proAlert: '이 기능을 사용하려면 상용 버전으로 업그레이드하세요',
|
||||
|
||||
@@ -2051,6 +2051,8 @@ const message = {
|
||||
nodes: 'nod',
|
||||
commands: 'Perintah Pantas',
|
||||
opsReport: 'Laporan Operasi',
|
||||
users: 'Pengurusan pengguna',
|
||||
auth: 'Pengesahan log masuk',
|
||||
},
|
||||
websiteLog: 'Log Laman Web',
|
||||
runLog: 'Log Jalankan',
|
||||
@@ -4049,10 +4051,10 @@ const message = {
|
||||
mountPoint: 'Titik lekap',
|
||||
},
|
||||
xpack: {
|
||||
expiresTrialAlert:
|
||||
'Peringatan mesra: Percubaan Edisi Komersial anda akan tamat dalam {0} hari, dan semua ciri Edisi Komersial tidak lagi dapat diakses. Sila perbaharui atau naik taraf ke versi penuh tepat pada masanya.',
|
||||
expiresAlert:
|
||||
'Peringatan mesra: Lesen Edisi Komersial anda akan tamat dalam {0} hari, dan semua ciri Edisi Komersial tidak lagi dapat diakses. Sila perbaharui segera untuk memastikan penggunaan berterusan.',
|
||||
expiresEnterpriseAlert:
|
||||
'Peringatan mesra: Lesen Enterprise Edition anda akan tamat dalam {0} hari, dan semua ciri Enterprise Edition tidak lagi dapat diakses. Sila perbaharui segera untuk memastikan penggunaan berterusan.',
|
||||
expiresProAlert:
|
||||
'Peringatan mesra: Lesen Pro Edition anda akan tamat dalam {0} hari, dan semua ciri Pro Edition tidak lagi dapat diakses. Sila perbaharui segera untuk memastikan penggunaan berterusan.',
|
||||
menu: 'Pro',
|
||||
upage: 'Pembina Laman Web AI',
|
||||
proAlert: 'Tingkatkan ke Edisi Komersial untuk menggunakan ciri ini',
|
||||
|
||||
@@ -2165,6 +2165,8 @@ const message = {
|
||||
nodes: 'nós',
|
||||
commands: 'Comandos Rápidos',
|
||||
opsReport: 'Relatório de Operações',
|
||||
users: 'Gerenciamento de usuários',
|
||||
auth: 'Autenticação de login',
|
||||
},
|
||||
websiteLog: 'Logs do website',
|
||||
runLog: 'Logs de execução',
|
||||
@@ -4188,10 +4190,10 @@ const message = {
|
||||
noFail: 'Falha na montagem não afeta a inicialização do sistema',
|
||||
},
|
||||
xpack: {
|
||||
expiresTrialAlert:
|
||||
'Lembrete: Sua avaliação da edição comercial expira em {0} dias. Depois disso, todos os recursos da edição comercial deixarão de ficar disponíveis. Renove ou faça upgrade em tempo hábil.',
|
||||
expiresAlert:
|
||||
'Lembrete: Sua licença da edição comercial expira em {0} dias. Depois disso, todos os recursos da edição comercial deixarão de ficar disponíveis. Renove a licença para manter o uso contínuo.',
|
||||
expiresEnterpriseAlert:
|
||||
'Lembrete: Sua licença da Enterprise Edition expira em {0} dias. Depois disso, todos os recursos da Enterprise Edition deixarão de ficar disponíveis. Renove a licença para manter o uso contínuo.',
|
||||
expiresProAlert:
|
||||
'Lembrete: Sua licença da Pro Edition expira em {0} dias. Depois disso, todos os recursos da Pro Edition deixarão de ficar disponíveis. Renove a licença para manter o uso contínuo.',
|
||||
menu: 'Pro',
|
||||
upage: 'Construtor de Sites com IA',
|
||||
proAlert: 'Atualize para comercial para usar este recurso',
|
||||
|
||||
@@ -2038,6 +2038,8 @@ const message = {
|
||||
nodes: 'ноды',
|
||||
commands: 'Быстрые команды',
|
||||
opsReport: 'Операционный отчет',
|
||||
users: 'Управление пользователями',
|
||||
auth: 'Аутентификация входа',
|
||||
},
|
||||
websiteLog: 'Логи веб-сайта',
|
||||
runLog: 'Логи выполнения',
|
||||
@@ -4040,10 +4042,10 @@ const message = {
|
||||
noFail: 'Сбой монтирования не влияет на запуск системы',
|
||||
},
|
||||
xpack: {
|
||||
expiresTrialAlert:
|
||||
'Дружеское напоминание: ваша пробная коммерческая версия истечет через {0} дней, и все функции коммерческой версии станут недоступны. Пожалуйста, своевременно продлите или обновите до коммерческой версии.',
|
||||
expiresAlert:
|
||||
'Дружеское напоминание: ваша лицензия коммерческой версии истечет через {0} дней, и все функции коммерческой версии станут недоступны. Пожалуйста, продлите лицензию вовремя, чтобы обеспечить дальнейшее использование.',
|
||||
expiresEnterpriseAlert:
|
||||
'Дружеское напоминание: ваша лицензия Enterprise Edition истечет через {0} дней, и все функции Enterprise Edition станут недоступны. Пожалуйста, продлите лицензию вовремя, чтобы обеспечить дальнейшее использование.',
|
||||
expiresProAlert:
|
||||
'Дружеское напоминание: ваша лицензия Pro Edition истечет через {0} дней, и все функции Pro Edition станут недоступны. Пожалуйста, продлите лицензию вовремя, чтобы обеспечить дальнейшее использование.',
|
||||
menu: 'Рro',
|
||||
upage: 'AI Конструктор сайтов',
|
||||
proAlert: 'Обновитесь до коммерческой версии, чтобы использовать эту функцию',
|
||||
|
||||
@@ -2047,6 +2047,8 @@ const message = {
|
||||
nodes: 'Düğüm',
|
||||
commands: 'Hızlı Komutlar',
|
||||
opsReport: 'Operasyon Raporu',
|
||||
users: 'Kullanıcı yönetimi',
|
||||
auth: 'Giriş kimlik doğrulaması',
|
||||
},
|
||||
websiteLog: 'Website logları',
|
||||
runLog: 'Çalıştırma logları',
|
||||
@@ -4041,10 +4043,10 @@ const message = {
|
||||
noFail: 'Bağlama hatası sistem başlangıcını etkilemez',
|
||||
},
|
||||
xpack: {
|
||||
expiresTrialAlert:
|
||||
'Nazik hatırlatma: Ticari sürüm denemeniz {0} gün içinde sona erecek ve tüm Ticari sürüm özellikleri kullanılamaz hale gelecektir. Lütfen zamanında yenileyin veya tam sürüme yükseltin.',
|
||||
expiresAlert:
|
||||
'Nazik hatırlatma: Ticari sürüm lisansınız {0} gün içinde sona erecek ve tüm Ticari sürüm özellikleri kullanılamaz hale gelecektir. Lütfen devam eden kullanım için zamanında yenileyin.',
|
||||
expiresEnterpriseAlert:
|
||||
'Nazik hatırlatma: Enterprise Edition lisansınız {0} gün içinde sona erecek ve tüm Enterprise Edition özellikleri kullanılamaz hale gelecektir. Lütfen devam eden kullanım için zamanında yenileyin.',
|
||||
expiresProAlert:
|
||||
'Nazik hatırlatma: Pro Edition lisansınız {0} gün içinde sona erecek ve tüm Pro Edition özellikleri kullanılamaz hale gelecektir. Lütfen devam eden kullanım için zamanında yenileyin.',
|
||||
menu: 'Pro',
|
||||
upage: 'AI Web Sitesi Oluşturucu',
|
||||
proAlert: 'Bu özelliği kullanmak için Ticari sürüme yükseltin',
|
||||
|
||||
@@ -1892,6 +1892,8 @@ const message = {
|
||||
nodes: '節點',
|
||||
commands: '快速指令',
|
||||
opsReport: '運維報表',
|
||||
users: '使用者管理',
|
||||
auth: '登入認證',
|
||||
},
|
||||
websiteLog: '網站日誌',
|
||||
runLog: '執行日誌',
|
||||
@@ -3681,7 +3683,8 @@ const message = {
|
||||
noFail: '掛載失敗不影響系統啟動',
|
||||
},
|
||||
xpack: {
|
||||
expiresAlert: '溫馨提醒:您的商業版許可證將在 {0} 天後到期,屆時所有商業版功能將無法繼續使用。',
|
||||
expiresEnterpriseAlert: '溫馨提醒:您的企業版許可證將在 {0} 天後到期,屆時所有企業版功能將無法繼續使用。',
|
||||
expiresProAlert: '溫馨提醒:您的專業版許可證將在 {0} 天後到期,屆時所有專業版功能將無法繼續使用。',
|
||||
name: '商業版',
|
||||
menu: '進階功能',
|
||||
upage: 'AI 建站',
|
||||
|
||||
@@ -1883,6 +1883,8 @@ const message = {
|
||||
nodes: '节点',
|
||||
commands: '快速命令',
|
||||
opsReport: '运维报表',
|
||||
users: '用户管理',
|
||||
auth: '登陆认证',
|
||||
},
|
||||
websiteLog: '网站日志',
|
||||
runLog: '运行日志',
|
||||
@@ -3670,7 +3672,8 @@ const message = {
|
||||
noFail: '挂载失败不影响系统启动',
|
||||
},
|
||||
xpack: {
|
||||
expiresAlert: '温馨提醒:商业版试用将于 [{0}] 天后到期,届时将停止使用所有商业版功能。',
|
||||
expiresEnterpriseAlert: '温馨提醒:企业版许可证将于 [{0}] 天后到期,届时将停止使用所有企业版功能。',
|
||||
expiresProAlert: '温馨提醒:专业版许可证将于 [{0}] 天后到期,届时将停止使用所有专业版功能。',
|
||||
menu: '高级功能',
|
||||
upage: 'AI 建站',
|
||||
proAlert: '升级商业版使用此功能',
|
||||
|
||||
@@ -248,7 +248,7 @@ onMounted(async () => {
|
||||
syncCustomAppstore.value = res.data.status === 'Enable';
|
||||
}
|
||||
}
|
||||
if (isOffline.value) {
|
||||
if (isOffline.value && !isEnterprise.value) {
|
||||
syncCustomAppstore.value = true;
|
||||
}
|
||||
mainHeight.value = window.innerHeight - 380;
|
||||
|
||||
Reference in New Issue
Block a user