diff --git a/.DS_Store b/.DS_Store
index 82c400a..3769869 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/backend/.DS_Store b/backend/.DS_Store
index 7cca320..b37bf87 100644
Binary files a/backend/.DS_Store and b/backend/.DS_Store differ
diff --git a/frontend/.DS_Store b/frontend/.DS_Store
index b9b9151..1d6ef60 100644
Binary files a/frontend/.DS_Store and b/frontend/.DS_Store differ
diff --git a/frontend/README.md b/frontend/README.md
new file mode 100644
index 0000000..936ccdd
--- /dev/null
+++ b/frontend/README.md
@@ -0,0 +1,169 @@
+# ALLinSSL 前端项目
+
+## 项目简介
+
+ALLinSSL是一个基于Monorepo架构的前端项目,使用Turborepo进行工作区管理,专注于提供SSL证书的申请、管理、部署和监控等功能。项目采用模块化设计,将通用功能抽象为独立包,提高代码复用性和可维护性。
+
+## 技术栈
+
+- **框架**:Vue 3.5.x
+- **开发语言**:TypeScript
+- **包管理工具**:pnpm 9.0.0
+- **Monorepo方案**:Turborepo
+- **构建工具**:Vite 6.x
+- **状态管理**:Pinia 2.x
+- **路由**:Vue Router 4.x
+- **UI组件库**:Naive UI 2.x
+- **CSS框架**:TailwindCSS 3.x
+- **国际化**:Vue I18n 11.x
+- **测试工具**:Vitest
+
+## 项目结构
+
+```
+frontend/
+├── apps/ # 应用目录
+│ └── allin-ssl/ # SSL证书管理应用
+├── packages/ # 共享包目录
+│ ├── hooks/ # 可复用的Vue Hooks
+│ ├── i18n/ # 国际化相关功能
+│ ├── naive-ui/ # UI组件库封装
+│ ├── pinia/ # 状态管理相关功能
+│ ├── router/ # 路由相关功能
+│ ├── utils/ # 通用工具函数
+│ └── vite/ # Vite相关配置和插件
+├── environment/ # 环境配置
+│ ├── eslint/ # ESLint配置
+│ ├── prettier/ # Prettier配置
+│ ├── stylelint/ # Stylelint配置
+│ └── typescript/ # TypeScript配置
+├── plugin/ # 项目插件
+│ ├── plugin-i18n/ # 国际化插件
+│ ├── project-ftp-sync/ # FTP同步插件
+│ └── project-sync-git/ # Git同步插件
+├── scripts/ # 脚本目录
+├── types/ # 全局类型定义
+└── turbo.json # Turborepo配置
+```
+
+## 应用
+
+### allin-ssl
+
+SSL证书管理平台,提供证书申请、管理、部署、监控等功能,帮助用户轻松管理和部署SSL证书,保障网站安全。
+
+## 共享包
+
+- **hooks**: 提供常用的Vue Hooks,简化组件逻辑
+- **i18n**: 国际化解决方案,支持多语言切换
+- **naive-ui**: 封装和扩展Naive UI组件库
+- **pinia**: 封装Pinia状态管理相关功能
+- **router**: 封装路由相关功能
+- **utils**: 提供常用工具函数和助手方法
+- **vite**: Vite相关配置和插件
+
+## 环境与规范
+
+- **eslint**: 代码质量检查配置
+- **prettier**: 代码格式化配置
+- **stylelint**: 样式质量检查配置
+- **typescript**: TypeScript配置
+
+## 插件
+
+- **plugin-i18n**: 国际化插件,支持自动提取和生成国际化资源
+- **project-ftp-sync**: FTP同步插件,用于部署前端资源
+- **project-sync-git**: Git同步插件,用于代码同步
+
+## 安装
+
+### 环境要求
+
+- Node.js >= 18.x
+- pnpm >= 9.0.0
+
+### 安装依赖
+
+```bash
+# 安装所有依赖
+pnpm install
+```
+
+## 开发命令
+
+```bash
+# 启动所有应用的开发服务
+pnpm dev
+
+# 只启动ALLinSSL应用
+pnpm dev --filter allin-ssl
+
+# 构建所有应用
+pnpm build
+
+# 只构建ALLinSSL应用
+pnpm build --filter allin-ssl
+
+# 运行代码检查
+pnpm lint
+
+# 运行类型检查
+pnpm check-types
+
+# 运行测试
+pnpm test
+
+# 清理构建缓存
+pnpm clear
+```
+
+## 开发指南
+
+### 新建应用
+
+1. 在 `apps` 目录下创建新的应用目录
+2. 初始化应用配置文件和依赖
+3. 在应用的 `package.json` 中添加对共享包的依赖
+
+### 使用共享包
+
+在应用或其他包的 `package.json` 中添加依赖,例如:
+
+```json
+"dependencies": {
+ "@baota/utils": "workspace:*",
+ "@baota/hooks": "workspace:*"
+}
+```
+
+### 开发规范
+
+1. 遵循项目的代码风格和组织方式
+2. 共享功能应提取到 `packages` 目录下的相应包中
+3. 应用特定功能应保留在各自的应用目录中
+4. 使用TypeScript进行类型定义
+5. 编写测试用例确保功能正确性
+
+## 部署
+
+### 构建生产版本
+
+```bash
+pnpm build
+```
+
+### FTP部署
+
+使用内置的FTP同步插件进行部署:
+
+```bash
+pnpm build
+# 自动部署到配置的FTP服务器
+```
+
+## 浏览器兼容性
+
+- Chrome >= 60
+- Firefox >= 55
+- Safari >= 11
+- Edge >= 79
diff --git a/frontend/apps/.DS_Store b/frontend/apps/.DS_Store
new file mode 100644
index 0000000..69bc89f
Binary files /dev/null and b/frontend/apps/.DS_Store differ
diff --git a/frontend/apps/allin-ssl/.DS_Store b/frontend/apps/allin-ssl/.DS_Store
new file mode 100644
index 0000000..cb53352
Binary files /dev/null and b/frontend/apps/allin-ssl/.DS_Store differ
diff --git a/frontend/apps/allin-ssl/README.md b/frontend/apps/allin-ssl/README.md
new file mode 100644
index 0000000..2787334
--- /dev/null
+++ b/frontend/apps/allin-ssl/README.md
@@ -0,0 +1,117 @@
+# ALLinSSL
+
+## 项目简介
+
+ALLinSSL是一个SSL证书管理平台,提供证书申请、管理、部署、监控等功能,帮助用户轻松管理和部署SSL证书,保障网站安全。
+
+## 技术栈
+
+- 框架:Vue 3.5.x
+- 开发语言:TypeScript
+- 构建工具:Vite 6.x
+- 状态管理:Pinia 2.x
+- 路由:Vue Router 4.x
+- UI组件库:Naive UI 2.x
+- CSS框架:TailwindCSS 3.x
+- 国际化:Vue I18n 11.x
+- HTTP客户端:Axios
+- 工具库:VueUse、UUID、CryptoJS等
+
+## 项目结构
+
+```
+src/
+├── api/ # API接口定义
+├── assets/ # 静态资源
+├── components/ # 公共组件
+├── config/ # 全局配置
+├── locales/ # 国际化资源
+├── router/ # 路由配置
+├── styles/ # 全局样式
+├── types/ # 类型定义
+├── views/ # 页面组件
+│ ├── autoDeploy/ # 自动部署
+│ ├── authApiManage/ # API管理
+│ ├── certApply/ # 证书申请
+│ ├── certManage/ # 证书管理
+│ ├── home/ # 首页
+│ ├── layout/ # 布局组件
+│ ├── login/ # 登录页面
+│ ├── monitor/ # 监控页面
+│ └── settings/ # 设置页面
+├── App.tsx # 应用根组件
+└── main.ts # 入口文件
+```
+
+## 功能模块
+
+- **证书管理**:集中管理所有SSL证书,包括查看、更新、删除等操作
+- **证书申请**:提供证书申请流程
+- **自动部署**:自动部署SSL证书到目标服务器
+- **监控系统**:监控证书状态,到期提醒等
+- **系统设置**:系统全局配置管理
+
+## 安装与运行
+
+### 环境要求
+
+- Node.js 16.x 或更高版本
+- pnpm 7.x 或更高版本(推荐使用)
+
+### 安装依赖
+
+```bash
+pnpm install
+```
+
+### 开发模式
+
+```bash
+pnpm dev
+```
+
+### 构建生产版本
+
+```bash
+pnpm build
+```
+
+### 预览构建结果
+
+```bash
+pnpm preview
+```
+
+### 运行测试
+
+```bash
+pnpm test
+```
+
+### 代码检查
+
+```bash
+pnpm lint
+```
+
+## 开发指南
+
+本项目采用模块化和组件化开发方式,开发新功能时请遵循以下原则:
+
+1. 遵循项目已有的代码风格和组织方式
+2. 新增API请在api目录下对应文件中添加
+3. 公共组件放在components目录
+4. 页面组件放在views目录下对应模块文件夹中
+5. 路由配置自动导入
+6. 使用CSS变量和TailwindCSS进行样式管理
+
+## 浏览器兼容性
+
+- Chrome >= 60
+- Firefox >= 55
+- Safari >= 11
+- Edge >= 79
+
+## 许可证
+
+私有项目,未经授权不得使用
diff --git a/frontend/apps/allin-ssl/cache/translation_cache.json b/frontend/apps/allin-ssl/cache/translation_cache.json
new file mode 100644
index 0000000..52c0bb5
--- /dev/null
+++ b/frontend/apps/allin-ssl/cache/translation_cache.json
@@ -0,0 +1,8280 @@
+{
+ "警告:您已进入未知区域,所访问的页面不存在,请点击按钮返回首页。": {
+ "text": "警告:您已进入未知区域,所访问的页面不存在,请点击按钮返回首页。",
+ "key": "t_0_1744098811152",
+ "translations": {
+ "zhCN": "警告:您已进入未知区域,所访问的页面不存在,请点击按钮返回首页。",
+ "zhTW": "警告:您已進入未知區域,所訪問的頁面不存在,請點擊按鈕返回首頁。",
+ "enUS": "Warning: You have entered an unknown area, the page you are visiting does not exist, please click the button to return to the homepage.",
+ "jaJP": "警告:未知のエリアに進入しました。アクセスしようとしたページは存在しません。ボタンをクリックしてホームページに戻ってください。",
+ "koKR": "경고: 알 수 없는 영역에 진입했습니다. 방문하려는 페이지가 존재하지 않습니다. 버튼을 클릭하여 홈페이지로 돌아가세요。",
+ "ruRU": "Предупреждение: Вы вошли в неизвестную зону, посещаемая страница не существует, пожалуйста, нажмите кнопку, чтобы вернуться на главную страницу.",
+ "ptBR": "Aviso: Você entrou em uma área desconhecida, a página que você está visitando não existe, por favor, clique no botão para voltar para a página inicial.",
+ "frFR": "Avertissement : Vous avez entré dans une zone inconnue, la page que vous visitez n'existe pas, veuillez cliquer sur le bouton pour revenir à la page d'accueil.",
+ "esAR": "Advertencia: Ha ingresado a una zona desconocida, la página que intenta visitar no existe, por favor, haga clic en el botón para regresar a la página de inicio.",
+ "arDZ": "تحذير: لقد دخلتم منطقة غير معروفة، الصفحة التي تحاول زيارتها غير موجودة، يرجى الضغط على الزر للعودة إلى الصفحة الرئيسية."
+ },
+ "timestamp": "2025-04-08T07:53:31.152Z"
+ },
+ "返回首页": {
+ "text": "返回首页",
+ "key": "t_1_1744098801860",
+ "translations": {
+ "zhCN": "返回首页",
+ "zhTW": "返回首頁",
+ "enUS": "Return Home",
+ "jaJP": "ホームに戻る",
+ "koKR": "홈으로 돌아가기",
+ "ruRU": "Вернуться на главную",
+ "ptBR": "Voltar para a homepage",
+ "frFR": "Retour à l'accueil",
+ "esAR": "Volver al inicio",
+ "arDZ": "رجوع إلى الصفحة الرئيسية"
+ },
+ "timestamp": "2025-04-08T07:53:31.153Z"
+ },
+ "安全提示:如果您认为这是个错误,请立即联系管理员": {
+ "text": "安全提示:如果您认为这是个错误,请立即联系管理员",
+ "key": "t_2_1744098804908",
+ "translations": {
+ "zhCN": "安全提示:如果您认为这是个错误,请立即联系管理员",
+ "zhTW": "安全提示:如果您認為這是個錯誤,請立即聯繫管理員",
+ "enUS": "Safety Tip: If you think this is an error, please contact the administrator immediately",
+ "jaJP": "安全注意:これが誤りだと思われる場合は、すぐに管理者に連絡してください",
+ "koKR": "안전 유의사항: 이가 오류라면 즉시 관리자에게 연락하십시오",
+ "ruRU": "Совет по безопасности: Если вы считаете, что это ошибка, немедленно свяжитесь с администратором",
+ "ptBR": "Dica de Segurança: Se você acha que isso é um erro, entre em contato com o administrador imediatamente",
+ "frFR": "Avis de sécurité : Si vous pensez que c'est une erreur, veuillez contacter l'administrateur immédiatement",
+ "esAR": "Consejo de seguridad: Si piensa que es un error, póngase en contacto con el administrador inmediatamente",
+ "arDZ": "نصيحة أمنية: إذا كنت تعتقد أن هذا خطأ، يرجى الاتصال بالمدير على الفور"
+ },
+ "timestamp": "2025-04-08T07:53:31.153Z"
+ },
+ "展开主菜单": {
+ "text": "展开主菜单",
+ "key": "t_3_1744098802647",
+ "translations": {
+ "zhCN": "展开主菜单",
+ "zhTW": "展開主菜單",
+ "enUS": "Expand Main Menu",
+ "jaJP": "メインメニューを展開する",
+ "koKR": "메인 메뉴 펼치기",
+ "ruRU": "Развернуть главное меню",
+ "ptBR": "Expandir o menu principal",
+ "frFR": "Développer le menu principal",
+ "esAR": "Expandir el menú principal",
+ "arDZ": "افتح القائمة الرئيسية"
+ },
+ "timestamp": "2025-04-08T07:53:31.153Z"
+ },
+ "折叠主菜单": {
+ "text": "折叠主菜单",
+ "key": "t_4_1744098802046",
+ "translations": {
+ "zhCN": "折叠主菜单",
+ "zhTW": "折疊主菜單",
+ "enUS": "Foldout Main Menu",
+ "jaJP": "折りたたみメインメニュー",
+ "koKR": "접기 메인 메뉴",
+ "ruRU": "Сворачиваемое главное меню",
+ "ptBR": "Menu principal dobrável",
+ "frFR": "Menu principal pliable",
+ "esAR": "Menú principal plegable",
+ "arDZ": "القائمة الرئيسية القابلة للطي"
+ },
+ "timestamp": "2025-04-08T07:53:31.153Z"
+ },
+ "欢迎使用AllinSSL,高效管理SSL证书": {
+ "text": "欢迎使用AllinSSL,高效管理SSL证书",
+ "key": "t_0_1744164843238",
+ "translations": {
+ "zhCN": "欢迎使用AllinSSL,高效管理SSL证书",
+ "zhTW": "歡迎使用AllinSSL,高效管理SSL憑證",
+ "enUS": "Welcome to AllinSSL, Efficient SSL Certificate Management",
+ "jaJP": "AllinSSLへようこそ、SSL証明書の効率的な管理",
+ "koKR": "AllinSSL을 환영합니다, SSL 셀프리피켓 효율적 관리",
+ "ruRU": "Добро пожаловать в AllinSSL, эффективное управление SSL-сертификатами",
+ "ptBR": "Bem-vindo ao AllinSSL, gerenciamento eficiente de certificados SSL",
+ "frFR": "Bienvenue dans AllinSSL, gestion efficace des certificats SSL",
+ "esAR": "Bienvenido a AllinSSL, gestión eficiente de certificados SSL",
+ "arDZ": "مرحبًا بكم في AllinSSL، إدارة فعالة لشهادات SSL"
+ },
+ "timestamp": "2025-04-09T02:14:03.238Z"
+ },
+ "AllinSSL": {
+ "text": "AllinSSL",
+ "key": "t_1_1744164835667",
+ "translations": {
+ "zhCN": "AllinSSL",
+ "zhTW": "AllinSSL",
+ "enUS": "AllinSSL",
+ "jaJP": "AllinSSL",
+ "koKR": "AllinSSL",
+ "ruRU": "AllinSSL",
+ "ptBR": "AllinSSL",
+ "frFR": "AllinSSL",
+ "esAR": "AllinSSL",
+ "arDZ": "AllinSSL"
+ },
+ "timestamp": "2025-04-09T02:14:03.240Z"
+ },
+ "账号登录": {
+ "text": "账号登录",
+ "key": "t_2_1744164839713",
+ "translations": {
+ "zhCN": "账号登录",
+ "zhTW": "帳號登錄",
+ "enUS": "Account Login",
+ "jaJP": "アカウントログイン",
+ "koKR": "계정 로그인",
+ "ruRU": "Вход в аккаунт",
+ "ptBR": "Login de Conta",
+ "frFR": "Connexion du compte",
+ "esAR": "Iniciar sesión en la cuenta",
+ "arDZ": "دخول الحساب"
+ },
+ "timestamp": "2025-04-09T02:14:03.240Z"
+ },
+ "请输入用户名": {
+ "text": "请输入用户名",
+ "key": "t_3_1744164839524",
+ "translations": {
+ "zhCN": "请输入用户名",
+ "zhTW": "請輸入用戶名",
+ "enUS": "Please enter the username",
+ "jaJP": "ユーザー名を入力してください",
+ "koKR": "사용자 이름을 입력하세요",
+ "ruRU": "Введите имя пользователя",
+ "ptBR": "Por favor, insira o nome de usuário",
+ "frFR": "Veuillez saisir le nom d'utilisateur",
+ "esAR": "Por favor, ingrese el nombre de usuario",
+ "arDZ": "من فضلك أدخل اسم المستخدم"
+ },
+ "timestamp": "2025-04-09T02:14:03.240Z"
+ },
+ "请输入密码": {
+ "text": "请输入密码",
+ "key": "t_4_1744164840458",
+ "translations": {
+ "zhCN": "请输入密码",
+ "zhTW": "請輸入密碼",
+ "enUS": "Please enter the password",
+ "jaJP": "パスワードを入力してください",
+ "koKR": "비밀번호를 입력하세요",
+ "ruRU": "Введіть пароль",
+ "ptBR": "Por favor, insira a senha",
+ "frFR": "Veuillez saisir le mot de passe",
+ "esAR": "Por favor, ingrese la contraseña",
+ "arDZ": "من فضلك أدخل كلمة المرور"
+ },
+ "timestamp": "2025-04-09T02:14:03.240Z"
+ },
+ "记住密码": {
+ "text": "记住密码",
+ "key": "t_5_1744164840468",
+ "translations": {
+ "zhCN": "记住密码",
+ "zhTW": "記住密碼",
+ "enUS": "Remember Password",
+ "jaJP": "パスワードを覚える",
+ "koKR": "암호를 기억하다",
+ "ruRU": "Запомнить пароль",
+ "ptBR": "Lembrar senha",
+ "frFR": "Rappelez-vous du mot de passe",
+ "esAR": "Recordar contraseña",
+ "arDZ": "تذكر كلمة المرور"
+ },
+ "timestamp": "2025-04-09T02:14:03.240Z"
+ },
+ "忘记密码": {
+ "text": "忘记密码",
+ "key": "t_6_1744164838900",
+ "translations": {
+ "zhCN": "忘记密码",
+ "zhTW": "忘記密碼",
+ "enUS": "Forget password",
+ "jaJP": "パスワードを忘れたら",
+ "koKR": "비밀번호를 잊었나요?",
+ "ruRU": "Забыли пароль?",
+ "ptBR": "Esqueceu sua senha?",
+ "frFR": "Oublié votre mot de passe?",
+ "esAR": "¿Olvidaste tu contraseña?",
+ "arDZ": "هل نسيت كلمة المرور؟"
+ },
+ "timestamp": "2025-04-09T02:14:03.240Z"
+ },
+ "登录中": {
+ "text": "登录中",
+ "key": "t_7_1744164838625",
+ "translations": {
+ "zhCN": "登录中",
+ "zhTW": "登錄中",
+ "enUS": "Logging in",
+ "jaJP": "ログイン中",
+ "koKR": "로그인 중",
+ "ruRU": "Вход в систему",
+ "ptBR": "Entrando",
+ "frFR": "En cours de connexion",
+ "esAR": "Logueándose",
+ "arDZ": "في إجراء الدخول"
+ },
+ "timestamp": "2025-04-09T02:14:03.240Z"
+ },
+ "登录": {
+ "text": "登录",
+ "key": "t_8_1744164839833",
+ "translations": {
+ "zhCN": "登录",
+ "zhTW": "登錄",
+ "enUS": "Login",
+ "jaJP": "ログイン",
+ "koKR": "로그인",
+ "ruRU": "Вход",
+ "ptBR": "Entrar",
+ "frFR": "Se connecter",
+ "esAR": "Iniciar sesión",
+ "arDZ": "تسجيل الدخول"
+ },
+ "timestamp": "2025-04-09T02:14:03.240Z"
+ },
+ "退出登录": {
+ "text": "退出登录",
+ "key": "t_0_1744168657526",
+ "translations": {
+ "zhCN": "退出登录",
+ "zhTW": "登出",
+ "enUS": "Log out",
+ "jaJP": "ログアウト",
+ "koKR": "로그아웃",
+ "ruRU": "Выйти из системы",
+ "ptBR": "Sair",
+ "frFR": "Déconnecter",
+ "esAR": "Salir",
+ "arDZ": "تسجيل الخروج"
+ },
+ "timestamp": "2025-04-09T03:17:37.526Z"
+ },
+ "首页": {
+ "text": "首页",
+ "key": "t_0_1744258111441",
+ "translations": {
+ "zhCN": "首页",
+ "zhTW": "首頁",
+ "enUS": "Home",
+ "jaJP": "ホーム",
+ "koKR": "홈",
+ "ruRU": "Главная",
+ "ptBR": "Início",
+ "frFR": "Accueil",
+ "esAR": "Inicio",
+ "arDZ": "الصفحة الرئيسية"
+ },
+ "timestamp": "2025-04-10T04:08:33.857Z"
+ },
+ "自动化部署": {
+ "text": "自动化部署",
+ "key": "t_1_1744258113857",
+ "translations": {
+ "zhCN": "自动化部署",
+ "zhTW": "自動部署",
+ "enUS": "Automation Deployment",
+ "jaJP": "自動デプロイメント",
+ "koKR": "자동 배포",
+ "ruRU": "Автоматическая部署",
+ "ptBR": "Implantação Automatizada",
+ "frFR": "Déploiement Automatisé",
+ "esAR": "Despliegue Automatizado",
+ "arDZ": "توزيع آلي"
+ },
+ "timestamp": "2025-04-10T04:08:33.857Z"
+ },
+ "证书管理": {
+ "text": "证书管理",
+ "key": "t_2_1744258111238",
+ "translations": {
+ "zhCN": "证书管理",
+ "zhTW": "證書管理",
+ "enUS": "Certificate Management",
+ "jaJP": "証明書管理",
+ "koKR": "서비스 관리",
+ "ruRU": "Управление сертификатами",
+ "ptBR": "Gestão de Certificados",
+ "frFR": "Gestion des certificats",
+ "esAR": "Gestión de certificados",
+ "arDZ": "إدارة الشهادات"
+ },
+ "timestamp": "2025-04-10T04:08:33.857Z"
+ },
+ "证书申请": {
+ "text": "证书申请",
+ "key": "t_3_1744258111182",
+ "translations": {
+ "zhCN": "证书申请",
+ "zhTW": "證書申請",
+ "enUS": "Certificate Application",
+ "jaJP": "証明書申請",
+ "koKR": "서류 신청",
+ "ruRU": "Заявка на сертификат",
+ "ptBR": "Aplicação de certificado",
+ "frFR": "Demande de certificat",
+ "esAR": "Solicitud de certificado",
+ "arDZ": "طلب شهادة"
+ },
+ "timestamp": "2025-04-10T04:08:33.857Z"
+ },
+ "授权API管理": {
+ "text": "授权API管理",
+ "key": "t_4_1744258111238",
+ "translations": {
+ "zhCN": "授权API管理",
+ "zhTW": "授權API管理",
+ "enUS": "Authorization API Management",
+ "jaJP": "認証API管理",
+ "koKR": "인증 API 관리",
+ "ruRU": "Управление API авторизации",
+ "ptBR": "Gerenciamento de API de autorização",
+ "frFR": "Gestion de l'API d'autorisation",
+ "esAR": "Gestión de API de autorización",
+ "arDZ": "إدارة API التصريح"
+ },
+ "timestamp": "2025-04-10T04:08:33.857Z"
+ },
+ "监控": {
+ "text": "监控",
+ "key": "t_5_1744258110516",
+ "translations": {
+ "zhCN": "监控",
+ "zhTW": "監控",
+ "enUS": "Monitoring",
+ "jaJP": "監視",
+ "koKR": "감시",
+ "ruRU": "Мониторинг",
+ "ptBR": "Monitoramento",
+ "frFR": "Surveillance",
+ "esAR": "Monitoreo",
+ "arDZ": "مراقبة"
+ },
+ "timestamp": "2025-04-10T04:08:33.857Z"
+ },
+ "设置": {
+ "text": "设置",
+ "key": "t_6_1744258111153",
+ "translations": {
+ "zhCN": "设置",
+ "zhTW": "設定",
+ "enUS": "Settings",
+ "jaJP": "設定",
+ "koKR": "설정",
+ "ruRU": "Настройки",
+ "ptBR": "Configurações",
+ "frFR": "Paramètres",
+ "esAR": "Ajustes",
+ "arDZ": "إعدادات"
+ },
+ "timestamp": "2025-04-10T04:08:33.857Z"
+ },
+ "返回工作流列表": {
+ "text": "返回工作流列表",
+ "key": "t_0_1744861190562",
+ "translations": {
+ "zhCN": "返回工作流列表",
+ "zhTW": "返回工作流程列表",
+ "enUS": "Return workflow list",
+ "jaJP": "ワークフローリストの返信",
+ "koKR": "워크플로우 목록 반환",
+ "ruRU": "Возврат списка workflows",
+ "ptBR": "Retornar lista de fluxos de trabalho",
+ "frFR": "Renvoyer la liste des flux de travail",
+ "esAR": "Retornar lista de flujos de trabajo",
+ "arDZ": "إرجاع قائمة عملية العمل"
+ },
+ "timestamp": "2025-04-17T03:39:54.395Z"
+ },
+ "运行": {
+ "text": "运行",
+ "key": "t_1_1744861189113",
+ "translations": {
+ "zhCN": "运行",
+ "zhTW": "運行",
+ "enUS": "Run",
+ "jaJP": "実行",
+ "koKR": "실행",
+ "ruRU": "Запуск",
+ "ptBR": "Executar",
+ "frFR": "Exécuter",
+ "esAR": "Ejecutar",
+ "arDZ": "تشغيل"
+ },
+ "timestamp": "2025-04-17T03:39:54.396Z"
+ },
+ "保存": {
+ "text": "保存",
+ "key": "t_2_1744861190040",
+ "translations": {
+ "zhCN": "保存",
+ "zhTW": "儲存",
+ "enUS": "Save",
+ "jaJP": "保存する",
+ "koKR": "저장",
+ "ruRU": "Сохранить",
+ "ptBR": "Salvar",
+ "frFR": "Sauvegarder",
+ "esAR": "Guardar",
+ "arDZ": "حفظ"
+ },
+ "timestamp": "2025-04-17T03:39:54.396Z"
+ },
+ "请选择一个节点进行配置": {
+ "text": "请选择一个节点进行配置",
+ "key": "t_3_1744861190932",
+ "translations": {
+ "zhCN": "请选择一个节点进行配置",
+ "zhTW": "請選擇一個節點進行配置",
+ "enUS": "Please select a node to configure",
+ "jaJP": "設定するノードを選んでください",
+ "koKR": "구성할 노드를 선택하세요",
+ "ruRU": "Выберите узел для конфигурации",
+ "ptBR": "Selecione um nó para configurar",
+ "frFR": "Veuillez sélectionner un nœud à configurer",
+ "esAR": "Seleccione un nodo para configurar",
+ "arDZ": "أختر عقدة لتكوينها"
+ },
+ "timestamp": "2025-04-17T03:39:54.396Z"
+ },
+ "点击左侧流程图中的节点来配置它": {
+ "text": "点击左侧流程图中的节点来配置它",
+ "key": "t_4_1744861194395",
+ "translations": {
+ "zhCN": "点击左侧流程图中的节点来配置它",
+ "zhTW": "點擊左側流程圖中的節點來配置它",
+ "enUS": "Click on the node in the left-side workflow diagram to configure it",
+ "jaJP": "左側のフローウォークダイアグラムのノードをクリックして設定してください",
+ "koKR": "왼쪽의 프로세스 다이어그램에서 노드를 클릭하여 설정하세요",
+ "ruRU": "Нажмите на узел в левой части схематического процесса, чтобы настроить его",
+ "ptBR": "Clique no nó do diagrama de workflow do lado esquerdo para configurá-lo",
+ "frFR": "Clique sur le nœud dans le diagramme de flux de gauche pour le configurer",
+ "esAR": "Haga clic en el nodo del diagrama de flujo en la parte izquierda para configurarlo",
+ "arDZ": "انقر على النقطة في الشريحة اليسرى من مخطط العمل لتزويده بالتكوين"
+ },
+ "timestamp": "2025-04-17T03:39:54.396Z"
+ },
+ "开始": {
+ "text": "开始",
+ "key": "t_5_1744861189528",
+ "translations": {
+ "zhCN": "开始",
+ "zhTW": "開始",
+ "enUS": "Start",
+ "jaJP": "始めます",
+ "koKR": "시작",
+ "ruRU": "начать",
+ "ptBR": "iniciar",
+ "frFR": "commencer",
+ "esAR": "comenzar",
+ "arDZ": "تبدأ"
+ },
+ "timestamp": "2025-04-17T03:39:54.396Z"
+ },
+ "未选择节点": {
+ "text": "未选择节点",
+ "key": "t_6_1744861190121",
+ "translations": {
+ "zhCN": "未选择节点",
+ "zhTW": "未選擇節點",
+ "enUS": "No node selected",
+ "jaJP": "ノードを選択していない",
+ "koKR": "노드를 선택하지 않았습니다",
+ "ruRU": "Элемент не выбран",
+ "ptBR": "Nenhum nó selected",
+ "frFR": "Aucun noeud sélectionné",
+ "esAR": "Nodo no seleccionado",
+ "arDZ": "لم يتم اختيار العقدة"
+ },
+ "timestamp": "2025-04-17T03:39:54.396Z"
+ },
+ "配置已保存": {
+ "text": "配置已保存",
+ "key": "t_7_1744861189625",
+ "translations": {
+ "zhCN": "配置已保存",
+ "zhTW": "配置已保存",
+ "enUS": "Configuration saved",
+ "jaJP": "設定が保存されました",
+ "koKR": "설정이 저장되었습니다",
+ "ruRU": "Конфигурация сохранена",
+ "ptBR": "Configuração salva",
+ "frFR": "Configuration enregistrée",
+ "esAR": "Configuración guardada",
+ "arDZ": "تم حفظ الإعدادات"
+ },
+ "timestamp": "2025-04-17T03:39:54.396Z"
+ },
+ "开始运行流程": {
+ "text": "开始运行流程",
+ "key": "t_8_1744861189821",
+ "translations": {
+ "zhCN": "开始运行流程",
+ "zhTW": "開始執行流程",
+ "enUS": "Start the workflow",
+ "jaJP": "ワークフローの開始",
+ "koKR": "워크플로우 시작",
+ "ruRU": "Начать процесс",
+ "ptBR": "Iniciar fluxo de trabalho",
+ "frFR": "Démarrer le processus",
+ "esAR": "Iniciar flujo de trabajo",
+ "arDZ": "بدء عملية العمل"
+ },
+ "timestamp": "2025-04-17T03:39:54.396Z"
+ },
+ "选中节点:": {
+ "text": "选中节点:",
+ "key": "t_9_1744861189580",
+ "translations": {
+ "zhCN": "选中节点:",
+ "zhTW": "選中節點:",
+ "enUS": "Selected node:",
+ "jaJP": "選択ノード:",
+ "koKR": "선택된 노드:",
+ "ruRU": "Выбранный узел:",
+ "ptBR": "Nó selecionado:",
+ "frFR": "Nœud sélectionné :",
+ "esAR": "Nodo seleccionado:",
+ "arDZ": "النقطة المختارة:"
+ },
+ "timestamp": "2025-04-17T03:39:54.396Z"
+ },
+ "节点": {
+ "text": "节点",
+ "key": "t_0_1744870861464",
+ "translations": {
+ "zhCN": "节点",
+ "zhTW": "節點",
+ "enUS": "Node",
+ "jaJP": "ノード",
+ "koKR": "노드",
+ "ruRU": "узел",
+ "ptBR": "nó",
+ "frFR": "nœud",
+ "esAR": "nodo",
+ "arDZ": "نقطة"
+ },
+ "timestamp": "2025-04-17T06:21:04.616Z"
+ },
+ "节点配置": {
+ "text": "节点配置",
+ "key": "t_1_1744870861944",
+ "translations": {
+ "zhCN": "节点配置",
+ "zhTW": "節點配置",
+ "enUS": "Node Configuration",
+ "jaJP": "ノード設定",
+ "koKR": "노드 설정",
+ "ruRU": "Конфигурация узла",
+ "ptBR": "Configuração de nó",
+ "frFR": "Configuration de noeud",
+ "esAR": "Configuración de nodo",
+ "arDZ": "إعداد العقدة"
+ },
+ "timestamp": "2025-04-17T06:21:04.616Z"
+ },
+ "请选择左侧节点进行配置": {
+ "text": "请选择左侧节点进行配置",
+ "key": "t_2_1744870863419",
+ "translations": {
+ "zhCN": "请选择左侧节点进行配置",
+ "zhTW": "請選擇左側節點進行配置",
+ "enUS": "Please select the left node for configuration",
+ "jaJP": "左側のノードを選択して設定してください",
+ "koKR": "왼쪽 노드를 선택하여 설정하세요",
+ "ruRU": "Выберите левый узел для настройки",
+ "ptBR": "Selecione o nó esquerdo para configuração",
+ "frFR": "Veuillez sélectionner le nœud de gauche pour la configuration",
+ "esAR": "Seleccione el nodo izquierdo para la configuración",
+ "arDZ": "يرجى اختيار العقدة اليسرى للتكوين"
+ },
+ "timestamp": "2025-04-17T06:21:04.616Z"
+ },
+ "未找到该节点类型的配置组件": {
+ "text": "未找到该节点类型的配置组件",
+ "key": "t_3_1744870864615",
+ "translations": {
+ "zhCN": "未找到该节点类型的配置组件",
+ "zhTW": "未找到該節點類型的配置組件",
+ "enUS": "Configuration component for this node type not found",
+ "jaJP": "このノードタイプの設定コンポーネントが見つかりませんでした",
+ "koKR": "이 노드 유형의 구성 구성 요소를 찾을 수 없습니다",
+ "ruRU": "Не найден компонент конфигурации для этого типа узла",
+ "ptBR": "Componente de configuração para esse tipo de nó não encontrado",
+ "frFR": "Composant de configuration pour ce type de noeud introuvable",
+ "esAR": "No se encontró el componente de configuración para este tipo de nodo",
+ "arDZ": "لم يتم العثور على مكون التكوين لهذا النوع من العقد"
+ },
+ "timestamp": "2025-04-17T06:21:04.616Z"
+ },
+ "取消": {
+ "text": "取消",
+ "key": "t_4_1744870861589",
+ "translations": {
+ "zhCN": "取消",
+ "zhTW": "取消",
+ "enUS": "Cancel",
+ "jaJP": "キャンセル",
+ "koKR": "취소",
+ "ruRU": "Отменить",
+ "ptBR": "Cancelar",
+ "frFR": "Annuler",
+ "esAR": "Cancelar",
+ "arDZ": "إلغاء"
+ },
+ "timestamp": "2025-04-17T06:21:04.616Z"
+ },
+ "确定": {
+ "text": "确定",
+ "key": "t_5_1744870862719",
+ "translations": {
+ "zhCN": "确定",
+ "zhTW": "確定",
+ "enUS": "Confirm",
+ "jaJP": "確定",
+ "koKR": "확인",
+ "ruRU": "подтвердить",
+ "ptBR": "confirmar",
+ "frFR": "confirmer",
+ "esAR": "confirmar",
+ "arDZ": "تحديد"
+ },
+ "timestamp": "2025-04-17T06:21:04.616Z"
+ },
+ "每分钟": {
+ "text": "每分钟",
+ "key": "t_0_1744875938285",
+ "translations": {
+ "zhCN": "每分钟",
+ "zhTW": "每分鐘",
+ "enUS": "Every minute",
+ "jaJP": "分ごとに",
+ "koKR": "분마다",
+ "ruRU": "каждую минуту",
+ "ptBR": "a cada minuto",
+ "frFR": "à chaque minute",
+ "esAR": "cada minuto",
+ "arDZ": "كل دقيقة"
+ },
+ "timestamp": "2025-04-17T07:45:40.750Z"
+ },
+ "每小时": {
+ "text": "每小时",
+ "key": "t_1_1744875938598",
+ "translations": {
+ "zhCN": "每小时",
+ "zhTW": "每小時",
+ "enUS": "Each hour",
+ "jaJP": "毎時間",
+ "koKR": "매 시간",
+ "ruRU": "каждый час",
+ "ptBR": "a cada hora",
+ "frFR": "chaque heure",
+ "esAR": "cada hora",
+ "arDZ": "كل ساعة"
+ },
+ "timestamp": "2025-04-17T07:45:40.750Z"
+ },
+ "每天": {
+ "text": "每天",
+ "key": "t_2_1744875938555",
+ "translations": {
+ "zhCN": "每天",
+ "zhTW": "每天",
+ "enUS": "Every day",
+ "jaJP": "毎日",
+ "koKR": "매일",
+ "ruRU": "каждый день",
+ "ptBR": "cada dia",
+ "frFR": "chaque jour",
+ "esAR": "cada día",
+ "arDZ": "كل يوم"
+ },
+ "timestamp": "2025-04-17T07:45:40.750Z"
+ },
+ "每月": {
+ "text": "每月",
+ "key": "t_3_1744875938310",
+ "translations": {
+ "zhCN": "每月",
+ "zhTW": "每月",
+ "enUS": "Each month",
+ "jaJP": "毎月",
+ "koKR": "매월",
+ "ruRU": "каждый месяц",
+ "ptBR": "cada mês",
+ "frFR": "chaque mois",
+ "esAR": "cada mes",
+ "arDZ": "كل شهر"
+ },
+ "timestamp": "2025-04-17T07:45:40.750Z"
+ },
+ "自动执行": {
+ "text": "自动执行",
+ "key": "t_4_1744875940750",
+ "translations": {
+ "zhCN": "自动执行",
+ "zhTW": "自動執行",
+ "enUS": "Automatic execution",
+ "jaJP": "自動実行",
+ "koKR": "자동 실행",
+ "ruRU": "Автоматическое выполнение",
+ "ptBR": "Execução automática",
+ "frFR": "Exécution automatique",
+ "esAR": "Ejecución automática",
+ "arDZ": "تنفيذ تلقائي"
+ },
+ "timestamp": "2025-04-17T07:45:40.750Z"
+ },
+ "手动执行": {
+ "text": "手动执行",
+ "key": "t_5_1744875940010",
+ "translations": {
+ "zhCN": "手动执行",
+ "zhTW": "手動執行",
+ "enUS": "Manual execution",
+ "jaJP": "手動実行",
+ "koKR": "수동 실행",
+ "ruRU": "Ручное выполнение",
+ "ptBR": "Execução manual",
+ "frFR": "Exécution manuelle",
+ "esAR": "Ejecución manual",
+ "arDZ": "تنفيذ يدوي"
+ },
+ "timestamp": "2025-04-17T07:45:40.750Z"
+ },
+ "测试PID": {
+ "text": "测试PID",
+ "key": "t_0_1744879616135",
+ "translations": {
+ "zhCN": "测试PID",
+ "zhTW": "測試PID",
+ "enUS": "Test PID",
+ "jaJP": "テストPID",
+ "koKR": "테스트PID",
+ "ruRU": "Тест PID",
+ "ptBR": "Teste PID",
+ "frFR": "Test PID",
+ "esAR": "Test PID",
+ "arDZ": "اختبار PID"
+ },
+ "timestamp": "2025-04-17T08:46:56.944Z"
+ },
+ "请输入测试PID": {
+ "text": "请输入测试PID",
+ "key": "t_1_1744879616555",
+ "translations": {
+ "zhCN": "请输入测试PID",
+ "zhTW": "請輸入測試PID",
+ "enUS": "Please enter the test PID",
+ "jaJP": "テストPIDを入力してください",
+ "koKR": "테스트 PID를 입력하세요",
+ "ruRU": "Введите тестовый PID",
+ "ptBR": "Por favor, insira o PID de teste",
+ "frFR": "Veuillez saisir le PID de test",
+ "esAR": "Por favor, ingrese el PID de prueba",
+ "arDZ": "الرجاء إدخال PID الاختباري"
+ },
+ "timestamp": "2025-04-17T08:46:56.945Z"
+ },
+ "执行周期": {
+ "text": "执行周期",
+ "key": "t_2_1744879616413",
+ "translations": {
+ "zhCN": "执行周期",
+ "zhTW": "執行周期",
+ "enUS": "Execution cycle",
+ "jaJP": "実行サイクル",
+ "koKR": "실행 주기",
+ "ruRU": "Период выполнения",
+ "ptBR": "Período de execução",
+ "frFR": "Cycle d'exécution",
+ "esAR": "Período de ejecución",
+ "arDZ": "فترة التنفيذ"
+ },
+ "timestamp": "2025-04-17T08:46:56.945Z"
+ },
+ "分钟": {
+ "text": "分钟",
+ "key": "t_3_1744879615723",
+ "translations": {
+ "zhCN": "分钟",
+ "zhTW": "分鐘",
+ "enUS": "minute",
+ "jaJP": "分",
+ "koKR": "분",
+ "ruRU": "минута",
+ "ptBR": "minuto",
+ "frFR": "minute",
+ "esAR": "minuto",
+ "arDZ": "دقيقة"
+ },
+ "timestamp": "2025-04-17T08:46:56.945Z"
+ },
+ "请输入分钟": {
+ "text": "请输入分钟",
+ "key": "t_4_1744879616168",
+ "translations": {
+ "zhCN": "请输入分钟",
+ "zhTW": "請輸入分鐘",
+ "enUS": "Please enter minutes",
+ "jaJP": "分を入力してください",
+ "koKR": "분을 입력하세요",
+ "ruRU": "Введите минуты",
+ "ptBR": "Por favor, insira os minutos",
+ "frFR": "Veuillez saisir les minutes",
+ "esAR": "Por favor, ingrese minutos",
+ "arDZ": "من فضلك، أدخل الدقائق"
+ },
+ "timestamp": "2025-04-17T08:46:56.945Z"
+ },
+ "小时": {
+ "text": "小时",
+ "key": "t_5_1744879615277",
+ "translations": {
+ "zhCN": "小时",
+ "zhTW": "小時",
+ "enUS": "hour",
+ "jaJP": "時間",
+ "koKR": "시간",
+ "ruRU": "час",
+ "ptBR": "hora",
+ "frFR": "heure",
+ "esAR": "hora",
+ "arDZ": "ساعة"
+ },
+ "timestamp": "2025-04-17T08:46:56.945Z"
+ },
+ "请输入小时": {
+ "text": "请输入小时",
+ "key": "t_6_1744879616944",
+ "translations": {
+ "zhCN": "请输入小时",
+ "zhTW": "請輸入小時",
+ "enUS": "Please enter hours",
+ "jaJP": "時間を入力してください",
+ "koKR": "시간을 입력하세요",
+ "ruRU": "Введіть часы",
+ "ptBR": "Por favor, insira as horas",
+ "frFR": "Veuillez saisir des heures",
+ "esAR": "Por favor, introduzca las horas",
+ "arDZ": "الرجاء إدخال الساعات"
+ },
+ "timestamp": "2025-04-17T08:46:56.945Z"
+ },
+ "日期": {
+ "text": "日期",
+ "key": "t_7_1744879615743",
+ "translations": {
+ "zhCN": "日期",
+ "zhTW": "日期",
+ "enUS": "Date",
+ "jaJP": "日付",
+ "koKR": "날짜",
+ "ruRU": "Дата",
+ "ptBR": "Data",
+ "frFR": "Date",
+ "esAR": "Fecha",
+ "arDZ": "التاريخ"
+ },
+ "timestamp": "2025-04-17T08:46:56.945Z"
+ },
+ "请选择日期": {
+ "text": "请选择日期",
+ "key": "t_8_1744879616493",
+ "translations": {
+ "zhCN": "请选择日期",
+ "zhTW": "請選擇日期",
+ "enUS": "Please select a date",
+ "jaJP": "日付を選択してください",
+ "koKR": "날짜를 선택하세요",
+ "ruRU": "Выберите дату",
+ "ptBR": "Selecione a data",
+ "frFR": "Sélectionnez une date",
+ "esAR": "Seleccione una fecha",
+ "arDZ": "اختر التاريخ"
+ },
+ "timestamp": "2025-04-17T08:46:56.945Z"
+ },
+ "每星期": {
+ "text": "每星期",
+ "key": "t_0_1744942117992",
+ "translations": {
+ "zhCN": "每周",
+ "zhTW": "每週",
+ "enUS": "Every week",
+ "jaJP": "毎週",
+ "koKR": "매 주",
+ "ruRU": "каждую неделю",
+ "ptBR": "cada semana",
+ "frFR": "chaque semaine",
+ "esAR": "cada semana",
+ "arDZ": "كل أسبوع"
+ },
+ "timestamp": "2025-04-18T02:08:37.992Z"
+ },
+ "周一": {
+ "text": "周一",
+ "key": "t_1_1744942116527",
+ "translations": {
+ "zhCN": "周一",
+ "zhTW": "星期一",
+ "enUS": "Monday",
+ "jaJP": "月曜日",
+ "koKR": "월요일",
+ "ruRU": "понедельник",
+ "ptBR": "segunda-feira",
+ "frFR": "lundi",
+ "esAR": "lunes",
+ "arDZ": "الإثنين"
+ },
+ "timestamp": "2025-04-18T02:08:37.993Z"
+ },
+ "周二": {
+ "text": "周二",
+ "key": "t_2_1744942117890",
+ "translations": {
+ "zhCN": "周二",
+ "zhTW": "星期二",
+ "enUS": "Tuesday",
+ "jaJP": "火曜日",
+ "koKR": "화요일",
+ "ruRU": "вторник",
+ "ptBR": "terça-feira",
+ "frFR": "mardi",
+ "esAR": "martes",
+ "arDZ": "الثلاثاء"
+ },
+ "timestamp": "2025-04-18T02:08:37.993Z"
+ },
+ "周三": {
+ "text": "周三",
+ "key": "t_3_1744942117885",
+ "translations": {
+ "zhCN": "周三",
+ "zhTW": "星期三",
+ "enUS": "Wednesday",
+ "jaJP": "水曜日",
+ "koKR": "수요일",
+ "ruRU": "Среда",
+ "ptBR": "Quarta-feira",
+ "frFR": "Mercredi",
+ "esAR": "Miércoles",
+ "arDZ": "الأربعاء"
+ },
+ "timestamp": "2025-04-18T02:08:37.993Z"
+ },
+ "周四": {
+ "text": "周四",
+ "key": "t_4_1744942117738",
+ "translations": {
+ "zhCN": "周四",
+ "zhTW": "週四",
+ "enUS": "Thursday",
+ "jaJP": "木曜日",
+ "koKR": "목요일",
+ "ruRU": "четверг",
+ "ptBR": "quarta-feira",
+ "frFR": "jeudi",
+ "esAR": "jueves",
+ "arDZ": "الخميس"
+ },
+ "timestamp": "2025-04-18T02:08:37.993Z"
+ },
+ "周五": {
+ "text": "周五",
+ "key": "t_5_1744942117167",
+ "translations": {
+ "zhCN": "周五",
+ "zhTW": "週五",
+ "enUS": "Friday",
+ "jaJP": "金曜日",
+ "koKR": "금요일",
+ "ruRU": "пятница",
+ "ptBR": "quinta-feira",
+ "frFR": "vendredi",
+ "esAR": "viernes",
+ "arDZ": "الجمعة"
+ },
+ "timestamp": "2025-04-18T02:08:37.993Z"
+ },
+ "周六": {
+ "text": "周六",
+ "key": "t_6_1744942117815",
+ "translations": {
+ "zhCN": "周六",
+ "zhTW": "週六",
+ "enUS": "Saturday",
+ "jaJP": "土曜日",
+ "koKR": "토요일",
+ "ruRU": "суббота",
+ "ptBR": "sábado",
+ "frFR": "samedi",
+ "esAR": "sábado",
+ "arDZ": "السبت"
+ },
+ "timestamp": "2025-04-18T02:08:37.993Z"
+ },
+ "周日": {
+ "text": "周日",
+ "key": "t_7_1744942117862",
+ "translations": {
+ "zhCN": "周日",
+ "zhTW": "週日",
+ "enUS": "Sunday",
+ "jaJP": "日曜日",
+ "koKR": "일요일",
+ "ruRU": "воскресенье",
+ "ptBR": "domingo",
+ "frFR": "dimanche",
+ "esAR": "domingo",
+ "arDZ": "الأحد"
+ },
+ "timestamp": "2025-04-18T02:08:37.993Z"
+ },
+ "请输入域名": {
+ "text": "请输入域名",
+ "key": "t_0_1744958839535",
+ "translations": {
+ "zhCN": "请输入域名",
+ "zhTW": "請輸入域名",
+ "enUS": "Please enter the domain name",
+ "jaJP": "ドメイン名を入力してください",
+ "koKR": "도메인 이름을 입력하세요",
+ "ruRU": "Введите доменное имя",
+ "ptBR": "Por favor, insira o nome do domínio",
+ "frFR": "Veuillez saisir le nom de domaine",
+ "esAR": "Por favor, ingrese el nombre de dominio",
+ "arDZ": "الرجاء إدخال اسم النطاق"
+ },
+ "timestamp": "2025-04-18T06:47:40.078Z"
+ },
+ "请输入邮箱": {
+ "text": "请输入邮箱",
+ "key": "t_1_1744958840747",
+ "translations": {
+ "zhCN": "请输入邮箱",
+ "zhTW": "請輸入郵箱",
+ "enUS": "Please enter your email",
+ "jaJP": "メールを入力してください",
+ "koKR": "이메일을 입력하세요",
+ "ruRU": "Введите адрес электронной почты",
+ "ptBR": "Por favor, insira seu e-mail",
+ "frFR": "Veuillez saisir votre adresse e-mail",
+ "esAR": "Por favor, ingrese su correo electrónico",
+ "arDZ": "الرجاء إدخال بريدك الإلكتروني"
+ },
+ "timestamp": "2025-04-18T06:47:40.083Z"
+ },
+ "邮箱格式不正确": {
+ "text": "邮箱格式不正确",
+ "key": "t_2_1744958840131",
+ "translations": {
+ "zhCN": "邮箱格式不正确",
+ "zhTW": "郵箱格式不正確",
+ "enUS": "Email format is incorrect",
+ "jaJP": "メールフォーマットが不正です",
+ "koKR": "이메일 형식이 틀립니다",
+ "ruRU": "Неправильный формат электронной почты",
+ "ptBR": "Formato de e-mail incorreto",
+ "frFR": "Le format de l'e-mail est incorrect",
+ "esAR": "El formato del correo electrónico es incorrecto",
+ "arDZ": "تنسيق البريد الإلكتروني غير صحيح"
+ },
+ "timestamp": "2025-04-18T06:47:40.083Z"
+ },
+ "请选择DNS提供商授权": {
+ "text": "请选择DNS提供商授权",
+ "key": "t_3_1744958840485",
+ "translations": {
+ "zhCN": "请选择DNS提供商授权",
+ "zhTW": "請選擇DNS提供商授權",
+ "enUS": "Please select DNS provider authorization",
+ "jaJP": "DNSプロバイダーの認証を選択してください",
+ "koKR": "DNS 제공업체 인증을 선택하세요",
+ "ruRU": "Выберите предоставление DNS-авторизации",
+ "ptBR": "Selecione o provedor de DNS para autorização",
+ "frFR": "Veuillez choisir le fournisseur de DNS pour l'autorisation",
+ "esAR": "Seleccione el proveedor de DNS para la autorización",
+ "arDZ": "يرجى اختيار مزود DNS للإذن"
+ },
+ "timestamp": "2025-04-18T06:47:40.083Z"
+ },
+ "本地部署": {
+ "text": "本地部署",
+ "key": "t_4_1744958838951",
+ "translations": {
+ "zhCN": "本地部署",
+ "zhTW": "本地部署",
+ "enUS": "Local Deployment",
+ "jaJP": "ローカルデプロイメント",
+ "koKR": "로컬 배포",
+ "ruRU": "Локальная установка",
+ "ptBR": "Implantação Local",
+ "frFR": "Déploiement local",
+ "esAR": "Despliegue local",
+ "arDZ": "تثبيت محلي"
+ },
+ "timestamp": "2025-04-18T06:47:40.083Z"
+ },
+ "SSH部署": {
+ "text": "SSH部署",
+ "key": "t_5_1744958839222",
+ "translations": {
+ "zhCN": "SSH部署",
+ "zhTW": "SSH部署",
+ "enUS": "SSH Deployment",
+ "jaJP": "SSHデプロイメント",
+ "koKR": "SSH 배포",
+ "ruRU": "SSH-деплой",
+ "ptBR": "Desempenho SSH",
+ "frFR": "Déploiement SSH",
+ "esAR": "Despliegue SSH",
+ "arDZ": "تثبيت SSH"
+ },
+ "timestamp": "2025-04-18T06:47:40.083Z"
+ },
+ "宝塔面板/1panel(部署到面板证书)": {
+ "text": "宝塔面板/1panel(部署到面板证书)",
+ "key": "t_6_1744958843569",
+ "translations": {
+ "zhCN": "宝塔面板/1面板(部署到面板证书)",
+ "zhTW": "宝塔面板/1面板(部署至面板憑證)",
+ "enUS": "Bao Ta Panel/1 panel (Deploy to panel certificate)",
+ "jaJP": "宝塔パネル/1パネル(パネル証明書にデプロイ)",
+ "koKR": "보타 패널/1 패널(패널 인증서로 배포)",
+ "ruRU": "Панель Баота/1 панель (Установить на панели сертификат)",
+ "ptBR": "Painel Bota/1 painel (Instalar no certificado do painel)",
+ "frFR": "Panneau Bao Ta/1 panneau (Déployer sur le certificat du panneau)",
+ "esAR": "Panel Bao Ta/1 panel (Desplegar en el certificado del panel)",
+ "arDZ": "لوحة بوتا/1 لوحة (تثبيت في شهادة لوحة)"
+ },
+ "timestamp": "2025-04-18T06:47:40.083Z"
+ },
+ "宝塔面板/1panel(部署到指定网站项目)": {
+ "text": "宝塔面板/1panel(部署到指定网站项目)",
+ "key": "t_7_1744958841708",
+ "translations": {
+ "zhCN": "宝塔面板/1面板(部署到指定网站项目)",
+ "zhTW": "宝塔面板/1面板(部署至指定網站項目)",
+ "enUS": "1panel (Deploy to specified website project)",
+ "jaJP": "1パネル(指定のウェブサイトプロジェクトにデプロイ)",
+ "koKR": "1판널(지정된 웹사이트 프로젝트로 배포)",
+ "ruRU": "1панель (Деплой на указанный веб-проект)",
+ "ptBR": "1painel (Deploiamento para o projeto de site especificado)",
+ "frFR": "1panneau (Déploiement sur le projet de site spécifié)",
+ "esAR": "1pantalla (Despliegue al proyecto de sitio específico)",
+ "arDZ": "1 panel (تثبيت على المشروع المحدد لل موقع)"
+ },
+ "timestamp": "2025-04-18T06:47:40.083Z"
+ },
+ "腾讯云CDN/阿里云CDN": {
+ "text": "腾讯云CDN/阿里云CDN",
+ "key": "t_8_1744958841658",
+ "translations": {
+ "zhCN": "腾讯云CDN/阿里云CDN",
+ "zhTW": "腾讯雲CDN/阿里雲CDN",
+ "enUS": "Tencent Cloud CDN/Aliyun CDN",
+ "jaJP": "テンセントクラウドCDN/アリクラウドCDN",
+ "koKR": "테encent 클라우드 CDN/알리 클라우드 CDN",
+ "ruRU": "Кloud CDN/АлиCloud CDN",
+ "ptBR": "Tencent Cloud CDN/AliCloud CDN",
+ "frFR": "Tencent Cloud CDN/AliCloud CDN",
+ "esAR": "Tencent Cloud CDN/AliCloud CDN",
+ "arDZ": "تencent Cloud CDN/أليCloud CDN"
+ },
+ "timestamp": "2025-04-18T06:47:40.083Z"
+ },
+ "腾讯云WAF": {
+ "text": "腾讯云WAF",
+ "key": "t_9_1744958840634",
+ "translations": {
+ "zhCN": "腾讯云WAF",
+ "zhTW": "腾讯雲WAF",
+ "enUS": "Tencent Cloud WAF",
+ "jaJP": "腾讯クラウドWAF",
+ "koKR": "테니엔 클라우드 WAF",
+ "ruRU": "Тencent Cloud WAF",
+ "ptBR": "WAF da Tencent Cloud",
+ "frFR": "WAF de Tencent Cloud",
+ "esAR": "WAF de Tencent Cloud",
+ "arDZ": "WAF من Tencent Cloud"
+ },
+ "timestamp": "2025-04-18T06:47:40.083Z"
+ },
+ "阿里云WAF": {
+ "text": "阿里云WAF",
+ "key": "t_10_1744958860078",
+ "translations": {
+ "zhCN": "阿里云WAF",
+ "zhTW": "阿里雲WAF",
+ "enUS": "Alicloud WAF",
+ "jaJP": "アリクラウドWAF",
+ "koKR": "아리 클라우드 WAF",
+ "ruRU": "АлиCloud WAF",
+ "ptBR": "Alicloud WAF",
+ "frFR": "WAF d'Alicloud",
+ "esAR": "WAF de AliCloud",
+ "arDZ": "WAF من آليكلاود"
+ },
+ "timestamp": "2025-04-18T06:47:40.083Z"
+ },
+ "本次自动申请的证书": {
+ "text": "本次自动申请的证书",
+ "key": "t_11_1744958840439",
+ "translations": {
+ "zhCN": "本次自动申请的证书",
+ "zhTW": "本次自動申請的證書",
+ "enUS": "This automatically applied certificate",
+ "jaJP": "この自動申請証明書",
+ "koKR": "이 자동 신청 증명서",
+ "ruRU": "Этот автоматически применяемый сертификат",
+ "ptBR": "Este certificado aplicado automaticamente",
+ "frFR": "Ce certificat appliqué automatiquement",
+ "esAR": "Este certificado aplicado automáticamente",
+ "arDZ": "هذا الشهادة المطلوبة تلقائيًا"
+ },
+ "timestamp": "2025-04-18T06:47:40.083Z"
+ },
+ "可选证书列表": {
+ "text": "可选证书列表",
+ "key": "t_12_1744958840387",
+ "translations": {
+ "zhCN": "可选证书列表",
+ "zhTW": "可選證書清單",
+ "enUS": "Optional certificate list",
+ "jaJP": "オプションの証明書リスト",
+ "koKR": "선택 가능한 인증서 목록",
+ "ruRU": "Список доступных сертификатов",
+ "ptBR": "Lista de certificados opcionais",
+ "frFR": "Liste des certificats optionnels",
+ "esAR": "Lista de certificados opcionales",
+ "arDZ": "قائمة الشهادات الاختيارية"
+ },
+ "timestamp": "2025-04-18T06:47:40.083Z"
+ },
+ "PEM(*.pem,*.crt,*.key)": {
+ "text": "PEM(*.pem,*.crt,*.key)",
+ "key": "t_13_1744958840714",
+ "translations": {
+ "zhCN": "PEM(*.pem,*.crt,*.key)",
+ "zhTW": "PEM(*.pem,*.crt,*.key)",
+ "enUS": "PEM (*.pem, *.crt, *.key)",
+ "jaJP": "PEM(*.pem、*.crt、*.key)",
+ "koKR": "PEM (*.pem, *.crt, *.key)",
+ "ruRU": "PEM (*.pem, *.crt, *.key)",
+ "ptBR": "PEM (*.pem, *.crt, *.key)",
+ "frFR": "PEM (*.pem, *.crt, *.key)",
+ "esAR": "PEM (*.pem, *.crt, *.key)",
+ "arDZ": "PEM (*.pem, *.crt, *.key)"
+ },
+ "timestamp": "2025-04-18T06:47:40.083Z"
+ },
+ "PFX(*.pfx)": {
+ "text": "PFX(*.pfx)",
+ "key": "t_14_1744958839470",
+ "translations": {
+ "zhCN": "PFX(*.pfx)",
+ "zhTW": "PFX(*.pfx)",
+ "enUS": "PFX (*.pfx)",
+ "jaJP": "PFX(*.pfx)",
+ "koKR": "PFX (*.pfx)",
+ "ruRU": "PFX (*.pfx)",
+ "ptBR": "PFX (*.pfx)",
+ "frFR": "PFX (*.pfx)",
+ "esAR": "PFX (*.pfx)",
+ "arDZ": "PFX (*.pfx)"
+ },
+ "timestamp": "2025-04-18T06:47:40.083Z"
+ },
+ "JKS(*.jks)": {
+ "text": "JKS(*.jks)",
+ "key": "t_15_1744958840790",
+ "translations": {
+ "zhCN": "JKS(*.jks)",
+ "zhTW": "JKS(*.jks)",
+ "enUS": "JKS (*.jks)",
+ "jaJP": "JKS (*.jks)",
+ "koKR": "JKS (*.jks)",
+ "ruRU": "JKS (*.jks)",
+ "ptBR": "JKS (*.jks)",
+ "frFR": "JKS (*.jks)",
+ "esAR": "JKS (*.jks)",
+ "arDZ": "JKS (*.jks)"
+ },
+ "timestamp": "2025-04-18T06:47:40.083Z"
+ },
+ "POSIX bash (linux/macos)": {
+ "text": "POSIX bash (linux/macos)",
+ "key": "t_16_1744958841116",
+ "translations": {
+ "zhCN": "POSIX bash(Linux/MacOS)",
+ "zhTW": "POSIX bash(Linux/macOS)",
+ "enUS": "POSIX bash (Linux/macOS)",
+ "jaJP": "POSIX bash(Linux/macOS)",
+ "koKR": "POSIX bash (Linux/macOS)",
+ "ruRU": "POSIX bash (Linux/macOS)",
+ "ptBR": "POSIX bash (Linux/macOS)",
+ "frFR": "POSIX bash (Linux/macOS)",
+ "esAR": "POSIX bash (Linux/macOS)",
+ "arDZ": "POSIX bash (Linux/macOS)"
+ },
+ "timestamp": "2025-04-18T06:47:40.083Z"
+ },
+ "CMD(Windows)": {
+ "text": "CMD(Windows)",
+ "key": "t_17_1744958839597",
+ "translations": {
+ "zhCN": "命令行(Windows)",
+ "zhTW": "命令行(Windows)",
+ "enUS": "CMD (Windows)",
+ "jaJP": "コマンドライン(Windows)",
+ "koKR": "명령어 라인 (Windows)",
+ "ruRU": "Комуンド лайн (Windows)",
+ "ptBR": "Linha de Comando (Windows)",
+ "frFR": "CMD (Windows)",
+ "esAR": "CMD (Windows)",
+ "arDZ": "CMD (Windows)"
+ },
+ "timestamp": "2025-04-18T06:47:40.083Z"
+ },
+ "PowerShell(Windows)": {
+ "text": "PowerShell(Windows)",
+ "key": "t_18_1744958839895",
+ "translations": {
+ "zhCN": "PowerShell(Windows)",
+ "zhTW": "PowerShell(Windows)",
+ "enUS": "PowerShell (Windows)",
+ "jaJP": "PowerShell(ウィンドウズ)",
+ "koKR": "파워셀(윈도우)",
+ "ruRU": "PowerShell (Windows)",
+ "ptBR": "PowerShell (Windows)",
+ "frFR": "PowerShell (Windows)",
+ "esAR": "PowerShell (Windows)",
+ "arDZ": "PowerShell (Windows)"
+ },
+ "timestamp": "2025-04-18T06:47:40.083Z"
+ },
+ "证书1": {
+ "text": "证书1",
+ "key": "t_19_1744958839297",
+ "translations": {
+ "zhCN": "证书1",
+ "zhTW": "證書1",
+ "enUS": "Certificate 1",
+ "jaJP": "証明書1",
+ "koKR": "인증서1",
+ "ruRU": "Сертификат1",
+ "ptBR": "Certificado 1",
+ "frFR": "Certificat 1",
+ "esAR": "Certificado 1",
+ "arDZ": "شهادة1"
+ },
+ "timestamp": "2025-04-18T06:47:40.083Z"
+ },
+ "证书2": {
+ "text": "证书2",
+ "key": "t_20_1744958839439",
+ "translations": {
+ "zhCN": "证书2",
+ "zhTW": "證書2",
+ "enUS": "Certificate 2",
+ "jaJP": "証明書2",
+ "koKR": "증명서 2",
+ "ruRU": "Сертификат 2",
+ "ptBR": "Certificado 2",
+ "frFR": "Certificat 2",
+ "esAR": "Certificado 2",
+ "arDZ": "شهادة 2"
+ },
+ "timestamp": "2025-04-18T06:47:40.083Z"
+ },
+ "服务器1": {
+ "text": "服务器1",
+ "key": "t_21_1744958839305",
+ "translations": {
+ "zhCN": "服务器1",
+ "zhTW": "伺服器1",
+ "enUS": "Server 1",
+ "jaJP": "サーバー1",
+ "koKR": "서버1",
+ "ruRU": "Сервер 1",
+ "ptBR": "Servidor 1",
+ "frFR": "Serveur 1",
+ "esAR": "Servidor 1",
+ "arDZ": "خادم 1"
+ },
+ "timestamp": "2025-04-18T06:47:40.083Z"
+ },
+ "服务器2": {
+ "text": "服务器2",
+ "key": "t_22_1744958841926",
+ "translations": {
+ "zhCN": "服务器2",
+ "zhTW": "伺服器2",
+ "enUS": "Server 2",
+ "jaJP": "サーバー2",
+ "koKR": "서버2",
+ "ruRU": "Сервер 2",
+ "ptBR": "Servidor 2",
+ "frFR": "Serveur 2",
+ "esAR": "Servidor 2",
+ "arDZ": "خادم 2"
+ },
+ "timestamp": "2025-04-18T06:47:40.083Z"
+ },
+ "面板1": {
+ "text": "面板1",
+ "key": "t_23_1744958838717",
+ "translations": {
+ "zhCN": "面板1",
+ "zhTW": "面板1",
+ "enUS": "Panel 1",
+ "jaJP": "パネル1",
+ "koKR": "판널 1",
+ "ruRU": "Панель 1",
+ "ptBR": "Painel 1",
+ "frFR": "Panneau 1",
+ "esAR": "Panel 1",
+ "arDZ": "اللوحة 1"
+ },
+ "timestamp": "2025-04-18T06:47:40.083Z"
+ },
+ "面板2": {
+ "text": "面板2",
+ "key": "t_24_1744958845324",
+ "translations": {
+ "zhCN": "面板2",
+ "zhTW": "面板2",
+ "enUS": "Panel 2",
+ "jaJP": "パネル2",
+ "koKR": "판널 2",
+ "ruRU": "PANEL 2",
+ "ptBR": "Painel 2",
+ "frFR": "Panneau 2",
+ "esAR": "Panel 2",
+ "arDZ": "لوحة 2"
+ },
+ "timestamp": "2025-04-18T06:47:40.083Z"
+ },
+ "网站1": {
+ "text": "网站1",
+ "key": "t_25_1744958839236",
+ "translations": {
+ "zhCN": "网站1",
+ "zhTW": "網站1",
+ "enUS": "Website 1",
+ "jaJP": "ウェブサイト1",
+ "koKR": "웹사이트 1",
+ "ruRU": "Сайт 1",
+ "ptBR": "Site 1",
+ "frFR": "Site 1",
+ "esAR": "Sitio 1",
+ "arDZ": "الموقع 1"
+ },
+ "timestamp": "2025-04-18T06:47:40.083Z"
+ },
+ "网站2": {
+ "text": "网站2",
+ "key": "t_26_1744958839682",
+ "translations": {
+ "zhCN": "网站2",
+ "zhTW": "網站2",
+ "enUS": "Website 2",
+ "jaJP": "ウェブサイト2",
+ "koKR": "웹사이트 2",
+ "ruRU": "Сайт 2",
+ "ptBR": "Site 2",
+ "frFR": "Site 2",
+ "esAR": "Sitio 2",
+ "arDZ": "الموقع 2"
+ },
+ "timestamp": "2025-04-18T06:47:40.083Z"
+ },
+ "腾讯云1": {
+ "text": "腾讯云1",
+ "key": "t_27_1744958840234",
+ "translations": {
+ "zhCN": "腾讯云1",
+ "zhTW": "腾讯雲1",
+ "enUS": "Tencent Cloud 1",
+ "jaJP": "テンセントクラウド1",
+ "koKR": "테encent 클라우드 1",
+ "ruRU": "Тencent Cloud 1",
+ "ptBR": "Tencent Cloud 1",
+ "frFR": "Tencent Cloud 1",
+ "esAR": "Tencent Cloud 1",
+ "arDZ": "تencent Cloud 1"
+ },
+ "timestamp": "2025-04-18T06:47:40.083Z"
+ },
+ "阿里云1": {
+ "text": "阿里云1",
+ "key": "t_28_1744958839760",
+ "translations": {
+ "zhCN": "阿里云1",
+ "zhTW": "阿里雲1",
+ "enUS": "Aliyun 1",
+ "jaJP": "アリyun 1",
+ "koKR": "阿里yun 1",
+ "ruRU": "Алиyun 1",
+ "ptBR": "Aliyun 1",
+ "frFR": "Aliyun 1",
+ "esAR": "Aliyun 1",
+ "arDZ": "ألييوان 1"
+ },
+ "timestamp": "2025-04-18T06:47:40.083Z"
+ },
+ "日": {
+ "text": "日",
+ "key": "t_29_1744958838904",
+ "translations": {
+ "zhCN": "日",
+ "zhTW": "日",
+ "enUS": "Day",
+ "jaJP": "日",
+ "koKR": "일",
+ "ruRU": "день",
+ "ptBR": "dia",
+ "frFR": "jour",
+ "esAR": "día",
+ "arDZ": "يوم"
+ },
+ "timestamp": "2025-04-18T06:47:40.083Z"
+ },
+ "证书格式不正确,请检查是否包含完整的证书头尾标识": {
+ "text": "证书格式不正确,请检查是否包含完整的证书头尾标识",
+ "key": "t_30_1744958843864",
+ "translations": {
+ "zhCN": "证书格式不正确,请检查是否包含完整的证书头尾标识",
+ "zhTW": "證書格式不正確,請檢查是否包含完整的證書頭尾識別",
+ "enUS": "Certificate format is incorrect, please check if it includes the complete certificate header and footer identifiers",
+ "jaJP": "証明書のフォーマットが不正です。完全な証明書のヘッダおよびフッタ識別子が含まれているか確認してください。",
+ "koKR": "서류 형식이 잘못되었습니다. 전체 서류 헤더 및 푸터 식별자가 포함되어 있는지 확인해 주세요.",
+ "ruRU": "Формат сертификата не правильный, пожалуйста, проверьте, содержит ли он полную информацию о заголовке и подзаголовке сертификата",
+ "ptBR": "O formato do certificado está incorreto, por favor verifique se ele contém os identificadores de cabeçalho e rodapé completos",
+ "frFR": "Le format du certificat est incorrect, veuillez vérifier s'il contient les identifiants d'en-tête et de pied de page complets",
+ "esAR": "El formato del certificado no es correcto, por favor revise si contiene las identificaciones de cabecera y pie completo",
+ "arDZ": "تنسيق الشهادة غير صحيح، يرجى التحقق مما إذا كان يحتوي على العناصر التوضيحية للعناوين والرؤوس الكاملة"
+ },
+ "timestamp": "2025-04-18T06:47:40.083Z"
+ },
+ "私钥格式不正确,请检查是否包含完整的私钥头尾标识": {
+ "text": "私钥格式不正确,请检查是否包含完整的私钥头尾标识",
+ "key": "t_31_1744958844490",
+ "translations": {
+ "zhCN": "私钥格式不正确,请检查是否包含完整的私钥头尾标识",
+ "zhTW": "私钥格式不正確,請檢查是否包含完整的私钥頭尾識別",
+ "enUS": "Private key format is incorrect, please check if it includes the complete private key header and footer identifier",
+ "jaJP": "プライベートキーフォーマットが不正です。完全なプライベートキーヘッダおよびフッタ識別子が含まれているか確認してください。",
+ "koKR": "비밀키 형식이 잘못되었습니다. 완전한 비밀키 헤더 및 푸터 식별자가 포함되어 있는지 확인해 주세요.",
+ "ruRU": "Формат私ного ключа incorrect, пожалуйста, проверьте, содержит ли он полный идентификатор заголовка и нижнего колонтитула частного ключа",
+ "ptBR": "O formato da chave privada está incorreto, por favor, verifique se ele contém o identificador completo do cabeçalho e pé de página da chave privada",
+ "frFR": "Le format de la clé privée est incorrect, veuillez vérifier si elle contient l'identifiant complet de l'en-tête et du pied de page de la clé privée",
+ "esAR": "El formato de la clave privada no es correcto, por favor verifique si contiene el identificador completo de la cabecera y el pie de página de la clave privada",
+ "arDZ": "شكل المفتاح الخاص غير صحيح، يرجى التحقق من أن يحتوي على معرف الرأس والساقطة الكاملة للمفتاح الخاص"
+ },
+ "timestamp": "2025-04-18T06:47:40.083Z"
+ },
+ "自动化名称": {
+ "text": "自动化名称",
+ "key": "t_0_1745215914686",
+ "translations": {
+ "zhCN": "自动化名称",
+ "zhTW": "自動化名稱",
+ "enUS": "Automation Name",
+ "jaJP": "自動化名前",
+ "koKR": "자동화 이름",
+ "ruRU": "Название автоматизации",
+ "ptBR": "Nome de automação",
+ "frFR": "Nom d'automatisation",
+ "esAR": "Nombre de automatización",
+ "arDZ": "اسم التلقائية"
+ },
+ "timestamp": "2025-04-21T06:11:56.235Z"
+ },
+ "自动": {
+ "text": "自动",
+ "key": "t_2_1745215915397",
+ "translations": {
+ "zhCN": "自动",
+ "zhTW": "自動",
+ "enUS": "Automatic",
+ "jaJP": "自動",
+ "koKR": "자동",
+ "ruRU": "автоматический",
+ "ptBR": "automático",
+ "frFR": "automatique",
+ "esAR": "automático",
+ "arDZ": "تلقائي"
+ },
+ "timestamp": "2025-04-21T06:11:56.237Z"
+ },
+ "手动": {
+ "text": "手动",
+ "key": "t_3_1745215914237",
+ "translations": {
+ "zhCN": "手动",
+ "zhTW": "手動",
+ "enUS": "Manual",
+ "jaJP": "手動",
+ "koKR": "수동",
+ "ruRU": "ручной",
+ "ptBR": "Manual",
+ "frFR": "Manuel",
+ "esAR": "Manual",
+ "arDZ": "يدوي"
+ },
+ "timestamp": "2025-04-21T06:11:56.237Z"
+ },
+ "启用状态": {
+ "text": "启用状态",
+ "key": "t_4_1745215914951",
+ "translations": {
+ "zhCN": "启用状态",
+ "zhTW": "啟用狀態",
+ "enUS": "Enabled Status",
+ "jaJP": "有効状態",
+ "koKR": "활성 상태",
+ "ruRU": "Активный статус",
+ "ptBR": "Estado ativado",
+ "frFR": "Statut activé",
+ "esAR": "Estado activo",
+ "arDZ": "حالة نشطة"
+ },
+ "timestamp": "2025-04-21T06:11:56.237Z"
+ },
+ "启用": {
+ "text": "启用",
+ "key": "t_5_1745215914671",
+ "translations": {
+ "zhCN": "启用",
+ "zhTW": "啟用",
+ "enUS": "Enable",
+ "jaJP": "有効にする",
+ "koKR": "활성화",
+ "ruRU": "Включить",
+ "ptBR": "Ativar",
+ "frFR": "Activer",
+ "esAR": "Activar",
+ "arDZ": "تفعيل"
+ },
+ "timestamp": "2025-04-21T06:11:56.237Z"
+ },
+ "停用": {
+ "text": "停用",
+ "key": "t_6_1745215914104",
+ "translations": {
+ "zhCN": "停用",
+ "zhTW": "停用",
+ "enUS": "Disabling",
+ "jaJP": "停止",
+ "koKR": "정지",
+ "ruRU": "Отключение",
+ "ptBR": "Desativar",
+ "frFR": "Désactiver",
+ "esAR": "Desactivar",
+ "arDZ": "إيقاف"
+ },
+ "timestamp": "2025-04-21T06:11:56.237Z"
+ },
+ "创建时间": {
+ "text": "创建时间",
+ "key": "t_7_1745215914189",
+ "translations": {
+ "zhCN": "创建时间",
+ "zhTW": "創建時間",
+ "enUS": "Creation Time",
+ "jaJP": "作成時間",
+ "koKR": "생성 시간",
+ "ruRU": "Время создания",
+ "ptBR": "Hora de criação",
+ "frFR": "Heure de création",
+ "esAR": "Tiempo de creación",
+ "arDZ": "وقت الإنشاء"
+ },
+ "timestamp": "2025-04-21T06:11:56.237Z"
+ },
+ "操作": {
+ "text": "操作",
+ "key": "t_8_1745215914610",
+ "translations": {
+ "zhCN": "操作",
+ "zhTW": "操作",
+ "enUS": "Operation",
+ "jaJP": "操作",
+ "koKR": "操作",
+ "ruRU": "Операция",
+ "ptBR": "Operação",
+ "frFR": "Opération",
+ "esAR": "Operación",
+ "arDZ": "عملية"
+ },
+ "timestamp": "2025-04-21T06:11:56.237Z"
+ },
+ "执行历史": {
+ "text": "执行历史",
+ "key": "t_9_1745215914666",
+ "translations": {
+ "zhCN": "执行历史",
+ "zhTW": "執行歷史",
+ "enUS": "Execution History",
+ "jaJP": "実行履歴",
+ "koKR": "실행 이력",
+ "ruRU": "История выполнения",
+ "ptBR": "Histórico de execução",
+ "frFR": "Historique d'exécution",
+ "esAR": "Historial de ejecución",
+ "arDZ": "تاريخ التنفيذ"
+ },
+ "timestamp": "2025-04-21T06:11:56.237Z"
+ },
+ "执行": {
+ "text": "执行",
+ "key": "t_10_1745215914342",
+ "translations": {
+ "zhCN": "执行",
+ "zhTW": "執行",
+ "enUS": "Execute",
+ "jaJP": "実行",
+ "koKR": "실行",
+ "ruRU": "исполнение",
+ "ptBR": "executar",
+ "frFR": "exécuter",
+ "esAR": "ejecutar",
+ "arDZ": "تنفيذ"
+ },
+ "timestamp": "2025-04-21T06:11:56.237Z"
+ },
+ "编辑": {
+ "text": "编辑",
+ "key": "t_11_1745215915429",
+ "translations": {
+ "zhCN": "编辑",
+ "zhTW": "編輯",
+ "enUS": "Edit",
+ "jaJP": "編集",
+ "koKR": "편집",
+ "ruRU": "Редактировать",
+ "ptBR": "Editar",
+ "frFR": "Éditer",
+ "esAR": "Editar",
+ "arDZ": "تعديل"
+ },
+ "timestamp": "2025-04-21T06:11:56.237Z"
+ },
+ "删除": {
+ "text": "删除",
+ "key": "t_12_1745215914312",
+ "translations": {
+ "zhCN": "删除",
+ "zhTW": "刪除",
+ "enUS": "Delete",
+ "jaJP": "削除",
+ "koKR": "삭제",
+ "ruRU": "Удалить",
+ "ptBR": "Excluir",
+ "frFR": "Supprimer",
+ "esAR": "Eliminar",
+ "arDZ": "حذف"
+ },
+ "timestamp": "2025-04-21T06:11:56.237Z"
+ },
+ "执行工作流": {
+ "text": "执行工作流",
+ "key": "t_13_1745215915455",
+ "translations": {
+ "zhCN": "执行工作流",
+ "zhTW": "執行工作流程",
+ "enUS": "Execute workflow",
+ "jaJP": "ワークフローの実行",
+ "koKR": "워크플로우 실행",
+ "ruRU": "Выполнение процесса",
+ "ptBR": "Executar fluxo de trabalho",
+ "frFR": "Exécuter le flux de travail",
+ "esAR": "Ejecutar flujo de trabajo",
+ "arDZ": "تنفيذ مسار العمل"
+ },
+ "timestamp": "2025-04-21T06:11:56.237Z"
+ },
+ "工作流执行成功": {
+ "text": "工作流执行成功",
+ "key": "t_14_1745215916235",
+ "translations": {
+ "zhCN": "工作流执行成功",
+ "zhTW": "工作流程執行成功",
+ "enUS": "Workflow executed successfully",
+ "jaJP": "ワークフローエグゼクション成功",
+ "koKR": "워크플로우 실행 성공",
+ "ruRU": "Успешное выполнение рабочей流程",
+ "ptBR": "Execução do fluxo de trabalho bem-sucedida",
+ "frFR": "Exécution du flux de travail réussie",
+ "esAR": "Ejecución del flujo de trabajo exitosa",
+ "arDZ": "نجاح تنفيذ عملية العمل"
+ },
+ "timestamp": "2025-04-21T06:11:56.237Z"
+ },
+ "工作流执行失败": {
+ "text": "工作流执行失败",
+ "key": "t_15_1745215915743",
+ "translations": {
+ "zhCN": "工作流执行失败",
+ "zhTW": "工作流程執行失敗",
+ "enUS": "Workflow execution failed",
+ "jaJP": "ワークフローエクセキュション失敗",
+ "koKR": "워크플로우 실행 실패",
+ "ruRU": "Неудача выполнения процесса",
+ "ptBR": "Execução do fluxo de trabalho falhou",
+ "frFR": "Échec de l'exécution du flux de travail",
+ "esAR": "Fallo en la ejecución del flujo de trabajo",
+ "arDZ": "فشل تنفيذ عملية العمل"
+ },
+ "timestamp": "2025-04-21T06:11:56.237Z"
+ },
+ "删除工作流": {
+ "text": "删除工作流",
+ "key": "t_16_1745215915209",
+ "translations": {
+ "zhCN": "删除工作流",
+ "zhTW": "刪除工作流程",
+ "enUS": "Delete Workflow",
+ "jaJP": "ワークフローを削除する",
+ "koKR": "워크플로우 제거",
+ "ruRU": "Удалить workflow",
+ "ptBR": "Excluir workflow",
+ "frFR": "Supprimer le flux de travail",
+ "esAR": "Eliminar flujo de trabajo",
+ "arDZ": "حذف مسار العمل"
+ },
+ "timestamp": "2025-04-21T06:11:56.237Z"
+ },
+ "工作流删除成功": {
+ "text": "工作流删除成功",
+ "key": "t_17_1745215915985",
+ "translations": {
+ "zhCN": "工作流删除成功",
+ "zhTW": "工作流程刪除成功",
+ "enUS": "Workflow deletion successful",
+ "jaJP": "ワークフローの削除が成功しました",
+ "koKR": "워크플로우가 성공적으로 삭제되었습니다",
+ "ruRU": "Удаление рабочей схемы успешено",
+ "ptBR": "Deleção do fluxo de trabalho bem-sucedida",
+ "frFR": "Suppression du flux de travail réussie",
+ "esAR": "Eliminación del flujo de trabajo exitosa",
+ "arDZ": "نجاح عملية حذف العملية"
+ },
+ "timestamp": "2025-04-21T06:11:56.237Z"
+ },
+ "工作流删除失败": {
+ "text": "工作流删除失败",
+ "key": "t_18_1745215915630",
+ "translations": {
+ "zhCN": "工作流删除失败",
+ "zhTW": "工作流程刪除失敗",
+ "enUS": "Workflow deletion failed",
+ "jaJP": "ワークフローの削除に失敗しました",
+ "koKR": "워크플로우 삭제 실패",
+ "ruRU": "Не удалось удалить рабочий процесс",
+ "ptBR": "Falha ao excluir fluxo de trabalho",
+ "frFR": "Échec de la suppression du flux de travail",
+ "esAR": "Fallo al eliminar el flujo de trabajo",
+ "arDZ": "فشل حذف مسار العمل"
+ },
+ "timestamp": "2025-04-21T06:11:56.237Z"
+ },
+ "新增自动化部署": {
+ "text": "新增自动化部署",
+ "key": "t_0_1745227838699",
+ "translations": {
+ "zhCN": "新增自动化部署",
+ "zhTW": "新增自動部署",
+ "enUS": "New Automated Deployment",
+ "jaJP": "新しい自動デプロイメント",
+ "koKR": "신규 자동 배포",
+ "ruRU": "Новый автоматический部署",
+ "ptBR": "Novo deployment automatizado",
+ "frFR": "Déploiement automatisé ajouté",
+ "esAR": "Despliegue automatizado nuevo",
+ "arDZ": "تثبيت آلي جديد"
+ },
+ "timestamp": "2025-04-21T09:30:41.739Z"
+ },
+ "请输入自动化名称": {
+ "text": "请输入自动化名称",
+ "key": "t_1_1745227838776",
+ "translations": {
+ "zhCN": "请输入自动化名称",
+ "zhTW": "請輸入自動化名稱",
+ "enUS": "Please enter the automation name",
+ "jaJP": "自動化名前を入力してください",
+ "koKR": "자동화 이름을 입력하세요",
+ "ruRU": "Введите имя автоматизации",
+ "ptBR": "Por favor, insira o nome da automação",
+ "frFR": "Veuillez saisir le nom de l'automatisation",
+ "esAR": "Por favor, ingrese el nombre de automatización",
+ "arDZ": "الرجاء إدخال اسم الت automatization"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "确定要执行{name}工作流吗?": {
+ "text": "确定要执行{name}工作流吗?",
+ "key": "t_2_1745227839794",
+ "translations": {
+ "zhCN": "确定要执行{name}工作流吗?",
+ "zhTW": "確定要執行{name}工作流程嗎?",
+ "enUS": "Are you sure you want to execute the {name} workflow?",
+ "jaJP": "{name}ワークフローの実行を確認しますか?",
+ "koKR": "{name} 작업 흐름을 실행하시겠습니까?",
+ "ruRU": "Уверены, что хотите выполнить workflow {name}?",
+ "ptBR": "Tem certeza de que deseja executar o workflow {name}?",
+ "frFR": "Êtes-vous sûr de vouloir exécuter le workflow {name}?",
+ "esAR": "¿Está seguro de que desea ejecutar el flujo de trabajo {name}?",
+ "arDZ": "هل أنت متأكد من أنك تريد تنفيذ عملية {name}؟"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "确认要删除{name}工作流吗?此操作不可恢复。": {
+ "text": "确认要删除{name}工作流吗?此操作不可恢复。",
+ "key": "t_3_1745227841567",
+ "translations": {
+ "zhCN": "确认要删除{name}工作流吗?此操作不可恢复。",
+ "zhTW": "確認要刪除{name}工作流程嗎?此操作無法恢復。",
+ "enUS": "Confirm deletion of {name} workflow? This action cannot be undone.",
+ "jaJP": "{name}のワークフローの削除を確認しますか?この操作は元に戻せません。",
+ "koKR": "{name} 작업流程을 정말로 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.",
+ "ruRU": "Подтвердите удаление {name} потока работы? Это действие нельзя отменить.",
+ "ptBR": "Confirma a exclusão do fluxo de trabalho {name}? Esta ação não pode ser revertida.",
+ "frFR": "Confirmez-vous la suppression du flux de travail {name} ? Cette action ne peut pas être annulée.",
+ "esAR": "¿Confirma la eliminación del flujo de trabajo {name}? Esta acción no se puede deshacer.",
+ "arDZ": "هل تؤكد على حذف {name} مسار العمل؟ هذه العملية لا يمكن إلغاؤها."
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "执行时间": {
+ "text": "执行时间",
+ "key": "t_4_1745227838558",
+ "translations": {
+ "zhCN": "执行时间",
+ "zhTW": "執行時間",
+ "enUS": "Execution Time",
+ "jaJP": "実行時間",
+ "koKR": "실행 시간",
+ "ruRU": "Время выполнения",
+ "ptBR": "Tempo de execução",
+ "frFR": "Temps d'exécution",
+ "esAR": "Tiempo de ejecución",
+ "arDZ": "وقت التنفيذ"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "结束时间": {
+ "text": "结束时间",
+ "key": "t_5_1745227839906",
+ "translations": {
+ "zhCN": "结束时间",
+ "zhTW": "結束時間",
+ "enUS": "End time",
+ "jaJP": "終了時間",
+ "koKR": "종료 시간",
+ "ruRU": "Время окончания",
+ "ptBR": "Hora de término",
+ "frFR": "Heure de fin",
+ "esAR": "Hora de finalización",
+ "arDZ": "وقت الانتهاء"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "执行方式": {
+ "text": "执行方式",
+ "key": "t_6_1745227838798",
+ "translations": {
+ "zhCN": "执行方式",
+ "zhTW": "執行方式",
+ "enUS": "Execution method",
+ "jaJP": "実行方法",
+ "koKR": "실행 방식",
+ "ruRU": "Способ выполнения",
+ "ptBR": "Método de execução",
+ "frFR": "Méthode d'exécution",
+ "esAR": "Método de ejecución",
+ "arDZ": "طريقة التنفيذ"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "状态": {
+ "text": "状态",
+ "key": "t_7_1745227838093",
+ "translations": {
+ "zhCN": "状态",
+ "zhTW": "狀態",
+ "enUS": "Status",
+ "jaJP": "状態",
+ "koKR": "상태",
+ "ruRU": "Состояние",
+ "ptBR": "Status",
+ "frFR": "Statut",
+ "esAR": "Estado",
+ "arDZ": "الحالة"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "成功": {
+ "text": "成功",
+ "key": "t_8_1745227838023",
+ "translations": {
+ "zhCN": "成功",
+ "zhTW": "成功",
+ "enUS": "Success",
+ "jaJP": "成功",
+ "koKR": "성공",
+ "ruRU": "Успех",
+ "ptBR": "Sucesso",
+ "frFR": "Réussite",
+ "esAR": "Éxito",
+ "arDZ": "نجاح"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "失败": {
+ "text": "失败",
+ "key": "t_9_1745227838305",
+ "translations": {
+ "zhCN": "失败",
+ "zhTW": "失敗",
+ "enUS": "Failure",
+ "jaJP": "失敗",
+ "koKR": "실패",
+ "ruRU": "неудача",
+ "ptBR": "fracasso",
+ "frFR": "échec",
+ "esAR": "fallo",
+ "arDZ": "فشل"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "执行中": {
+ "text": "执行中",
+ "key": "t_10_1745227838234",
+ "translations": {
+ "zhCN": "执行中",
+ "zhTW": "執行中",
+ "enUS": "In progress",
+ "jaJP": "実行中",
+ "koKR": "진행 중",
+ "ruRU": "В процессе",
+ "ptBR": "Em andamento",
+ "frFR": "En cours",
+ "esAR": "En ejecución",
+ "arDZ": "في تنفيذ"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "未知": {
+ "text": "未知",
+ "key": "t_11_1745227838422",
+ "translations": {
+ "zhCN": "未知",
+ "zhTW": "未知",
+ "enUS": "Unknown",
+ "jaJP": "不明",
+ "koKR": "알 수 없음",
+ "ruRU": "неизвестно",
+ "ptBR": "desconhecido",
+ "frFR": "inconnu",
+ "esAR": "desconocido",
+ "arDZ": "غير معروف"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "详情": {
+ "text": "详情",
+ "key": "t_12_1745227838814",
+ "translations": {
+ "zhCN": "详情",
+ "zhTW": "詳細",
+ "enUS": "Details",
+ "jaJP": "詳細",
+ "koKR": "상세정보",
+ "ruRU": "Подробности",
+ "ptBR": "Detalhes",
+ "frFR": "Détails",
+ "esAR": "Detalles",
+ "arDZ": "تفاصيل"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "上传证书": {
+ "text": "上传证书",
+ "key": "t_13_1745227838275",
+ "translations": {
+ "zhCN": "上传证书",
+ "zhTW": "上傳證書",
+ "enUS": "Upload Certificate",
+ "jaJP": "証明書のアップロード",
+ "koKR": "서명서 업로드",
+ "ruRU": "Загрузить сертификат",
+ "ptBR": "Enviar certificado",
+ "frFR": "Télécharger un certificat",
+ "esAR": "Subir certificado",
+ "arDZ": "تحميل شهادة"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "请输入证书域名或品牌名称搜索": {
+ "text": "请输入证书域名或品牌名称搜索",
+ "key": "t_14_1745227840904",
+ "translations": {
+ "zhCN": "请输入证书域名或品牌名称进行搜索",
+ "zhTW": "請輸入證書域名或品牌名稱搜尋",
+ "enUS": "Please enter the certificate domain name or brand name to search",
+ "jaJP": "証明書ドメイン名またはブランド名を入力して検索してください",
+ "koKR": "자격증 도메인 이름 또는 브랜드 이름을 입력하여 검색하세요",
+ "ruRU": "Введіть доменное имя сертификата или название бренда для поиска",
+ "ptBR": "Insira o nome do domínio do certificado ou o nome da marca para pesquisa",
+ "frFR": "Saisissez le nom de domaine du certificat ou le nom de la marque pour la recherche",
+ "esAR": "Ingrese el nombre de dominio del certificado o el nombre de la marca para buscar",
+ "arDZ": "الرجاء إدخال اسم نطاق الشهادة أو اسم العلامة التجارية للبحث عنها"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "共": {
+ "text": "共",
+ "key": "t_15_1745227839354",
+ "translations": {
+ "zhCN": "共",
+ "zhTW": "共",
+ "enUS": "Together",
+ "jaJP": "共同に",
+ "koKR": "함께",
+ "ruRU": "вместе",
+ "ptBR": "juntos",
+ "frFR": "ensemble",
+ "esAR": "juntos",
+ "arDZ": "معا"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "条": {
+ "text": "条",
+ "key": "t_16_1745227838930",
+ "translations": {
+ "zhCN": "条",
+ "zhTW": "條",
+ "enUS": "strip",
+ "jaJP": "本",
+ "koKR": "개",
+ "ruRU": "шт",
+ "ptBR": "unidade",
+ "frFR": "unité",
+ "esAR": "pieza",
+ "arDZ": "شريحة"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "域名": {
+ "text": "域名",
+ "key": "t_17_1745227838561",
+ "translations": {
+ "zhCN": "域名",
+ "zhTW": "域名",
+ "enUS": "Domain name",
+ "jaJP": "ドメイン名",
+ "koKR": "도메인 이름",
+ "ruRU": "Доменное имя",
+ "ptBR": "Nome de domínio",
+ "frFR": "Nom de domaine",
+ "esAR": "Nombre de dominio",
+ "arDZ": "اسم النطاق"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "品牌": {
+ "text": "品牌",
+ "key": "t_18_1745227838154",
+ "translations": {
+ "zhCN": "品牌",
+ "zhTW": "品牌",
+ "enUS": "Brand",
+ "jaJP": "ブランド",
+ "koKR": "브랜드",
+ "ruRU": "Бренд",
+ "ptBR": "Marca",
+ "frFR": "Marque",
+ "esAR": "Marca",
+ "arDZ": "العلامة التجارية"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "剩余天数": {
+ "text": "剩余天数",
+ "key": "t_19_1745227839107",
+ "translations": {
+ "zhCN": "剩余天数",
+ "zhTW": "剩餘天數",
+ "enUS": "Remaining days",
+ "jaJP": "残り日数",
+ "koKR": "남은 날짜",
+ "ruRU": "Оставшиеся дни",
+ "ptBR": "Dias restantes",
+ "frFR": "Jours restants",
+ "esAR": "Días restantes",
+ "arDZ": "أيام متبقية"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "到期时间": {
+ "text": "到期时间",
+ "key": "t_20_1745227838813",
+ "translations": {
+ "zhCN": "到期时间",
+ "zhTW": "到期時間",
+ "enUS": "Expiry Time",
+ "jaJP": "期限時間",
+ "koKR": "만료 시간",
+ "ruRU": "Время истечения",
+ "ptBR": "Tempo de expiração",
+ "frFR": "Heure d'expiration",
+ "esAR": "Tiempo de vencimiento",
+ "arDZ": "زمن انتهاء الصلاحية"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "来源": {
+ "text": "来源",
+ "key": "t_21_1745227837972",
+ "translations": {
+ "zhCN": "来源",
+ "zhTW": "來源",
+ "enUS": "Source",
+ "jaJP": "出典",
+ "koKR": "출처",
+ "ruRU": "Источник",
+ "ptBR": "Fonte",
+ "frFR": "Source",
+ "esAR": "Fuente",
+ "arDZ": "مصدر"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "自动申请": {
+ "text": "自动申请",
+ "key": "t_22_1745227838154",
+ "translations": {
+ "zhCN": "自动申请",
+ "zhTW": "自動申請",
+ "enUS": "Automatic Application",
+ "jaJP": "自動申請",
+ "koKR": "자동 신청",
+ "ruRU": "Автоматическая заявка",
+ "ptBR": "Aplicação Automática",
+ "frFR": "Demande automatique",
+ "esAR": "Solicitud automática",
+ "arDZ": "طلب تلقائي"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "手动上传": {
+ "text": "手动上传",
+ "key": "t_23_1745227838699",
+ "translations": {
+ "zhCN": "手动上传",
+ "zhTW": "手動上傳",
+ "enUS": "Manual upload",
+ "jaJP": "手動アップロード",
+ "koKR": "수동 업로드",
+ "ruRU": "Ручная загрузка",
+ "ptBR": "Upload manual",
+ "frFR": "Téléversement manuel",
+ "esAR": "Carga manual",
+ "arDZ": "تحميل يدوي"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "添加时间": {
+ "text": "添加时间",
+ "key": "t_24_1745227839508",
+ "translations": {
+ "zhCN": "添加时间",
+ "zhTW": "加入時間",
+ "enUS": "Add Time",
+ "jaJP": "時間を追加",
+ "koKR": "시간 추가",
+ "ruRU": "Добавить время",
+ "ptBR": "Adicionar tempo",
+ "frFR": "Ajouter une date",
+ "esAR": "Agregar tiempo",
+ "arDZ": "إضافة وقت"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "下载": {
+ "text": "下载",
+ "key": "t_25_1745227838080",
+ "translations": {
+ "zhCN": "下载",
+ "zhTW": "下載",
+ "enUS": "Download",
+ "jaJP": "ダウンロード",
+ "koKR": "다운로드",
+ "ruRU": "Загрузка",
+ "ptBR": "Baixar",
+ "frFR": "Télécharger",
+ "esAR": "Descargar",
+ "arDZ": "تحميل"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "即将过期": {
+ "text": "即将过期",
+ "key": "t_27_1745227838583",
+ "translations": {
+ "zhCN": "即将过期",
+ "zhTW": "即將過期",
+ "enUS": "About to expire",
+ "jaJP": "切れ替わります",
+ "koKR": "만료될 예정",
+ "ruRU": "Скоро закончится",
+ "ptBR": "Próximo de expirar",
+ "frFR": "Bientôt expiré",
+ "esAR": "Casi caducado",
+ "arDZ": "قريب من انتهاء الصلاحية"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "正常": {
+ "text": "正常",
+ "key": "t_28_1745227837903",
+ "translations": {
+ "zhCN": "正常",
+ "zhTW": "正常",
+ "enUS": "Normal",
+ "jaJP": "通常",
+ "koKR": "정상",
+ "ruRU": "нормальный",
+ "ptBR": "normal",
+ "frFR": "normal",
+ "esAR": "normal",
+ "arDZ": "طبيعي"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "删除证书": {
+ "text": "删除证书",
+ "key": "t_29_1745227838410",
+ "translations": {
+ "zhCN": "删除证书",
+ "zhTW": "刪除證書",
+ "enUS": "Delete certificate",
+ "jaJP": "証明書を削除する",
+ "koKR": "인증서 삭제",
+ "ruRU": "Удалить сертификат",
+ "ptBR": "Excluir certificado",
+ "frFR": "Supprimer le certificat",
+ "esAR": "Eliminar certificado",
+ "arDZ": "حذف الشهادة"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "确认要删除这个证书吗?此操作不可恢复。": {
+ "text": "确认要删除这个证书吗?此操作不可恢复。",
+ "key": "t_30_1745227841739",
+ "translations": {
+ "zhCN": "确认要删除这个证书吗?此操作不可恢复。",
+ "zhTW": "確認要刪除這個證書嗎?此操作無法恢復。",
+ "enUS": "Are you sure you want to delete this certificate? This action cannot be undone.",
+ "jaJP": "この証明書を削除してもよろしいですか?この操作は元に戻せません。",
+ "koKR": "이 증명서를 지우시겠습니까? 이 작업은 복구할 수 없습니다.",
+ "ruRU": "Вы уверены, что хотите удалить этот сертификат? Эта операция не может быть отменена.",
+ "ptBR": "Tem certeza de que deseja excluir este certificado? Esta ação não pode ser revertida.",
+ "frFR": "Confirmez-vous que vous souhaitez supprimer ce certificat ? Cette action ne peut pas être annulée.",
+ "esAR": "¿Está seguro de que desea eliminar este certificado? Esta acción no se puede deshacer.",
+ "arDZ": "هل أنت متأكد من أنك تريد حذف هذا الشهادة؟ لا يمكن استعادة هذه العملية."
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "确认": {
+ "text": "确认",
+ "key": "t_31_1745227838461",
+ "translations": {
+ "zhCN": "确认",
+ "zhTW": "確認",
+ "enUS": "Confirm",
+ "jaJP": "確認してください",
+ "koKR": "확인하세요",
+ "ruRU": "Подтвердите",
+ "ptBR": "Confirmar",
+ "frFR": "Confirmer",
+ "esAR": "Confirmar",
+ "arDZ": "تأكيد"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "证书名称": {
+ "text": "证书名称",
+ "key": "t_32_1745227838439",
+ "translations": {
+ "zhCN": "证书名称",
+ "zhTW": "證書名稱",
+ "enUS": "Certificate Name",
+ "jaJP": "証明書名前",
+ "koKR": "서명",
+ "ruRU": "Название сертификата",
+ "ptBR": "Nome do Certificado",
+ "frFR": "Nom du certificat",
+ "esAR": "Nombre del certificado",
+ "arDZ": "اسم الشهادة"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "请输入证书名称": {
+ "text": "请输入证书名称",
+ "key": "t_33_1745227838984",
+ "translations": {
+ "zhCN": "请输入证书名称",
+ "zhTW": "請輸入證書名稱",
+ "enUS": "Please enter the certificate name",
+ "jaJP": "証明書の名前を入力してください",
+ "koKR": "증명서 이름을 입력하세요",
+ "ruRU": "Введіть назву сертификата",
+ "ptBR": "Por favor, insira o nome do certificado",
+ "frFR": "Veuillez saisir le nom du certificat",
+ "esAR": "Por favor, ingrese el nombre del certificado",
+ "arDZ": "الرجاء إدخال اسم الشهادة"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "证书内容(PEM)": {
+ "text": "证书内容(PEM)",
+ "key": "t_34_1745227839375",
+ "translations": {
+ "zhCN": "证书内容(PEM)",
+ "zhTW": "證書內容(PEM)",
+ "enUS": "Certificate Content (PEM)",
+ "jaJP": "証明書の内容(PEM)",
+ "koKR": "인증서 내용(PEM)",
+ "ruRU": "Содержание сертификата (PEM)",
+ "ptBR": "Conteúdo do certificado (PEM)",
+ "frFR": "Contenu du certificat (PEM)",
+ "esAR": "Contenido del certificado (PEM)",
+ "arDZ": "محتويات الشهادة (PEM)"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "请输入证书内容": {
+ "text": "请输入证书内容",
+ "key": "t_35_1745227839208",
+ "translations": {
+ "zhCN": "请输入证书内容",
+ "zhTW": "請輸入證書內容",
+ "enUS": "Please enter the certificate content",
+ "jaJP": "証明書の内容を入力してください",
+ "koKR": "서류 내용을 입력하세요",
+ "ruRU": "Введіть содержимое сертификата",
+ "ptBR": "Por favor, insira o conteúdo do certificado",
+ "frFR": "Veuillez saisir le contenu du certificat",
+ "esAR": "Por favor, ingrese el contenido del certificado",
+ "arDZ": "الرجاء إدخال محتويات الشهادة"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "私钥内容(KEY)": {
+ "text": "私钥内容(KEY)",
+ "key": "t_36_1745227838958",
+ "translations": {
+ "zhCN": "私钥内容(KEY)",
+ "zhTW": "私鑰內容(KEY)",
+ "enUS": "Private key content (KEY)",
+ "jaJP": "プライベートキー内容(KEY)",
+ "koKR": "사용자 키 내용(KEY)",
+ "ruRU": "Содержание частного ключа (KEY)",
+ "ptBR": "Conteúdo da chave privada (KEY)",
+ "frFR": "Contenu de la clé privée (KEY)",
+ "esAR": "Contenido de la clave privada (KEY)",
+ "arDZ": "محتويات المفتاح الخاص (KEY)"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "请输入私钥内容": {
+ "text": "请输入私钥内容",
+ "key": "t_37_1745227839669",
+ "translations": {
+ "zhCN": "请输入私钥内容",
+ "zhTW": "請輸入私鑰內容",
+ "enUS": "Please enter the private key content",
+ "jaJP": "プライベートキーの内容を入力してください",
+ "koKR": "비밀키 내용을 입력하세요",
+ "ruRU": "Введіть содержимое частного ключа",
+ "ptBR": "Por favor, insira o conteúdo da chave privada",
+ "frFR": "Veuillez saisir le contenu de la clé privée",
+ "esAR": "Por favor, ingrese el contenido de la clave privada",
+ "arDZ": "الرجاء إدخال محتويات المفتاح الخاص"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "下载失败": {
+ "text": "下载失败",
+ "key": "t_38_1745227838813",
+ "translations": {
+ "zhCN": "下载失败",
+ "zhTW": "下載失敗",
+ "enUS": "Download failed",
+ "jaJP": "ダウンロード失敗",
+ "koKR": "다운로드 실패",
+ "ruRU": "Не удалось загрузить",
+ "ptBR": "Falha ao baixar",
+ "frFR": "Échec du téléchargement",
+ "esAR": "Falla en la descarga",
+ "arDZ": "فشل التحميل"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "上传失败": {
+ "text": "上传失败",
+ "key": "t_39_1745227838696",
+ "translations": {
+ "zhCN": "上传失败",
+ "zhTW": "上傳失敗",
+ "enUS": "Upload failed",
+ "jaJP": "アップロードに失敗しました",
+ "koKR": "업로드 실패",
+ "ruRU": "Не удалось загрузить",
+ "ptBR": "Falha ao carregar",
+ "frFR": "Échec du téléversement",
+ "esAR": "Fallo en la subida",
+ "arDZ": "فشل التحميل"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "删除失败": {
+ "text": "删除失败",
+ "key": "t_40_1745227838872",
+ "translations": {
+ "zhCN": "删除失败",
+ "zhTW": "刪除失敗",
+ "enUS": "Delete failed",
+ "jaJP": "削除失敗",
+ "koKR": "삭제 실패",
+ "ruRU": "Удаление失败",
+ "ptBR": "Falha na exclusão",
+ "frFR": "Échec de la suppression",
+ "esAR": "Falla en la eliminación",
+ "arDZ": "فشل الحذف"
+ },
+ "timestamp": "2025-04-21T09:30:41.741Z"
+ },
+ "添加授权API": {
+ "text": "添加授权API",
+ "key": "t_0_1745289355714",
+ "translations": {
+ "zhCN": "添加授权API",
+ "zhTW": "添加授權API",
+ "enUS": "Add Authorization API",
+ "jaJP": "認証APIを追加する",
+ "koKR": "인증 API 추가",
+ "ruRU": "Добавить API авторизации",
+ "ptBR": "Adicionar API de autorização",
+ "frFR": "Ajouter l'API d'autorisation",
+ "esAR": "Agregar API de autorización",
+ "arDZ": "إضافة API للإذن"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "请输入授权api名称或类型": {
+ "text": "请输入授权api名称或类型",
+ "key": "t_1_1745289356586",
+ "translations": {
+ "zhCN": "请输入授权API名称或类型",
+ "zhTW": "請輸入授權API名稱或類型",
+ "enUS": "Please enter the authorized API name or type",
+ "jaJP": "認証APIの名前またはタイプを入力してください",
+ "koKR": "인증 API 이름 또는 유형을 입력하세요",
+ "ruRU": "Введите имя или тип авторизованного API",
+ "ptBR": "Por favor, insira o nome ou o tipo do API autorizado",
+ "frFR": "Veuillez saisir le nom ou le type de l'API autorisée",
+ "esAR": "Por favor, ingrese el nombre o el tipo de API autorizada",
+ "arDZ": "الرجاء إدخال اسم أو نوع API المصرح به"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "名称": {
+ "text": "名称",
+ "key": "t_2_1745289353944",
+ "translations": {
+ "zhCN": "名称",
+ "zhTW": "名稱",
+ "enUS": "Name",
+ "jaJP": "名称",
+ "koKR": "이름",
+ "ruRU": "Название",
+ "ptBR": "Nome",
+ "frFR": "Nom",
+ "esAR": "Nombre",
+ "arDZ": "اسم"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "授权API类型": {
+ "text": "授权API类型",
+ "key": "t_3_1745289354664",
+ "translations": {
+ "zhCN": "授权API类型",
+ "zhTW": "授權API類型",
+ "enUS": "Authorization API Type",
+ "jaJP": "認証APIタイプ",
+ "koKR": "인증 API 유형",
+ "ruRU": "Тип API авторизации",
+ "ptBR": "Tipo de API de autorização",
+ "frFR": "Type d'API d'autorisation",
+ "esAR": "Tipo de API de autorización",
+ "arDZ": "نوع API للاذن"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "编辑授权API": {
+ "text": "编辑授权API",
+ "key": "t_4_1745289354902",
+ "translations": {
+ "zhCN": "编辑授权API",
+ "zhTW": "編輯授權API",
+ "enUS": "Edit Authorization API",
+ "jaJP": "編集権限API",
+ "koKR": "編집 권한 API",
+ "ruRU": "API для редактирования разрешений",
+ "ptBR": "API de autorização de edição",
+ "frFR": "API d'édition d'autorisation",
+ "esAR": "API de autorización de edición",
+ "arDZ": "API للتحرير المسموح به"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "删除授权API": {
+ "text": "删除授权API",
+ "key": "t_5_1745289355718",
+ "translations": {
+ "zhCN": "删除授权API",
+ "zhTW": "刪除授權API",
+ "enUS": "Delete Authorization API",
+ "jaJP": "認証APIの削除",
+ "koKR": "인증 API 제거",
+ "ruRU": "Удаление API авторизации",
+ "ptBR": "Remover API de autorização",
+ "frFR": "Suppression de l'API d'autorisation",
+ "esAR": "Eliminar API de autorización",
+ "arDZ": "حذف API التحقق من الصلاحيات"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "确定删除该授权API吗?此操作不可恢复。": {
+ "text": "确定删除该授权API吗?此操作不可恢复。",
+ "key": "t_6_1745289358340",
+ "translations": {
+ "zhCN": "确定删除该授权API吗?此操作不可恢复。",
+ "zhTW": "確定刪除該授權API嗎?此操作無法恢復。",
+ "enUS": "Are you sure you want to delete this authorized API? This action cannot be undone.",
+ "jaJP": "この認証されたAPIを削除してもよろしいですか?この操作は元に戻すことができません。",
+ "koKR": "이 권한된 API를 정말로 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.",
+ "ruRU": "Уверены, что хотите удалить этот авторизованный API? Это действие нельзя отменить.",
+ "ptBR": "Tem certeza de que deseja excluir este API autorizado? Esta ação não pode ser revertida.",
+ "frFR": "Êtes-vous sûr de vouloir supprimer cet API autorisé ? Cette action ne peut pas être annulée.",
+ "esAR": "¿Está seguro de que desea eliminar este API autorizado? Esta acción no se puede deshacer.",
+ "arDZ": "هل أنت متأكد من أنك تريد حذف هذا API المصرح به؟ لا يمكن استعادة هذا الإجراء."
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "添加失败": {
+ "text": "添加失败",
+ "key": "t_7_1745289355714",
+ "translations": {
+ "zhCN": "添加失败",
+ "zhTW": "添加失敗",
+ "enUS": "Add failed",
+ "jaJP": "追加失敗",
+ "koKR": "추가 실패",
+ "ruRU": "Добавление失败",
+ "ptBR": "Falha ao adicionar",
+ "frFR": "Échec de l'ajout",
+ "esAR": "Fallo al agregar",
+ "arDZ": "فشل الإضافة"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "更新失败": {
+ "text": "更新失败",
+ "key": "t_8_1745289354902",
+ "translations": {
+ "zhCN": "更新失败",
+ "zhTW": "更新失敗",
+ "enUS": "Update failed",
+ "jaJP": "アップデート失敗",
+ "koKR": "업데이트 실패",
+ "ruRU": "Обновление失败",
+ "ptBR": "Falha na atualização",
+ "frFR": "Échec de mise à jour",
+ "esAR": "Fallo en la actualización",
+ "arDZ": "فشل التحديث"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "已过期{days}天": {
+ "text": "已过期{days}天",
+ "key": "t_9_1745289355714",
+ "translations": {
+ "zhCN": "已过期{days}天",
+ "zhTW": "已過期{days}天",
+ "enUS": "Expired {days} days",
+ "jaJP": "{days}日経過",
+ "koKR": "{days}일 경과",
+ "ruRU": "Прошло {days} дней",
+ "ptBR": "Expirado há {days} dias",
+ "frFR": "Expiré {days} jours",
+ "esAR": "Vencido {days} días",
+ "arDZ": "انتهت صلاحيته {days} يوم"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "监控管理": {
+ "text": "监控管理",
+ "key": "t_10_1745289354650",
+ "translations": {
+ "zhCN": "监控管理",
+ "zhTW": "監控管理",
+ "enUS": "Monitoring Management",
+ "jaJP": "監視管理",
+ "koKR": "모니터링 관리",
+ "ruRU": "Мониторинг управления",
+ "ptBR": "Gestão de Monitoramento",
+ "frFR": "Gestion de surveillance",
+ "esAR": "Gestión de monitoreo",
+ "arDZ": "إدارة المراقبة"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "添加监控": {
+ "text": "添加监控",
+ "key": "t_11_1745289354516",
+ "translations": {
+ "zhCN": "添加监控",
+ "zhTW": "加入監控",
+ "enUS": "Add Monitoring",
+ "jaJP": "監視を追加する",
+ "koKR": "모니터링 추가",
+ "ruRU": "Добавить мониторинг",
+ "ptBR": "Adicionar monitoramento",
+ "frFR": "Ajouter une surveillance",
+ "esAR": "Agregar monitoreo",
+ "arDZ": "إضافة المراقبة"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "请输入监控名称或域名搜索": {
+ "text": "请输入监控名称或域名搜索",
+ "key": "t_12_1745289356974",
+ "translations": {
+ "zhCN": "请输入监控名称或域名进行搜索",
+ "zhTW": "請輸入監控名稱或域名進行搜尋",
+ "enUS": "Please enter the monitoring name or domain to search",
+ "jaJP": "監視名前缀またはドメインを入力して検索してください",
+ "koKR": "모니터링 이름이나 도메인을 입력하여 검색하세요",
+ "ruRU": "Введите имя монитора или домен для поиска",
+ "ptBR": "Por favor, insira o nome do monitoramento ou o domínio para pesquisar",
+ "frFR": "Veuillez saisir le nom de surveillance ou le domaine pour la recherche",
+ "esAR": "Por favor, ingrese el nombre de monitoreo o el dominio para buscar",
+ "arDZ": "الرجاء إدخال اسم المراقبة أو اسم النطاق للبحث عنه"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "监控名称": {
+ "text": "监控名称",
+ "key": "t_13_1745289354528",
+ "translations": {
+ "zhCN": "监控名称",
+ "zhTW": "監控名稱",
+ "enUS": "Monitor Name",
+ "jaJP": "モニタ名称",
+ "koKR": "모니터 이름",
+ "ruRU": "Название монитора",
+ "ptBR": "Nome do Monitor",
+ "frFR": "Nom du moniteur",
+ "esAR": "Nombre del monitor",
+ "arDZ": "اسم المراقب"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "证书域名": {
+ "text": "证书域名",
+ "key": "t_14_1745289354902",
+ "translations": {
+ "zhCN": "证书域名",
+ "zhTW": "證書域名",
+ "enUS": "Certificate Domain",
+ "jaJP": "証明書ドメイン",
+ "koKR": "인증서 도메인",
+ "ruRU": "Сертификат домена",
+ "ptBR": "Domínio do certificado",
+ "frFR": "Domaine du certificat",
+ "esAR": "Dominio del certificado",
+ "arDZ": "اسم المجال للمستند"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "证书颁发机构": {
+ "text": "证书颁发机构",
+ "key": "t_15_1745289355714",
+ "translations": {
+ "zhCN": "证书颁发机构",
+ "zhTW": "證書發頒機構",
+ "enUS": "Certificate Authority",
+ "jaJP": "証明書発行機関",
+ "koKR": "인증서 발급 기관",
+ "ruRU": "Аутентификационная служба",
+ "ptBR": "Autoridade de Certificação",
+ "frFR": "Autorité de certification",
+ "esAR": "Autoridad de certificación",
+ "arDZ": "جهة إصدار الشهادات"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "证书状态": {
+ "text": "证书状态",
+ "key": "t_16_1745289354902",
+ "translations": {
+ "zhCN": "证书状态",
+ "zhTW": "證書狀態",
+ "enUS": "Certificate Status",
+ "jaJP": "証明書の状態",
+ "koKR": "서류 상태",
+ "ruRU": "Состояние сертификата",
+ "ptBR": "Status do certificado",
+ "frFR": "Statut du certificat",
+ "esAR": "Estado del certificado",
+ "arDZ": "حالة الشهادة"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "证书到期时间": {
+ "text": "证书到期时间",
+ "key": "t_17_1745289355715",
+ "translations": {
+ "zhCN": "证书到期时间",
+ "zhTW": "證書到期時間",
+ "enUS": "Certificate Expiration Date",
+ "jaJP": "証明書の有効期限",
+ "koKR": "인증서 만료일",
+ "ruRU": "Дата окончания действия сертификата",
+ "ptBR": "Data de expiração do certificado",
+ "frFR": "Date d'expiration du certificat",
+ "esAR": "Fecha de expiración del certificado",
+ "arDZ": "تاريخ انتهاء صلاحية الشهادة"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "告警渠道": {
+ "text": "告警渠道",
+ "key": "t_18_1745289354598",
+ "translations": {
+ "zhCN": "告警渠道",
+ "zhTW": "告警管道",
+ "enUS": "Alert Channels",
+ "jaJP": "警報チャネル",
+ "koKR": "알림 채널",
+ "ruRU": "Каналы оповещений",
+ "ptBR": "Canais de alerta",
+ "frFR": "Canaux d'alerte",
+ "esAR": "Canales de alerta",
+ "arDZ": "قنوات التحذير"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "上次检查时间": {
+ "text": "上次检查时间",
+ "key": "t_19_1745289354676",
+ "translations": {
+ "zhCN": "上次检查时间",
+ "zhTW": "上次檢查時間",
+ "enUS": "Last Check Time",
+ "jaJP": "最後のチェック時刻",
+ "koKR": "최근 점검 시간",
+ "ruRU": "Время последней проверки",
+ "ptBR": "Última data de verificação",
+ "frFR": "Dernière date de vérification",
+ "esAR": "Última revisión",
+ "arDZ": "تاريخ آخر فحص"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "编辑监控": {
+ "text": "编辑监控",
+ "key": "t_20_1745289354598",
+ "translations": {
+ "zhCN": "编辑监控",
+ "zhTW": "編輯監控",
+ "enUS": "Edit Monitoring",
+ "jaJP": "編集監視",
+ "koKR": "편집 모니터링",
+ "ruRU": "Редактирование мониторинга",
+ "ptBR": "Edição de Monitoramento",
+ "frFR": "Édition de surveillance",
+ "esAR": "Edición de monitoreo",
+ "arDZ": "تعديل الرقابة"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "确认删除": {
+ "text": "确认删除",
+ "key": "t_21_1745289354598",
+ "translations": {
+ "zhCN": "确认删除",
+ "zhTW": "確認刪除",
+ "enUS": "Confirm Delete",
+ "jaJP": "削除を確認してください",
+ "koKR": "삭제 확인",
+ "ruRU": "Подтвердите удаление",
+ "ptBR": "Confirmar exclusão",
+ "frFR": "Confirmez la suppression",
+ "esAR": "Confirmar eliminación",
+ "arDZ": "تأكيد الحذف"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "删除后无法恢复,确认要删除该监控吗?": {
+ "text": "删除后无法恢复,确认要删除该监控吗?",
+ "key": "t_22_1745289359036",
+ "translations": {
+ "zhCN": "删除后将无法恢复,您确认要删除该监控吗?",
+ "zhTW": "刪除後將無法恢復,您確定要刪除該監控嗎?",
+ "enUS": "Items cannot be restored after deletion. Are you sure you want to delete this monitor?",
+ "jaJP": "削除後は復元できません。この監視を削除する場合は確定しますか?",
+ "koKR": "삭제된 아이템은 복원할 수 없습니다. 이 모니터를 정말로 삭제하시겠습니까?",
+ "ruRU": "Элементы нельзя восстановить после удаления. Вы уверены, что хотите удалить этот монитор?",
+ "ptBR": "Os itens não podem ser restaurados após a exclusão. Tem certeza de que deseja excluir este monitor?",
+ "frFR": "Les éléments ne peuvent pas être restaurés après suppression. Êtes-vous sûr de vouloir supprimer ce moniteur?",
+ "esAR": "Los elementos no se pueden recuperar después de su eliminación. ¿Está seguro de que desea eliminar este monitor?",
+ "arDZ": "لا يمكن استعادة العناصر بعد الحذف. هل أنت متأكد من أنك تريد حذف هذا المراقب؟"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "修改失败": {
+ "text": "修改失败",
+ "key": "t_23_1745289355716",
+ "translations": {
+ "zhCN": "修改失败",
+ "zhTW": "修改失敗",
+ "enUS": "Modification failed",
+ "jaJP": "変更失敗",
+ "koKR": "변경 실패",
+ "ruRU": "Не удалось изменить",
+ "ptBR": "Falha na modificação",
+ "frFR": "Échec de la modification",
+ "esAR": "Fallo en la modificación",
+ "arDZ": "فشل التعديل"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "设置失败": {
+ "text": "设置失败",
+ "key": "t_24_1745289355715",
+ "translations": {
+ "zhCN": "设置失败",
+ "zhTW": "設定失敗",
+ "enUS": "Setup Failed",
+ "jaJP": "設定失敗",
+ "koKR": "설정 실패",
+ "ruRU": "Сбой настройки",
+ "ptBR": "Falha na configuração",
+ "frFR": "Échec de la configuration",
+ "esAR": "Fallo en la configuración",
+ "arDZ": "فشل في الإعداد"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "请输入验证码": {
+ "text": "请输入验证码",
+ "key": "t_25_1745289355721",
+ "translations": {
+ "zhCN": "请输入验证码",
+ "zhTW": "請輸入驗證碼",
+ "enUS": "Please enter the verification code",
+ "jaJP": "認証コードを入力してください",
+ "koKR": "인증 코드를 입력하세요",
+ "ruRU": "Введите код подтверждения",
+ "ptBR": "Por favor, insira o código de verificação",
+ "frFR": "Veuillez saisir le code de vérification",
+ "esAR": "Por favor, ingrese el código de verificación",
+ "arDZ": "من فضلك، أدخل رمز التحقق"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "表单验证失败,请检查填写内容": {
+ "text": "表单验证失败,请检查填写内容",
+ "key": "t_26_1745289358341",
+ "translations": {
+ "zhCN": "表单验证失败,请检查填写内容",
+ "zhTW": "表單驗證失敗,請檢查填寫內容",
+ "enUS": "Form validation failed, please check the filled content",
+ "jaJP": "フォームのバリデーションに失敗しました、記入内容を確認してください",
+ "koKR": "양식 검증 실패, 입력 내용을 확인해 주세요",
+ "ruRU": "Проверка формы не пройдена, пожалуйста, проверьте填写的内容",
+ "ptBR": "Validação do formulário falhou, por favor, verifique o conteúdo preenchido",
+ "frFR": "Échec de validation du formulaire, veuillez vérifier le contenu rempli",
+ "esAR": "Validación del formulario fallida, por favor revise el contenido ingresado",
+ "arDZ": "فشل التحقق من النموذج، يرجى التحقق من المحتويات المملوءة"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "请输入授权API名称": {
+ "text": "请输入授权API名称",
+ "key": "t_27_1745289355721",
+ "translations": {
+ "zhCN": "请输入授权API名称",
+ "zhTW": "請輸入授權API名稱",
+ "enUS": "Please enter the authorized API name",
+ "jaJP": "認証API名前を入力してください",
+ "koKR": "인증 API 이름을 입력하세요",
+ "ruRU": "Введите имя авторизованного API",
+ "ptBR": "Por favor, insira o nome do API autorizado",
+ "frFR": "Veuillez saisir le nom de l'API autorisée",
+ "esAR": "Por favor, ingrese el nombre del API autorizado",
+ "arDZ": "من فضلك أدخل اسم API المصرح به"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "请选择授权API类型": {
+ "text": "请选择授权API类型",
+ "key": "t_28_1745289356040",
+ "translations": {
+ "zhCN": "请选择授权API类型",
+ "zhTW": "請選擇授權API類型",
+ "enUS": "Please select the authorization API type",
+ "jaJP": "認証APIタイプを選択してください",
+ "koKR": "인증 API 유형을 선택하세요",
+ "ruRU": "Выберите тип авторизации API",
+ "ptBR": "Selecione o tipo de API de autorização",
+ "frFR": "Veuillez sélectionner le type d'API d'autorisation",
+ "esAR": "Seleccione el tipo de API de autorización",
+ "arDZ": "يرجى اختيار نوع API الت�权يز"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "请输入服务器IP": {
+ "text": "请输入服务器IP",
+ "key": "t_29_1745289355850",
+ "translations": {
+ "zhCN": "请输入服务器IP",
+ "zhTW": "請輸入伺服器IP",
+ "enUS": "Please enter the server IP",
+ "jaJP": "サーバーIPを入力してください",
+ "koKR": "서버 IP를 입력하세요",
+ "ruRU": "Введите IP-адрес сервера",
+ "ptBR": "Por favor, insira o IP do servidor",
+ "frFR": "Veuillez saisir l'IP du serveur",
+ "esAR": "Por favor, ingrese la IP del servidor",
+ "arDZ": "الرجاء إدخال عنوان IP للخادم"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "请输入SSH端口": {
+ "text": "请输入SSH端口",
+ "key": "t_30_1745289355718",
+ "translations": {
+ "zhCN": "请输入SSH端口",
+ "zhTW": "請輸入SSH端口",
+ "enUS": "Please enter the SSH port",
+ "jaJP": "SSHポートを入力してください",
+ "koKR": "SSH 포트를 입력하세요",
+ "ruRU": "Введите порт SSH",
+ "ptBR": "Por favor, insira a porta SSH",
+ "frFR": "S'il vous plaît, entrez le port SSH",
+ "esAR": "Por favor, ingrese el puerto SSH",
+ "arDZ": "من فضلك، أدخل ميناء SSH"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "请输入SSH密钥": {
+ "text": "请输入SSH密钥",
+ "key": "t_31_1745289355715",
+ "translations": {
+ "zhCN": "请输入SSH密钥",
+ "zhTW": "請輸入SSH金鑰",
+ "enUS": "Please enter the SSH key",
+ "jaJP": "SSHキーを入力してください",
+ "koKR": "SSH 키를 입력하세요",
+ "ruRU": "Введите SSH-ключ",
+ "ptBR": "Por favor, insira a chave SSH",
+ "frFR": "Veuillez saisir la clé SSH",
+ "esAR": "Por favor, ingrese la clave SSH",
+ "arDZ": "من فضلك أدخل مفتاح SSH"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "请输入宝塔地址": {
+ "text": "请输入宝塔地址",
+ "key": "t_32_1745289356127",
+ "translations": {
+ "zhCN": "请输入宝塔地址",
+ "zhTW": "請輸入寶塔地址",
+ "enUS": "Please enter the Baota address",
+ "jaJP": "宝塔アドレスを入力してください",
+ "koKR": "보타 주소를 입력하세요",
+ "ruRU": "Введите адрес Ботты",
+ "ptBR": "Por favor, insira o endereço do Baota",
+ "frFR": "Veuillez saisir l'adresse de Baota",
+ "esAR": "Por favor, ingrese la dirección de Baota",
+ "arDZ": "الرجاء إدخال عنوان بوتا"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "请输入API密钥": {
+ "text": "请输入API密钥",
+ "key": "t_33_1745289355721",
+ "translations": {
+ "zhCN": "请输入API密钥",
+ "zhTW": "請輸入API金鑰",
+ "enUS": "Please enter the API key",
+ "jaJP": "APIキーを入力してください",
+ "koKR": "API 키를 입력하세요",
+ "ruRU": "Введіть ключ API",
+ "ptBR": "Por favor, insira a chave da API",
+ "frFR": "Veuillez saisir la clé API",
+ "esAR": "Por favor, ingrese la clave de API",
+ "arDZ": "الرجاء إدخال مفتاح API"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "请输入1panel地址": {
+ "text": "请输入1panel地址",
+ "key": "t_34_1745289356040",
+ "translations": {
+ "zhCN": "请输入1panel地址",
+ "zhTW": "請輸入1panel地址",
+ "enUS": "Please enter the 1panel address",
+ "jaJP": "1panelのアドレスを入力してください",
+ "koKR": "1panel 주소를 입력해 주세요",
+ "ruRU": "Введите адрес 1panel",
+ "ptBR": "Por favor, insira o endereço do 1panel",
+ "frFR": "Veuillez saisir l'adresse 1panel",
+ "esAR": "Por favor, ingrese la dirección de 1panel",
+ "arDZ": "الرجاء إدخال عنوان 1panel"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "请输入AccessKeyId": {
+ "text": "请输入AccessKeyId",
+ "key": "t_35_1745289355714",
+ "translations": {
+ "zhCN": "请输入AccessKeyId",
+ "zhTW": "請輸入AccessKeyId",
+ "enUS": "Please enter AccessKeyId",
+ "jaJP": "AccessKeyIdを入力してください",
+ "koKR": "AccessKeyId을 입력하세요",
+ "ruRU": "Введите AccessKeyId",
+ "ptBR": "Por favor, insira AccessKeyId",
+ "frFR": "Veuillez saisir AccessKeyId",
+ "esAR": "Por favor, ingrese AccessKeyId",
+ "arDZ": "من فضلك أدخل AccessKeyId"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "请输入AccessKeySecret": {
+ "text": "请输入AccessKeySecret",
+ "key": "t_36_1745289355715",
+ "translations": {
+ "zhCN": "请输入AccessKeySecret",
+ "zhTW": "請輸入AccessKeySecret",
+ "enUS": "Please enter AccessKeySecret",
+ "jaJP": "AccessKeySecretを入力してください",
+ "koKR": "AccessKeySecret을 입력하세요",
+ "ruRU": "Введите AccessKeySecret",
+ "ptBR": "Por favor, insira AccessKeySecret",
+ "frFR": "Veuillez saisir AccessKeySecret",
+ "esAR": "Por favor, ingrese AccessKeySecret",
+ "arDZ": "من فضلك، أدخل AccessKeySecret"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "请输入SecretId": {
+ "text": "请输入SecretId",
+ "key": "t_37_1745289356041",
+ "translations": {
+ "zhCN": "请输入SecretId",
+ "zhTW": "請輸入SecretId",
+ "enUS": "Please enter SecretId",
+ "jaJP": "SecretIdを入力してください",
+ "koKR": "SecretId를 입력하세요",
+ "ruRU": "Введіть SecretId",
+ "ptBR": "Por favor, insira SecretId",
+ "frFR": "S'il vous plaît, entrez SecretId",
+ "esAR": "Por favor, ingrese SecretId",
+ "arDZ": "من فضلك، أدخل SecretId"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "请输入SecretKey": {
+ "text": "请输入SecretKey",
+ "key": "t_38_1745289356419",
+ "translations": {
+ "zhCN": "请输入密钥",
+ "zhTW": "請輸入密鑰",
+ "enUS": "Please enter SecretKey",
+ "jaJP": "SecretKeyを入力してください",
+ "koKR": "SecretKey를 입력하세요",
+ "ruRU": "Введите SecretKey",
+ "ptBR": "Por favor, insira a Chave Secreta",
+ "frFR": "Veuillez saisir la Clé Secrète",
+ "esAR": "Por favor, ingrese la Clave Secreta",
+ "arDZ": "من فضلك أدخل مفتاح السر"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "更新成功": {
+ "text": "更新成功",
+ "key": "t_39_1745289354902",
+ "translations": {
+ "zhCN": "更新成功",
+ "zhTW": "更新成功",
+ "enUS": "Update successful",
+ "jaJP": "更新成功",
+ "koKR": "업데이트 성공",
+ "ruRU": "Успешно обновлено",
+ "ptBR": "Atualização bem-sucedida",
+ "frFR": "Mise à jour réussie",
+ "esAR": "Actualización exitosa",
+ "arDZ": "نجاح التحديث"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "添加成功": {
+ "text": "添加成功",
+ "key": "t_40_1745289355715",
+ "translations": {
+ "zhCN": "添加成功",
+ "zhTW": "添加成功",
+ "enUS": "Addition Successful",
+ "jaJP": "追加成功",
+ "koKR": "추가 성공",
+ "ruRU": "Успешно добавлено",
+ "ptBR": "Adição bem-sucedida",
+ "frFR": "Ajout réussi",
+ "esAR": "Añadido con éxito",
+ "arDZ": "نجاح الإضافة"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "类型": {
+ "text": "类型",
+ "key": "t_41_1745289354902",
+ "translations": {
+ "zhCN": "类型",
+ "zhTW": "類型",
+ "enUS": "Type",
+ "jaJP": "タイプ",
+ "koKR": "타입",
+ "ruRU": "Тип",
+ "ptBR": "Tipo",
+ "frFR": "Type",
+ "esAR": "Tipo",
+ "arDZ": "نوع"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "服务器IP": {
+ "text": "服务器IP",
+ "key": "t_42_1745289355715",
+ "translations": {
+ "zhCN": "服务器IP",
+ "zhTW": "伺服器IP",
+ "enUS": "Server IP",
+ "jaJP": "サーバーIP",
+ "koKR": "서버 IP",
+ "ruRU": "Сервер IP",
+ "ptBR": "IP do Servidor",
+ "frFR": "IP du serveur",
+ "esAR": "IP del servidor",
+ "arDZ": "IP del serveur"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "SSH端口": {
+ "text": "SSH端口",
+ "key": "t_43_1745289354598",
+ "translations": {
+ "zhCN": "SSH端口",
+ "zhTW": "SSH端口",
+ "enUS": "SSH port",
+ "jaJP": "SSHポート",
+ "koKR": "SSH 포트",
+ "ruRU": "Порт SSH",
+ "ptBR": "Porta SSH",
+ "frFR": "Port SSH",
+ "esAR": "Puerto SSH",
+ "arDZ": "منفذ SSH"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "用户名": {
+ "text": "用户名",
+ "key": "t_44_1745289354583",
+ "translations": {
+ "zhCN": "用户名",
+ "zhTW": "用戶名",
+ "enUS": "Username",
+ "jaJP": "ユーザー名",
+ "koKR": "사용자 이름",
+ "ruRU": "Имя пользователя",
+ "ptBR": "Nome de usuário",
+ "frFR": "Nom d'utilisateur",
+ "esAR": "Nombre de usuario",
+ "arDZ": "اسم المستخدم"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "认证方式": {
+ "text": "认证方式",
+ "key": "t_45_1745289355714",
+ "translations": {
+ "zhCN": "认证方式",
+ "zhTW": "認證方式",
+ "enUS": "Authentication method",
+ "jaJP": "認証方法",
+ "koKR": "인증 방법",
+ "ruRU": "Способ проверки",
+ "ptBR": "Método de autenticação",
+ "frFR": "Méthode d'authentification",
+ "esAR": "Método de autenticación",
+ "arDZ": "طريقة التحقق"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "密码认证": {
+ "text": "密码认证",
+ "key": "t_46_1745289355723",
+ "translations": {
+ "zhCN": "密码认证",
+ "zhTW": "密碼驗證",
+ "enUS": "Password authentication",
+ "jaJP": "パスワード認証",
+ "koKR": "암호 인증",
+ "ruRU": "Парольная аутентификация",
+ "ptBR": "Autenticação por senha",
+ "frFR": "Authentification par mot de passe",
+ "esAR": "Autenticación por contraseña",
+ "arDZ": "تأكيد البصمة البصرية"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "密钥认证": {
+ "text": "密钥认证",
+ "key": "t_47_1745289355715",
+ "translations": {
+ "zhCN": "密钥认证",
+ "zhTW": "密钥認證",
+ "enUS": "Key authentication",
+ "jaJP": "キー認証",
+ "koKR": "키 인증",
+ "ruRU": "Ключевая аутентификация",
+ "ptBR": "Autenticação de chave",
+ "frFR": "Authentification par clé",
+ "esAR": "Autenticación de clave",
+ "arDZ": "تأكيد البصمة"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "密码": {
+ "text": "密码",
+ "key": "t_48_1745289355714",
+ "translations": {
+ "zhCN": "密码",
+ "zhTW": "密碼",
+ "enUS": "Password",
+ "jaJP": "パスワード",
+ "koKR": "비밀번호",
+ "ruRU": "Пароль",
+ "ptBR": "Senha",
+ "frFR": "Mot de passe",
+ "esAR": "Contraseña",
+ "arDZ": "كلمة المرور"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "SSH私钥": {
+ "text": "SSH私钥",
+ "key": "t_49_1745289355714",
+ "translations": {
+ "zhCN": "SSH私钥",
+ "zhTW": "SSH私鑰",
+ "enUS": "SSH private key",
+ "jaJP": "SSHプライベートキー",
+ "koKR": "SSH 비밀키",
+ "ruRU": "SSH частный ключ",
+ "ptBR": "Chave privada SSH",
+ "frFR": "Clé privée SSH",
+ "esAR": "Llave privada SSH",
+ "arDZ": "مفتاح خاص SSH"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "请输入SSH私钥": {
+ "text": "请输入SSH私钥",
+ "key": "t_50_1745289355715",
+ "translations": {
+ "zhCN": "请输入SSH私钥",
+ "zhTW": "請輸入SSH私鑰",
+ "enUS": "Please enter the SSH private key",
+ "jaJP": "SSHプライベートキーを入力してください",
+ "koKR": "SSH 프라이빗 키를 입력하세요",
+ "ruRU": "Введите SSH частный ключ",
+ "ptBR": "Por favor, insira a chave privada SSH",
+ "frFR": "Veuillez saisir la clé privée SSH",
+ "esAR": "Por favor, ingrese la clave privada SSH",
+ "arDZ": "الرجاء إدخال مفتاح SSH الخاص"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "私钥密码": {
+ "text": "私钥密码",
+ "key": "t_51_1745289355714",
+ "translations": {
+ "zhCN": "私钥密码",
+ "zhTW": "私鍵密碼",
+ "enUS": "Private key password",
+ "jaJP": "プライベートキーワード",
+ "koKR": "private key 비밀번호",
+ "ruRU": "Пароль私ного ключа",
+ "ptBR": "Senha da chave privada",
+ "frFR": "Mot de passe de la clé privée",
+ "esAR": "Contraseña de la clave privada",
+ "arDZ": "كلمة المرور الخاصة بالمفتاح الخاص"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "如果私钥有密码,请输入": {
+ "text": "如果私钥有密码,请输入",
+ "key": "t_52_1745289359565",
+ "translations": {
+ "zhCN": "如果私钥有密码,请输入",
+ "zhTW": "如果私钥有密碼,請輸入",
+ "enUS": "If the private key has a password, please enter",
+ "jaJP": "プライベートキーにパスワードがある場合、入力してください",
+ "koKR": "비밀키에 비밀번호가 있으면 입력하세요",
+ "ruRU": "Если у私ного ключа есть пароль, введите",
+ "ptBR": "Se a chave privada tiver uma senha, insira",
+ "frFR": "Si la clé privée a un mot de passe, veuillez saisir",
+ "esAR": "Si la clave privada tiene una contraseña, ingrese",
+ "arDZ": "إذا كانت المفتاح الخاص يحتوي على كلمة مرور، أدخلها"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "宝塔面板地址": {
+ "text": "宝塔面板地址",
+ "key": "t_53_1745289356446",
+ "translations": {
+ "zhCN": "宝塔面板地址",
+ "zhTW": "宝塔面板地址",
+ "enUS": "BaoTa Panel Address",
+ "jaJP": "宝塔パネルのアドレス",
+ "koKR": "보타 패널 주소",
+ "ruRU": "Адрес панели Баота",
+ "ptBR": "Endereço da tela BaoTa",
+ "frFR": "Adresse du panneau BaoTa",
+ "esAR": "Dirección del panel BaoTa",
+ "arDZ": "عنوان واجهة بوتا"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "请输入宝塔面板地址,例如: https://bt.example.com": {
+ "text": "请输入宝塔面板地址,例如: https://bt.example.com",
+ "key": "t_54_1745289358683",
+ "translations": {
+ "zhCN": "请输入宝塔面板地址,例如:https://bt.example.com",
+ "zhTW": "請輸入宝塔面板地址,例如:https://bt.example.com",
+ "enUS": "Please enter the Baota panel address, for example: https://bt.example.com",
+ "jaJP": "宝塔パネルのアドレスを入力してください、例えば:https://bt.example.com",
+ "koKR": "보타 패널 주소를 입력하세요,예를 들어: https://bt.example.com",
+ "ruRU": "Введіть адресс панели Baota, например: https://bt.example.com",
+ "ptBR": "Por favor, insira o endereço do painel Baota, por exemplo: https://bt.example.com",
+ "frFR": "Veuillez saisir l'adresse du panneau Baota, par exemple : https://bt.example.com",
+ "esAR": "Por favor, ingrese la dirección del panel Baota, por ejemplo: https://bt.example.com",
+ "arDZ": "من فضلك أدخل عنوان لوحة بوتا، مثل: https://bt.example.com"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "API密钥": {
+ "text": "API密钥",
+ "key": "t_55_1745289355715",
+ "translations": {
+ "zhCN": "API密钥",
+ "zhTW": "API金鑰",
+ "enUS": "API Key",
+ "jaJP": "APIキー",
+ "koKR": "API 키",
+ "ruRU": "API ключ",
+ "ptBR": "Chave API",
+ "frFR": "Clé API",
+ "esAR": "Clave API",
+ "arDZ": "مفتاح API"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "1panel地址": {
+ "text": "1panel地址",
+ "key": "t_56_1745289355714",
+ "translations": {
+ "zhCN": "1面板地址",
+ "zhTW": "1面板地址",
+ "enUS": "1 panel address",
+ "jaJP": "1パネルのアドレス",
+ "koKR": "1판의 주소",
+ "ruRU": "Адрес 1 панели",
+ "ptBR": "Endereço do painel 1",
+ "frFR": "Adresse du panneau 1",
+ "esAR": "Dirección del panel 1",
+ "arDZ": "عنوان اللوحة 1"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "请输入1panel地址,例如: https://1panel.example.com": {
+ "text": "请输入1panel地址,例如: https://1panel.example.com",
+ "key": "t_57_1745289358341",
+ "translations": {
+ "zhCN": "请输入1panel地址,例如:https://1panel.example.com",
+ "zhTW": "請輸入1panel地址,例如:https://1panel.example.com",
+ "enUS": "Please enter the 1panel address, for example: https://1panel.example.com",
+ "jaJP": "1panelのアドレスを入力してください、例えば:https://1panel.example.com",
+ "koKR": "1panel 주소를 입력하세요, 예를 들어: https://1panel.example.com",
+ "ruRU": "Введіть адресс 1panel, например: https://1panel.example.com",
+ "ptBR": "Insira o endereço do 1panel, por exemplo: https://1panel.example.com",
+ "frFR": "Saisissez l'adresse 1panel, par exemple : https://1panel.example.com",
+ "esAR": "Ingrese la dirección de 1panel, por ejemplo: https://1panel.example.com",
+ "arDZ": "ادخل عنوان 1panel، مثلًا: https://1panel.example.com"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "请输入AccessKey ID": {
+ "text": "请输入AccessKey ID",
+ "key": "t_58_1745289355721",
+ "translations": {
+ "zhCN": "请输入AccessKey ID",
+ "zhTW": "請輸入AccessKey ID",
+ "enUS": "Please enter the AccessKey ID",
+ "jaJP": "アクセスキーIDを入力してください",
+ "koKR": "AccessKey ID를 입력하세요",
+ "ruRU": "Введите ID AccessKey",
+ "ptBR": "Insira o ID do AccessKey",
+ "frFR": "Saisissez l'ID AccessKey",
+ "esAR": "Ingrese el ID de AccessKey",
+ "arDZ": "ادخل معرف AccessKey"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "请输入AccessKey Secret": {
+ "text": "请输入AccessKey Secret",
+ "key": "t_59_1745289356803",
+ "translations": {
+ "zhCN": "请输入访问密钥的秘密",
+ "zhTW": "請輸入AccessKey密碼",
+ "enUS": "Please input AccessKey Secret",
+ "jaJP": "アクセスキーのシークレットを入力してください",
+ "koKR": "AccessKey 비밀번호를 입력하세요",
+ "ruRU": "Введите секрет AccessKey",
+ "ptBR": "Por favor, insira o segredo do AccessKey",
+ "frFR": "Veuillez saisir le secret d'AccessKey",
+ "esAR": "Por favor, ingrese el secreto de AccessKey",
+ "arDZ": "من فضلك ادخل سرية مفتاح الوصول"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "请输入监控名称": {
+ "text": "请输入监控名称",
+ "key": "t_60_1745289355715",
+ "translations": {
+ "zhCN": "请输入监控名称",
+ "zhTW": "請輸入監控名稱",
+ "enUS": "Please enter the monitoring name",
+ "jaJP": "監視名前を入力してください",
+ "koKR": "모니터링 이름을 입력하세요",
+ "ruRU": "Введите имя монитора",
+ "ptBR": "Por favor, insira o nome do monitoramento",
+ "frFR": "Veuillez saisir le nom de surveillance",
+ "esAR": "Por favor, ingrese el nombre de monitoreo",
+ "arDZ": "الرجاء إدخال اسم المراقبة"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "请输入域名/IP": {
+ "text": "请输入域名/IP",
+ "key": "t_61_1745289355878",
+ "translations": {
+ "zhCN": "请输入域名/IP",
+ "zhTW": "請輸入域名/IP",
+ "enUS": "Please enter the domain/IP",
+ "jaJP": "ドメイン/IPを入力してください",
+ "koKR": "도메인/IP를 입력하세요",
+ "ruRU": "Введите домен/IP",
+ "ptBR": "Por favor, insira o domínio/IP",
+ "frFR": "Veuillez saisir le domaine/IP",
+ "esAR": "Por favor, ingrese el dominio/IP",
+ "arDZ": "الرجاء إدخال اسم النطاق/IP"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "请选择检查周期": {
+ "text": "请选择检查周期",
+ "key": "t_62_1745289360212",
+ "translations": {
+ "zhCN": "请选择检查周期",
+ "zhTW": "請選擇檢查週期",
+ "enUS": "Please select the inspection cycle",
+ "jaJP": "検査サイクルを選択してください",
+ "koKR": "검사 주기를 선택하세요",
+ "ruRU": "Выберите период проверки",
+ "ptBR": "Selecione o período de inspeção",
+ "frFR": "Veuillez sélectionner le cycle d'inspection",
+ "esAR": "Por favor, seleccione el período de inspección",
+ "arDZ": "يرجى اختيار فترة التحقق"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "5分钟": {
+ "text": "5分钟",
+ "key": "t_63_1745289354897",
+ "translations": {
+ "zhCN": "5分钟",
+ "zhTW": "5分鐘",
+ "enUS": "5 minutes",
+ "jaJP": "5分",
+ "koKR": "5분",
+ "ruRU": "5 минут",
+ "ptBR": "5 minutos",
+ "frFR": "5 minutes",
+ "esAR": "5 minutos",
+ "arDZ": "5 دقائق"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "10分钟": {
+ "text": "10分钟",
+ "key": "t_64_1745289354670",
+ "translations": {
+ "zhCN": "10分钟",
+ "zhTW": "10分鐘",
+ "enUS": "10 minutes",
+ "jaJP": "10分",
+ "koKR": "10분",
+ "ruRU": "10 минут",
+ "ptBR": "10 minutos",
+ "frFR": "10 minutes",
+ "esAR": "10 minutos",
+ "arDZ": "10 دقائق"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "15分钟": {
+ "text": "15分钟",
+ "key": "t_65_1745289354591",
+ "translations": {
+ "zhCN": "15分钟",
+ "zhTW": "15分鐘",
+ "enUS": "15 minutes",
+ "jaJP": "15分",
+ "koKR": "15분",
+ "ruRU": "15 минут",
+ "ptBR": "15 minutos",
+ "frFR": "15 minutes",
+ "esAR": "15 minutos",
+ "arDZ": "15 دقيقة"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "30分钟": {
+ "text": "30分钟",
+ "key": "t_66_1745289354655",
+ "translations": {
+ "zhCN": "30分钟",
+ "zhTW": "30分鐘",
+ "enUS": "30 minutes",
+ "jaJP": "30分",
+ "koKR": "30분",
+ "ruRU": "30 минут",
+ "ptBR": "30 minutos",
+ "frFR": "30 minutes",
+ "esAR": "30 minutos",
+ "arDZ": "30 دقيقة"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "60分钟": {
+ "text": "60分钟",
+ "key": "t_67_1745289354487",
+ "translations": {
+ "zhCN": "60分钟",
+ "zhTW": "60分鐘",
+ "enUS": "60 minutes",
+ "jaJP": "60分",
+ "koKR": "60분",
+ "ruRU": "60 минут",
+ "ptBR": "60 minutos",
+ "frFR": "60 minutes",
+ "esAR": "60 minutos",
+ "arDZ": "60 دقيقة"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "邮件": {
+ "text": "邮件",
+ "key": "t_68_1745289354676",
+ "translations": {
+ "zhCN": "邮件",
+ "zhTW": "郵件",
+ "enUS": "Email",
+ "jaJP": "メール",
+ "koKR": "이메일",
+ "ruRU": "Электронная почта",
+ "ptBR": "E-mail",
+ "frFR": "E-mail",
+ "esAR": "Correo electrónico",
+ "arDZ": "بريد إلكتروني"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "短信": {
+ "text": "短信",
+ "key": "t_69_1745289355721",
+ "translations": {
+ "zhCN": "短信",
+ "zhTW": "短信",
+ "enUS": "SMS",
+ "jaJP": "ショートメッセージ",
+ "koKR": "문자",
+ "ruRU": "СМС",
+ "ptBR": "SMS",
+ "frFR": "SMS",
+ "esAR": "SMS",
+ "arDZ": "رسالة قصيرة"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "微信": {
+ "text": "微信",
+ "key": "t_70_1745289354904",
+ "translations": {
+ "zhCN": "微信",
+ "zhTW": "微信",
+ "enUS": "WeChat",
+ "jaJP": "ライン",
+ "koKR": "위챗",
+ "ruRU": "Вайбер",
+ "ptBR": "WeChat",
+ "frFR": "WeChat",
+ "esAR": "WeChat",
+ "arDZ": "واتساب"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "域名/IP": {
+ "text": "域名/IP",
+ "key": "t_71_1745289354583",
+ "translations": {
+ "zhCN": "域名/IP",
+ "zhTW": "域名/IP",
+ "enUS": "Domain/IP",
+ "jaJP": "ドメイン/IP",
+ "koKR": "도메인/IP",
+ "ruRU": "Домен/IP",
+ "ptBR": "Domínio/IP",
+ "frFR": "Domaine/IP",
+ "esAR": "Dominio/IP",
+ "arDZ": "اسم النطاق/IP"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "检查周期": {
+ "text": "检查周期",
+ "key": "t_72_1745289355715",
+ "translations": {
+ "zhCN": "检查周期",
+ "zhTW": "檢查週期",
+ "enUS": "Inspection cycle",
+ "jaJP": "検査サイクル",
+ "koKR": "점검 주기",
+ "ruRU": "Период проверки",
+ "ptBR": "Período de inspeção",
+ "frFR": "Période de contrôle",
+ "esAR": "Período de inspección",
+ "arDZ": "فترة التحقق"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "请选择告警渠道": {
+ "text": "请选择告警渠道",
+ "key": "t_73_1745289356103",
+ "translations": {
+ "zhCN": "请选择告警渠道",
+ "zhTW": "請選擇告警渠道",
+ "enUS": "Please select an alert channel",
+ "jaJP": "警報チャンネルを選択してください",
+ "koKR": "경고 채널을 선택해 주세요",
+ "ruRU": "Выберите канал уведомлений",
+ "ptBR": "Selecione o canal de alerta",
+ "frFR": "Sélectionnez un canal d'alerte",
+ "esAR": "Seleccione un canal de alerta",
+ "arDZ": "يرجى اختيار قناة التحذير"
+ },
+ "timestamp": "2025-04-22T02:36:00.212Z"
+ },
+ "请输入授权api名称": {
+ "text": "请输入授权api名称",
+ "key": "t_0_1745289808449",
+ "translations": {
+ "zhCN": "请输入授权API名称",
+ "zhTW": "請輸入授權API名稱",
+ "enUS": "Please enter the authorized API name",
+ "jaJP": "認証APIの名前を入力してください",
+ "koKR": "인증 API 이름을 입력하세요",
+ "ruRU": "Введите имя авторизованного API",
+ "ptBR": "Por favor, insira o nome do API autorizado",
+ "frFR": "Veuillez saisir le nom de l'API autorisée",
+ "esAR": "Por favor, ingrese el nombre del API autorizado",
+ "arDZ": "الرجاء إدخال اسم API المصرح به"
+ },
+ "timestamp": "2025-04-22T02:43:28.449Z"
+ },
+ "删除监控": {
+ "text": "删除监控",
+ "key": "t_0_1745294710530",
+ "translations": {
+ "zhCN": "删除监控",
+ "zhTW": "刪除監控",
+ "enUS": "Delete monitoring",
+ "jaJP": "監視を削除する",
+ "koKR": "모니터링 삭제",
+ "ruRU": "Удалить мониторинг",
+ "ptBR": "Excluir monitoramento",
+ "frFR": "Supprimer la surveillance",
+ "esAR": "Eliminar monitoreo",
+ "arDZ": "حذف المراقبة"
+ },
+ "timestamp": "2025-04-22T04:05:10.531Z"
+ },
+ "更新时间": {
+ "text": "更新时间",
+ "key": "t_0_1745295228865",
+ "translations": {
+ "zhCN": "更新时间",
+ "zhTW": "更新時間",
+ "enUS": "Update Time",
+ "jaJP": "更新時刻",
+ "koKR": "업데이트 시간",
+ "ruRU": "Время обновления",
+ "ptBR": "Data de atualização",
+ "frFR": "Heure de mise à jour",
+ "esAR": "Fecha de actualización",
+ "arDZ": "زمن التحديث"
+ },
+ "timestamp": "2025-04-22T04:13:48.865Z"
+ },
+ "服务器IP地址格式错误": {
+ "text": "服务器IP地址格式错误",
+ "key": "t_0_1745317313835",
+ "translations": {
+ "zhCN": "服务器IP地址格式错误",
+ "zhTW": "伺服器IP位址格式錯誤",
+ "enUS": "Server IP address format error",
+ "jaJP": "サーバーIPアドレスの形式が不正です",
+ "koKR": "서버 IP 주소 형식이 오류입니다",
+ "ruRU": "Ошибочный формат IP-адреса сервера",
+ "ptBR": "Endereço IP do servidor está no formato incorreto",
+ "frFR": "Format de l'adresse IP du serveur incorrect",
+ "esAR": "Formato incorrecto de la dirección IP del servidor",
+ "arDZ": "تنسيق عنوان IP للخادم غير صحيح"
+ },
+ "timestamp": "2025-04-22T10:21:55.286Z"
+ },
+ "端口格式错误": {
+ "text": "端口格式错误",
+ "key": "t_1_1745317313096",
+ "translations": {
+ "zhCN": "端口格式错误",
+ "zhTW": "端口格式錯誤",
+ "enUS": "Port format error",
+ "jaJP": "ポートフォーマットエラー",
+ "koKR": "포트 포맷 오류",
+ "ruRU": "Ошибка формата порта",
+ "ptBR": "Erro de formato de porta",
+ "frFR": "Erreur de format de port",
+ "esAR": "Error de formato de puerto",
+ "arDZ": "خطأ في تنسيق المنفذ"
+ },
+ "timestamp": "2025-04-22T10:21:55.287Z"
+ },
+ "面板URL地址格式错误": {
+ "text": "面板URL地址格式错误",
+ "key": "t_2_1745317314362",
+ "translations": {
+ "zhCN": "面板URL地址格式错误",
+ "zhTW": "面板URL地址格式錯誤",
+ "enUS": "Panel URL address format error",
+ "jaJP": "パネルURLアドレスの形式が不正です",
+ "koKR": "패널 URL 주소 형식이 잘못되었습니다",
+ "ruRU": "Ошибка формата URL адреса панели",
+ "ptBR": "Formato de endereço da URL da página do painel incorreto",
+ "frFR": "Format incorrect de l'adresse URL du panneau",
+ "esAR": "Error de formato en la dirección URL del panel",
+ "arDZ": "خطأ في صيغة عنوان URL للوحة"
+ },
+ "timestamp": "2025-04-22T10:21:55.287Z"
+ },
+ "请输入面板API密钥": {
+ "text": "请输入面板API密钥",
+ "key": "t_3_1745317313561",
+ "translations": {
+ "zhCN": "请输入面板API密钥",
+ "zhTW": "請輸入面板API金鑰",
+ "enUS": "Please enter the panel API key",
+ "jaJP": "パネルAPIキーを入力してください",
+ "koKR": "패널 API 키를 입력하세요",
+ "ruRU": "Введіть ключ API панелі",
+ "ptBR": "Por favor, insira a chave API da panela",
+ "frFR": "Veuillez saisir la clé API du panneau",
+ "esAR": "Por favor, ingrese la clave API del panel",
+ "arDZ": "الرجاء إدخال مفتاح API لوحة التحكم"
+ },
+ "timestamp": "2025-04-22T10:21:55.287Z"
+ },
+ "请输入阿里云AccessKeyId": {
+ "text": "请输入阿里云AccessKeyId",
+ "key": "t_4_1745317314054",
+ "translations": {
+ "zhCN": "请输入阿里云AccessKeyId",
+ "zhTW": "請輸入阿里雲AccessKeyId",
+ "enUS": "Please enter the Aliyun AccessKeyId",
+ "jaJP": "阿里云アクセスキーIDを入力してください",
+ "koKR": "阿里云 접근키 ID를 입력하세요",
+ "ruRU": "Введите Aliyun AccessKeyId",
+ "ptBR": "Por favor, insira o AccessKeyId da Aliyun",
+ "frFR": "Veuillez saisir le AccessKeyId d'Aliyun",
+ "esAR": "Por favor, ingrese el AccessKeyId de Aliyun",
+ "arDZ": "الرجاء إدخال AccessKeyId لـ Aliyun"
+ },
+ "timestamp": "2025-04-22T10:21:55.287Z"
+ },
+ "请输入阿里云AccessKeySecret": {
+ "text": "请输入阿里云AccessKeySecret",
+ "key": "t_5_1745317315285",
+ "translations": {
+ "zhCN": "请输入阿里云AccessKeySecret",
+ "zhTW": "請輸入阿里雲AccessKeySecret",
+ "enUS": "Please input the Aliyun AccessKeySecret",
+ "jaJP": "阿里云のAccessKeySecretを入力してください",
+ "koKR": "阿里yun AccessKeySecret을 입력하세요",
+ "ruRU": "Ввведите секретный ключ AccessKey Aliyun",
+ "ptBR": "Por favor, insira o AccessKeySecret da Aliyun",
+ "frFR": "Veuillez saisir le AccessKeySecret d'Aliyun",
+ "esAR": "Por favor, ingrese el AccessKeySecret de Aliyun",
+ "arDZ": "الرجاء إدخال AccessKeySecret لـ Aliyun"
+ },
+ "timestamp": "2025-04-22T10:21:55.287Z"
+ },
+ "请输入腾讯云SecretId": {
+ "text": "请输入腾讯云SecretId",
+ "key": "t_6_1745317313383",
+ "translations": {
+ "zhCN": "请输入腾讯云SecretId",
+ "zhTW": "請輸入腾讯雲SecretId",
+ "enUS": "Please enter the Tencent Cloud SecretId",
+ "jaJP": "腾讯云SecretIdを入力してください",
+ "koKR": "腾讯云 SecretId를 입력하세요",
+ "ruRU": "Введите Tencent Cloud SecretId",
+ "ptBR": "Por favor, insira o SecretId do Tencent Cloud",
+ "frFR": "S'il vous plaît saisir le SecretId de Tencent Cloud",
+ "esAR": "Por favor, ingrese el SecretId de Tencent Cloud",
+ "arDZ": "الرجاء إدخال SecretId لتencent cloud"
+ },
+ "timestamp": "2025-04-22T10:21:55.287Z"
+ },
+ "请输入腾讯云SecretKey": {
+ "text": "请输入腾讯云SecretKey",
+ "key": "t_7_1745317313831",
+ "translations": {
+ "zhCN": "请输入腾讯云SecretKey",
+ "zhTW": "請輸入腾讯雲SecretKey",
+ "enUS": "Please enter the Tencent Cloud SecretKey",
+ "jaJP": "腾讯雲のSecretKeyを入力してください",
+ "koKR": "腾讯云 SecretKey를 입력하세요",
+ "ruRU": "Введите SecretKey Tencent Cloud",
+ "ptBR": "Por favor, insira a SecretKey da Tencent Cloud",
+ "frFR": "Veuillez saisir la SecretKey de Tencent Cloud",
+ "esAR": "Por favor, ingrese la SecretKey de Tencent Cloud",
+ "arDZ": "من فضلك أدخل SecretKey Tencent Cloud"
+ },
+ "timestamp": "2025-04-22T10:21:55.287Z"
+ },
+ "已启用": {
+ "text": "已启用",
+ "key": "t_0_1745457486299",
+ "translations": {
+ "zhCN": "已启用",
+ "zhTW": "已啟用",
+ "enUS": "Enabled",
+ "jaJP": "有効",
+ "koKR": "활성화됨",
+ "ruRU": "Включено",
+ "ptBR": "Ativado",
+ "frFR": "Activé",
+ "esAR": "Habilitado",
+ "arDZ": "ممكّن"
+ },
+ "timestamp": "2025-04-24T01:18:20.045Z"
+ },
+ "已停止": {
+ "text": "已停止",
+ "key": "t_1_1745457484314",
+ "translations": {
+ "zhCN": "已停止",
+ "zhTW": "已停止",
+ "enUS": "Stopped",
+ "jaJP": "停止しました",
+ "koKR": "중지됨",
+ "ruRU": "Остановлено",
+ "ptBR": "Parado",
+ "frFR": "Arrêté",
+ "esAR": "Detenido",
+ "arDZ": "توقف"
+ },
+ "timestamp": "2025-04-24T01:18:20.046Z"
+ },
+ "切换为手动模式": {
+ "text": "切换为手动模式",
+ "key": "t_2_1745457488661",
+ "translations": {
+ "zhCN": "切换为手动模式",
+ "zhTW": "切換為手動模式",
+ "enUS": "Switch to manual mode",
+ "jaJP": "手動モードに切り替え",
+ "koKR": "수동 모드로 전환",
+ "ruRU": "Переключиться в ручной режим",
+ "ptBR": "Mudar para o modo manual",
+ "frFR": "Passer en mode manuel",
+ "esAR": "Cambiar a modo manual",
+ "arDZ": "التبديل إلى الوضع اليدوي"
+ },
+ "timestamp": "2025-04-24T01:18:20.046Z"
+ },
+ "切换为自动模式": {
+ "text": "切换为自动模式",
+ "key": "t_3_1745457486983",
+ "translations": {
+ "zhCN": "切换为自动模式",
+ "zhTW": "切換為自動模式",
+ "enUS": "Switch to automatic mode",
+ "jaJP": "自動モードに切り替える",
+ "koKR": "자동 모드로 전환",
+ "ruRU": "Переключиться в автоматический режим",
+ "ptBR": "Mudar para o modo automático",
+ "frFR": "Passer en mode automatique",
+ "esAR": "Cambiar a modo automático",
+ "arDZ": "التبديل إلى الوضع التلقائي"
+ },
+ "timestamp": "2025-04-24T01:18:20.046Z"
+ },
+ "切换为手动模式后,工作流将不再自动执行,但仍可手动执行": {
+ "text": "切换为手动模式后,工作流将不再自动执行,但仍可手动执行",
+ "key": "t_4_1745457497303",
+ "translations": {
+ "zhCN": "切换为手动模式后,工作流将不再自动执行,但仍可手动执行",
+ "zhTW": "切換為手動模式後,工作流將不再自動執行,但仍可手動執行",
+ "enUS": "After switching to manual mode, the workflow will no longer be executed automatically, but can still be executed manually",
+ "jaJP": "手動モードに切り替えた後、ワークフローは自動的に実行されなくなりますが、手動で実行することは可能です",
+ "koKR": "수동 모드로 전환한 후 워크플로우는 더 이상 자동으로 실행되지 않지만 수동으로 실행할 수 있습니다",
+ "ruRU": "После переключения в ручной режим рабочий процесс больше не будет выполняться автоматически, но его все равно можно выполнить вручную",
+ "ptBR": "Ao mudar para o modo manual, o fluxo de trabalho não será mais executado automaticamente, mas ainda pode ser executado manualmente",
+ "frFR": "Après avoir basculé en mode manuel, le flux de travail ne s'exécutera plus automatiquement, mais peut toujours être exécuté manuellement",
+ "esAR": "Después de cambiar al modo manual, el flujo de trabajo ya no se ejecutará automáticamente, pero aún se puede ejecutar manualmente",
+ "arDZ": "بعد التبديل إلى الوضع اليدوي، لن يتم تنفيذ سير العمل تلقائيًا، ولكن لا يزال يمكن تنفيذه يدويًا"
+ },
+ "timestamp": "2025-04-24T01:18:20.046Z"
+ },
+ "切换为自动模式后,工作流将按照配置的时间自动执行": {
+ "text": "切换为自动模式后,工作流将按照配置的时间自动执行",
+ "key": "t_5_1745457494695",
+ "translations": {
+ "zhCN": "切换为自动模式后,工作流将按照配置的时间自动执行",
+ "zhTW": "切換為自動模式後,工作流將按照配置的時間自動執行",
+ "enUS": "After switching to automatic mode, the workflow will automatically execute according to the configured time",
+ "jaJP": "自動モードに切り替えた後、ワークフローは設定された時間に従って自動的に実行されます",
+ "koKR": "자동 모드로 전환한 후 워크플로우는 구성된 시간에 따라 자동으로 실행됩니다",
+ "ruRU": "После переключения в автоматический режим рабочий процесс будет автоматически выполняться в соответствии с настроенным временем",
+ "ptBR": "Após mudar para o modo automático, o fluxo de trabalho será executado automaticamente de acordo com o tempo configurado",
+ "frFR": "Après être passé en mode automatique, le flux de travail s'exécutera automatiquement selon le temps configuré",
+ "esAR": "Después de cambiar al modo automático, el flujo de trabajo se ejecutará automáticamente según el tiempo configurado",
+ "arDZ": "بعد التبديل إلى الوضع التلقائي، سيعمل سير العمل تلقائيًا وفقًا للوقت المحدد"
+ },
+ "timestamp": "2025-04-24T01:18:20.046Z"
+ },
+ "关闭当前工作流": {
+ "text": "关闭当前工作流",
+ "key": "t_6_1745457487560",
+ "translations": {
+ "zhCN": "关闭当前工作流",
+ "zhTW": "關閉當前工作流程",
+ "enUS": "Close current workflow",
+ "jaJP": "現在のワークフローを閉じる",
+ "koKR": "현재 워크플로우 닫기",
+ "ruRU": "Закрыть текущий рабочий процесс",
+ "ptBR": "Fechar fluxo de trabalho atual",
+ "frFR": "Fermer le flux de travail actuel",
+ "esAR": "Cerrar flujo de trabajo actual",
+ "arDZ": "إغلاق سير العمل الحالي"
+ },
+ "timestamp": "2025-04-24T01:18:20.046Z"
+ },
+ "启用当前工作流": {
+ "text": "启用当前工作流",
+ "key": "t_7_1745457487185",
+ "translations": {
+ "zhCN": "启用当前工作流",
+ "zhTW": "啟用當前工作流程",
+ "enUS": "Enable current workflow",
+ "jaJP": "現在のワークフローを有効にする",
+ "koKR": "현재 워크플로우 활성화",
+ "ruRU": "Включить текущий рабочий процесс",
+ "ptBR": "Ativar fluxo de trabalho atual",
+ "frFR": "Activer le flux de travail actuel",
+ "esAR": "Habilitar flujo de trabajo actual",
+ "arDZ": "تمكين سير العمل الحالي"
+ },
+ "timestamp": "2025-04-24T01:18:20.046Z"
+ },
+ "关闭后,工作流将不再自动执行,手动也无法执行,是否继续?": {
+ "text": "关闭后,工作流将不再自动执行,手动也无法执行,是否继续?",
+ "key": "t_8_1745457496621",
+ "translations": {
+ "zhCN": "关闭后,工作流将不再自动执行,手动也无法执行,是否继续?",
+ "zhTW": "關閉後,工作流將不再自動執行,手動也無法執行,是否繼續?",
+ "enUS": "After closing, the workflow will no longer execute automatically and cannot be executed manually. Continue?",
+ "jaJP": "閉じると、ワークフローは自動的に実行されなくなり、手動でも実行できません。続行しますか?",
+ "koKR": "닫으면 워크플로우가 자동으로 실행되지 않고 수동으로도 실행할 수 없습니다. 계속하시겠습니까?",
+ "ruRU": "После закрытия рабочий процесс больше не будет выполняться автоматически и вручную его тоже невозможно будет выполнить. Продолжить?",
+ "ptBR": "Após o fechamento, o fluxo de trabalho não será mais executado automaticamente e não poderá ser executado manualmente. Continuar?",
+ "frFR": "Après la fermeture, le flux de travail ne s'exécutera plus automatiquement et ne pourra pas être exécuté manuellement. Continuer ?",
+ "esAR": "Después de cerrar, el flujo de trabajo ya no se ejecutará automáticamente ni se podrá ejecutar manualmente. ¿Continuar?",
+ "arDZ": "بعد الإغلاق، لن يتم تنفيذ سير العمل تلقائيًا ولن يمكن تنفيذه يدويًا. هل تريد المتابعة؟"
+ },
+ "timestamp": "2025-04-24T01:18:20.046Z"
+ },
+ "启用后,工作流配置自动执行,或手动执行,是否继续?": {
+ "text": "启用后,工作流配置自动执行,或手动执行,是否继续?",
+ "key": "t_9_1745457500045",
+ "translations": {
+ "zhCN": "启用后,工作流配置自动执行,或手动执行,是否继续?",
+ "zhTW": "啟用後,工作流程配置自動執行,或手動執行,是否繼續?",
+ "enUS": "After enabling, the workflow configuration will execute automatically or manually. Continue?",
+ "jaJP": "有効にすると、ワークフロー設定が自動的に実行されるか、手動で実行されます。続行しますか?",
+ "koKR": "활성화 후, 워크플로 구성이 자동 또는 수동으로 실행됩니다. 계속하시겠습니까?",
+ "ruRU": "После включения конфигурация рабочего процесса будет выполняться автоматически или вручную. Продолжить?",
+ "ptBR": "Após ativar, a configuração do fluxo de trabalho será executada automaticamente ou manualmente. Continuar?",
+ "frFR": "Après activation, la configuration du flux de travail s'exécutera automatiquement ou manuellement. Continuer ?",
+ "esAR": "Después de habilitar, la configuración del flujo de trabajo se ejecutará automáticamente o manualmente. ¿Continuar?",
+ "arDZ": "بعد التمكين، سيتم تنفيذ تكوين سير العمل تلقائيًا أو يدويًا. متابعة؟"
+ },
+ "timestamp": "2025-04-24T01:18:20.046Z"
+ },
+ "添加工作流失败": {
+ "text": "添加工作流失败",
+ "key": "t_10_1745457486451",
+ "translations": {
+ "zhCN": "添加工作流失败",
+ "zhTW": "添加工作流程失敗",
+ "enUS": "Failed to add workflow",
+ "jaJP": "ワークフローの追加に失敗しました",
+ "koKR": "워크플로우 추가 실패",
+ "ruRU": "Не удалось добавить рабочий процесс",
+ "ptBR": "Falha ao adicionar fluxo de trabalho",
+ "frFR": "Échec de l'ajout du flux de travail",
+ "esAR": "Error al añadir el flujo de trabajo",
+ "arDZ": "فشل إضافة سير العمل"
+ },
+ "timestamp": "2025-04-24T01:18:20.046Z"
+ },
+ "设置工作流运行方式失败": {
+ "text": "设置工作流运行方式失败",
+ "key": "t_11_1745457488256",
+ "translations": {
+ "zhCN": "设置工作流运行方式失败",
+ "zhTW": "設置工作流程運行方式失敗",
+ "enUS": "Failed to set workflow execution method",
+ "jaJP": "ワークフローの実行方法の設定に失敗しました",
+ "koKR": "워크플로우 실행 방식 설정 실패",
+ "ruRU": "Не удалось установить метод выполнения рабочего процесса",
+ "ptBR": "Falha ao definir o método de execução do fluxo de trabalho",
+ "frFR": "Échec de la définition du mode d'exécution du flux de travail",
+ "esAR": "Error al configurar el método de ejecución del flujo de trabajo",
+ "arDZ": "فشل في تعيين طريقة تنفيذ سير العمل"
+ },
+ "timestamp": "2025-04-24T01:18:20.046Z"
+ },
+ "启用或禁用工作流失败": {
+ "text": "启用或禁用工作流失败",
+ "key": "t_12_1745457489076",
+ "translations": {
+ "zhCN": "启用或禁用工作流失败",
+ "zhTW": "啟用或禁用工作流程失敗",
+ "enUS": "Enable or disable workflow failure",
+ "jaJP": "ワークフローの失敗を有効または無効にする",
+ "koKR": "워크플로우 실패 활성화 또는 비활성화",
+ "ruRU": "Включение или отключение сбоя рабочего процесса",
+ "ptBR": "Ativar ou desativar falha no fluxo de trabalho",
+ "frFR": "Activer ou désactiver l'échec du flux de travail",
+ "esAR": "Habilitar o deshabilitar falla del flujo de trabajo",
+ "arDZ": "تمكين أو تعطيل فشل سير العمل"
+ },
+ "timestamp": "2025-04-24T01:18:20.046Z"
+ },
+ "执行工作流失败": {
+ "text": "执行工作流失败",
+ "key": "t_13_1745457487555",
+ "translations": {
+ "zhCN": "执行工作流失败",
+ "zhTW": "執行工作流程失敗",
+ "enUS": "Failed to execute workflow",
+ "jaJP": "ワークフローの実行に失敗しました",
+ "koKR": "워크플로우 실행 실패",
+ "ruRU": "Не удалось выполнить рабочий процесс",
+ "ptBR": "Falha ao executar o fluxo de trabalho",
+ "frFR": "Échec de l'exécution du workflow",
+ "esAR": "Error al ejecutar el flujo de trabajo",
+ "arDZ": "فشل تنفيذ سير العمل"
+ },
+ "timestamp": "2025-04-24T01:18:20.046Z"
+ },
+ "删除工作流失败": {
+ "text": "删除工作流失败",
+ "key": "t_14_1745457488092",
+ "translations": {
+ "zhCN": "删除工作流失败",
+ "zhTW": "刪除工作流失敗",
+ "enUS": "Failed to delete workflow",
+ "jaJP": "ワークフローの削除に失敗しました",
+ "koKR": "워크플로우 삭제 실패",
+ "ruRU": "Не удалось удалить рабочий процесс",
+ "ptBR": "Falha ao excluir fluxo de trabalho",
+ "frFR": "Échec de la suppression du flux de travail",
+ "esAR": "Error al eliminar el flujo de trabajo",
+ "arDZ": "فشل في حذف سير العمل"
+ },
+ "timestamp": "2025-04-24T01:18:20.046Z"
+ },
+ "退出": {
+ "text": "退出",
+ "key": "t_15_1745457484292",
+ "translations": {
+ "zhCN": "退出",
+ "zhTW": "退出",
+ "enUS": "Exit",
+ "jaJP": "終了",
+ "koKR": "종료",
+ "ruRU": "Выход",
+ "ptBR": "Sair",
+ "frFR": "Quitter",
+ "esAR": "Salir",
+ "arDZ": "خروج"
+ },
+ "timestamp": "2025-04-24T01:18:20.046Z"
+ },
+ "即将退出登录状态,确认退出吗?": {
+ "text": "即将退出登录状态,确认退出吗?",
+ "key": "t_16_1745457491607",
+ "translations": {
+ "zhCN": "即将退出登录状态,确认退出吗?",
+ "zhTW": "即將登出,確認要登出嗎?",
+ "enUS": "You are about to log out. Are you sure you want to exit?",
+ "jaJP": "ログアウトしようとしています。ログアウトしますか?",
+ "koKR": "로그아웃하려고 합니다. 로그아웃하시겠습니까?",
+ "ruRU": "Вы собираетесь выйти из системы. Вы уверены, что хотите выйти?",
+ "ptBR": "Você está prestes a sair. Tem certeza de que deseja sair?",
+ "frFR": "Vous êtes sur le point de vous déconnecter. Êtes-vous sûr de vouloir quitter ?",
+ "esAR": "Estás a punto de cerrar sesión. ¿Seguro que quieres salir?",
+ "arDZ": "أنت على وشك تسجيل الخروج. هل أنت متأكد أنك تريد الخروج؟"
+ },
+ "timestamp": "2025-04-24T01:18:20.046Z"
+ },
+ "正在退出登录状态,请稍后...": {
+ "text": "正在退出登录状态,请稍后...",
+ "key": "t_17_1745457488251",
+ "translations": {
+ "zhCN": "正在退出登录状态,请稍后...",
+ "zhTW": "正在登出,請稍候...",
+ "enUS": "Logging out, please wait...",
+ "jaJP": "ログアウト中です、少々お待ちください...",
+ "koKR": "로그아웃 중입니다. 잠시만 기다려주세요...",
+ "ruRU": "Выход из системы, пожалуйста, подождите...",
+ "ptBR": "Saindo da conta, por favor aguarde...",
+ "frFR": "Déconnexion en cours, veuillez patienter...",
+ "esAR": "Cerrando sesión, por favor espere...",
+ "arDZ": "جاري تسجيل الخروج، يرجى الانتظار..."
+ },
+ "timestamp": "2025-04-24T01:18:20.046Z"
+ },
+ "添加邮箱通知": {
+ "text": "添加邮箱通知",
+ "key": "t_18_1745457490931",
+ "translations": {
+ "zhCN": "添加邮箱通知",
+ "zhTW": "新增郵箱通知",
+ "enUS": "Add email notification",
+ "jaJP": "メール通知を追加",
+ "koKR": "이메일 알림 추가",
+ "ruRU": "Добавить уведомление по электронной почте",
+ "ptBR": "Adicionar notificação por e-mail",
+ "frFR": "Ajouter une notification par e-mail",
+ "esAR": "Agregar notificación por correo electrónico",
+ "arDZ": "إضافة إشعار عبر البريد الإلكتروني"
+ },
+ "timestamp": "2025-04-24T01:18:20.046Z"
+ },
+ "保存成功": {
+ "text": "保存成功",
+ "key": "t_19_1745457484684",
+ "translations": {
+ "zhCN": "保存成功",
+ "zhTW": "儲存成功",
+ "enUS": "Saved successfully",
+ "jaJP": "保存が成功しました",
+ "koKR": "저장 성공",
+ "ruRU": "Сохранено успешно",
+ "ptBR": "Salvo com sucesso",
+ "frFR": "Enregistré avec succès",
+ "esAR": "Guardado exitosamente",
+ "arDZ": "تم الحفظ بنجاح"
+ },
+ "timestamp": "2025-04-24T01:18:20.046Z"
+ },
+ "删除成功": {
+ "text": "删除成功",
+ "key": "t_20_1745457485905",
+ "translations": {
+ "zhCN": "删除成功",
+ "zhTW": "刪除成功",
+ "enUS": "Deleted successfully",
+ "jaJP": "削除に成功しました",
+ "koKR": "삭제 성공",
+ "ruRU": "Удалено успешно",
+ "ptBR": "Excluído com sucesso",
+ "frFR": "Supprimé avec succès",
+ "esAR": "Eliminado con éxito",
+ "arDZ": "تم الحذف بنجاح"
+ },
+ "timestamp": "2025-04-24T01:18:20.046Z"
+ },
+ "获取系统设置失败": {
+ "text": "获取系统设置失败",
+ "key": "t_0_1745464080226",
+ "translations": {
+ "zhCN": "获取系统设置失败",
+ "zhTW": "獲取系統設置失敗",
+ "enUS": "Failed to get system settings",
+ "jaJP": "システム設定の取得に失敗しました",
+ "koKR": "시스템 설정 가져오기 실패",
+ "ruRU": "Не удалось получить настройки системы",
+ "ptBR": "Falha ao obter as configurações do sistema",
+ "frFR": "Échec de la récupération des paramètres du système",
+ "esAR": "Error al obtener la configuración del sistema",
+ "arDZ": "فشل الحصول على إعدادات النظام"
+ },
+ "timestamp": "2025-04-24T03:08:06.047Z"
+ },
+ "设置保存失败": {
+ "text": "设置保存失败",
+ "key": "t_1_1745464079590",
+ "translations": {
+ "zhCN": "设置保存失败",
+ "zhTW": "設定儲存失敗",
+ "enUS": "Failed to save settings",
+ "jaJP": "設定の保存に失敗しました",
+ "koKR": "설정 저장 실패",
+ "ruRU": "Не удалось сохранить настройки",
+ "ptBR": "Falha ao salvar configurações",
+ "frFR": "Échec de l'enregistrement des paramètres",
+ "esAR": "Error al guardar la configuración",
+ "arDZ": "فشل حفظ الإعدادات"
+ },
+ "timestamp": "2025-04-24T03:08:06.048Z"
+ },
+ "获取通知设置失败": {
+ "text": "获取通知设置失败",
+ "key": "t_2_1745464077081",
+ "translations": {
+ "zhCN": "获取通知设置失败",
+ "zhTW": "獲取通知設置失敗",
+ "enUS": "Failed to get notification settings",
+ "jaJP": "通知設定の取得に失敗しました",
+ "koKR": "알림 설정 가져오기 실패",
+ "ruRU": "Не удалось получить настройки уведомлений",
+ "ptBR": "Falha ao obter configurações de notificação",
+ "frFR": "Échec de la récupération des paramètres de notification",
+ "esAR": "Error al obtener la configuración de notificaciones",
+ "arDZ": "فشل الحصول على إعدادات الإشعار"
+ },
+ "timestamp": "2025-04-24T03:08:06.048Z"
+ },
+ "保存通知设置失败": {
+ "text": "保存通知设置失败",
+ "key": "t_3_1745464081058",
+ "translations": {
+ "zhCN": "保存通知设置失败",
+ "zhTW": "儲存通知設定失敗",
+ "enUS": "Failed to save notification settings",
+ "jaJP": "通知設定の保存に失敗しました",
+ "koKR": "알림 설정 저장 실패",
+ "ruRU": "Не удалось сохранить настройки уведомлений",
+ "ptBR": "Falha ao salvar configurações de notificação",
+ "frFR": "Échec de l'enregistrement des paramètres de notification",
+ "esAR": "Error al guardar la configuración de notificaciones",
+ "arDZ": "فشل حفظ إعدادات الإشعار"
+ },
+ "timestamp": "2025-04-24T03:08:06.048Z"
+ },
+ "获取通知渠道列表失败": {
+ "text": "获取通知渠道列表失败",
+ "key": "t_4_1745464075382",
+ "translations": {
+ "zhCN": "获取通知渠道列表失败",
+ "zhTW": "獲取通知渠道列表失敗",
+ "enUS": "Failed to get notification channel list",
+ "jaJP": "通知チャネルリストの取得に失敗しました",
+ "koKR": "알림 채널 목록 가져오기 실패",
+ "ruRU": "Не удалось получить список каналов уведомлений",
+ "ptBR": "Falha ao obter a lista de canais de notificação",
+ "frFR": "Échec de la récupération de la liste des canaux de notification",
+ "esAR": "Error al obtener la lista de canales de notificación",
+ "arDZ": "فشل في الحصول على قائمة قنوات الإخطار"
+ },
+ "timestamp": "2025-04-24T03:08:06.048Z"
+ },
+ "添加邮箱通知渠道失败": {
+ "text": "添加邮箱通知渠道失败",
+ "key": "t_5_1745464086047",
+ "translations": {
+ "zhCN": "添加邮箱通知渠道失败",
+ "zhTW": "添加郵箱通知渠道失敗",
+ "enUS": "Failed to add email notification channel",
+ "jaJP": "メール通知チャネルの追加に失敗しました",
+ "koKR": "이메일 알림 채널 추가 실패",
+ "ruRU": "Не удалось добавить канал уведомлений по электронной почте",
+ "ptBR": "Falha ao adicionar canal de notificação por e-mail",
+ "frFR": "Échec de l'ajout du canal de notification par email",
+ "esAR": "Error al agregar el canal de notificación por correo electrónico",
+ "arDZ": "فشل إضافة قناة إشعار البريد الإلكتروني"
+ },
+ "timestamp": "2025-04-24T03:08:06.048Z"
+ },
+ "更新通知渠道失败": {
+ "text": "更新通知渠道失败",
+ "key": "t_6_1745464075714",
+ "translations": {
+ "zhCN": "更新通知渠道失败",
+ "zhTW": "更新通知渠道失敗",
+ "enUS": "Failed to update notification channel",
+ "jaJP": "通知チャネルの更新に失敗しました",
+ "koKR": "알림 채널 업데이트 실패",
+ "ruRU": "Не удалось обновить канал уведомлений",
+ "ptBR": "Falha ao atualizar o canal de notificação",
+ "frFR": "Échec de la mise à jour du canal de notification",
+ "esAR": "Error al actualizar el canal de notificación",
+ "arDZ": "فشل تحديث قناة الإشعارات"
+ },
+ "timestamp": "2025-04-24T03:08:06.048Z"
+ },
+ "删除通知渠道失败": {
+ "text": "删除通知渠道失败",
+ "key": "t_7_1745464073330",
+ "translations": {
+ "zhCN": "删除通知渠道失败",
+ "zhTW": "刪除通知渠道失敗",
+ "enUS": "Failed to delete notification channel",
+ "jaJP": "通知チャネルの削除に失敗しました",
+ "koKR": "알림 채널 삭제 실패",
+ "ruRU": "Не удалось удалить канал уведомлений",
+ "ptBR": "Falha ao excluir o canal de notificação",
+ "frFR": "Échec de la suppression du canal de notification",
+ "esAR": "Error al eliminar el canal de notificación",
+ "arDZ": "فشل حذف قناة الإشعار"
+ },
+ "timestamp": "2025-04-24T03:08:06.048Z"
+ },
+ "检查版本更新失败": {
+ "text": "检查版本更新失败",
+ "key": "t_8_1745464081472",
+ "translations": {
+ "zhCN": "检查版本更新失败",
+ "zhTW": "檢查版本更新失敗",
+ "enUS": "Failed to check for version update",
+ "jaJP": "バージョン更新の確認に失敗しました",
+ "koKR": "버전 업데이트 확인 실패",
+ "ruRU": "Не удалось проверить обновление версии",
+ "ptBR": "Falha ao verificar atualização de versão",
+ "frFR": "Échec de la vérification de la mise à jour de version",
+ "esAR": "Error al comprobar la actualización de versión",
+ "arDZ": "فشل التحقق من تحديث النسخة"
+ },
+ "timestamp": "2025-04-24T03:08:06.048Z"
+ },
+ "保存设置": {
+ "text": "保存设置",
+ "key": "t_9_1745464078110",
+ "translations": {
+ "zhCN": "保存设置",
+ "zhTW": "儲存設定",
+ "enUS": "Save settings",
+ "jaJP": "設定を保存",
+ "koKR": "설정 저장",
+ "ruRU": "Сохранить настройки",
+ "ptBR": "Salvar configurações",
+ "frFR": "Enregistrer les paramètres",
+ "esAR": "Guardar configuración",
+ "arDZ": "حفظ الإعدادات"
+ },
+ "timestamp": "2025-04-24T03:08:06.048Z"
+ },
+ "基础设置": {
+ "text": "基础设置",
+ "key": "t_10_1745464073098",
+ "translations": {
+ "zhCN": "基础设置",
+ "zhTW": "基礎設定",
+ "enUS": "Basic Settings",
+ "jaJP": "基本設定",
+ "koKR": "기본 설정",
+ "ruRU": "Основные настройки",
+ "ptBR": "Configurações básicas",
+ "frFR": "Paramètres de base",
+ "esAR": "Configuración básica",
+ "arDZ": "الإعدادات الأساسية"
+ },
+ "timestamp": "2025-04-24T03:08:06.048Z"
+ },
+ "选择模板": {
+ "text": "选择模板",
+ "key": "t_0_1745474945127",
+ "translations": {
+ "zhCN": "选择模板",
+ "zhTW": "選擇範本",
+ "enUS": "Choose template",
+ "jaJP": "テンプレートを選択",
+ "koKR": "템플릿 선택",
+ "ruRU": "Выбрать шаблон",
+ "ptBR": "Escolher modelo",
+ "frFR": "Choisir un modèle",
+ "esAR": "Elegir plantilla",
+ "arDZ": "اختر نموذج"
+ },
+ "timestamp": "2025-04-24T06:09:05.127Z"
+ },
+ "请输入工作流名称": {
+ "text": "请输入工作流名称",
+ "key": "t_0_1745490735213",
+ "translations": {
+ "zhCN": "请输入工作流名称",
+ "enUS": "Please enter the workflow name",
+ "jaJP": "ワークフロー名を入力してください",
+ "koKR": "워크플로우 이름을 입력하세요",
+ "ruRU": "Введите название рабочего процесса",
+ "ptBR": "Por favor, insira o nome do fluxo de trabalho",
+ "frFR": "Veuillez saisir le nom du workflow",
+ "esAR": "Por favor ingrese el nombre del flujo de trabajo",
+ "arDZ": "الرجاء إدخال اسم سير العمل",
+ "zhTW": "請輸入工作流程名稱"
+ },
+ "timestamp": "2025-04-24T10:32:19.917Z"
+ },
+ "配置": {
+ "text": "配置",
+ "key": "t_1_1745490731990",
+ "translations": {
+ "zhCN": "配置",
+ "zhTW": "配置",
+ "enUS": "Configuration",
+ "jaJP": "設定",
+ "koKR": "설정",
+ "ruRU": "Конфигурация",
+ "ptBR": "Configuração",
+ "frFR": "Configuration",
+ "esAR": "Configuración",
+ "arDZ": "إعدادات"
+ },
+ "timestamp": "2025-04-24T10:32:19.918Z"
+ },
+ "请输入邮箱格式": {
+ "text": "请输入邮箱格式",
+ "key": "t_2_1745490735558",
+ "translations": {
+ "zhCN": "请输入邮箱格式",
+ "zhTW": "請輸入電郵格式",
+ "enUS": "Please enter the email format",
+ "jaJP": "メール形式を入力してください",
+ "koKR": "이메일 형식을 입력하세요",
+ "ruRU": "Пожалуйста, введите формат электронной почты",
+ "ptBR": "Por favor, insira o formato de e-mail",
+ "frFR": "Veuillez saisir le format d'e-mail",
+ "esAR": "Por favor, ingrese el formato de correo electrónico",
+ "arDZ": "يرجى إدخال البريد الإلكتروني"
+ },
+ "timestamp": "2025-04-24T10:32:19.918Z"
+ },
+ "请选择DNS提供商": {
+ "text": "请选择DNS提供商",
+ "key": "t_3_1745490735059",
+ "translations": {
+ "zhCN": "请选择DNS提供商",
+ "zhTW": "請選擇DNS提供商",
+ "enUS": "Please select a DNS provider",
+ "jaJP": "DNSプロバイダーを選択してください",
+ "koKR": "DNS 공급자를 선택하세요",
+ "ruRU": "Пожалуйста, выберите поставщика DNS",
+ "ptBR": "Por favor, selecione um provedor de DNS",
+ "frFR": "Veuillez sélectionner un fournisseur DNS",
+ "esAR": "Por favor, seleccione un proveedor de DNS",
+ "arDZ": "يرجى اختيار موفر DNS"
+ },
+ "timestamp": "2025-04-24T10:32:19.918Z"
+ },
+ "请输入续签间隔": {
+ "text": "请输入续签间隔",
+ "key": "t_4_1745490735630",
+ "translations": {
+ "zhCN": "请输入续签间隔",
+ "zhTW": "請輸入續簽間隔",
+ "enUS": "Please enter the renewal interval",
+ "jaJP": "更新間隔を入力してください",
+ "koKR": "갱신 간격을 입력하세요",
+ "ruRU": "Введите интервал продления",
+ "ptBR": "Por favor, insira o intervalo de renovação",
+ "frFR": "Veuillez saisir l'intervalle de renouvellement",
+ "esAR": "Por favor, ingrese el intervalo de renovación",
+ "arDZ": "الرجاء إدخال فاصل التجديد"
+ },
+ "timestamp": "2025-04-24T10:32:19.918Z"
+ },
+ "请输入域名,域名不能为空": {
+ "text": "请输入域名,域名不能为空",
+ "key": "t_5_1745490738285",
+ "translations": {
+ "zhCN": "请输入域名,域名不能为空",
+ "zhTW": "請輸入域名,域名不能為空",
+ "enUS": "Please enter the domain name, the domain name cannot be empty",
+ "jaJP": "ドメイン名を入力してください。ドメイン名は空にできません",
+ "koKR": "도메인 이름을 입력하세요. 도메인 이름은 비워둘 수 없습니다",
+ "ruRU": "Введите доменное имя, оно не может быть пустым",
+ "ptBR": "Digite o nome de domínio, o nome de domínio não pode estar vazio",
+ "frFR": "Veuillez entrer le nom de domaine, il ne peut pas être vide",
+ "esAR": "Ingrese el nombre de dominio, el nombre de dominio no puede estar vacío",
+ "arDZ": "الرجاء إدخال اسم النطاق، لا يمكن أن يكون اسم النطاق فارغًا"
+ },
+ "timestamp": "2025-04-24T10:32:19.918Z"
+ },
+ "请输入邮箱,邮箱不能为空": {
+ "text": "请输入邮箱,邮箱不能为空",
+ "key": "t_6_1745490738548",
+ "translations": {
+ "zhCN": "请输入邮箱,邮箱不能为空",
+ "zhTW": "請輸入郵箱,郵箱不能為空",
+ "enUS": "Please enter your email, email cannot be empty",
+ "jaJP": "メールアドレスを入力してください、メールアドレスは空にできません",
+ "koKR": "이메일을 입력하세요, 이메일은 비워둘 수 없습니다",
+ "ruRU": "Пожалуйста, введите адрес электронной почты, поле не может быть пустым",
+ "ptBR": "Por favor, insira o e-mail, o e-mail não pode estar vazio",
+ "frFR": "Veuillez entrer votre email, l'email ne peut pas être vide",
+ "esAR": "Por favor ingrese el correo electrónico, el correo electrónico no puede estar vacío",
+ "arDZ": "الرجاء إدخال البريد الإلكتروني، لا يمكن أن يكون البريد الإلكتروني فارغًا"
+ },
+ "timestamp": "2025-04-24T10:32:19.918Z"
+ },
+ "请选择DNS提供商,DNS提供商不能为空": {
+ "text": "请选择DNS提供商,DNS提供商不能为空",
+ "key": "t_7_1745490739917",
+ "translations": {
+ "zhCN": "请选择DNS提供商,DNS提供商不能为空",
+ "zhTW": "請選擇DNS提供商,DNS提供商不能為空",
+ "enUS": "Please select a DNS provider, the DNS provider cannot be empty",
+ "jaJP": "DNSプロバイダーを選択してください。DNSプロバイダーは空にできません",
+ "koKR": "DNS 공급자를 선택하십시오. DNS 공급자는 비워 둘 수 없습니다",
+ "ruRU": "Пожалуйста, выберите DNS-провайдера, DNS-провайдер не может быть пустым",
+ "ptBR": "Por favor, selecione um provedor DNS, o provedor DNS não pode estar vazio",
+ "frFR": "Veuillez sélectionner un fournisseur DNS, le fournisseur DNS ne peut pas être vide",
+ "esAR": "Por favor, seleccione un proveedor DNS, el proveedor DNS no puede estar vacío",
+ "arDZ": "الرجاء اختيار موفر DNS، لا يمكن أن يكون موفر DNS فارغًا"
+ },
+ "timestamp": "2025-04-24T10:32:19.918Z"
+ },
+ "请输入续签间隔,续签间隔不能为空": {
+ "text": "请输入续签间隔,续签间隔不能为空",
+ "key": "t_8_1745490739319",
+ "translations": {
+ "zhCN": "请输入续签间隔,续签间隔不能为空",
+ "zhTW": "請輸入續簽間隔,續簽間隔不能為空",
+ "enUS": "Please enter the renewal interval, the renewal interval cannot be empty",
+ "jaJP": "更新間隔を入力してください。更新間隔は空にできません",
+ "koKR": "갱신 간격을 입력하세요. 갱신 간격은 비워둘 수 없습니다",
+ "ruRU": "Введите интервал продления, интервал продления не может быть пустым",
+ "ptBR": "Insira o intervalo de renovação, o intervalo de renovação não pode estar vazio",
+ "frFR": "Veuillez saisir l'intervalle de renouvellement, l'intervalle de renouvellement ne peut pas être vide",
+ "esAR": "Ingrese el intervalo de renovación, el intervalo de renovación no puede estar vacío",
+ "arDZ": "الرجاء إدخال فترة التجديد، فترة التجديد لا يمكن أن تكون فارغة"
+ },
+ "timestamp": "2025-04-24T10:32:19.918Z"
+ },
+ "域名格式错误,请输入正确的域名": {
+ "text": "域名格式错误,请输入正确的域名",
+ "key": "t_0_1745553910661",
+ "translations": {
+ "zhCN": "域名格式错误,请输入正确的域名",
+ "zhTW": "域名格式錯誤,請輸入正確的域名",
+ "enUS": "Domain format error, please enter the correct domain",
+ "jaJP": "ドメイン形式が間違っています。正しいドメインを入力してください",
+ "koKR": "도메인 형식이 잘못되었습니다. 올바른 도메인을 입력하세요",
+ "ruRU": "Ошибка формата домена, введите правильный домен",
+ "ptBR": "Formato de domínio incorreto, insira o domínio correto",
+ "frFR": "Format de domaine incorrect, veuillez entrer le bon domaine",
+ "esAR": "Formato de dominio incorrecto, ingrese el dominio correcto",
+ "arDZ": "خطأ في تنسيق النطاق، يُرجى إدخال النطاق الصحيح"
+ },
+ "timestamp": "2025-04-25T04:05:10.661Z"
+ },
+ "邮箱格式错误,请输入正确的邮箱": {
+ "text": "邮箱格式错误,请输入正确的邮箱",
+ "key": "t_1_1745553909483",
+ "translations": {
+ "zhCN": "邮箱格式错误,请输入正确的邮箱",
+ "zhTW": "郵箱格式錯誤,請輸入正確的郵箱",
+ "enUS": "Invalid email format, please enter a correct email",
+ "jaJP": "メールの形式が正しくありません。正しいメールアドレスを入力してください",
+ "koKR": "이메일 형식이 잘못되었습니다. 올바른 이메일을 입력하세요",
+ "ruRU": "Неверный формат электронной почты, введите правильный адрес",
+ "ptBR": "Formato de e-mail inválido, por favor insira um e-mail correto",
+ "frFR": "Format d'email incorrect, veuillez saisir un email valide",
+ "esAR": "Formato de correo electrónico incorrecto, ingrese un correo correcto",
+ "arDZ": "تنسيق البريد الإلكتروني غير صحيح، يرجى إدخال بريد صحيح"
+ },
+ "timestamp": "2025-04-25T04:05:10.662Z"
+ },
+ "续签间隔不能为空": {
+ "text": "续签间隔不能为空",
+ "key": "t_2_1745553907423",
+ "translations": {
+ "zhCN": "续签间隔不能为空",
+ "zhTW": "續簽間隔不能為空",
+ "enUS": "Renewal interval cannot be empty",
+ "jaJP": "更新間隔は空にできません",
+ "koKR": "갱신 간격은 비워둘 수 없습니다",
+ "ruRU": "Интервал продления не может быть пустым",
+ "ptBR": "O intervalo de renovação não pode estar vazio",
+ "frFR": "L'intervalle de renouvellement ne peut pas être vide",
+ "esAR": "El intervalo de renovación no puede estar vacío",
+ "arDZ": "لا يمكن أن يكون فاصل التجديد فارغًا"
+ },
+ "timestamp": "2025-04-25T04:05:10.662Z"
+ },
+ "请输入证书域名,多个域名用逗号分隔": {
+ "text": "请输入证书域名,多个域名用逗号分隔",
+ "key": "t_0_1745735774005",
+ "translations": {
+ "zhCN": "请输入证书域名,多个域名用逗号分隔",
+ "zhTW": "請輸入證書域名,多個域名用逗號分隔",
+ "enUS": "Please enter the certificate domain name, multiple domain names separated by commas",
+ "jaJP": "証明書のドメイン名を入力してください。複数のドメイン名はカンマで区切ります",
+ "koKR": "인증서 도메인 이름을 입력하세요. 여러 도메인 이름은 쉼표로 구분합니다",
+ "ruRU": "Введите доменное имя сертификата, несколько доменных имен разделяются запятыми",
+ "ptBR": "Digite o nome de domínio do certificado, vários nomes de domínio separados por vírgulas",
+ "frFR": "Veuillez saisir le nom de domaine du certificat, plusieurs noms de domaine séparés par des virgules",
+ "esAR": "Ingrese el nombre de dominio del certificado, varios nombres de dominio separados por comas",
+ "arDZ": "الرجاء إدخال اسم نطاق الشهادة، أسماء نطاقات متعددة مفصولة بفواصل"
+ },
+ "timestamp": "2025-04-27T06:36:55.317Z"
+ },
+ "邮箱": {
+ "text": "邮箱",
+ "key": "t_1_1745735764953",
+ "translations": {
+ "zhCN": "邮箱",
+ "zhTW": "信箱",
+ "enUS": "Mailbox",
+ "jaJP": "メールボックス",
+ "koKR": "메일박스",
+ "ruRU": "Почтовый ящик",
+ "ptBR": "Caixa de correio",
+ "frFR": "Boîte aux lettres",
+ "esAR": "Buzón",
+ "arDZ": "صندوق البريد"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "请输入邮箱,用于接收证书颁发机构的邮件通知": {
+ "text": "请输入邮箱,用于接收证书颁发机构的邮件通知",
+ "key": "t_2_1745735773668",
+ "translations": {
+ "zhCN": "请输入邮箱,用于接收证书颁发机构的邮件通知",
+ "zhTW": "請輸入郵箱,用於接收證書頒發機構的郵件通知",
+ "enUS": "Please enter your email to receive notifications from the certificate authority",
+ "jaJP": "証明書発行機関からのメール通知を受け取るためにメールアドレスを入力してください",
+ "koKR": "인증 기관의 메일 알림을 수신할 이메일을 입력해 주세요",
+ "ruRU": "Введите адрес электронной почты для получения уведомлений от сертификационного органа",
+ "ptBR": "Digite seu e-mail para receber notificações da autoridade certificadora",
+ "frFR": "Veuillez saisir votre adresse e-mail pour recevoir les notifications de l'autorité de certification",
+ "esAR": "Ingrese su correo electrónico para recibir notificaciones de la autoridad certificadora",
+ "arDZ": "الرجاء إدخال البريد الإلكتروني لتلقي إشعارات من سلطة الشهادات"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "DNS提供商": {
+ "text": "DNS提供商",
+ "key": "t_3_1745735765112",
+ "translations": {
+ "zhCN": "DNS提供商",
+ "zhTW": "DNS提供商",
+ "enUS": "DNS provider",
+ "jaJP": "DNSプロバイダー",
+ "koKR": "DNS 제공자",
+ "ruRU": "Провайдер DNS",
+ "ptBR": "Provedor de DNS",
+ "frFR": "Fournisseur DNS",
+ "esAR": "Proveedor de DNS",
+ "arDZ": "موفر DNS"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "添加": {
+ "text": "添加",
+ "key": "t_4_1745735765372",
+ "translations": {
+ "zhCN": "添加",
+ "zhTW": "添加",
+ "enUS": "Add",
+ "jaJP": "追加",
+ "koKR": "추가",
+ "ruRU": "Добавить",
+ "ptBR": "Adicionar",
+ "frFR": "Ajouter",
+ "esAR": "Agregar",
+ "arDZ": "إضافة"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "续签间隔(天)": {
+ "text": "续签间隔(天)",
+ "key": "t_5_1745735769112",
+ "translations": {
+ "zhCN": "续签间隔(天)",
+ "zhTW": "續簽間隔(天)",
+ "enUS": "Renewal Interval (Days)",
+ "jaJP": "更新間隔 (日)",
+ "koKR": "갱신 간격 (일)",
+ "ruRU": "Интервал продления (дни)",
+ "ptBR": "Intervalo de Renovação (Dias)",
+ "frFR": "Intervalle de renouvellement (jours)",
+ "esAR": "Intervalo de Renovación (Días)",
+ "arDZ": "فترة التجديد (أيام)"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "续签间隔时间": {
+ "text": "续签间隔时间",
+ "key": "t_6_1745735765205",
+ "translations": {
+ "zhCN": "续签间隔时间",
+ "zhTW": "續簽間隔時間",
+ "enUS": "Renewal interval",
+ "jaJP": "更新間隔",
+ "koKR": "갱신 간격",
+ "ruRU": "Интервал продления",
+ "ptBR": "Intervalo de renovação",
+ "frFR": "Intervalle de renouvellement",
+ "esAR": "Intervalo de renovación",
+ "arDZ": "فترة التجديد"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "天,到期后自动续签": {
+ "text": "天,到期后自动续签",
+ "key": "t_7_1745735768326",
+ "translations": {
+ "zhCN": "天,到期后自动续签",
+ "zhTW": "天,到期後自動續簽",
+ "enUS": "day, automatically renewed upon expiration",
+ "jaJP": "日、期限切れ後に自動更新",
+ "koKR": "일, 만료 후 자동 갱신",
+ "ruRU": "дней, автоматически продлевается после истечения срока",
+ "ptBR": "dias, renovado automaticamente após o vencimento",
+ "frFR": "jour(s), renouvelé automatiquement à l'expiration",
+ "esAR": "días, se renueva automáticamente al vencimiento",
+ "arDZ": "يوم، يتم التجديد تلقائيًا عند الانتهاء"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "已配置": {
+ "text": "已配置",
+ "key": "t_8_1745735765753",
+ "translations": {
+ "zhCN": "已配置",
+ "zhTW": "已配置",
+ "enUS": "Configured",
+ "jaJP": "設定済み",
+ "koKR": "구성됨",
+ "ruRU": "Настроено",
+ "ptBR": "Configurado",
+ "frFR": "Configuré",
+ "esAR": "Configurado",
+ "arDZ": "تم التكوين"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "未配置": {
+ "text": "未配置",
+ "key": "t_9_1745735765287",
+ "translations": {
+ "zhCN": "未配置",
+ "zhTW": "未配置",
+ "enUS": "Not configured",
+ "jaJP": "未設定",
+ "koKR": "구성되지 않음",
+ "ruRU": "Не настроено",
+ "ptBR": "Não configurado",
+ "frFR": "Non configuré",
+ "esAR": "No configurado",
+ "arDZ": "غير مهيأ"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "宝塔面板": {
+ "text": "宝塔面板",
+ "key": "t_10_1745735765165",
+ "translations": {
+ "zhCN": "宝塔面板",
+ "zhTW": "寶塔面板",
+ "enUS": "Pagoda Panel",
+ "jaJP": "パゴダパネル",
+ "koKR": "파고다 패널",
+ "ruRU": "Панель Пагода",
+ "ptBR": "Painel Pagode",
+ "frFR": "Panneau Pagode",
+ "esAR": "Panel Pagoda",
+ "arDZ": "لوحة باغودة"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "宝塔面板网站": {
+ "text": "宝塔面板网站",
+ "key": "t_11_1745735766456",
+ "translations": {
+ "zhCN": "宝塔面板网站",
+ "zhTW": "寶塔面板網站",
+ "enUS": "Pagoda Panel Website",
+ "jaJP": "宝塔パネルのウェブサイト",
+ "koKR": "파고다 패널 웹사이트",
+ "ruRU": "Веб-сайт панели Pagoda",
+ "ptBR": "Site do Painel Pagoda",
+ "frFR": "Site Web du Panneau Pagode",
+ "esAR": "Sitio web del Panel Pagoda",
+ "arDZ": "موقع لوحة باغودا"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "1Panel面板": {
+ "text": "1Panel面板",
+ "key": "t_12_1745735765571",
+ "translations": {
+ "zhCN": "1Panel面板",
+ "zhTW": "1Panel面板",
+ "enUS": "1Panel",
+ "jaJP": "1Panelパネル",
+ "koKR": "1Panel 패널",
+ "ruRU": "Панель 1Panel",
+ "ptBR": "Painel 1Panel",
+ "frFR": "Panneau 1Panel",
+ "esAR": "Panel 1Panel",
+ "arDZ": "لوحة 1Panel"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "1Panel网站": {
+ "text": "1Panel网站",
+ "key": "t_13_1745735766084",
+ "translations": {
+ "zhCN": "1Panel网站",
+ "zhTW": "1Panel網站",
+ "enUS": "1Panel website",
+ "jaJP": "1Panelウェブサイト",
+ "koKR": "1Panel 웹사이트",
+ "ruRU": "1Panel веб-сайт",
+ "ptBR": "1Panel site",
+ "frFR": "1Panel site web",
+ "esAR": "1Panel sitio web",
+ "arDZ": "1Panel موقع إلكتروني"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "腾讯云CDN": {
+ "text": "腾讯云CDN",
+ "key": "t_14_1745735766121",
+ "translations": {
+ "zhCN": "腾讯云CDN",
+ "zhTW": "騰訊雲CDN",
+ "enUS": "Tencent Cloud CDN",
+ "jaJP": "Tencent Cloud CDN",
+ "koKR": "텐센트 클라우드 CDN",
+ "ruRU": "Tencent Cloud CDN",
+ "ptBR": "Tencent Cloud CDN",
+ "frFR": "Tencent Cloud CDN",
+ "esAR": "Tencent Cloud CDN",
+ "arDZ": "تنسنت كلاود CDN"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "腾讯云COS": {
+ "text": "腾讯云COS",
+ "key": "t_15_1745735768976",
+ "translations": {
+ "zhCN": "腾讯云COS",
+ "zhTW": "騰訊雲COS",
+ "enUS": "Tencent Cloud COS",
+ "jaJP": "Tencent Cloud COS",
+ "koKR": "텐센트 클라우드 COS",
+ "ruRU": "Tencent Cloud COS",
+ "ptBR": "Tencent Cloud COS",
+ "frFR": "Tencent Cloud COS",
+ "esAR": "Tencent Cloud COS",
+ "arDZ": "تنسنت كلاود كوس"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "阿里云CDN": {
+ "text": "阿里云CDN",
+ "key": "t_16_1745735766712",
+ "translations": {
+ "zhCN": "阿里云CDN",
+ "zhTW": "阿里雲CDN",
+ "enUS": "Alibaba Cloud CDN",
+ "jaJP": "阿里雲CDN",
+ "koKR": "알리바바 클라우드 CDN",
+ "ruRU": "Alibaba Cloud CDN",
+ "ptBR": "Alibaba Cloud CDN",
+ "frFR": "Alibaba Cloud CDN",
+ "esAR": "Alibaba Cloud CDN",
+ "arDZ": "ألي بابا كلاود CDN"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "部署类型": {
+ "text": "部署类型",
+ "key": "t_18_1745735765638",
+ "translations": {
+ "zhCN": "部署类型",
+ "zhTW": "部署類型",
+ "enUS": "Deployment Type",
+ "jaJP": "展開タイプ",
+ "koKR": "배포 유형",
+ "ruRU": "Тип развертывания",
+ "ptBR": "Tipo de Implantação",
+ "frFR": "Type de déploiement",
+ "esAR": "Tipo de despliegue",
+ "arDZ": "نوع النشر"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "请选择部署类型": {
+ "text": "请选择部署类型",
+ "key": "t_19_1745735766810",
+ "translations": {
+ "zhCN": "请选择部署类型",
+ "zhTW": "請選擇部署類型",
+ "enUS": "Please select deployment type",
+ "jaJP": "展開タイプを選択してください",
+ "koKR": "배포 유형을 선택하세요",
+ "ruRU": "Пожалуйста, выберите тип развертывания",
+ "ptBR": "Por favor, selecione o tipo de implantação",
+ "frFR": "Veuillez sélectionner le type de déploiement",
+ "esAR": "Por favor, seleccione el tipo de despliegue",
+ "arDZ": "يرجى اختيار نوع النشر"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "请输入部署路径": {
+ "text": "请输入部署路径",
+ "key": "t_20_1745735768764",
+ "translations": {
+ "zhCN": "请输入部署路径",
+ "enUS": "Please enter the deployment path",
+ "jaJP": "展開パスを入力してください",
+ "koKR": "배포 경로를 입력하십시오",
+ "ruRU": "Введите путь развертывания",
+ "ptBR": "Por favor, insira o caminho de implantação",
+ "frFR": "Veuillez entrer le chemin de déploiement",
+ "esAR": "Por favor, ingrese la ruta de despliegue",
+ "arDZ": "الرجاء إدخال مسار النشر",
+ "zhTW": "請輸入部署路徑"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "请输入前置命令": {
+ "text": "请输入前置命令",
+ "key": "t_21_1745735769154",
+ "translations": {
+ "zhCN": "请输入前置命令",
+ "zhTW": "請輸入前置命令",
+ "enUS": "Please enter the prefix command",
+ "jaJP": "前置コマンドを入力してください",
+ "koKR": "앞에 명령어를 입력하세요",
+ "ruRU": "Пожалуйста, введите префиксную команду",
+ "ptBR": "Por favor, insira o comando de prefixo",
+ "frFR": "Veuillez saisir la commande de préfixe",
+ "esAR": "Por favor, ingrese el comando de prefijo",
+ "arDZ": "الرجاء إدخال الأمر البادئة"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "请输入后置命令": {
+ "text": "请输入后置命令",
+ "key": "t_22_1745735767366",
+ "translations": {
+ "zhCN": "请输入后置命令",
+ "zhTW": "請輸入後置命令",
+ "enUS": "Please enter the post command",
+ "jaJP": "後置コマンドを入力してください",
+ "koKR": "후치 명령어를 입력하세요",
+ "ruRU": "Пожалуйста, введите пост-команду",
+ "ptBR": "Por favor, insira o comando pós",
+ "frFR": "Veuillez entrer la commande postérieure",
+ "esAR": "Por favor, ingrese el comando posterior",
+ "arDZ": "الرجاء إدخال الأمر اللاحق"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "请输入站点名称": {
+ "text": "请输入站点名称",
+ "key": "t_23_1745735766455",
+ "translations": {
+ "zhCN": "请输入站点名称",
+ "zhTW": "請輸入站點名稱",
+ "enUS": "Please enter the site name",
+ "jaJP": "サイト名を入力してください",
+ "koKR": "사이트 이름을 입력하세요",
+ "ruRU": "Пожалуйста, введите название сайта",
+ "ptBR": "Por favor, insira o nome do site",
+ "frFR": "Veuillez entrer le nom du site",
+ "esAR": "Por favor, ingrese el nombre del sitio",
+ "arDZ": "الرجاء إدخال اسم الموقع"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "请输入站点ID": {
+ "text": "请输入站点ID",
+ "key": "t_24_1745735766826",
+ "translations": {
+ "zhCN": "请输入站点ID",
+ "zhTW": "請輸入站點ID",
+ "enUS": "Please enter the site ID",
+ "jaJP": "サイトIDを入力してください",
+ "koKR": "사이트 ID를 입력하십시오",
+ "ruRU": "Введите идентификатор сайта",
+ "ptBR": "Por favor, insira o ID do site",
+ "frFR": "Veuillez entrer l'ID du site",
+ "esAR": "Por favor ingrese el ID del sitio",
+ "arDZ": "يرجى إدخال معرف الموقع"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "请输入区域": {
+ "text": "请输入区域",
+ "key": "t_25_1745735766651",
+ "translations": {
+ "zhCN": "请输入区域",
+ "zhTW": "請輸入區域",
+ "enUS": "Please enter the region",
+ "jaJP": "地域を入力してください",
+ "koKR": "지역을 입력하세요",
+ "ruRU": "Пожалуйста, введите регион",
+ "ptBR": "Por favor, insira a região",
+ "frFR": "Veuillez entrer la région",
+ "esAR": "Por favor, ingrese la región",
+ "arDZ": "الرجاء إدخال المنطقة"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "请输入存储桶": {
+ "text": "请输入存储桶",
+ "key": "t_26_1745735767144",
+ "translations": {
+ "zhCN": "请输入存储桶",
+ "zhTW": "請輸入儲存桶",
+ "enUS": "Please enter the bucket",
+ "jaJP": "バケットを入力してください",
+ "koKR": "버킷을 입력하세요",
+ "ruRU": "Пожалуйста, введите ведро",
+ "ptBR": "Por favor, insira o balde",
+ "frFR": "Veuillez entrer le seau",
+ "esAR": "Por favor ingrese el cubo",
+ "arDZ": "الرجاء إدخال الحاوية"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "下一步": {
+ "text": "下一步",
+ "key": "t_27_1745735764546",
+ "translations": {
+ "zhCN": "下一步",
+ "zhTW": "下一步",
+ "enUS": "Next step",
+ "jaJP": "次のステップ",
+ "koKR": "다음 단계",
+ "ruRU": "Следующий шаг",
+ "ptBR": "Próximo passo",
+ "frFR": "Étape suivante",
+ "esAR": "Próximo paso",
+ "arDZ": "الخطوة التالية"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "选择部署类型": {
+ "text": "选择部署类型",
+ "key": "t_28_1745735766626",
+ "translations": {
+ "zhCN": "选择部署类型",
+ "zhTW": "選擇部署類型",
+ "enUS": "Select deployment type",
+ "jaJP": "展開タイプを選択",
+ "koKR": "배포 유형 선택",
+ "ruRU": "Выберите тип развертывания",
+ "ptBR": "Selecionar tipo de implantação",
+ "frFR": "Sélectionner le type de déploiement",
+ "esAR": "Seleccionar tipo de implementación",
+ "arDZ": "اختر نوع النشر"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "配置部署参数": {
+ "text": "配置部署参数",
+ "key": "t_29_1745735768933",
+ "translations": {
+ "zhCN": "配置部署参数",
+ "zhTW": "配置部署參數",
+ "enUS": "Configure deployment parameters",
+ "jaJP": "展開パラメータを設定する",
+ "koKR": "배포 매개변수 구성",
+ "ruRU": "Настройка параметров развертывания",
+ "ptBR": "Configurar parâmetros de implantação",
+ "frFR": "Configurer les paramètres de déploiement",
+ "esAR": "Configurar parámetros de despliegue",
+ "arDZ": "تكوين معلمات النشر"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "运行模式": {
+ "text": "运行模式",
+ "key": "t_30_1745735764748",
+ "translations": {
+ "zhCN": "运行模式",
+ "zhTW": "運行模式",
+ "enUS": "Operation mode",
+ "jaJP": "動作モード",
+ "koKR": "운영 모드",
+ "ruRU": "Режим работы",
+ "ptBR": "Modo de operação",
+ "frFR": "Mode de fonctionnement",
+ "esAR": "Modo de operación",
+ "arDZ": "وضع التشغيل"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "运行模式未配置": {
+ "text": "运行模式未配置",
+ "key": "t_31_1745735767891",
+ "translations": {
+ "zhCN": "运行模式未配置",
+ "zhTW": "運行模式未配置",
+ "enUS": "Operation mode not configured",
+ "jaJP": "動作モードが設定されていません",
+ "koKR": "운영 모드가 구성되지 않았습니다",
+ "ruRU": "Режим работы не настроен",
+ "ptBR": "Modo de operação não configurado",
+ "frFR": "Mode de fonctionnement non configuré",
+ "esAR": "Modo de operación no configurado",
+ "arDZ": "وضع التشغيل غير مُهيأ"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "运行周期未配置": {
+ "text": "运行周期未配置",
+ "key": "t_32_1745735767156",
+ "translations": {
+ "zhCN": "运行周期未配置",
+ "zhTW": "運行週期未配置",
+ "enUS": "Running cycle not configured",
+ "jaJP": "実行周期が設定されていません",
+ "koKR": "실행 주기가 구성되지 않았습니다",
+ "ruRU": "Цикл выполнения не настроен",
+ "ptBR": "Ciclo de execução não configurado",
+ "frFR": "Cycle d'exécution non configuré",
+ "esAR": "Ciclo de ejecución no configurado",
+ "arDZ": "دورة التشغيل غير مهيأة"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "运行时间未配置": {
+ "text": "运行时间未配置",
+ "key": "t_33_1745735766532",
+ "translations": {
+ "zhCN": "运行时间未配置",
+ "zhTW": "運行時間未配置",
+ "enUS": "Runtime not configured",
+ "jaJP": "実行時間が設定されていません",
+ "koKR": "실행 시간이 구성되지 않았습니다",
+ "ruRU": "Время выполнения не настроено",
+ "ptBR": "Tempo de execução não configurado",
+ "frFR": "Durée d'exécution non configurée",
+ "esAR": "Tiempo de ejecución no configurado",
+ "arDZ": "وقت التشغيل غير مضبوط"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "证书文件(PEM 格式)": {
+ "text": "证书文件(PEM 格式)",
+ "key": "t_34_1745735771147",
+ "translations": {
+ "zhCN": "证书文件(PEM 格式)",
+ "zhTW": "證書文件(PEM 格式)",
+ "enUS": "Certificate file (PEM format)",
+ "jaJP": "証明書ファイル(PEM形式)",
+ "koKR": "인증서 파일 (PEM 포맷)",
+ "ruRU": "Файл сертификата (формат PEM)",
+ "ptBR": "Arquivo de certificado (formato PEM)",
+ "frFR": "Fichier de certificat (format PEM)",
+ "esAR": "Archivo de certificado (formato PEM)",
+ "arDZ": "ملف الشهادة (تنسيق PEM)"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "请粘贴证书文件内容,例如:\\n-----BEGIN CERTIFICATE-----\\n...\\n-----END CERTIFICATE-----": {
+ "text": "请粘贴证书文件内容,例如:\\n-----BEGIN CERTIFICATE-----\\n...\\n-----END CERTIFICATE-----",
+ "key": "t_35_1745735781545",
+ "translations": {
+ "zhCN": "请粘贴证书文件内容,例如:\n-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
+ "zhTW": "請貼上證書文件內容,例如:\n-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
+ "enUS": "Please paste the certificate file content, for example:\n-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
+ "jaJP": "証明書ファイルの内容を貼り付けてください。例:\n-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
+ "koKR": "인증서 파일 내용을 붙여넣으세요, 예:\n-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
+ "ruRU": "Пожалуйста, вставьте содержимое файла сертификата, например:\n-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
+ "ptBR": "Por favor, cole o conteúdo do arquivo de certificado, por exemplo:\n-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
+ "frFR": "Veuillez coller le contenu du fichier de certificat, par exemple :\n-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
+ "esAR": "Por favor, pegue el contenido del archivo de certificado, por ejemplo:\n-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
+ "arDZ": "الرجاء لصق محتوى ملف الشهادة، على سبيل المثال:\n-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "私钥文件(KEY 格式)": {
+ "text": "私钥文件(KEY 格式)",
+ "key": "t_36_1745735769443",
+ "translations": {
+ "zhCN": "私钥文件(KEY 格式)",
+ "zhTW": "私鑰文件(KEY 格式)",
+ "enUS": "Private key file (KEY format)",
+ "jaJP": "秘密鍵ファイル(KEY 形式)",
+ "koKR": "개인 키 파일 (KEY 형식)",
+ "ruRU": "Файл закрытого ключа (формат KEY)",
+ "ptBR": "Arquivo de chave privada (formato KEY)",
+ "frFR": "Fichier de clé privée (format KEY)",
+ "esAR": "Archivo de clave privada (formato KEY)",
+ "arDZ": "ملف المفتاح الخاص (تنسيق KEY)"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "请粘贴私钥文件内容,例如:\\n-----BEGIN PRIVATE KEY-----\\n...\\n-----END PRIVATE KEY-----": {
+ "text": "请粘贴私钥文件内容,例如:\\n-----BEGIN PRIVATE KEY-----\\n...\\n-----END PRIVATE KEY-----",
+ "key": "t_37_1745735779980",
+ "translations": {
+ "zhCN": "请粘贴私钥文件内容,例如:\n-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
+ "zhTW": "請貼上私鑰文件內容,例如:\n-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
+ "enUS": "Please paste the private key file content, for example:\n-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
+ "jaJP": "秘密キーファイルの内容を貼り付けてください、例:\n-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
+ "koKR": "개인 키 파일 내용을 붙여넣으세요, 예:\n-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
+ "ruRU": "Вставьте содержимое файла закрытого ключа, например:\n-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
+ "ptBR": "Cole o conteúdo do arquivo de chave privada, por exemplo:\n-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
+ "frFR": "Collez le contenu du fichier de clé privée, par exemple:\n-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
+ "esAR": "Pega el contenido del archivo de clave privada, por ejemplo:\n-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
+ "arDZ": "الصق محتوى ملف المفتاح الخاص، على سبيل المثال:\n-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "证书私钥内容不能为空": {
+ "text": "证书私钥内容不能为空",
+ "key": "t_38_1745735769521",
+ "translations": {
+ "zhCN": "证书私钥内容不能为空",
+ "zhTW": "證書私鑰內容不能為空",
+ "enUS": "Certificate private key content cannot be empty",
+ "jaJP": "証明書の秘密鍵の内容は空にできません",
+ "koKR": "인증서 개인 키 내용은 비워둘 수 없습니다",
+ "ruRU": "Содержимое закрытого ключа сертификата не может быть пустым",
+ "ptBR": "O conteúdo da chave privada do certificado não pode estar vazio",
+ "frFR": "Le contenu de la clé privée du certificat ne peut pas être vide",
+ "esAR": "El contenido de la clave privada del certificado no puede estar vacío",
+ "arDZ": "محتوى المفتاح الخاص للشهادة لا يمكن أن يكون فارغًا"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "证书私钥格式不正确": {
+ "text": "证书私钥格式不正确",
+ "key": "t_39_1745735768565",
+ "translations": {
+ "zhCN": "证书私钥格式不正确",
+ "zhTW": "證書私鑰格式不正確",
+ "enUS": "The format of the certificate private key is incorrect",
+ "jaJP": "証明書の秘密鍵の形式が正しくありません",
+ "koKR": "인증서 개인 키 형식이 올바르지 않습니다",
+ "ruRU": "Неверный формат закрытого ключа сертификата",
+ "ptBR": "O formato da chave privada do certificado está incorreto",
+ "frFR": "Le format de la clé privée du certificat est incorrect",
+ "esAR": "El formato de la clave privada del certificado es incorrecto",
+ "arDZ": "تنسيق مفتاح الشهادة الخاص غير صحيح"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "证书内容不能为空": {
+ "text": "证书内容不能为空",
+ "key": "t_40_1745735815317",
+ "translations": {
+ "zhCN": "证书内容不能为空",
+ "zhTW": "證書內容不能為空",
+ "enUS": "Certificate content cannot be empty",
+ "jaJP": "証明書の内容は空にできません",
+ "koKR": "인증서 내용은 비울 수 없습니다",
+ "ruRU": "Содержимое сертификата не может быть пустым",
+ "ptBR": "O conteúdo do certificado não pode estar vazio",
+ "frFR": "Le contenu du certificat ne peut pas être vide",
+ "esAR": "El contenido del certificado no puede estar vacío",
+ "arDZ": "محتوى الشهادة لا يمكن أن يكون فارغا"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "证书格式不正确": {
+ "text": "证书格式不正确",
+ "key": "t_41_1745735767016",
+ "translations": {
+ "zhCN": "证书格式不正确",
+ "zhTW": "證書格式不正確",
+ "enUS": "Certificate format is incorrect",
+ "jaJP": "証明書の形式が正しくありません",
+ "koKR": "인증서 형식이 올바르지 않습니다",
+ "ruRU": "Неправильный формат сертификата",
+ "ptBR": "Formato do certificado incorreto",
+ "frFR": "Format du certificat incorrect",
+ "esAR": "Formato de certificado incorrecto",
+ "arDZ": "تنسيق الشهادة غير صحيح"
+ },
+ "timestamp": "2025-04-27T06:36:55.318Z"
+ },
+ "上一步": {
+ "text": "上一步",
+ "key": "t_0_1745738961258",
+ "translations": {
+ "zhCN": "上一步",
+ "zhTW": "上一步",
+ "enUS": "Previous",
+ "jaJP": "前へ",
+ "koKR": "이전",
+ "ruRU": "Назад",
+ "ptBR": "Anterior",
+ "frFR": "Précédent",
+ "esAR": "Anterior",
+ "arDZ": "السابق"
+ },
+ "timestamp": "2025-04-27T07:29:29.879Z"
+ },
+ "提交": {
+ "text": "提交",
+ "key": "t_1_1745738963744",
+ "translations": {
+ "zhCN": "提交",
+ "zhTW": "提交",
+ "enUS": "Submit",
+ "jaJP": "提出",
+ "koKR": "제출",
+ "ruRU": "Отправить",
+ "ptBR": "Enviar",
+ "frFR": "Soumettre",
+ "esAR": "Enviar",
+ "arDZ": "إرسال"
+ },
+ "timestamp": "2025-04-27T07:29:29.881Z"
+ },
+ "配置部署参数,类型决定参数配置": {
+ "text": "配置部署参数,类型决定参数配置",
+ "key": "t_2_1745738969878",
+ "translations": {
+ "zhCN": "配置部署参数,类型决定参数配置",
+ "zhTW": "配置部署參數,類型決定參數配置",
+ "enUS": "Configure deployment parameters, the type determines the parameter configuration",
+ "jaJP": "展開パラメータを設定し、タイプによってパラメータの設定が決まる",
+ "koKR": "배포 매개변수 구성, 유형이 매개변수 구성을 결정함",
+ "ruRU": "Настройка параметров развертывания, тип определяет конфигурацию параметров",
+ "ptBR": "Configurar parâmetros de implantação, o tipo determina a configuração do parâmetro",
+ "frFR": "Configurer les paramètres de déploiement, le type détermine la configuration des paramètres",
+ "esAR": "Configurar parámetros de despliegue, el tipo determina la configuración de parámetros",
+ "arDZ": "تكوين معلمات النشر، النوع يحدد تكوين المعلمة"
+ },
+ "timestamp": "2025-04-27T07:29:29.881Z"
+ },
+ "部署设备来源": {
+ "text": "部署设备来源",
+ "key": "t_0_1745744491696",
+ "translations": {
+ "zhCN": "部署设备来源",
+ "zhTW": "部署設備來源",
+ "enUS": "Deployment device source",
+ "jaJP": "展開デバイスのソース",
+ "koKR": "배포 장치 소스",
+ "ruRU": "Источник устройства развертывания",
+ "ptBR": "Fonte do dispositivo de implantação",
+ "frFR": "Source de l'appareil de déploiement",
+ "esAR": "Fuente del dispositivo de implementación",
+ "arDZ": "مصدر جهاز النشر"
+ },
+ "timestamp": "2025-04-27T09:01:35.813Z"
+ },
+ "请选择部署设备来源": {
+ "text": "请选择部署设备来源",
+ "key": "t_1_1745744495019",
+ "translations": {
+ "zhCN": "请选择部署设备来源",
+ "zhTW": "請選擇部署設備來源",
+ "enUS": "Please select the deployment device source",
+ "jaJP": "展開デバイスのソースを選んでください",
+ "koKR": "배포 장치 소스를 선택하십시오",
+ "ruRU": "Пожалуйста, выберите источник устройства развертывания",
+ "ptBR": "Selecione a fonte do dispositivo de implantação",
+ "frFR": "Veuillez sélectionner la source de l'appareil de déploiement",
+ "esAR": "Por favor seleccione la fuente del dispositivo de despliegue",
+ "arDZ": "الرجاء اختيار مصدر جهاز التوزيع"
+ },
+ "timestamp": "2025-04-27T09:01:35.813Z"
+ },
+ "请选择部署类型后,点击下一步": {
+ "text": "请选择部署类型后,点击下一步",
+ "key": "t_2_1745744495813",
+ "translations": {
+ "zhCN": "请选择部署类型后,点击下一步",
+ "zhTW": "請選擇部署類型後,點擊下一步",
+ "enUS": "Please select the deployment type and click Next",
+ "jaJP": "展開タイプを選択して、次へをクリックしてください",
+ "koKR": "배포 유형을 선택하고 다음을 클릭하십시오",
+ "ruRU": "Пожалуйста, выберите тип развертывания и нажмите Далее",
+ "ptBR": "Por favor, selecione o tipo de implantação e clique em Avançar",
+ "frFR": "Veuillez sélectionner le type de déploiement et cliquer sur Suivant",
+ "esAR": "Por favor, seleccione el tipo de implementación y haga clic en Siguiente",
+ "arDZ": "الرجاء اختيار نوع النشر والنقر فوق التالي"
+ },
+ "timestamp": "2025-04-27T09:01:35.813Z"
+ },
+ "部署来源": {
+ "text": "部署来源",
+ "key": "t_0_1745744902975",
+ "translations": {
+ "zhCN": "部署来源",
+ "zhTW": "部署來源",
+ "enUS": "Deployment source",
+ "jaJP": "デプロイソース",
+ "koKR": "배포 소스",
+ "ruRU": "Источник развертывания",
+ "ptBR": "Fonte de implantação",
+ "frFR": "Source de déploiement",
+ "esAR": "Fuente de implementación",
+ "arDZ": "مصدر النشر"
+ },
+ "timestamp": "2025-04-27T09:08:25.566Z"
+ },
+ "请选择部署来源": {
+ "text": "请选择部署来源",
+ "key": "t_1_1745744905566",
+ "translations": {
+ "zhCN": "请选择部署来源",
+ "zhTW": "請選擇部署來源",
+ "enUS": "Please select deployment source",
+ "jaJP": "デプロイソースを選択してください",
+ "koKR": "배포 소스를 선택하세요",
+ "ruRU": "Выберите источник развертывания",
+ "ptBR": "Selecione a fonte de implantação",
+ "frFR": "Veuillez sélectionner la source de déploiement",
+ "esAR": "Seleccione la fuente de despliegue",
+ "arDZ": "الرجاء اختيار مصدر النشر"
+ },
+ "timestamp": "2025-04-27T09:08:25.568Z"
+ },
+ "添加更多设备": {
+ "text": "添加更多设备",
+ "key": "t_2_1745744903722",
+ "translations": {
+ "zhCN": "添加更多设备",
+ "zhTW": "新增更多設備",
+ "enUS": "Add more devices",
+ "jaJP": "さらにデバイスを追加",
+ "koKR": "더 많은 기기 추가",
+ "ruRU": "Добавить больше устройств",
+ "ptBR": "Adicionar mais dispositivos",
+ "frFR": "Ajouter plus d'appareils",
+ "esAR": "Agregar más dispositivos",
+ "arDZ": "إضافة المزيد من الأجهزة"
+ },
+ "timestamp": "2025-04-27T09:08:25.568Z"
+ },
+ "添加部署来源": {
+ "text": "添加部署来源",
+ "key": "t_0_1745748292337",
+ "translations": {
+ "zhCN": "添加部署来源",
+ "zhTW": "添加部署來源",
+ "enUS": "Add deployment source",
+ "jaJP": "デプロイソースの追加",
+ "koKR": "배포 소스 추가",
+ "ruRU": "Добавить источник развертывания",
+ "ptBR": "Adicionar fonte de implantação",
+ "frFR": "Ajouter une source de déploiement",
+ "esAR": "Agregar fuente de despliegue",
+ "arDZ": "إضافة مصدر النشر"
+ },
+ "timestamp": "2025-04-27T10:04:58.903Z"
+ },
+ "证书来源": {
+ "text": "证书来源",
+ "key": "t_1_1745748290291",
+ "translations": {
+ "zhCN": "证书来源",
+ "zhTW": "證書來源",
+ "enUS": "Certificate Source",
+ "jaJP": "証明書の出所",
+ "koKR": "인증서 출처",
+ "ruRU": "Источник сертификата",
+ "ptBR": "Fonte do Certificado",
+ "frFR": "Source du certificat",
+ "esAR": "Fuente del certificado",
+ "arDZ": "مصدر الشهادة"
+ },
+ "timestamp": "2025-04-27T10:04:58.904Z"
+ },
+ "当前类型部署来源为空,请先添加部署来源": {
+ "text": "当前类型部署来源为空,请先添加部署来源",
+ "key": "t_2_1745748298902",
+ "translations": {
+ "zhCN": "当前类型部署来源为空,请先添加部署来源",
+ "zhTW": "當前類型部署來源為空,請先添加部署來源",
+ "enUS": "The current type deployment source is empty, please add a deployment source first",
+ "jaJP": "現在のタイプのデプロイソースが空です、デプロイソースを追加してください",
+ "koKR": "현재 유형의 배포 소스가 비어 있습니다. 배포 소스를 먼저 추가하십시오",
+ "ruRU": "Источник развертывания текущего типа пуст, сначала добавьте источник развертывания",
+ "ptBR": "A origem da implantação do tipo atual está vazia, adicione uma origem de implantação primeiro",
+ "frFR": "La source de déploiement du type actuel est vide, veuillez d'abord ajouter une source de déploiement",
+ "esAR": "La fuente de implementación del tipo actual está vacía, agregue una fuente de implementación primero",
+ "arDZ": "مصدر النشر للنوع الحالي فارغ، يرجى إضافة مصدر نشر أولاً"
+ },
+ "timestamp": "2025-04-27T10:04:58.904Z"
+ },
+ "当前流程中没有申请节点,请先添加申请节点": {
+ "text": "当前流程中没有申请节点,请先添加申请节点",
+ "key": "t_3_1745748298161",
+ "translations": {
+ "zhCN": "当前流程中没有申请节点,请先添加申请节点",
+ "zhTW": "當前流程中沒有申請節點,請先添加申請節點",
+ "enUS": "There is no application node in the current process, please add an application node first",
+ "jaJP": "現在のプロセスには申請ノードがありません、まず申請ノードを追加してください",
+ "koKR": "현재 프로세스에 신청 노드가 없습니다. 먼저 신청 노드를 추가하세요",
+ "ruRU": "В текущем процессе нет узла заявки, пожалуйста, сначала добавьте узел заявки",
+ "ptBR": "Não há nó de aplicação no processo atual, por favor, adicione um nó de aplicação primeiro",
+ "frFR": "Il n'y a pas de nœud de demande dans le processus actuel, veuillez d'abord ajouter un nœud de demande",
+ "esAR": "No hay ningún nodo de solicitud en el proceso actual, por favor agregue un nodo de solicitud primero",
+ "arDZ": "لا توجد عقدة طلب في العملية الحالية، يرجى إضافة عقدة طلب أولاً"
+ },
+ "timestamp": "2025-04-27T10:04:58.904Z"
+ },
+ "提交内容": {
+ "text": "提交内容",
+ "key": "t_4_1745748290292",
+ "translations": {
+ "zhCN": "提交内容",
+ "zhTW": "提交內容",
+ "enUS": "Submit content",
+ "jaJP": "提出内容",
+ "koKR": "제출 내용",
+ "ruRU": "Отправить содержание",
+ "ptBR": "Enviar conteúdo",
+ "frFR": "Soumettre le contenu",
+ "esAR": "Enviar contenido",
+ "arDZ": "إرسال المحتوى"
+ },
+ "timestamp": "2025-04-27T10:04:58.904Z"
+ },
+ "点击编辑工作流标题": {
+ "text": "点击编辑工作流标题",
+ "key": "t_0_1745765864788",
+ "translations": {
+ "zhCN": "点击编辑工作流标题",
+ "zhTW": "點擊編輯工作流程標題",
+ "enUS": "Click to edit workflow title",
+ "jaJP": "ワークフロータイトルを編集するにはクリックします",
+ "koKR": "작업 흐름 제목 편집을 클릭하세요",
+ "ruRU": "Нажмите, чтобы редактировать заголовок рабочего процесса",
+ "ptBR": "Clique para editar o título do fluxo de trabalho",
+ "frFR": "Cliquez pour modifier le titre du flux de travail",
+ "esAR": "Haz clic para editar el título del flujo de trabajo",
+ "arDZ": "انقر لتحرير عنوان سير العمل"
+ },
+ "timestamp": "2025-04-27T14:58:40.953Z"
+ },
+ "删除节点-【{name}】": {
+ "text": "删除节点-【{name}】",
+ "key": "t_1_1745765875247",
+ "translations": {
+ "zhCN": "删除节点-【{name}】",
+ "zhTW": "刪除節點-【{name}】",
+ "enUS": "Delete Node - 【{name}】",
+ "jaJP": "ノード削除 - 【{name}】",
+ "koKR": "노드 삭제 - 【{name}】",
+ "ruRU": "Удалить узел - 【{name}】",
+ "ptBR": "Excluir Nó - 【{name}】",
+ "frFR": "Supprimer le nœud - 【{name}】",
+ "esAR": "Eliminar Nodo - 【{name}】",
+ "arDZ": "حذف العقدة - 【{name}】"
+ },
+ "timestamp": "2025-04-27T14:58:40.954Z"
+ },
+ "当前节点存在子节点,删除后会影响其他节点,是否确认删除?": {
+ "text": "当前节点存在子节点,删除后会影响其他节点,是否确认删除?",
+ "key": "t_2_1745765875918",
+ "translations": {
+ "zhCN": "当前节点存在子节点,删除后会影响其他节点,是否确认删除?",
+ "zhTW": "當前節點存在子節點,刪除後會影響其他節點,是否確認刪除?",
+ "enUS": "The current node has child nodes. Deleting it will affect other nodes. Are you sure you want to delete it?",
+ "jaJP": "現在のノードには子ノードが存在します。削除すると他のノードに影響を与えます。削除してもよろしいですか?",
+ "koKR": "현재 노드에 하위 노드가 존재합니다. 삭제하면 다른 노드에 영향을 미치게 됩니다. 삭제하시겠습니까?",
+ "ruRU": "Текущий узел имеет дочерние узлы. Удаление повлияет на другие узлы. Вы уверены, что хотите удалить?",
+ "ptBR": "O nó atual possui nós filhos. A exclusão afetará outros nós. Tem certeza de que deseja excluir?",
+ "frFR": "Le nœud actuel contient des nœuds enfants. La suppression affectera d'autres nœuds. Confirmez-vous la suppression ?",
+ "esAR": "El nodo actual tiene nodos hijos. Eliminarlo afectará a otros nodos. ¿Está seguro de que desea eliminarlo?",
+ "arDZ": "العقدة الحالية تحتوي على عقد فرعية. حذفها سيؤثر على عقد أخرى. هل أنت متأكد أنك تريد الحذف؟"
+ },
+ "timestamp": "2025-04-27T14:58:40.954Z"
+ },
+ "当前节点存在配置数据,是否确认删除?": {
+ "text": "当前节点存在配置数据,是否确认删除?",
+ "key": "t_3_1745765920953",
+ "translations": {
+ "zhCN": "当前节点存在配置数据,是否确认删除?",
+ "zhTW": "目前節點存在配置數據,是否確認刪除?",
+ "enUS": "The current node has configuration data, are you sure you want to delete it?",
+ "jaJP": "現在のノードには設定データがあります。削除してもよろしいですか?",
+ "koKR": "현재 노드에 구성 데이터가 있습니다. 삭제하시겠습니까?",
+ "ruRU": "Текущий узел содержит данные конфигурации, вы уверены, что хотите их удалить?",
+ "ptBR": "O nó atual possui dados de configuração, tem certeza que deseja excluí-lo?",
+ "frFR": "Le nœud actuel contient des données de configuration, êtes-vous sûr de vouloir le supprimer ?",
+ "esAR": "El nodo actual tiene datos de configuración, ¿está seguro de que desea eliminarlo?",
+ "arDZ": "العقدة الحالية تحتوي على بيانات التكوين، هل أنت متأكد أنك تريد حذفها؟"
+ },
+ "timestamp": "2025-04-27T14:58:40.954Z"
+ },
+ "请选择部署类型后,在进行下一步": {
+ "text": "请选择部署类型后,在进行下一步",
+ "key": "t_4_1745765868807",
+ "translations": {
+ "zhCN": "请选择部署类型后,再进行下一步",
+ "zhTW": "請選擇部署類型後,再進行下一步",
+ "enUS": "Please select the deployment type before proceeding to the next step",
+ "jaJP": "デプロイメントタイプを選択してから、次に進んでください",
+ "koKR": "배포 유형을 선택한 후 다음 단계로 진행하십시오",
+ "ruRU": "Пожалуйста, выберите тип развертывания, прежде чем перейти к следующему шагу",
+ "ptBR": "Por favor, selecione o tipo de implantação antes de prosseguir para a próxima etapa",
+ "frFR": "Veuillez sélectionner le type de déploiement avant de passer à l'étape suivante",
+ "esAR": "Por favor, seleccione el tipo de implementación antes de continuar con el siguiente paso",
+ "arDZ": "الرجاء تحديد نوع النشر قبل المتابعة إلى الخطوة التالية"
+ },
+ "timestamp": "2025-04-27T14:58:40.954Z"
+ },
+ "请选择类型": {
+ "text": "请选择类型",
+ "key": "t_0_1745833934390",
+ "translations": {
+ "zhCN": "请选择类型",
+ "zhTW": "請選擇類型",
+ "enUS": "Please select type",
+ "jaJP": "タイプを選択してください",
+ "koKR": "유형을 선택하십시오",
+ "ruRU": "Пожалуйста, выберите тип",
+ "ptBR": "Por favor, selecione o tipo",
+ "frFR": "Veuillez sélectionner le type",
+ "esAR": "Por favor, seleccione el tipo",
+ "arDZ": "يرجى اختيار النوع"
+ },
+ "timestamp": "2025-04-28T09:52:23.713Z"
+ },
+ "主机": {
+ "text": "主机",
+ "key": "t_1_1745833931535",
+ "translations": {
+ "zhCN": "主机",
+ "zhTW": "主機",
+ "enUS": "Host",
+ "jaJP": "ホスト",
+ "koKR": "호스트",
+ "ruRU": "Хост",
+ "ptBR": "Host",
+ "frFR": "Hôte",
+ "esAR": "Host",
+ "arDZ": "مضيف"
+ },
+ "timestamp": "2025-04-28T09:52:23.715Z"
+ },
+ "端口": {
+ "text": "端口",
+ "key": "t_2_1745833931404",
+ "translations": {
+ "zhCN": "端口",
+ "zhTW": "埠",
+ "enUS": "port",
+ "jaJP": "ポート",
+ "koKR": "포트",
+ "ruRU": "порт",
+ "ptBR": "porta",
+ "frFR": "port",
+ "esAR": "puerto",
+ "arDZ": "منفذ"
+ },
+ "timestamp": "2025-04-28T09:52:23.715Z"
+ },
+ "获取首页概览数据失败": {
+ "text": "获取首页概览数据失败",
+ "key": "t_3_1745833936770",
+ "translations": {
+ "zhCN": "获取首页概览数据失败",
+ "zhTW": "獲取首頁概覽數據失敗",
+ "enUS": "Failed to get homepage overview data",
+ "jaJP": "ホームページの概要データの取得に失敗しました",
+ "koKR": "홈페이지 개요 데이터 가져오기 실패",
+ "ruRU": "Не удалось получить обзорные данные главной страницы",
+ "ptBR": "Falha ao obter dados de visão geral da página inicial",
+ "frFR": "Échec de la récupération des données de vue d'ensemble de la page d'accueil",
+ "esAR": "Error al obtener los datos de vista general de la página de inicio",
+ "arDZ": "فشل في الحصول على بيانات نظرة عامة على الصفحة الرئيسية"
+ },
+ "timestamp": "2025-04-28T09:52:23.715Z"
+ },
+ "版本信息": {
+ "text": "版本信息",
+ "key": "t_4_1745833932780",
+ "translations": {
+ "zhCN": "版本信息",
+ "zhTW": "版本資訊",
+ "enUS": "Version information",
+ "jaJP": "バージョン情報",
+ "koKR": "버전 정보",
+ "ruRU": "Информация о версии",
+ "ptBR": "Informações da versão",
+ "frFR": "Information de version",
+ "esAR": "Información de versión",
+ "arDZ": "معلومات النسخة"
+ },
+ "timestamp": "2025-04-28T09:52:23.715Z"
+ },
+ "当前版本": {
+ "text": "当前版本",
+ "key": "t_5_1745833933241",
+ "translations": {
+ "zhCN": "当前版本",
+ "zhTW": "目前版本",
+ "enUS": "Current version",
+ "jaJP": "現在のバージョン",
+ "koKR": "현재 버전",
+ "ruRU": "Текущая версия",
+ "ptBR": "Versão atual",
+ "frFR": "Version actuelle",
+ "esAR": "Versión actual",
+ "arDZ": "الإصدار الحالي"
+ },
+ "timestamp": "2025-04-28T09:52:23.715Z"
+ },
+ "更新方式": {
+ "text": "更新方式",
+ "key": "t_6_1745833933523",
+ "translations": {
+ "zhCN": "更新方式",
+ "zhTW": "更新方式",
+ "enUS": "Update method",
+ "jaJP": "更新方法",
+ "koKR": "업데이트 방법",
+ "ruRU": "Метод обновления",
+ "ptBR": "Método de atualização",
+ "frFR": "Méthode de mise à jour",
+ "esAR": "Método de actualización",
+ "arDZ": "طريقة التحديث"
+ },
+ "timestamp": "2025-04-28T09:52:23.715Z"
+ },
+ "最新版本": {
+ "text": "最新版本",
+ "key": "t_7_1745833933278",
+ "translations": {
+ "zhCN": "最新版本",
+ "zhTW": "最新版本",
+ "enUS": "Latest version",
+ "jaJP": "最新バージョン",
+ "koKR": "최신 버전",
+ "ruRU": "Последняя версия",
+ "ptBR": "Última versão",
+ "frFR": "Dernière version",
+ "esAR": "Última versión",
+ "arDZ": "أحدث إصدار"
+ },
+ "timestamp": "2025-04-28T09:52:23.715Z"
+ },
+ "更新日志": {
+ "text": "更新日志",
+ "key": "t_8_1745833933552",
+ "translations": {
+ "zhCN": "更新日志",
+ "zhTW": "更新日誌",
+ "enUS": "Changelog",
+ "jaJP": "更新履歴",
+ "koKR": "업데이트 로그",
+ "ruRU": "История изменений",
+ "ptBR": "Registro de alterações",
+ "frFR": "Journal des modifications",
+ "esAR": "Registro de cambios",
+ "arDZ": "سجل التغييرات"
+ },
+ "timestamp": "2025-04-28T09:52:23.715Z"
+ },
+ "客服二维码": {
+ "text": "客服二维码",
+ "key": "t_9_1745833935269",
+ "translations": {
+ "zhCN": "客服二维码",
+ "zhTW": "客服二維碼",
+ "enUS": "Customer Service QR Code",
+ "jaJP": "カスタマーサービスQRコード",
+ "koKR": "고객 서비스 QR 코드",
+ "ruRU": "QR-код службы поддержки",
+ "ptBR": "Código QR do Atendimento ao Cliente",
+ "frFR": "Code QR du Service Client",
+ "esAR": "Código QR de Servicio al Cliente",
+ "arDZ": "رمز QR لخدمة العملاء"
+ },
+ "timestamp": "2025-04-28T09:52:23.715Z"
+ },
+ "扫码添加客服": {
+ "text": "扫码添加客服",
+ "key": "t_10_1745833941691",
+ "translations": {
+ "zhCN": "扫码添加客服",
+ "zhTW": "掃碼添加客服",
+ "enUS": "Scan the QR code to add customer service",
+ "jaJP": "QRコードをスキャンしてカスタマーサービスを追加",
+ "koKR": "QR 코드를 스캔하여 고객 서비스 추가",
+ "ruRU": "Сканируйте QR-код, чтобы добавить службу поддержки",
+ "ptBR": "Escaneie o código QR para adicionar atendimento ao cliente",
+ "frFR": "Scannez le code QR pour ajouter le service client",
+ "esAR": "Escanee el código QR para agregar servicio al cliente",
+ "arDZ": "امسح رمز QR لإضافة خدمة العملاء"
+ },
+ "timestamp": "2025-04-28T09:52:23.715Z"
+ },
+ "微信公众号": {
+ "text": "微信公众号",
+ "key": "t_11_1745833935261",
+ "translations": {
+ "zhCN": "微信公众号",
+ "zhTW": "微信公眾號",
+ "enUS": "WeChat Official Account",
+ "jaJP": "WeChat公式アカウント",
+ "koKR": "위챗 공식 계정",
+ "ruRU": "Официальный аккаунт WeChat",
+ "ptBR": "Conta Oficial do WeChat",
+ "frFR": "Compte officiel WeChat",
+ "esAR": "Cuenta Oficial de WeChat",
+ "arDZ": "حساب وي تشات الرسمي"
+ },
+ "timestamp": "2025-04-28T09:52:23.715Z"
+ },
+ "扫码关注微信公众号": {
+ "text": "扫码关注微信公众号",
+ "key": "t_12_1745833943712",
+ "translations": {
+ "zhCN": "扫码关注微信公众号",
+ "zhTW": "掃碼關注微信公眾號",
+ "enUS": "Scan to follow the WeChat official account",
+ "jaJP": "QRコードをスキャンしてWeChat公式アカウントをフォロー",
+ "koKR": "QR 코드를 스캔하여 WeChat 공식 계정 팔로우",
+ "ruRU": "Сканируйте QR-код, чтобы подписаться на официальный аккаунт WeChat",
+ "ptBR": "Escaneie para seguir a conta oficial do WeChat",
+ "frFR": "Scannez pour suivre le compte officiel WeChat",
+ "esAR": "Escanea para seguir la cuenta oficial de WeChat",
+ "arDZ": "امسح الكود الضوئي لمتابعة الحساب الرسمي على WeChat"
+ },
+ "timestamp": "2025-04-28T09:52:23.715Z"
+ },
+ "关于产品": {
+ "text": "关于产品",
+ "key": "t_13_1745833933630",
+ "translations": {
+ "zhCN": "关于产品",
+ "zhTW": "關於產品",
+ "enUS": "About the product",
+ "jaJP": "製品について",
+ "koKR": "제품 정보",
+ "ruRU": "О продукте",
+ "ptBR": "Sobre o produto",
+ "frFR": "À propos du produit",
+ "esAR": "Acerca del producto",
+ "arDZ": "حول المنتج"
+ },
+ "timestamp": "2025-04-28T09:52:23.715Z"
+ },
+ "SMTP服务器": {
+ "text": "SMTP服务器",
+ "key": "t_14_1745833932440",
+ "translations": {
+ "zhCN": "SMTP服务器",
+ "zhTW": "SMTP伺服器",
+ "enUS": "SMTP server",
+ "jaJP": "SMTPサーバー",
+ "koKR": "SMTP 서버",
+ "ruRU": "SMTP сервер",
+ "ptBR": "Servidor SMTP",
+ "frFR": "Serveur SMTP",
+ "esAR": "Servidor SMTP",
+ "arDZ": "خادم SMTP"
+ },
+ "timestamp": "2025-04-28T09:52:23.715Z"
+ },
+ "请输入SMTP服务器": {
+ "text": "请输入SMTP服务器",
+ "key": "t_15_1745833940280",
+ "translations": {
+ "zhCN": "请输入SMTP服务器",
+ "zhTW": "請輸入SMTP伺服器",
+ "enUS": "Please enter the SMTP server",
+ "jaJP": "SMTPサーバーを入力してください",
+ "koKR": "SMTP 서버를 입력하세요",
+ "ruRU": "Пожалуйста, введите SMTP сервер",
+ "ptBR": "Por favor, insira o servidor SMTP",
+ "frFR": "Veuillez entrer le serveur SMTP",
+ "esAR": "Por favor, ingrese el servidor SMTP",
+ "arDZ": "الرجاء إدخال خادم SMTP"
+ },
+ "timestamp": "2025-04-28T09:52:23.715Z"
+ },
+ "SMTP端口": {
+ "text": "SMTP端口",
+ "key": "t_16_1745833933819",
+ "translations": {
+ "zhCN": "SMTP端口",
+ "zhTW": "SMTP埠",
+ "enUS": "SMTP port",
+ "jaJP": "SMTPポート",
+ "koKR": "SMTP 포트",
+ "ruRU": "SMTP порт",
+ "ptBR": "Porta SMTP",
+ "frFR": "Port SMTP",
+ "esAR": "Puerto SMTP",
+ "arDZ": "منفذ SMTP"
+ },
+ "timestamp": "2025-04-28T09:52:23.715Z"
+ },
+ "请输入SMTP端口": {
+ "text": "请输入SMTP端口",
+ "key": "t_17_1745833935070",
+ "translations": {
+ "zhCN": "请输入SMTP端口",
+ "zhTW": "請輸入SMTP端口",
+ "enUS": "Please enter the SMTP port",
+ "jaJP": "SMTPポートを入力してください",
+ "koKR": "SMTP 포트를 입력하세요",
+ "ruRU": "Введите порт SMTP",
+ "ptBR": "Por favor, insira a porta SMTP",
+ "frFR": "Veuillez entrer le port SMTP",
+ "esAR": "Por favor, ingrese el puerto SMTP",
+ "arDZ": "الرجاء إدخال منفذ SMTP"
+ },
+ "timestamp": "2025-04-28T09:52:23.715Z"
+ },
+ "SSL/TLS连接": {
+ "text": "SSL/TLS连接",
+ "key": "t_18_1745833933989",
+ "translations": {
+ "zhCN": "SSL/TLS连接",
+ "zhTW": "SSL/TLS連接",
+ "enUS": "SSL/TLS connection",
+ "jaJP": "SSL/TLS接続",
+ "koKR": "SSL/TLS 연결",
+ "ruRU": "SSL/TLS соединение",
+ "ptBR": "Conexão SSL/TLS",
+ "frFR": "Connexion SSL/TLS",
+ "esAR": "Conexión SSL/TLS",
+ "arDZ": "اتصال SSL/TLS"
+ },
+ "timestamp": "2025-04-28T09:52:23.715Z"
+ },
+ "请选择消息通知": {
+ "text": "请选择消息通知",
+ "key": "t_0_1745887835267",
+ "translations": {
+ "zhCN": "请选择消息通知",
+ "enUS": "Please select message notification",
+ "jaJP": "メッセージ通知を選択してください",
+ "koKR": "메시지 알림을 선택하세요",
+ "ruRU": "Пожалуйста, выберите уведомление о сообщении",
+ "ptBR": "Por favor, selecione notificação de mensagem",
+ "frFR": "Veuillez sélectionner la notification de message",
+ "esAR": "Por favor, seleccione notificación de mensaje",
+ "arDZ": "الرجاء اختيار إشعار الرسالة"
+ },
+ "timestamp": "2025-04-29T00:50:35.267Z"
+ },
+ "消息通知": {
+ "text": "消息通知",
+ "key": "t_1_1745887832941",
+ "translations": {
+ "zhCN": "消息通知",
+ "zhTW": "訊息通知",
+ "enUS": "Notification",
+ "jaJP": "通知",
+ "koKR": "알림",
+ "ruRU": "Уведомление",
+ "ptBR": "Notificação",
+ "frFR": "Notification",
+ "esAR": "Notificación",
+ "arDZ": "إشعار"
+ },
+ "timestamp": "2025-04-29T00:50:35.268Z"
+ },
+ "添加通知渠道": {
+ "text": "添加通知渠道",
+ "key": "t_2_1745887834248",
+ "translations": {
+ "zhCN": "添加通知渠道",
+ "zhTW": "新增通知渠道",
+ "enUS": "Add notification channel",
+ "jaJP": "通知チャネルを追加",
+ "koKR": "알림 채널 추가",
+ "ruRU": "Добавить канал уведомлений",
+ "ptBR": "Adicionar canal de notificação",
+ "frFR": "Ajouter un canal de notification",
+ "esAR": "Agregar canal de notificación",
+ "arDZ": "إضافة قناة إشعار"
+ },
+ "timestamp": "2025-04-29T00:50:35.268Z"
+ },
+ "请输入通知主题": {
+ "text": "请输入通知主题",
+ "key": "t_3_1745887835089",
+ "translations": {
+ "zhCN": "请输入通知主题",
+ "zhTW": "請輸入通知主題",
+ "enUS": "Please enter the notification subject",
+ "jaJP": "通知の件名を入力してください",
+ "koKR": "알림 제목을 입력하세요",
+ "ruRU": "Введите тему уведомления",
+ "ptBR": "Digite o assunto da notificação",
+ "frFR": "Veuillez saisir le sujet de la notification",
+ "esAR": "Ingrese el asunto de la notificación",
+ "arDZ": "الرجاء إدخال موضوع الإشعار"
+ },
+ "timestamp": "2025-04-29T00:50:35.268Z"
+ },
+ "请输入通知内容": {
+ "text": "请输入通知内容",
+ "key": "t_4_1745887835265",
+ "translations": {
+ "zhCN": "请输入通知内容",
+ "zhTW": "請輸入通知內容",
+ "enUS": "Please enter the notification content",
+ "jaJP": "通知内容を入力してください",
+ "koKR": "알림 내용을 입력하세요",
+ "ruRU": "Введите содержание уведомления",
+ "ptBR": "Por favor, insira o conteúdo da notificação",
+ "frFR": "Veuillez saisir le contenu de la notification",
+ "esAR": "Por favor ingrese el contenido de la notificación",
+ "arDZ": "يرجى إدخال محتوى الإشعار"
+ },
+ "timestamp": "2025-04-29T00:50:35.268Z"
+ },
+ "修改邮箱通知配置": {
+ "text": "修改邮箱通知配置",
+ "key": "t_0_1745895057404",
+ "translations": {
+ "zhCN": "修改邮箱通知配置",
+ "zhTW": "修改郵箱通知配置",
+ "enUS": "Modify email notification settings",
+ "jaJP": "メール通知設定の変更",
+ "koKR": "이메일 알림 설정 수정",
+ "ruRU": "Изменение настроек уведомлений по электронной почте",
+ "ptBR": "Modificar configurações de notificação por e-mail",
+ "frFR": "Modifier les paramètres de notification par e-mail",
+ "esAR": "Modificar configuración de notificaciones por correo electrónico",
+ "arDZ": "تعديل إعدادات الإشعارات عبر البريد الإلكتروني"
+ },
+ "timestamp": "2025-04-29T02:50:57.404Z"
+ },
+ "通知主题": {
+ "text": "通知主题",
+ "key": "t_0_1745920566646",
+ "translations": {
+ "zhCN": "通知主题",
+ "zhTW": "通知主題",
+ "enUS": "Notification Subject",
+ "jaJP": "通知主題",
+ "koKR": "공지 주제",
+ "ruRU": "Тема уведомления",
+ "ptBR": "Assunto da Notificação",
+ "frFR": "Sujet de la notification",
+ "esAR": "Asunto de la notificación",
+ "arDZ": "موضوع الإشعار"
+ },
+ "timestamp": "2025-04-29T09:56:07.200Z"
+ },
+ "通知内容": {
+ "text": "通知内容",
+ "key": "t_1_1745920567200",
+ "translations": {
+ "zhCN": "通知内容",
+ "zhTW": "通知內容",
+ "enUS": "Notification content",
+ "jaJP": "通知内容",
+ "koKR": "공지 내용",
+ "ruRU": "Содержание уведомления",
+ "ptBR": "Conteúdo da notificação",
+ "frFR": "Contenu de la notification",
+ "esAR": "Contenido de la notificación",
+ "arDZ": "محتوى الإخطار"
+ },
+ "timestamp": "2025-04-29T09:56:07.200Z"
+ },
+ "点击获取验证码": {
+ "text": "点击获取验证码",
+ "key": "t_0_1745936396853",
+ "translations": {
+ "zhCN": "点击获取验证码",
+ "zhTW": "點擊獲取驗證碼",
+ "enUS": "Click to get verification code",
+ "jaJP": "確認コードを取得するにはクリックしてください",
+ "koKR": "인증 코드 받기",
+ "ruRU": "Нажмите, чтобы получить код подтверждения",
+ "ptBR": "Clique para obter o código de verificação",
+ "frFR": "Cliquez pour obtenir le code de vérification",
+ "esAR": "Haz clic para obtener el código de verificación",
+ "arDZ": "انقر للحصول على رمز التحقق"
+ },
+ "timestamp": "2025-04-29T14:19:56.853Z"
+ },
+ "剩余{days}天": {
+ "text": "剩余{days}天",
+ "key": "t_0_1745999035681",
+ "translations": {
+ "zhCN": "剩余{days}天",
+ "zhTW": "剩餘{days}天",
+ "enUS": "remaining {days} days",
+ "jaJP": "残り{days}日",
+ "koKR": "남은 {days}일",
+ "ruRU": "осталось {days} дней",
+ "ptBR": "faltam {days} dias",
+ "frFR": "il reste {days} jours",
+ "esAR": "faltan {days} días",
+ "arDZ": "باقي {days} يوم"
+ },
+ "timestamp": "2025-04-30T07:43:56.289Z"
+ },
+ "即将到期{days}天": {
+ "text": "即将到期{days}天",
+ "key": "t_1_1745999036289",
+ "translations": {
+ "zhCN": "即将到期{days}天",
+ "zhTW": "即將到期{days}天",
+ "enUS": "Expiring soon {days} days",
+ "jaJP": "まもなく期限切れ {days} 日",
+ "koKR": "곧 만료됩니다 {days} 일",
+ "ruRU": "Скоро истекает срок действия {days} дней",
+ "ptBR": "Expirando em breve {days} dias",
+ "frFR": "Expiration prochaine {days} jours",
+ "esAR": "Próximo a vencer {days} días",
+ "arDZ": "قريباً تنتهي الصلاحية {days} يوم"
+ },
+ "timestamp": "2025-04-30T07:43:56.291Z"
+ },
+ "已过期": {
+ "text": "已过期",
+ "key": "t_0_1746000517848",
+ "translations": {
+ "zhCN": "已过期",
+ "zhTW": "已過期",
+ "enUS": "Expired",
+ "jaJP": "期限切れ",
+ "koKR": "만료됨",
+ "ruRU": "Истек срок",
+ "ptBR": "Expirado",
+ "frFR": "Expiré",
+ "esAR": "Caducado",
+ "arDZ": "منتهي الصلاحية"
+ },
+ "timestamp": "2025-04-30T08:08:37.848Z"
+ },
+ "已到期": {
+ "text": "已到期",
+ "key": "t_0_1746001199409",
+ "translations": {
+ "zhCN": "已到期",
+ "zhTW": "已到期",
+ "enUS": "Expired",
+ "jaJP": "期限切れ",
+ "koKR": "만료됨",
+ "ruRU": "Истекший",
+ "ptBR": "Expirado",
+ "frFR": "Expiré",
+ "esAR": "Expirado",
+ "arDZ": "انتهت الصلاحية"
+ },
+ "timestamp": "2025-04-30T08:19:59.409Z"
+ },
+ "DNS提供商为空": {
+ "text": "DNS提供商为空",
+ "key": "t_0_1746004861782",
+ "translations": {
+ "zhCN": "DNS提供商为空",
+ "zhTW": "DNS提供商為空",
+ "enUS": "DNS provider is empty",
+ "jaJP": "DNSプロバイダーが空です",
+ "koKR": "DNS 공급자가 비어 있습니다",
+ "ruRU": "DNS-провайдер пуст",
+ "ptBR": "Provedor DNS está vazio",
+ "frFR": "Le fournisseur DNS est vide",
+ "esAR": "El proveedor DNS está vacío",
+ "arDZ": "موفر DNS فارغ"
+ },
+ "timestamp": "2025-04-30T09:21:01.782Z"
+ },
+ "添加DNS提供商": {
+ "text": "添加DNS提供商",
+ "key": "t_1_1746004861166",
+ "translations": {
+ "zhCN": "添加DNS提供商",
+ "zhTW": "新增DNS供應商",
+ "enUS": "Add DNS provider",
+ "jaJP": "DNSプロバイダーを追加",
+ "koKR": "DNS 공급자 추가",
+ "ruRU": "Добавить DNS-провайдера",
+ "ptBR": "Adicionar provedor de DNS",
+ "frFR": "Ajouter un fournisseur DNS",
+ "esAR": "Agregar proveedor de DNS",
+ "arDZ": "إضافة مزود DNS"
+ },
+ "timestamp": "2025-04-30T09:21:01.782Z"
+ },
+ "刷新": {
+ "text": "刷新",
+ "key": "t_0_1746497662220",
+ "translations": {
+ "zhCN": "刷新",
+ "zhTW": "刷新",
+ "enUS": "Refresh",
+ "jaJP": "更新",
+ "koKR": "새로 고침",
+ "ruRU": "Обновить",
+ "ptBR": "Atualizar",
+ "frFR": "Rafraîchir",
+ "esAR": "Actualizar",
+ "arDZ": "تحديث"
+ },
+ "timestamp": "2025-05-06T02:14:22.220Z"
+ },
+ "运行中": {
+ "text": "运行中",
+ "key": "t_0_1746519384035",
+ "translations": {
+ "zhCN": "运行中",
+ "zhTW": "運行中",
+ "enUS": "Running",
+ "jaJP": "実行中",
+ "koKR": "실행 중",
+ "ruRU": "В работе",
+ "ptBR": "Em execução",
+ "frFR": "En cours",
+ "esAR": "En ejecución",
+ "arDZ": "قيد التشغيل"
+ },
+ "timestamp": "2025-05-06T08:16:24.035Z"
+ },
+ "执行历史详情": {
+ "text": "执行历史详情",
+ "key": "t_0_1746579648713",
+ "translations": {
+ "zhCN": "执行历史详情",
+ "zhTW": "執行歷史詳情",
+ "enUS": "Execution History Details",
+ "jaJP": "実行履歴の詳細",
+ "koKR": "실행 내역 상세 정보",
+ "ruRU": "Детали истории выполнения",
+ "ptBR": "Detalhes do Histórico de Execução",
+ "frFR": "Détails de l'historique d'exécution",
+ "esAR": "Detalles del Historial de Ejecución",
+ "arDZ": "تفاصيل سجل التنفيذ"
+ },
+ "timestamp": "2025-05-07T01:00:48.713Z"
+ },
+ "执行状态": {
+ "text": "执行状态",
+ "key": "t_0_1746590054456",
+ "translations": {
+ "zhCN": "执行状态",
+ "zhTW": "執行狀態",
+ "enUS": "Execution status",
+ "jaJP": "実行状態",
+ "koKR": "실행 상태",
+ "ruRU": "Статус выполнения",
+ "ptBR": "Status de execução",
+ "frFR": "État d'exécution",
+ "esAR": "Estado de ejecución",
+ "arDZ": "حالة التنفيذ"
+ },
+ "timestamp": "2025-05-07T03:54:20.448Z"
+ },
+ "触发方式": {
+ "text": "触发方式",
+ "key": "t_1_1746590060448",
+ "translations": {
+ "zhCN": "触发方式",
+ "zhTW": "觸發方式",
+ "enUS": "Trigger Method",
+ "jaJP": "トリガー方式",
+ "koKR": "트리거 방식",
+ "ruRU": "Способ активации",
+ "ptBR": "Método de Ativação",
+ "frFR": "Méthode de Déclenchement",
+ "esAR": "Método de Activación",
+ "arDZ": "طريقة التشغيل"
+ },
+ "timestamp": "2025-05-07T03:54:20.449Z"
+ },
+ "正在提交信息,请稍后...": {
+ "text": "正在提交信息,请稍后...",
+ "key": "t_0_1746667592819",
+ "translations": {
+ "zhCN": "正在提交信息,请稍后...",
+ "zhTW": "正在提交資訊,請稍後...",
+ "enUS": "Submitting information, please wait...",
+ "jaJP": "情報を送信中、少々お待ちください...",
+ "koKR": "정보를 제출 중입니다. 잠시 기다려주세요...",
+ "ruRU": "Отправка информации, пожалуйста, подождите...",
+ "ptBR": "Enviando informações, por favor aguarde...",
+ "frFR": "Soumission des informations en cours, veuillez patienter...",
+ "esAR": "Enviando información, por favor espere...",
+ "arDZ": "جاري تقديم المعلومات، يرجى الانتظار..."
+ },
+ "timestamp": "2025-05-08T01:26:39.218Z"
+ },
+ "密钥": {
+ "text": "密钥",
+ "key": "t_1_1746667588689",
+ "translations": {
+ "zhCN": "密钥",
+ "zhTW": "密鑰",
+ "enUS": "Key",
+ "jaJP": "キー",
+ "koKR": "키",
+ "ruRU": "Ключ",
+ "ptBR": "Chave",
+ "frFR": "Clé",
+ "esAR": "Clave",
+ "arDZ": "مفتاح"
+ },
+ "timestamp": "2025-05-08T01:26:39.219Z"
+ },
+ "面板URL": {
+ "text": "面板URL",
+ "key": "t_2_1746667592840",
+ "translations": {
+ "zhCN": "面板URL",
+ "zhTW": "面板URL",
+ "enUS": "Panel URL",
+ "jaJP": "パネルURL",
+ "koKR": "패널 URL",
+ "ruRU": "URL панели",
+ "ptBR": "URL do painel",
+ "frFR": "URL du panneau",
+ "esAR": "URL del panel",
+ "arDZ": "عنوان URL للوحة"
+ },
+ "timestamp": "2025-05-08T01:26:39.219Z"
+ },
+ "忽略 SSL/TLS证书错误": {
+ "text": "忽略 SSL/TLS证书错误",
+ "key": "t_3_1746667592270",
+ "translations": {
+ "zhCN": "忽略 SSL/TLS证书错误",
+ "zhTW": "忽略 SSL/TLS證書錯誤",
+ "enUS": "Ignore SSL/TLS certificate errors",
+ "jaJP": "SSL/TLS証明書のエラーを無視する",
+ "koKR": "SSL/TLS 인증서 오류 무시",
+ "ruRU": "Игнорировать ошибки SSL/TLS сертификатов",
+ "ptBR": "Ignorar erros de certificado SSL/TLS",
+ "frFR": "Ignorer les erreurs de certificat SSL/TLS",
+ "esAR": "Ignorar errores de certificado SSL/TLS",
+ "arDZ": "تجاهل أخطاء شهادة SSL/TLS"
+ },
+ "timestamp": "2025-05-08T01:26:39.219Z"
+ },
+ "表单验证失败": {
+ "text": "表单验证失败",
+ "key": "t_4_1746667590873",
+ "translations": {
+ "zhCN": "表单验证失败",
+ "zhTW": "表單驗證失敗",
+ "enUS": "Form validation failed",
+ "jaJP": "フォーム検証失敗",
+ "koKR": "양식 검증 실패",
+ "ruRU": "Проверка формы не удалась",
+ "ptBR": "Validação de formulário falhou",
+ "frFR": "Échec de la validation du formulaire",
+ "esAR": "Falló la validación del formulario",
+ "arDZ": "فشل التحقق من النموذج"
+ },
+ "timestamp": "2025-05-08T01:26:39.219Z"
+ },
+ "新建工作流": {
+ "text": "新建工作流",
+ "key": "t_5_1746667590676",
+ "translations": {
+ "zhCN": "新建工作流",
+ "zhTW": "新增工作流程",
+ "enUS": "New workflow",
+ "jaJP": "新しいワークフロー",
+ "koKR": "새 워크플로우",
+ "ruRU": "Новый рабочий процесс",
+ "ptBR": "Novo fluxo de trabalho",
+ "frFR": "Nouveau flux de travail",
+ "esAR": "Nuevo flujo de trabajo",
+ "arDZ": "سير عمل جديد"
+ },
+ "timestamp": "2025-05-08T01:26:39.219Z"
+ },
+ "正在提交申请,请稍后...": {
+ "text": "正在提交申请,请稍后...",
+ "key": "t_6_1746667592831",
+ "translations": {
+ "zhCN": "正在提交申请,请稍后...",
+ "zhTW": "正在提交申請,請稍後...",
+ "enUS": "Submitting application, please wait...",
+ "jaJP": "申請を提出しています、少々お待ちください...",
+ "koKR": "제출 중입니다. 잠시만 기다려 주세요...",
+ "ruRU": "Отправка заявки, пожалуйста, подождите...",
+ "ptBR": "Enviando aplicação, por favor aguarde...",
+ "frFR": "Soumission de la demande, veuillez patienter...",
+ "esAR": "Enviando aplicación, por favor espere...",
+ "arDZ": "جارٍ تقديم الطلب، يرجى الانتظار..."
+ },
+ "timestamp": "2025-05-08T01:26:39.219Z"
+ },
+ "请输入正确的域名": {
+ "text": "请输入正确的域名",
+ "key": "t_7_1746667592468",
+ "translations": {
+ "zhCN": "请输入正确的域名",
+ "zhTW": "請輸入正確的域名",
+ "enUS": "Please enter the correct domain name",
+ "jaJP": "正しいドメイン名を入力してください",
+ "koKR": "올바른 도메인 이름을 입력하세요",
+ "ruRU": "Пожалуйста, введите правильное доменное имя",
+ "ptBR": "Por favor, insira o nome de domínio correto",
+ "frFR": "Veuillez entrer le nom de domaine correct",
+ "esAR": "Por favor ingrese el nombre de dominio correcto",
+ "arDZ": "يرجى إدخال اسم النطاق الصحيح"
+ },
+ "timestamp": "2025-05-08T01:26:39.219Z"
+ },
+ "请选择解析方式": {
+ "text": "请选择解析方式",
+ "key": "t_8_1746667591924",
+ "translations": {
+ "zhCN": "请选择解析方式",
+ "zhTW": "請選擇解析方式",
+ "enUS": "Please select the parsing method",
+ "jaJP": "解析方法を選択してください",
+ "koKR": "파싱 방법을 선택하세요",
+ "ruRU": "Пожалуйста, выберите метод анализа",
+ "ptBR": "Por favor, selecione o método de análise",
+ "frFR": "Veuillez sélectionner la méthode d'analyse",
+ "esAR": "Por favor, seleccione el método de análisis",
+ "arDZ": "يرجى اختيار طريقة التحليل"
+ },
+ "timestamp": "2025-05-08T01:26:39.219Z"
+ },
+ "刷新列表": {
+ "text": "刷新列表",
+ "key": "t_9_1746667589516",
+ "translations": {
+ "zhCN": "刷新列表",
+ "zhTW": "刷新列表",
+ "enUS": "Refresh list",
+ "jaJP": "リストを更新",
+ "koKR": "목록 새로 고침",
+ "ruRU": "Обновить список",
+ "ptBR": "Atualizar lista",
+ "frFR": "Actualiser la liste",
+ "esAR": "Actualizar lista",
+ "arDZ": "تحديث القائمة"
+ },
+ "timestamp": "2025-05-08T01:26:39.219Z"
+ },
+ "通配符": {
+ "text": "通配符",
+ "key": "t_10_1746667589575",
+ "translations": {
+ "zhCN": "通配符",
+ "zhTW": "通配符",
+ "enUS": "Wildcard",
+ "jaJP": "ワイルドカード",
+ "koKR": "와일드카드",
+ "ruRU": "Подстановочный знак",
+ "ptBR": "Curinga",
+ "frFR": "Joker",
+ "esAR": "Comodín",
+ "arDZ": "حرف بدل"
+ },
+ "timestamp": "2025-05-08T01:26:39.219Z"
+ },
+ "多域名": {
+ "text": "多域名",
+ "key": "t_11_1746667589598",
+ "translations": {
+ "zhCN": "多域名",
+ "zhTW": "多域名",
+ "enUS": "Multi-domain",
+ "jaJP": "マルチドメイン",
+ "koKR": "멀티 도메인",
+ "ruRU": "Мультидомен",
+ "ptBR": "Multidomínio",
+ "frFR": "Multi-domaine",
+ "esAR": "Multidominio",
+ "arDZ": "متعدد النطاقات"
+ },
+ "timestamp": "2025-05-08T01:26:39.219Z"
+ },
+ "热门": {
+ "text": "热门",
+ "key": "t_12_1746667589733",
+ "translations": {
+ "zhCN": "热门",
+ "zhTW": "熱門",
+ "enUS": "Popular",
+ "jaJP": "人気",
+ "koKR": "인기",
+ "ruRU": "Популярные",
+ "ptBR": "Popular",
+ "frFR": "Populaire",
+ "esAR": "Popular",
+ "arDZ": "شائع"
+ },
+ "timestamp": "2025-05-08T01:26:39.219Z"
+ },
+ "是广泛使用的免费SSL证书提供商,适合个人网站和测试环境。": {
+ "text": "是广泛使用的免费SSL证书提供商,适合个人网站和测试环境。",
+ "key": "t_13_1746667599218",
+ "translations": {
+ "zhCN": "是广泛使用的免费SSL证书提供商,适合个人网站和测试环境。",
+ "zhTW": "是廣泛使用的免費SSL證書提供商,適合個人網站和測試環境。",
+ "enUS": "is a widely used free SSL certificate provider, suitable for personal websites and testing environments.",
+ "jaJP": "広く使用されている無料のSSL証明書プロバイダーで、個人のウェブサイトやテスト環境に適しています。",
+ "koKR": "개인 웹사이트 및 테스트 환경에 적합한 널리 사용되는 무료 SSL 인증서 제공업체입니다.",
+ "ruRU": "широко используемый бесплатный провайдер SSL-сертификатов, подходящий для личных веб-сайтов и тестовых сред.",
+ "ptBR": "é um fornecedor de certificados SSL gratuito amplamente utilizado, adequado para sites pessoais e ambientes de teste.",
+ "frFR": "est un fournisseur de certificats SSL gratuits largement utilisé, adapté aux sites personnels et aux environnements de test.",
+ "esAR": "es un proveedor de certificados SSL gratuito ampliamente utilizado, adecuado para sitios web personales y entornos de prueba.",
+ "arDZ": "هو موفر شهادات SSL مجاني مستخدم على نطاق واسع، مناسب للمواقع الشخصية وبيئات الاختبار."
+ },
+ "timestamp": "2025-05-08T01:26:39.219Z"
+ },
+ "支持域名数": {
+ "text": "支持域名数",
+ "key": "t_14_1746667590827",
+ "translations": {
+ "zhCN": "支持域名数",
+ "zhTW": "支持域名數",
+ "enUS": "Number of supported domains",
+ "jaJP": "サポートされているドメインの数",
+ "koKR": "지원되는 도메인 수",
+ "ruRU": "Количество поддерживаемых доменов",
+ "ptBR": "Número de domínios suportados",
+ "frFR": "Nombre de domaines pris en charge",
+ "esAR": "Número de dominios soportados",
+ "arDZ": "عدد النطاقات المدعومة"
+ },
+ "timestamp": "2025-05-08T01:26:39.219Z"
+ },
+ "个": {
+ "text": "个",
+ "key": "t_15_1746667588493",
+ "translations": {
+ "zhCN": "个",
+ "zhTW": "個",
+ "enUS": "piece",
+ "jaJP": "個",
+ "koKR": "개",
+ "ruRU": "штука",
+ "ptBR": "peça",
+ "frFR": "pièce",
+ "esAR": "pieza",
+ "arDZ": "قطعة"
+ },
+ "timestamp": "2025-05-08T01:26:39.219Z"
+ },
+ "支持通配符": {
+ "text": "支持通配符",
+ "key": "t_16_1746667591069",
+ "translations": {
+ "zhCN": "支持通配符",
+ "zhTW": "支援萬用字元",
+ "enUS": "Support wildcards",
+ "jaJP": "ワイルドカードをサポート",
+ "koKR": "와일드카드 지원",
+ "ruRU": "Поддержка подстановочных знаков",
+ "ptBR": "Suporte a curingas",
+ "frFR": "Prise en charge des caractères génériques",
+ "esAR": "Compatibilidad con caracteres comodín",
+ "arDZ": "دعم أحرف البدل"
+ },
+ "timestamp": "2025-05-08T01:26:39.219Z"
+ },
+ "支持": {
+ "text": "支持",
+ "key": "t_17_1746667588785",
+ "translations": {
+ "zhCN": "支持",
+ "zhTW": "支持",
+ "enUS": "support",
+ "jaJP": "サポート",
+ "koKR": "지원",
+ "ruRU": "поддержка",
+ "ptBR": "suporte",
+ "frFR": "soutien",
+ "esAR": "apoyo",
+ "arDZ": "دعم"
+ },
+ "timestamp": "2025-05-08T01:26:39.219Z"
+ },
+ "不支持": {
+ "text": "不支持",
+ "key": "t_18_1746667590113",
+ "translations": {
+ "zhCN": "不支持",
+ "zhTW": "不支援",
+ "enUS": "Not supported",
+ "jaJP": "サポートされていません",
+ "koKR": "지원되지 않음",
+ "ruRU": "Не поддерживается",
+ "ptBR": "Não suportado",
+ "frFR": "Non pris en charge",
+ "esAR": "No soportado",
+ "arDZ": "غير مدعوم"
+ },
+ "timestamp": "2025-05-08T01:26:39.219Z"
+ },
+ "有效期": {
+ "text": "有效期",
+ "key": "t_19_1746667589295",
+ "translations": {
+ "zhCN": "有效期",
+ "zhTW": "有效期",
+ "enUS": "Validity period",
+ "jaJP": "有効期間",
+ "koKR": "유효 기간",
+ "ruRU": "Срок действия",
+ "ptBR": "Validade",
+ "frFR": "Période de validité",
+ "esAR": "Período de validez",
+ "arDZ": "فترة الصلاحية"
+ },
+ "timestamp": "2025-05-08T01:26:39.219Z"
+ },
+ "天": {
+ "text": "天",
+ "key": "t_20_1746667588453",
+ "translations": {
+ "zhCN": "天",
+ "zhTW": "天",
+ "enUS": "Day",
+ "jaJP": "天",
+ "koKR": "하늘",
+ "ruRU": "день",
+ "ptBR": "dia",
+ "frFR": "jour",
+ "esAR": "día",
+ "arDZ": "يوم"
+ },
+ "timestamp": "2025-05-08T01:26:39.219Z"
+ },
+ "支持小程序": {
+ "text": "支持小程序",
+ "key": "t_21_1746667590834",
+ "translations": {
+ "zhCN": "支持小程序",
+ "zhTW": "支援小程式",
+ "enUS": "Support Mini Program",
+ "jaJP": "ミニプログラムをサポート",
+ "koKR": "미니프로그램 지원",
+ "ruRU": "Поддержка мини-программ",
+ "ptBR": "Suporte para Mini Programas",
+ "frFR": "Prise en charge des mini-programmes",
+ "esAR": "Soporte para Mini Programas",
+ "arDZ": "دعم البرامج الصغيرة"
+ },
+ "timestamp": "2025-05-08T01:26:39.219Z"
+ },
+ "适用网站": {
+ "text": "适用网站",
+ "key": "t_22_1746667591024",
+ "translations": {
+ "zhCN": "适用网站",
+ "zhTW": "適用網站",
+ "enUS": "Applicable websites",
+ "jaJP": "対応サイト",
+ "koKR": "적용 가능한 웹사이트",
+ "ruRU": "Применимые веб-сайты",
+ "ptBR": "Sites aplicáveis",
+ "frFR": "Sites applicables",
+ "esAR": "Sitios aplicables",
+ "arDZ": "المواقع المطبقة"
+ },
+ "timestamp": "2025-05-08T01:26:39.219Z"
+ },
+ "*.example.com、*.demo.com": {
+ "text": "*.example.com、*.demo.com",
+ "key": "t_23_1746667591989",
+ "translations": {
+ "zhCN": "*.example.com、*.demo.com",
+ "zhTW": "*.example.com、*.demo.com",
+ "enUS": "*.example.com, *.demo.com",
+ "jaJP": "*.example.com、*.demo.com",
+ "koKR": "*.example.com, *.demo.com",
+ "ruRU": "*.example.com, *.demo.com",
+ "ptBR": "*.example.com, *.demo.com",
+ "frFR": "*.example.com, *.demo.com",
+ "esAR": "*.example.com, *.demo.com",
+ "arDZ": "*.example.com، *.demo.com"
+ },
+ "timestamp": "2025-05-08T01:26:39.219Z"
+ },
+ "*.example.com": {
+ "text": "*.example.com",
+ "key": "t_24_1746667583520",
+ "translations": {
+ "zhCN": "*.example.com",
+ "zhTW": "*.example.com",
+ "enUS": "*.example.com",
+ "jaJP": "*.example.com",
+ "koKR": "*.example.com",
+ "ruRU": "*.example.com",
+ "ptBR": "*.example.com",
+ "frFR": "*.example.com",
+ "esAR": "*.example.com",
+ "arDZ": "*.example.com"
+ },
+ "timestamp": "2025-05-08T01:26:39.219Z"
+ },
+ "example.com、demo.com": {
+ "text": "example.com、demo.com",
+ "key": "t_25_1746667590147",
+ "translations": {
+ "zhCN": "example.com、demo.com",
+ "zhTW": "example.com、demo.com",
+ "enUS": "example.com、demo.com",
+ "jaJP": "example.com、demo.com",
+ "koKR": "example.com、demo.com",
+ "ruRU": "example.com、demo.com",
+ "ptBR": "example.com、demo.com",
+ "frFR": "example.com、demo.com",
+ "esAR": "example.com、demo.com",
+ "arDZ": "example.com、demo.com"
+ },
+ "timestamp": "2025-05-08T01:26:39.219Z"
+ },
+ "www.example.com、example.com": {
+ "text": "www.example.com、example.com",
+ "key": "t_26_1746667594662",
+ "translations": {
+ "zhCN": "www.example.com、example.com",
+ "zhTW": "www.example.com、example.com",
+ "enUS": "www.example.com, example.com",
+ "jaJP": "www.example.com、example.com",
+ "koKR": "www.example.com, example.com",
+ "ruRU": "www.example.com, example.com",
+ "ptBR": "www.example.com, example.com",
+ "frFR": "www.example.com, example.com",
+ "esAR": "www.example.com, example.com",
+ "arDZ": "www.example.com، example.com"
+ },
+ "timestamp": "2025-05-08T01:26:39.219Z"
+ },
+ "免费": {
+ "text": "免费",
+ "key": "t_27_1746667589350",
+ "translations": {
+ "zhCN": "免费",
+ "zhTW": "免費",
+ "enUS": "Free",
+ "jaJP": "無料",
+ "koKR": "무료",
+ "ruRU": "Бесплатно",
+ "ptBR": "Grátis",
+ "frFR": "Gratuit",
+ "esAR": "Gratis",
+ "arDZ": "مجاني"
+ },
+ "timestamp": "2025-05-08T01:26:39.219Z"
+ },
+ "立即申请": {
+ "text": "立即申请",
+ "key": "t_28_1746667590336",
+ "translations": {
+ "zhCN": "立即申请",
+ "zhTW": "立即申請",
+ "enUS": "Apply Now",
+ "jaJP": "今すぐ申し込む",
+ "koKR": "지금 신청하기",
+ "ruRU": "Подать заявку сейчас",
+ "ptBR": "Aplicar agora",
+ "frFR": "Postuler maintenant",
+ "esAR": "Aplicar ahora",
+ "arDZ": "تقديم الآن"
+ },
+ "timestamp": "2025-05-08T01:26:39.219Z"
+ },
+ "项目地址": {
+ "text": "项目地址",
+ "key": "t_29_1746667589773",
+ "translations": {
+ "zhCN": "项目地址",
+ "zhTW": "專案地址",
+ "enUS": "Project address",
+ "jaJP": "プロジェクトアドレス",
+ "koKR": "프로젝트 주소",
+ "ruRU": "Адрес проекта",
+ "ptBR": "Endereço do projeto",
+ "frFR": "Adresse du projet",
+ "esAR": "Dirección del proyecto",
+ "arDZ": "عنوان المشروع"
+ },
+ "timestamp": "2025-05-08T01:26:39.219Z"
+ },
+ "请输入证书文件路径": {
+ "text": "请输入证书文件路径",
+ "key": "t_30_1746667591892",
+ "translations": {
+ "zhCN": "请输入证书文件路径",
+ "zhTW": "請輸入憑證檔案路徑",
+ "enUS": "Please enter the certificate file path",
+ "jaJP": "証明書ファイルのパスを入力してください",
+ "koKR": "인증서 파일 경로를 입력하세요",
+ "ruRU": "Введите путь к файлу сертификата",
+ "ptBR": "Digite o caminho do arquivo de certificado",
+ "frFR": "Veuillez entrer le chemin du fichier de certificat",
+ "esAR": "Ingrese la ruta del archivo de certificado",
+ "arDZ": "الرجاء إدخال مسار ملف الشهادة"
+ },
+ "timestamp": "2025-05-08T01:26:39.219Z"
+ },
+ "请输入私钥文件路径": {
+ "text": "请输入私钥文件路径",
+ "key": "t_31_1746667593074",
+ "translations": {
+ "zhCN": "请输入私钥文件路径",
+ "zhTW": "請輸入私鑰文件路徑",
+ "enUS": "Please enter the private key file path",
+ "jaJP": "秘密鍵ファイルのパスを入力してください",
+ "koKR": "개인 키 파일 경로를 입력하세요",
+ "ruRU": "Введите путь к файлу закрытого ключа",
+ "ptBR": "Digite o caminho do arquivo de chave privada",
+ "frFR": "Veuillez entrer le chemin du fichier de clé privée",
+ "esAR": "Ingrese la ruta del archivo de clave privada",
+ "arDZ": "الرجاء إدخال مسار ملف المفتاح الخاص"
+ },
+ "timestamp": "2025-05-08T01:26:39.219Z"
+ },
+ "当前DNS提供商为空,请先添加DNS提供商": {
+ "text": "当前DNS提供商为空,请先添加DNS提供商",
+ "key": "t_0_1746673515941",
+ "translations": {
+ "zhCN": "当前DNS提供商为空,请先添加DNS提供商",
+ "zhTW": "當前DNS提供商為空,請先添加DNS提供商",
+ "enUS": "The current DNS provider is empty, please add a DNS provider first",
+ "jaJP": "現在のDNSプロバイダーが空です。まずDNSプロバイダーを追加してください",
+ "koKR": "현재 DNS 공급자가 비어 있습니다. 먼저 DNS 공급자를 추가하세요",
+ "ruRU": "Текущий DNS-провайдер отсутствует, сначала добавьте DNS-провайдера",
+ "ptBR": "O provedor de DNS atual está vazio, adicione um provedor de DNS primeiro",
+ "frFR": "Le fournisseur DNS actuel est vide, veuillez d'abord ajouter un fournisseur DNS",
+ "esAR": "El proveedor de DNS actual está vacío, por favor agregue un proveedor de DNS primero",
+ "arDZ": "موفر DNS الحالي فارغ، يرجى إضافة موفر DNS أولاً"
+ },
+ "timestamp": "2025-05-08T03:05:15.942Z"
+ },
+ "测试通知发送失败": {
+ "text": "测试通知发送失败",
+ "key": "t_0_1746676862189",
+ "translations": {
+ "zhCN": "测试通知发送失败",
+ "zhTW": "測試通知發送失敗",
+ "enUS": "Test notification sending failed",
+ "jaJP": "テスト通知の送信に失敗しました",
+ "koKR": "테스트 알림 전송 실패",
+ "ruRU": "Не удалось отправить тестовое уведомление",
+ "ptBR": "Falha no envio da notificação de teste",
+ "frFR": "Échec de l'envoi de la notification de test",
+ "esAR": "Error en el envío de notificación de prueba",
+ "arDZ": "فشل إرسال إشعار الاختبار"
+ },
+ "timestamp": "2025-05-08T04:01:02.329Z"
+ },
+ "添加配置": {
+ "text": "添加配置",
+ "key": "t_1_1746676859550",
+ "translations": {
+ "zhCN": "添加配置",
+ "zhTW": "新增配置",
+ "enUS": "Add Configuration",
+ "jaJP": "設定を追加",
+ "koKR": "구성 추가",
+ "ruRU": "Добавить конфигурацию",
+ "ptBR": "Adicionar Configuração",
+ "frFR": "Ajouter une Configuration",
+ "esAR": "Agregar Configuración",
+ "arDZ": "إضافة تكوين"
+ },
+ "timestamp": "2025-05-08T04:01:02.331Z"
+ },
+ "暂未支持": {
+ "text": "暂未支持",
+ "key": "t_2_1746676856700",
+ "translations": {
+ "zhCN": "暂未支持",
+ "zhTW": "暫不支持",
+ "enUS": "Not supported yet",
+ "jaJP": "まだサポートされていません",
+ "koKR": "아직 지원되지 않음",
+ "ruRU": "Пока не поддерживается",
+ "ptBR": "Ainda não suportado",
+ "frFR": "Pas encore pris en charge",
+ "esAR": "Aún no compatible",
+ "arDZ": "غير مدعوم بعد"
+ },
+ "timestamp": "2025-05-08T04:01:02.331Z"
+ },
+ "邮件通知": {
+ "text": "邮件通知",
+ "key": "t_3_1746676857930",
+ "translations": {
+ "zhCN": "邮件通知",
+ "zhTW": "郵件通知",
+ "enUS": "Email notification",
+ "jaJP": "メール通知",
+ "koKR": "이메일 알림",
+ "ruRU": "Уведомление по электронной почте",
+ "ptBR": "Notificação por e-mail",
+ "frFR": "Notification par e-mail",
+ "esAR": "Notificación por correo electrónico",
+ "arDZ": "إشعار البريد الإلكتروني"
+ },
+ "timestamp": "2025-05-08T04:01:02.331Z"
+ },
+ "通过邮件发送告警通知": {
+ "text": "通过邮件发送告警通知",
+ "key": "t_4_1746676861473",
+ "translations": {
+ "zhCN": "通过邮件发送告警通知",
+ "zhTW": "透過郵件發送警報通知",
+ "enUS": "Send alert notifications via email",
+ "jaJP": "メールでアラート通知を送信する",
+ "koKR": "이메일로 경고 알림 보내기",
+ "ruRU": "Отправка уведомлений о тревоге по электронной почте",
+ "ptBR": "Enviar notificações de alerta por e-mail",
+ "frFR": "Envoyer des notifications d'alerte par e-mail",
+ "esAR": "Enviar notificaciones de alerta por correo electrónico",
+ "arDZ": "إرسال إخطارات التنبيه عبر البريد الإلكتروني"
+ },
+ "timestamp": "2025-05-08T04:01:02.331Z"
+ },
+ "钉钉通知": {
+ "text": "钉钉通知",
+ "key": "t_5_1746676856974",
+ "translations": {
+ "zhCN": "钉钉通知",
+ "zhTW": "釘釘通知",
+ "enUS": "DingTalk Notification",
+ "jaJP": "DingTalk通知",
+ "koKR": "DingTalk 알림",
+ "ruRU": "Уведомление DingTalk",
+ "ptBR": "Notificação DingTalk",
+ "frFR": "Notification DingTalk",
+ "esAR": "Notificación de DingTalk",
+ "arDZ": "إشعار DingTalk"
+ },
+ "timestamp": "2025-05-08T04:01:02.331Z"
+ },
+ "通过钉钉机器人发送告警通知": {
+ "text": "通过钉钉机器人发送告警通知",
+ "key": "t_6_1746676860886",
+ "translations": {
+ "zhCN": "通过钉钉机器人发送告警通知",
+ "zhTW": "通過釘釘機器人發送警報通知",
+ "enUS": "Send alarm notifications via DingTalk robot",
+ "jaJP": "DingTalkロボットを通じてアラーム通知を送信する",
+ "koKR": "DingTalk 봇을 통해 경고 알림 보내기",
+ "ruRU": "Отправка уведомлений о тревоге через робота DingTalk",
+ "ptBR": "Enviar notificações de alarme via robô DingTalk",
+ "frFR": "Envoyer des notifications d'alarme via le robot DingTalk",
+ "esAR": "Enviar notificaciones de alarma a través del robot DingTalk",
+ "arDZ": "إرسال إشعارات الإنذار عبر روبوت DingTalk"
+ },
+ "timestamp": "2025-05-08T04:01:02.331Z"
+ },
+ "企业微信通知": {
+ "text": "企业微信通知",
+ "key": "t_7_1746676857191",
+ "translations": {
+ "zhCN": "企业微信通知",
+ "zhTW": "企業微信通知",
+ "enUS": "WeChat Work Notification",
+ "jaJP": "企業WeChat通知",
+ "koKR": "기업 위챗 알림",
+ "ruRU": "Уведомление WeChat Work",
+ "ptBR": "Notificação do WeChat Work",
+ "frFR": "Notification WeChat Work",
+ "esAR": "Notificación de WeChat Work",
+ "arDZ": "إشعار WeChat Work"
+ },
+ "timestamp": "2025-05-08T04:01:02.331Z"
+ },
+ "通过企业微信机器人发送告警通知": {
+ "text": "通过企业微信机器人发送告警通知",
+ "key": "t_8_1746676860457",
+ "translations": {
+ "zhCN": "通过企业微信机器人发送告警通知",
+ "zhTW": "通過企業微信機器人發送警報通知",
+ "enUS": "Send alarm notifications via WeCom bot",
+ "jaJP": "WeComボットでアラーム通知を送信",
+ "koKR": "WeCom 봇을 통해 경고 알림 보내기",
+ "ruRU": "Отправка уведомлений о тревоге через бота WeCom",
+ "ptBR": "Enviar notificações de alarme via bot do WeCom",
+ "frFR": "Envoyer des notifications d'alarme via le bot WeCom",
+ "esAR": "Enviar notificaciones de alarma a través del bot de WeCom",
+ "arDZ": "إرسال تنبيهات الإنذار عبر بوت WeCom"
+ },
+ "timestamp": "2025-05-08T04:01:02.331Z"
+ },
+ "飞书通知": {
+ "text": "飞书通知",
+ "key": "t_9_1746676857164",
+ "translations": {
+ "zhCN": "飞书通知",
+ "zhTW": "飛書通知",
+ "enUS": "Feishu Notification",
+ "jaJP": "Feishu通知",
+ "koKR": "Feishu 알림",
+ "ruRU": "Уведомление Feishu",
+ "ptBR": "Notificação Feishu",
+ "frFR": "Notification Feishu",
+ "esAR": "Notificación de Feishu",
+ "arDZ": "إشعار Feishu"
+ },
+ "timestamp": "2025-05-08T04:01:02.331Z"
+ },
+ "通过飞书机器人发送告警通知": {
+ "text": "通过飞书机器人发送告警通知",
+ "key": "t_10_1746676862329",
+ "translations": {
+ "zhCN": "通过飞书机器人发送告警通知",
+ "zhTW": "通過飛書機器人發送告警通知",
+ "enUS": "Send alarm notifications via Feishu bot",
+ "jaJP": "飛書ロボットでアラーム通知を送信する",
+ "koKR": "Feishu 봇을 통해 알림 알림 보내기",
+ "ruRU": "Отправка уведомлений о тревоге через бота Feishu",
+ "ptBR": "Enviar notificações de alarme via bot Feishu",
+ "frFR": "Envoyer des notifications d'alarme via le bot Feishu",
+ "esAR": "Enviar notificaciones de alarma a través del bot Feishu",
+ "arDZ": "إرسال إخطارات الإنذار عبر بوت Feishu"
+ },
+ "timestamp": "2025-05-08T04:01:02.331Z"
+ },
+ "WebHook通知": {
+ "text": "WebHook通知",
+ "key": "t_11_1746676859158",
+ "translations": {
+ "zhCN": "WebHook通知",
+ "zhTW": "WebHook通知",
+ "enUS": "WebHook Notification",
+ "jaJP": "WebHook通知",
+ "koKR": "WebHook 알림",
+ "ruRU": "WebHook уведомление",
+ "ptBR": "Notificação WebHook",
+ "frFR": "Notification WebHook",
+ "esAR": "Notificación WebHook",
+ "arDZ": "إشعار WebHook"
+ },
+ "timestamp": "2025-05-08T04:01:02.331Z"
+ },
+ "通过WebHook发送告警通知": {
+ "text": "通过WebHook发送告警通知",
+ "key": "t_12_1746676860503",
+ "translations": {
+ "zhCN": "通过WebHook发送告警通知",
+ "zhTW": "通過WebHook發送警報通知",
+ "enUS": "Send alarm notifications via WebHook",
+ "jaJP": "WebHookを介してアラーム通知を送信する",
+ "koKR": "WebHook를 통해 알림 알림 보내기",
+ "ruRU": "Отправка уведомлений о тревоге через WebHook",
+ "ptBR": "Enviar notificações de alarme via WebHook",
+ "frFR": "Envoyer des notifications d'alarme via WebHook",
+ "esAR": "Enviar notificaciones de alarma a través de WebHook",
+ "arDZ": "إرسال إشعارات الإنذار عبر WebHook"
+ },
+ "timestamp": "2025-05-08T04:01:02.331Z"
+ },
+ "通知渠道": {
+ "text": "通知渠道",
+ "key": "t_13_1746676856842",
+ "translations": {
+ "zhCN": "通知渠道",
+ "zhTW": "通知渠道",
+ "enUS": "Notification channel",
+ "jaJP": "通知チャネル",
+ "koKR": "알림 채널",
+ "ruRU": "Канал уведомлений",
+ "ptBR": "Canal de notificação",
+ "frFR": "Canal de notification",
+ "esAR": "Canal de notificación",
+ "arDZ": "قناة الإخطار"
+ },
+ "timestamp": "2025-05-08T04:01:02.331Z"
+ },
+ "已配置的通知渠道": {
+ "text": "已配置的通知渠道",
+ "key": "t_14_1746676859019",
+ "translations": {
+ "zhCN": "已配置的通知渠道",
+ "zhTW": "已配置的通知頻道",
+ "enUS": "Configured notification channels",
+ "jaJP": "設定済みの通知チャネル",
+ "koKR": "구성된 알림 채널",
+ "ruRU": "Настроенные каналы уведомлений",
+ "ptBR": "Canais de notificação configurados",
+ "frFR": "Canaux de notification configurés",
+ "esAR": "Canales de notificación configurados",
+ "arDZ": "قنوات الإعلام المُهيأة"
+ },
+ "timestamp": "2025-05-08T04:01:02.331Z"
+ },
+ "已停用": {
+ "text": "已停用",
+ "key": "t_15_1746676856567",
+ "translations": {
+ "zhCN": "已停用",
+ "zhTW": "已停用",
+ "enUS": "Disabled",
+ "jaJP": "無効化",
+ "koKR": "비활성화됨",
+ "ruRU": "Отключено",
+ "ptBR": "Desativado",
+ "frFR": "Désactivé",
+ "esAR": "Desactivado",
+ "arDZ": "معطل"
+ },
+ "timestamp": "2025-05-08T04:01:02.331Z"
+ },
+ "测试": {
+ "text": "测试",
+ "key": "t_16_1746676855270",
+ "translations": {
+ "zhCN": "测试",
+ "zhTW": "測試",
+ "enUS": "Test",
+ "jaJP": "テスト",
+ "koKR": "테스트",
+ "ruRU": "тест",
+ "ptBR": "Teste",
+ "frFR": "Test",
+ "esAR": "Prueba",
+ "arDZ": "اختبار"
+ },
+ "timestamp": "2025-05-08T04:01:02.331Z"
+ },
+ "最后一次执行状态": {
+ "text": "最后一次执行状态",
+ "key": "t_0_1746677882486",
+ "translations": {
+ "zhCN": "最后一次执行状态",
+ "zhTW": "最後一次執行狀態",
+ "enUS": "Last execution status",
+ "jaJP": "最後の実行状態",
+ "koKR": "마지막 실행 상태",
+ "ruRU": "Последний статус выполнения",
+ "ptBR": "Último status de execução",
+ "frFR": "Dernier état d'exécution",
+ "esAR": "Último estado de ejecución",
+ "arDZ": "حالة التنفيذ الأخيرة"
+ },
+ "timestamp": "2025-05-08T04:18:02.487Z"
+ },
+ "域名不能为空": {
+ "text": "域名不能为空",
+ "key": "t_0_1746697487119",
+ "translations": {
+ "zhCN": "域名不能为空",
+ "zhTW": "域名不能為空",
+ "enUS": "Domain name cannot be empty",
+ "jaJP": "ドメイン名は空にできません",
+ "koKR": "도메인 이름은 비워둘 수 없습니다",
+ "ruRU": "Имя домена не может быть пустым",
+ "ptBR": "O nome do domínio não pode estar vazio",
+ "frFR": "Le nom de domaine ne peut pas être vide",
+ "esAR": "El nombre de dominio no puede estar vacío",
+ "arDZ": "اسم النطاق لا يمكن أن يكون فارغًا"
+ },
+ "timestamp": "2025-05-08T09:44:47.164Z"
+ },
+ "邮箱不能为空": {
+ "text": "邮箱不能为空",
+ "key": "t_1_1746697485188",
+ "translations": {
+ "zhCN": "邮箱不能为空",
+ "zhTW": "郵箱不能為空",
+ "enUS": "Email cannot be empty",
+ "jaJP": "メールアドレスは空にできません",
+ "koKR": "이메일은 비워둘 수 없습니다",
+ "ruRU": "Почта не может быть пустой",
+ "ptBR": "O e-mail não pode estar vazio",
+ "frFR": "L'e-mail ne peut pas être vide",
+ "esAR": "El correo electrónico no puede estar vacío",
+ "arDZ": "البريد الإلكتروني لا يمكن أن يكون فارغاً"
+ },
+ "timestamp": "2025-05-08T09:44:47.164Z"
+ },
+ "阿里云OSS": {
+ "text": "阿里云OSS",
+ "key": "t_2_1746697487164",
+ "translations": {
+ "zhCN": "阿里云OSS",
+ "zhTW": "阿里雲OSS",
+ "enUS": "Alibaba Cloud OSS",
+ "jaJP": "アリババクラウドOSS",
+ "koKR": "알리바바 클라우드 OSS",
+ "ruRU": "Alibaba Cloud OSS",
+ "ptBR": "Alibaba Cloud OSS",
+ "frFR": "Alibaba Cloud OSS",
+ "esAR": "Alibaba Cloud OSS",
+ "arDZ": "علي بابا كلاود OSS"
+ },
+ "timestamp": "2025-05-08T09:44:47.164Z"
+ },
+ "主机提供商": {
+ "text": "主机提供商",
+ "key": "t_0_1746754500246",
+ "translations": {
+ "zhCN": "主机提供商",
+ "zhTW": "主機供應商",
+ "enUS": "Hosting Provider",
+ "jaJP": "ホスティングプロバイダー",
+ "koKR": "호스팅 제공업체",
+ "ruRU": "Хостинг-провайдер",
+ "ptBR": "Provedor de Hospedagem",
+ "frFR": "Fournisseur d'hébergement",
+ "esAR": "Proveedor de Alojamiento",
+ "arDZ": "مزود الاستضافة"
+ },
+ "timestamp": "2025-05-09T01:35:00.270Z"
+ },
+ "API来源": {
+ "text": "API来源",
+ "key": "t_1_1746754499371",
+ "translations": {
+ "zhCN": "API来源",
+ "zhTW": "API來源",
+ "enUS": "API Source",
+ "jaJP": "APIソース",
+ "koKR": "API 소스",
+ "ruRU": "Источник API",
+ "ptBR": "Fonte da API",
+ "frFR": "Source de l'API",
+ "esAR": "Fuente de la API",
+ "arDZ": "مصدر API"
+ },
+ "timestamp": "2025-05-09T01:35:00.270Z"
+ },
+ "API 类型": {
+ "text": "API 类型",
+ "key": "t_2_1746754500270",
+ "translations": {
+ "zhCN": "API 类型",
+ "zhTW": "API 類型",
+ "enUS": "API type",
+ "jaJP": "APIタイプ",
+ "koKR": "API 유형",
+ "ruRU": "Тип API",
+ "ptBR": "Tipo de API",
+ "frFR": "Type d'API",
+ "esAR": "Tipo de API",
+ "arDZ": "نوع API"
+ },
+ "timestamp": "2025-05-09T01:35:00.270Z"
+ },
+ "请求错误": {
+ "text": "请求错误",
+ "key": "t_0_1746760933542",
+ "translations": {
+ "zhCN": "请求错误",
+ "zhTW": "請求錯誤",
+ "enUS": "Request error",
+ "jaJP": "リクエストエラー",
+ "koKR": "요청 오류",
+ "ruRU": "Ошибка запроса",
+ "ptBR": "Erro de solicitação",
+ "frFR": "Erreur de requête",
+ "esAR": "Error de solicitud",
+ "arDZ": "خطأ في الطلب"
+ },
+ "timestamp": "2025-05-09T03:22:13.542Z"
+ },
+ "共{0}条": {
+ "text": "共{0}条",
+ "key": "t_0_1746773350551",
+ "translations": {
+ "zhCN": "共{0}条",
+ "zhTW": "共{0}條",
+ "enUS": "{0} results",
+ "jaJP": "合計{0}件",
+ "koKR": "총 {0}건",
+ "ruRU": "Всего {0}",
+ "ptBR": "Total de {0} itens",
+ "frFR": "{0} résultats",
+ "esAR": "{0} en total",
+ "arDZ": "مجموع {0}"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "未执行": {
+ "text": "未执行",
+ "key": "t_1_1746773348701",
+ "translations": {
+ "zhCN": "未执行",
+ "zhTW": "未執行",
+ "enUS": "Not executed",
+ "jaJP": "未実行",
+ "koKR": "실행되지 않음",
+ "ruRU": "Не выполнено",
+ "ptBR": "Não executado",
+ "frFR": "Non exécuté",
+ "esAR": "No ejecutado",
+ "arDZ": "لم يتم التنفيذ"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "自动化工作流": {
+ "text": "自动化工作流",
+ "key": "t_2_1746773350970",
+ "translations": {
+ "zhCN": "自动化工作流",
+ "zhTW": "自動化工作流程",
+ "enUS": "Automated workflow",
+ "jaJP": "自動化ワークフロー",
+ "koKR": "자동화 워크플로우",
+ "ruRU": "Автоматизированный рабочий процесс",
+ "ptBR": "Fluxo de trabalho automatizado",
+ "frFR": "Workflow automatisé",
+ "esAR": "Flujo de trabajo automatizado",
+ "arDZ": "سير العمل الآلي"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "总数量": {
+ "text": "总数量",
+ "key": "t_3_1746773348798",
+ "translations": {
+ "zhCN": "总数量",
+ "zhTW": "總數量",
+ "enUS": "Total quantity",
+ "jaJP": "総数量",
+ "koKR": "총 수량",
+ "ruRU": "Общее количество",
+ "ptBR": "Quantidade total",
+ "frFR": "Quantité totale",
+ "esAR": "Cantidad total",
+ "arDZ": "العدد الكلي"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "执行失败": {
+ "text": "执行失败",
+ "key": "t_4_1746773348957",
+ "translations": {
+ "zhCN": "执行失败",
+ "zhTW": "執行失敗",
+ "enUS": "Execution failed",
+ "jaJP": "実行に失敗しました",
+ "koKR": "실행 실패",
+ "ruRU": "Ошибка выполнения",
+ "ptBR": "Falha na execução",
+ "frFR": "Échec de l'exécution",
+ "esAR": "Falló la ejecución",
+ "arDZ": "فشل التنفيذ"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "即将到期": {
+ "text": "即将到期",
+ "key": "t_5_1746773349141",
+ "translations": {
+ "zhCN": "即将到期",
+ "zhTW": "即將到期",
+ "enUS": "Expiring soon",
+ "jaJP": "まもなく期限切れ",
+ "koKR": "곧 만료됩니다",
+ "ruRU": "Скоро истекает",
+ "ptBR": "Expirando em breve",
+ "frFR": "Expire bientôt",
+ "esAR": "Próximo a expirar",
+ "arDZ": "تنتهي قريبا"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "实时监控": {
+ "text": "实时监控",
+ "key": "t_6_1746773349980",
+ "translations": {
+ "zhCN": "实时监控",
+ "zhTW": "即時監控",
+ "enUS": "Real-time monitoring",
+ "jaJP": "リアルタイム監視",
+ "koKR": "실시간 모니터링",
+ "ruRU": "Мониторинг в реальном времени",
+ "ptBR": "Monitoramento em tempo real",
+ "frFR": "Surveillance en temps réel",
+ "esAR": "Monitoreo en tiempo real",
+ "arDZ": "مراقبة في الوقت الحقيقي"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "异常数量": {
+ "text": "异常数量",
+ "key": "t_7_1746773349302",
+ "translations": {
+ "zhCN": "异常数量",
+ "zhTW": "異常數量",
+ "enUS": "Abnormal quantity",
+ "jaJP": "異常数量",
+ "koKR": "이상 수량",
+ "ruRU": "Аномальное количество",
+ "ptBR": "Quantidade anormal",
+ "frFR": "Quantité anormale",
+ "esAR": "Cantidad anormal",
+ "arDZ": "كمية غير طبيعية"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "最近工作流执行记录": {
+ "text": "最近工作流执行记录",
+ "key": "t_8_1746773351524",
+ "translations": {
+ "zhCN": "最近工作流执行记录",
+ "zhTW": "最近工作流程執行紀錄",
+ "enUS": "Recent workflow execution records",
+ "jaJP": "最近のワークフロー実行記録",
+ "koKR": "최근 워크플로우 실행 기록",
+ "ruRU": "Недавние записи выполнения рабочего процесса",
+ "ptBR": "Registros recentes de execução de fluxo de trabalho",
+ "frFR": "Récents enregistrements d'exécution de flux de travail",
+ "esAR": "Registros recientes de ejecución de flujo de trabajo",
+ "arDZ": "سجلات تنفيذ سير العمل الحديثة"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "查看全部": {
+ "text": "查看全部",
+ "key": "t_9_1746773348221",
+ "translations": {
+ "zhCN": "查看全部",
+ "zhTW": "查看全部",
+ "enUS": "View all",
+ "jaJP": "すべて表示",
+ "koKR": "모두 보기",
+ "ruRU": "Просмотреть все",
+ "ptBR": "Ver tudo",
+ "frFR": "Voir tout",
+ "esAR": "Ver todo",
+ "arDZ": "عرض الكل"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "暂无工作流执行记录": {
+ "text": "暂无工作流执行记录",
+ "key": "t_10_1746773351576",
+ "translations": {
+ "zhCN": "暂无工作流执行记录",
+ "zhTW": "暫無工作流執行記錄",
+ "enUS": "No workflow execution records",
+ "jaJP": "ワークフロー実行記録がありません",
+ "koKR": "워크플로우 실행 기록 없음",
+ "ruRU": "Нет записей выполнения рабочего процесса",
+ "ptBR": "Nenhum registro de execução de fluxo de trabalho",
+ "frFR": "Aucun enregistrement d'exécution de flux de travail",
+ "esAR": "No hay registros de ejecución de flujo de trabajo",
+ "arDZ": "لا توجد سجلات تنفيذ سير العمل"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "创建工作流": {
+ "text": "创建工作流",
+ "key": "t_11_1746773349054",
+ "translations": {
+ "zhCN": "创建工作流",
+ "zhTW": "建立工作流程",
+ "enUS": "Create workflow",
+ "jaJP": "ワークフローの作成",
+ "koKR": "워크플로우 생성",
+ "ruRU": "Создание рабочего процесса",
+ "ptBR": "Criar fluxo de trabalho",
+ "frFR": "Créer un workflow",
+ "esAR": "Crear flujo de trabajo",
+ "arDZ": "إنشاء سير العمل"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "点击创建自动化工作流程,提高效率": {
+ "text": "点击创建自动化工作流程,提高效率",
+ "key": "t_12_1746773355641",
+ "translations": {
+ "zhCN": "点击创建自动化工作流程,提高效率",
+ "zhTW": "點擊創建自動化工作流程,提高效率",
+ "enUS": "Click to create an automated workflow to improve efficiency",
+ "jaJP": "効率を向上させるために自動化されたワークフローを作成するにはクリックしてください",
+ "koKR": "효율성을 높이기 위해 자동화된 워크플로우를 생성하려면 클릭하세요",
+ "ruRU": "Нажмите, чтобы создать автоматизированный рабочий процесс для повышения эффективности",
+ "ptBR": "Clique para criar um fluxo de trabalho automatizado para melhorar a eficiência",
+ "frFR": "Cliquez pour créer un flux de travail automatisé afin d'améliorer l'efficacité",
+ "esAR": "Haz clic para crear un flujo de trabajo automatizado y mejorar la eficiencia",
+ "arDZ": "انقر لإنشاء سير عمل آلي لتحسين الكفاءة"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "申请证书": {
+ "text": "申请证书",
+ "key": "t_13_1746773349526",
+ "translations": {
+ "zhCN": "申请证书",
+ "zhTW": "申請證書",
+ "enUS": "Apply for certificate",
+ "jaJP": "証明書を申請する",
+ "koKR": "증명서 신청",
+ "ruRU": "Подать заявку на сертификат",
+ "ptBR": "Solicitar certificado",
+ "frFR": "Demander un certificat",
+ "esAR": "Solicitar certificado",
+ "arDZ": "التقدم بطلب للحصول على شهادة"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "点击申请和管理SSL证书,保障安全": {
+ "text": "点击申请和管理SSL证书,保障安全",
+ "key": "t_14_1746773355081",
+ "translations": {
+ "zhCN": "点击申请和管理SSL证书,保障安全",
+ "zhTW": "點擊申請和管理SSL證書,保障安全",
+ "enUS": "Click to apply for and manage SSL certificates to ensure security",
+ "jaJP": "SSL証明書の申請と管理をクリックして、セキュリティを確保します",
+ "koKR": "SSL 인증서를 신청하고 관리하여 보안을 보장합니다",
+ "ruRU": "Нажмите, чтобы подать заявку на SSL-сертификаты и управлять ими для обеспечения безопасности",
+ "ptBR": "Clique para solicitar e gerenciar certificados SSL para garantir segurança",
+ "frFR": "Cliquez pour demander et gérer les certificats SSL afin d'assurer la sécurité",
+ "esAR": "Haz clic para solicitar y administrar certificados SSL para garantizar la seguridad",
+ "arDZ": "انقر للتقدم بطلب وإدارة شهادات SSL لضمان الأمان"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "点击设置网站监控,实时掌握运行状态": {
+ "text": "点击设置网站监控,实时掌握运行状态",
+ "key": "t_15_1746773358151",
+ "translations": {
+ "zhCN": "点击设置网站监控,实时掌握运行状态",
+ "zhTW": "點擊設置網站監控,即時掌握運行狀態",
+ "enUS": "Click to set up website monitoring and keep track of the runtime status in real time",
+ "jaJP": "クリックしてウェブサイトの監視を設定し、実行状態をリアルタイムで把握します",
+ "koKR": "웹사이트 모니터링을 설정하려면 클릭하세요. 실시간으로 실행 상태를 확인할 수 있습니다",
+ "ruRU": "Нажмите, чтобы настроить мониторинг веб-сайта и отслеживать состояние работы в режиме реального времени",
+ "ptBR": "Clique para configurar o monitoramento do site e acompanhar o status de execução em tempo real",
+ "frFR": "Cliquez pour configurer la surveillance du site et suivre l'état d'exécution en temps réel",
+ "esAR": "Haz clic para configurar el monitoreo del sitio web y realiza un seguimiento del estado de ejecución en tiempo real",
+ "arDZ": "انقر لإعداد مراقبة الموقع وتتبع حالة التشغيل في الوقت الفعلي"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "最多只能配置一个邮箱通知渠道": {
+ "text": "最多只能配置一个邮箱通知渠道",
+ "key": "t_16_1746773356568",
+ "translations": {
+ "zhCN": "最多只能配置一个邮箱通知渠道",
+ "zhTW": "最多只能配置一個郵箱通知渠道",
+ "enUS": "Only one email notification channel can be configured at most",
+ "jaJP": "最大で1つのメール通知チャネルしか設定できません",
+ "koKR": "최대 하나의 이메일 알림 채널만 구성할 수 있습니다",
+ "ruRU": "Можно настроить только один канал уведомлений по электронной почте",
+ "ptBR": "No máximo, apenas um canal de notificação por e-mail pode ser configurado",
+ "frFR": "Un seul canal de notification par e-mail peut être configuré au maximum",
+ "esAR": "Solo se puede configurar un canal de notificación por correo electrónico como máximo",
+ "arDZ": "يمكن تكوين قناة إشعار واحدة فقط عبر البريد الإلكتروني كحد أقصى"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "确认{0}通知渠道": {
+ "text": "确认{0}通知渠道",
+ "key": "t_17_1746773351220",
+ "translations": {
+ "zhCN": "确认{0}通知渠道",
+ "zhTW": "確認{0}通知渠道",
+ "enUS": "Confirm {0} notification channel",
+ "jaJP": "{0}通知チャネルの確認",
+ "koKR": "{0} 알림 채널 확인",
+ "ruRU": "Подтвердить канал уведомлений {0}",
+ "ptBR": "Confirmar canal de notificação {0}",
+ "frFR": "Confirmer le canal de notification {0}",
+ "esAR": "Confirmar canal de notificación {0}",
+ "arDZ": "تأكيد قناة الإشعارات {0}"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "{0}通知渠道,将开始发送告警通知。": {
+ "text": "{0}通知渠道,将开始发送告警通知。",
+ "key": "t_18_1746773355467",
+ "translations": {
+ "zhCN": "{0}通知渠道,将开始发送告警通知。",
+ "zhTW": "{0}通知渠道,將開始發送告警通知。",
+ "enUS": "{0} notification channels will start sending alert notifications.",
+ "jaJP": "{0}通知チャネルは、アラート通知の送信を開始します。",
+ "koKR": "{0} 알림 채널에서 경고 알림을 보내기 시작할 예정입니다.",
+ "ruRU": "{0} каналы уведомлений начнут отправлять оповещения.",
+ "ptBR": "Os canais de notificação {0} começarão a enviar alertas.",
+ "frFR": "Les canaux de notification {0} commenceront à envoyer des alertes.",
+ "esAR": "Los canales de notificación {0} comenzarán a enviar alertas.",
+ "arDZ": "ستبدأ قنوات الإشعار {0} في إرسال تنبيهات."
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "当前通知渠道不支持测试": {
+ "text": "当前通知渠道不支持测试",
+ "key": "t_19_1746773352558",
+ "translations": {
+ "zhCN": "当前通知渠道不支持测试",
+ "zhTW": "當前通知渠道不支援測試",
+ "enUS": "The current notification channel does not support testing",
+ "jaJP": "現在の通知チャネルはテストをサポートしていません",
+ "koKR": "현재 알림 채널은 테스트를 지원하지 않습니다",
+ "ruRU": "Текущий канал уведомлений не поддерживает тестирование",
+ "ptBR": "O canal de notificação atual não suporta testes",
+ "frFR": "Le canal de notification actuel ne prend pas en charge les tests",
+ "esAR": "El canal de notificación actual no admite pruebas",
+ "arDZ": "قناة الإشعارات الحالية لا تدعم الاختبار"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "正在发送测试邮件,请稍后...": {
+ "text": "正在发送测试邮件,请稍后...",
+ "key": "t_20_1746773356060",
+ "translations": {
+ "zhCN": "正在发送测试邮件,请稍后...",
+ "zhTW": "正在發送測試郵件,請稍後...",
+ "enUS": "Sending test email, please wait...",
+ "jaJP": "テストメールを送信しています、少々お待ちください...",
+ "koKR": "테스트 이메일을 보내는 중입니다. 잠시 기다려주세요...",
+ "ruRU": "Отправка тестового письма, пожалуйста, подождите...",
+ "ptBR": "Enviando e-mail de teste, por favor aguarde...",
+ "frFR": "Envoi d'un e-mail de test, veuillez patienter...",
+ "esAR": "Enviando correo de prueba, por favor espere...",
+ "arDZ": "يتم إرسال البريد الإلكتروني الاختباري، يرجى الانتظار..."
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "测试邮件": {
+ "text": "测试邮件",
+ "key": "t_21_1746773350759",
+ "translations": {
+ "zhCN": "测试邮件",
+ "zhTW": "測試郵件",
+ "enUS": "Test email",
+ "jaJP": "テストメール",
+ "koKR": "테스트 이메일",
+ "ruRU": "Тестовое письмо",
+ "ptBR": "E-mail de teste",
+ "frFR": "E-mail de test",
+ "esAR": "Correo de prueba",
+ "arDZ": "بريد إلكتروني تجريبي"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "发送测试邮件到当前配置的邮箱,是否继续?": {
+ "text": "发送测试邮件到当前配置的邮箱,是否继续?",
+ "key": "t_22_1746773360711",
+ "translations": {
+ "zhCN": "发送测试邮件到当前配置的邮箱,是否继续?",
+ "zhTW": "發送測試郵件到當前配置的郵箱,是否繼續?",
+ "enUS": "Send a test email to the currently configured mailbox, continue?",
+ "jaJP": "現在設定されているメールボックスにテストメールを送信します。続けますか?",
+ "koKR": "현재 설정된 메일박스로 테스트 메일을 보내시겠습니까?",
+ "ruRU": "Отправить тестовое письмо на текущий настроенный почтовый ящик, продолжить?",
+ "ptBR": "Enviar um e-mail de teste para a caixa de correio configurada atualmente, continuar?",
+ "frFR": "Envoyer un e-mail de test à la boîte mail configurée actuellement, continuer ?",
+ "esAR": "¿Enviar un correo de prueba al buzón configurado actualmente, continuar?",
+ "arDZ": "إرسال بريد إلكتروني اختباري إلى صندوق البريد الحالي المُهيأ، هل تتابع؟"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "删除确认": {
+ "text": "删除确认",
+ "key": "t_23_1746773350040",
+ "translations": {
+ "zhCN": "删除确认",
+ "zhTW": "刪除確認",
+ "enUS": "Delete Confirmation",
+ "jaJP": "削除の確認",
+ "koKR": "삭제 확인",
+ "ruRU": "Подтверждение удаления",
+ "ptBR": "Confirmação de exclusão",
+ "frFR": "Confirmation de suppression",
+ "esAR": "Confirmación de eliminación",
+ "arDZ": "تأكيد الحذف"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "请输入名称": {
+ "text": "请输入名称",
+ "key": "t_25_1746773349596",
+ "translations": {
+ "zhCN": "请输入名称",
+ "zhTW": "請輸入名稱",
+ "enUS": "Please enter name",
+ "jaJP": "名前を入力してください",
+ "koKR": "이름을 입력하세요",
+ "ruRU": "Пожалуйста, введите имя",
+ "ptBR": "Por favor, insira o nome",
+ "frFR": "Veuillez entrer le nom",
+ "esAR": "Por favor ingrese el nombre",
+ "arDZ": "الرجاء إدخال الاسم"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "请输入正确的SMTP端口": {
+ "text": "请输入正确的SMTP端口",
+ "key": "t_26_1746773353409",
+ "translations": {
+ "zhCN": "请输入正确的SMTP端口",
+ "zhTW": "請輸入正確的SMTP端口",
+ "enUS": "Please enter the correct SMTP port",
+ "jaJP": "正しいSMTPポートを入力してください",
+ "koKR": "올바른 SMTP 포트를 입력하세요",
+ "ruRU": "Пожалуйста, введите правильный порт SMTP",
+ "ptBR": "Por favor, insira a porta SMTP correta",
+ "frFR": "Veuillez saisir le bon port SMTP",
+ "esAR": "Por favor, ingrese el puerto SMTP correcto",
+ "arDZ": "الرجاء إدخال منفذ SMTP الصحيح"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "请输入用户密码": {
+ "text": "请输入用户密码",
+ "key": "t_27_1746773352584",
+ "translations": {
+ "zhCN": "请输入用户密码",
+ "zhTW": "請輸入使用者密碼",
+ "enUS": "Please enter user password",
+ "jaJP": "ユーザーパスワードを入力してください",
+ "koKR": "사용자 비밀번호를 입력하세요",
+ "ruRU": "Введите пароль пользователя",
+ "ptBR": "Por favor, insira a senha do usuário",
+ "frFR": "Veuillez entrer le mot de passe utilisateur",
+ "esAR": "Por favor, ingrese la contraseña de usuario",
+ "arDZ": "يرجى إدخال كلمة مرور المستخدم"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "请输入正确的发送人邮箱": {
+ "text": "请输入正确的发送人邮箱",
+ "key": "t_28_1746773354048",
+ "translations": {
+ "zhCN": "请输入正确的发送人邮箱",
+ "zhTW": "請輸入正確的發件人郵箱",
+ "enUS": "Please enter the correct sender email",
+ "jaJP": "正しい送信者のメールアドレスを入力してください",
+ "koKR": "올바른 발신자 이메일을 입력하세요",
+ "ruRU": "Пожалуйста, введите правильный адрес электронной почты отправителя",
+ "ptBR": "Por favor, insira o e-mail do remetente correto",
+ "frFR": "Veuillez entrer l'e-mail correct de l'expéditeur",
+ "esAR": "Por favor, ingrese el correo electrónico correcto del remitente",
+ "arDZ": "الرجاء إدخال البريد الإلكتروني الصحيح للمرسل"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "请输入正确的接收邮箱": {
+ "text": "请输入正确的接收邮箱",
+ "key": "t_29_1746773351834",
+ "translations": {
+ "zhCN": "请输入正确的接收邮箱",
+ "zhTW": "請輸入正確的接收信箱",
+ "enUS": "Please enter the correct receiving email",
+ "jaJP": "正しい受信メールを入力してください",
+ "koKR": "올바른 수신 이메일을 입력하세요",
+ "ruRU": "Пожалуйста, введите правильную электронную почту",
+ "ptBR": "Por favor, insira o e-mail de recebimento correto",
+ "frFR": "Veuillez entrer le bon e-mail de réception",
+ "esAR": "Por favor, ingrese el correo electrónico de recepción correcto",
+ "arDZ": "الرجاء إدخال البريد الإلكتروني الصحيح"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "发送人邮箱": {
+ "text": "发送人邮箱",
+ "key": "t_30_1746773350013",
+ "translations": {
+ "zhCN": "发送人邮箱",
+ "zhTW": "寄件人信箱",
+ "enUS": "Sender's email",
+ "jaJP": "送信者のメール",
+ "koKR": "보내는 사람 이메일",
+ "ruRU": "Электронная почта отправителя",
+ "ptBR": "E-mail do remetente",
+ "frFR": "E-mail de l'expéditeur",
+ "esAR": "Correo electrónico del remitente",
+ "arDZ": "بريد المرسل الإلكتروني"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "接收邮箱": {
+ "text": "接收邮箱",
+ "key": "t_31_1746773349857",
+ "translations": {
+ "zhCN": "接收邮箱",
+ "zhTW": "接收郵箱",
+ "enUS": "Receive Email",
+ "jaJP": "受信メール",
+ "koKR": "이메일 수신",
+ "ruRU": "Получить электронную почту",
+ "ptBR": "Receber E-mail",
+ "frFR": "Recevoir un e-mail",
+ "esAR": "Recibir correo electrónico",
+ "arDZ": "تلقي البريد الإلكتروني"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "钉钉": {
+ "text": "钉钉",
+ "key": "t_32_1746773348993",
+ "translations": {
+ "zhCN": "钉钉",
+ "zhTW": "釘釘",
+ "enUS": "DingTalk",
+ "jaJP": "ディンタン",
+ "koKR": "딩톡",
+ "ruRU": "ДинТолк",
+ "ptBR": "DingTalk",
+ "frFR": "DingTalk",
+ "esAR": "DingTalk",
+ "arDZ": "دينغتالک"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "企业微信": {
+ "text": "企业微信",
+ "key": "t_33_1746773350932",
+ "translations": {
+ "zhCN": "企业微信",
+ "zhTW": "企業微信",
+ "enUS": "WeChat Work",
+ "jaJP": "WeChat Work",
+ "koKR": "위챗 워크",
+ "ruRU": "WeChat Work",
+ "ptBR": "WeChat Work",
+ "frFR": "WeChat Work",
+ "esAR": "WeChat Work",
+ "arDZ": "WeChat Work"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "飞书": {
+ "text": "飞书",
+ "key": "t_34_1746773350153",
+ "translations": {
+ "zhCN": "飞书",
+ "zhTW": "飛書",
+ "enUS": "Feishu",
+ "jaJP": "飛書",
+ "koKR": "페이슈",
+ "ruRU": "Фэйшу",
+ "ptBR": "Feishu",
+ "frFR": "Feishu",
+ "esAR": "Feishu",
+ "arDZ": "فيشو"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "一个集证书申请、管理、部署和监控于一体的SSL证书全生命周期管理工具。": {
+ "text": "一个集证书申请、管理、部署和监控于一体的SSL证书全生命周期管理工具。",
+ "key": "t_35_1746773362992",
+ "translations": {
+ "zhCN": "一个集证书申请、管理、部署和监控于一体的SSL证书全生命周期管理工具。",
+ "zhTW": "一個集證書申請、管理、部署和監控於一體的SSL證書全生命週期管理工具。",
+ "enUS": "A comprehensive SSL certificate lifecycle management tool that integrates application, management, deployment, and monitoring.",
+ "jaJP": "SSL証明書の申請、管理、展開、監視を統合したライフサイクル管理ツール。",
+ "koKR": "SSL 인증서 신청, 관리, 배포 및 모니터링을 통합한 전 생애 주기 관리 도구.",
+ "ruRU": "Инструмент управления полным жизненным циклом SSL-сертификатов, объединяющий подачу заявки, управление, развертывание и мониторинг.",
+ "ptBR": "Uma ferramenta de gerenciamento do ciclo de vida completo de certificados SSL que integra solicitação, gerenciamento, implantação e monitoramento.",
+ "frFR": "Un outil de gestion du cycle de vie complet des certificats SSL intégrant la demande, la gestion, le déploiement et la surveillance.",
+ "esAR": "Una herramienta de gestión del ciclo de vida completo de certificados SSL que integra solicitud, gestión, implementación y monitoreo.",
+ "arDZ": "أداة إدارة دورة حياة شهادات SSL متكاملة تشمل التقديم، الإدارة، النشر والمراقبة."
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "证书申请:": {
+ "text": "证书申请:",
+ "key": "t_36_1746773348989",
+ "translations": {
+ "zhCN": "证书申请",
+ "zhTW": "證書申請",
+ "enUS": "Certificate Application",
+ "jaJP": "証明書申請",
+ "koKR": "증명서 신청",
+ "ruRU": "Заявка на сертификат",
+ "ptBR": "Pedido de Certificado",
+ "frFR": "Demande de certificat",
+ "esAR": "Solicitud de Certificado",
+ "arDZ": "طلب الشهادة"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "支持通过ACME协议从Let": {
+ "text": "支持通过ACME协议从Let",
+ "key": "t_37_1746773356895",
+ "translations": {
+ "zhCN": "支持通过ACME协议从Let's Encrypt获取证书",
+ "zhTW": "支援通過ACME協議從Let's Encrypt獲取證書",
+ "enUS": "Support obtaining certificates from Let's Encrypt via ACME protocol",
+ "jaJP": "ACMEプロトコルを介してLet's Encryptから証明書を取得する",
+ "koKR": "ACME 프로토콜을 통해 Let's Encrypt에서 인증서를 획득할 수 있도록 지원",
+ "ruRU": "Поддержка получения сертификатов от Let's Encrypt через протокол ACME",
+ "ptBR": "Suporte à obtenção de certificados do Let's Encrypt através do protocolo ACME",
+ "frFR": "Support pour obtenir des certificats de Let's Encrypt via le protocole ACME",
+ "esAR": "Soporte para obtener certificados de Let's Encrypt a través del protocolo ACME",
+ "arDZ": "دعم الحصول على شهادات من Let's Encrypt عبر بروتوكول ACME"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "证书管理:": {
+ "text": "证书管理:",
+ "key": "t_38_1746773349796",
+ "translations": {
+ "zhCN": "证书管理",
+ "zhTW": "證書管理",
+ "enUS": "Certificate Management",
+ "jaJP": "証明書管理",
+ "koKR": "인증서 관리",
+ "ruRU": "Управление сертификатами",
+ "ptBR": "Gerenciamento de Certificados",
+ "frFR": "Gestion des certificats",
+ "esAR": "Gestión de Certificados",
+ "arDZ": "إدارة الشهادات"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "集中管理所有SSL证书,包括手动上传和自动申请的证书": {
+ "text": "集中管理所有SSL证书,包括手动上传和自动申请的证书",
+ "key": "t_39_1746773358932",
+ "translations": {
+ "zhCN": "集中管理所有SSL证书,包括手动上传和自动申请的证书",
+ "zhTW": "集中管理所有SSL證書,包括手動上傳和自動申請的證書",
+ "enUS": "Centralized management of all SSL certificates, including manually uploaded and automatically applied certificates",
+ "jaJP": "すべてのSSL証明書を一元管理、手動アップロードおよび自動申請の証明書を含む",
+ "koKR": "모든 SSL 인증서를 중앙에서 관리하며, 수동으로 업로드한 인증서와 자동으로 신청한 인증서를 포함합니다",
+ "ruRU": "Централизованное управление всеми SSL-сертификатами, включая загруженные вручную и автоматически запрошенные сертификаты",
+ "ptBR": "Gerenciamento centralizado de todos os certificados SSL, incluindo certificados carregados manualmente e aplicados automaticamente",
+ "frFR": "Gestion centralisée de tous les certificats SSL, y compris les certificats téléchargés manuellement et appliqués automatiquement",
+ "esAR": "Gestión centralizada de todos los certificados SSL, incluidos los certificados cargados manualmente y aplicados automáticamente",
+ "arDZ": "الإدارة المركزية لجميع شهادات SSL، بما في ذلك الشهادات المرفوعة يدويًا والمطبقة تلقائيًا"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "证书部署:": {
+ "text": "证书部署:",
+ "key": "t_40_1746773352188",
+ "translations": {
+ "zhCN": "证书部署",
+ "zhTW": "證書部署",
+ "enUS": "Certificate deployment",
+ "jaJP": "証明書の展開",
+ "koKR": "인증서 배포",
+ "ruRU": "Развертывание сертификата",
+ "ptBR": "Implantaçã de certificado",
+ "frFR": "Déploiement de certificat",
+ "esAR": "Implementación de certificado",
+ "arDZ": "نشر الشهادة"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "支持一键部署证书到多种平台,如阿里云、腾讯云、宝塔面板、1Panel等": {
+ "text": "支持一键部署证书到多种平台,如阿里云、腾讯云、宝塔面板、1Panel等",
+ "key": "t_41_1746773364475",
+ "translations": {
+ "zhCN": "支持一键部署证书到多种平台,如阿里云、腾讯云、宝塔面板、1Panel等",
+ "zhTW": "支援一鍵部署證書到多種平台,如阿里雲、騰訊雲、寶塔面板、1Panel等",
+ "enUS": "Support one-click certificate deployment to multiple platforms such as Alibaba Cloud, Tencent Cloud, Pagoda Panel, 1Panel, etc.",
+ "jaJP": "ワンクリックでの証明書のデプロイを複数のプラットフォームでサポート、例えばアリババクラウド、テンセントクラウド、Pagoda Panel、1Panelなど",
+ "koKR": "여러 플랫폼에 한 번의 클릭으로 인증서 배포 지원, 알리바바 클라우드, 텐센트 클라우드, Pagoda Panel, 1Panel 등",
+ "ruRU": "Поддержка развертывания сертификатов в один клик на нескольких платформах, таких как Alibaba Cloud, Tencent Cloud, Pagoda Panel, 1Panel и др.",
+ "ptBR": "Suporte à implantação de certificados com um clique em várias plataformas, como Alibaba Cloud, Tencent Cloud, Pagoda Panel, 1Panel, etc.",
+ "frFR": "Prise en charge du déploiement de certificats en un clic sur plusieurs plateformes telles que Alibaba Cloud, Tencent Cloud, Pagoda Panel, 1Panel, etc.",
+ "esAR": "Soporte para implementar certificados con un clic en múltiples plataformas como Alibaba Cloud, Tencent Cloud, Pagoda Panel, 1Panel, etc.",
+ "arDZ": "دعم نشر الشهادات بنقرة واحدة على منصات متعددة مثل علي بابا كلاود، تينسنت كلاود، لوحة باغودا، 1Panel، إلخ."
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "站点监控:": {
+ "text": "站点监控:",
+ "key": "t_42_1746773348768",
+ "translations": {
+ "zhCN": "站点监控",
+ "zhTW": "站點監控",
+ "enUS": "Site monitoring",
+ "jaJP": "サイト監視",
+ "koKR": "사이트 모니터링",
+ "ruRU": "Мониторинг сайта",
+ "ptBR": "Monitoramento do site",
+ "frFR": "Surveillance du site",
+ "esAR": "Monitoreo del sitio",
+ "arDZ": "مراقبة الموقع"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "实时监控站点SSL证书状态,提前预警证书过期": {
+ "text": "实时监控站点SSL证书状态,提前预警证书过期",
+ "key": "t_43_1746773359511",
+ "translations": {
+ "zhCN": "实时监控站点SSL证书状态,提前预警证书过期",
+ "zhTW": "實時監控站點SSL證書狀態,提前預警證書過期",
+ "enUS": "Real-time monitoring of site SSL certificate status to provide early warning of certificate expiration",
+ "jaJP": "サイトのSSL証明書の状態をリアルタイムで監視し、証明書の有効期限切れを事前に警告します",
+ "koKR": "사이트 SSL 인증서 상태를 실시간으로 모니터링하여 인증서 만료를 사전에 경고합니다",
+ "ruRU": "Мониторинг состояния SSL-сертификатов сайта в режиме реального времени с предупреждением об истечении срока действия сертификата",
+ "ptBR": "Monitoramento em tempo real do status do certificado SSL do site para alertar sobre a expiração do certificado",
+ "frFR": "Surveillance en temps réel de l'état des certificats SSL du site pour prévenir l'expiration des certificats",
+ "esAR": "Monitoreo en tiempo real del estado de los certificados SSL del sitio para alertar sobre la expiración de los certificados",
+ "arDZ": "مراقبة حالة شهادات SSL للموقع في الوقت الفعلي للتحذير المسبق من انتهاء صلاحية الشهادة"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "自动化任务:": {
+ "text": "自动化任务:",
+ "key": "t_44_1746773352805",
+ "translations": {
+ "zhCN": "自动化任务:",
+ "zhTW": "自動化任務:",
+ "enUS": "Automation task:",
+ "jaJP": "自動化タスク:",
+ "koKR": "자동화 작업:",
+ "ruRU": "Автоматизированная задача:",
+ "ptBR": "Tarefa automatizada:",
+ "frFR": "Tâche automatisée :",
+ "esAR": "Tarea automatizada:",
+ "arDZ": "مهمة الأتمتة:"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "支持定时任务,自动续期证书并部署": {
+ "text": "支持定时任务,自动续期证书并部署",
+ "key": "t_45_1746773355717",
+ "translations": {
+ "zhCN": "支持定时任务,自动续期证书并部署",
+ "zhTW": "支援定時任務,自動續期證書並部署",
+ "enUS": "Support scheduled tasks, automatically renew certificates and deploy",
+ "jaJP": "スケジュールされたタスクをサポートし、証明書を自動的に更新して展開します",
+ "koKR": "예약된 작업 지원, 인증서 자동 갱신 및 배포",
+ "ruRU": "Поддержка запланированных задач, автоматическое продление сертификатов и развертывание",
+ "ptBR": "Suporta tarefas agendadas, renova automaticamente os certificados e implanta",
+ "frFR": "Prend en charge les tâches planifiées, renouvellement automatique des certificats et déploiement",
+ "esAR": "Admite tareas programadas, renovación automática de certificados e implementación",
+ "arDZ": "يدعم المهام المجدولة، تجديد الشهادات تلقائياً ونشرها"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "多平台支持:": {
+ "text": "多平台支持:",
+ "key": "t_46_1746773350579",
+ "translations": {
+ "zhCN": "多平台支持",
+ "zhTW": "多平台支援",
+ "enUS": "Multi-platform support",
+ "jaJP": "マルチプラットフォーム対応",
+ "koKR": "다중 플랫폼 지원",
+ "ruRU": "Поддержка нескольких платформ",
+ "ptBR": "Suporte multiplataforma",
+ "frFR": "Prise en charge multiplateforme",
+ "esAR": "Soporte multiplataforma",
+ "arDZ": "دعم متعدد المنصات"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "支持多种DNS提供商(阿里云、腾讯云等)的DNS验证方式": {
+ "text": "支持多种DNS提供商(阿里云、腾讯云等)的DNS验证方式",
+ "key": "t_47_1746773360760",
+ "translations": {
+ "zhCN": "支持多种DNS提供商(阿里云、腾讯云等)的DNS验证方式",
+ "zhTW": "支援多種DNS提供商(阿里雲、騰訊雲等)的DNS驗證方式",
+ "enUS": "Supports DNS verification methods for multiple DNS providers (Alibaba Cloud, Tencent Cloud, etc.)",
+ "jaJP": "複数のDNSプロバイダー(アリババクラウド、テンセントクラウドなど)のDNS検証方法をサポート",
+ "koKR": "다양한 DNS 제공업체(알리바바 클라우드, 텐센트 클라우드 등)의 DNS 확인 방법 지원",
+ "ruRU": "Поддерживает методы проверки DNS для нескольких поставщиков DNS (Alibaba Cloud, Tencent Cloud и др.)",
+ "ptBR": "Suporta métodos de verificação DNS para vários provedores de DNS (Alibaba Cloud, Tencent Cloud, etc.)",
+ "frFR": "Prend en charge les méthodes de vérification DNS pour plusieurs fournisseurs DNS (Alibaba Cloud, Tencent Cloud, etc.)",
+ "esAR": "Admite métodos de verificación DNS para múltiples proveedores de DNS (Alibaba Cloud, Tencent Cloud, etc.)",
+ "arDZ": "يدعم طرق التحقق DNS لعدة موفري DNS (Alibaba Cloud، Tencent Cloud، إلخ)"
+ },
+ "timestamp": "2025-05-09T06:49:24.475Z"
+ },
+ "确定要删除{0},通知渠道吗?": {
+ "text": "确定要删除{0},通知渠道吗?",
+ "key": "t_0_1746773763967",
+ "translations": {
+ "zhCN": "确定要删除{0},通知渠道吗?",
+ "zhTW": "確定要刪除{0},通知渠道嗎?",
+ "enUS": "Are you sure you want to delete {0}, the notification channel?",
+ "jaJP": "{0}、通知チャネルを削除してもよろしいですか?",
+ "koKR": "{0}, 알림 채널을 삭제하시겠습니까?",
+ "ruRU": "Вы уверены, что хотите удалить {0}, канал уведомлений?",
+ "ptBR": "Tem certeza que deseja excluir {0}, o canal de notificação?",
+ "frFR": "Êtes-vous sûr de vouloir supprimer {0}, le canal de notification ?",
+ "esAR": "¿Estás seguro de que deseas eliminar {0}, el canal de notificaciones?",
+ "arDZ": "هل أنت متأكد أنك تريد حذف {0}، قناة الإشعارات؟"
+ },
+ "timestamp": "2025-05-09T06:56:03.967Z"
+ },
+ "Let%27Encrypt等CA自动申请免费证书": {
+ "text": "Let%27Encrypt等CA自动申请免费证书",
+ "key": "t_1_1746773763643",
+ "translations": {
+ "zhCN": "Let's Encrypt等CA自动申请免费证书",
+ "zhTW": "Let's Encrypt等CA自動申請免費證書",
+ "enUS": "Let's Encrypt and other CAs automatically apply for free certificates",
+ "jaJP": "Let's EncryptなどのCAが無料の証明書を自動的に申請する",
+ "koKR": "Let's Encrypt 등의 CA에서 무료 인증서를 자동으로 신청",
+ "ruRU": "Let's Encrypt и другие центры сертификации автоматически подают заявки на бесплатные сертификаты",
+ "ptBR": "Let's Encrypt e outras autoridades de certificação solicitam automaticamente certificados gratuitos",
+ "frFR": "Let's Encrypt et d'autres CA demandent automatiquement des certificats gratuits",
+ "esAR": "Let's Encrypt y otras CA solicitan automáticamente certificados gratuitos",
+ "arDZ": "Let's Encrypt وغيرها من الجهات المصدقة تطلب شهادات مجانية تلقائيًا"
+ },
+ "timestamp": "2025-05-09T06:56:03.967Z"
+ }
+}
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/eslint.config.js b/frontend/apps/allin-ssl/eslint.config.js
new file mode 100644
index 0000000..19df2d8
--- /dev/null
+++ b/frontend/apps/allin-ssl/eslint.config.js
@@ -0,0 +1,22 @@
+import vueConfig from '@baota/eslint/vue'
+import baseConfig from '@baota/eslint'
+
+/** @type {import("eslint").Linter.Config[]} */
+const config = [
+ // Vue 相关配置,包含 TypeScript 支持
+ ...vueConfig,
+
+ // 基础配置,用于通用的 JavaScript/TypeScript 规则
+ ...baseConfig,
+
+ // 项目特定的配置覆盖
+ {
+ files: ['**/*.{js,ts,tsx,jsx,vue}'],
+ rules: {
+ // 在此处添加项目特定的规则覆盖
+ 'vue/multi-word-component-names': 'off', // 关闭组件名称必须由多个单词组成的规则
+ },
+ },
+]
+
+export default config
diff --git a/frontend/index.html b/frontend/apps/allin-ssl/index.html
similarity index 53%
rename from frontend/index.html
rename to frontend/apps/allin-ssl/index.html
index 3c2bd51..5863211 100644
--- a/frontend/index.html
+++ b/frontend/apps/allin-ssl/index.html
@@ -2,13 +2,12 @@
-
+
ALLinSSL
-
-
+
diff --git a/frontend/apps/allin-ssl/mardown/api.md b/frontend/apps/allin-ssl/mardown/api.md
new file mode 100644
index 0000000..9da8f11
--- /dev/null
+++ b/frontend/apps/allin-ssl/mardown/api.md
@@ -0,0 +1,28 @@
+分别生成以下相关的类型文件,在 types/ 目录下,以及 api 文件,在 api/目录下
+
+文件名称如下:
+home
+autoDeploy
+certManage
+certApply
+authAPIManage
+monitor
+settings
+
+1、types文件命名方式:{视图名称}.d.ts
+
+2、api文件命名方式:{视图名称}.ts
+
+3、api文件结构如下:
+
+```typescript
+import { useApi } from './index'
+import type { loginParams, loginResponse } from '@/types/public'
+
+/**
+ * 登录
+ * @param params 登录参数
+ * @returns 登录
+ */
+export const loginCloudControl = (params?: loginParams) => useApi('/v1/user/login', params)
+```
diff --git a/frontend/apps/allin-ssl/mardown/base.md b/frontend/apps/allin-ssl/mardown/base.md
new file mode 100644
index 0000000..6f7b830
--- /dev/null
+++ b/frontend/apps/allin-ssl/mardown/base.md
@@ -0,0 +1,273 @@
+
+
+目前接口返回格式
+```ts
+export interface AxiosResponseData {
+ code: number
+ count: number
+ data: T
+ message: string
+ status: boolean
+}
+```
+
+后端请求的协议方式,formdata 还是 json
+
+登录的方式,使用那种方案jwt,以及加密方式
+
+接口文档需要包含一下内容
+接口类型、接口返回值、以及其他需要处理的内容需要说清楚,例如登录失效,以及状态的判断
+
+
+
+
+基础要求
+1、基于vue3 的 tsx文件编写,并将业务和数据、视图分离成 mvc 模式,如果代码中没有包含业务和数据,可以移除该文件,确保结构单一和可维护性。
+2、视图文件文件入口为 index.tsx
+3、业务代码文件入口为 useController.tsx
+4、数据代码文件入口为 useStore.tsx
+5、使用hooks编写,如果存在表单、表格使用配置生成。参考如下
+
+
+视图文件内容要求
+1、所有的视图style,使用css module 编写,基于tailwind 的@apply 实现,如果行内元素少,可以省略创建css module。
+2、如果视图使用naiveui tsx 开发内容,如果没有相应的组件,则使用原生样式实现
+
+业务代码内容要求
+1、包含 hooks 配置的生成方法,需要导出
+2、事件逻辑处理、dom 操作、生命周期、监听函数等,
+3、数据代码转发,支持将 sotre 数据直接转发
+
+数据代码内容要求
+1、包含所有的数据内容,例如请求方法、表单数据处理
+2、响应式数据存储、持久化数据存储
+
+国际化内容要求
+1、将文件中的中文文本未使用 $t 包裹的内容,使用 $t('中文内容') 包裹起来,如果存在则引入 $t,import { $t } from "@locales/index"
+
+格式要求
+1、注释采用jsdoc格式,使用中文作为注释语言
+2、注释内容清晰,对同类的函数位置整理和功能使用注释分割线分
+3、方法名称规范化,根据类型和作用定义。
+
+
+
+
+基础视图参考:/Users/chudong/project/tools-monorepo/apps/allin-ssl/src/components/baseComponent/index.tsx
+
+
+首页模块设计
+1、界面设计
+ 包含三个模块,采用上下结构
+ * 概览模块包含工作流、证书、监控模块,每个模块,都具备所有数量、启用/到期/异常数量、失败/到期数量,以及对应产品图标
+ * 最近工作流执行列表,包含字段:
+ * 名称
+ * 执行状态
+ * 执行时间
+ * 快捷入口模块,提供常用的三个模块入口,工作流构建、申请证书、添加监控
+
+2、接口设计包含
+ * 概览数据接口
+ * 最近工作流列表
+
+工作流列表模块设计
+1、界面设计
+ 采用基础视图组件设计该页面,传入相关内容,
+ * 添加按钮文本:新增工作流
+ * 搜索框提示内容:请输入工作流名称
+ * 表格包含字段:
+ * 工作流名称
+ * 触发方式(自动执行或手动可切换)
+ * 启用状态(启用/停用)
+ * 最后一次执行时间
+ * 创建时间
+ * 操作(包含日志、执行、编辑、删除)
+ * 添加工作流按钮触发弹窗内容
+ * 弹窗界面包含多个具备概览图的单选项
+ * 常用SSL部署工作流
+ * 自定义工作流
+
+2、接口设计包含
+ * 工作流列表
+ * 获取指定工作流程数据
+ * 新建自定义工作流程数据
+ * 获取指定工作流执行日志
+ * 执行指定工作流
+ * 保存指定工作流程数据
+ * 删除指定工作流程数据
+
+
+工作流设计模块设计
+1、界面设计
+ 采用流程图构建组建,设计页面,需要设计一下节点设计,所有节点采用
+ * 申请SSL(表单设计)
+ * 域名信息(input、必填)
+ * 邮箱信息(input、非必填)
+ * DNS 提供商(select,支持添加,添加调用 API 授权页面的添加表单)
+ * 高级选项折叠
+ * 数字证书算法(select,支持字段RSA2048\RSA3072\RSA4096\RSA8192\EC256\EC384,默认使用RSA2048\)
+ * 指定DNS解析服务器(input,非必填,提示:申请证书过程中优先使用它)
+ * DNS超时时间(input、非必填)
+ * DNS解析TTL时间(input、非必填)
+ * 关闭CNAME跟随(switch,默认关闭)
+ * 关闭ARI续期(switch,默认关闭)
+ * 续签间隔(input,当上次签发的证书距离到期时间超过xx天后,跳过续签,使用 )
+ * 部署SSL到指定位置(表单设计,需要手动开发,使用 AI 生成消耗时间,而且基本上可用性低)
+ *
+ * 通知告警
+ * 通知主题(input、必填)
+ * 通知内容(textarea、必填)
+ * 选择通知渠道(select,右侧支持添加渠道)
+ *
+ * 并行分支
+ * 触发并行添加节点的功能
+ * 执行结果分支(只有节点是申请SSL、部署SSL到指定位置、通知告警节点后面才出现此分支提供选择)
+ * 触发条件判断分支,仅事件触发的节点支持添加该节点
+ * 节点执行成功后
+ * 节点执行失败后
+
+2、接口设计包含
+ * 获取API服务商列表
+ * 获取证书列表
+ * 获取网站列表(宝塔面板)
+ * 获取 CDN 加速域名(仅腾讯、阿里相关密钥获取)
+ * 获取 WAF 包含域名(仅腾讯、阿里相关密钥获取)
+
+
+证书管理列表模块设计
+1、界面设计
+ 采用基础视图组件设计该页面,传入相关内容,
+ * 添加按钮文本:上传证书
+ * 搜索框提示内容:请输入证书名称/类型
+ * 表格包含字段:
+ * 域名
+ * 品牌
+ * 剩余天数
+ * 到期时间
+ * 来源
+ * 添加时间
+ * 操作(下载、删除)
+ * 上传证书按钮触发弹窗内容
+ * 弹窗界面包含表单(支持证书压缩上传,识别腾讯、阿里下的证书压缩包文件)
+ * 证书名称
+ * 证书内容 (PEM 格式)
+ * 私钥内容 (KEY 格式)
+
+2、接口设计包含
+ * 获取证书列表
+ * 下载指定证书
+ * 上传证书信息
+ * 删除指定证书信息
+
+
+
+申请证书模块模块设计
+1、界面设计
+ 采用 tab 页面切换,分为商业证书页面和免费证书页面
+ * 商业证书采用,iframe 内嵌官网页面,官网页面需要新增一个界面作为兼容页面。
+ * 免费证书采用,卡片式设计界面,以便于后期支持其他渠道
+ * 证书申请表单
+ * 手动申请和自动部署的选项卡片(包含 icon 和文件描述)
+ * 手动申请,采用 DNS 验证自动认证的方式,参考面板的统一设计
+ * 自动化部署,直接调用工作流的界面。
+
+2、接口设计包含
+ * 申请证书信息
+ * 证书验证接口
+
+
+授权API管理列表模块设计
+1、界面设计
+ 采用基础视图组件设计该页面,传入相关内容,
+ * 添加按钮文本:上传授权 API 管理
+ * 搜索框提示内容:请输入授权api 名称或类型
+ * 表格包含字段:
+ * 名称
+ * 授权API类型(提供商,如腾讯云,宝塔面板)
+ * 创建时间
+ * 操作(编辑、删除)
+ * 上传证书按钮触发弹窗内容
+ * 弹窗界面包含表单
+ * 授权 API 类型(select,支持类型 SSH、宝塔、1panel、腾讯、阿里)
+ * 不同的类型显示不同的东西
+ * SSH
+ * 服务器IP(input)
+ * SSH端口(input,默认填充22)
+ * 用户名(input,默认填充root)
+ * 验证类型(radio-button)
+ 1. 密码
+ 2. SSH密钥
+ 1. SSH密钥口令
+ * 宝塔
+ * 地址(input,包含协议和端口)
+ * api 密钥(input)
+ * 1panel
+ * 地址(input,包含协议和端口)
+ * api 密钥(input)
+ * 阿里云
+ * AccessKeyId(input)
+ * AccessKeySecret(input)
+ * 腾讯云
+ * SecretId(input)
+ * SecretKey(input)
+
+2、接口设计包含
+ * 获取授权 api 列表
+ * 新建授权 api 信息
+ * 编辑指定授权 aai 信息
+ * 删除指定授权 api 信息
+
+
+监控管理列表模块设计
+1、界面设计
+ 采用基础视图组件设计该页面,传入相关内容,
+ * 添加按钮文本:添加监控
+ * 搜索框提示内容:请输入监控名称和域名
+ * 表格包含字段:
+ * 名称
+ * 授权API类型(提供商,如腾讯云,宝塔面板)
+ * 创建时间
+ * 操作(编辑、删除)
+ * 上传证书按钮触发弹窗内容
+ * 弹窗界面包含表单
+ * 监控名称(input)
+ * 域名/IP(input)
+ * 检查周期(select,5/10/15/30/60分钟)
+ * 告警渠道(多选,右侧支持添加渠道)
+2、接口设计包含
+ * 获取监控管理列表
+ * 设置指定监控启动状态
+ * 添加监控信息
+ * 编辑指定监控信息
+ * 删除指定监控信息
+
+
+设置管理模块设置
+1、界面设置
+ 采用 tab 页面切换,分为三个界面常用设置、告警通知、更新版本,内容部分采用卡片设计
+ * 常用设置(采用1:1 分栏设计,支持表单元素行显示),包含一下具体模块,采用统一保存的方式,保存按钮固定在顶部,避免设置过长的导致问题
+ * 超时时间(input)
+ * 管理员账号(input)
+ * 管理员密码(input)
+ * SSL 配置(switch,关闭,提供粘贴 key,pem 文本域输入,默认折叠隐藏)
+ * 告警通知(采用上下结构),包含全局通知模块和通知渠道配置两个模块
+ * 全局通知模块(表单)
+ * 通知主题(input,默认文字)
+ * 通知内容(textarea,默认文字)
+ * 通知渠道(卡片列表,参考面板的设计)
+ * 左侧图标名称(包含已配置数量,点击可查看)+右侧操作
+ * 关于我们
+ * 版本信息,支持更新版本
+ * 客服二维码
+ * 微信公众好
+ * 关于产品介绍
+
+2、接口设计包含
+ * 获取基础设置信息
+ * 保存基础设置信息
+ * 获取告警通用模板配置
+ * 设置告警通用模板配置
+ * 获取告警渠道列表
+ * 设置告警渠道
+ * 获取更新信息
+ * 更新版本版本
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/mardown/flowChart.md b/frontend/apps/allin-ssl/mardown/flowChart.md
new file mode 100644
index 0000000..ddf8501
--- /dev/null
+++ b/frontend/apps/allin-ssl/mardown/flowChart.md
@@ -0,0 +1,70 @@
+流程/工作流图拆封设计
+
+- 基础节点
+ - 初始化节点(不支持上传)
+ - 并行节点
+ - 执行结果节点(删除整个条件判断)
+
+- 任务节点
+ - 申请节点(支持执行结果判断)
+ - 上传节点(不支持执行结果判断)
+ - 部署节点(支持执行结果判断)
+ - 通知节点(支持执行结果判断)
+
+- 节点操作
+ - 重命名
+ - 删除
+
+- 节点下一步配置
+ - 申请
+ - 上传
+ - 部署
+ - 通知
+ - 执行结果判断(上传节点不支持)
+ - 并行
+
+- 节点辅助功能
+ - 拖拽
+ - 放大、缩小、还原
+
+- 节点验证
+ - 验证任务节点
+
+结构规划
+- 状态存储(包含节点默认配置数据)
+- 基础节点
+- 任务节点(可以根据外部的机构自由的构建任务节点,主要有节点条件,节点操作方法)
+- 节点渲染器
+- 工具方法
+- 入口文件
+
+
+
+
+工作流图组件
+├─ 状态存储
+│ └─ 节点默认配置数据
+├─ 基础节点
+│ ├─ 初始化节点
+│ ├─ 并行节点
+│ └─ 执行结果节点
+├─ 任务节点
+│ ├─ 申请节点
+│ ├─ 上传节点
+│ ├─ 部署节点
+│ └─ 通知节点
+├─ 节点渲染器
+│ └─ 渲染节点到界面
+├─ 工具方法
+│ ├─ 创建节点
+│ ├─ 重命名节点
+│ ├─ 删除节点
+│ ├─ 配置节点下一步
+│ ├─ 视图缩放
+│ └─ 流程验证
+└─ 入口文件
+ └─ 初始化工作流图组件
+
+
+
+
diff --git a/frontend/apps/allin-ssl/mardown/view.md b/frontend/apps/allin-ssl/mardown/view.md
new file mode 100644
index 0000000..d8a3a59
--- /dev/null
+++ b/frontend/apps/allin-ssl/mardown/view.md
@@ -0,0 +1,95 @@
+以下是当前项目的视图结构,参考/src/view/test 的目录结构和内容,生成下述的文件和内容
+src/
+├── views/
+│ ├── home/
+│ │ ├── index.tsx
+│ │ ├── index.model.css
+│ │ ├── useController.tsx
+│ │ ├── useStore.tsx
+│ ├── autoDeploy/
+│ │ ├── index.tsx
+│ │ ├── index.model.css
+│ │ ├── useController.tsx
+│ │ ├── useStore.tsx
+│ │ └── children/
+│ │ └── pipeDesign/
+│ │ ├── index.tsx
+│ │ ├── index.model.css
+│ │ ├── useController.tsx
+│ │ └── useStore.tsx
+│ ├── certManage/
+│ │ ├── index.tsx
+│ │ ├── index.model.css
+│ │ ├── useController.tsx
+│ │ ├── useStore.tsx
+│ │ └── components/
+│ │ └── uploadCert/
+│ │ ├── index.tsx
+│ │ ├── index.model.css
+│ │ ├── useController.tsx
+│ │ └── useStore.tsx
+│ ├── certApply/
+│ │ ├── index.tsx
+│ │ ├── index.model.css
+│ │ ├── useController.tsx
+│ │ ├── useStore.tsx
+│ │ ├── components/
+│ │ │ └── certApplyForm/
+│ │ │ ├── index.tsx
+│ │ │ ├── index.model.css
+│ │ │ ├── useController.tsx
+│ │ │ └── useStore.tsx
+│ │ └── children/
+│ │ ├── commCert/
+│ │ │ ├── index.tsx
+│ │ │ ├── index.model.css
+│ │ │ ├── useController.tsx
+│ │ │ └── useStore.tsx
+│ │ └── freeSslCert/
+│ │ ├── index.tsx
+│ │ ├── index.model.css
+│ │ ├── useController.tsx
+│ │ └── useStore.tsx
+│ ├── authApiManage/
+│ │ ├── index.tsx
+│ │ ├── index.model.css
+│ │ ├── useController.tsx
+│ │ ├── useStore.tsx
+│ │ └── components/
+│ │ └── addAuthApi/
+│ │ ├── index.tsx
+│ │ ├── index.model.css
+│ │ ├── useController.tsx
+│ │ └── useStore.tsx
+│ ├── monitor/
+│ │ ├── index.tsx
+│ │ ├── index.model.css
+│ │ ├── useController.tsx
+│ │ ├── useStore.tsx
+│ │ └── components/
+│ │ └── addMonitor/
+│ │ ├── index.tsx
+│ │ ├── index.model.css
+│ │ ├── useController.tsx
+│ │ └── useStore.tsx
+│ └── settings/
+│ ├── index.tsx
+│ ├── index.model.css
+│ ├── useController.tsx
+│ ├── useStore.tsx
+│ └── components/
+│ ├── commSettings/
+│ │ ├── index.tsx
+│ │ ├── index.model.css
+│ │ ├── useController.tsx
+│ │ └── useStore.tsx
+│ ├── notifySettings/
+│ │ ├── index.tsx
+│ │ ├── index.model.css
+│ │ ├── useController.tsx
+│ │ └── useStore.tsx
+│ └── aboutUs/
+│ ├── index.tsx
+│ ├── index.model.css
+│ ├── useController.tsx
+│ └── useStore.tsx
diff --git a/frontend/apps/allin-ssl/mock/access.ts b/frontend/apps/allin-ssl/mock/access.ts
new file mode 100644
index 0000000..3b535ec
--- /dev/null
+++ b/frontend/apps/allin-ssl/mock/access.ts
@@ -0,0 +1,96 @@
+import Mock from 'mockjs'
+import { listTemplate, messageTemplate } from './template'
+
+// 授权列表
+export const getAccessList = Mock.mock(/\/access\/get_list/, 'post', () => {
+ const list = []
+ for (let i = 0; i < 10; i++) {
+ list.push({
+ id: Mock.Random.id(),
+ name: `授权-${Mock.Random.ctitle(3, 5)}`,
+ type: Mock.Random.pick(['ssh', 'btpanel', '1panel', 'aliyun', 'tencent']),
+ status: Mock.Random.integer(0, 1),
+ created_at: Mock.Random.datetime('yyyy-MM-dd HH:mm:ss'),
+ })
+ }
+ return {
+ code: 0,
+ count: list.length,
+ data: {
+ list,
+ total: 18,
+ },
+ message: '获取成功',
+ status: true,
+ }
+})
+
+// 授权类型列表
+export const getAccessTypes = Mock.mock(/\/access\/get_access_types/, 'post', () => ({
+ code: 0,
+ count: 3,
+ data: [
+ { key: 'ssh', name: 'SSH验证' },
+ { key: 'btpanel', name: '宝塔验证' },
+ { key: '1panel', name: '1Panel验证' },
+ { key: 'aliyun', name: '阿里云验证' },
+ { key: 'tencentcloud', name: '腾讯云验证' },
+ ],
+ message: '获取成功',
+ status: true,
+}))
+
+// 新增授权
+export const addAccess = Mock.mock(/\/access\/add_access/, 'post', () => ({
+ code: 0,
+ count: 0,
+ data: {
+ id: Mock.Random.id(),
+ },
+ message: '添加成功',
+ status: true,
+}))
+
+// 修改授权
+export const updateAccess = Mock.mock(/\/access\/upd_access/, 'post', () => ({
+ code: 0,
+ count: 0,
+ data: {
+ id: Mock.Random.id(),
+ },
+ message: '修改成功',
+ status: true,
+}))
+
+// 删除授权
+export const deleteAccess = Mock.mock(/\/access\/del_access/, 'post', () => ({
+ code: 0,
+ count: 0,
+ data: null,
+ message: '删除成功',
+ status: true,
+}))
+
+// 获取工作流 dns 配置
+
+export const getAccessAllList = Mock.mock(/\/access\/get_all/, 'post', () => {
+ const list: Array<{ id: string; name: string; type: string }> = []
+ for (let i = 0; i < 3; i++) {
+ const group = Mock.Random.pick([
+ { name: '阿里云', type: 'aliyun' },
+ { name: '腾讯云', type: 'tencentcloud' },
+ ])
+ list.push({
+ id: Mock.Random.id(),
+ name: `${group.name} DNS 配置`,
+ type: group.type,
+ })
+ }
+ return {
+ code: 0,
+ count: list.length,
+ data: list,
+ message: '获取成功',
+ status: true,
+ }
+})
diff --git a/frontend/apps/allin-ssl/mock/cert.ts b/frontend/apps/allin-ssl/mock/cert.ts
new file mode 100644
index 0000000..34c773d
--- /dev/null
+++ b/frontend/apps/allin-ssl/mock/cert.ts
@@ -0,0 +1,70 @@
+import Mock from 'mockjs'
+import { listTemplate, messageTemplate } from './template'
+
+// 证书列表
+export const getCertList = Mock.mock(/\/cert\/get_list/, 'post', () => {
+ const list = []
+ for (let i = 0; i < 15; i++) {
+ list.push({
+ id: Mock.Random.id(),
+ name: `${Mock.Random.domain()}证书`,
+ domain: Mock.Random.domain(),
+ expire_time: Mock.Random.datetime('yyyy-MM-dd'),
+ status: Mock.Random.integer(0, 2),
+ created_at: Mock.Random.datetime('yyyy-MM-dd HH:mm:ss'),
+ })
+ }
+ return {
+ code: 0,
+ count: list.length,
+ data: {
+ list,
+ total: 32,
+ },
+ message: '获取成功',
+ status: true,
+ }
+})
+
+// 申请证书
+export const applyCert = Mock.mock(/\/cert\/apply_cert/, 'post', () => ({
+ code: 0,
+ count: 0,
+ data: {
+ id: Mock.Random.id(),
+ },
+ message: '申请成功',
+ status: true,
+}))
+
+// 上传证书
+export const uploadCert = Mock.mock(/\/cert\/upload_cert/, 'post', () => ({
+ code: 0,
+ count: 0,
+ data: {
+ id: Mock.Random.id(),
+ },
+ message: '上传成功',
+ status: true,
+}))
+
+// 删除证书
+export const deleteCert = Mock.mock(/\/cert\/del_cert/, 'post', () => ({
+ code: 0,
+ count: 0,
+ data: null,
+ message: '删除成功',
+ status: true,
+}))
+
+// 下载证书
+export const downloadCert = Mock.mock(/\/cert\/download_cert/, 'get', () => {
+ // 二进制文件流模拟,实际上应该是从服务器获取的二进制数据
+ return {
+ code: 0,
+ count: 0,
+ data: 'certificate-file-content',
+ message: '下载成功',
+ status: true,
+ }
+})
diff --git a/frontend/apps/allin-ssl/mock/index.ts b/frontend/apps/allin-ssl/mock/index.ts
new file mode 100644
index 0000000..3d2559f
--- /dev/null
+++ b/frontend/apps/allin-ssl/mock/index.ts
@@ -0,0 +1,9 @@
+// 导出所有模块
+export * from './userInfo' // 示例接口
+export * from './overview'
+export * from './workflow'
+export * from './cert'
+export * from './access'
+export * from './siteMonitor'
+export * from './setting'
+export * from './login'
diff --git a/frontend/apps/allin-ssl/mock/login.ts b/frontend/apps/allin-ssl/mock/login.ts
new file mode 100644
index 0000000..21843c5
--- /dev/null
+++ b/frontend/apps/allin-ssl/mock/login.ts
@@ -0,0 +1,14 @@
+import Mock from 'mockjs'
+import { listTemplate, messageTemplate } from './template'
+
+// 登录
+export const login = Mock.mock(/\/login\/login/, 'post', () => ({
+ code: 0,
+ count: 0,
+ data: {
+ token:
+ 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNjE0NjE5MDQ2LCJleHAiOjE2MTQ3MDU0NDZ9._QS2nQa2FRpqH7zJSnjYVBXCOp7-QR-zrXsHl6dTHaU',
+ },
+ message: '登录成功',
+ status: true,
+}))
diff --git a/frontend/apps/allin-ssl/mock/overview.ts b/frontend/apps/allin-ssl/mock/overview.ts
new file mode 100644
index 0000000..f243a06
--- /dev/null
+++ b/frontend/apps/allin-ssl/mock/overview.ts
@@ -0,0 +1,58 @@
+import Mock from 'mockjs'
+import { listTemplate, messageTemplate } from './template'
+
+// 获取首页概览
+export const getOverviews = Mock.mock(/\/overview\/get_overviews/, 'post', () => ({
+ code: 0,
+ count: 0,
+ data: {
+ workfolw: {
+ count: Mock.Random.integer(150, 250),
+ active: Mock.Random.integer(120, 200),
+ failure: Mock.Random.integer(0, 10),
+ },
+ cert: {
+ count: Mock.Random.integer(30, 80),
+ will: Mock.Random.integer(5, 15),
+ end: Mock.Random.integer(0, 5),
+ },
+ site_monitor: {
+ count: Mock.Random.integer(80, 150),
+ exception: Mock.Random.integer(0, 8),
+ },
+ workflow_history: [
+ {
+ name: '服务A部署流水线',
+ state: Mock.Random.integer(-1, 1),
+ mode: Mock.Random.pick(['定时触发', '手动触发']),
+ exec_time: Mock.Random.datetime('yyyy-MM-dd HH:mm'),
+ },
+ {
+ name: '1panel 面板证书部署流水线',
+ state: Mock.Random.integer(-1, 1),
+ mode: Mock.Random.pick(['定时触发', '手动触发']),
+ exec_time: Mock.Random.datetime('yyyy-MM-dd HH:mm'),
+ },
+ {
+ name: '网站证书申请流水线',
+ state: Mock.Random.integer(-1, 1),
+ mode: Mock.Random.pick(['定时触发', '手动触发']),
+ exec_time: Mock.Random.datetime('yyyy-MM-dd HH:mm'),
+ },
+ {
+ name: '网站证书申请流水线',
+ state: Mock.Random.integer(-1, 1),
+ mode: Mock.Random.pick(['定时触发', '手动触发']),
+ exec_time: Mock.Random.datetime('yyyy-MM-dd HH:mm'),
+ },
+ {
+ name: '网站证书申请流水线',
+ state: Mock.Random.integer(-1, 1),
+ mode: Mock.Random.pick(['定时触发', '手动触发']),
+ exec_time: Mock.Random.datetime('yyyy-MM-dd HH:mm'),
+ },
+ ],
+ },
+ message: '获取成功',
+ status: true,
+}))
diff --git a/frontend/apps/allin-ssl/mock/setting.ts b/frontend/apps/allin-ssl/mock/setting.ts
new file mode 100644
index 0000000..5246748
--- /dev/null
+++ b/frontend/apps/allin-ssl/mock/setting.ts
@@ -0,0 +1,87 @@
+import Mock from 'mockjs'
+import { listTemplate, messageTemplate } from './template'
+
+// 获取系统设置
+export const getSystemSetting = Mock.mock(/\/setting\/get_setting/, 'post', () => ({
+ code: 0,
+ count: 0,
+ data: {
+ auto_renew: true,
+ renew_days: 30,
+ notify_enable: true,
+ notify_days: 15,
+ },
+ message: '获取成功',
+ status: true,
+}))
+
+// 保存系统设置
+export const saveSystemSetting = Mock.mock(/\/setting\/save_setting/, 'post', () => ({
+ code: 0,
+ count: 0,
+ data: null,
+ message: '保存成功',
+ status: true,
+}))
+
+// 获取告警类型列表
+export const getReportTypes = Mock.mock(/\/setting\/get_report_types/, 'post', () => ({
+ code: 0,
+ count: 4,
+ data: [
+ { key: 'email', name: '邮件通知' },
+ { key: 'sms', name: '短信通知' },
+ { key: 'webhook', name: 'Webhook' },
+ { key: 'dingtalk', name: '钉钉通知' },
+ ],
+ message: '获取成功',
+ status: true,
+}))
+
+// 配置告警
+export const setReport = Mock.mock(/\/setting\/set_report/, 'post', () => ({
+ code: 0,
+ count: 0,
+ data: null,
+ message: '配置成功',
+ status: true,
+}))
+
+// 删除告警
+export const deleteReport = Mock.mock(/\/setting\/del_report/, 'post', () => ({
+ code: 0,
+ count: 0,
+ data: null,
+ message: '删除成功',
+ status: true,
+}))
+
+// 获取证书过期通知模板
+export const getCertEndNoticeTemplate = Mock.mock(/\/setting\/get_certend_notice_temp/, 'post', () => ({
+ code: 0,
+ count: 0,
+ data: {
+ title: '证书即将过期通知',
+ content: '您的证书 {{domain}} 将在 {{days}} 天后过期,请及时更新。',
+ },
+ message: '获取成功',
+ status: true,
+}))
+
+// 保存证书过期通知模板
+export const saveCertEndNoticeTemplate = Mock.mock(/\/setting\/save_certend_notice_temp/, 'post', () => ({
+ code: 0,
+ count: 0,
+ data: null,
+ message: '保存成功',
+ status: true,
+}))
+
+// 系统更新
+export const systemUpdate = Mock.mock(/\/setting\/update/, 'post', () => ({
+ code: 0,
+ count: 0,
+ data: null,
+ message: '更新成功',
+ status: true,
+}))
diff --git a/frontend/apps/allin-ssl/mock/siteMonitor.ts b/frontend/apps/allin-ssl/mock/siteMonitor.ts
new file mode 100644
index 0000000..96d13ee
--- /dev/null
+++ b/frontend/apps/allin-ssl/mock/siteMonitor.ts
@@ -0,0 +1,68 @@
+import Mock from 'mockjs'
+import { listTemplate, messageTemplate } from './template'
+
+// 站点监控列表
+export const getSiteMonitorList = Mock.mock(/\/siteMonitor\/get_list/, 'post', () => {
+ const list = []
+ for (let i = 0; i < 12; i++) {
+ list.push({
+ id: Mock.Random.id(),
+ name: `${Mock.Random.ctitle(2, 5)}网站监控`,
+ url: `https://${Mock.Random.domain()}/api/${Mock.Random.word(3, 8)}`,
+ type: Mock.Random.pick(['HTTP', 'HTTPS', 'TCP', 'PING']),
+ status: Mock.Random.integer(0, 1),
+ check_result: Mock.Random.pick(['连接成功', '超时', '证书有效', '证书已过期']),
+ created_at: Mock.Random.datetime('yyyy-MM-dd HH:mm:ss'),
+ })
+ }
+ return {
+ code: 0,
+ count: list.length,
+ data: {
+ list,
+ total: 25,
+ },
+ message: '获取成功',
+ status: true,
+ }
+})
+
+// 新增站点监控
+export const addSiteMonitor = Mock.mock(/\/siteMonitor\/add_site_monitor/, 'post', () => ({
+ code: 0,
+ count: 0,
+ data: {
+ id: Mock.Random.id(),
+ },
+ message: '添加成功',
+ status: true,
+}))
+
+// 修改站点监控
+export const updateSiteMonitor = Mock.mock(/\/siteMonitor\/upd_site_monitor/, 'post', () => ({
+ code: 0,
+ count: 0,
+ data: {
+ id: Mock.Random.id(),
+ },
+ message: '修改成功',
+ status: true,
+}))
+
+// 删除站点监控
+export const deleteSiteMonitor = Mock.mock(/\/siteMonitor\/del_site_monitor/, 'post', () => ({
+ code: 0,
+ count: 0,
+ data: null,
+ message: '删除成功',
+ status: true,
+}))
+
+// 启用/禁用站点监控
+export const setSiteMonitor = Mock.mock(/\/siteMonitor\/set_site_monitor/, 'post', () => ({
+ code: 0,
+ count: 0,
+ data: null,
+ message: '设置成功',
+ status: true,
+}))
diff --git a/frontend/apps/allin-ssl/mock/template.ts b/frontend/apps/allin-ssl/mock/template.ts
new file mode 100644
index 0000000..d834533
--- /dev/null
+++ b/frontend/apps/allin-ssl/mock/template.ts
@@ -0,0 +1,24 @@
+/**
+ * @description 成功模板
+ * @param {string} msg 消息
+ * @returns
+ */
+export const listTemplate = (data: T, count: number) => ({
+ code: 200, // 状态码
+ count, // 总数,仅data 为数组时有效
+ data, // 数据
+ message: '', // 消息
+ status: true, // 消息状态,true 为成功,false 为失败
+})
+
+/**
+ * @description 消息模板
+ * @param {object} data 数据
+ * @returns
+ */
+export const messageTemplate = (message: string, status: boolean) => ({
+ code: 200, // 状态码
+ count: 0, // 总数,仅data 为数组时有效
+ message, // 消息
+ status, // 消息状态,true 为成功,false 为失败
+})
diff --git a/frontend/apps/allin-ssl/mock/userInfo.ts b/frontend/apps/allin-ssl/mock/userInfo.ts
new file mode 100644
index 0000000..443dbc4
--- /dev/null
+++ b/frontend/apps/allin-ssl/mock/userInfo.ts
@@ -0,0 +1,26 @@
+import Mock from 'mockjs'
+import { listTemplate, messageTemplate } from './template'
+
+// 用户列表 (案例接口)
+export const listUser = Mock.mock(
+ /\/api\/user\/list/,
+ 'post',
+ listTemplate(
+ {
+ id: '@id',
+ name: '@cname',
+ avatar: '@image',
+ 'age|18-60': 18,
+ 'gender|1': ['男', '女'],
+ phone: /^1[385][1-9]\d{8}/,
+ email: '@EMAIL',
+ address: '@county(true)',
+ 'role|1': ['admin', 'user'],
+ },
+ 100,
+ ),
+)
+
+// 用户详情 (案例接口)
+export const addUser = Mock.mock(/\/api\/user\/add/, 'post', messageTemplate('添加成功', true))
+
diff --git a/frontend/apps/allin-ssl/mock/workflow.ts b/frontend/apps/allin-ssl/mock/workflow.ts
new file mode 100644
index 0000000..32d4a8e
--- /dev/null
+++ b/frontend/apps/allin-ssl/mock/workflow.ts
@@ -0,0 +1,90 @@
+import Mock from 'mockjs'
+import { listTemplate, messageTemplate } from './template'
+
+// 工作流列表
+export const getWorkflowList = Mock.mock(/\/workflow\/get_list/, 'post', () => {
+ const list = []
+ for (let i = 0; i < 10; i++) {
+ list.push({
+ id: Mock.Random.id(),
+ name: `${Mock.Random.ctitle(3, 8)}部署流水线`,
+ type: Mock.Random.pick(['auto', 'manual']),
+ status: Mock.Random.integer(0, 1),
+ created_at: Mock.Random.datetime('yyyy-MM-dd HH:mm:ss'),
+ updated_at: Mock.Random.datetime('yyyy-MM-dd HH:mm:ss'),
+ })
+ }
+ return {
+ code: 0,
+ count: list.length,
+ data: {
+ list,
+ total: 28,
+ },
+ message: '获取成功',
+ status: true,
+ }
+})
+
+// 新增工作流
+export const addWorkflow = Mock.mock(/\/workflow\/add_workflow/, 'post', () => ({
+ code: 0,
+ count: 0,
+ data: {
+ id: Mock.Random.id(),
+ },
+ message: '添加成功',
+ status: true,
+}))
+
+// 修改工作流
+export const updateWorkflow = Mock.mock(/\/workflow\/upd_workflow/, 'post', () => ({
+ code: 0,
+ count: 0,
+ data: {
+ id: Mock.Random.id(),
+ },
+ message: '修改成功',
+ status: true,
+}))
+
+// 删除工作流
+export const deleteWorkflow = Mock.mock(/\/workflow\/del_workflow/, 'post', () => ({
+ code: 0,
+ count: 0,
+ data: null,
+ message: '删除成功',
+ status: true,
+}))
+
+// 获取工作流执行历史
+export const getWorkflowHistory = Mock.mock(/\/workflow\/get_workflow_history/, 'post', () => {
+ const list = []
+ for (let i = 0; i < 10; i++) {
+ list.push({
+ id: Mock.Random.id(),
+ workflow_id: Mock.Random.id(),
+ workflow_name: `${Mock.Random.ctitle(3, 8)}部署流水线`,
+ state: Mock.Random.integer(-1, 1),
+ mode: Mock.Random.pick(['定时触发', '手动触发']),
+ exec_time: Mock.Random.datetime('yyyy-MM-dd HH:mm:ss'),
+ })
+ }
+ return {
+ code: 0,
+ count: list.length,
+ data: list,
+ message: '获取成功',
+ status: true,
+ }
+})
+
+// 手动执行工作流
+export const executeWorkflow = Mock.mock(/\/workflow\/execute_workflow/, 'post', () => ({
+ code: 0,
+ count: 0,
+ data: null,
+ message: '执行成功',
+ status: true,
+}))
+
diff --git a/frontend/apps/allin-ssl/package.json b/frontend/apps/allin-ssl/package.json
new file mode 100644
index 0000000..b5c10eb
--- /dev/null
+++ b/frontend/apps/allin-ssl/package.json
@@ -0,0 +1,87 @@
+{
+ "name": "allin-ssl",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite --host",
+ "build": "vite build --mode build",
+ "preview": "vite preview",
+ "test": "vitest",
+ "tsc": "vue-tsc -b --noEmit",
+ "lint:ts": "eslint --ext .ts,.js src --fix",
+ "lint:style": "stylelint --config .stylelintrc.cjs --fix",
+ "lint": "npm run lint:ts && npm run lint:style"
+ },
+ "dependencies": {
+ "@baota/hooks": "workspace:*",
+ "@baota/i18n": "workspace:*",
+ "@baota/naive-ui": "workspace:*",
+ "@baota/pinia": "workspace:*",
+ "@baota/router": "workspace:*",
+ "@baota/utils": "workspace:*",
+ "@vicons/antd": "^0.13.0",
+ "@vicons/carbon": "^0.13.0",
+ "@vicons/fa": "^0.13.0",
+ "@vicons/fluent": "^0.13.0",
+ "@vicons/ionicons5": "^0.13.0",
+ "@vicons/tabler": "^0.13.0",
+ "@vue-flow/background": "^1.3.2",
+ "@vue-flow/controls": "^1.1.2",
+ "@vue-flow/core": "^1.42.5",
+ "@vue-flow/minimap": "^1.5.3",
+ "@vue-flow/node-toolbar": "^1.1.1",
+ "@vueuse/core": "^12.4.0",
+ "@vueuse/integrations": "^12.4.0",
+ "axios": "^1.7.9",
+ "crypto-js": "^4.1.1",
+ "echarts": "^5.6.0",
+ "jsoneditor": "^10.2.0",
+ "naive-ui": "^2.41.0",
+ "normalize.css": "^8.0.1",
+ "nprogress": "^0.2.0",
+ "particlesjs": "^2.2.3",
+ "pinia": "^2.3.0",
+ "pinia-plugin-persistedstate": "^4.2.0",
+ "uuid": "^11.1.0",
+ "vue": "^3.5.13",
+ "vue-i18n": "^11.1.2",
+ "vue-router": "^4.5.0"
+ },
+ "devDependencies": {
+ "@baota/eslint": "workspace:*",
+ "@baota/plugin-i18n": "workspace:*",
+ "@baota/prettier": "workspace:*",
+ "@baota/stylelint": "workspace:*",
+ "@baota/typescript": "workspace:*",
+ "@baota/project-ftp-sync": "workspace:*",
+ "@types/crypto-js": "^4.1.1",
+ "@types/humps": "^2.0.6",
+ "@types/md5": "^2.3.5",
+ "@types/minimist": "^1.2.5",
+ "@types/mockjs": "^1.0.10",
+ "@types/node": "^22.10.7",
+ "@types/ramda": "^0.30.2",
+ "@vitejs/plugin-basic-ssl": "^1.2.0",
+ "@vitejs/plugin-legacy": "^6.0.0",
+ "@vitejs/plugin-vue": "^5.2.1",
+ "@vitejs/plugin-vue-jsx": "^4.1.1",
+ "@vue/tsconfig": "^0.7.0",
+ "autoprefixer": "^10.4.20",
+ "humps": "^2.0.1",
+ "minimist": "^1.2.8",
+ "mockjs": "^1.1.0",
+ "postcss": "^8.5.1",
+ "tailwindcss": "^3.4.17",
+ "typescript-plugin-css-modules": "^5.1.0",
+ "unplugin-auto-import": "^19.0.0",
+ "unplugin-vue-components": "^28.0.0",
+ "vite": "^6.0.5",
+ "vite-plugin-compression2": "^1.3.3",
+ "vite-plugin-svg-icons": "2.0.1",
+ "vite-plugin-vue-devtools": "^7.7.0",
+ "vite-plugin-vue-mcp": "^0.3.2",
+ "vitest": "^3.0.2",
+ "vue-tsc": "^2.2.0"
+ }
+}
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/postcss.config.js b/frontend/apps/allin-ssl/postcss.config.js
new file mode 100644
index 0000000..1a52624
--- /dev/null
+++ b/frontend/apps/allin-ssl/postcss.config.js
@@ -0,0 +1,6 @@
+export default {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
+}
diff --git a/frontend/apps/allin-ssl/prettier.config.js b/frontend/apps/allin-ssl/prettier.config.js
new file mode 100644
index 0000000..87c65c9
--- /dev/null
+++ b/frontend/apps/allin-ssl/prettier.config.js
@@ -0,0 +1,3 @@
+import prettierConfig from '@baota/prettier'
+
+export default prettierConfig
diff --git a/frontend/apps/allin-ssl/public/.DS_Store b/frontend/apps/allin-ssl/public/.DS_Store
new file mode 100644
index 0000000..3b9b356
Binary files /dev/null and b/frontend/apps/allin-ssl/public/.DS_Store differ
diff --git a/frontend/favicon.ico b/frontend/apps/allin-ssl/public/favicon.ico
similarity index 100%
rename from frontend/favicon.ico
rename to frontend/apps/allin-ssl/public/favicon.ico
diff --git a/frontend/static/.DS_Store b/frontend/apps/allin-ssl/public/static/.DS_Store
similarity index 81%
rename from frontend/static/.DS_Store
rename to frontend/apps/allin-ssl/public/static/.DS_Store
index aa1b331..179b23a 100644
Binary files a/frontend/static/.DS_Store and b/frontend/apps/allin-ssl/public/static/.DS_Store differ
diff --git a/frontend/static/icons/letsencrypt-icon.svg b/frontend/apps/allin-ssl/public/static/icons/letsencrypt-icon.svg
similarity index 100%
rename from frontend/static/icons/letsencrypt-icon.svg
rename to frontend/apps/allin-ssl/public/static/icons/letsencrypt-icon.svg
diff --git a/frontend/static/icons/positive-ico.png b/frontend/apps/allin-ssl/public/static/icons/positive-ico.png
similarity index 100%
rename from frontend/static/icons/positive-ico.png
rename to frontend/apps/allin-ssl/public/static/icons/positive-ico.png
diff --git a/frontend/static/icons/sectigo-ico.png b/frontend/apps/allin-ssl/public/static/icons/sectigo-ico.png
similarity index 100%
rename from frontend/static/icons/sectigo-ico.png
rename to frontend/apps/allin-ssl/public/static/icons/sectigo-ico.png
diff --git a/frontend/static/icons/ssltrus-ico.png b/frontend/apps/allin-ssl/public/static/icons/ssltrus-ico.png
similarity index 100%
rename from frontend/static/icons/ssltrus-ico.png
rename to frontend/apps/allin-ssl/public/static/icons/ssltrus-ico.png
diff --git a/frontend/static/images/.DS_Store b/frontend/apps/allin-ssl/public/static/images/.DS_Store
similarity index 100%
rename from frontend/static/images/.DS_Store
rename to frontend/apps/allin-ssl/public/static/images/.DS_Store
diff --git a/frontend/static/images/container.png b/frontend/apps/allin-ssl/public/static/images/container.png
similarity index 100%
rename from frontend/static/images/container.png
rename to frontend/apps/allin-ssl/public/static/images/container.png
diff --git a/frontend/static/images/login-bg-dark.svg b/frontend/apps/allin-ssl/public/static/images/login-bg-dark.svg
similarity index 100%
rename from frontend/static/images/login-bg-dark.svg
rename to frontend/apps/allin-ssl/public/static/images/login-bg-dark.svg
diff --git a/frontend/static/images/login-bg.svg b/frontend/apps/allin-ssl/public/static/images/login-bg.svg
similarity index 100%
rename from frontend/static/images/login-bg.svg
rename to frontend/apps/allin-ssl/public/static/images/login-bg.svg
diff --git a/frontend/static/images/login-display.svg b/frontend/apps/allin-ssl/public/static/images/login-display.svg
similarity index 100%
rename from frontend/static/images/login-display.svg
rename to frontend/apps/allin-ssl/public/static/images/login-display.svg
diff --git a/frontend/static/images/logo.png b/frontend/apps/allin-ssl/public/static/images/logo.png
similarity index 100%
rename from frontend/static/images/logo.png
rename to frontend/apps/allin-ssl/public/static/images/logo.png
diff --git a/frontend/static/images/site.png b/frontend/apps/allin-ssl/public/static/images/site.png
similarity index 100%
rename from frontend/static/images/site.png
rename to frontend/apps/allin-ssl/public/static/images/site.png
diff --git a/frontend/apps/allin-ssl/script/create-alias.sh b/frontend/apps/allin-ssl/script/create-alias.sh
new file mode 100644
index 0000000..0ac170b
--- /dev/null
+++ b/frontend/apps/allin-ssl/script/create-alias.sh
@@ -0,0 +1,145 @@
+#!/bin/bash
+
+# 获取脚本所在目录的绝对路径
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+# 项目根目录
+PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
+# src 目录
+SRC_DIR="$PROJECT_ROOT/src"
+# tmp 目录
+TMP_DIR="$PROJECT_ROOT/.temp"
+
+# 临时文件
+TEMP_PATHS_FILE="$TMP_DIR/tsconfig_paths.json"
+TEMP_ALIAS_FILE="$TMP_DIR/vite_alias.js"
+
+# 清理函数
+cleanup() {
+ echo "清理临时文件..."
+ rm -rf "$TMP_DIR"
+}
+
+# 错误处理
+handle_error() {
+ echo "错误: $1"
+ cleanup
+ exit 1
+}
+
+# 注册清理函数
+trap cleanup EXIT
+
+# 检查并创建 tmp 目录
+if [ ! -d "$TMP_DIR" ]; then
+ echo "创建临时目录: $TMP_DIR"
+ mkdir -p "$TMP_DIR" || handle_error "无法创建临时目录"
+fi
+
+# 初始化临时文件
+echo "{" > "$TEMP_PATHS_FILE"
+echo "import path from 'path'" > "$TEMP_ALIAS_FILE"
+echo "export default {" >> "$TEMP_ALIAS_FILE"
+
+# 处理 views 目录下的第一层目录
+if [ -d "$SRC_DIR/views" ]; then
+ echo "处理 views 目录..."
+ # 确保没有尾随逗号的最后一个条目
+ view_dirs=()
+ while IFS= read -r dir; do
+ if [ -d "$dir" ]; then
+ dir_name=$(basename "$dir")
+ view_dirs+=("$dir_name")
+ fi
+ done < <(find "$SRC_DIR/views" -mindepth 1 -maxdepth 1 -type d)
+
+ # 处理 views 子目录
+ total=${#view_dirs[@]}
+ for ((i=0; i> "$TEMP_PATHS_FILE"
+ echo " '@$dir_name': path.resolve(__dirname, 'src/views/$dir_name')," >> "$TEMP_ALIAS_FILE"
+ # 如果不是最后一个元素,添加逗号
+ if [ $i -lt $((total-1)) ]; then
+ echo "," >> "$TEMP_PATHS_FILE"
+ fi
+ done
+fi
+
+# 处理 src 目录下的所有目录
+echo "处理 src 目录下的其他目录..."
+src_dirs=()
+while IFS= read -r dir; do
+ if [ -d "$dir" ] && [ "$(basename "$dir")" != "views" ]; then
+ dir_name=$(basename "$dir")
+ src_dirs+=("$dir_name")
+ fi
+done < <(find "$SRC_DIR" -mindepth 1 -maxdepth 1 -type d)
+
+# 如果之前有 views 目录的条目,添加逗号
+if [ ${#view_dirs[@]} -gt 0 ] && [ ${#src_dirs[@]} -gt 0 ]; then
+ echo "," >> "$TEMP_PATHS_FILE"
+fi
+
+# 处理其他目录
+total=${#src_dirs[@]}
+for ((i=0; i> "$TEMP_PATHS_FILE"
+ echo " '@$dir_name': path.resolve(__dirname, 'src/$dir_name')," >> "$TEMP_ALIAS_FILE"
+ # 如果不是最后一个元素,添加逗号
+ if [ $i -lt $((total-1)) ]; then
+ echo "," >> "$TEMP_PATHS_FILE"
+ fi
+done
+
+# 添加根路径(确保添加逗号如果之前有其他条目)
+if [ ${#view_dirs[@]} -gt 0 ] || [ ${#src_dirs[@]} -gt 0 ]; then
+ echo "," >> "$TEMP_PATHS_FILE"
+fi
+echo " \"@/*\": [\"./src/*\"]" >> "$TEMP_PATHS_FILE"
+echo "}" >> "$TEMP_PATHS_FILE"
+
+# 添加根路径到 alias 配置
+echo " '@': path.resolve(__dirname, 'src')" >> "$TEMP_ALIAS_FILE"
+echo "}" >> "$TEMP_ALIAS_FILE"
+
+# 更新 tsconfig.app.json
+echo "更新 tsconfig.app.json..."
+TSCONFIG="$PROJECT_ROOT/tsconfig.app.json"
+if [ -f "$TSCONFIG" ]; then
+ # 创建临时文件
+ TSCONFIG_TMP="${TSCONFIG}.tmp"
+
+ # 使用 jq 处理 JSON(如果可用)
+ if command -v jq >/dev/null 2>&1; then
+ jq --arg paths "$(cat "$TEMP_PATHS_FILE")" '.compilerOptions.paths = $paths' "$TSCONFIG" > "$TSCONFIG_TMP" \
+ && mv "$TSCONFIG_TMP" "$TSCONFIG" \
+ || handle_error "更新 tsconfig.app.json 失败"
+ else
+ # 回退到 sed 方案
+ sed -e '/"paths":/,/}/c\ "paths": '"$(cat "$TEMP_PATHS_FILE")"',' "$TSCONFIG" > "$TSCONFIG_TMP" \
+ && mv "$TSCONFIG_TMP" "$TSCONFIG" \
+ || handle_error "更新 tsconfig.app.json 失败"
+ fi
+ echo "tsconfig.app.json 更新成功"
+else
+ handle_error "找不到 tsconfig.app.json 文件"
+fi
+
+# 更新 vite.config.ts
+echo "更新 vite.config.ts..."
+VITE_CONFIG="$PROJECT_ROOT/vite.config.ts"
+if [ -f "$VITE_CONFIG" ]; then
+ VITE_CONFIG_TMP="${VITE_CONFIG}.tmp"
+
+ # 使用 sed 更新 alias 配置
+ sed -e '/resolve: {/,/}/c\ resolve: {\n alias: '"$(cat "$TEMP_ALIAS_FILE")"'\n },' "$VITE_CONFIG" > "$VITE_CONFIG_TMP" \
+ && mv "$VITE_CONFIG_TMP" "$VITE_CONFIG" \
+ || handle_error "更新 vite.config.ts 失败"
+
+ echo "vite.config.ts 更新成功"
+else
+ handle_error "找不到 vite.config.ts 文件"
+fi
+
+echo "路径别名配置更新完成!"
diff --git a/frontend/apps/allin-ssl/script/create-roles.sh b/frontend/apps/allin-ssl/script/create-roles.sh
new file mode 100644
index 0000000..9c4880a
--- /dev/null
+++ b/frontend/apps/allin-ssl/script/create-roles.sh
@@ -0,0 +1,891 @@
+#!/bin/bash
+
+# 遇到错误时退出
+set -e
+
+# 显示帮助信息
+show_help() {
+ echo "使用方法: ./create-roles.sh [选项]"
+ echo "选项:"
+ echo " -h, --help 显示帮助信息"
+ echo
+ echo "此脚本在 src/views 目录下创建角色管理相关的 Vue3 TSX 路由视图结构"
+ echo "将生成以下结构:"
+ echo "src/views/<角色名称>"
+ echo "├── index.tsx # 入口文件"
+ echo "├── useController.ts # 控制器"
+ echo "├── useStore.ts # 状态管理"
+ echo "├── index.module.css # 样式文件"
+ echo "├── types.d.ts # 类型定义"
+ echo "├── children/ # 子路由"
+ echo "│ └── permissions # 权限管理子路由"
+ echo "│ ├── index.tsx # 视图"
+ echo "│ ├── index.module.css # 样式"
+ echo "│ ├── useController.ts # 控制器"
+ echo "│ ├── useStore.ts # 状态管理"
+ echo "│ └── types.d.ts # 类型定义"
+ echo "└── components/ # 组件"
+ echo " └── role-form # 角色表单组件"
+ echo " ├── index.tsx # 视图"
+ echo " ├── index.module.css # 样式"
+ echo " ├── useController.ts # 控制器"
+ echo " ├── useStore.ts # 状态管理"
+ echo " └── types.d.ts # 类型定义"
+ echo
+ echo "同时会创建:"
+ echo "src/api/<角色名称>.ts # API 文件"
+ echo "src/types/<角色名称>.d.ts # 类型定义文件"
+}
+
+# 解析命令行参数
+while [[ $# -gt 0 ]]; do
+ case $1 in
+ -h|--help)
+ show_help
+ exit 0
+ ;;
+ *)
+ echo "错误: 未知参数 $1"
+ show_help
+ exit 1
+ ;;
+ esac
+done
+
+# 交互式选择函数
+select_option() {
+ local prompt="$1"
+ local options=("是" "否")
+ local selected
+
+ echo "$prompt"
+ select choice in "${options[@]}"; do
+ case $REPLY in
+ 1|2)
+ selected=$choice
+ break
+ ;;
+ *)
+ echo "请选择有效的选项 [1-2]"
+ ;;
+ esac
+ done
+
+ [[ "$selected" == "是" ]] && return 0 || return 1
+}
+
+# 交互式输入路由名称
+read -p "请输入路由名称 (routerName): " ROUTER_NAME
+if [ -z "$ROUTER_NAME" ]; then
+ echo "错误: 路由名称不能为空"
+ exit 1
+fi
+
+# 询问是否创建子路由
+if select_option "是否创建子路由?"; then
+ read -p "请输入子路由名称 [默认: list]: " CHILD_ROUTER_NAME
+ CHILD_ROUTER_NAME=${CHILD_ROUTER_NAME:-"list"}
+ echo "将创建子路由: $CHILD_ROUTER_NAME"
+else
+ CHILD_ROUTER_NAME=""
+ echo "不创建子路由"
+fi
+
+# 询问是否创建组件
+if select_option "是否创建组件?"; then
+ read -p "请输入组件名称 [默认: todo-form]: " COMPONENT_NAME
+ COMPONENT_NAME=${COMPONENT_NAME:-"todo-form"}
+ echo "将创建组件: $COMPONENT_NAME"
+else
+ COMPONENT_NAME=""
+ echo "不创建组件"
+fi
+
+# 获取脚本所在目录的绝对路径
+SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+# 获取项目根目录
+PROJECT_ROOT="$SCRIPT_DIR/../"
+
+# 创建目录函数
+create_dir() {
+ local dir="$1"
+ mkdir -p "$PROJECT_ROOT/$dir"
+}
+
+# 确保必需的目录存在
+create_dir "src/views"
+create_dir "src/api"
+create_dir "src/types"
+
+# 创建主目录结构
+create_dir "src/views/$ROUTER_NAME/children/$CHILD_ROUTER_NAME"
+create_dir "src/views/$ROUTER_NAME/components/$COMPONENT_NAME"
+
+# 创建 API 文件
+cat > "$PROJECT_ROOT/src/api/${ROUTER_NAME}.ts" << ''
+
+# 创建类型定义文件
+cat > "$PROJECT_ROOT/src/types/${ROUTER_NAME}.d.ts" << ''
+
+# 创建主路由类型文件
+cat > "$PROJECT_ROOT/src/views/$ROUTER_NAME/types.d.ts" << EOL
+export interface Todo {
+ id: string
+ title: string
+ completed: boolean
+ createdAt: string
+}
+
+export interface TodoState {
+ todos: Todo[]
+ loading: boolean
+ error: string | null
+}
+EOL
+
+# 创建主路由状态管理文件
+cat > "$PROJECT_ROOT/src/views/$ROUTER_NAME/useStore.ts" << EOL
+import { defineStore } from '@baota/pinia'
+import { ref } from 'vue'
+import type { Todo, TodoState } from './types'
+
+const store = defineStore('todo-store', () => {
+ const todos = ref([])
+ const loading = ref(false)
+ const error = ref(null)
+
+ const addTodo = (title: string) => {
+ const newTodo: Todo = {
+ id: Date.now().toString(),
+ title,
+ completed: false,
+ createdAt: new Date().toISOString()
+ }
+ todos.value.push(newTodo)
+ }
+
+ const toggleTodo = (id: string) => {
+ const todo = todos.value.find(t => t.id === id)
+ if (todo) {
+ todo.completed = !todo.completed
+ }
+ }
+
+ const removeTodo = (id: string) => {
+ todos.value = todos.value.filter(t => t.id !== id)
+ }
+
+ return {
+ todos,
+ loading,
+ error,
+ addTodo,
+ toggleTodo,
+ removeTodo
+ }
+})
+
+export const useStore = () => store()
+EOL
+
+# 创建主路由控制器文件
+cat > "$PROJECT_ROOT/src/views/$ROUTER_NAME/useController.ts" << EOL
+import { onMounted } from 'vue'
+import { storeToRefs } from '@baota/pinia'
+import { useStore } from './useStore'
+
+export const useController = () => {
+ const store = useStore()
+ const { todos, loading, error } = storeToRefs(store)
+
+ const handleAddTodo = (title: string) => {
+ if (title.trim()) {
+ store.addTodo(title.trim())
+ }
+ }
+
+ const handleToggleTodo = (id: string) => {
+ store.toggleTodo(id)
+ }
+
+ const handleRemoveTodo = (id: string) => {
+ store.removeTodo(id)
+ }
+
+ onMounted(() => {
+ // 可以在这里加载初始数据
+ console.log('Todo List Component Mounted')
+ })
+
+ return {
+ todos,
+ loading,
+ error,
+ handleAddTodo,
+ handleToggleTodo,
+ handleRemoveTodo
+ }
+}
+EOL
+
+# 创建主路由样式文件
+cat > "$PROJECT_ROOT/src/views/$ROUTER_NAME/index.module.css" << EOL
+.container {
+ max-width: 600px;
+ margin: 0 auto;
+ padding: 24px;
+}
+
+.header {
+ margin-bottom: 24px;
+ text-align: center;
+}
+
+.title {
+ font-size: 32px;
+ color: #2c3e50;
+}
+
+.form {
+ display: flex;
+ gap: 8px;
+ margin-bottom: 24px;
+}
+
+.input {
+ flex: 1;
+ padding: 8px 12px;
+ border: 1px solid #ddd;
+ border-radius: 4px;
+ font-size: 16px;
+}
+
+.button {
+ padding: 8px 16px;
+ background: #42b883;
+ color: white;
+ border: none;
+ border-radius: 4px;
+ cursor: pointer;
+ font-size: 16px;
+}
+
+.button:hover {
+ background: #3aa876;
+}
+
+.todoList {
+ list-style: none;
+ padding: 0;
+}
+
+.todoItem {
+ display: flex;
+ align-items: center;
+ padding: 12px;
+ background: white;
+ border-radius: 4px;
+ margin-bottom: 8px;
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
+}
+
+.todoCheckbox {
+ margin-right: 12px;
+}
+
+.todoTitle {
+ flex: 1;
+}
+
+.todoTitle.completed {
+ text-decoration: line-through;
+ color: #999;
+}
+
+.deleteButton {
+ padding: 4px 8px;
+ background: #ff4757;
+ color: white;
+ border: none;
+ border-radius: 4px;
+ cursor: pointer;
+}
+
+.deleteButton:hover {
+ background: #ff3748;
+}
+EOL
+
+# 创建主路由入口文件
+cat > "$PROJECT_ROOT/src/views/$ROUTER_NAME/index.tsx" << EOL
+import { defineComponent, ref } from 'vue'
+import { useController } from './useController'
+import styles from './index.module.css'
+
+export default defineComponent({
+ name: 'TodoList',
+
+ setup() {
+ const { todos, handleAddTodo, handleToggleTodo, handleRemoveTodo } = useController()
+ const newTodo = ref('')
+
+ const onSubmit = (e: Event) => {
+ e.preventDefault()
+ handleAddTodo(newTodo.value)
+ newTodo.value = ''
+ }
+
+ return () => (
+
+ )
+ }
+})
+EOL
+
+# 在脚本开头添加大写转换函数
+to_upper_first() {
+ local str="$1"
+ local first_char=$(echo "${str:0:1}" | tr '[:lower:]' '[:upper:]')
+ echo "$first_char${str:1}"
+}
+
+# 存储转换后的变量
+ROUTER_NAME_PASCAL=$(to_upper_first "$ROUTER_NAME")
+
+# 创建表单组件类型文件
+cat > "$PROJECT_ROOT/src/views/$ROUTER_NAME/components/$COMPONENT_NAME/types.d.ts" << EOL
+import type { ${ROUTER_NAME_PASCAL}Data } from '@/types/${ROUTER_NAME}'
+
+export interface FormProps {
+ data?: ${ROUTER_NAME_PASCAL}Data | null
+}
+
+export interface FormEmits {
+ (e: 'submit', data: ${ROUTER_NAME_PASCAL}Data): void
+ (e: 'cancel'): void
+}
+EOL
+
+# 创建表单组件状态管理文件
+cat > "$PROJECT_ROOT/src/views/$ROUTER_NAME/components/$COMPONENT_NAME/useStore.ts" << EOL
+import { defineStore } from '@baota/pinia'
+import { ref } from 'vue'
+import type { ${ROUTER_NAME_PASCAL}Data } from '@/types/${ROUTER_NAME}'
+
+// 定义 store
+const store = defineStore('${ROUTER_NAME}-form-store', () => {
+ const loading = ref(false)
+ const formData = ref<${ROUTER_NAME_PASCAL}Data>({
+ id: '',
+ name: '',
+ code: '',
+ description: '',
+ permissions: [],
+ createdAt: '',
+ updatedAt: ''
+ })
+
+ return {
+ loading,
+ formData
+ }
+})
+
+export const useStore = () => store()
+EOL
+
+# 创建表单组件控制器文件
+cat > "$PROJECT_ROOT/src/views/$ROUTER_NAME/components/$COMPONENT_NAME/useController.ts" << EOL
+import { onMounted } from 'vue'
+import { storeToRefs } from '@baota/pinia'
+import { useStore } from './useStore'
+import type { ${ROUTER_NAME_PASCAL}Data } from '@/types/${ROUTER_NAME}'
+
+export const useController = (initialData?: ${ROUTER_NAME_PASCAL}Data | null) => {
+ const store = useStore()
+ const storeRef = storeToRefs(store)
+
+ onMounted(() => {
+ if (initialData) {
+ store.formData = { ...initialData }
+ }
+ })
+
+ return {
+ ...storeRef
+ }
+}
+EOL
+
+# 创建表单组件样式文件
+cat > "$PROJECT_ROOT/src/views/$ROUTER_NAME/components/$COMPONENT_NAME/index.module.css" << EOL
+.form {
+ max-width: 600px;
+}
+
+.formTitle {
+ font-size: 18px;
+ font-weight: bold;
+ margin-bottom: 24px;
+}
+
+.formItem {
+ margin-bottom: 16px;
+}
+
+.label {
+ display: block;
+ margin-bottom: 8px;
+ font-weight: 500;
+}
+
+.input {
+ width: 100%;
+ padding: 8px;
+ border: 1px solid #d9d9d9;
+ border-radius: 4px;
+ transition: all 0.3s;
+}
+
+.input:hover {
+ border-color: #40a9ff;
+}
+
+.input:focus {
+ border-color: #1890ff;
+ outline: none;
+ box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
+}
+
+.textarea {
+ composes: input;
+ min-height: 100px;
+ resize: vertical;
+}
+
+.actions {
+ margin-top: 24px;
+ display: flex;
+ gap: 8px;
+ justify-content: flex-end;
+}
+
+.button {
+ padding: 8px 16px;
+ border: 1px solid #d9d9d9;
+ border-radius: 4px;
+ cursor: pointer;
+ background: #fff;
+ transition: all 0.3s;
+}
+
+.button:hover {
+ background: #f5f5f5;
+}
+
+.primaryButton {
+ composes: button;
+ background: #1890ff;
+ color: #fff;
+ border-color: #1890ff;
+}
+
+.primaryButton:hover {
+ background: #40a9ff;
+}
+EOL
+
+# 创建表单组件入口文件
+cat > "$PROJECT_ROOT/src/views/$ROUTER_NAME/components/$COMPONENT_NAME/index.tsx" << EOL
+import { defineComponent } from 'vue'
+import { useController } from './useController'
+import type { FormProps, FormEmits } from './types'
+import styles from './index.module.css'
+
+export default defineComponent({
+ name: 'RoleForm',
+
+ props: {
+ data: {
+ type: Object as PropType,
+ default: null
+ }
+ },
+
+ emits: ['submit', 'cancel'],
+
+ setup(props, { emit }) {
+ const { formData } = useController(props.data)
+
+ const handleSubmit = (e: Event) => {
+ e.preventDefault()
+ emit('submit', formData.value)
+ }
+
+ return () => (
+
+ )
+ }
+})
+EOL
+
+# 创建子路由类型文件
+cat > "$PROJECT_ROOT/src/views/$ROUTER_NAME/children/$CHILD_ROUTER_NAME/types.d.ts" << EOL
+import type { ${ROUTER_NAME_PASCAL}Data } from '@/types/${ROUTER_NAME}'
+
+export interface Permission {
+ code: string
+ name: string
+ description?: string
+}
+
+export interface PermissionState {
+ loading: boolean
+ data: ${ROUTER_NAME_PASCAL}Data | null
+ permissions: Permission[]
+ selectedPermissions: string[]
+}
+EOL
+
+# 创建子路由状态管理文件
+cat > "$PROJECT_ROOT/src/views/$ROUTER_NAME/children/$CHILD_ROUTER_NAME/useStore.ts" << EOL
+import { defineStore } from '@baota/pinia'
+import { ref } from 'vue'
+import type { ${ROUTER_NAME_PASCAL}Data } from '@/types/${ROUTER_NAME}'
+import type { Permission } from './types'
+
+// 定义 store
+const store = defineStore('${ROUTER_NAME}-permissions-store', () => {
+ const loading = ref(false)
+ const data = ref<${ROUTER_NAME_PASCAL}Data | null>(null)
+ const permissions = ref([])
+ const selectedPermissions = ref([])
+
+ return {
+ loading,
+ data,
+ permissions,
+ selectedPermissions
+ }
+})
+
+// 导出 store
+export const useStore = () => store()
+EOL
+
+# 创建子路由控制器文件
+cat > "$PROJECT_ROOT/src/views/$ROUTER_NAME/children/$CHILD_ROUTER_NAME/useController.ts" << EOL
+import { onMounted } from 'vue'
+import { storeToRefs } from '@baota/pinia'
+import { useStore } from './useStore'
+import { get${ROUTER_NAME_PASCAL}Data } from '@/api/${ROUTER_NAME}'
+
+export const useController = (roleId: string) => {
+ const store = useStore()
+ const storeRef = storeToRefs(store)
+
+ const fetchData = async () => {
+ try {
+ store.loading = true
+ const data = await get${ROUTER_NAME_PASCAL}Data(roleId)
+ store.data = data
+ store.selectedPermissions = data.permissions
+ } catch (error) {
+ console.error('获取数据失败:', error)
+ } finally {
+ store.loading = false
+ }
+ }
+
+ const handleSave = async () => {
+ try {
+ store.loading = true
+ // 调用保存API
+ store.loading = false
+ } catch (error) {
+ console.error('保存失败:', error)
+ }
+ }
+
+ onMounted(() => {
+ fetchData()
+ })
+
+ return {
+ ...storeRef,
+ handleSave
+ }
+}
+EOL
+
+# 创建子路由样式文件
+cat > "$PROJECT_ROOT/src/views/$ROUTER_NAME/children/$CHILD_ROUTER_NAME/index.module.css" << EOL
+.container {
+ padding: 24px;
+}
+
+.header {
+ margin-bottom: 24px;
+}
+
+.title {
+ font-size: 24px;
+ font-weight: bold;
+}
+
+.content {
+ background: #fff;
+ padding: 24px;
+ border-radius: 8px;
+}
+
+.loading {
+ text-align: center;
+ padding: 24px;
+}
+
+.permissionList {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
+ gap: 16px;
+ margin: 24px 0;
+}
+
+.permissionItem {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.actions {
+ margin-top: 24px;
+ display: flex;
+ justify-content: flex-end;
+ gap: 8px;
+}
+
+.button {
+ padding: 8px 16px;
+ border: 1px solid #d9d9d9;
+ border-radius: 4px;
+ cursor: pointer;
+ background: #fff;
+ transition: all 0.3s;
+}
+
+.button:hover {
+ background: #f5f5f5;
+}
+
+.primaryButton {
+ composes: button;
+ background: #1890ff;
+ color: #fff;
+ border-color: #1890ff;
+}
+
+.primaryButton:hover {
+ background: #40a9ff;
+}
+EOL
+
+# 创建子路由入口文件
+cat > "$PROJECT_ROOT/src/views/$ROUTER_NAME/children/$CHILD_ROUTER_NAME/index.tsx" << EOL
+import { defineComponent } from 'vue'
+import { useRoute, useRouter } from '@baota/router'
+import { useController } from './useController'
+import styles from './index.module.css'
+
+export default defineComponent({
+ name: 'RolePermissions',
+
+ setup() {
+ const route = useRoute()
+ const router = useRouter()
+ const roleId = route.params.id as string
+
+ const {
+ loading,
+ data,
+ permissions,
+ selectedPermissions,
+ handleSave
+ } = useController(roleId)
+
+ const handleCancel = () => {
+ router.push('/${ROUTER_NAME}')
+ }
+
+ return () => (
+
+
+
+
+ {loading.value ? (
+
加载中...
+ ) : (
+ <>
+
{data.value?.name} - 权限配置
+
+
+ {permissions.value.map(permission => (
+
+ ))}
+
+
+
+
+
+
+ >
+ )}
+
+
+ )
+ }
+})
+EOL
+
+echo "✨ 文件结构生成成功!"
+echo "📁 主路由: $PROJECT_ROOT/src/views/$ROUTER_NAME"
+echo "📁 子路由: $PROJECT_ROOT/src/views/$ROUTER_NAME/children/$CHILD_ROUTER_NAME"
+echo "📁 组件: $PROJECT_ROOT/src/views/$ROUTER_NAME/components/$COMPONENT_NAME"
+echo "📄 API文件: $PROJECT_ROOT/src/api/${ROUTER_NAME}.ts"
+echo "📄 类型文件: $PROJECT_ROOT/src/types/${ROUTER_NAME}.d.ts"
+echo
+echo "目录结构:"
+echo "├── src/views/$ROUTER_NAME"
+echo "│ ├── index.tsx"
+echo "│ ├── useController.ts"
+echo "│ ├── useStore.ts"
+echo "│ ├── index.module.css"
+echo "│ ├── types.d.ts"
+echo "│ ├── children"
+echo "│ │ └── $CHILD_ROUTER_NAME"
+echo "│ │ ├── index.tsx"
+echo "│ │ ├── index.module.css"
+echo "│ │ ├── useController.ts"
+echo "│ │ ├── useStore.ts"
+echo "│ │ └── types.d.ts"
+echo "│ └── components"
+echo "│ └── $COMPONENT_NAME"
+echo "│ ├── index.tsx"
+echo "│ ├── index.module.css"
+echo "│ ├── useController.ts"
+echo "│ ├── useStore.ts"
+echo "│ └── types.d.ts"
+echo "├── src/api"
+echo "│ └── ${ROUTER_NAME}.ts"
+echo "└── src/types"
+echo " └── ${ROUTER_NAME}.d.ts"
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/.DS_Store b/frontend/apps/allin-ssl/src/.DS_Store
new file mode 100644
index 0000000..3cf1fe8
Binary files /dev/null and b/frontend/apps/allin-ssl/src/.DS_Store differ
diff --git a/frontend/apps/allin-ssl/src/App.tsx b/frontend/apps/allin-ssl/src/App.tsx
new file mode 100644
index 0000000..84f1a76
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/App.tsx
@@ -0,0 +1,21 @@
+import { Transition, type Component as ComponentType, h } from 'vue'
+
+import { RouterView } from 'vue-router'
+import CustomProvider from '@baota/naive-ui/components/customProvider'
+
+export default defineComponent({
+ name: 'App',
+ setup() {
+ return () => (
+
+
+ {({ Component }: { Component: ComponentType }) => (
+
+ {Component && h(Component)}
+
+ )}
+
+
+ )
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/api/access.ts b/frontend/apps/allin-ssl/src/api/access.ts
new file mode 100644
index 0000000..32283af
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/api/access.ts
@@ -0,0 +1,51 @@
+import { useApi } from './index'
+import type {
+ AccessListParams,
+ AccessListResponse,
+ AddAccessParams,
+ UpdateAccessParams,
+ DeleteAccessParams,
+ GetAccessAllListParams,
+ GetAccessAllListResponse,
+} from '../types/access'
+import type { AxiosResponseData } from '../types/public'
+
+/**
+ * @description 获取授权列表
+ * @param {AccessListParams} [params] 请求参数
+ * @returns {Promise>} 授权列表
+ */
+export const getAccessList = (params?: AccessListParams) =>
+ useApi('/v1/access/get_list', params)
+
+/**
+ * @description 新增授权
+ * @param {AddAccessParams} [params] 请求参数
+ * @returns {Promise>} 新增结果
+ */
+export const addAccess = (params?: AddAccessParams) =>
+ useApi>('/v1/access/add_access', params)
+
+/**
+ * @description 修改授权
+ * @param {UpdateAccessParams} [params] 请求参数
+ * @returns {Promise>} 修改结果
+ */
+export const updateAccess = (params?: UpdateAccessParams) =>
+ useApi>('/v1/access/upd_access', params)
+
+/**
+ * @description 删除授权
+ * @param {DeleteAccessParams} [params] 请求参数
+ * @returns {Promise>} 删除结果
+ */
+export const deleteAccess = (params?: DeleteAccessParams) =>
+ useApi('/v1/access/del_access', params)
+
+/**
+ * @description 获取DNS提供商列表
+ * @param {GetAccessAllListParams} [params] 请求参数
+ * @returns {Promise>} 工作流 dns 配置
+ */
+export const getAccessAllList = (params?: GetAccessAllListParams) =>
+ useApi('/v1/access/get_all', params)
diff --git a/frontend/apps/allin-ssl/src/api/cert.ts b/frontend/apps/allin-ssl/src/api/cert.ts
new file mode 100644
index 0000000..4a7659b
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/api/cert.ts
@@ -0,0 +1,56 @@
+import { useApi } from './index'
+import type {
+ CertListParams,
+ CertListResponse,
+ ApplyCertParams,
+ ApplyCertResponse,
+ UploadCertParams,
+ UploadCertResponse,
+ DeleteCertParams,
+ DeleteCertResponse,
+ DownloadCertParams,
+} from '../types/cert'
+import axios from 'axios'
+
+/**
+ * @description 获取证书列表
+ * @param {CertListParams} [params] 请求参数
+ * @returns {Promise>} 证书列表
+ */
+export const getCertList = (params?: CertListParams) =>
+ useApi('/v1/cert/get_list', params)
+
+/**
+ * @description 申请证书
+ * @param {ApplyCertParams} [params] 请求参数
+ * @returns {Promise>} 申请结果
+ */
+export const applyCert = (params?: ApplyCertParams) =>
+ useApi('/v1/cert/apply_cert', params)
+
+/**
+ * @description 上传证书
+ * @param {UploadCertParams} [params] 请求参数
+ * @returns {Promise>} 上传结果
+ */
+export const uploadCert = (params?: UploadCertParams) =>
+ useApi('/v1/cert/upload_cert', params)
+
+/**
+ * @description 删除证书
+ * @param {DeleteCertParams} [params] 请求参数
+ * @returns {Promise>} 删除结果
+ */
+export const deleteCert = (params?: DeleteCertParams) =>
+ useApi('/v1/cert/del_cert', params)
+
+/**
+ * @description 下载证书
+ * @param {DownloadCertParams} [params] 请求参数
+ * @returns {Promise>} 下载结果
+ */
+export const downloadCert = (params?: DownloadCertParams) => {
+ return axios.get('/v1/cert/download', {
+ params,
+ })
+}
diff --git a/frontend/apps/allin-ssl/src/api/index.ts b/frontend/apps/allin-ssl/src/api/index.ts
new file mode 100644
index 0000000..7b48149
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/api/index.ts
@@ -0,0 +1,86 @@
+import { AxiosError } from 'axios'
+import MD5 from 'crypto-js/md5'
+import { isDev } from '@baota/utils/browser'
+import { HttpClient, useAxios, useAxiosReturn } from '@baota/hooks/axios'
+import { errorMiddleware } from '@baota/hooks/axios/model'
+import { router } from '@router/index'
+
+import type { AxiosResponseData } from '@/types/public'
+
+/**
+ * @description 处理返回数据,如果状态码为 401
+ * @param {AxiosResponseData} response 返回数据
+ * @returns {AxiosResponseData} 返回数据
+ */
+export const responseHandleStatusCode = errorMiddleware((error: AxiosError) => {
+ // 处理 401 状态码
+ if (error.status === 401) {
+ router.push(`/login`)
+ }
+ // 处理404状态码
+ if (error.status === 404) {
+ router.go(0) // 刷新页面
+ }
+ return error
+})
+
+/**
+ * @description 返回数据
+ * @param {T} data 数据
+ * @returns {AxiosResponseData} 返回数据
+ */
+export const useApiReturn = (data: T, message?: string): AxiosResponseData => {
+ return {
+ code: 200,
+ count: 0,
+ data,
+ message: message || '请求返回值错误,请检查',
+ status: false,
+ } as AxiosResponseData
+}
+
+/**
+ * @description 创建http客户端实例
+ */
+export const instance = new HttpClient({
+ baseURL: isDev() ? '/api' : '/',
+ timeout: 50000,
+ headers: {
+ 'Content-Type': 'application/x-www-form-urlencoded',
+ },
+ middlewares: [responseHandleStatusCode],
+})
+
+/**
+ * @description 创建api token
+ * @returns {string} api token
+ */
+export const createApiToken = () => {
+ const now = new Date().getTime()
+ const apiKey = '123456'
+ const api_token = MD5(now + MD5(apiKey).toString()).toString()
+ return { api_token, timestamp: now }
+}
+
+/**
+/**
+ * @description 创建axios请求
+ * @param {string} url 请求地址
+ * @param {Z} params 请求参数
+ * @returns {useAxiosReturn} 返回结果
+ */
+export const useApi = >(url: string, params?: Z) => {
+ const { urlRef, paramsRef, ...other } = useAxios(instance)
+ const apiParams = createApiToken()
+ urlRef.value = url
+ paramsRef.value = isDev() ? { ...(params || {}), ...apiParams } : params || {}
+ return { urlRef, paramsRef: paramsRef as Ref, ...other } as useAxiosReturn
+}
+
+// 导出所有模块
+export * from './public'
+export * from './workflow'
+export * from './cert'
+export * from './access'
+export * from './monitor'
+export * from './setting'
diff --git a/frontend/apps/allin-ssl/src/api/monitor.ts b/frontend/apps/allin-ssl/src/api/monitor.ts
new file mode 100644
index 0000000..287b1cc
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/api/monitor.ts
@@ -0,0 +1,50 @@
+import { useApi } from './index'
+import type { AxiosResponseData } from '@/types/public'
+import type {
+ SiteMonitorListParams,
+ SiteMonitorListResponse,
+ AddSiteMonitorParams,
+ UpdateSiteMonitorParams,
+ DeleteSiteMonitorParams,
+ SetSiteMonitorParams,
+} from '../types/monitor'
+
+/**
+ * @description 获取站点监控列表
+ * @param {SiteMonitorListParams} [params] 请求参数
+ * @returns {Promise>} 站点监控列表
+ */
+export const getSiteMonitorList = (params?: SiteMonitorListParams) =>
+ useApi('/v1/siteMonitor/get_list', params)
+
+/**
+ * @description 新增站点监控
+ * @param {AddSiteMonitorParams} [params] 请求参数
+ * @returns {Promise>} 新增结果
+ */
+export const addSiteMonitor = (params?: AddSiteMonitorParams) =>
+ useApi('/v1/siteMonitor/add_site_monitor', params)
+
+/**
+ * @description 修改站点监控
+ * @param {UpdateSiteMonitorParams} [params] 请求参数
+ * @returns {Promise>} 修改结果
+ */
+export const updateSiteMonitor = (params?: UpdateSiteMonitorParams) =>
+ useApi('/v1/siteMonitor/upd_site_monitor', params)
+
+/**
+ * @description 删除站点监控
+ * @param {DeleteSiteMonitorParams} [params] 请求参数
+ * @returns {Promise>} 删除结果
+ */
+export const deleteSiteMonitor = (params?: DeleteSiteMonitorParams) =>
+ useApi('/v1/siteMonitor/del_site_monitor', params)
+
+/**
+ * @description 启用/禁用站点监控
+ * @param {SetSiteMonitorParams} [params] 请求参数
+ * @returns {Promise>} 操作结果
+ */
+export const setSiteMonitor = (params?: SetSiteMonitorParams) =>
+ useApi('/v1/siteMonitor/set_site_monitor', params)
diff --git a/frontend/apps/allin-ssl/src/api/public.ts b/frontend/apps/allin-ssl/src/api/public.ts
new file mode 100644
index 0000000..7e1a28c
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/api/public.ts
@@ -0,0 +1,38 @@
+import axios from 'axios'
+import { useApi } from './index'
+import type {
+ loginParams,
+ loginResponse,
+ GetOverviewsParams,
+ GetOverviewsResponse,
+ AxiosResponseData,
+} from '@/types/public'
+
+/**
+ * @description 登录
+ * @param {loginParams} [params] 登录参数
+ * @returns {Promise>} 登录结果
+ */
+export const login = (params?: loginParams) => useApi('/v1/login/sign', params)
+
+/**
+ * @description 获取登录验证码
+ * @returns {Promise>} 登录验证码
+ */
+export const getLoginCode = () => {
+ return axios.get('/v1/login/get_code')
+}
+
+/**
+ * @description 登出
+ * @returns {Promise>} 登出结果
+ */
+export const signOut = () => useApi('/v1/login/sign-out')
+
+/**
+ * @description 获取首页概览
+ * @param {GetOverviewsParams} [params] 请求参数
+ * @returns {Promise>} 首页概览数据
+ */
+export const getOverviews = (params?: GetOverviewsParams) =>
+ useApi('/v1/overview/get_overviews', params)
diff --git a/frontend/apps/allin-ssl/src/api/setting.ts b/frontend/apps/allin-ssl/src/api/setting.ts
new file mode 100644
index 0000000..da1a5c8
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/api/setting.ts
@@ -0,0 +1,69 @@
+import { useApi } from './index'
+import type { AxiosResponseData } from '../types/public'
+import type {
+ GetSettingParams,
+ GetSettingResponse,
+ SaveSettingParams,
+ GetReportListParams,
+ GetReportListResponse,
+ AddReportParams,
+ UpdateReportParams,
+ DeleteReportParams,
+ TestReportParams,
+} from '../types/setting'
+
+/**
+ * @description 获取系统设置
+ * @param {GetSettingParams} [params] 请求参数
+ * @returns {Promise>} 系统设置
+ */
+export const getSystemSetting = (params?: GetSettingParams) =>
+ useApi('/v1/setting/get_setting', params)
+
+/**
+ * @description 保存系统设置
+ * @param {SaveSettingParams} [params] 请求参数
+ * @returns {Promise>} 保存结果
+ */
+export const saveSystemSetting = (params?: SaveSettingParams) =>
+ useApi('/v1/setting/save_setting', params)
+
+/**
+ * @description 添加告警
+ * @param {AddReportParams} [params] 请求参数
+ * @returns {Promise>} 配置结果
+ */
+export const addReport = (params?: AddReportParams) =>
+ useApi('/v1/report/add_report', params)
+
+/**
+ * @description 更新告警
+ * @param {UpdateReportParams} [params] 请求参数
+ * @returns {Promise>} 更新结果
+ */
+export const updateReport = (params?: UpdateReportParams) =>
+ useApi('/v1/report/upd_report', params)
+
+/**
+ * @description 删除告警
+ * @param {DeleteReportParams} [params] 请求参数
+ * @returns {Promise>} 删除结果
+ */
+export const deleteReport = (params?: DeleteReportParams) =>
+ useApi('/v1/report/del_report', params)
+
+/**
+ * @description 测试告警
+ * @param {TestReportParams} [params] 请求参数
+ * @returns {Promise>} 测试结果
+ */
+export const testReport = (params?: TestReportParams) =>
+ useApi('/v1/report/notify_test', params)
+
+/**
+ * @description 获取告警类型列表
+ * @param {GetReportListParams} [params] 请求参数
+ * @returns {Promise>} 告警类型列表
+ */
+export const getReportList = (params?: GetReportListParams) =>
+ useApi('/v1/report/get_list', params)
diff --git a/frontend/apps/allin-ssl/src/api/workflow.ts b/frontend/apps/allin-ssl/src/api/workflow.ts
new file mode 100644
index 0000000..a4a0548
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/api/workflow.ts
@@ -0,0 +1,90 @@
+import { useApi } from './index'
+import type {
+ WorkflowListParams,
+ WorkflowListResponse,
+ AddWorkflowParams,
+ UpdateWorkflowParams,
+ DeleteWorkflowParams,
+ WorkflowHistoryParams,
+ WorkflowHistoryResponse,
+ ExecuteWorkflowParams,
+ UpdateWorkflowExecTypeParams,
+ EnableWorkflowParams,
+ WorkflowHistoryDetailParams,
+} from '../types/workflow'
+import { AxiosResponseData } from '@/types/public'
+
+/**
+ * @description 获取工作流列表
+ * @param {WorkflowListParams} [params] 请求参数
+ * @returns {Promise>} 工作流列表
+ */
+export const getWorkflowList = (params?: WorkflowListParams) =>
+ useApi('/v1/workflow/get_list', params)
+
+/**
+ * @description 新增工作流
+ * @param {AddWorkflowParams} [params] 请求参数
+ * @returns {Promise>} 新增结果
+ */
+export const addWorkflow = (params?: AddWorkflowParams) =>
+ useApi('/v1/workflow/add_workflow', params)
+
+/**
+ * @description 修改工作流
+ * @param {UpdateWorkflowParams} [params] 请求参数
+ * @returns {Promise>} 修改结果
+ */
+export const updateWorkflow = (params?: UpdateWorkflowParams) =>
+ useApi('/v1/workflow/upd_workflow', params)
+
+/**
+ * @description 删除工作流
+ * @param {DeleteWorkflowParams} [params] 请求参数
+ * @returns {Promise>} 删除结果
+ */
+export const deleteWorkflow = (params?: DeleteWorkflowParams) =>
+ useApi('/v1/workflow/del_workflow', params)
+
+/**
+ * @description 获取工作流执行历史
+ * @param {WorkflowHistoryParams} [params] 请求参数
+ * @returns {Promise>} 工作流执行历史
+ */
+export const getWorkflowHistory = (params?: WorkflowHistoryParams) =>
+ useApi('/v1/workflow/get_workflow_history', params)
+
+/**
+ * @description 获取工作流执行历史详情
+ * @param {WorkflowHistoryDetailParams} [params] 请求参数
+ * @returns {Promise>} 工作流执行历史详情
+ */
+export const getWorkflowHistoryDetail = (params?: WorkflowHistoryDetailParams) =>
+ useApi('/v1/workflow/get_exec_log', params)
+
+/**
+ * @description 手动执行工作流
+ * @param {ExecuteWorkflowParams} [params] 请求参数
+ * @returns {Promise>} 执行结果
+ */
+export const executeWorkflow = (params?: ExecuteWorkflowParams) =>
+ useApi('/v1/workflow/execute_workflow', params)
+
+/**
+ * @description 修改工作流执行方式
+ * @param {UpdateWorkflowExecTypeParams} [params] 请求参数
+ * @returns {Promise>} 修改结果
+ */
+export const updateWorkflowExecType = (params?: UpdateWorkflowExecTypeParams) =>
+ useApi('/v1/workflow/exec_type', params)
+
+/**
+ * @description 启用工作流或禁用工作流
+ * @param {EnableWorkflowParams} [params] 请求参数
+ * @returns {Promise>} 启用或禁用结果
+ */
+export const enableWorkflow = (params?: EnableWorkflowParams) =>
+ useApi('/v1/workflow/active', params)
+
+
+
diff --git a/frontend/apps/allin-ssl/src/assets/.DS_Store b/frontend/apps/allin-ssl/src/assets/.DS_Store
new file mode 100644
index 0000000..4be5b2e
Binary files /dev/null and b/frontend/apps/allin-ssl/src/assets/.DS_Store differ
diff --git a/frontend/apps/allin-ssl/src/assets/icons/.DS_Store b/frontend/apps/allin-ssl/src/assets/icons/.DS_Store
new file mode 100644
index 0000000..64a5569
Binary files /dev/null and b/frontend/apps/allin-ssl/src/assets/icons/.DS_Store differ
diff --git a/frontend/apps/allin-ssl/src/assets/icons/svg/.DS_Store b/frontend/apps/allin-ssl/src/assets/icons/svg/.DS_Store
new file mode 100644
index 0000000..4912f85
Binary files /dev/null and b/frontend/apps/allin-ssl/src/assets/icons/svg/.DS_Store differ
diff --git a/frontend/apps/allin-ssl/src/assets/icons/svg/close.svg b/frontend/apps/allin-ssl/src/assets/icons/svg/close.svg
new file mode 100644
index 0000000..3b6bafc
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/assets/icons/svg/close.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/assets/icons/svg/flow/apply.svg b/frontend/apps/allin-ssl/src/assets/icons/svg/flow/apply.svg
new file mode 100644
index 0000000..b26c429
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/assets/icons/svg/flow/apply.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/assets/icons/svg/flow/branch.svg b/frontend/apps/allin-ssl/src/assets/icons/svg/flow/branch.svg
new file mode 100644
index 0000000..5db1ca5
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/assets/icons/svg/flow/branch.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/assets/icons/svg/flow/deploy.svg b/frontend/apps/allin-ssl/src/assets/icons/svg/flow/deploy.svg
new file mode 100644
index 0000000..6870e01
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/assets/icons/svg/flow/deploy.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/assets/icons/svg/flow/error.svg b/frontend/apps/allin-ssl/src/assets/icons/svg/flow/error.svg
new file mode 100644
index 0000000..5f2a3b1
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/assets/icons/svg/flow/error.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/assets/icons/svg/flow/notify.svg b/frontend/apps/allin-ssl/src/assets/icons/svg/flow/notify.svg
new file mode 100644
index 0000000..2126612
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/assets/icons/svg/flow/notify.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/assets/icons/svg/flow/success.svg b/frontend/apps/allin-ssl/src/assets/icons/svg/flow/success.svg
new file mode 100644
index 0000000..bcb2d7b
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/assets/icons/svg/flow/success.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/assets/icons/svg/flow/upload.svg b/frontend/apps/allin-ssl/src/assets/icons/svg/flow/upload.svg
new file mode 100644
index 0000000..554e68c
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/assets/icons/svg/flow/upload.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/assets/icons/svg/notify/dingtalk.svg b/frontend/apps/allin-ssl/src/assets/icons/svg/notify/dingtalk.svg
new file mode 100644
index 0000000..4fa9eb8
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/assets/icons/svg/notify/dingtalk.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/assets/icons/svg/notify/feishu.svg b/frontend/apps/allin-ssl/src/assets/icons/svg/notify/feishu.svg
new file mode 100644
index 0000000..4586fdc
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/assets/icons/svg/notify/feishu.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/assets/icons/svg/notify/mail.svg b/frontend/apps/allin-ssl/src/assets/icons/svg/notify/mail.svg
new file mode 100644
index 0000000..b982b6e
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/assets/icons/svg/notify/mail.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/assets/icons/svg/notify/webhook.svg b/frontend/apps/allin-ssl/src/assets/icons/svg/notify/webhook.svg
new file mode 100644
index 0000000..4dc779e
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/assets/icons/svg/notify/webhook.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/assets/icons/svg/notify/wecom.svg b/frontend/apps/allin-ssl/src/assets/icons/svg/notify/wecom.svg
new file mode 100644
index 0000000..5ae81bd
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/assets/icons/svg/notify/wecom.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/assets/icons/svg/plus.svg b/frontend/apps/allin-ssl/src/assets/icons/svg/plus.svg
new file mode 100644
index 0000000..eb70c78
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/assets/icons/svg/plus.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/assets/icons/svg/resources/.DS_Store b/frontend/apps/allin-ssl/src/assets/icons/svg/resources/.DS_Store
new file mode 100644
index 0000000..5008ddf
Binary files /dev/null and b/frontend/apps/allin-ssl/src/assets/icons/svg/resources/.DS_Store differ
diff --git a/frontend/apps/allin-ssl/src/assets/icons/svg/resources/1panel.svg b/frontend/apps/allin-ssl/src/assets/icons/svg/resources/1panel.svg
new file mode 100644
index 0000000..8bfc9f6
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/assets/icons/svg/resources/1panel.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/assets/icons/svg/resources/aliyun.svg b/frontend/apps/allin-ssl/src/assets/icons/svg/resources/aliyun.svg
new file mode 100644
index 0000000..7fe7400
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/assets/icons/svg/resources/aliyun.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/assets/icons/svg/resources/btpanel.svg b/frontend/apps/allin-ssl/src/assets/icons/svg/resources/btpanel.svg
new file mode 100644
index 0000000..b387988
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/assets/icons/svg/resources/btpanel.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/assets/icons/svg/resources/ssh.svg b/frontend/apps/allin-ssl/src/assets/icons/svg/resources/ssh.svg
new file mode 100644
index 0000000..32b720b
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/assets/icons/svg/resources/ssh.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/assets/icons/svg/resources/tencentcloud.svg b/frontend/apps/allin-ssl/src/assets/icons/svg/resources/tencentcloud.svg
new file mode 100644
index 0000000..10291c6
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/assets/icons/svg/resources/tencentcloud.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/assets/icons/svg/subtract.svg b/frontend/apps/allin-ssl/src/assets/icons/svg/subtract.svg
new file mode 100644
index 0000000..f954379
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/assets/icons/svg/subtract.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/assets/icons/svg/tips.svg b/frontend/apps/allin-ssl/src/assets/icons/svg/tips.svg
new file mode 100644
index 0000000..72aa6c0
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/assets/icons/svg/tips.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/assets/vue.svg b/frontend/apps/allin-ssl/src/assets/vue.svg
new file mode 100644
index 0000000..770e9d3
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/assets/vue.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/components/.DS_Store b/frontend/apps/allin-ssl/src/components/.DS_Store
new file mode 100644
index 0000000..7a66a04
Binary files /dev/null and b/frontend/apps/allin-ssl/src/components/.DS_Store differ
diff --git a/frontend/apps/allin-ssl/src/components/baseComponent/index.tsx b/frontend/apps/allin-ssl/src/components/baseComponent/index.tsx
new file mode 100644
index 0000000..1652655
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/baseComponent/index.tsx
@@ -0,0 +1,60 @@
+/**
+ * @description 基础组件
+ * @example
+ * ```tsx
+ *
+ * 左侧头部内容
+ * 右侧头部内容
+ * 主要内容
+ * 左侧底部内容
+ * 右侧底部内容
+ * 弹窗内容
+ *
+ * ```
+ */
+export default defineComponent({
+ name: 'BaseComponent',
+ setup(_, { slots }) {
+ // 获取插槽内容,支持驼峰和短横线两种命名方式
+ const slotHL = slots['header-left'] || slots['headerLeft']
+ const slotHR = slots['header-right'] || slots['headerRight']
+ const slotHeader = slots['header'] || slots['header']
+ const slotFL = slots['footer-left'] || slots['footerLeft']
+ const slotFR = slots['footer-right'] || slots['footerRight']
+ const slotFooter = slots['footer'] || slots['footer']
+
+ return () => (
+
+ {/* 头部区域 */}
+ {(slotHL || slotHR) && (
+
+
{slotHL && slotHL()}
+
{slotHR && slotHR()}
+
+ )}
+
+ {/* 头部区域 */}
+ {slotHeader &&
{slotHeader && slotHeader()}
}
+
+ {/* 内容区域 */}
+
+ {slots.content && slots.content()}
+
+
+ {/* 底部区域 */}
+ {(slotFL || slotFR) && (
+
+
{slotFL && slotFL()}
+
{slotFR && slotFR()}
+
+ )}
+
+ {/* 底部区域 */}
+ {slotFooter &&
{slotFooter()}
}
+
+ {/* 弹窗区域 */}
+ {slots.popup && slots.popup()}
+
+ )
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/components/dnsProviderSelect/index.tsx b/frontend/apps/allin-ssl/src/components/dnsProviderSelect/index.tsx
new file mode 100644
index 0000000..9a7b905
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/dnsProviderSelect/index.tsx
@@ -0,0 +1,300 @@
+import { NButton, NFormItemGi, NGrid, NSelect, NText, NSpin, NFlex } from 'naive-ui'
+import { useError } from '@baota/hooks/error'
+import { $t } from '@locales/index'
+import { useStore } from '@layout/useStore'
+import SvgIcon from '@components/svgIcon'
+
+interface DnsProviderOption {
+ label: string
+ value: string
+ type: string
+}
+
+type DnsProviderType = 'btpanel' | 'aliyun' | 'ssh' | 'tencentcloud' | '1panel' | 'dns' | ''
+
+interface DnsProviderSelectProps {
+ // 表单类型,用于获取不同的下拉列表
+ type: DnsProviderType
+ // 表单,用于绑定表单的值
+ path: string
+ // 表单的值
+ value: string
+ // 表单的值类型
+ valueType: 'value' | 'type'
+ // 是否为添加模式
+ isAddMode: boolean
+ // 是否禁用
+ disabled?: boolean
+ // 自定义样式
+ customClass?: string
+}
+
+/**
+ * @component DnsProviderSelect
+ * @description DNS提供商选择组件,支持多种DNS提供商类型,并提供刷新和跳转到授权页面的功能
+ *
+ * @example 基础使用
+ *
+ *
+ * @example 仅显示选择器(无添加按钮)
+ *
+ *
+ * @example 禁用状态
+ *
+ *
+ * @property {string} type - DNS提供商类型,支持 'btpanel'|'aliyun'|'ssh'|'tencentcloud'|'1panel'|'dns'|''
+ * @property {string} path - 表单路径,用于绑定表单的值
+ * @property {string} value - 表单的值,通过v-model:value绑定
+ * @property {string} valueType - 表单的值类型,可选值为 'value'(默认) 或 'type'
+ * @property {boolean} isAddMode - 是否显示添加和刷新按钮,默认为true
+ * @property {boolean} disabled - 是否禁用选择器,默认为false
+ * @property {string} customClass - 自定义CSS类名
+ *
+ * @emits update:value - 当选择的DNS提供商变更时触发
+ */
+
+export default defineComponent({
+ name: 'DnsProviderSelect',
+ props: {
+ // 表单类型,用于获取不同的下拉列表
+ type: {
+ type: String as PropType,
+ default: '',
+ },
+ // 表单,用于绑定表单的值
+ path: {
+ type: String,
+ default: '',
+ },
+ // 表单的值
+ value: {
+ type: String,
+ default: '',
+ },
+ // 表单的值类型
+ valueType: {
+ type: String,
+ default: 'value',
+ },
+ // 是否为添加模式
+ isAddMode: {
+ type: Boolean,
+ default: true,
+ },
+ // 是否禁用
+ disabled: {
+ type: Boolean,
+ default: false,
+ },
+ // 自定义样式
+ customClass: {
+ type: String,
+ default: '',
+ },
+ },
+ emits: ['update:value'],
+ setup(props: DnsProviderSelectProps, { emit }) {
+ // 错误处理
+ const { handleError } = useError()
+ // 获取DNS提供商
+ const { fetchDnsProvider, dnsProvider } = useStore()
+ // 表单的值
+ const param = ref({
+ label: '',
+ value: '',
+ type: '',
+ })
+ const dnsProviderRef = ref([])
+ // 加载状态
+ const isLoading = ref(false)
+ // 错误信息
+ const errorMessage = ref('')
+
+ /**
+ * @description 跳转到DNS提供商授权页面
+ */
+ const goToAddDnsProvider = () => {
+ window.open('/auth-api-manage', '_blank')
+ }
+
+ /**
+ * 渲染单选标签
+ * @param option - 选项
+ * @returns 渲染后的VNode
+ */
+ const renderSingleSelectTag = ({ option }: Record): VNode => {
+ return (
+
+ {option.label ? (
+
+
+ {option.label}
+
+ ) : (
+ {props.type === 'dns' ? $t('t_3_1745490735059') : $t('t_19_1745735766810')}
+ )}
+
+ )
+ }
+
+ /**
+ * 渲染标签
+ * @param option - 选项
+ * @returns 渲染后的VNode
+ */
+ const renderLabel = (option: { type: string; label: string }): VNode => {
+ return (
+
+
+ {option.label}
+
+ )
+ }
+
+ /**
+ * @description 更新类型
+ */
+ const handleUpdateType = async () => {
+ const items = dnsProvider.value.find((item) => {
+ return item.value === param.value.value
+ })
+ if (items) {
+ param.value = {
+ label: items.label,
+ value: items.value,
+ type: items.type,
+ }
+ }
+ if (dnsProvider.value.length > 0 && param.value.value === '') {
+ param.value = {
+ label: dnsProvider.value[0]?.label || '',
+ value: dnsProvider.value[0]?.value || '',
+ type: dnsProvider.value[0]?.type || '',
+ }
+ }
+ emit('update:value', param.value)
+ }
+
+ /**
+ * 更新表单的值
+ * @param value - 表单的值
+ */
+ const handleUpdateValue = (value: string) => {
+ param.value.value = value
+ handleUpdateType()
+ }
+
+ /**
+ * @description 加载DNS提供商选项
+ */
+ const loadDnsProviders = async (type: DnsProviderType = '') => {
+ isLoading.value = true
+ errorMessage.value = ''
+
+ try {
+ await fetchDnsProvider(type)
+ } catch (error) {
+ errorMessage.value = typeof error === 'string' ? error : $t('t_0_1746760933542')
+ handleError(error)
+ } finally {
+ isLoading.value = false
+ }
+ }
+
+ /**
+ * @description 搜索过滤函数
+ * @param pattern - 搜索文本
+ * @param option - 选项
+ */
+ const handleFilter = (pattern: string, option: any) => {
+ return option.label.toLowerCase().includes(pattern.toLowerCase())
+ }
+
+ // 监听消息通知提供商
+ watch(
+ () => dnsProvider.value,
+ (newVal) => {
+ dnsProviderRef.value =
+ newVal.map((item) => ({
+ label: item.label,
+ value: props.valueType === 'value' ? item.value : item.type,
+ type: props.valueType === 'value' ? item.type : item.value,
+ })) || []
+ handleUpdateType()
+ },
+ )
+
+ // 监听父组件的值
+ watch(
+ () => props.value,
+ () => {
+ loadDnsProviders(props.type)
+ handleUpdateValue(props.value)
+ },
+ { immediate: true },
+ )
+
+ return () => (
+
+
+
+ {
+ return (
+
+ {errorMessage.value || (props.type === 'dns' ? $t('t_3_1745490735059') : $t('t_1_1745744905566'))}
+
+ )
+ },
+ }}
+ />
+
+ {props.isAddMode && (
+
+
+ {props.type === 'dns' ? $t('t_1_1746004861166') : $t('t_0_1745748292337')}
+
+ loadDnsProviders(props.type)} loading={isLoading.value} disabled={props.disabled}>
+ {$t('t_0_1746497662220')}
+
+
+ )}
+
+
+ )
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/.DS_Store b/frontend/apps/allin-ssl/src/components/flowChart/.DS_Store
new file mode 100644
index 0000000..37e90c1
Binary files /dev/null and b/frontend/apps/allin-ssl/src/components/flowChart/.DS_Store differ
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/components/.DS_Store b/frontend/apps/allin-ssl/src/components/flowChart/components/.DS_Store
new file mode 100644
index 0000000..7909e45
Binary files /dev/null and b/frontend/apps/allin-ssl/src/components/flowChart/components/.DS_Store differ
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/components/base/baseNode/index.module.css b/frontend/apps/allin-ssl/src/components/flowChart/components/base/baseNode/index.module.css
new file mode 100644
index 0000000..7202297
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/components/base/baseNode/index.module.css
@@ -0,0 +1,182 @@
+.node {
+ @apply flex flex-col items-center relative mx-[1.2rem];
+}
+
+.nodeArrows::before {
+ content: '';
+ position: absolute;
+ top: -1.2rem;
+ left: 50%;
+ transform: translateX(-50%);
+ width: 0;
+ height: 0.4rem;
+ border-style: solid;
+ border-width: 0.8rem 0.6rem 0.4rem;
+ border-color: #cacaca transparent transparent;
+ background-color: #f5f5f7;
+}
+
+.nodeContent {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ width: 20rem;
+ min-height: 8rem;
+ font-size: 1.4rem;
+ box-shadow: .2rem .2rem .5rem .2rem rgba(0, 0, 0, 0.2);
+ white-space: normal;
+ word-break: break-word;
+ position: relative;
+ box-sizing: border-box;
+ border-radius: 0.5rem;
+ transition: box-shadow 0.1s;
+}
+
+.nodeContent:hover {
+ box-shadow: 0.3rem 0.3rem .6rem 0.3rem rgba(0, 0, 0, 0.2);
+}
+
+.nodeSelected {
+ box-shadow: 0 0 0 2px #1e83e9;
+ border: 1px solid #1e83e9;
+}
+
+.nodeHeader {
+ @apply w-full flex relative items-center justify-center bg-[#1e83e9] rounded-t-[0.5rem] p-[0.5rem_1rem] text-white box-border;
+}
+
+.nodeHeaderBranch{
+ @apply flex-1 justify-between;
+}
+
+.nodeCondition{
+ min-height: 5rem;
+}
+
+.nodeConditionHeader {
+ min-height: 5rem;
+ border-radius: 1rem;
+ color: #333 !important;
+ background-color: #f8fafc !important;
+}
+
+.nodeConditionHeader input{
+ color: #333 !important;
+}
+
+.nodeConditionHeader input:focus{
+ background-color: #efefef !important;
+}
+
+
+.nodeConditionHeader .nodeIcon{
+ color: #333 !important;
+}
+
+.nodeIcon {
+ @apply text-[1.6rem];
+}
+
+.nodeHeaderTitle {
+ @apply flex flex-row items-center justify-center relative px-[2rem];
+}
+
+.nodeHeaderTitleText {
+ @apply max-w-[11rem] min-w-[2rem] mr-[0.5rem] whitespace-nowrap overflow-hidden text-ellipsis;
+}
+
+.nodeHeaderTitleInput {
+ @apply w-auto ;
+}
+
+.nodeHeaderTitleInput input {
+ @apply w-full text-center border border-none rounded px-2 py-1 text-[#fff] focus:outline-none bg-transparent;
+}
+
+.nodeHeaderTitleInput input:focus {
+ @apply border-[#1e83e9] bg-white text-[#333];
+}
+
+.nodeHeaderTitleEdit {
+ @apply w-[3rem] cursor-pointer hidden;
+}
+
+.nodeHeaderTitle:hover .nodeHeaderTitleEdit {
+ @apply inline;
+}
+
+.nodeClose {
+ @apply text-[1.6rem] text-center cursor-pointer;
+}
+
+.nodeBody {
+ @apply w-full flex-1 flex flex-col justify-center bg-white rounded-b-[0.5rem] p-[1rem] text-[#5a5e66] cursor-pointer box-border;
+}
+
+.nodeConditionBody {
+ @apply bg-[#f8fafc] rounded-[0.5rem];
+}
+
+.nodeError {
+
+ box-shadow: 0 0 1rem 0.2rem rgba(243, 5, 5, 0.5);
+}
+
+.nodeError:hover {
+ box-shadow: 0 0 1.2rem 0.4rem rgba(243, 5, 5, 0.5);
+}
+
+.nodeErrorMsg {
+ @apply absolute top-1/2 -translate-y-1/2 -right-[5.5rem] z-[1];
+}
+
+.nodeErrorMsgBox {
+ @apply relative;
+}
+
+.nodeErrorIcon {
+ @apply w-[2.5rem] h-[2.5rem] cursor-pointer;
+}
+
+.nodeErrorTips {
+ position: absolute;
+ z-index: 3;
+ top: 50%;
+ transform: translateY(-50%);
+ left: 4.5rem;
+ min-width: 15rem;
+ background-color: white;
+ border-radius: 0.5rem;
+ box-shadow: 0.5rem 0.5rem 1rem 0.2rem rgba(0, 0, 0, 0.2);
+ display: flex;
+ padding: 1.6rem;
+}
+
+.nodeErrorTips::before {
+ content: '';
+ width: 0;
+ height: 0;
+ border-width: 1rem;
+ border-style: solid;
+ position: absolute;
+ top: 50%;
+ left: -2rem;
+ transform: translateY(-50%);
+ border-color: transparent #FFFFFF transparent transparent;
+}
+
+.nodeMove {
+ @apply absolute top-1/2 -translate-y-1/2;
+}
+
+.nodeMoveLeft {
+ @apply -left-[3rem];
+}
+
+.nodeMoveRight {
+ @apply -right-[3rem];
+}
+
+.nodeMoveIcon {
+ @apply w-[3.5rem] h-[3.5rem] cursor-pointer;
+}
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/components/base/baseNode/index.tsx b/frontend/apps/allin-ssl/src/components/flowChart/components/base/baseNode/index.tsx
new file mode 100644
index 0000000..dbebd60
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/components/base/baseNode/index.tsx
@@ -0,0 +1,230 @@
+import { v4 as uuidv4 } from 'uuid'
+import { useStore } from '@components/flowChart/useStore'
+import { useController } from '@components/flowChart/useController'
+import nodeOptions from '@components/flowChart/lib/config'
+import { useDialog } from '@baota/naive-ui/hooks'
+import { $t } from '@locales/index'
+import { CONDITION, EXECUTE_RESULT_CONDITION, START } from '@components/flowChart/lib/alias'
+import { useNodeValidator } from '@components/flowChart/lib/verify'
+
+import AddNode from '@components/flowChart/components/other/addNode/index'
+import SvgIcon from '@components/svgIcon'
+
+import type { BaseNodeData, NodeNum, BaseRenderNodeOptions, BaseNodeProps } from '@components/flowChart/types'
+
+import styles from './index.module.css'
+import ErrorNode from '../errorNode'
+
+export default defineComponent({
+ name: 'BaseNode',
+ props: {
+ // 节点数据
+ node: {
+ type: Object as PropType,
+ required: true, // 自读
+ },
+ },
+ setup(props: BaseNodeProps) {
+ // ====================== 基础状态数据 ======================
+ const { validator, validate } = useNodeValidator() // 验证器
+ const tempNodeId = ref(props.node.id || uuidv4()) // 节点id
+ const config = ref>(nodeOptions[props.node.type]() || {}) // 节点配置
+ const nodeNameRef = ref(null) // 节点名称输入框
+ const isShowEditNodeName = ref(false) // 是否显示编辑节点名称
+ const inputValue = ref(props.node.name) // 输入框值
+ const renderNodeContent = shallowRef() // 节点组件
+ const { removeNode, updateNode } = useStore()
+ const { handleSelectNode } = useController()
+
+ // ====================== 节点状态数据 ======================
+ // 错误状态
+ const errorState = ref({
+ isError: false,
+ message: null as string | null,
+ showTips: false,
+ })
+
+ // ====================== 计算属性 ======================
+ // 是否是开始节点
+ const isStart = computed(() => props.node.type === START)
+
+ // 是否可以删除
+ const isRemoved = computed(() => config.value?.operateNode?.remove)
+
+ // 是否是条件节点
+ const isCondition = computed(() => [CONDITION, EXECUTE_RESULT_CONDITION].includes(props.node.type))
+
+ // 根据节点类型获取图标
+ const typeIcon: ComputedRef = computed(() => {
+ const type = {
+ success: 'flow-success',
+ fail: 'flow-error',
+ }
+ // console.log(props.node.config?.type)
+ if (props.node.type === EXECUTE_RESULT_CONDITION)
+ return (type[props.node.config?.type as keyof typeof type] || '') as string
+ return ''
+ })
+
+ // 根据节点类型获取图标颜色
+ const typeIconColor: ComputedRef = computed(() => {
+ if (props.node.type === EXECUTE_RESULT_CONDITION) return (props.node.config?.type || '') as string
+ return '#FFFFFF'
+ })
+
+ const nodeComponents = import.meta.glob('../../task/**/index.tsx')
+ // ====================== 数据监听与副作用 ======================
+ // 监听节点数据,更新节点配置
+ watch(
+ () => props.node,
+ () => {
+ config.value = nodeOptions[props.node.type as NodeNum]() // 更新节点配置
+ inputValue.value = props.node.name // 更新节点名称
+ tempNodeId.value = props.node.id || uuidv4() // 更新节点id
+ validator.validateAll() // 验证器验证
+ const NodeComp =
+ nodeComponents[`../../task/${props.node.type}Node/index.tsx`] ||
+ import('@components/flowChart/components/base/errorNode')
+ renderNodeContent.value = defineAsyncComponent({
+ loader: NodeComp as Promise,
+ loadingComponent: () => Loading...
,
+ errorComponent: () => ,
+ })
+ },
+ { immediate: true },
+ )
+
+ // ====================== 渲染节点内容 ======================
+
+ // // 渲染节点内容
+ // const renderNodeContent = defineAsyncComponent({
+ // loader: () =>
+ // (nodeComp ? nodeComp : import('@components/flowChart/components/base/errorNode')) as Promise,
+ // loadingComponent: () => Loading...
,
+ // errorComponent: () => ,
+ // })
+
+ // ====================== 节点操作方法 ======================
+ // 显示错误提示
+ const showErrorTips = (flag: boolean) => {
+ errorState.value.showTips = flag
+ }
+
+ // 删除节点
+ const removeFindNode = (ev: MouseEvent, id: string, node: BaseNodeData) => {
+ const validator = validate(id)
+ console.log(validator)
+ if (validator.valid) {
+ useDialog({
+ type: 'warning',
+ title: $t('t_1_1745765875247', { name: node.name }),
+ content: node.type === CONDITION ? $t('t_2_1745765875918') : $t('t_3_1745765920953'),
+ onPositiveClick: () => removeNode(id),
+ })
+ }
+ // 如果节点类型是条件节点或验证不通过,则删除节点
+ if ([EXECUTE_RESULT_CONDITION].includes(node.type) || !validator.valid) {
+ removeNode(id)
+ }
+ ev.stopPropagation()
+ ev.preventDefault()
+ }
+
+ // 点击节点
+ const handleNodeClick = () => {
+ handleSelectNode(props.node.id || '', props.node.type)
+ }
+
+ // ====================== 事件处理函数 ======================
+ // 回车保存
+ const keyupSaveNodeName = (e: KeyboardEvent) => {
+ if (e.keyCode === 13) {
+ isShowEditNodeName.value = false
+ }
+ }
+
+ // 保存节点名称
+ const saveNodeName = (e: Event) => {
+ const target = e.target as HTMLInputElement
+ inputValue.value = target.value
+ updateNode(tempNodeId.value, { name: inputValue.value })
+ }
+
+ // ====================== 渲染函数 ======================
+ return () => (
+
+
+ {/* 节点头部 */}
+
+ {/* 节点图标 */}
+ {typeIcon.value ? (
+
+ ) : null}
+
+ {/* 节点标题 */}
+
+
+ {/* 删除按钮 */}
+ {isRemoved.value && (
+ removeFindNode(ev, tempNodeId.value, props.node)}
+ class="flex items-center justify-center absolute top-[50%] right-[1rem] -mt-[.9rem]"
+ >
+
+
+ )}
+
+ {/* 节点主体 */}
+ {!isCondition.value ? (
+
+ {renderNodeContent.value &&
+ h(renderNodeContent.value, {
+ id: props.node.id,
+ node: props.node || {},
+ class: 'text-center',
+ })}
+
+ ) : null}
+ {/* 错误提示 */}
+ {errorState.value.showTips && (
+
+
+
showErrorTips(true)} onMouseleave={() => showErrorTips(false)}>
+
+
+ {errorState.value.message &&
{errorState.value.message}
}
+
+
+ )}
+
+ {/* 添加节点组件 */}
+
+
+ )
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/components/base/branchNode/index.module.css b/frontend/apps/allin-ssl/src/components/flowChart/components/base/branchNode/index.module.css
new file mode 100644
index 0000000..3bb2cfb
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/components/base/branchNode/index.module.css
@@ -0,0 +1,69 @@
+.flowNodeBranch {
+ @apply flex flex-col justify-center w-full relative max-w-full overflow-visible;
+}
+
+/* 多列分支样式 */
+.multipleColumns {
+ @apply w-full
+}
+
+.flowNodeBranchBox {
+ @apply flex flex-row w-full flex-nowrap min-h-[50px] relative overflow-visible;
+}
+
+/* 有嵌套分支的容器样式 */
+.hasNestedBranch {
+ @apply w-full justify-around;
+}
+
+.flowNodeBranchCol {
+ @apply flex flex-col items-center border-t-2 border-b-2 border-[#cacaca] pt-[50px] bg-[#f8fafc] flex-1 relative max-w-[50%];
+}
+
+
+/* 有嵌套分支时列宽调整 */
+.hasNestedBranch .flowNodeBranchCol {
+ @apply w-full;
+}
+
+/* 多级嵌套分支样式调整 */
+.flowNodeBranchCol .flowNodeBranchCol {
+ @apply min-w-[20rem] w-[24rem]
+}
+
+
+.flowNodeBranchCol::before {
+ @apply content-[''] absolute top-0 left-0 right-0 bottom-0 z-0 m-auto w-[2px] h-full bg-[#cacaca];
+}
+
+.coverLine {
+ @apply absolute h-[8px] w-[calc(50%-1px)] bg-[#f8fafc];
+}
+
+.topLeftCoverLine {
+ @apply -top-[4px] left-0;
+}
+
+.topRightCoverLine {
+ @apply -top-[4px] right-0;
+}
+
+.bottomLeftCoverLine {
+ @apply -bottom-[4px] left-0;
+}
+
+.bottomRightCoverLine {
+ @apply -bottom-[4px] right-0;
+}
+
+.rightCoverLine{
+ @apply absolute w-[2px] bg-[#f8fafc] top-0 right-0 h-full;
+}
+
+.leftCoverLine{
+ @apply absolute w-[2px] bg-[#f8fafc] top-0 left-0 h-full;
+}
+
+.flowConditionNodeAdd {
+ @apply absolute left-1/2 -translate-x-1/2 -top-[15px] flex justify-center items-center z-[2] w-[70px] h-[30px] text-[12px] text-[#1c84c6] bg-white rounded-[20px] cursor-pointer shadow-md;
+}
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/components/base/branchNode/index.tsx b/frontend/apps/allin-ssl/src/components/flowChart/components/base/branchNode/index.tsx
new file mode 100644
index 0000000..a0280c3
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/components/base/branchNode/index.tsx
@@ -0,0 +1,113 @@
+import { v4 as uuidv4 } from 'uuid'
+import nodeOptions from '@components/flowChart/lib/config'
+import { useStore } from '@components/flowChart/useStore'
+import { CONDITION } from '@components/flowChart/lib/alias'
+
+import NodeWrap from '@components/flowChart/components/render/nodeWrap'
+import AddNode from '@components/flowChart/components/other/addNode'
+import styles from './index.module.css'
+import type { BaseRenderNodeOptions, BranchNodeData } from '@components/flowChart/types'
+
+export default defineComponent({
+ name: 'BranchNode',
+ props: {
+ node: {
+ type: Object as () => BranchNodeData,
+ default: () => ({}),
+ },
+ },
+
+ setup(props: { node: BranchNodeData }) {
+ const { addNode } = useStore() // 流程图数据
+ const config = ref>(nodeOptions[props.node.type]() || {}) // 节点配置
+
+ watch(
+ () => props.node.type,
+ (newVal) => {
+ config.value = nodeOptions[newVal]() || {}
+ },
+ )
+
+ // 添加分支
+ const addCondition = () => {
+ const tempNodeId = uuidv4() // 临时节点id
+ addNode(
+ props.node.id || '',
+ CONDITION,
+ {
+ id: tempNodeId,
+ name: `分支${(props.node.conditionNodes?.length || 0) + 1}`,
+ },
+ props.node.conditionNodes?.length,
+ )
+ }
+
+ // 计算容器类名,根据分支数量调整样式
+ const getContainerClass = () => {
+ const count = props.node.conditionNodes?.length || 0
+ const baseClass = styles.flowNodeBranch
+
+ // 分支数量多时添加特殊类
+ if (count > 3) {
+ return `${baseClass} ${styles.multipleColumns}`
+ }
+
+ return baseClass
+ }
+
+ // 计算分支盒子类名,处理多层嵌套情况
+ const getBoxClass = () => {
+ // 检查是否有嵌套的分支节点
+ const hasNestedBranch = props.node.conditionNodes?.some(
+ (node) => node.childNode && ['branch', 'execute_result_branch'].includes(node.childNode.type),
+ )
+
+ const baseClass = styles.flowNodeBranchBox
+ if (hasNestedBranch) {
+ return `${baseClass} ${styles.hasNestedBranch}`
+ }
+
+ return baseClass
+ }
+
+ return () => (
+
+ {config.value.operateNode?.addBranch && (
+
+ {config.value.operateNode?.addBranchTitle || '添加分支'}
+
+ )}
+
+ {props.node.conditionNodes?.map((condition, index: number) => (
+
+ {/* 条件节点 */}
+
+ {/* 用来遮挡最左列的线 */}
+ {index === 0 && (
+
+ )}
+ {/* 用来遮挡最右列的线 */}
+ {index === (props.node.conditionNodes?.length || 0) - 1 && (
+
+ )}
+
+ ))}
+
+
+
+ )
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/components/base/conditionNode/index.tsx b/frontend/apps/allin-ssl/src/components/flowChart/components/base/conditionNode/index.tsx
new file mode 100644
index 0000000..779f765
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/components/base/conditionNode/index.tsx
@@ -0,0 +1,111 @@
+import { v4 as uuidv4 } from 'uuid'
+import nodeOptions from '@components/flowChart/lib/config'
+import { useStore } from '@components/flowChart/useStore'
+import { CONDITION } from '@components/flowChart/lib/alias'
+
+import NodeWrap from '@components/flowChart/components/render/nodeWrap'
+import AddNode from '@components/flowChart/components/other/addNode'
+import styles from '../branchNode/index.module.css'
+import type { BaseRenderNodeOptions, ExecuteResultBranchNodeData } from '@components/flowChart/types'
+
+export default defineComponent({
+ name: 'BranchNode',
+ props: {
+ node: {
+ type: Object as () => ExecuteResultBranchNodeData,
+ default: () => ({}),
+ },
+ },
+
+ setup(props: { node: ExecuteResultBranchNodeData }) {
+ const { addNode } = useStore() // 流程图数据
+ const config = ref>(nodeOptions[props.node.type]() || {}) // 节点配置
+
+ watch(
+ () => props.node.type,
+ (newVal) => {
+ config.value = nodeOptions[newVal]() || {}
+ },
+ )
+
+ // 添加条件
+ const addCondition = () => {
+ const tempNodeId = uuidv4() // 临时节点id
+ addNode(
+ props.node.id || '',
+ CONDITION,
+ {
+ id: tempNodeId,
+ name: `分支${(props.node.conditionNodes?.length || 0) + 1}`,
+ },
+ props.node.conditionNodes?.length,
+ )
+ }
+
+ // 计算容器类名,根据分支数量调整样式
+ const getContainerClass = () => {
+ const count = props.node.conditionNodes?.length || 0
+ const baseClass = styles.flowNodeBranch
+
+ // 分支数量多时添加特殊类
+ if (count > 3) {
+ return `${baseClass} ${styles.multipleColumns}`
+ }
+
+ return baseClass
+ }
+
+ // 计算分支盒子类名,处理多层嵌套情况
+ const getBoxClass = () => {
+ // 检查是否有嵌套的分支节点
+ const hasNestedBranch = props.node.conditionNodes?.some(
+ (node) => node.childNode && ['branch', 'execute_result_branch'].includes(node.childNode.type),
+ )
+ const baseClass = styles.flowNodeBranchBox
+ if (hasNestedBranch) {
+ return `${baseClass} ${styles.hasNestedBranch}`
+ }
+ return baseClass
+ }
+
+ return () => (
+
+ {config.value.operateNode?.addBranch && (
+
+ {config.value.operateNode?.addBranchTitle || '添加分支'}
+
+ )}
+
+ {props.node.conditionNodes?.map((condition, index: number) => (
+
+ {/* 条件节点 */}
+
+ {/* 用来遮挡最左列的线 */}
+ {index === 0 && (
+
+ )}
+ {/* 用来遮挡最右列的线 */}
+ {index === (props.node.conditionNodes?.length || 0) - 1 && (
+
+ )}
+
+ ))}
+
+
+
+ )
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/components/base/endNode.tsx b/frontend/apps/allin-ssl/src/components/flowChart/components/base/endNode.tsx
new file mode 100644
index 0000000..533b5ab
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/components/base/endNode.tsx
@@ -0,0 +1,11 @@
+export default defineComponent({
+ name: 'EndNode',
+ setup() {
+ return () => (
+
+ )
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/components/base/errorNode/index.tsx b/frontend/apps/allin-ssl/src/components/flowChart/components/base/errorNode/index.tsx
new file mode 100644
index 0000000..35d57e7
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/components/base/errorNode/index.tsx
@@ -0,0 +1,14 @@
+import { BaseNodeData } from '@components/flowChart/types'
+
+export default defineComponent({
+ name: 'BranchNode',
+ props: {
+ node: {
+ type: Object as () => BaseNodeData,
+ default: () => ({}),
+ },
+ },
+ setup() {
+ return () => 渲染节点失败,请检查类型是否支持
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/components/other/addNode/index.module.css b/frontend/apps/allin-ssl/src/components/flowChart/components/other/addNode/index.module.css
new file mode 100644
index 0000000..ba8605d
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/components/other/addNode/index.module.css
@@ -0,0 +1,129 @@
+.add {
+ position: relative;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ padding: 4rem 0;
+}
+
+.add::before {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ z-index: -1;
+ margin: auto;
+ width: 0.2rem;
+ height: 100%;
+ background-color: #cacaca;
+}
+
+.addBtn {
+ position: absolute;
+ left: 50%;
+ top: 50%;
+ margin-left: -1.2rem;
+ margin-top: -2rem;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: 2.4rem;
+ height: 2.4rem;
+ border-radius: 4rem;
+ background-color: #1c84c6;
+ box-shadow: 0.5rem 0.5rem 1rem 0.2rem rgba(0, 0, 0, 0.2);
+ transition-property: width, height;
+ transition-duration: 0.1s;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+/* .addBtn:hover {
+ width: 3.5rem;
+ height: 3.5rem;
+} */
+
+.addBtnIcon {
+ font-weight: bold;
+ color: #FFFFFF;
+ cursor: pointer;
+}
+
+.addSelectBox {
+ position: absolute;
+ z-index: 9999999999999999;
+ top: -.8rem;
+ min-width: 160px;
+ padding: 4px;
+ list-style-type: none;
+ background-color: #ffffff;
+ background-clip: padding-box;
+ border-radius: 8px;
+ outline: none;
+ box-shadow: 0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 9px 28px 8px rgba(0, 0, 0, 0.05);
+}
+
+.addSelectBox::before {
+ content: '';
+ width: 0;
+ height: 0;
+ border: 1rem solid;
+ position: absolute;
+ top: 1rem;
+}
+
+.addSelectItem {
+ margin: 0;
+ width: 100%;
+ padding: 5px 12px;
+ color: rgba(0, 0, 0, 0.88);
+ font-weight: normal;
+ font-size: 14px;
+ line-height: 1.5714285714285714;
+ cursor: pointer;
+ transition: all 0.2s;
+ border-radius: 4px;
+ display: flex;
+ align-items: center;
+}
+
+.addSelectItem:hover {
+ background-color: #1e83e9 !important;
+ color: #FFFFFF !important;
+}
+
+.addSelectItemIcon {
+ width: 1.2rem;
+ height: 1.2rem;
+ margin-right: 1rem;
+}
+
+.addSelectItemTitle {
+ font-size: 1.4rem;
+}
+
+.addSelected {
+ background-color: #1e83e9 !important;
+ color: #FFFFFF !important;
+}
+
+.addLeft {
+ right: 3.4rem;
+}
+
+.addLeft::before {
+ right: -2rem;
+ border-color: transparent transparent transparent #FFFFFF;
+}
+
+.addRight {
+ left: 3.4rem;
+}
+
+.addRight::before {
+ left: -2rem;
+ border-color: transparent #FFFFFF transparent transparent;
+}
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/components/other/addNode/index.tsx b/frontend/apps/allin-ssl/src/components/flowChart/components/other/addNode/index.tsx
new file mode 100644
index 0000000..4d643e2
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/components/other/addNode/index.tsx
@@ -0,0 +1,93 @@
+import { useAddNodeController } from '@components/flowChart/useController'
+import SvgIcon from '@components/svgIcon'
+import styles from './index.module.css'
+
+import type {
+ NodeIcon,
+ NodeNum,
+ NodeTitle,
+ BaseNodeData,
+ BranchNodeData,
+ BaseRenderNodeOptions,
+} from '@components/flowChart/types'
+import nodeOptions from '@components/flowChart/lib/config'
+
+interface NodeSelect {
+ title: NodeTitle
+ type: NodeNum
+ icon: NodeIcon
+ selected: boolean
+}
+
+export default defineComponent({
+ name: 'AddNode',
+ props: {
+ node: {
+ type: Object as PropType,
+ default: () => ({}),
+ },
+ },
+ setup(props) {
+ const {
+ isShowAddNodeSelect,
+ nodeSelectList,
+ addNodeBtnRef,
+ addNodeSelectRef,
+ addNodeSelectPostion,
+ showNodeSelect,
+ addNodeData,
+ itemNodeSelected,
+ excludeNodeSelectList,
+ } = useAddNodeController()
+
+ const config = ref>() // 节点配置
+
+ watch(
+ () => props.node.type,
+ (newVal) => {
+ config.value = nodeOptions[newVal]() || {}
+ },
+ )
+
+ return () => (
+
+
showNodeSelect(true, props.node.type as NodeNum)}
+ onMouseleave={() => showNodeSelect(false)}
+ >
+
+ {isShowAddNodeSelect.value && (
+
+ {nodeSelectList.value.map((item: NodeSelect) => {
+ // 判断类型是否支持添加
+ if (!excludeNodeSelectList.value?.includes(item.type)) {
+ return (
+ - addNodeData(props.node, item.type)}
+ onMouseenter={itemNodeSelected}
+ >
+
+
{item.title.name}
+
+ )
+ }
+ return null
+ })}
+
+ )}
+
+
+ )
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/components/other/drawer.tsx b/frontend/apps/allin-ssl/src/components/flowChart/components/other/drawer.tsx
new file mode 100644
index 0000000..ca5cc00
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/components/other/drawer.tsx
@@ -0,0 +1,82 @@
+import { NEmpty } from 'naive-ui'
+import type { BaseNodeData } from '@/components/flowChart/types'
+import { $t } from '@locales/index'
+
+type AsyncComponentLoader = () => Promise
+
+/**
+ * 节点配置抽屉组件
+ * 用于显示节点配置界面,根据节点类型动态加载对应的配置组件
+ */
+export default defineComponent({
+ name: 'FlowChartDrawer',
+ props: {
+ /**
+ * 节点数据
+ */
+ node: {
+ type: Object as PropType,
+ default: null,
+ },
+ },
+ setup(props) {
+ /**
+ * 节点配置组件Map
+ */
+ const nodeConfigComponents = shallowRef>({})
+
+ /**
+ * 动态导入节点配置组件
+ * 使用import.meta.glob导入所有drawer组件
+ * 1. 任务节点配置组件
+ * 2. 基础节点配置组件
+ */
+ const taskDrawers: Record = import.meta.glob('../task/*/drawer.tsx') as Record<
+ string,
+ AsyncComponentLoader
+ >
+
+ // 预加载所有抽屉组件
+ const loadComponents = () => {
+ // 加载任务节点组件
+ Object.keys(taskDrawers).forEach((path) => {
+ const matches = path.match(/\.\.\/task\/(\w+)\/drawer\.tsx/)
+ if (matches && matches[1]) {
+ const nodeType = matches[1].replace('Node', '').toLowerCase()
+ const loaderFn = taskDrawers[path]
+ if (loaderFn) {
+ nodeConfigComponents.value[nodeType] = defineAsyncComponent(loaderFn)
+ }
+ }
+ })
+ }
+
+ /**
+ * 渲染节点配置组件
+ */
+ const renderConfigComponent = computed(() => {
+ if (!props.node || !props.node.type) {
+ return h(NEmpty, {
+ description: $t('t_2_1744870863419'),
+ })
+ }
+ const nodeType = props.node.type
+ // 查找对应类型的配置组件
+ if (nodeConfigComponents.value[nodeType]) {
+ return h(nodeConfigComponents.value[nodeType], { node: props.node })
+ }
+ // 找不到对应的配置组件时显示提示
+ return h(NEmpty, {
+ description: $t('t_3_1744870864615'),
+ })
+ })
+
+ loadComponents()
+
+ return () => (
+
+ {renderConfigComponent.value}
+
+ )
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/components/render/nodeWrap.tsx b/frontend/apps/allin-ssl/src/components/flowChart/components/render/nodeWrap.tsx
new file mode 100644
index 0000000..6ee3e03
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/components/render/nodeWrap.tsx
@@ -0,0 +1,80 @@
+import { BRANCH, EXECUTE_RESULT_BRANCH } from '@components/flowChart/lib/alias'
+import BranchNode from '@components/flowChart/components/base/branchNode'
+import ConditionNode from '@components/flowChart/components/base/conditionNode'
+import BaseNode from '@components/flowChart/components/base/baseNode'
+import NodeWrap from '@components/flowChart/components/render/nodeWrap'
+
+import type { BaseNodeData, BranchNodeData, ExecuteResultBranchNodeData } from '@components/flowChart/types'
+
+interface NodeWrapProps {
+ node?: BaseNodeData | BranchNodeData
+ depth?: number
+}
+
+// 自定义样式
+const styles = {
+ flowNodeWrap: 'flex flex-col items-center w-full relative',
+ flowNodeWrapNested: 'nested-node-wrap w-full',
+ flowNodeWrapDeep: 'deep-nested-node-wrap w-full',
+}
+
+export default defineComponent({
+ name: 'NodeWrap',
+ props: {
+ // 节点数据
+ node: {
+ type: Object as PropType,
+ default: () => ({}),
+ },
+ // 嵌套深度
+ depth: {
+ type: Number,
+ default: 0,
+ },
+ },
+ emits: ['select'],
+ setup(props: NodeWrapProps, { emit }) {
+ // 计算当前节点的嵌套深度样式类
+ const getDepthClass = () => {
+ if (props.depth && props.depth > 1) {
+ return props.depth > 2 ? styles.flowNodeWrapDeep : styles.flowNodeWrapNested
+ }
+ return styles.flowNodeWrap
+ }
+
+ // 选中节点
+ const handleSelect = (node: BaseNodeData | BranchNodeData | ExecuteResultBranchNodeData) => {
+ if (node.id) emit('select', node.id)
+ }
+
+ return {
+ getDepthClass,
+ handleSelect,
+ }
+ },
+ render() {
+ if (!this.node) return null
+ const currentDepth = this.depth || 0
+ const nextDepth = currentDepth + 1
+
+ return (
+
+ {/* 判断是否为分支节点或普通节点 */}
+ {this.node.type === BRANCH ? : null}
+
+ {/* 判断是否为条件节点 */}
+ {this.node.type === EXECUTE_RESULT_BRANCH ? (
+
+ ) : null}
+
+ {/* 判断是否为普通节点 */}
+ {![BRANCH, EXECUTE_RESULT_BRANCH].includes(this.node.type) ? : null}
+
+ {/* 判断是否存在子节点 */}
+ {this.node.childNode?.type && (
+ this.$emit('select', nodeId)} />
+ )}
+
+ )
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/components/task/.DS_Store b/frontend/apps/allin-ssl/src/components/flowChart/components/task/.DS_Store
new file mode 100644
index 0000000..646cc91
Binary files /dev/null and b/frontend/apps/allin-ssl/src/components/flowChart/components/task/.DS_Store differ
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/components/task/applyNode/drawer.tsx b/frontend/apps/allin-ssl/src/components/flowChart/components/task/applyNode/drawer.tsx
new file mode 100644
index 0000000..15514d5
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/components/task/applyNode/drawer.tsx
@@ -0,0 +1,103 @@
+import { NFormItem, NInputNumber } from 'naive-ui'
+import { useForm, useFormHooks, useModalHooks } from '@baota/naive-ui/hooks'
+import { useStore } from '@components/flowChart/useStore'
+import { $t } from '@locales/index'
+import rules from './verify'
+import DnsProviderSelect from '@components/dnsProviderSelect'
+
+import type { ApplyNodeConfig } from '@components/flowChart/types'
+
+export default defineComponent({
+ name: 'ApplyNodeDrawer',
+ props: {
+ // 节点配置数据
+ node: {
+ type: Object as PropType<{ id: string; config: ApplyNodeConfig }>,
+ default: () => ({
+ id: '',
+ config: {},
+ }),
+ },
+ },
+ setup(props) {
+ const { updateNodeConfig, isRefreshNode } = useStore()
+ // 弹窗辅助
+ const { confirm } = useModalHooks()
+ // 获取表单助手函数
+ const { useFormInput } = useFormHooks()
+
+ // 表单参数
+ const param = ref(
+ Object.keys(props.node.config).length > 0
+ ? props.node.config
+ : { domains: '', email: '', provider_id: '', provider: '', end_day: 30 },
+ )
+
+ // 表单渲染配置
+ const config = computed(() => {
+ // 基本选项
+ return [
+ useFormInput($t('t_17_1745227838561'), 'domains', {
+ placeholder: $t('t_0_1745735774005'),
+ }),
+ useFormInput($t('t_1_1745735764953'), 'email', {
+ placeholder: $t('t_2_1745735773668'),
+ }),
+ {
+ type: 'custom' as const,
+ render: () => {
+ return (
+ {
+ param.value.provider_id = val.value
+ param.value.provider = val.type
+ }}
+ />
+ )
+ },
+ },
+ {
+ type: 'custom' as const,
+ render: () => {
+ return (
+
+
+ {$t('t_7_1745735768326')}
+
+ )
+ },
+ },
+ ]
+ })
+
+ // 创建表单实例
+ const { component: Form, data, example } = useForm({ defaultValue: param, config, rules })
+
+ // 确认事件触发
+ confirm(async (close) => {
+ try {
+ await example.value?.validate()
+ updateNodeConfig(props.node.id, data.value) // 更新节点配置
+ isRefreshNode.value = props.node.id // 刷新节点
+ close()
+ } catch (error) {
+ console.log(error)
+ }
+ })
+
+ return () => (
+
+
+
+ )
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/components/task/applyNode/index.tsx b/frontend/apps/allin-ssl/src/components/flowChart/components/task/applyNode/index.tsx
new file mode 100644
index 0000000..ee68589
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/components/task/applyNode/index.tsx
@@ -0,0 +1,61 @@
+import { useNodeValidator } from '@components/flowChart/lib/verify'
+import { useStore } from '@components/flowChart/useStore'
+import { useThemeCssVar } from '@baota/naive-ui/theme'
+import { $t } from '@locales/index'
+import rules from './verify'
+import type { ApplyNodeConfig } from '@components/flowChart/types'
+
+interface NodeProps {
+ node: {
+ id: string
+ config: ApplyNodeConfig
+ }
+}
+
+export default defineComponent({
+ name: 'ApplyNode',
+ props: {
+ node: {
+ type: Object as PropType<{ id: string; config: ApplyNodeConfig }>,
+ default: () => ({ id: '', config: {} }),
+ },
+ },
+ setup(props: NodeProps) {
+ // 注册验证器
+ const { isRefreshNode } = useStore()
+ // 初始化节点状态
+ const { registerCompatValidator, validate, validationResult, unregisterValidator } = useNodeValidator()
+ // 主题色
+ const cssVar = useThemeCssVar(['warningColor', 'primaryColor'])
+
+ // 是否有效
+ const validColor = computed(() => {
+ return validationResult.value.valid ? 'var(--n-primary-color)' : 'var(--n-warning-color)'
+ })
+
+ // 监听是否刷新节点
+ watch(
+ () => isRefreshNode.value,
+ (newVal) => {
+ useTimeoutFn(() => {
+ registerCompatValidator(props.node.id, rules, props.node.config)
+ validate(props.node.id)
+ isRefreshNode.value = null
+ }, 500)
+ },
+ { immediate: true },
+ )
+
+ //
+ onUnmounted(() => unregisterValidator(props.node.id))
+
+ // 渲染节点状态
+ return () => (
+
+
+ {validationResult.value.valid ? '域名:' + props.node.config?.domains : $t('t_9_1745735765287')}
+
+
+ )
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/components/task/applyNode/verify.tsx b/frontend/apps/allin-ssl/src/components/flowChart/components/task/applyNode/verify.tsx
new file mode 100644
index 0000000..b490e2f
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/components/task/applyNode/verify.tsx
@@ -0,0 +1,62 @@
+import type { FormRules, FormItemRule } from 'naive-ui'
+import { isDomainGroup, isEmail } from '@baota/utils/business'
+import { $t } from '@locales/index'
+
+export default {
+ domains: {
+ required: true,
+ trigger: 'input',
+ validator: (rule: FormItemRule, value: string) => {
+ return new Promise((resolve, reject) => {
+ if (!isDomainGroup(value)) {
+ reject(new Error($t('t_0_1745553910661')))
+ } else if (!value) {
+ reject(new Error($t('t_0_1746697487119')))
+ } else {
+ resolve()
+ }
+ })
+ },
+ },
+ email: {
+ required: true,
+ trigger: 'input',
+ validator: (rule: FormItemRule, value: string) => {
+ return new Promise((resolve, reject) => {
+ if (!isEmail(value)) {
+ reject(new Error($t('t_1_1745553909483')))
+ } else if (!value) {
+ reject(new Error($t('t_1_1746697485188')))
+ } else {
+ resolve()
+ }
+ })
+ },
+ },
+ provider_id: {
+ required: true,
+ trigger: 'change',
+ validator: (rule: FormItemRule, value: string) => {
+ return new Promise((resolve, reject) => {
+ if (!value) {
+ reject(new Error($t('t_3_1745490735059')))
+ } else {
+ resolve()
+ }
+ })
+ },
+ },
+ end_day: {
+ required: true,
+ trigger: 'input',
+ validator: (rule: FormItemRule, value: number) => {
+ return new Promise((resolve, reject) => {
+ if (!value) {
+ reject(new Error($t('t_2_1745553907423')))
+ } else {
+ resolve()
+ }
+ })
+ },
+ },
+} as FormRules
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/components/task/deployNode/drawer.tsx b/frontend/apps/allin-ssl/src/components/flowChart/components/task/deployNode/drawer.tsx
new file mode 100644
index 0000000..b95f809
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/components/task/deployNode/drawer.tsx
@@ -0,0 +1,293 @@
+import { NButton, NCard, NStep, NSteps, NText, NTooltip } from 'naive-ui'
+import { useForm, useFormHooks, useModalClose, useModalOptions, useMessage } from '@baota/naive-ui/hooks'
+import { useThemeCssVar } from '@baota/naive-ui/theme'
+import { useError } from '@baota/hooks/error'
+import { useStore } from '@components/flowChart/useStore'
+import { DeployNodeConfig, DeployNodeInputsConfig } from '@components/flowChart/types'
+import { $t } from '@locales/index'
+import SvgIcon from '@components/svgIcon'
+import DnsProviderSelect from '@/components/dnsProviderSelect'
+
+import styles from './index.module.css'
+import verifyRules from './verify'
+
+type StepStatus = 'process' | 'wait' | 'finish' | 'error'
+
+export default defineComponent({
+ name: 'DeployNodeDrawer',
+ props: {
+ // 节点配置数据
+ node: {
+ type: Object as PropType<{ id: string; config: DeployNodeConfig; inputs: DeployNodeInputsConfig[] }>,
+ default: () => ({
+ id: '',
+ inputs: [],
+ config: {
+ provider: '',
+ provider_id: '',
+ },
+ }),
+ },
+ },
+ setup(props) {
+ const { updateNode, updateNodeConfig, findApplyUploadNodesUp, isRefreshNode } = useStore()
+ // 获取表单助手函数
+ const { useFormInput, useFormTextarea, useFormSelect } = useFormHooks()
+ // 样式支持
+ const cssVar = useThemeCssVar(['primaryColor', 'borderColor'])
+ // 错误处理
+ const { handleError } = useError()
+ // 消息处理
+ const message = useMessage()
+ // 弹窗配置
+ const modalOptions = useModalOptions()
+ // 弹窗关闭
+ const closeModal = useModalClose()
+
+ // 部署类型选项
+ const deployTypeOptions = [
+ { label: $t('t_5_1744958839222'), value: 'ssh' },
+ { label: $t('t_10_1745735765165'), value: 'btpanel' },
+ { label: $t('t_11_1745735766456'), value: 'btpanel-site' },
+ { label: $t('t_12_1745735765571'), value: '1panel' },
+ { label: $t('t_13_1745735766084'), value: '1panel-site' },
+ { label: $t('t_14_1745735766121'), value: 'tencentcloud-cdn' },
+ { label: $t('t_15_1745735768976'), value: 'tencentcloud-cos' },
+ { label: $t('t_16_1745735766712'), value: 'aliyun-cdn' },
+ { label: $t('t_2_1746697487164'), value: 'aliyun-oss' },
+ ]
+ const certOptions = ref<{ label: string; value: string }[]>([]) // 证书选项
+ const current = ref(1) // 当前步骤
+ const next = ref(true) // 是否是下一步
+ const currentStatus = ref('process') // 当前步骤状态
+ // 表单参数
+ const param = ref(
+ Object.keys(props.node.config).length > 0
+ ? {
+ ...props.node.config,
+ inputs: Array.isArray(props.node.inputs) ? props.node.inputs[0] : { fromNodeId: '', name: '' },
+ }
+ : {
+ provider: '',
+ provider_id: '',
+ inputs: {
+ fromNodeId: '',
+ name: '',
+ },
+ },
+ ) as Ref
+
+ // 表单配置
+ const formConfig = computed(() => {
+ const config = []
+ config.push(
+ ...[
+ {
+ type: 'custom' as const,
+ render: () => {
+ return (
+ {
+ param.value.provider_id = val.value
+ }}
+ />
+ )
+ },
+ },
+ ],
+ useFormSelect($t('t_1_1745748290291'), 'inputs.fromNodeId', certOptions.value, {
+ onUpdateValue: (val, option: { label: string; value: string }) => {
+ param.value.inputs.fromNodeId = val
+ param.value.inputs.name = option?.label
+ },
+ }),
+ )
+ switch (param.value.provider) {
+ case 'ssh':
+ config.push(
+ ...[
+ useFormInput('证书文件路径(仅支持PEM格式)', 'certPath', { placeholder: $t('t_30_1746667591892') }),
+ useFormInput('私钥文件路径', 'keyPath', { placeholder: $t('t_31_1746667593074') }),
+ useFormTextarea(
+ '前置命令',
+ 'beforeCmd',
+ { placeholder: $t('t_21_1745735769154') },
+ { showRequireMark: false },
+ ),
+ useFormTextarea(
+ '后置命令',
+ 'afterCmd',
+ { placeholder: $t('t_22_1745735767366') },
+ { showRequireMark: false },
+ ),
+ ],
+ )
+ break
+ case 'btpanel-site':
+ config.push(...[useFormInput('站点名称', 'siteName', { placeholder: $t('t_23_1745735766455') })])
+ break
+ case '1panel-site':
+ config.push(...[useFormInput('站点ID', 'site_id', { placeholder: $t('t_24_1745735766826') })])
+ break
+ case 'tencentcloud-cdn':
+ case 'aliyun-cdn':
+ config.push(...[useFormInput('域名', 'domain', { placeholder: $t('t_0_1744958839535') })])
+ break
+ case 'tencentcloud-cos':
+ case 'aliyun-oss':
+ config.push(...[useFormInput('域名', 'domain', { placeholder: $t('t_0_1744958839535') })])
+ config.push(...[useFormInput('区域', 'region', { placeholder: $t('t_25_1745735766651') })])
+ config.push(...[useFormInput('存储桶', 'bucket', { placeholder: $t('t_26_1745735767144') })])
+ break
+ }
+ return config
+ })
+
+ /**
+ * @description 下一步
+ * @returns
+ */
+ const nextStep = async () => {
+ if (!param.value.provider) return message.error($t('t_19_1745735766810'))
+
+ // 加载证书来源选项
+ certOptions.value = findApplyUploadNodesUp(props.node.id).map((item) => {
+ return { label: item.name, value: item.id }
+ })
+ if (!certOptions.value.length) {
+ message.warning($t('t_3_1745748298161'))
+ } else if (!(param.value.inputs && param.value.inputs.fromNodeId)) {
+ param.value.inputs = {} as DeployNodeInputsConfig
+ param.value.inputs.name = certOptions.value[0]?.label || ''
+ param.value.inputs.fromNodeId = certOptions.value[0]?.value || ''
+ }
+ current.value++
+ next.value = false
+ }
+
+ /**
+ * @description 上一步
+ * @returns
+ */
+ const prevStep = () => {
+ current.value--
+ next.value = true
+ param.value.provider_id = ''
+ param.value.provider = ''
+ }
+
+ // 表单组件
+ const { component: Form, example } = useForm({
+ config: formConfig,
+ defaultValue: param,
+ rules: verifyRules,
+ })
+
+ /**
+ * @description 提交
+ * @returns
+ */
+ const submit = async () => {
+ try {
+ await example.value?.validate()
+ const tempData = param.value
+ const inputs = tempData.inputs
+ console.log(inputs, 'inputs', props.node)
+ updateNode(
+ props.node.id,
+ {
+ inputs: [inputs],
+ config: {},
+ },
+ false,
+ )
+ delete tempData.inputs
+ updateNodeConfig(props.node.id, {
+ ...tempData,
+ })
+ isRefreshNode.value = props.node.id
+ closeModal()
+ } catch (error) {
+ handleError(error)
+ }
+ }
+
+ // 初始化
+ onMounted(() => {
+ // 隐藏底部按钮
+ modalOptions.value.footer = false
+ // 如果已经选择了部署类型,则跳转到下一步
+ if (param.value.provider) {
+ if (props.node.inputs) param.value.inputs = props.node.inputs
+ nextStep()
+ }
+ })
+
+ return () => (
+
+
+
+
+
+ {current.value === 1 && (
+
+ {deployTypeOptions.map((item) => (
+
{
+ param.value.provider = item.value
+ }}
+ >
+
+
+ {item.label}
+
+
+ ))}
+
+ )}
+ {current.value === 2 && (
+
+
+
+ )}
+
+
+ )
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/components/task/deployNode/index.module.css b/frontend/apps/allin-ssl/src/components/flowChart/components/task/deployNode/index.module.css
new file mode 100644
index 0000000..a6d923c
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/components/task/deployNode/index.module.css
@@ -0,0 +1,70 @@
+/* Deploy Node Drawer Styles */
+
+/* Card container styles */
+.cardContainer {
+ @apply grid grid-cols-3 gap-4 mt-[2.4rem];
+}
+
+/* Option card styles */
+.optionCard {
+ @apply flex items-center justify-center rounded-[0.4rem] transition-all border-[1px] border-transparent;
+ border-color: var(--n-border-color);
+}
+
+.optionCardSelected {
+ @apply border-[1px] relative overflow-hidden;
+ border-color: var(--n-primary-color);
+}
+
+/* Add checkmark for selected item */
+.optionCardSelected::after {
+ content: '';
+ @apply absolute bottom-[.1rem] right-[.1rem] w-[1rem] h-[1rem] rounded-full z-10;
+ @apply bg-[length:14px_14px] bg-center bg-no-repeat;
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3E%3Cpath d='M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z'/%3E%3C/svg%3E");
+}
+
+/* Add triangle in bottom-right corner for selected item */
+.optionCardSelected::before {
+ content: '';
+ @apply absolute -bottom-[.1rem] -right-[.1rem] w-0 h-0 z-10 text-white text-xs flex items-center justify-center;
+ border-style: solid;
+ border-width: 0 0 20px 20px;
+ border-color: transparent transparent var(--n-primary-color) transparent;
+ line-height: 0;
+ padding-left: 2px;
+ padding-bottom: 2px;
+}
+
+/* Card content styles */
+.cardContent {
+ @apply flex flex-col items-center justify-center p-[4px] cursor-pointer;
+}
+
+/* Icon styles */
+.icon {
+ @apply mb-[0.4rem];
+}
+
+.iconSelected {
+ color: var(--n-primary-color);
+}
+
+/* Footer styles */
+.footer {
+ @apply flex justify-end absolute right-[1.2rem] -bottom-[1.2rem];
+}
+
+.footerButton {
+ @apply mr-[0.8rem];
+}
+
+/* Main container */
+.container {
+ @apply pb-[3.2rem];
+}
+
+/* Form container */
+.formContainer {
+ @apply mt-[2.4rem];
+}
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/components/task/deployNode/index.tsx b/frontend/apps/allin-ssl/src/components/flowChart/components/task/deployNode/index.tsx
new file mode 100644
index 0000000..dbf3dec
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/components/task/deployNode/index.tsx
@@ -0,0 +1,68 @@
+import { useNodeValidator } from '@components/flowChart/lib/verify'
+import { useStore } from '@components/flowChart/useStore'
+import { useThemeCssVar } from '@baota/naive-ui/theme'
+import { $t } from '@locales/index'
+import TypeIcon from '@components/typeIcon'
+import rules from './verify'
+import type { DeployNodeConfig, DeployNodeInputsConfig } from '@components/flowChart/types'
+
+interface NodeProps {
+ node: {
+ id: string
+ inputs: DeployNodeInputsConfig
+ config: DeployNodeConfig
+ }
+}
+
+export default defineComponent({
+ name: 'DeployNode',
+ props: {
+ node: {
+ type: Object as PropType<{ id: string; inputs: DeployNodeInputsConfig; config: DeployNodeConfig }>,
+ default: () => ({ id: '', inputs: {}, config: {} }),
+ },
+ },
+ setup(props: NodeProps) {
+ // 注册验证器
+ const { isRefreshNode } = useStore()
+ // 初始化节点状态
+ const { registerCompatValidator, validate, validationResult, unregisterValidator } = useNodeValidator()
+ // 主题色
+ const cssVar = useThemeCssVar(['warningColor', 'primaryColor'])
+
+ // 是否有效
+ const validColor = computed(() => {
+ return validationResult.value.valid ? 'var(--n-primary-color)' : 'var(--n-warning-color)'
+ })
+
+ // 提示内容
+ const verificationPrompt = computed(() => {
+ console.log(props.node.config.provider, 'validationResult')
+ if (validationResult.value.valid) return
+ return $t('t_9_1745735765287')
+ })
+
+ // 监听是否刷新节点
+ watch(
+ () => isRefreshNode.value,
+ (newVal) => {
+ useTimeoutFn(() => {
+ registerCompatValidator(props.node.id, rules, props.node.config)
+ validate(props.node.id)
+ isRefreshNode.value = null
+ }, 500)
+ },
+ { immediate: true },
+ )
+
+ //
+ onUnmounted(() => unregisterValidator(props.node.id))
+
+ // 渲染节点状态
+ return () => (
+
+
{verificationPrompt.value}
+
+ )
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/components/task/deployNode/verify.tsx b/frontend/apps/allin-ssl/src/components/flowChart/components/task/deployNode/verify.tsx
new file mode 100644
index 0000000..c2919e8
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/components/task/deployNode/verify.tsx
@@ -0,0 +1,72 @@
+import type { FormRules, FormItemRule } from 'naive-ui'
+import { $t } from '@locales/index'
+import { isDomain } from '@baota/utils/business'
+
+export default {
+ provider: {
+ required: true,
+ message: $t('t_19_1745735766810'),
+ type: 'string',
+ trigger: 'change',
+ },
+ provider_id: {
+ required: true,
+ trigger: 'change',
+ type: 'string',
+ validator: (rule: FormItemRule, value: number) => {
+ if (!value) {
+ return new Error($t('t_1_1745744905566'))
+ }
+ },
+ },
+ 'inputs.fromNodeId': {
+ required: true,
+ message: $t('t_3_1745748298161'),
+ trigger: 'change',
+ },
+
+ certPath: {
+ required: true,
+ message: $t('t_30_1746667591892'),
+ trigger: 'input',
+ },
+ keyPath: {
+ required: true,
+ message: $t('t_31_1746667593074'),
+ trigger: 'input',
+ },
+
+ // btpanel相关字段
+ siteName: {
+ required: true,
+ message: $t('t_23_1745735766455'),
+ trigger: 'input',
+ },
+ // 1panel相关字段
+ site_id: {
+ required: true,
+ message: $t('t_24_1745735766826'),
+ trigger: 'input',
+ },
+ // CDN相关字段
+ domain: {
+ required: true,
+ trigger: 'input',
+ validator: (rule: FormItemRule, value: string) => {
+ if (!isDomain(value)) {
+ return new Error($t('t_0_1744958839535'))
+ }
+ },
+ },
+ // 存储桶相关字段
+ region: {
+ required: true,
+ message: $t('t_25_1745735766651'),
+ trigger: 'input',
+ },
+ bucket: {
+ required: true,
+ message: $t('t_26_1745735767144'),
+ trigger: 'input',
+ },
+} as FormRules
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/components/task/notifyNode/drawer.tsx b/frontend/apps/allin-ssl/src/components/flowChart/components/task/notifyNode/drawer.tsx
new file mode 100644
index 0000000..61b7001
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/components/task/notifyNode/drawer.tsx
@@ -0,0 +1,97 @@
+import { useForm, useFormHooks, useModalHooks } from '@baota/naive-ui/hooks'
+import { FormConfig } from '@baota/naive-ui/types/form'
+import { useStore } from '@components/flowChart/useStore'
+import { useError } from '@baota/hooks/error'
+import { $t } from '@locales/index'
+// 假设这个类型需要在types文件中定义
+
+import NotifyProviderSelect from '@components/notifyProviderSelect'
+import verify from './verify'
+
+import { NotifyNodeConfig } from '@components/flowChart/types'
+
+export default defineComponent({
+ name: 'NotifyNodeDrawer',
+ props: {
+ // 节点配置数据
+ node: {
+ type: Object as PropType<{ id: string; config: NotifyNodeConfig }>,
+ default: () => ({
+ id: '',
+ config: {
+ provider: '',
+ provider_id: '',
+ subject: '',
+ body: '',
+ },
+ }),
+ },
+ },
+ setup(props) {
+ const { updateNodeConfig, isRefreshNode } = useStore()
+ const { useFormInput, useFormTextarea, useFormCustom } = useFormHooks()
+ const { confirm } = useModalHooks()
+ const { handleError } = useError()
+ const param = ref(
+ Object.keys(props.node.config).length > 0
+ ? props.node.config
+ : {
+ provider: '',
+ provider_id: '',
+ subject: '',
+ body: '',
+ },
+ )
+
+ // 表单渲染配置
+ const formConfig: FormConfig = [
+ useFormInput($t('t_0_1745920566646'), 'subject', {
+ placeholder: $t('t_3_1745887835089'),
+ }),
+ useFormTextarea($t('t_1_1745920567200'), 'body', {
+ placeholder: $t('t_4_1745887835265'),
+ rows: 4,
+ }),
+ useFormCustom(() => (
+ {
+ param.value.provider_id = item.value
+ param.value.provider = item.type
+ }}
+ />
+ )),
+ ]
+
+ // 创建表单实例
+ const {
+ component: Form,
+ data,
+ example,
+ } = useForm({
+ defaultValue: param,
+ config: formConfig,
+ rules: verify,
+ })
+
+ // 确认事件触发
+ confirm(async (close) => {
+ try {
+ await example.value?.validate()
+ updateNodeConfig(props.node.id, data.value)
+ isRefreshNode.value = props.node.id
+ close()
+ } catch (error) {
+ handleError(error)
+ }
+ })
+
+ return () => (
+
+
+
+ )
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/components/task/notifyNode/index.tsx b/frontend/apps/allin-ssl/src/components/flowChart/components/task/notifyNode/index.tsx
new file mode 100644
index 0000000..4e84da6
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/components/task/notifyNode/index.tsx
@@ -0,0 +1,61 @@
+import { useThemeCssVar } from '@baota/naive-ui/theme'
+import { useNodeValidator } from '@components/flowChart/lib/verify'
+import { NotifyNodeConfig } from '@components/flowChart/types'
+import { useStore } from '@components/flowChart/useStore'
+
+import rules from './verify'
+import TypeIcon from '@components/typeIcon'
+import { $t } from '@locales/index'
+export default defineComponent({
+ name: 'NotifyNode',
+ props: {
+ node: {
+ type: Object as PropType<{ id: string; config: NotifyNodeConfig }>,
+ default: () => ({ id: '', config: {} }),
+ },
+ },
+ setup(props) {
+ // 注册验证器
+ const { isRefreshNode } = useStore()
+ const { validate, validationResult, registerCompatValidator, unregisterValidator } = useNodeValidator()
+ // 主题色
+ const cssVar = useThemeCssVar(['warningColor', 'primaryColor'])
+
+ // 是否有效
+ const validColor = computed(() => {
+ return validationResult.value.valid && props.node.config.provider
+ ? 'var(--n-primary-color)'
+ : 'var(--n-warning-color)'
+ })
+
+ // 提示内容
+ const verificationPrompt = computed(() => {
+ if (validationResult.value.valid && props.node.config.provider)
+ return
+ return $t('t_9_1745735765287')
+ })
+
+ // 监听是否刷新节点
+ watch(
+ () => isRefreshNode.value,
+ (newVal) => {
+ useTimeoutFn(() => {
+ registerCompatValidator(props.node.id, rules, props.node.config)
+ validate(props.node.id)
+ isRefreshNode.value = null
+ }, 500)
+ },
+ { immediate: true },
+ )
+
+ // 卸载验证器
+ onUnmounted(() => unregisterValidator(props.node.id))
+
+ // 渲染节点状态
+ return () => (
+
+
{verificationPrompt.value}
+
+ )
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/components/task/notifyNode/verify.tsx b/frontend/apps/allin-ssl/src/components/flowChart/components/task/notifyNode/verify.tsx
new file mode 100644
index 0000000..892b6f4
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/components/task/notifyNode/verify.tsx
@@ -0,0 +1,46 @@
+import type { FormItemRule, FormRules } from 'naive-ui'
+import { $t } from '@locales/index'
+
+export default {
+ subject: {
+ trigger: 'input',
+ validator: (rule: FormItemRule, value: string) => {
+ return new Promise((resolve, reject) => {
+ if (!value) {
+ reject(new Error($t('t_3_1745887835089')))
+ } else if (value.length > 100) {
+ reject(new Error($t('t_3_1745887835089') + '长度不能超过100个字符'))
+ } else {
+ resolve()
+ }
+ })
+ },
+ },
+ body: {
+ trigger: 'input',
+ validator: (rule: FormItemRule, value: string) => {
+ return new Promise((resolve, reject) => {
+ if (!value) {
+ reject(new Error($t('t_4_1745887835265')))
+ } else if (value.length > 1000) {
+ reject(new Error($t('t_4_1745887835265') + '长度不能超过1000个字符'))
+ } else {
+ resolve()
+ }
+ })
+ },
+ },
+ provider_id: {
+ trigger: 'change',
+ type: 'string',
+ validator: (rule: FormItemRule, value: string) => {
+ return new Promise((resolve, reject) => {
+ if (!value) {
+ reject(new Error($t('t_0_1745887835267')))
+ } else {
+ resolve()
+ }
+ })
+ },
+ },
+} as FormRules
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/components/task/startNode/drawer.tsx b/frontend/apps/allin-ssl/src/components/flowChart/components/task/startNode/drawer.tsx
new file mode 100644
index 0000000..20ae096
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/components/task/startNode/drawer.tsx
@@ -0,0 +1,206 @@
+import { NFormItemGi, NGrid, NInputGroup, NInputGroupLabel, NInputNumber, NSelect } from 'naive-ui'
+import { useForm, useFormHooks, useModalHooks } from '@baota/naive-ui/hooks'
+import { $t } from '@locales/index'
+import { useStore } from '@components/flowChart/useStore'
+import rules from './verify'
+
+import type { StartNodeConfig } from '@components/flowChart/types'
+import type { FormConfig } from '@baota/naive-ui/types/form'
+
+// 类型
+import type { VNode } from 'vue'
+import { useError } from '@baota/hooks/error'
+
+export default defineComponent({
+ name: 'StartNodeDrawer',
+ props: {
+ // 节点配置数据
+ node: {
+ type: Object as PropType<{ id: string; config: StartNodeConfig }>,
+ default: () => ({}),
+ },
+ },
+ setup(props) {
+ const { updateNodeConfig, isRefreshNode } = useStore()
+ // 弹窗辅助
+ const { confirm } = useModalHooks()
+ // 错误处理
+ const { handleError } = useError()
+ // 获取表单助手函数
+ const { useFormRadio, useFormCustom } = useFormHooks()
+ // 表单参数
+ const param = ref(
+ Object.values(props.node.config).length > 0 ? props.node.config : { exec_type: 'manual' },
+ )
+
+ // 周期类型选项
+ const cycleTypeOptions = [
+ { label: $t('t_2_1744875938555'), value: 'day' },
+ { label: $t('t_0_1744942117992'), value: 'week' },
+ { label: $t('t_3_1744875938310'), value: 'month' },
+ ]
+
+ // 星期选项
+ const weekOptions = [
+ { label: $t('t_1_1744942116527'), value: 1 },
+ { label: $t('t_2_1744942117890'), value: 2 },
+ { label: $t('t_3_1744942117885'), value: 3 },
+ { label: $t('t_4_1744942117738'), value: 4 },
+ { label: $t('t_5_1744942117167'), value: 5 },
+ { label: $t('t_6_1744942117815'), value: 6 },
+ { label: $t('t_7_1744942117862'), value: 0 },
+ ]
+
+ // 定义默认值常量,避免重复
+ const DEFAULT_AUTO_SETTINGS: Record = {
+ day: { exec_type: 'auto', type: 'day', hour: 1, minute: 0 },
+ week: { exec_type: 'auto', type: 'week', hour: 1, minute: 0, week: 1 },
+ month: { exec_type: 'auto', type: 'month', hour: 1, minute: 0, month: 1 },
+ }
+
+ // 节点配置
+ const { config } = toRefs(props.node)
+
+ // 创建时间输入input
+ const createTimeInput = (value: number, updateFn: (val: number) => void, max: number, label: string): VNode => (
+
+ {
+ if (val !== null) {
+ updateFn(val)
+ }
+ }}
+ max={max}
+ min={0}
+ showButton={false}
+ class="w-full"
+ />
+ {label}
+
+ )
+
+ // 表单渲染
+ const formRender = computed(() => {
+ const formItems: FormConfig = []
+ if (param.value.exec_type === 'auto') {
+ formItems.push(
+ useFormCustom(() => {
+ return (
+
+
+
+
+
+ {param.value.type !== 'day' && (
+
+ {param.value.type === 'week' ? (
+ {
+ if (typeof val === 'number') {
+ param.value.week = val
+ }
+ }}
+ options={weekOptions}
+ />
+ ) : (
+ createTimeInput(
+ param.value.month || 0,
+ (val: number) => (param.value.month = val),
+ 31,
+ $t('t_29_1744958838904'),
+ )
+ )}
+
+ )}
+
+
+ {createTimeInput(
+ param.value.hour || 0,
+ (val: number) => (param.value.hour = val),
+ 23,
+ $t('t_5_1744879615277'),
+ )}
+
+
+
+ {createTimeInput(
+ param.value.minute || 0,
+ (val: number) => (param.value.minute = val),
+ 59,
+ $t('t_3_1744879615723'),
+ )}
+
+
+ )
+ }),
+ )
+ }
+ return [
+ // 运行模式选择
+ useFormRadio($t('t_30_1745735764748'), 'exec_type', [
+ { label: $t('t_4_1744875940750'), value: 'auto' },
+ { label: $t('t_5_1744875940010'), value: 'manual' },
+ ]),
+ ...formItems,
+ ]
+ })
+
+ // 创建表单实例
+ const {
+ component: Form,
+ data,
+ example,
+ } = useForm({
+ defaultValue: param,
+ config: formRender,
+ rules,
+ })
+
+ // 更新参数的函数
+ const updateParamValue = (updates: StartNodeConfig) => {
+ param.value = { ...updates }
+ }
+
+ // 监听执行类型变化
+ watch(
+ () => param.value.exec_type,
+ (newVal) => {
+ if (newVal === 'auto') {
+ updateParamValue(DEFAULT_AUTO_SETTINGS.day as StartNodeConfig)
+ } else if (newVal === 'manual') {
+ updateParamValue({ exec_type: 'manual' })
+ }
+ },
+ )
+
+ // 监听类型变化
+ watch(
+ () => param.value.type,
+ (newVal) => {
+ if (newVal && param.value.exec_type === 'auto') {
+ updateParamValue(DEFAULT_AUTO_SETTINGS[newVal] as StartNodeConfig)
+ }
+ },
+ )
+
+ // 确认事件触发
+ confirm(async (close) => {
+ try {
+ await example.value?.validate()
+ updateNodeConfig(props.node.id, data.value) // 更新节点配置
+ isRefreshNode.value = props.node.id // 刷新节点
+ close()
+ } catch (error) {
+ handleError(error)
+ }
+ })
+
+ return () => (
+
+
+
+ )
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/components/task/startNode/index.tsx b/frontend/apps/allin-ssl/src/components/flowChart/components/task/startNode/index.tsx
new file mode 100644
index 0000000..65e3fdf
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/components/task/startNode/index.tsx
@@ -0,0 +1,68 @@
+// import { defineComponent, inject } from 'vue'
+// import { KEY_PROCESS_DATA, KEY_VALIDATOR } from '../../config/keys'
+import { useStore } from '@components/flowChart/useStore'
+import { useNodeValidator } from '@components/flowChart/lib/verify'
+import { useThemeCssVar } from '@baota/naive-ui/theme'
+import { $t } from '@locales/index'
+import rules from './verify'
+import type { StartNodeConfig } from '@components/flowChart/types'
+
+interface NodeProps {
+ node: {
+ id: string
+ config: StartNodeConfig
+ }
+}
+
+export default defineComponent({
+ name: 'StartNode',
+ props: {
+ node: {
+ type: Object as PropType<{ id: string; config: StartNodeConfig }>,
+ default: () => ({ id: '', config: {} }),
+ },
+ },
+ setup(props: NodeProps) {
+ // 注册验证器
+ const { isRefreshNode } = useStore()
+ // 验证器
+ const { validate, validationResult, registerCompatValidator, unregisterValidator } = useNodeValidator()
+ // 主题色
+ const cssVar = useThemeCssVar(['warningColor', 'primaryColor'])
+
+ // 是否有效
+ const validColor = computed(() => {
+ return validationResult.value.valid ? 'var(--n-primary-color)' : 'var(--n-warning-color)'
+ })
+
+ // 提示
+ const verificationPrompt = computed(() => {
+ if (validationResult.value.valid) {
+ return props.node.config.exec_type === 'auto' ? $t('t_4_1744875940750') : $t('t_5_1744875940010')
+ }
+ return '未配置'
+ })
+
+ // 监听是否刷新节点
+ // 监听是否刷新节点
+ watch(
+ () => isRefreshNode.value,
+ (newVal) => {
+ useTimeoutFn(() => {
+ registerCompatValidator(props.node.id, rules, props.node.config)
+ validate(props.node.id)
+ isRefreshNode.value = null
+ }, 500)
+ },
+ { immediate: true },
+ )
+
+ onUnmounted(() => unregisterValidator(props.node.id))
+
+ return () => (
+
+
{verificationPrompt.value}
+
+ )
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/components/task/startNode/verify.tsx b/frontend/apps/allin-ssl/src/components/flowChart/components/task/startNode/verify.tsx
new file mode 100644
index 0000000..6b1217c
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/components/task/startNode/verify.tsx
@@ -0,0 +1,11 @@
+import type { FormRules } from 'naive-ui'
+import { $t } from '@locales/index'
+
+export default {
+ exec_type: { required: true, message: $t('t_31_1745735767891'), trigger: 'change' },
+ type: { required: true, message: $t('t_32_1745735767156'), trigger: 'change' },
+ week: { required: true, message: $t('t_33_1745735766532'), trigger: 'input', type: 'number' },
+ month: { required: true, message: $t('t_33_1745735766532'), trigger: 'input', type: 'number' },
+ hour: { required: true, message: $t('t_33_1745735766532'), trigger: 'input', type: 'number' },
+ minute: { required: true, message: $t('t_33_1745735766532'), trigger: 'input', type: 'number' },
+} as FormRules
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/components/task/uploadNode/drawer.tsx b/frontend/apps/allin-ssl/src/components/flowChart/components/task/uploadNode/drawer.tsx
new file mode 100644
index 0000000..5fb3610
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/components/task/uploadNode/drawer.tsx
@@ -0,0 +1,77 @@
+import { useForm, useFormHooks, useModalHooks } from '@baota/naive-ui/hooks'
+import { FormConfig } from '@baota/naive-ui/types/form'
+import { $t } from '@locales/index'
+import { useStore } from '@components/flowChart/useStore'
+import { useError } from '@baota/hooks/error'
+import verifyRules from './verify'
+import { UploadNodeConfig } from '@components/flowChart/types'
+
+export default defineComponent({
+ name: 'UploadNodeDrawer',
+ props: {
+ // 节点配置数据
+ node: {
+ type: Object as PropType<{ id: string; config: UploadNodeConfig }>,
+ default: () => ({
+ id: '',
+ config: {
+ cert: '',
+ key: '',
+ },
+ }),
+ },
+ },
+ setup(props) {
+ // 获取store
+ const { updateNodeConfig, isRefreshNode } = useStore()
+ // 获取表单助手函数
+ const { useFormTextarea } = useFormHooks()
+ // 节点配置数据
+ const { config } = toRefs(props.node)
+ // 弹窗辅助
+ const { confirm } = useModalHooks()
+ // 错误处理
+ const { handleError } = useError()
+
+ // 表单渲染配置
+ const formConfig: FormConfig = [
+ useFormTextarea($t('t_34_1745735771147'), 'cert', {
+ placeholder: $t('t_35_1745735781545'),
+ rows: 6,
+ }),
+ useFormTextarea($t('t_36_1745735769443'), 'key', {
+ placeholder: $t('t_37_1745735779980'),
+ rows: 6,
+ }),
+ ]
+
+ // 创建表单实例
+ const {
+ component: Form,
+ data,
+ example,
+ } = useForm({
+ defaultValue: config,
+ config: formConfig,
+ rules: verifyRules,
+ })
+
+ // 确认事件触发
+ confirm(async (close) => {
+ try {
+ await example.value?.validate()
+ updateNodeConfig(props.node.id, data.value) // 更新节点配置
+ console.log(data.value, props.node.id)
+ isRefreshNode.value = props.node.id // 刷新节点
+ close()
+ } catch (error) {
+ handleError(error)
+ }
+ })
+ return () => (
+
+
+
+ )
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/components/task/uploadNode/index.tsx b/frontend/apps/allin-ssl/src/components/flowChart/components/task/uploadNode/index.tsx
new file mode 100644
index 0000000..8225b77
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/components/task/uploadNode/index.tsx
@@ -0,0 +1,54 @@
+import { useNodeValidator } from '@components/flowChart/lib/verify'
+import rules from './verify'
+import { useThemeCssVar } from '@baota/naive-ui/theme'
+import { useStore } from '@components/flowChart/useStore'
+import { UploadNodeConfig } from '@components/flowChart/types'
+
+export default defineComponent({
+ name: 'UploadNode',
+ props: {
+ node: {
+ type: Object as PropType<{ id: string; config: UploadNodeConfig }>,
+ default: () => ({ id: '', config: {} }),
+ },
+ },
+ setup(props) {
+ // 注册验证器
+ const { isRefreshNode } = useStore()
+ const { validate, validationResult, registerCompatValidator, unregisterValidator } = useNodeValidator()
+ // 主题色
+ const cssVar = useThemeCssVar(['warningColor', 'primaryColor'])
+
+ // 是否有效
+ const validColor = computed(() => {
+ return validationResult.value.valid ? 'var(--n-primary-color)' : 'var(--n-warning-color)'
+ })
+
+ // 提示内容
+ const verificationPrompt = computed(() => {
+ if (validationResult.value.valid) return '已配置'
+ return '未配置'
+ })
+
+ // 监听是否刷新节点
+ watch(
+ () => isRefreshNode.value,
+ (newVal) => {
+ useTimeoutFn(() => {
+ registerCompatValidator(props.node.id, rules, props.node.config)
+ validate(props.node.id)
+ isRefreshNode.value = null
+ }, 500)
+ },
+ { immediate: true },
+ )
+
+ onUnmounted(() => unregisterValidator(props.node.id))
+
+ return () => (
+
+
{verificationPrompt.value}
+
+ )
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/components/task/uploadNode/verify.tsx b/frontend/apps/allin-ssl/src/components/flowChart/components/task/uploadNode/verify.tsx
new file mode 100644
index 0000000..2501bcc
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/components/task/uploadNode/verify.tsx
@@ -0,0 +1,30 @@
+import { $t } from '@locales/index'
+import type { FormItemRule, FormRules } from 'naive-ui'
+export default {
+ key: {
+ required: true,
+ trigger: 'input',
+ validator: (rule: FormItemRule, value: string) => {
+ return new Promise((resolve, reject) => {
+ if (!value) {
+ reject(new Error($t('t_38_1745735769521')))
+ } else {
+ resolve()
+ }
+ })
+ },
+ },
+ cert: {
+ required: true,
+ trigger: 'input',
+ validator: (rule: FormItemRule, value: string) => {
+ return new Promise((resolve, reject) => {
+ if (!value) {
+ reject(new Error($t('t_40_1745735815317')))
+ } else {
+ resolve()
+ }
+ })
+ },
+ },
+} as FormRules
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/index.module.css b/frontend/apps/allin-ssl/src/components/flowChart/index.module.css
new file mode 100644
index 0000000..dbfc301
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/index.module.css
@@ -0,0 +1,49 @@
+:root {
+ --bg-color: #f5f5f7;
+ --border-color: #5a5e66;
+}
+
+.flowContainer {
+ @apply flex relative box-border w-full h-[calc(100vh-19rem)] overflow-x-auto overflow-y-auto bg-slate-50 dark:bg-gray-900 ;
+}
+
+.flowProcess {
+ @apply relative h-full w-full;
+}
+
+.flowZoom {
+ @apply flex fixed items-center justify-between h-[4rem] w-[12.5rem] bottom-[4rem] z-[99];
+}
+
+.flowZoomIcon {
+ @apply w-[2.5rem] h-[2.5rem] cursor-pointer border flex items-center justify-center;
+ border-color: var(--border-color);
+}
+
+/* 嵌套节点包装器样式 */
+.nested-node-wrap {
+ @apply flex flex-col items-center relative;
+ max-width: 100%;
+}
+
+.deep-nested-node-wrap {
+ @apply flex flex-col items-center relative;
+ max-width: 100%;
+}
+
+/* 右侧配置区样式 */
+.configPanel {
+ @apply flex flex-col w-[360px] min-w-[360px] bg-white dark:bg-gray-800 dark:border-gray-700 z-10 rounded-lg;
+}
+
+.configHeader {
+ @apply flex items-center justify-between px-4 py-3 border-b border-gray-200 dark:border-gray-700;
+}
+
+.configContent {
+ @apply flex-1 overflow-y-auto ;
+}
+
+.emptyTip {
+ @apply flex items-center justify-center h-full text-gray-400 dark:text-gray-500;
+}
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/index.tsx b/frontend/apps/allin-ssl/src/components/flowChart/index.tsx
new file mode 100644
index 0000000..75b07fa
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/index.tsx
@@ -0,0 +1,102 @@
+import { NButton, NIcon, NInput } from 'naive-ui'
+import { SaveOutlined, ArrowLeftOutlined } from '@vicons/antd'
+import { $t } from '@locales/index'
+import SvgIcon from '@components/svgIcon'
+
+import { useController } from './useController'
+import { useStore } from './useStore'
+
+import EndNode from './components/base/endNode'
+import NodeWrap from './components/render/nodeWrap'
+
+import styles from './index.module.css'
+import type { FlowNode, FlowNodeProps } from './types'
+import { useThemeCssVar } from '@baota/naive-ui/theme'
+
+export default defineComponent({
+ name: 'FlowChart',
+ props: {
+ isEdit: {
+ type: Boolean,
+ default: false,
+ },
+ type: {
+ type: String as PropType<'quick' | 'advanced'>,
+ default: 'quick',
+ },
+ node: {
+ type: Object as PropType,
+ default: () => ({}),
+ },
+ },
+ setup(props: FlowNodeProps) {
+ const cssVars = useThemeCssVar([
+ 'borderColor',
+ 'dividerColor',
+ 'textColor1',
+ 'textColor2',
+ 'primaryColor',
+ 'primaryColorHover',
+ 'bodyColor',
+ ])
+ const { flowData, selectedNodeId, flowZoom, resetFlowData } = useStore()
+ const { initData, handleSaveConfig, handleZoom, handleSelectNode, goBack } = useController({
+ type: props?.type,
+ node: props?.node,
+ isEdit: props?.isEdit,
+ })
+ onMounted(initData)
+ onUnmounted(resetFlowData)
+ return () => (
+
+
+
+
+
+
+
+ {$t('t_0_1744861190562')}
+
+
+
+
+
+
+
+
+
+
+ {$t('t_2_1744861190040')}
+
+
+
+
+ {/* 左侧流程容器 */}
+
+ {/* 流程容器*/}
+
+ {/* 渲染流程节点 */}
+
+ {/* 流程结束节点 */}
+
+
+ {/* 缩放控制区 */}
+
+
handleZoom(1)}>
+
+
+
{flowZoom.value}%
+
handleZoom(2)}>
+
+
+
+
+
+
+ )
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/lib/alias.tsx b/frontend/apps/allin-ssl/src/components/flowChart/lib/alias.tsx
new file mode 100644
index 0000000..872f4d4
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/lib/alias.tsx
@@ -0,0 +1,14 @@
+// 基础节点
+export const END = 'end' // 结束节点
+export const DEFAULT = 'default' // 默认节点
+
+
+export const START = 'start' // 开始节点
+export const BRANCH = 'branch' // 分支节点(并行分支和条件分支)
+export const CONDITION = 'condition' // 条件子节点
+export const EXECUTE_RESULT_BRANCH = 'execute_result_branch' // 执行结果节点
+export const EXECUTE_RESULT_CONDITION = 'execute_result_condition' // 执行结果条件节点
+export const UPLOAD = 'upload' // 上传节点
+export const NOTIFY = 'notify' // 通知节点
+export const APPLY = 'apply' // 申请节点
+export const DEPLOY = 'deploy' // 部署节点
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/lib/config.tsx b/frontend/apps/allin-ssl/src/components/flowChart/lib/config.tsx
new file mode 100644
index 0000000..69debcf
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/lib/config.tsx
@@ -0,0 +1,266 @@
+import { deepMerge } from '@baota/utils/data'
+import { v4 as uuidv4 } from 'uuid'
+import {
+ APPLY,
+ BRANCH,
+ CONDITION,
+ DEPLOY,
+ NOTIFY,
+ UPLOAD,
+ EXECUTE_RESULT_BRANCH,
+ EXECUTE_RESULT_CONDITION,
+ START,
+} from './alias'
+import {
+ BaseRenderNodeOptions,
+ NodeOptions,
+ BaseNodeData,
+ ExecuteResultConditionNodeData,
+ ExecuteResultBranchNodeData,
+} from '../types'
+
+const nodeOptions = {} as NodeOptions
+
+// 基础节点配置
+const baseOptions = (
+ options: Partial> & { defaultNode?: T },
+): BaseRenderNodeOptions => {
+ const defaultOptions: BaseRenderNodeOptions = {
+ title: {
+ name: '', // 节点标题
+ color: '#FFFFFF', // 节点标题颜色
+ bgColor: '#3CB371', // 节点标题背景颜色
+ },
+ icon: {
+ name: '', // 节点图标
+ color: '#3CB371', // 节点图标颜色
+ },
+ operateNode: {
+ add: true, // 节点是否可以追加
+ sort: 1, // 节点排序,用于排序节点的显示优先级,主要用于配置节点的操作
+ addBranch: false, // 节点是否可以添加分支
+ edit: true, // 节点是否可以编辑
+ remove: true, // 节点是否可以删除
+ onSupportNode: [], // 节点不支持添加的节点类型
+ },
+ isHasDrawer: false, // 节点是否可以进行配置
+ defaultNode: {} as T,
+ }
+ return deepMerge(defaultOptions, options) as BaseRenderNodeOptions
+}
+
+// ------------------------------ 基础节点配置 ------------------------------
+
+// // 结束节点
+// nodeOptions[END] = baseOptions({
+// title: { name: '结束' },
+// icon: { name: END },
+// addNode: false,
+// removedNode: false,
+// hasDrawer: false,
+// hiddenNode: true,
+// })
+
+// // 默认节点
+// nodeOptions[DEFAULT] = baseOptions({
+// title: { name: '默认' },
+// icon: { name: DEFAULT },
+// addNode: true,
+// hasDrawer: true,
+// defaultNode: {
+// name: '默认',
+// type: DEFAULT,
+// config: {},
+// childNode: null,
+// },
+// })
+
+// ------------------------------ 执行业务节点配置 ------------------------------
+
+// 开始节点
+nodeOptions[START] = () =>
+ baseOptions({
+ title: { name: '开始' },
+ operateNode: { onSupportNode: [EXECUTE_RESULT_BRANCH], remove: false, edit: false, add: false },
+ defaultNode: {
+ id: uuidv4(),
+ name: '开始',
+ type: START,
+ config: {
+ exec_type: 'manual',
+ },
+ childNode: null,
+ },
+ })
+
+// 申请节点
+nodeOptions[APPLY] = () =>
+ baseOptions({
+ title: { name: '申请' },
+ icon: { name: APPLY },
+ operateNode: { sort: 1 },
+ defaultNode: {
+ id: uuidv4(),
+ name: '申请',
+ type: APPLY,
+ config: {
+ domains: '',
+ email: '',
+ provider: '',
+ provider_id: '',
+ end_day: 30,
+ },
+ childNode: null,
+ },
+ })
+
+// 上传节点
+nodeOptions[UPLOAD] = () =>
+ baseOptions({
+ title: { name: '上传' },
+ icon: { name: UPLOAD },
+ operateNode: { sort: 2, onSupportNode: [EXECUTE_RESULT_BRANCH] },
+ defaultNode: {
+ id: uuidv4(),
+ name: '上传',
+ type: UPLOAD,
+ config: {
+ cert: '',
+ key: '',
+ },
+ childNode: null,
+ },
+ })
+
+// 部署节点
+nodeOptions[DEPLOY] = () =>
+ baseOptions({
+ title: { name: '部署' },
+ icon: { name: DEPLOY },
+ operateNode: { sort: 3 },
+ defaultNode: {
+ id: uuidv4(),
+ name: '部署',
+ type: DEPLOY,
+ inputs: [],
+ config: {
+ provider: '',
+ provider_id: '',
+ },
+ childNode: null,
+ },
+ })
+
+// 通知节点
+nodeOptions[NOTIFY] = () =>
+ baseOptions({
+ title: { name: '通知' },
+ icon: { name: NOTIFY },
+ operateNode: { sort: 4 },
+ defaultNode: {
+ id: uuidv4(),
+ name: '通知',
+ type: NOTIFY,
+ config: {
+ provider: '',
+ provider_id: '',
+ subject: '',
+ body: '',
+ },
+ childNode: null,
+ },
+ })
+
+// 分支节点
+nodeOptions[BRANCH] = () =>
+ baseOptions({
+ title: { name: '并行分支' },
+ icon: { name: BRANCH },
+ operateNode: { sort: 5, addBranch: true },
+ defaultNode: {
+ id: uuidv4(),
+ name: '并行分支',
+ type: BRANCH,
+ conditionNodes: [
+ {
+ id: uuidv4(),
+ name: '分支1',
+ type: CONDITION,
+ config: {},
+ childNode: null,
+ },
+ {
+ id: uuidv4(),
+ name: '分支2',
+ type: CONDITION,
+ config: {},
+ childNode: null,
+ },
+ ],
+ },
+ })
+
+// 条件节点
+nodeOptions[CONDITION] = () =>
+ baseOptions({
+ title: { name: '分支1' },
+ icon: { name: CONDITION },
+ operateNode: { add: false, onSupportNode: [EXECUTE_RESULT_BRANCH] },
+ defaultNode: {
+ id: uuidv4(),
+ name: '分支1',
+ type: CONDITION,
+ icon: { name: CONDITION },
+ config: {},
+ childNode: null,
+ },
+ })
+
+// 执行结构分支
+nodeOptions[EXECUTE_RESULT_BRANCH] = () =>
+ baseOptions({
+ title: { name: '执行结果分支' },
+ icon: { name: BRANCH },
+ operateNode: { sort: 7, onSupportNode: [EXECUTE_RESULT_BRANCH] },
+ defaultNode: {
+ id: uuidv4(),
+ name: '执行结果分支',
+ type: EXECUTE_RESULT_BRANCH,
+ conditionNodes: [
+ {
+ id: uuidv4(),
+ name: '若当前节点执行成功…',
+ type: EXECUTE_RESULT_CONDITION,
+ icon: { name: 'success' },
+ config: { type: 'success' },
+ childNode: null,
+ },
+ {
+ id: uuidv4(),
+ name: '若当前节点执行失败…',
+ type: EXECUTE_RESULT_CONDITION,
+ icon: { name: 'error' },
+ config: { type: 'fail' },
+ childNode: null,
+ },
+ ],
+ },
+ })
+
+// 执行结构条件
+nodeOptions[EXECUTE_RESULT_CONDITION] = () =>
+ baseOptions({
+ title: { name: '执行结构条件' },
+ icon: { name: BRANCH },
+ operateNode: { add: false, onSupportNode: [EXECUTE_RESULT_BRANCH] },
+ defaultNode: {
+ id: uuidv4(),
+ name: '若前序节点执行失败…',
+ type: EXECUTE_RESULT_CONDITION,
+ icon: { name: 'SUCCESS' },
+ config: { type: 'SUCCESS' },
+ childNode: null,
+ },
+ })
+
+export default nodeOptions
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/lib/verify.tsx b/frontend/apps/allin-ssl/src/components/flowChart/lib/verify.tsx
new file mode 100644
index 0000000..6c77bcf
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/lib/verify.tsx
@@ -0,0 +1,411 @@
+import { ref, onUnmounted } from 'vue'
+import { ValidatorResult, ValidatorFunction, RuleItem, ValidatorDescriptor } from '../types'
+
+/**
+ * 验证器类
+ * 用于管理所有节点的验证函数和验证结果
+ */
+class Validator {
+ // 存储所有节点的验证函数
+ private validators: Map = new Map()
+ // 存储所有节点的验证结果
+ private validationResults: Map = new Map()
+ // 存储所有节点的数据
+ private valuesMap: Map = new Map()
+ // 存储节点规则验证状态
+ public rulesMap: Map = new Map()
+
+ /**
+ * 注册验证器
+ * @param nodeId - 节点ID
+ * @param validator - 验证函数
+ */
+ register(nodeId: string, validator: ValidatorFunction) {
+ this.validators.set(nodeId, validator)
+ this.validate(nodeId)
+ }
+
+ /**
+ * 注销验证器
+ * @param nodeId - 节点ID
+ */
+ unregister(nodeId: string) {
+ this.validators.delete(nodeId)
+ this.validationResults.delete(nodeId)
+ this.valuesMap.delete(nodeId)
+ }
+
+ unregisterAll() {
+ this.validators.clear()
+ this.validationResults.clear()
+ this.valuesMap.clear()
+ }
+
+ /**
+ * 注册兼容async-validator的规则
+ * @param nodeId - 节点ID
+ * @param descriptor - 验证规则描述符
+ * @param initialValues - 初始值
+ */
+ registerCompatValidator(nodeId: string, descriptor: ValidatorDescriptor, initialValues?: Record) {
+ if (initialValues) {
+ this.valuesMap.set(nodeId, { ...initialValues })
+ } else {
+ this.valuesMap.set(nodeId, {})
+ }
+
+ const validator = () => {
+ return this.validateWithRules(nodeId, descriptor)
+ }
+ this.validators.set(nodeId, validator)
+ }
+
+ /**
+ * 设置节点的值
+ * @param nodeId - 节点ID
+ * @param key - 属性名
+ * @param value - 属性值
+ */
+ setValue(nodeId: string, key: string, value: any) {
+ const values = this.valuesMap.get(nodeId) || {}
+ values[key] = value
+ this.valuesMap.set(nodeId, values)
+ }
+
+ /**
+ * 批量设置节点的值
+ * @param nodeId - 节点ID
+ * @param values - 属性值集合
+ */
+ setValues(nodeId: string, values: Record) {
+ const currentValues = this.valuesMap.get(nodeId) || {}
+ this.valuesMap.set(nodeId, { ...currentValues, ...values })
+ }
+
+ /**
+ * 获取节点的值
+ * @param nodeId - 节点ID
+ * @param key - 属性名
+ */
+ getValue(nodeId: string, key: string) {
+ const values = this.valuesMap.get(nodeId) || {}
+ return values[key]
+ }
+
+ /**
+ * 获取节点的所有值
+ * @param nodeId - 节点ID
+ */
+ getValues(nodeId: string) {
+ return this.valuesMap.get(nodeId) || {}
+ }
+
+ /**
+ * 使用兼容async-validator的规则验证数据
+ * @param nodeId - 节点ID
+ * @param descriptor - 验证规则描述符
+ * @returns 验证结果
+ */
+ validateWithRules(nodeId: string, descriptor: ValidatorDescriptor): ValidatorResult {
+ const values = this.valuesMap.get(nodeId) || {}
+ for (const field in descriptor) {
+ const rules = Array.isArray(descriptor[field])
+ ? (descriptor[field] as RuleItem[])
+ : [descriptor[field] as RuleItem]
+ const value = values[field]
+ if (field in values) {
+ for (const rule of rules) {
+ // 检查必填
+ if (rule.required && (value === undefined || value === null || value === '')) {
+ const message = rule.message || `${field}是必填项`
+ return { valid: false, message }
+ }
+
+ // 如果值为空但不是必填,则跳过其他验证
+ if ((value === undefined || value === null || value === '') && !rule.required) {
+ continue
+ }
+
+ // 检查类型
+ if (rule.type && !this.validateType(rule.type, value)) {
+ const message = rule.message || `${field}的类型应为${rule.type}`
+ return { valid: false, message }
+ }
+
+ // 检查格式
+ if (rule.pattern && !rule.pattern.test(String(value))) {
+ const message = rule.message || `${field}格式不正确`
+ return { valid: false, message }
+ }
+
+ // 检查长度范围
+ if (rule.type === 'string' || rule.type === 'array') {
+ const length = value.length || 0
+
+ if (rule.len !== undefined && length !== rule.len) {
+ const message = rule.message || `${field}的长度应为${rule.len}`
+ return { valid: false, message }
+ }
+
+ if (rule.min !== undefined && length < rule.min) {
+ const message = rule.message || `${field}的长度不应小于${rule.min}`
+ return { valid: false, message }
+ }
+
+ if (rule.max !== undefined && length > rule.max) {
+ const message = rule.message || `${field}的长度不应大于${rule.max}`
+ return { valid: false, message }
+ }
+ }
+
+ // 检查数值范围
+ if (rule.type === 'number') {
+ if (rule.len !== undefined && value !== rule.len) {
+ const message = rule.message || `${field}应等于${rule.len}`
+ return { valid: false, message }
+ }
+
+ if (rule.min !== undefined && value < rule.min) {
+ const message = rule.message || `${field}不应小于${rule.min}`
+ return { valid: false, message }
+ }
+
+ if (rule.max !== undefined && value > rule.max) {
+ const message = rule.message || `${field}不应大于${rule.max}`
+ return { valid: false, message }
+ }
+ }
+
+ // 检查枚举值
+ if (rule.enum && !rule.enum.includes(value)) {
+ const message = rule.message || `${field}的值不在允许范围内`
+ return { valid: false, message }
+ }
+
+ // 检查空白字符
+ if (rule.whitespace && rule.type === 'string' && !value.trim()) {
+ const message = rule.message || `${field}不能只包含空白字符`
+ return { valid: false, message }
+ }
+
+ // 自定义验证器
+ if (rule.validator) {
+ try {
+ const result = rule.validator(rule, value, undefined)
+
+ if (result === false) {
+ const message = rule.message || `${field}验证失败`
+ return { valid: false, message }
+ }
+
+ if (result instanceof Error) {
+ return { valid: false, message: result.message }
+ }
+
+ if (Array.isArray(result) && result.length > 0 && result[0] instanceof Error) {
+ return { valid: false, message: result[0].message }
+ }
+ } catch (error) {
+ return { valid: false, message: error instanceof Error ? error.message : `${field}验证出错` }
+ }
+ }
+ }
+ }
+ }
+ return { valid: true, message: '' }
+ }
+
+ /**
+ * 验证值的类型
+ * @param type - 类型
+ * @param value - 值
+ * @returns 是否通过验证
+ */
+ private validateType(type: string, value: any): boolean {
+ switch (type) {
+ case 'string':
+ return typeof value === 'string'
+ case 'number':
+ return typeof value === 'number' && !isNaN(value)
+ case 'boolean':
+ return typeof value === 'boolean'
+ case 'method':
+ return typeof value === 'function'
+ case 'regexp':
+ return value instanceof RegExp
+ case 'integer':
+ return typeof value === 'number' && Number.isInteger(value)
+ case 'float':
+ return typeof value === 'number' && !Number.isInteger(value)
+ case 'array':
+ return Array.isArray(value)
+ case 'object':
+ return typeof value === 'object' && !Array.isArray(value) && value !== null
+ case 'enum':
+ return true // 枚举类型在单独的规则中验证
+ case 'date':
+ return value instanceof Date
+ case 'url':
+ try {
+ new URL(value)
+ return true
+ } catch (e) {
+ return false
+ }
+ case 'email':
+ return /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(value)
+ default:
+ return true
+ }
+ }
+
+ /**
+ * 验证指定节点
+ * @param nodeId - 节点ID
+ * @returns ValidatorResult - 验证结果
+ */
+ validate(nodeId: string) {
+ const validator = this.validators.get(nodeId)
+ if (validator) {
+ const result = validator()
+ this.validationResults.set(nodeId, result)
+ return result
+ }
+ return { valid: false, message: '' }
+ }
+
+ /**
+ * 验证所有已注册的节点
+ * @returns 包含所有节点验证结果的对象
+ */
+ validateAll() {
+ let allValid = true
+ const results: Record = {}
+ this.validators.forEach((validator, nodeId) => {
+ const result = this.validate(nodeId)
+ results[nodeId] = result
+ if (!result.valid) {
+ allValid = false
+ }
+ })
+ return {
+ valid: allValid,
+ results,
+ }
+ }
+
+ /**
+ * 获取指定节点的验证结果
+ * @param nodeId - 节点ID
+ * @returns ValidatorResult - 验证结果
+ */
+ getValidationResult(nodeId: string): ValidatorResult {
+ return this.validationResults.get(nodeId) || { valid: true, message: '' }
+ }
+}
+
+// 创建全局验证器实例
+const validator = new Validator()
+
+/**
+ * 节点验证器 Hook
+ * 提供节点验证相关的功能
+ * @returns 包含验证相关方法和状态的对象
+ */
+export function useNodeValidator() {
+ // 响应式的验证结果
+ const validationResult = ref({ valid: false, message: '' })
+
+ /**
+ * 注册验证器函数
+ * @param nodeId - 节点ID
+ * @param validateFn - 验证函数
+ */
+ const registerValidator = (nodeId: string, validateFn: ValidatorFunction) => {
+ validator.register(nodeId, validateFn)
+ validationResult.value = validator.getValidationResult(nodeId)
+ }
+
+ /**
+ * 注册兼容async-validator的规则
+ * @param nodeId - 节点ID
+ * @param descriptor - 验证规则描述符
+ * @param initialValues - 初始值
+ */
+ const registerCompatValidator = (
+ nodeId: string,
+ descriptor: ValidatorDescriptor,
+ initialValues?: Record,
+ ) => {
+ validator.registerCompatValidator(nodeId, descriptor, initialValues)
+ validationResult.value = validator.getValidationResult(nodeId)
+ }
+
+ /**
+ * 设置字段值
+ * @param nodeId - 节点ID
+ * @param key - 字段名
+ * @param value - 字段值
+ */
+ const setFieldValue = (nodeId: string, key: string, value: any) => {
+ validator.setValue(nodeId, key, value)
+ }
+
+ /**
+ * 批量设置字段值
+ * @param nodeId - 节点ID
+ * @param values - 字段值集合
+ */
+ const setFieldValues = (nodeId: string, values: Record) => {
+ validator.setValues(nodeId, values)
+ }
+
+ /**
+ * 获取字段值
+ * @param nodeId - 节点ID
+ * @param key - 字段名
+ */
+ const getFieldValue = (nodeId: string, key: string) => {
+ return validator.getValue(nodeId, key)
+ }
+
+ /**
+ * 获取所有字段值
+ * @param nodeId - 节点ID
+ */
+ const getFieldValues = (nodeId: string) => {
+ return validator.getValues(nodeId)
+ }
+
+ /**
+ * 执行验证
+ * @param nodeId - 节点ID
+ * @returns ValidatorResult - 验证结果
+ */
+ const validate = (nodeId: string) => {
+ const result = validator.validate(nodeId)
+ validationResult.value = result
+ return result
+ }
+
+ /**
+ * 注销验证器
+ * @param nodeId - 节点ID
+ */
+ const unregisterValidator = (nodeId: string) => {
+ validator.unregister(nodeId)
+ }
+
+ return {
+ validationResult, // 验证结果(响应式)
+ registerValidator, // 注册验证器方法
+ registerCompatValidator, // 注册兼容async-validator的规则
+ setFieldValue, // 设置字段值
+ setFieldValues, // 批量设置字段值
+ getFieldValue, // 获取字段值
+ getFieldValues, // 获取所有字段值
+ validate, // 执行验证方法
+ unregisterValidator, // 注销验证器方法
+ validator, // 验证器实例
+ }
+}
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/mock/index.ts b/frontend/apps/allin-ssl/src/components/flowChart/mock/index.ts
new file mode 100644
index 0000000..f8cf4d9
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/mock/index.ts
@@ -0,0 +1,77 @@
+export default {
+ name: '',
+ childNode: {
+ id: 'start-1',
+ name: '开始',
+ type: 'start',
+ config: {
+ exec_type: 'auto',
+ type: 'day',
+ hour: 1,
+ minute: 0,
+ },
+ childNode: {
+ id: 'apply-1',
+ name: '申请证书',
+ type: 'apply',
+ config: {
+ domains: '',
+ email: '',
+ provider_id: '',
+ provider: '',
+ end_day: 30,
+ },
+ childNode: {
+ id: 'deploy-1',
+ name: '部署',
+ type: 'deploy',
+ inputs: {},
+ config: {
+ provider: '',
+ provider_id: '',
+ inputs: {
+ fromNodeId: '',
+ name: '',
+ },
+ },
+ childNode: {
+ id: 'execute',
+ name: '执行结果',
+ type: 'execute_result_branch',
+ config: { fromNodeId: 'deploy-1' },
+ conditionNodes: [
+ {
+ id: 'execute-success',
+ name: '执行成功',
+ type: 'execute_result_condition',
+ config: {
+ fromNodeId: '',
+ type: 'success',
+ },
+ },
+ {
+ id: 'execute-failure',
+ name: '执行失败',
+ type: 'execute_result_condition',
+ config: {
+ fromNodeId: '',
+ type: 'fail',
+ },
+ },
+ ],
+ childNode: {
+ id: 'notify-1',
+ name: '通知任务',
+ type: 'notify',
+ config: {
+ provider: '',
+ provider_id: '',
+ subject: '',
+ body: '',
+ },
+ },
+ },
+ },
+ },
+ },
+}
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/types.d.ts b/frontend/apps/allin-ssl/src/components/flowChart/types.d.ts
new file mode 100644
index 0000000..1070a51
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/types.d.ts
@@ -0,0 +1,316 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
+import {
+ APPLY,
+ BRANCH,
+ CONDITION,
+ DEPLOY,
+ END,
+ EXECUTE_RESULT_BRANCH,
+ EXECUTE_RESULT_CONDITION,
+ NOTIFY,
+ START,
+ UPLOAD,
+ DEFAULT,
+} from './lib/alias'
+import type { FormRules } from 'naive-ui'
+
+// 拖拽效果
+export interface FlowNodeProps {
+ isEdit: boolean
+ type: 'quick' | 'advanced'
+ node: FlowNode
+}
+
+
+export interface FlowNode {
+ id: string
+ name: string
+ childNode: BaseNodeData
+}
+
+// 添加节点选项
+export interface NodeSelect {
+ title: NodeTitle
+ type: NodeNum
+ icon: NodeIcon
+ selected: boolean
+}
+
+// 节点标题配置
+export interface NodeTitle {
+ name: string
+ color?: string
+ bgColor?: string
+}
+
+// 节点图标配置
+export interface NodeIcon {
+ name: string
+ color?: string
+}
+
+// 操作节点配置,用于渲染节点的操作功能
+export interface operateNodeOptions {
+ add?: boolean // 是否显示添加节点
+ sort?: number // 节点排序,用于排序节点的显示优先级,主要用于配置节点的操作
+ addBranch?: boolean // 是否显示添加分支节点,仅在节点类型为分支节点时有效
+ addBranchTitle?: string // 添加分支节点标题,仅在节点类型为分支节点时有效
+ edit?: boolean // 是否可编辑
+ remove?: boolean // 是否可删除
+ onSupportNode?: NodeNum[] // 不支持添加的节点类型
+}
+
+// 基础节点渲染配置,用于渲染节点
+export interface BaseRenderNodeOptions {
+ title: NodeTitle // 节点标题
+ icon?: NodeIcon // 节点图标
+ isAddNode?: boolean // 是否显示添加节点
+ isHasDrawer?: boolean // 是否显示抽屉
+ operateNode?: operateNodeOptions // 是否显示操作节点
+ defaultNode?: T // 默认节点数据 -- 节点数据,用于组合相应结构
+}
+
+// 基础节点数据
+export interface BaseNodeData> {
+ type: NodeNum // 节点类型
+ id?: string // 节点id,用于编辑
+ name: string // 节点名称
+ icon?: NodeIcon // 节点图标
+ inputs?: Record[] // 输入,用于连接其他节点的数据
+ config?: T // 参数,用于配置当前的节点
+ childNode?: BaseNodeData | BranchNodeData | null // 子节点
+}
+
+// 分支节点数据
+export interface BranchNodeData = Record> extends BaseNodeData {
+ type: typeof BRANCH // 节点类型
+ conditionNodes: ConditionNodeData[] // 子节点
+}
+
+// 执行条件分支节点数据
+export interface ExecuteResultBranchNodeData extends BaseNodeData {
+ type: typeof EXECUTE_RESULT_BRANCH // 节点类型
+ conditionNodes: ExecuteResultConditionNodeData[] // 子节点
+}
+
+// 执行结果条件节点数据
+interface ExecuteResultCondition {
+ type: 'success' | 'fail'
+ [key: string]: unknown
+}
+
+// 条件节点数据
+export interface ExecuteResultConditionNodeData extends BaseNodeData {
+ type: typeof EXECUTE_RESULT_CONDITION // 节点类型
+ config: ExecuteResultCondition
+}
+
+// 节点类型
+export type NodeNum =
+ | typeof START // 开始节点
+ | typeof DEFAULT // 默认节点
+ | typeof END // 结束节点
+ | typeof BRANCH // 分支节点
+ | typeof CONDITION // 条件节点
+ | typeof EXECUTE_RESULT_BRANCH // 执行结果分支节点(if)
+ | typeof EXECUTE_RESULT_CONDITION // 执行结果条件节点
+ | typeof UPLOAD // 上传节点(业务)
+ | typeof NOTIFY // 通知节点(业务)
+ | typeof APPLY // 申请节点(业务)
+ | typeof DEPLOY // 部署节点(业务)
+
+// 节点配置映射
+export type NodeOptions = {
+ [START]: () => BaseRenderNodeOptions
+ [END]: () => BaseRenderNodeOptions
+ [DEFAULT]: () => BaseRenderNodeOptions
+ [BRANCH]: () => BaseRenderNodeOptions
+ [CONDITION]: () => BaseRenderNodeOptions
+ [EXECUTE_RESULT_BRANCH]: () => BaseRenderNodeOptions
+ [EXECUTE_RESULT_CONDITION]: () => BaseRenderNodeOptions
+ [UPLOAD]: () => BaseRenderNodeOptions
+ [NOTIFY]: () => BaseRenderNodeOptions
+ [APPLY]: () => BaseRenderNodeOptions
+ [DEPLOY]: () => BaseRenderNodeOptions
+}
+
+// 基础节点配置
+interface BaseNodeProps {
+ node: BaseNodeData>
+}
+
+/**
+ * 验证结果接口
+ * @property valid - 验证是否通过
+ * @property message - 验证失败时的提示信息
+ */
+export interface ValidatorResult {
+ valid: boolean
+ message: string
+}
+
+/**
+ * 验证函数类型定义
+ * @returns ValidatorResult - 返回验证结果对象
+ */
+export type ValidatorFunction = () => ValidatorResult
+
+/**
+ * 兼容async-validator的类型定义
+ */
+export interface RuleItem {
+ type?: string
+ required?: boolean
+ pattern?: RegExp
+ min?: number
+ max?: number
+ len?: number
+ enum?: Array
+ whitespace?: boolean
+ message?: string
+ validator?: (
+ rule: RuleItem,
+ value: any,
+ callback?: (error?: Error) => void,
+ ) => boolean | Error | Error[] | Promise
+ asyncValidator?: (rule: RuleItem, value: any, callback?: (error?: Error) => void) => Promise
+ transform?: (value: any) => any
+ [key: string]: any
+}
+
+/**
+ * 兼容async-validator的描述符类型
+ */
+export type ValidatorDescriptor = FormRules
+
+// 定义组件接收的参数类型(开始节点)
+export interface StartNodeConfig {
+ // 执行模式:auto-自动,manual-手动
+ exec_type: 'auto' | 'manual'
+ // 执行周期类型
+ type?: 'month' | 'day' | 'week'
+ month?: number
+ week?: number
+ hour?: number
+ minute?: number
+}
+
+// 定义组件接收的参数类型(申请节点)
+export interface ApplyNodeConfig {
+ // 基本选项
+ domains: string // 域名
+ email: string // 邮箱
+ provider_id: string // DNS提供商授权ID
+ provider: string // DNS提供商
+ end_day: number // 续签间隔
+ // 高级功能
+ // algorithm: 'RSA2048' | 'RSA3072' | 'RSA4096' | 'RSA8192' | 'EC256' | 'EC384' // 数字证书算法
+ // dnsServer?: string // 指定DNS解析服务器
+ // dnsTimeout?: number // DNS超时时间
+ // dnsTtl?: number // DNS解析TTL时间
+ // disableCnameFollow: boolean // 关闭CNAME跟随
+ // disableAutoRenew: boolean // 关闭ARI续期
+ // renewInterval?: number // 续签间隔
+}
+
+// 部署节点配置
+export interface DeployConfig<
+ Z extends Record,
+ T extends
+ | 'ssh'
+ | 'btpanel'
+ | '1panel'
+ | 'btpanel-site'
+ | '1panel-site'
+ | 'tencentcloud-cdn'
+ | 'tencentcloud-cos'
+ | 'aliyun-cdn'
+ | 'aliyun-oss',
+> {
+ provider: T
+ provider_id: string
+ [key: string]: Z
+}
+
+export interface DeployPanelConfig {
+}
+
+// 部署节点配置(ssh)
+export interface DeploySSHConfig {
+ certPath: string // 证书文件路径
+ keyPath: string // 私钥文件路径
+ beforeCmd: string // 前置命令
+ afterCmd?: string // 后置命令
+}
+
+// 部署节点配置(宝塔面板)
+export interface DeployBTPanelConfig {
+ siteName: string
+}
+
+// 部署节点配置(1Panel)
+export interface Deploy1PanelConfig {
+ site_id: string
+}
+
+// 部署腾讯云CDN/阿里云CDN
+export interface DeployCDNConfig {
+ domain: string
+}
+
+// 部署腾讯云COS/阿里云OSS
+export interface DeployStorageConfig {
+ domain: string
+ region: string
+ bucket: string
+}
+
+
+// 部署节点配置
+export type DeployNodeConfig = DeployConfig<
+ DeploySSHConfig | DeployBTPanelConfig | Deploy1PanelConfig | DeployCDNConfig | DeployStorageConfig
+>
+
+
+// 部署节点输入配置
+export interface DeployNodeInputsConfig {
+ name: string
+ fromNodeId: string
+}
+
+
+
+// 定义通知节点配置类型
+interface NotifyNodeConfig {
+ provider: string
+ provider_id: string
+ subject: string
+ body: string
+}
+
+
+
+// 定义上传节点配置类型
+interface UploadNodeConfig {
+ cert: string
+ key: string
+}
+
+
+
+
+
+// 部署节点配置(ssh)
+// export type DeployNodeConfigSSH = DeployNodeConfig<'ssh', DeploySSHConfig>
+
+
+
+// 部署节点配置(宝塔面板)
+// export type DeployNodeConfigBTPanel = DeployNodeConfig<'btpanel', DeployBTPanelConfig>
+
+
+
+
+
+
+
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/useController.tsx b/frontend/apps/allin-ssl/src/components/flowChart/useController.tsx
new file mode 100644
index 0000000..f7003ec
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/useController.tsx
@@ -0,0 +1,282 @@
+import { v4 as uuidv4 } from 'uuid'
+import { useModal, useMessage } from '@baota/naive-ui/hooks'
+import { $t } from '@locales/index'
+import { useStore } from '@components/flowChart/useStore'
+import { useStore as useWorkflowViewStore } from '@autoDeploy/children/workflowView/useStore'
+import { CONDITION, EXECUTE_RESULT_CONDITION } from '@components/flowChart/lib/alias'
+import FlowChart from '@components/flowChart/components/other/drawer'
+
+import { useNodeValidator } from '@components/flowChart/lib/verify'
+import { useError } from '@baota/hooks/error'
+
+import type { BaseNodeData, BranchNodeData, FlowNodeProps, NodeNum, StartNodeConfig } from '@components/flowChart/types'
+
+const message = useMessage()
+const {
+ flowData,
+ selectedNodeId,
+ setflowZoom,
+ initFlowData,
+ updateFlowData,
+ setShowAddNodeSelect,
+ addNode,
+ getAddNodeSelect,
+ resetFlowData,
+} = useStore()
+
+const { workflowData, addNewWorkflow, updateWorkflowData, resetWorkflowData } = useWorkflowViewStore()
+const { handleError } = useError()
+/**
+ * 流程图控制器
+ * 用于处理流程图的业务逻辑和用户交互
+ * @param {FlowNodeProps} props - 节点数据,可选
+ */
+export const useController = (props: FlowNodeProps = { type: 'quick', node: flowData.value, isEdit: false }) => {
+ // 使用store获取所有需要的方法和状态
+ const router = useRouter()
+ const route = useRoute()
+ /**
+ * 当前选中的节点数据
+ * @type {ComputedRef}
+ */
+ const selectedNode = computed(() => {
+ if (!selectedNodeId.value) return null
+ // 使用findNodeRecursive查找节点
+ return findNodeRecursive(flowData.value.childNode, selectedNodeId.value)
+ })
+
+ /**
+ * 节点标题
+ * @type {ComputedRef}
+ */
+ const nodeTitle = computed(() => {
+ if (!selectedNode.value) return $t('t_6_1744861190121')
+ return selectedNode.value.name
+ })
+
+ /**
+ * 递归查找节点
+ * @param {BaseNodeData | BranchNodeData} node - 当前节点
+ * @param {string} targetId - 目标节点ID
+ * @returns {BaseNodeData | null} 找到的节点或null
+ */
+ const findNodeRecursive = (node: BaseNodeData | BranchNodeData, targetId: string): BaseNodeData | null => {
+ if (node.id === targetId) return node as BaseNodeData
+
+ // 优先检查子节点
+ if (node.childNode) {
+ const found = findNodeRecursive(node.childNode, targetId)
+ if (found) return found
+ }
+
+ // 检查条件节点
+ if ((node as BranchNodeData).conditionNodes?.length) {
+ for (const conditionNode of (node as BranchNodeData).conditionNodes) {
+ const found = findNodeRecursive(conditionNode, targetId)
+ if (found) return found
+ }
+ }
+ return null
+ }
+
+ /**
+ * 选择节点
+ * @param {string} nodeId 节点ID
+ * @param {NodeNum} nodeType 节点类型
+ */
+ const handleSelectNode = (nodeId: string, nodeType: NodeNum) => {
+ if (nodeType === CONDITION || nodeType === EXECUTE_RESULT_CONDITION) {
+ selectedNodeId.value = ''
+ } else {
+ selectedNodeId.value = nodeId
+ useModal({
+ title: `${selectedNode.value?.name}${$t('t_1_1745490731990')}`,
+ area: '60rem',
+ component: () => ,
+ confirmText: $t('t_2_1744861190040'),
+ footer: true,
+ })
+ }
+ }
+
+ /**
+ * 保存节点配置
+ * 将当前选中节点的配置保存到流程图中
+ */
+ const handleSaveConfig = () => {
+ const { validator } = useNodeValidator()
+ const res = validator.validateAll()
+ try {
+ if (res.valid && flowData.value.name) {
+ const { active } = workflowData.value
+ const { id, name, childNode } = flowData.value
+ const { exec_type, ...exec_time } = childNode.config as unknown as StartNodeConfig
+ const param = {
+ name,
+ active,
+ content: JSON.stringify(childNode),
+ exec_type,
+ exec_time: JSON.stringify(exec_time || {}),
+ }
+ if (route.query.isEdit) {
+ updateWorkflowData({ id, ...param })
+ } else {
+ addNewWorkflow(param)
+ }
+ router.push('/auto-deploy')
+ } else if (!flowData.value.name) {
+ message.error('保存失败,请输入工作流名称')
+ }
+ for (const key in res.results) {
+ if (res.results.hasOwnProperty(key)) {
+ const result = res.results[key] as { valid: boolean; message: string }
+ if (!result.valid) {
+ message.error(result.message)
+ break
+ }
+ }
+ }
+ } catch (error) {
+ handleError(error).default($t('t_12_1745457489076'))
+ }
+ }
+
+ /**
+ * 运行流程图
+ * 触发流程图的执行
+ */
+ const handleRun = () => {
+ message.info($t('t_8_1744861189821'))
+ // 这里可以添加实际的运行逻辑
+ }
+
+ /**
+ * 流程图缩放控制
+ * @param {number} type - 缩放类型 1:缩小,2:放大
+ */
+ const handleZoom = (type: number) => {
+ setflowZoom(type)
+ }
+
+ /**
+ * 返回上一级
+ */
+ const goBack = () => {
+ router.back()
+ }
+
+ /**
+ * 初始化流程图数据
+ */
+ const initData = () => {
+ console.log(props.node, 'init')
+ resetFlowData()
+ resetWorkflowData()
+ // 如果传入了节点数据,使用传入的数据
+ if (props.isEdit && props.node) {
+ console.log(props.node, 'edit')
+ updateFlowData(props.node)
+ } else if (props.type === 'quick') {
+ initFlowData() // 否则使用默认数据初始化
+ } else if (props.type === 'advanced') {
+ updateFlowData(props.node)
+ }
+ }
+
+ // 如果传入了node,则当node变化时更新store中的flowData
+ if (props.node) {
+ watch(
+ () => props.node,
+ (newVal) => {
+ updateFlowData(newVal)
+ },
+ { deep: true },
+ )
+ }
+
+ return {
+ flowData,
+ selectedNodeId,
+ selectedNode,
+ nodeTitle,
+ handleSaveConfig,
+ handleSelectNode,
+ handleZoom,
+ handleRun,
+ goBack,
+ initData,
+ }
+}
+
+/**
+ * 添加节点控制器
+ * 用于处理添加节点的业务逻辑
+ */
+export function useAddNodeController() {
+ // 使用store获取所有需要的方法和状态
+ const store = useStore()
+
+ /**
+ * 是否显示添加节点选择框
+ * @type {Ref}
+ */
+ const isShowAddNodeSelect = ref(false)
+
+ /**
+ * 定时器
+ * @type {Ref}
+ */
+ const timer = ref(null)
+
+ /**
+ * 显示节点选择
+ * @param {boolean} flag - 是否显示
+ * @param {NodeNum} [nodeType] - 节点类型
+ */
+ const showNodeSelect = (flag: boolean, nodeType?: NodeNum) => {
+ if (!flag) {
+ clearTimeout(timer.value as number)
+ timer.value = window.setTimeout(() => {
+ isShowAddNodeSelect.value = flag
+ }, 200) as unknown as number
+ } else {
+ isShowAddNodeSelect.value = false
+ isShowAddNodeSelect.value = flag
+ }
+ // 设置添加节点选择状态
+ if (nodeType) {
+ setShowAddNodeSelect(flag, nodeType)
+ }
+ }
+
+ /**
+ * 添加节点数据
+ * @param {BaseNodeData} parentNode - 父节点
+ * @param {NodeNum} type - 生成节点类型
+ */
+ const addNodeData = (parentNode: BaseNodeData, type: NodeNum) => {
+ console.log(parentNode, type)
+ // 设置添加节点选择状态
+ isShowAddNodeSelect.value = false
+ // 判断是否存储节点配置数据
+ if (parentNode.id) addNode(parentNode.id, type, { id: uuidv4() })
+ }
+
+ /**
+ * 添加节点选中状态
+ */
+ const itemNodeSelected = () => {
+ clearTimeout(timer.value as number)
+ }
+
+ // 获取添加节点选择
+ getAddNodeSelect()
+
+ return {
+ ...store,
+ addNodeData,
+ itemNodeSelected,
+ isShowAddNodeSelect,
+ showNodeSelect,
+ }
+}
diff --git a/frontend/apps/allin-ssl/src/components/flowChart/useStore.tsx b/frontend/apps/allin-ssl/src/components/flowChart/useStore.tsx
new file mode 100644
index 0000000..6e2b160
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/flowChart/useStore.tsx
@@ -0,0 +1,579 @@
+import { formatDate } from '@baota/utils/date'
+import { deepMerge } from '@baota/utils/data'
+import nodeOptions from '@components/flowChart/lib/config'
+import MockData from '@components/flowChart/mock'
+import type {
+ NodeIcon,
+ NodeNum,
+ NodeTitle,
+ FlowNode,
+ BaseNodeData,
+ NodeSelect,
+ BranchNodeData,
+ ExecuteResultBranchNodeData,
+} from '@components/flowChart/types'
+import { BRANCH, CONDITION, EXECUTE_RESULT_BRANCH, EXECUTE_RESULT_CONDITION } from './lib/alias'
+
+/**
+ * 流程图数据存储
+ * 用于管理流程图的状态、缩放等数据
+ */
+export const useFlowStore = defineStore('flow-store', () => {
+ const flowData = ref({
+ id: '',
+ name: '',
+ childNode: {
+ id: 'start-1',
+ name: '开始',
+ type: 'start',
+ config: {
+ exec_type: 'manual',
+ },
+ childNode: null,
+ },
+ }) // 流程图数据
+ const flowZoom = ref(100) // 流程图缩放比例
+ const addNodeSelectList = ref([]) // 添加节点选项列表
+ const excludeNodeSelectList = ref([]) // 排除的节点选项列表
+ const addNodeBtnRef = ref(null) // 添加节点按钮
+ const addNodeSelectRef = ref(null) // 添加节点选择框
+ const addNodeSelectPostion = ref(null) // 添加节点选择框位置
+ const selectedNodeId = ref(null) // 当前选中的节点ID
+ const isRefreshNode = ref(null) // 是否刷新节点
+
+ // 计算添加节点选项列表,排除的节点选项列表
+ const nodeSelectList = computed(() => {
+ return addNodeSelectList.value.filter((item) => !excludeNodeSelectList.value.includes(item.type))
+ })
+
+ /**
+ * 获取添加节点选项列表
+ * @type {NodeSelect[]}
+ */
+ const getAddNodeSelect = () => {
+ addNodeSelectList.value = []
+ Object.keys(nodeOptions).forEach((key) => {
+ const item = nodeOptions[key as NodeNum]()
+ if (item.operateNode?.add) {
+ addNodeSelectList.value.push({
+ title: { name: item.title.name } as NodeTitle,
+ type: key as NodeNum,
+ icon: { ...(item.icon || {}) } as NodeIcon,
+ selected: false,
+ })
+ }
+ })
+ }
+
+ /**
+ * 添加排除的节点选项列表
+ * @param {NodeNum[]} nodeTypes - 节点类型
+ */
+ const addExcludeNodeSelectList = (nodeTypes: NodeNum[]) => {
+ excludeNodeSelectList.value = nodeTypes
+ }
+
+ /**
+ * 清除排除的节点选项列表
+ */
+ const clearExcludeNodeSelectList = () => {
+ excludeNodeSelectList.value = []
+ }
+
+ /**
+ * 显示添加节点选择框
+ * @param {boolean} flag - 是否显示添加节点选择框
+ */
+ const setShowAddNodeSelect = (flag: boolean, nodeType: NodeNum) => {
+ // 设置排除的节点选项列表
+ excludeNodeSelectList.value = nodeOptions[nodeType]().operateNode?.onSupportNode || []
+ // 设置添加节点选择框位置
+ if (flag && addNodeSelectRef.value && addNodeBtnRef.value) {
+ const box = addNodeSelectRef.value.getBoundingClientRect() // 添加节点选择框
+ const boxWidth = box.width // 添加节点选择框宽度
+ const btn = addNodeBtnRef.value.getBoundingClientRect() // 添加节点按钮
+ const btnRight = btn.right // 添加节点按钮右侧位置
+ const windowWidth = window.innerWidth // 窗口宽度
+ addNodeSelectPostion.value = btnRight + boxWidth > windowWidth ? 1 : 2
+ }
+ }
+
+ /**
+ * 初始化流程图数据
+ * 创建一个默认的开始节点作为流程图的起点
+ */
+ const initFlowData = () => {
+ const deepMockData = JSON.parse(JSON.stringify(MockData))
+ deepMockData.name = '工作流(' + formatDate(new Date(), 'yyyy/MM/dd HH:mm:ss') + ')'
+ flowData.value = deepMockData
+ }
+
+ /**
+ * 重置流程图数据
+ * 清空当前流程图的所有数据
+ */
+ const resetFlowData = () => initFlowData()
+
+ /**
+ * 递归查找节点
+ * @param node 当前节点
+ * @param targetId 目标节点ID
+ * @returns 找到的节点或null
+ */
+ const findNodeRecursive = (node: BaseNodeData | BranchNodeData, targetId: string): BaseNodeData | null => {
+ if (node.id === targetId) return node
+
+ // 优先检查子节点
+ if (node.childNode) {
+ const found = findNodeRecursive(node.childNode, targetId)
+ if (found) return found
+ }
+ // 再检查条件节点
+ if ((node as BranchNodeData).conditionNodes?.length) {
+ for (const conditionNode of (node as BranchNodeData).conditionNodes) {
+ const found = findNodeRecursive(conditionNode, targetId)
+ if (found) return found
+ }
+ }
+
+ return null
+ }
+
+ /**
+ * 通过节点id查找节点数据
+ * @param nodeId 节点id
+ * @returns 节点数据或null
+ */
+ const getFlowFindNodeData = (nodeId: string): BaseNodeData | null => {
+ return findNodeRecursive(flowData.value.childNode, nodeId)
+ }
+
+ /**
+ * 递归更新节点
+ * @param node 当前节点
+ * @param targetId 目标节点ID
+ * @param updateFn 更新函数
+ * @param parent 父节点
+ * @returns 是否更新成功
+ */
+ const updateNodeRecursive = (
+ node: BaseNodeData | BranchNodeData,
+ targetId: string,
+ updateFn: (node: BaseNodeData | BranchNodeData, parent: BaseNodeData | BranchNodeData | null) => void,
+ parent: BaseNodeData | BranchNodeData | null = null,
+ ): boolean => {
+ if (node.id === targetId) {
+ updateFn(node, parent)
+ return true
+ }
+
+ if (node.childNode) {
+ if (updateNodeRecursive(node.childNode, targetId, updateFn, node)) {
+ return true
+ }
+ }
+
+ if ((node as BranchNodeData).conditionNodes?.length) {
+ for (const conditionNode of (node as BranchNodeData).conditionNodes) {
+ if (updateNodeRecursive(conditionNode, targetId, updateFn, node)) {
+ return true
+ }
+ }
+ }
+
+ return false
+ }
+
+ /**
+ * 添加节点
+ * @param parentNodeId 父节点ID
+ * @param nodeType 节点类型
+ * @param nodeData 节点数据
+ * @param position 插入位置(对于条件节点有效)
+ */
+ const addNode = (
+ parentNodeId: string, // 父节点ID
+ nodeType: NodeNum, // 节点类型
+ nodeData: Partial = {}, // 节点数据
+ ) => {
+ // 获取父节点
+ const parentNode = getFlowFindNodeData(parentNodeId)
+ if (!parentNode) {
+ console.warn(`Parent node with id ${parentNodeId} not found`)
+ return
+ }
+ // 获取支持的节点默认配置
+ let newNodeData = deepMerge(nodeOptions[nodeType]().defaultNode as BaseNodeData, nodeData) as
+ | BaseNodeData
+ | BranchNodeData // 获取支持的节点默认配置
+
+ // 更新原始数据
+ updateNodeRecursive(flowData.value.childNode, parentNodeId, (node, parent) => {
+ switch (nodeType) {
+ case CONDITION:
+ // console.log('条件节点', node, parent)
+ if ((node as BranchNodeData).conditionNodes) {
+ newNodeData.name = `分支${(node as BranchNodeData).conditionNodes.length + 1}`
+ ;(node as BranchNodeData).conditionNodes.push(newNodeData)
+ }
+ break
+ case BRANCH:
+ case EXECUTE_RESULT_BRANCH:
+ // 执行结果分支节点
+ if (nodeType === EXECUTE_RESULT_BRANCH) {
+ newNodeData = { ...newNodeData, config: { fromNodeId: parentNodeId } }
+ }
+
+ ;(newNodeData as BranchNodeData).conditionNodes[0].childNode = node.childNode
+ node.childNode = newNodeData
+ break
+ default:
+ // console.log('其他节点', node, parent)
+ if (node.childNode) newNodeData.childNode = node.childNode // 组件嵌套到 childNode 中
+ node.childNode = newNodeData
+ break
+ }
+ })
+ }
+
+ /**
+ * 向上查找数据类型为 apply 或 upload 的节点
+ * @param nodeId 起始节点ID
+ * @returns 符合条件的节点数组 [{name: string, id: string}]
+ */
+ const findApplyUploadNodesUp = (
+ nodeId: string,
+ scanNode: string[] = ['apply', 'upload'],
+ ): Array<{ name: string; id: string }> => {
+ const result: Array<{ name: string; id: string }> = []
+
+ // 递归查找父节点的函数
+ const findParentRecursive = (
+ currentNode: BaseNodeData | BranchNodeData,
+ targetId: string,
+ path: Array = [],
+ ): Array | null => {
+ // 检查当前节点是否为目标节点
+ if (currentNode.id === targetId) {
+ return path
+ }
+
+ // 检查子节点
+ if (currentNode.childNode) {
+ const newPath = [...path, currentNode]
+ const found = findParentRecursive(currentNode.childNode, targetId, newPath)
+ if (found) return found
+ }
+
+ // 检查条件节点
+ if ((currentNode as BranchNodeData).conditionNodes?.length) {
+ for (const conditionNode of (currentNode as BranchNodeData).conditionNodes) {
+ const newPath = [...path, currentNode]
+ const found = findParentRecursive(conditionNode, targetId, newPath)
+ if (found) return found
+ }
+ }
+
+ return null
+ }
+
+ // 从根节点开始查找路径
+ const path = findParentRecursive(flowData.value.childNode, nodeId)
+ // 如果找到路径,筛选出 apply 和 upload 类型的节点
+ if (path) {
+ path.forEach((node) => {
+ if (scanNode.includes(node.type)) {
+ result.push({
+ name: node.name,
+ id: node.id as string,
+ })
+ }
+ })
+ }
+ return result
+ }
+
+ /**
+ * 删除节点
+ * @param nodeId 要删除的节点ID
+ * @param deep 是否深度删除(默认false,即子节点上移)
+ */
+ const removeNode = (nodeId: string, deep: boolean = false) => {
+ const node = getFlowFindNodeData(nodeId)
+ if (!node) {
+ console.warn(`Node with id ${nodeId} not found`)
+ return
+ }
+ console.log(nodeId, node)
+
+ // 更新原始数据
+ updateNodeRecursive(flowData.value.childNode, nodeId, (node, parent) => {
+ if (!parent) {
+ console.warn('Cannot remove root node')
+ return
+ }
+ const { type, conditionNodes } = parent as BranchNodeData | ExecuteResultBranchNodeData
+ // 处理条件节点(分支节点、执行结果分支节点)
+ // console.log(type, conditionNodes, node)
+
+ // 条件一:当前节点为普通节点
+ const nodeTypeList = [CONDITION, EXECUTE_RESULT_CONDITION, BRANCH, EXECUTE_RESULT_BRANCH]
+ if (!nodeTypeList.includes(node.type) && parent.childNode?.id === nodeId) {
+ console.log(deep)
+ // 处理普通节点
+ if (deep) {
+ // 深度删除,直接移除
+ parent.childNode = undefined
+ } else {
+ console.log(parent.childNode, node.childNode)
+ // 非深度删除,子节点上移
+ if (node.childNode) {
+ parent.childNode = node.childNode
+ } else {
+ parent.childNode = undefined
+ }
+ }
+ return
+ }
+
+ // 条件二:当前节点为条件节点
+ if (nodeTypeList.includes(node.type)) {
+ // 条件节点为分支节点或执行结果分支节点
+ if (conditionNodes.length === 2) {
+ // 条件节点为分支节点,则选定对立节点的子节点作为当前节点的子节点
+ // console.log('条件节点为分支节点', parent)
+ if (type === BRANCH) {
+ updateNodeRecursive(flowData.value.childNode, parent.id as string, (nodes, parents) => {
+ const index = conditionNodes.findIndex((n) => n.id === nodeId)
+ const backNode = nodes.childNode
+ if (index !== -1 && parents) {
+ parents.childNode = conditionNodes[index === 0 ? 1 : 0].childNode // 将选定对立节点的子节点作为当前节点的子节
+ const allChildNode = getNodePropertyToLast(parents, 'childNode') as BaseNodeData
+ allChildNode.childNode = backNode
+ }
+ })
+ } else {
+ updateNodeRecursive(flowData.value.childNode, parent.id as string, (nodes, parents) => {
+ if (parents) {
+ if (parent?.childNode?.id) {
+ parents.childNode = parent.childNode
+ } else {
+ parents.childNode = undefined
+ }
+ }
+ })
+ }
+ } else {
+ const index = (parent as BranchNodeData).conditionNodes.findIndex((n) => n.id === nodeId)
+ if (index !== -1) {
+ if (deep) {
+ // 深度删除,直接移除
+ ;(parent as BranchNodeData).conditionNodes.splice(index, 1)
+ } else {
+ // 非深度删除,子节点上移
+ const targetNode = (parent as BranchNodeData).conditionNodes[index]
+ if (targetNode?.childNode) {
+ ;(parent as BranchNodeData).conditionNodes[index] = targetNode.childNode
+ } else {
+ ;(parent as BranchNodeData).conditionNodes.splice(index, 1)
+ }
+ }
+ }
+ }
+ }
+ })
+
+ return flowData.value
+ }
+
+ /**
+ * 递归查询节点属性直到最后一层
+ * @param node 当前节点
+ * @param property 要查询的属性名
+ * @returns 最后一层的属性值
+ */
+ const getNodePropertyToLast = (node: BaseNodeData, property: string) => {
+ if (!node) return null
+ const value = (node as any)[property]
+ if (!value) return node
+ // 如果属性值是一个对象,继续递归查询
+ if (typeof value === 'object' && value !== null) {
+ return getNodePropertyToLast(value, property)
+ }
+ }
+
+ /**
+ * 更新节点配置
+ * @param nodeId 节点ID
+ * @param config 新的配置数据
+ */
+ const updateNodeConfig = (nodeId: string, config: Record) => {
+ const node = getFlowFindNodeData(nodeId)
+ if (!node) {
+ console.warn(`Node with id ${nodeId} not found`)
+ return
+ }
+ // 更新原始数据
+ updateNodeRecursive(flowData.value.childNode, nodeId, (node) => {
+ node.config = config
+ })
+ return flowData.value
+ }
+
+ /**
+ * 更新节点数据
+ * @param nodeId 要更新的节点ID
+ * @param newNodeData 新的节点数据
+ */
+ const updateNode = (nodeId: string, newNodeData: Partial, isMergeArray: boolean = true) => {
+ const node = getFlowFindNodeData(nodeId)
+ if (!node) {
+ console.warn(`Node with id ${nodeId} not found`)
+ return
+ }
+
+ // 更新原始数据
+ updateNodeRecursive(flowData.value.childNode, nodeId, (node) => {
+ const updatedNode = deepMerge(node, newNodeData, isMergeArray) as BaseNodeData
+ Object.keys(updatedNode).forEach((key) => {
+ if (key in node) {
+ ;(node as any)[key] = updatedNode[key as keyof typeof updatedNode]
+ }
+ })
+ })
+
+ return flowData.value
+ }
+
+ /**
+ * 检查节点是否存在子节点
+ * @param nodeId 节点id
+ * @returns 是否存在子节点
+ */
+ const checkFlowNodeChild = (nodeId: string): boolean => {
+ const node = getFlowFindNodeData(nodeId)
+ return node ? !!(node.childNode || (node as BranchNodeData).conditionNodes?.length) : false
+ }
+
+ /**
+ * 检查是否存在行内节点
+ * @param nodeId 节点id
+ */
+ const checkFlowInlineNode = (nodeId: string) => {
+ const node = getFlowFindNodeData(nodeId)
+ if (!node || node.type !== 'condition') return
+
+ // 更新原始数据
+ updateNodeRecursive(flowData.value.childNode, nodeId, (node) => {
+ if ((node as BranchNodeData).conditionNodes) {
+ ;(node as BranchNodeData).conditionNodes = (node as BranchNodeData).conditionNodes.filter(
+ (n) => n.id !== nodeId,
+ )
+ }
+ })
+ }
+
+ // /**
+ // * @description 显示节点选择
+ // * @param {boolean} flag
+ // * @param {NodeNum} nodeData
+ // */
+ // const showNodeSelect = (flag: boolean, nodeType?: NodeNum) => {
+ // if (!flag) {
+ // clearTimeout(timer.value as number)
+ // timer.value = window.setTimeout(() => {
+ // isShowAddNodeSelect.value = flag
+ // }, 1000) as unknown as null
+ // } else {
+ // isShowAddNodeSelect.value = false
+ // isShowAddNodeSelect.value = flag
+ // }
+ // // 设置添加节点选择状态
+ // if (nodeType) {
+ // flowStore.setShowAddNodeSelect(flag, nodeType)
+ // }
+ // }
+
+ /**
+ * 获取流程图数据
+ * 返回当前流程图数据的深拷贝,避免直接修改原始数据
+ * @returns {Object} 流程图数据的副本
+ */
+ const getResultData = () => {
+ return deepMerge({}, flowData.value)
+ }
+
+ /**
+ * 更新流程图数据
+ * 用新的数据替换当前的流程图数据
+ * @param {Object} newData - 新的流程图数据
+ */
+ const updateFlowData = (newData: FlowNode) => {
+ flowData.value = newData
+ }
+
+ /**
+ * 设置流程图缩放比例
+ * 控制流程图的显示大小
+ * @param {number} type - 缩放类型:1 表示缩小,2 表示放大
+ */
+ const setflowZoom = (type: number) => {
+ if (type === 1 && flowZoom.value > 50) {
+ flowZoom.value -= 10
+ } else if (type === 2 && flowZoom.value < 300) {
+ flowZoom.value += 10
+ }
+ }
+
+ return {
+ // 数据
+ flowData, // 流程图数据
+ flowZoom, // 流程图缩放比例
+ selectedNodeId, // 当前选中的节点ID
+ isRefreshNode, // 是否刷新节点
+
+ // 方法
+ initFlowData, // 初始化流程图数据
+ resetFlowData, // 重置流程图数据
+ getResultData, // 获取流程图数据
+ updateFlowData, // 更新流程图数据
+ setflowZoom, // 设置流程图缩放比例
+
+ // 添加节点-数据
+ addNodeSelectList, // 添加节点选项列表
+ nodeSelectList, // 计算添加节点选项列表,排除的节点选项列表
+ excludeNodeSelectList, // 排除的节点选项列表
+ addNodeBtnRef, // 添加节点按钮
+ addNodeSelectRef, // 添加节点选择框
+ addNodeSelectPostion, // 添加节点选择框位置
+
+ // 添加节点-方法
+ getAddNodeSelect, // 获取添加节点选项列表
+ addExcludeNodeSelectList, // 添加排除的节点选项列表
+ clearExcludeNodeSelectList, // 清除排除的节点选项列表
+ setShowAddNodeSelect, // 设置显示添加节点选择框
+
+ // 节点操作
+ addNode,
+ removeNode,
+ updateNodeConfig,
+ updateNode,
+ findApplyUploadNodesUp, // 向上查找 apply 和 upload 类型节点
+ checkFlowNodeChild, // 检查节点是否存在子节点
+ checkFlowInlineNode, // 检查是否存在行内节点
+ }
+})
+
+/**
+ * 使用流程图数据存储
+ * 提供流程图数据存储的引用和解构
+ * @returns {Object} 包含流程图数据存储的引用和解构
+ */
+export const useStore = () => {
+ const flowStore = useFlowStore()
+ const storeRef = storeToRefs(flowStore)
+ return {
+ ...flowStore,
+ ...storeRef,
+ }
+}
diff --git a/frontend/apps/allin-ssl/src/components/logViewer/index.tsx b/frontend/apps/allin-ssl/src/components/logViewer/index.tsx
new file mode 100644
index 0000000..fae25f8
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/logViewer/index.tsx
@@ -0,0 +1,151 @@
+import { NCard, NText, NSpin, NScrollbar, NButton, NSpace, NIcon } from 'naive-ui'
+import { DownloadOutline } from '@vicons/ionicons5'
+
+export default defineComponent({
+ name: 'LogViewer',
+ props: {
+ // 日志内容
+ content: {
+ type: String,
+ default: '',
+ },
+ // 是否加载中
+ loading: {
+ type: Boolean,
+ default: false,
+ },
+ // 是否允许下载
+ enableDownload: {
+ type: Boolean,
+ default: true,
+ },
+ // 下载文件名
+ downloadFileName: {
+ type: String,
+ default: 'logs.txt',
+ },
+ // 标题
+ title: {
+ type: String,
+ default: '日志详情',
+ },
+ // 获取日志方法
+ fetchLogs: {
+ type: Function as PropType<() => Promise>,
+ default: () => Promise.resolve(''),
+ },
+ },
+ setup(props) {
+ const logs = ref(props.content || '')
+ const isLoading = ref(props.loading)
+ const logContainerRef = ref(null)
+
+ // 监听内容变化
+ watch(
+ () => props.content,
+ (newValue) => {
+ logs.value = newValue
+ scrollToBottom()
+ },
+ )
+
+ // 监听加载状态变化
+ watch(
+ () => props.loading,
+ (newValue) => {
+ isLoading.value = newValue
+ },
+ )
+
+ watch(
+ () => props.fetchLogs,
+ (newValue) => {
+ console.log('fetchLogs', props.fetchLogs)
+ },
+ )
+
+ onMounted(() => {
+ // 如果有传入获取日志的方法,则调用
+ // 这里可以根据需要设置一个定时器来定时获取日志
+ loadLogs()
+ scrollToBottom()
+ })
+
+ // 加载日志
+ const loadLogs = async () => {
+ if (!props.fetchLogs) return
+ isLoading.value = true
+ try {
+ const result = await props.fetchLogs()
+ console.log('获取日志:', result)
+ logs.value = result
+ scrollToBottom()
+ } catch (error) {
+ console.error('加载日志失败:', error)
+ } finally {
+ isLoading.value = false
+ }
+ }
+
+ // 下载日志
+ const downloadLogs = () => {
+ if (!logs.value) return
+
+ const blob = new Blob([logs.value], { type: 'text/plain' })
+ const url = URL.createObjectURL(blob)
+ const a = document.createElement('a')
+ a.href = url
+ a.download = props.downloadFileName
+ document.body.appendChild(a)
+ a.click()
+ document.body.removeChild(a)
+ URL.revokeObjectURL(url)
+ }
+
+ // 滚动到底部
+ const scrollToBottom = () => {
+ setTimeout(() => {
+ if (logContainerRef.value) {
+ const scrollElement = logContainerRef.value.querySelector('.n-scrollbar-container')
+ if (scrollElement) {
+ scrollElement.scrollTop = scrollElement.scrollHeight
+ }
+ }
+ }, 100)
+ }
+
+ // 刷新日志
+ const refreshLogs = () => {
+ loadLogs()
+ }
+
+ return () => (
+
+
+
+
+
+ 刷新
+
+ {props.enableDownload && (
+
+
+
+
+ 下载日志
+
+ )}
+
+
+
+
+
+ {logs.value ? logs.value : '暂无日志信息'}
+
+
+
+
+
+ )
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/components/notifyProviderSelect/index.tsx b/frontend/apps/allin-ssl/src/components/notifyProviderSelect/index.tsx
new file mode 100644
index 0000000..14d12d6
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/notifyProviderSelect/index.tsx
@@ -0,0 +1,178 @@
+import { defineComponent, VNode } from 'vue'
+import { NButton, NFlex, NFormItemGi, NGrid, NSelect, NText } from 'naive-ui'
+import { $t } from '@locales/index'
+import { useStore } from '@/views/layout/useStore'
+import SvgIcon from '@components/svgIcon'
+
+interface NotifyProviderOption {
+ label: string
+ value: string
+ type: string
+}
+
+interface NotifyProviderSelectProps {
+ path: string
+ value: string
+ valueType: 'value' | 'type'
+ isAddMode: boolean
+}
+
+export default defineComponent({
+ name: 'NotifyProviderSelect',
+ props: {
+ // 表单,用于绑定表单的值
+ path: {
+ type: String,
+ default: '',
+ },
+ // 表单的值
+ value: {
+ type: String,
+ default: '',
+ },
+ // 表单的值类型
+ valueType: {
+ type: String,
+ default: 'value',
+ },
+
+ // 是否为添加模式
+ isAddMode: {
+ type: Boolean,
+ default: false,
+ },
+ },
+ emits: ['update:value'],
+ setup(props: NotifyProviderSelectProps, { emit }) {
+ // 获取消息通知提供商
+ const { fetchNotifyProvider, notifyProvider } = useStore()
+ // 表单的值
+ const param = ref({
+ label: '',
+ value: '',
+ type: '',
+ })
+ const notifyProviderRef = ref([])
+
+ /**
+ * 打开通知渠道配置页面
+ */
+ const goToAddNotifyProvider = () => {
+ window.open('/settings?tab=notification', '_blank')
+ }
+
+ /**
+ * 渲染单选标签
+ * @param option - 选项
+ * @returns 渲染后的VNode
+ */
+ const renderSingleSelectTag = ({ option }: Record): VNode => {
+ return (
+
+ {option.label ? (
+
+
+ {option.label}
+
+ ) : (
+ {$t('t_0_1745887835267')}
+ )}
+
+ )
+ }
+
+ /**
+ * 渲染标签
+ * @param option - 选项
+ * @returns 渲染后的VNode
+ */
+ const renderLabel = (option: NotifyProviderOption): VNode => {
+ return (
+
+
+ {option.label}
+
+ )
+ }
+
+ /**
+ * @description 更新类型
+ * @param option - 选项
+ * @param value - 值
+ */
+ const handleUpdateType = (value: string) => {
+ if (!value) return
+ const row = notifyProviderRef.value.find((item) => {
+ return item.value === value
+ })
+ param.value = {
+ label: row?.label || '',
+ value: row?.value || '',
+ type: row?.type || '',
+ }
+ }
+
+ /**
+ * 更新表单的值
+ * @param value - 表单的值
+ */
+ const handleUpdateValue = (value: string) => {
+ handleUpdateType(value)
+ emit('update:value', param.value)
+ }
+
+ // 监听父组件的值
+ watch(
+ () => props.value,
+ (newVal) => {
+ fetchNotifyProvider()
+ handleUpdateType(newVal)
+ },
+ { immediate: true },
+ )
+
+ // 监听消息通知提供商
+ watch(
+ () => notifyProvider.value,
+ (newVal) => {
+ notifyProviderRef.value =
+ newVal.map((item) => ({
+ label: item.label,
+ value: props.valueType === 'value' ? item.value : item.type,
+ type: props.valueType === 'value' ? item.type : item.value,
+ })) || []
+ handleUpdateType(props.value)
+ },
+ )
+
+ return () => (
+
+
+ {
+ return {$t('t_0_1745887835267')}
+ },
+ }}
+ />
+
+ {props.isAddMode && (
+
+
+ {$t('t_2_1745887834248')}
+
+ {$t('t_0_1746497662220')}
+
+ )}
+
+ )
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/components/svgIcon/index.tsx b/frontend/apps/allin-ssl/src/components/svgIcon/index.tsx
new file mode 100644
index 0000000..b6bb08f
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/svgIcon/index.tsx
@@ -0,0 +1,40 @@
+import { defineComponent, computed, PropType } from 'vue'
+
+interface SvgIconProps {
+ size: string
+ icon: string
+ color?: string
+}
+
+export default defineComponent({
+ name: 'SvgIcon',
+ props: {
+ // 图标
+ icon: {
+ type: String as PropType,
+ required: true,
+ },
+ // 颜色
+ color: {
+ type: String as PropType,
+ default: '',
+ },
+ // 大小
+ size: {
+ type: String as PropType,
+ default: '1.8rem',
+ },
+ },
+ setup(props: SvgIconProps) {
+ const iconName = computed(() => `#icon-${props.icon}`)
+ return () => (
+
+ )
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/components/typeIcon/index.tsx b/frontend/apps/allin-ssl/src/components/typeIcon/index.tsx
new file mode 100644
index 0000000..6f41fa3
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/components/typeIcon/index.tsx
@@ -0,0 +1,110 @@
+import { defineComponent, PropType } from 'vue'
+import { NTag, NText } from 'naive-ui'
+import SvgIcon from '../svgIcon/index' // 注意修改引入路径以匹配实际位置
+
+// 定义支持的访问类型
+const types = {
+ ssh: 'SSH',
+ aliyun: '阿里云',
+ tencentcloud: '腾讯云',
+ btpanel: '宝塔面板',
+ '1panel': '1Panel',
+ mail: '邮件',
+ dingtalk: '钉钉',
+ wecom: '企业微信',
+ feishu: '飞书',
+ webhook: 'WebHook',
+ 'tencentcloud-cdn': '腾讯云CDN',
+ 'tencentcloud-cos': '腾讯云COS',
+ 'aliyun-cdn': '阿里云CDN',
+ 'aliyun-oss': '阿里云OSS',
+ '1panel-site': '1Panel网站',
+ 'btpanel-site': '宝塔面板网站',
+}
+
+export const AuthApiTypeIcon = defineComponent({
+ name: 'TypeIcon',
+ props: {
+ // 图标类型
+ icon: {
+ type: String as PropType,
+ required: true,
+ },
+ // tag类型
+ type: {
+ type: String as PropType<'default' | 'primary' | 'info' | 'success' | 'warning' | 'error'>,
+ default: 'default',
+ },
+ // 对齐方式
+ align: {
+ type: String as PropType<'left' | 'right'>,
+ default: 'left',
+ },
+ // 是否显示文本
+ text: {
+ type: Boolean,
+ default: true,
+ },
+ },
+ setup(props) {
+ // 获取图标路径的函数 - 进一步优化版
+ const iconPath = computed(() => {
+ const isNotify = ['mail', 'dingtalk', 'wecom', 'feishu', 'webhook'].includes(props.icon)
+ const RESOURCE_PREFIX = isNotify ? 'notify-' : 'resources-'
+
+ // 所有支持的类型直接映射到对应的资源名称
+ const iconMap: Record = {
+ ssh: 'ssh',
+ aliyun: 'aliyun',
+ tencentcloud: 'tencentcloud',
+ btpanel: 'btpanel',
+ '1panel': '1panel',
+ mail: 'mail',
+ dingtalk: 'dingtalk',
+ wecom: 'wecom',
+ feishu: 'feishu',
+ webhook: 'webhook',
+ 'tencentcloud-cdn': 'tencentcloud',
+ 'tencentcloud-cos': 'tencentcloud',
+ 'aliyun-cdn': 'aliyun',
+ 'aliyun-oss': 'aliyun',
+ '1panel-site': '1panel',
+ 'btpanel-site': 'btpanel',
+ }
+
+ // 返回匹配的图标路径或默认图标
+ return RESOURCE_PREFIX + (iconMap[props.icon] || 'default')
+ })
+ const typeName = computed(() => types[props.icon as keyof typeof types] || props.icon)
+
+ watch(
+ () => props.icon,
+ (newVal) => {
+ console.log(newVal, 'newVal')
+ },
+ )
+
+ watch(
+ () => props.type,
+ (newVal) => {
+ console.log(newVal, 'newVal')
+ },
+ )
+
+ return () => (
+ ,
+ }}
+ >
+ {props.text && {typeName.value}}
+
+ )
+ },
+})
+
+// 默认导出组件,方便使用
+export default AuthApiTypeIcon
diff --git a/frontend/apps/allin-ssl/src/config/i18n.ts b/frontend/apps/allin-ssl/src/config/i18n.ts
new file mode 100644
index 0000000..c65a032
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/config/i18n.ts
@@ -0,0 +1,53 @@
+;[
+ {
+ code: 'zh-CN',
+ name: '中文',
+ icon: 'cn',
+ },
+ {
+ code: 'zh-tw',
+ name: '繁體中文',
+ icon: 'tw',
+ },
+ {
+ code: 'en-US',
+ name: 'English',
+ icon: 'us',
+ },
+
+ {
+ code: 'ja-JP',
+ name: '日本語',
+ icon: 'jp',
+ },
+ {
+ code: 'ko-KR',
+ name: '한국어',
+ icon: 'kr',
+ },
+ {
+ code: 'ru-RU',
+ name: 'Русский',
+ icon: 'ru',
+ },
+ {
+ code: 'pt-BR',
+ name: 'Português',
+ icon: 'br',
+ },
+ {
+ code: 'fr-FR',
+ name: 'Français',
+ icon: 'fr',
+ },
+ {
+ code: 'es-AR',
+ name: 'Español',
+ icon: 'es',
+ },
+ {
+ code: 'ar-DZ',
+ name: 'العربية',
+ icon: 'dz',
+ },
+]
diff --git a/frontend/apps/allin-ssl/src/config/route.ts b/frontend/apps/allin-ssl/src/config/route.ts
new file mode 100644
index 0000000..019e069
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/config/route.ts
@@ -0,0 +1,16 @@
+import { $t } from '@locales/index'
+
+export default {
+ sortRoute: [
+ { name: 'home', title: $t('t_0_1744258111441') },
+ { name: 'autoDeploy', title: $t('t_1_1744258113857') },
+ { name: 'certManage', title: $t('t_2_1744258111238') },
+ { name: 'certApply', title: $t('t_3_1744258111182') },
+ { name: 'authApiManage', title: $t('t_4_1744258111238') },
+ { name: 'monitor', title: $t('t_5_1744258110516') },
+ { name: 'settings', title: $t('t_6_1744258111153') },
+ ], // 路由排序
+ frameworkRoute: ['layout'], // 框架路由
+ systemRoute: ['login', '404'], // 系统路由
+ disabledRoute: [], // 禁用路由
+}
diff --git a/frontend/apps/allin-ssl/src/locales/index.ts b/frontend/apps/allin-ssl/src/locales/index.ts
new file mode 100644
index 0000000..a56ffd2
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/locales/index.ts
@@ -0,0 +1,18 @@
+// 自动生成的i18n入口文件
+// 自动生成的i18n入口文件
+import { useLocale } from '@baota/i18n'
+import zhCN from './model/zhCN.json'
+import enUS from './model/enUS.json'
+
+// 使用 i18n 插件
+export const { i18n, $t, locale, localeOptions } = useLocale(
+ {
+ messages: { zhCN, enUS },
+ locale: 'zhCN',
+ fileExt: 'json'
+ },
+ import.meta.glob([`./model/*.json`], {
+ eager: false,
+ }),
+)
+
diff --git a/frontend/apps/allin-ssl/src/locales/model/arDZ.json b/frontend/apps/allin-ssl/src/locales/model/arDZ.json
new file mode 100644
index 0000000..6be7ead
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/locales/model/arDZ.json
@@ -0,0 +1,490 @@
+{
+ "t_0_1746773763967": "هل أنت متأكد أنك تريد حذف {0}، قناة الإشعارات؟",
+ "t_1_1746773763643": "Let's Encrypt وغيرها من الجهات المصدقة تطلب شهادات مجانية تلقائيًا",
+ "t_0_1744098811152": "تحذير: لقد دخلتم منطقة غير معروفة، الصفحة التي تحاول زيارتها غير موجودة، يرجى الضغط على الزر للعودة إلى الصفحة الرئيسية.",
+ "t_1_1744098801860": "رجوع إلى الصفحة الرئيسية",
+ "t_2_1744098804908": "نصيحة أمنية: إذا كنت تعتقد أن هذا خطأ، يرجى الاتصال بالمدير على الفور",
+ "t_3_1744098802647": "افتح القائمة الرئيسية",
+ "t_4_1744098802046": "القائمة الرئيسية القابلة للطي",
+ "t_0_1744164843238": "مرحبًا بكم في AllinSSL، إدارة فعالة لشهادات SSL",
+ "t_1_1744164835667": "AllinSSL",
+ "t_2_1744164839713": "دخول الحساب",
+ "t_3_1744164839524": "من فضلك أدخل اسم المستخدم",
+ "t_4_1744164840458": "من فضلك أدخل كلمة المرور",
+ "t_5_1744164840468": "تذكر كلمة المرور",
+ "t_6_1744164838900": "هل نسيت كلمة المرور؟",
+ "t_7_1744164838625": "في إجراء الدخول",
+ "t_8_1744164839833": "تسجيل الدخول",
+ "t_0_1744168657526": "تسجيل الخروج",
+ "t_0_1744258111441": "الصفحة الرئيسية",
+ "t_1_1744258113857": "توزيع آلي",
+ "t_2_1744258111238": "إدارة الشهادات",
+ "t_3_1744258111182": "طلب شهادة",
+ "t_4_1744258111238": "إدارة API التصريح",
+ "t_5_1744258110516": "مراقبة",
+ "t_6_1744258111153": "إعدادات",
+ "t_0_1744861190562": "إرجاع قائمة عملية العمل",
+ "t_1_1744861189113": "تشغيل",
+ "t_2_1744861190040": "حفظ",
+ "t_3_1744861190932": "أختر عقدة لتكوينها",
+ "t_4_1744861194395": "انقر على النقطة في الشريحة اليسرى من مخطط العمل لتزويده بالتكوين",
+ "t_5_1744861189528": "تبدأ",
+ "t_6_1744861190121": "لم يتم اختيار العقدة",
+ "t_7_1744861189625": "تم حفظ الإعدادات",
+ "t_8_1744861189821": "بدء عملية العمل",
+ "t_9_1744861189580": "النقطة المختارة:",
+ "t_0_1744870861464": "نقطة",
+ "t_1_1744870861944": "إعداد العقدة",
+ "t_2_1744870863419": "يرجى اختيار العقدة اليسرى للتكوين",
+ "t_3_1744870864615": "لم يتم العثور على مكون التكوين لهذا النوع من العقد",
+ "t_4_1744870861589": "إلغاء",
+ "t_5_1744870862719": "تحديد",
+ "t_0_1744875938285": "كل دقيقة",
+ "t_1_1744875938598": "كل ساعة",
+ "t_2_1744875938555": "كل يوم",
+ "t_3_1744875938310": "كل شهر",
+ "t_4_1744875940750": "تنفيذ تلقائي",
+ "t_5_1744875940010": "تنفيذ يدوي",
+ "t_0_1744879616135": "اختبار PID",
+ "t_1_1744879616555": "الرجاء إدخال PID الاختباري",
+ "t_2_1744879616413": "فترة التنفيذ",
+ "t_3_1744879615723": "دقيقة",
+ "t_4_1744879616168": "من فضلك، أدخل الدقائق",
+ "t_5_1744879615277": "ساعة",
+ "t_6_1744879616944": "الرجاء إدخال الساعات",
+ "t_7_1744879615743": "التاريخ",
+ "t_8_1744879616493": "اختر التاريخ",
+ "t_0_1744942117992": "كل أسبوع",
+ "t_1_1744942116527": "الإثنين",
+ "t_2_1744942117890": "الثلاثاء",
+ "t_3_1744942117885": "الأربعاء",
+ "t_4_1744942117738": "الخميس",
+ "t_5_1744942117167": "الجمعة",
+ "t_6_1744942117815": "السبت",
+ "t_7_1744942117862": "الأحد",
+ "t_0_1744958839535": "الرجاء إدخال اسم النطاق",
+ "t_1_1744958840747": "الرجاء إدخال بريدك الإلكتروني",
+ "t_2_1744958840131": "تنسيق البريد الإلكتروني غير صحيح",
+ "t_3_1744958840485": "يرجى اختيار مزود DNS للإذن",
+ "t_4_1744958838951": "تثبيت محلي",
+ "t_5_1744958839222": "تثبيت SSH",
+ "t_6_1744958843569": "لوحة بوتا/1 لوحة (تثبيت في شهادة لوحة)",
+ "t_7_1744958841708": "1 panel (تثبيت على المشروع المحدد لل موقع)",
+ "t_8_1744958841658": "تencent Cloud CDN/أليCloud CDN",
+ "t_9_1744958840634": "WAF من Tencent Cloud",
+ "t_10_1744958860078": "WAF من آليكلاود",
+ "t_11_1744958840439": "هذا الشهادة المطلوبة تلقائيًا",
+ "t_12_1744958840387": "قائمة الشهادات الاختيارية",
+ "t_13_1744958840714": "PEM (*.pem, *.crt, *.key)",
+ "t_14_1744958839470": "PFX (*.pfx)",
+ "t_15_1744958840790": "JKS (*.jks)",
+ "t_16_1744958841116": "POSIX bash (Linux/macOS)",
+ "t_17_1744958839597": "CMD (Windows)",
+ "t_18_1744958839895": "PowerShell (Windows)",
+ "t_19_1744958839297": "شهادة1",
+ "t_20_1744958839439": "شهادة 2",
+ "t_21_1744958839305": "خادم 1",
+ "t_22_1744958841926": "خادم 2",
+ "t_23_1744958838717": "اللوحة 1",
+ "t_24_1744958845324": "لوحة 2",
+ "t_25_1744958839236": "الموقع 1",
+ "t_26_1744958839682": "الموقع 2",
+ "t_27_1744958840234": "تencent Cloud 1",
+ "t_28_1744958839760": "ألييوان 1",
+ "t_29_1744958838904": "يوم",
+ "t_30_1744958843864": "تنسيق الشهادة غير صحيح، يرجى التحقق مما إذا كان يحتوي على العناصر التوضيحية للعناوين والرؤوس الكاملة",
+ "t_31_1744958844490": "شكل المفتاح الخاص غير صحيح، يرجى التحقق من أن يحتوي على معرف الرأس والساقطة الكاملة للمفتاح الخاص",
+ "t_0_1745215914686": "اسم التلقائية",
+ "t_2_1745215915397": "تلقائي",
+ "t_3_1745215914237": "يدوي",
+ "t_4_1745215914951": "حالة نشطة",
+ "t_5_1745215914671": "تفعيل",
+ "t_6_1745215914104": "إيقاف",
+ "t_7_1745215914189": "وقت الإنشاء",
+ "t_8_1745215914610": "عملية",
+ "t_9_1745215914666": "تاريخ التنفيذ",
+ "t_10_1745215914342": "تنفيذ",
+ "t_11_1745215915429": "تعديل",
+ "t_12_1745215914312": "حذف",
+ "t_13_1745215915455": "تنفيذ مسار العمل",
+ "t_14_1745215916235": "نجاح تنفيذ عملية العمل",
+ "t_15_1745215915743": "فشل تنفيذ عملية العمل",
+ "t_16_1745215915209": "حذف مسار العمل",
+ "t_17_1745215915985": "نجاح عملية حذف العملية",
+ "t_18_1745215915630": "فشل حذف مسار العمل",
+ "t_0_1745227838699": "تثبيت آلي جديد",
+ "t_1_1745227838776": "الرجاء إدخال اسم الت automatization",
+ "t_2_1745227839794": "هل أنت متأكد من أنك تريد تنفيذ عملية {name}؟",
+ "t_3_1745227841567": "هل تؤكد على حذف {name} مسار العمل؟ هذه العملية لا يمكن إلغاؤها.",
+ "t_4_1745227838558": "وقت التنفيذ",
+ "t_5_1745227839906": "وقت الانتهاء",
+ "t_6_1745227838798": "طريقة التنفيذ",
+ "t_7_1745227838093": "الحالة",
+ "t_8_1745227838023": "نجاح",
+ "t_9_1745227838305": "فشل",
+ "t_10_1745227838234": "في تنفيذ",
+ "t_11_1745227838422": "غير معروف",
+ "t_12_1745227838814": "تفاصيل",
+ "t_13_1745227838275": "تحميل شهادة",
+ "t_14_1745227840904": "الرجاء إدخال اسم نطاق الشهادة أو اسم العلامة التجارية للبحث عنها",
+ "t_15_1745227839354": "معا",
+ "t_16_1745227838930": "شريحة",
+ "t_17_1745227838561": "اسم النطاق",
+ "t_18_1745227838154": "العلامة التجارية",
+ "t_19_1745227839107": "أيام متبقية",
+ "t_20_1745227838813": "زمن انتهاء الصلاحية",
+ "t_21_1745227837972": "مصدر",
+ "t_22_1745227838154": "طلب تلقائي",
+ "t_23_1745227838699": "تحميل يدوي",
+ "t_24_1745227839508": "إضافة وقت",
+ "t_25_1745227838080": "تحميل",
+ "t_27_1745227838583": "قريب من انتهاء الصلاحية",
+ "t_28_1745227837903": "طبيعي",
+ "t_29_1745227838410": "حذف الشهادة",
+ "t_30_1745227841739": "هل أنت متأكد من أنك تريد حذف هذا الشهادة؟ لا يمكن استعادة هذه العملية.",
+ "t_31_1745227838461": "تأكيد",
+ "t_32_1745227838439": "اسم الشهادة",
+ "t_33_1745227838984": "الرجاء إدخال اسم الشهادة",
+ "t_34_1745227839375": "محتويات الشهادة (PEM)",
+ "t_35_1745227839208": "الرجاء إدخال محتويات الشهادة",
+ "t_36_1745227838958": "محتويات المفتاح الخاص (KEY)",
+ "t_37_1745227839669": "الرجاء إدخال محتويات المفتاح الخاص",
+ "t_38_1745227838813": "فشل التحميل",
+ "t_39_1745227838696": "فشل التحميل",
+ "t_40_1745227838872": "فشل الحذف",
+ "t_0_1745289355714": "إضافة API للإذن",
+ "t_1_1745289356586": "الرجاء إدخال اسم أو نوع API المصرح به",
+ "t_2_1745289353944": "اسم",
+ "t_3_1745289354664": "نوع API للاذن",
+ "t_4_1745289354902": "API للتحرير المسموح به",
+ "t_5_1745289355718": "حذف API التحقق من الصلاحيات",
+ "t_6_1745289358340": "هل أنت متأكد من أنك تريد حذف هذا API المصرح به؟ لا يمكن استعادة هذا الإجراء.",
+ "t_7_1745289355714": "فشل الإضافة",
+ "t_8_1745289354902": "فشل التحديث",
+ "t_9_1745289355714": "انتهت صلاحيته {days} يوم",
+ "t_10_1745289354650": "إدارة المراقبة",
+ "t_11_1745289354516": "إضافة المراقبة",
+ "t_12_1745289356974": "الرجاء إدخال اسم المراقبة أو اسم النطاق للبحث عنه",
+ "t_13_1745289354528": "اسم المراقب",
+ "t_14_1745289354902": "اسم المجال للمستند",
+ "t_15_1745289355714": "جهة إصدار الشهادات",
+ "t_16_1745289354902": "حالة الشهادة",
+ "t_17_1745289355715": "تاريخ انتهاء صلاحية الشهادة",
+ "t_18_1745289354598": "قنوات التحذير",
+ "t_19_1745289354676": "تاريخ آخر فحص",
+ "t_20_1745289354598": "تعديل الرقابة",
+ "t_21_1745289354598": "تأكيد الحذف",
+ "t_22_1745289359036": "لا يمكن استعادة العناصر بعد الحذف. هل أنت متأكد من أنك تريد حذف هذا المراقب؟",
+ "t_23_1745289355716": "فشل التعديل",
+ "t_24_1745289355715": "فشل في الإعداد",
+ "t_25_1745289355721": "من فضلك، أدخل رمز التحقق",
+ "t_26_1745289358341": "فشل التحقق من النموذج، يرجى التحقق من المحتويات المملوءة",
+ "t_27_1745289355721": "من فضلك أدخل اسم API المصرح به",
+ "t_28_1745289356040": "يرجى اختيار نوع API الت�权يز",
+ "t_29_1745289355850": "الرجاء إدخال عنوان IP للخادم",
+ "t_30_1745289355718": "من فضلك، أدخل ميناء SSH",
+ "t_31_1745289355715": "من فضلك أدخل مفتاح SSH",
+ "t_32_1745289356127": "الرجاء إدخال عنوان بوتا",
+ "t_33_1745289355721": "الرجاء إدخال مفتاح API",
+ "t_34_1745289356040": "الرجاء إدخال عنوان 1panel",
+ "t_35_1745289355714": "من فضلك أدخل AccessKeyId",
+ "t_36_1745289355715": "من فضلك، أدخل AccessKeySecret",
+ "t_37_1745289356041": "من فضلك، أدخل SecretId",
+ "t_38_1745289356419": "من فضلك أدخل مفتاح السر",
+ "t_39_1745289354902": "نجاح التحديث",
+ "t_40_1745289355715": "نجاح الإضافة",
+ "t_41_1745289354902": "نوع",
+ "t_42_1745289355715": "IP del serveur",
+ "t_43_1745289354598": "منفذ SSH",
+ "t_44_1745289354583": "اسم المستخدم",
+ "t_45_1745289355714": "طريقة التحقق",
+ "t_46_1745289355723": "تأكيد البصمة البصرية",
+ "t_47_1745289355715": "تأكيد البصمة",
+ "t_48_1745289355714": "كلمة المرور",
+ "t_49_1745289355714": "مفتاح خاص SSH",
+ "t_50_1745289355715": "الرجاء إدخال مفتاح SSH الخاص",
+ "t_51_1745289355714": "كلمة المرور الخاصة بالمفتاح الخاص",
+ "t_52_1745289359565": "إذا كانت المفتاح الخاص يحتوي على كلمة مرور، أدخلها",
+ "t_53_1745289356446": "عنوان واجهة بوتا",
+ "t_54_1745289358683": "من فضلك أدخل عنوان لوحة بوتا، مثل: https://bt.example.com",
+ "t_55_1745289355715": "مفتاح API",
+ "t_56_1745289355714": "عنوان اللوحة 1",
+ "t_57_1745289358341": "ادخل عنوان 1panel، مثلًا: https://1panel.example.com",
+ "t_58_1745289355721": "ادخل معرف AccessKey",
+ "t_59_1745289356803": "من فضلك ادخل سرية مفتاح الوصول",
+ "t_60_1745289355715": "الرجاء إدخال اسم المراقبة",
+ "t_61_1745289355878": "الرجاء إدخال اسم النطاق/IP",
+ "t_62_1745289360212": "يرجى اختيار فترة التحقق",
+ "t_63_1745289354897": "5 دقائق",
+ "t_64_1745289354670": "10 دقائق",
+ "t_65_1745289354591": "15 دقيقة",
+ "t_66_1745289354655": "30 دقيقة",
+ "t_67_1745289354487": "60 دقيقة",
+ "t_68_1745289354676": "بريد إلكتروني",
+ "t_69_1745289355721": "رسالة قصيرة",
+ "t_70_1745289354904": "واتساب",
+ "t_71_1745289354583": "اسم النطاق/IP",
+ "t_72_1745289355715": "فترة التحقق",
+ "t_73_1745289356103": "يرجى اختيار قناة التحذير",
+ "t_0_1745289808449": "الرجاء إدخال اسم API المصرح به",
+ "t_0_1745294710530": "حذف المراقبة",
+ "t_0_1745295228865": "زمن التحديث",
+ "t_0_1745317313835": "تنسيق عنوان IP للخادم غير صحيح",
+ "t_1_1745317313096": "خطأ في تنسيق المنفذ",
+ "t_2_1745317314362": "خطأ في صيغة عنوان URL للوحة",
+ "t_3_1745317313561": "الرجاء إدخال مفتاح API لوحة التحكم",
+ "t_4_1745317314054": "الرجاء إدخال AccessKeyId لـ Aliyun",
+ "t_5_1745317315285": "الرجاء إدخال AccessKeySecret لـ Aliyun",
+ "t_6_1745317313383": "الرجاء إدخال SecretId لتencent cloud",
+ "t_7_1745317313831": "من فضلك أدخل SecretKey Tencent Cloud",
+ "t_0_1745457486299": "ممكّن",
+ "t_1_1745457484314": "توقف",
+ "t_2_1745457488661": "التبديل إلى الوضع اليدوي",
+ "t_3_1745457486983": "التبديل إلى الوضع التلقائي",
+ "t_4_1745457497303": "بعد التبديل إلى الوضع اليدوي، لن يتم تنفيذ سير العمل تلقائيًا، ولكن لا يزال يمكن تنفيذه يدويًا",
+ "t_5_1745457494695": "بعد التبديل إلى الوضع التلقائي، سيعمل سير العمل تلقائيًا وفقًا للوقت المحدد",
+ "t_6_1745457487560": "إغلاق سير العمل الحالي",
+ "t_7_1745457487185": "تمكين سير العمل الحالي",
+ "t_8_1745457496621": "بعد الإغلاق، لن يتم تنفيذ سير العمل تلقائيًا ولن يمكن تنفيذه يدويًا. هل تريد المتابعة؟",
+ "t_9_1745457500045": "بعد التمكين، سيتم تنفيذ تكوين سير العمل تلقائيًا أو يدويًا. متابعة؟",
+ "t_10_1745457486451": "فشل إضافة سير العمل",
+ "t_11_1745457488256": "فشل في تعيين طريقة تنفيذ سير العمل",
+ "t_12_1745457489076": "تمكين أو تعطيل فشل سير العمل",
+ "t_13_1745457487555": "فشل تنفيذ سير العمل",
+ "t_14_1745457488092": "فشل في حذف سير العمل",
+ "t_15_1745457484292": "خروج",
+ "t_16_1745457491607": "أنت على وشك تسجيل الخروج. هل أنت متأكد أنك تريد الخروج؟",
+ "t_17_1745457488251": "جاري تسجيل الخروج، يرجى الانتظار...",
+ "t_18_1745457490931": "إضافة إشعار عبر البريد الإلكتروني",
+ "t_19_1745457484684": "تم الحفظ بنجاح",
+ "t_20_1745457485905": "تم الحذف بنجاح",
+ "t_0_1745464080226": "فشل الحصول على إعدادات النظام",
+ "t_1_1745464079590": "فشل حفظ الإعدادات",
+ "t_2_1745464077081": "فشل الحصول على إعدادات الإشعار",
+ "t_3_1745464081058": "فشل حفظ إعدادات الإشعار",
+ "t_4_1745464075382": "فشل في الحصول على قائمة قنوات الإخطار",
+ "t_5_1745464086047": "فشل إضافة قناة إشعار البريد الإلكتروني",
+ "t_6_1745464075714": "فشل تحديث قناة الإشعارات",
+ "t_7_1745464073330": "فشل حذف قناة الإشعار",
+ "t_8_1745464081472": "فشل التحقق من تحديث النسخة",
+ "t_9_1745464078110": "حفظ الإعدادات",
+ "t_10_1745464073098": "الإعدادات الأساسية",
+ "t_0_1745474945127": "اختر نموذج",
+ "t_0_1745490735213": "الرجاء إدخال اسم سير العمل",
+ "t_1_1745490731990": "إعدادات",
+ "t_2_1745490735558": "يرجى إدخال البريد الإلكتروني",
+ "t_3_1745490735059": "يرجى اختيار موفر DNS",
+ "t_4_1745490735630": "الرجاء إدخال فاصل التجديد",
+ "t_5_1745490738285": "الرجاء إدخال اسم النطاق، لا يمكن أن يكون اسم النطاق فارغًا",
+ "t_6_1745490738548": "الرجاء إدخال البريد الإلكتروني، لا يمكن أن يكون البريد الإلكتروني فارغًا",
+ "t_7_1745490739917": "الرجاء اختيار موفر DNS، لا يمكن أن يكون موفر DNS فارغًا",
+ "t_8_1745490739319": "الرجاء إدخال فترة التجديد، فترة التجديد لا يمكن أن تكون فارغة",
+ "t_0_1745553910661": "خطأ في تنسيق النطاق، يُرجى إدخال النطاق الصحيح",
+ "t_1_1745553909483": "تنسيق البريد الإلكتروني غير صحيح، يرجى إدخال بريد صحيح",
+ "t_2_1745553907423": "لا يمكن أن يكون فاصل التجديد فارغًا",
+ "t_0_1745735774005": "الرجاء إدخال اسم نطاق الشهادة، أسماء نطاقات متعددة مفصولة بفواصل",
+ "t_1_1745735764953": "صندوق البريد",
+ "t_2_1745735773668": "الرجاء إدخال البريد الإلكتروني لتلقي إشعارات من سلطة الشهادات",
+ "t_3_1745735765112": "موفر DNS",
+ "t_4_1745735765372": "إضافة",
+ "t_5_1745735769112": "فترة التجديد (أيام)",
+ "t_6_1745735765205": "فترة التجديد",
+ "t_7_1745735768326": "يوم، يتم التجديد تلقائيًا عند الانتهاء",
+ "t_8_1745735765753": "تم التكوين",
+ "t_9_1745735765287": "غير مهيأ",
+ "t_10_1745735765165": "لوحة باغودة",
+ "t_11_1745735766456": "موقع لوحة باغودا",
+ "t_12_1745735765571": "لوحة 1Panel",
+ "t_13_1745735766084": "1Panel موقع إلكتروني",
+ "t_14_1745735766121": "تنسنت كلاود CDN",
+ "t_15_1745735768976": "تنسنت كلاود كوس",
+ "t_16_1745735766712": "ألي بابا كلاود CDN",
+ "t_18_1745735765638": "نوع النشر",
+ "t_19_1745735766810": "يرجى اختيار نوع النشر",
+ "t_20_1745735768764": "الرجاء إدخال مسار النشر",
+ "t_21_1745735769154": "الرجاء إدخال الأمر البادئة",
+ "t_22_1745735767366": "الرجاء إدخال الأمر اللاحق",
+ "t_23_1745735766455": "الرجاء إدخال اسم الموقع",
+ "t_24_1745735766826": "يرجى إدخال معرف الموقع",
+ "t_25_1745735766651": "الرجاء إدخال المنطقة",
+ "t_26_1745735767144": "الرجاء إدخال الحاوية",
+ "t_27_1745735764546": "الخطوة التالية",
+ "t_28_1745735766626": "اختر نوع النشر",
+ "t_29_1745735768933": "تكوين معلمات النشر",
+ "t_30_1745735764748": "وضع التشغيل",
+ "t_31_1745735767891": "وضع التشغيل غير مُهيأ",
+ "t_32_1745735767156": "دورة التشغيل غير مهيأة",
+ "t_33_1745735766532": "وقت التشغيل غير مضبوط",
+ "t_34_1745735771147": "ملف الشهادة (تنسيق PEM)",
+ "t_35_1745735781545": "الرجاء لصق محتوى ملف الشهادة، على سبيل المثال:\n-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
+ "t_36_1745735769443": "ملف المفتاح الخاص (تنسيق KEY)",
+ "t_37_1745735779980": "الصق محتوى ملف المفتاح الخاص، على سبيل المثال:\n-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
+ "t_38_1745735769521": "محتوى المفتاح الخاص للشهادة لا يمكن أن يكون فارغًا",
+ "t_39_1745735768565": "تنسيق مفتاح الشهادة الخاص غير صحيح",
+ "t_40_1745735815317": "محتوى الشهادة لا يمكن أن يكون فارغا",
+ "t_41_1745735767016": "تنسيق الشهادة غير صحيح",
+ "t_0_1745738961258": "السابق",
+ "t_1_1745738963744": "إرسال",
+ "t_2_1745738969878": "تكوين معلمات النشر، النوع يحدد تكوين المعلمة",
+ "t_0_1745744491696": "مصدر جهاز النشر",
+ "t_1_1745744495019": "الرجاء اختيار مصدر جهاز التوزيع",
+ "t_2_1745744495813": "الرجاء اختيار نوع النشر والنقر فوق التالي",
+ "t_0_1745744902975": "مصدر النشر",
+ "t_1_1745744905566": "الرجاء اختيار مصدر النشر",
+ "t_2_1745744903722": "إضافة المزيد من الأجهزة",
+ "t_0_1745748292337": "إضافة مصدر النشر",
+ "t_1_1745748290291": "مصدر الشهادة",
+ "t_2_1745748298902": "مصدر النشر للنوع الحالي فارغ، يرجى إضافة مصدر نشر أولاً",
+ "t_3_1745748298161": "لا توجد عقدة طلب في العملية الحالية، يرجى إضافة عقدة طلب أولاً",
+ "t_4_1745748290292": "إرسال المحتوى",
+ "t_0_1745765864788": "انقر لتحرير عنوان سير العمل",
+ "t_1_1745765875247": "حذف العقدة - 【{name}】",
+ "t_2_1745765875918": "العقدة الحالية تحتوي على عقد فرعية. حذفها سيؤثر على عقد أخرى. هل أنت متأكد أنك تريد الحذف؟",
+ "t_3_1745765920953": "العقدة الحالية تحتوي على بيانات التكوين، هل أنت متأكد أنك تريد حذفها؟",
+ "t_4_1745765868807": "الرجاء تحديد نوع النشر قبل المتابعة إلى الخطوة التالية",
+ "t_0_1745833934390": "يرجى اختيار النوع",
+ "t_1_1745833931535": "مضيف",
+ "t_2_1745833931404": "منفذ",
+ "t_3_1745833936770": "فشل في الحصول على بيانات نظرة عامة على الصفحة الرئيسية",
+ "t_4_1745833932780": "معلومات النسخة",
+ "t_5_1745833933241": "الإصدار الحالي",
+ "t_6_1745833933523": "طريقة التحديث",
+ "t_7_1745833933278": "أحدث إصدار",
+ "t_8_1745833933552": "سجل التغييرات",
+ "t_9_1745833935269": "رمز QR لخدمة العملاء",
+ "t_10_1745833941691": "امسح رمز QR لإضافة خدمة العملاء",
+ "t_11_1745833935261": "حساب وي تشات الرسمي",
+ "t_12_1745833943712": "امسح الكود الضوئي لمتابعة الحساب الرسمي على WeChat",
+ "t_13_1745833933630": "حول المنتج",
+ "t_14_1745833932440": "خادم SMTP",
+ "t_15_1745833940280": "الرجاء إدخال خادم SMTP",
+ "t_16_1745833933819": "منفذ SMTP",
+ "t_17_1745833935070": "الرجاء إدخال منفذ SMTP",
+ "t_18_1745833933989": "اتصال SSL/TLS",
+ "t_0_1745887835267": "الرجاء اختيار إشعار الرسالة",
+ "t_1_1745887832941": "إشعار",
+ "t_2_1745887834248": "إضافة قناة إشعار",
+ "t_3_1745887835089": "الرجاء إدخال موضوع الإشعار",
+ "t_4_1745887835265": "يرجى إدخال محتوى الإشعار",
+ "t_0_1745895057404": "تعديل إعدادات الإشعارات عبر البريد الإلكتروني",
+ "t_0_1745920566646": "موضوع الإشعار",
+ "t_1_1745920567200": "محتوى الإخطار",
+ "t_0_1745936396853": "انقر للحصول على رمز التحقق",
+ "t_0_1745999035681": "باقي {days} يوم",
+ "t_1_1745999036289": "قريباً تنتهي الصلاحية {days} يوم",
+ "t_0_1746000517848": "منتهي الصلاحية",
+ "t_0_1746001199409": "انتهت الصلاحية",
+ "t_0_1746004861782": "موفر DNS فارغ",
+ "t_1_1746004861166": "إضافة مزود DNS",
+ "t_0_1746497662220": "تحديث",
+ "t_0_1746519384035": "قيد التشغيل",
+ "t_0_1746579648713": "تفاصيل سجل التنفيذ",
+ "t_0_1746590054456": "حالة التنفيذ",
+ "t_1_1746590060448": "طريقة التشغيل",
+ "t_0_1746667592819": "جاري تقديم المعلومات، يرجى الانتظار...",
+ "t_1_1746667588689": "مفتاح",
+ "t_2_1746667592840": "عنوان URL للوحة",
+ "t_3_1746667592270": "تجاهل أخطاء شهادة SSL/TLS",
+ "t_4_1746667590873": "فشل التحقق من النموذج",
+ "t_5_1746667590676": "سير عمل جديد",
+ "t_6_1746667592831": "جارٍ تقديم الطلب، يرجى الانتظار...",
+ "t_7_1746667592468": "يرجى إدخال اسم النطاق الصحيح",
+ "t_8_1746667591924": "يرجى اختيار طريقة التحليل",
+ "t_9_1746667589516": "تحديث القائمة",
+ "t_10_1746667589575": "حرف بدل",
+ "t_11_1746667589598": "متعدد النطاقات",
+ "t_12_1746667589733": "شائع",
+ "t_13_1746667599218": "هو موفر شهادات SSL مجاني مستخدم على نطاق واسع، مناسب للمواقع الشخصية وبيئات الاختبار.",
+ "t_14_1746667590827": "عدد النطاقات المدعومة",
+ "t_15_1746667588493": "قطعة",
+ "t_16_1746667591069": "دعم أحرف البدل",
+ "t_17_1746667588785": "دعم",
+ "t_18_1746667590113": "غير مدعوم",
+ "t_19_1746667589295": "فترة الصلاحية",
+ "t_20_1746667588453": "يوم",
+ "t_21_1746667590834": "دعم البرامج الصغيرة",
+ "t_22_1746667591024": "المواقع المطبقة",
+ "t_23_1746667591989": "*.example.com، *.demo.com",
+ "t_24_1746667583520": "*.example.com",
+ "t_25_1746667590147": "example.com、demo.com",
+ "t_26_1746667594662": "www.example.com، example.com",
+ "t_27_1746667589350": "مجاني",
+ "t_28_1746667590336": "تقديم الآن",
+ "t_29_1746667589773": "عنوان المشروع",
+ "t_30_1746667591892": "الرجاء إدخال مسار ملف الشهادة",
+ "t_31_1746667593074": "الرجاء إدخال مسار ملف المفتاح الخاص",
+ "t_0_1746673515941": "موفر DNS الحالي فارغ، يرجى إضافة موفر DNS أولاً",
+ "t_0_1746676862189": "فشل إرسال إشعار الاختبار",
+ "t_1_1746676859550": "إضافة تكوين",
+ "t_2_1746676856700": "غير مدعوم بعد",
+ "t_3_1746676857930": "إشعار البريد الإلكتروني",
+ "t_4_1746676861473": "إرسال إخطارات التنبيه عبر البريد الإلكتروني",
+ "t_5_1746676856974": "إشعار DingTalk",
+ "t_6_1746676860886": "إرسال إشعارات الإنذار عبر روبوت DingTalk",
+ "t_7_1746676857191": "إشعار WeChat Work",
+ "t_8_1746676860457": "إرسال تنبيهات الإنذار عبر بوت WeCom",
+ "t_9_1746676857164": "إشعار Feishu",
+ "t_10_1746676862329": "إرسال إخطارات الإنذار عبر بوت Feishu",
+ "t_11_1746676859158": "إشعار WebHook",
+ "t_12_1746676860503": "إرسال إشعارات الإنذار عبر WebHook",
+ "t_13_1746676856842": "قناة الإخطار",
+ "t_14_1746676859019": "قنوات الإعلام المُهيأة",
+ "t_15_1746676856567": "معطل",
+ "t_16_1746676855270": "اختبار",
+ "t_0_1746677882486": "حالة التنفيذ الأخيرة",
+ "t_0_1746697487119": "اسم النطاق لا يمكن أن يكون فارغًا",
+ "t_1_1746697485188": "البريد الإلكتروني لا يمكن أن يكون فارغاً",
+ "t_2_1746697487164": "علي بابا كلاود OSS",
+ "t_0_1746754500246": "مزود الاستضافة",
+ "t_1_1746754499371": "مصدر API",
+ "t_2_1746754500270": "نوع API",
+ "t_0_1746760933542": "خطأ في الطلب",
+ "t_0_1746773350551": "مجموع {0}",
+ "t_1_1746773348701": "لم يتم التنفيذ",
+ "t_2_1746773350970": "سير العمل الآلي",
+ "t_3_1746773348798": "العدد الكلي",
+ "t_4_1746773348957": "فشل التنفيذ",
+ "t_5_1746773349141": "تنتهي قريبا",
+ "t_6_1746773349980": "مراقبة في الوقت الحقيقي",
+ "t_7_1746773349302": "كمية غير طبيعية",
+ "t_8_1746773351524": "سجلات تنفيذ سير العمل الحديثة",
+ "t_9_1746773348221": "عرض الكل",
+ "t_10_1746773351576": "لا توجد سجلات تنفيذ سير العمل",
+ "t_11_1746773349054": "إنشاء سير العمل",
+ "t_12_1746773355641": "انقر لإنشاء سير عمل آلي لتحسين الكفاءة",
+ "t_13_1746773349526": "التقدم بطلب للحصول على شهادة",
+ "t_14_1746773355081": "انقر للتقدم بطلب وإدارة شهادات SSL لضمان الأمان",
+ "t_15_1746773358151": "انقر لإعداد مراقبة الموقع وتتبع حالة التشغيل في الوقت الفعلي",
+ "t_16_1746773356568": "يمكن تكوين قناة إشعار واحدة فقط عبر البريد الإلكتروني كحد أقصى",
+ "t_17_1746773351220": "تأكيد قناة الإشعارات {0}",
+ "t_18_1746773355467": "ستبدأ قنوات الإشعار {0} في إرسال تنبيهات.",
+ "t_19_1746773352558": "قناة الإشعارات الحالية لا تدعم الاختبار",
+ "t_20_1746773356060": "يتم إرسال البريد الإلكتروني الاختباري، يرجى الانتظار...",
+ "t_21_1746773350759": "بريد إلكتروني تجريبي",
+ "t_22_1746773360711": "إرسال بريد إلكتروني اختباري إلى صندوق البريد الحالي المُهيأ، هل تتابع؟",
+ "t_23_1746773350040": "تأكيد الحذف",
+ "t_24_1746773349367": "تأكيد الحذف",
+ "t_25_1746773349596": "الرجاء إدخال الاسم",
+ "t_26_1746773353409": "الرجاء إدخال منفذ SMTP الصحيح",
+ "t_27_1746773352584": "يرجى إدخال كلمة مرور المستخدم",
+ "t_28_1746773354048": "الرجاء إدخال البريد الإلكتروني الصحيح للمرسل",
+ "t_29_1746773351834": "الرجاء إدخال البريد الإلكتروني الصحيح",
+ "t_30_1746773350013": "بريد المرسل الإلكتروني",
+ "t_31_1746773349857": "تلقي البريد الإلكتروني",
+ "t_32_1746773348993": "دينغتالک",
+ "t_33_1746773350932": "WeChat Work",
+ "t_34_1746773350153": "فيشو",
+ "t_35_1746773362992": "أداة إدارة دورة حياة شهادات SSL متكاملة تشمل التقديم، الإدارة، النشر والمراقبة.",
+ "t_36_1746773348989": "طلب الشهادة",
+ "t_37_1746773356895": "دعم الحصول على شهادات من Let's Encrypt عبر بروتوكول ACME",
+ "t_38_1746773349796": "إدارة الشهادات",
+ "t_39_1746773358932": "الإدارة المركزية لجميع شهادات SSL، بما في ذلك الشهادات المرفوعة يدويًا والمطبقة تلقائيًا",
+ "t_40_1746773352188": "نشر الشهادة",
+ "t_41_1746773364475": "دعم نشر الشهادات بنقرة واحدة على منصات متعددة مثل علي بابا كلاود، تينسنت كلاود، لوحة باغودا، 1Panel، إلخ.",
+ "t_42_1746773348768": "مراقبة الموقع",
+ "t_43_1746773359511": "مراقبة حالة شهادات SSL للموقع في الوقت الفعلي للتحذير المسبق من انتهاء صلاحية الشهادة",
+ "t_44_1746773352805": "مهمة الأتمتة:",
+ "t_45_1746773355717": "يدعم المهام المجدولة، تجديد الشهادات تلقائياً ونشرها",
+ "t_46_1746773350579": "دعم متعدد المنصات",
+ "t_47_1746773360760": "يدعم طرق التحقق DNS لعدة موفري DNS (Alibaba Cloud، Tencent Cloud، إلخ)"
+}
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/locales/model/enUS.json b/frontend/apps/allin-ssl/src/locales/model/enUS.json
new file mode 100644
index 0000000..16469e9
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/locales/model/enUS.json
@@ -0,0 +1,490 @@
+{
+ "t_0_1746773763967": "Are you sure you want to delete {0}, the notification channel?",
+ "t_1_1746773763643": "Let's Encrypt and other CAs automatically apply for free certificates",
+ "t_0_1744098811152": "Warning: You have entered an unknown area, the page you are visiting does not exist, please click the button to return to the homepage.",
+ "t_1_1744098801860": "Return Home",
+ "t_2_1744098804908": "Safety Tip: If you think this is an error, please contact the administrator immediately",
+ "t_3_1744098802647": "Expand Main Menu",
+ "t_4_1744098802046": "Foldout Main Menu",
+ "t_0_1744164843238": "Welcome to AllinSSL, Efficient SSL Certificate Management",
+ "t_1_1744164835667": "AllinSSL",
+ "t_2_1744164839713": "Account Login",
+ "t_3_1744164839524": "Please enter the username",
+ "t_4_1744164840458": "Please enter the password",
+ "t_5_1744164840468": "Remember Password",
+ "t_6_1744164838900": "Forget password",
+ "t_7_1744164838625": "Logging in",
+ "t_8_1744164839833": "Login",
+ "t_0_1744168657526": "Log out",
+ "t_0_1744258111441": "Home",
+ "t_1_1744258113857": "Automation Deployment",
+ "t_2_1744258111238": "Certificate Management",
+ "t_3_1744258111182": "Certificate Application",
+ "t_4_1744258111238": "Authorization API Management",
+ "t_5_1744258110516": "Monitoring",
+ "t_6_1744258111153": "Settings",
+ "t_0_1744861190562": "Return workflow list",
+ "t_1_1744861189113": "Run",
+ "t_2_1744861190040": "Save",
+ "t_3_1744861190932": "Please select a node to configure",
+ "t_4_1744861194395": "Click on the node in the left-side workflow diagram to configure it",
+ "t_5_1744861189528": "Start",
+ "t_6_1744861190121": "No node selected",
+ "t_7_1744861189625": "Configuration saved",
+ "t_8_1744861189821": "Start the workflow",
+ "t_9_1744861189580": "Selected node:",
+ "t_0_1744870861464": "Node",
+ "t_1_1744870861944": "Node Configuration",
+ "t_2_1744870863419": "Please select the left node for configuration",
+ "t_3_1744870864615": "Configuration component for this node type not found",
+ "t_4_1744870861589": "Cancel",
+ "t_5_1744870862719": "Confirm",
+ "t_0_1744875938285": "Every minute",
+ "t_1_1744875938598": "Each hour",
+ "t_2_1744875938555": "Every day",
+ "t_3_1744875938310": "Each month",
+ "t_4_1744875940750": "Automatic execution",
+ "t_5_1744875940010": "Manual execution",
+ "t_0_1744879616135": "Test PID",
+ "t_1_1744879616555": "Please enter the test PID",
+ "t_2_1744879616413": "Execution cycle",
+ "t_3_1744879615723": "minute",
+ "t_4_1744879616168": "Please enter minutes",
+ "t_5_1744879615277": "hour",
+ "t_6_1744879616944": "Please enter hours",
+ "t_7_1744879615743": "Date",
+ "t_8_1744879616493": "Please select a date",
+ "t_0_1744942117992": "Every week",
+ "t_1_1744942116527": "Monday",
+ "t_2_1744942117890": "Tuesday",
+ "t_3_1744942117885": "Wednesday",
+ "t_4_1744942117738": "Thursday",
+ "t_5_1744942117167": "Friday",
+ "t_6_1744942117815": "Saturday",
+ "t_7_1744942117862": "Sunday",
+ "t_0_1744958839535": "Please enter the domain name",
+ "t_1_1744958840747": "Please enter your email",
+ "t_2_1744958840131": "Email format is incorrect",
+ "t_3_1744958840485": "Please select DNS provider authorization",
+ "t_4_1744958838951": "Local Deployment",
+ "t_5_1744958839222": "SSH Deployment",
+ "t_6_1744958843569": "Bao Ta Panel/1 panel (Deploy to panel certificate)",
+ "t_7_1744958841708": "1panel (Deploy to specified website project)",
+ "t_8_1744958841658": "Tencent Cloud CDN/Aliyun CDN",
+ "t_9_1744958840634": "Tencent Cloud WAF",
+ "t_10_1744958860078": "Alicloud WAF",
+ "t_11_1744958840439": "This automatically applied certificate",
+ "t_12_1744958840387": "Optional certificate list",
+ "t_13_1744958840714": "PEM (*.pem, *.crt, *.key)",
+ "t_14_1744958839470": "PFX (*.pfx)",
+ "t_15_1744958840790": "JKS (*.jks)",
+ "t_16_1744958841116": "POSIX bash (Linux/macOS)",
+ "t_17_1744958839597": "CMD (Windows)",
+ "t_18_1744958839895": "PowerShell (Windows)",
+ "t_19_1744958839297": "Certificate 1",
+ "t_20_1744958839439": "Certificate 2",
+ "t_21_1744958839305": "Server 1",
+ "t_22_1744958841926": "Server 2",
+ "t_23_1744958838717": "Panel 1",
+ "t_24_1744958845324": "Panel 2",
+ "t_25_1744958839236": "Website 1",
+ "t_26_1744958839682": "Website 2",
+ "t_27_1744958840234": "Tencent Cloud 1",
+ "t_28_1744958839760": "Aliyun 1",
+ "t_29_1744958838904": "Day",
+ "t_30_1744958843864": "Certificate format is incorrect, please check if it includes the complete certificate header and footer identifiers",
+ "t_31_1744958844490": "Private key format is incorrect, please check if it includes the complete private key header and footer identifier",
+ "t_0_1745215914686": "Automation Name",
+ "t_2_1745215915397": "Automatic",
+ "t_3_1745215914237": "Manual",
+ "t_4_1745215914951": "Enabled Status",
+ "t_5_1745215914671": "Enable",
+ "t_6_1745215914104": "Disabling",
+ "t_7_1745215914189": "Creation Time",
+ "t_8_1745215914610": "Operation",
+ "t_9_1745215914666": "Execution History",
+ "t_10_1745215914342": "Execute",
+ "t_11_1745215915429": "Edit",
+ "t_12_1745215914312": "Delete",
+ "t_13_1745215915455": "Execute workflow",
+ "t_14_1745215916235": "Workflow executed successfully",
+ "t_15_1745215915743": "Workflow execution failed",
+ "t_16_1745215915209": "Delete Workflow",
+ "t_17_1745215915985": "Workflow deletion successful",
+ "t_18_1745215915630": "Workflow deletion failed",
+ "t_0_1745227838699": "New Automated Deployment",
+ "t_1_1745227838776": "Please enter the automation name",
+ "t_2_1745227839794": "Are you sure you want to execute the {name} workflow?",
+ "t_3_1745227841567": "Confirm deletion of {name} workflow? This action cannot be undone.",
+ "t_4_1745227838558": "Execution Time",
+ "t_5_1745227839906": "End time",
+ "t_6_1745227838798": "Execution method",
+ "t_7_1745227838093": "Status",
+ "t_8_1745227838023": "Success",
+ "t_9_1745227838305": "Failure",
+ "t_10_1745227838234": "In progress",
+ "t_11_1745227838422": "Unknown",
+ "t_12_1745227838814": "Details",
+ "t_13_1745227838275": "Upload Certificate",
+ "t_14_1745227840904": "Please enter the certificate domain name or brand name to search",
+ "t_15_1745227839354": "Together",
+ "t_16_1745227838930": "strip",
+ "t_17_1745227838561": "Domain name",
+ "t_18_1745227838154": "Brand",
+ "t_19_1745227839107": "Remaining days",
+ "t_20_1745227838813": "Expiry Time",
+ "t_21_1745227837972": "Source",
+ "t_22_1745227838154": "Automatic Application",
+ "t_23_1745227838699": "Manual upload",
+ "t_24_1745227839508": "Add Time",
+ "t_25_1745227838080": "Download",
+ "t_27_1745227838583": "About to expire",
+ "t_28_1745227837903": "Normal",
+ "t_29_1745227838410": "Delete certificate",
+ "t_30_1745227841739": "Are you sure you want to delete this certificate? This action cannot be undone.",
+ "t_31_1745227838461": "Confirm",
+ "t_32_1745227838439": "Certificate Name",
+ "t_33_1745227838984": "Please enter the certificate name",
+ "t_34_1745227839375": "Certificate Content (PEM)",
+ "t_35_1745227839208": "Please enter the certificate content",
+ "t_36_1745227838958": "Private key content (KEY)",
+ "t_37_1745227839669": "Please enter the private key content",
+ "t_38_1745227838813": "Download failed",
+ "t_39_1745227838696": "Upload failed",
+ "t_40_1745227838872": "Delete failed",
+ "t_0_1745289355714": "Add Authorization API",
+ "t_1_1745289356586": "Please enter the authorized API name or type",
+ "t_2_1745289353944": "Name",
+ "t_3_1745289354664": "Authorization API Type",
+ "t_4_1745289354902": "Edit Authorization API",
+ "t_5_1745289355718": "Delete Authorization API",
+ "t_6_1745289358340": "Are you sure you want to delete this authorized API? This action cannot be undone.",
+ "t_7_1745289355714": "Add failed",
+ "t_8_1745289354902": "Update failed",
+ "t_9_1745289355714": "Expired {days} days",
+ "t_10_1745289354650": "Monitoring Management",
+ "t_11_1745289354516": "Add Monitoring",
+ "t_12_1745289356974": "Please enter the monitoring name or domain to search",
+ "t_13_1745289354528": "Monitor Name",
+ "t_14_1745289354902": "Certificate Domain",
+ "t_15_1745289355714": "Certificate Authority",
+ "t_16_1745289354902": "Certificate Status",
+ "t_17_1745289355715": "Certificate Expiration Date",
+ "t_18_1745289354598": "Alert Channels",
+ "t_19_1745289354676": "Last Check Time",
+ "t_20_1745289354598": "Edit Monitoring",
+ "t_21_1745289354598": "Confirm Delete",
+ "t_22_1745289359036": "Items cannot be restored after deletion. Are you sure you want to delete this monitor?",
+ "t_23_1745289355716": "Modification failed",
+ "t_24_1745289355715": "Setup Failed",
+ "t_25_1745289355721": "Please enter the verification code",
+ "t_26_1745289358341": "Form validation failed, please check the filled content",
+ "t_27_1745289355721": "Please enter the authorized API name",
+ "t_28_1745289356040": "Please select the authorization API type",
+ "t_29_1745289355850": "Please enter the server IP",
+ "t_30_1745289355718": "Please enter the SSH port",
+ "t_31_1745289355715": "Please enter the SSH key",
+ "t_32_1745289356127": "Please enter the Baota address",
+ "t_33_1745289355721": "Please enter the API key",
+ "t_34_1745289356040": "Please enter the 1panel address",
+ "t_35_1745289355714": "Please enter AccessKeyId",
+ "t_36_1745289355715": "Please enter AccessKeySecret",
+ "t_37_1745289356041": "Please enter SecretId",
+ "t_38_1745289356419": "Please enter SecretKey",
+ "t_39_1745289354902": "Update successful",
+ "t_40_1745289355715": "Addition Successful",
+ "t_41_1745289354902": "Type",
+ "t_42_1745289355715": "Server IP",
+ "t_43_1745289354598": "SSH port",
+ "t_44_1745289354583": "Username",
+ "t_45_1745289355714": "Authentication method",
+ "t_46_1745289355723": "Password authentication",
+ "t_47_1745289355715": "Key authentication",
+ "t_48_1745289355714": "Password",
+ "t_49_1745289355714": "SSH private key",
+ "t_50_1745289355715": "Please enter the SSH private key",
+ "t_51_1745289355714": "Private key password",
+ "t_52_1745289359565": "If the private key has a password, please enter",
+ "t_53_1745289356446": "BaoTa Panel Address",
+ "t_54_1745289358683": "Please enter the Baota panel address, for example: https://bt.example.com",
+ "t_55_1745289355715": "API Key",
+ "t_56_1745289355714": "1 panel address",
+ "t_57_1745289358341": "Please enter the 1panel address, for example: https://1panel.example.com",
+ "t_58_1745289355721": "Please enter the AccessKey ID",
+ "t_59_1745289356803": "Please input AccessKey Secret",
+ "t_60_1745289355715": "Please enter the monitoring name",
+ "t_61_1745289355878": "Please enter the domain/IP",
+ "t_62_1745289360212": "Please select the inspection cycle",
+ "t_63_1745289354897": "5 minutes",
+ "t_64_1745289354670": "10 minutes",
+ "t_65_1745289354591": "15 minutes",
+ "t_66_1745289354655": "30 minutes",
+ "t_67_1745289354487": "60 minutes",
+ "t_68_1745289354676": "Email",
+ "t_69_1745289355721": "SMS",
+ "t_70_1745289354904": "WeChat",
+ "t_71_1745289354583": "Domain/IP",
+ "t_72_1745289355715": "Inspection cycle",
+ "t_73_1745289356103": "Please select an alert channel",
+ "t_0_1745289808449": "Please enter the authorized API name",
+ "t_0_1745294710530": "Delete monitoring",
+ "t_0_1745295228865": "Update Time",
+ "t_0_1745317313835": "Server IP address format error",
+ "t_1_1745317313096": "Port format error",
+ "t_2_1745317314362": "Panel URL address format error",
+ "t_3_1745317313561": "Please enter the panel API key",
+ "t_4_1745317314054": "Please enter the Aliyun AccessKeyId",
+ "t_5_1745317315285": "Please input the Aliyun AccessKeySecret",
+ "t_6_1745317313383": "Please enter the Tencent Cloud SecretId",
+ "t_7_1745317313831": "Please enter the Tencent Cloud SecretKey",
+ "t_0_1745457486299": "Enabled",
+ "t_1_1745457484314": "Stopped",
+ "t_2_1745457488661": "Switch to manual mode",
+ "t_3_1745457486983": "Switch to automatic mode",
+ "t_4_1745457497303": "After switching to manual mode, the workflow will no longer be executed automatically, but can still be executed manually",
+ "t_5_1745457494695": "After switching to automatic mode, the workflow will automatically execute according to the configured time",
+ "t_6_1745457487560": "Close current workflow",
+ "t_7_1745457487185": "Enable current workflow",
+ "t_8_1745457496621": "After closing, the workflow will no longer execute automatically and cannot be executed manually. Continue?",
+ "t_9_1745457500045": "After enabling, the workflow configuration will execute automatically or manually. Continue?",
+ "t_10_1745457486451": "Failed to add workflow",
+ "t_11_1745457488256": "Failed to set workflow execution method",
+ "t_12_1745457489076": "Enable or disable workflow failure",
+ "t_13_1745457487555": "Failed to execute workflow",
+ "t_14_1745457488092": "Failed to delete workflow",
+ "t_15_1745457484292": "Exit",
+ "t_16_1745457491607": "You are about to log out. Are you sure you want to exit?",
+ "t_17_1745457488251": "Logging out, please wait...",
+ "t_18_1745457490931": "Add email notification",
+ "t_19_1745457484684": "Saved successfully",
+ "t_20_1745457485905": "Deleted successfully",
+ "t_0_1745464080226": "Failed to get system settings",
+ "t_1_1745464079590": "Failed to save settings",
+ "t_2_1745464077081": "Failed to get notification settings",
+ "t_3_1745464081058": "Failed to save notification settings",
+ "t_4_1745464075382": "Failed to get notification channel list",
+ "t_5_1745464086047": "Failed to add email notification channel",
+ "t_6_1745464075714": "Failed to update notification channel",
+ "t_7_1745464073330": "Failed to delete notification channel",
+ "t_8_1745464081472": "Failed to check for version update",
+ "t_9_1745464078110": "Save settings",
+ "t_10_1745464073098": "Basic Settings",
+ "t_0_1745474945127": "Choose template",
+ "t_0_1745490735213": "Please enter the workflow name",
+ "t_1_1745490731990": "Configuration",
+ "t_2_1745490735558": "Please enter the email format",
+ "t_3_1745490735059": "Please select a DNS provider",
+ "t_4_1745490735630": "Please enter the renewal interval",
+ "t_5_1745490738285": "Please enter the domain name, the domain name cannot be empty",
+ "t_6_1745490738548": "Please enter your email, email cannot be empty",
+ "t_7_1745490739917": "Please select a DNS provider, the DNS provider cannot be empty",
+ "t_8_1745490739319": "Please enter the renewal interval, the renewal interval cannot be empty",
+ "t_0_1745553910661": "Domain format error, please enter the correct domain",
+ "t_1_1745553909483": "Invalid email format, please enter a correct email",
+ "t_2_1745553907423": "Renewal interval cannot be empty",
+ "t_0_1745735774005": "Please enter the certificate domain name, multiple domain names separated by commas",
+ "t_1_1745735764953": "Mailbox",
+ "t_2_1745735773668": "Please enter your email to receive notifications from the certificate authority",
+ "t_3_1745735765112": "DNS provider",
+ "t_4_1745735765372": "Add",
+ "t_5_1745735769112": "Renewal Interval (Days)",
+ "t_6_1745735765205": "Renewal interval",
+ "t_7_1745735768326": "day, automatically renewed upon expiration",
+ "t_8_1745735765753": "Configured",
+ "t_9_1745735765287": "Not configured",
+ "t_10_1745735765165": "Pagoda Panel",
+ "t_11_1745735766456": "Pagoda Panel Website",
+ "t_12_1745735765571": "1Panel",
+ "t_13_1745735766084": "1Panel website",
+ "t_14_1745735766121": "Tencent Cloud CDN",
+ "t_15_1745735768976": "Tencent Cloud COS",
+ "t_16_1745735766712": "Alibaba Cloud CDN",
+ "t_18_1745735765638": "Deployment Type",
+ "t_19_1745735766810": "Please select deployment type",
+ "t_20_1745735768764": "Please enter the deployment path",
+ "t_21_1745735769154": "Please enter the prefix command",
+ "t_22_1745735767366": "Please enter the post command",
+ "t_23_1745735766455": "Please enter the site name",
+ "t_24_1745735766826": "Please enter the site ID",
+ "t_25_1745735766651": "Please enter the region",
+ "t_26_1745735767144": "Please enter the bucket",
+ "t_27_1745735764546": "Next step",
+ "t_28_1745735766626": "Select deployment type",
+ "t_29_1745735768933": "Configure deployment parameters",
+ "t_30_1745735764748": "Operation mode",
+ "t_31_1745735767891": "Operation mode not configured",
+ "t_32_1745735767156": "Running cycle not configured",
+ "t_33_1745735766532": "Runtime not configured",
+ "t_34_1745735771147": "Certificate file (PEM format)",
+ "t_35_1745735781545": "Please paste the certificate file content, for example:\n-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
+ "t_36_1745735769443": "Private key file (KEY format)",
+ "t_37_1745735779980": "Please paste the private key file content, for example:\n-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
+ "t_38_1745735769521": "Certificate private key content cannot be empty",
+ "t_39_1745735768565": "The format of the certificate private key is incorrect",
+ "t_40_1745735815317": "Certificate content cannot be empty",
+ "t_41_1745735767016": "Certificate format is incorrect",
+ "t_0_1745738961258": "Previous",
+ "t_1_1745738963744": "Submit",
+ "t_2_1745738969878": "Configure deployment parameters, the type determines the parameter configuration",
+ "t_0_1745744491696": "Deployment device source",
+ "t_1_1745744495019": "Please select the deployment device source",
+ "t_2_1745744495813": "Please select the deployment type and click Next",
+ "t_0_1745744902975": "Deployment source",
+ "t_1_1745744905566": "Please select deployment source",
+ "t_2_1745744903722": "Add more devices",
+ "t_0_1745748292337": "Add deployment source",
+ "t_1_1745748290291": "Certificate Source",
+ "t_2_1745748298902": "The current type deployment source is empty, please add a deployment source first",
+ "t_3_1745748298161": "There is no application node in the current process, please add an application node first",
+ "t_4_1745748290292": "Submit content",
+ "t_0_1745765864788": "Click to edit workflow title",
+ "t_1_1745765875247": "Delete Node - 【{name}】",
+ "t_2_1745765875918": "The current node has child nodes. Deleting it will affect other nodes. Are you sure you want to delete it?",
+ "t_3_1745765920953": "The current node has configuration data, are you sure you want to delete it?",
+ "t_4_1745765868807": "Please select the deployment type before proceeding to the next step",
+ "t_0_1745833934390": "Please select type",
+ "t_1_1745833931535": "Host",
+ "t_2_1745833931404": "port",
+ "t_3_1745833936770": "Failed to get homepage overview data",
+ "t_4_1745833932780": "Version information",
+ "t_5_1745833933241": "Current version",
+ "t_6_1745833933523": "Update method",
+ "t_7_1745833933278": "Latest version",
+ "t_8_1745833933552": "Changelog",
+ "t_9_1745833935269": "Customer Service QR Code",
+ "t_10_1745833941691": "Scan the QR code to add customer service",
+ "t_11_1745833935261": "WeChat Official Account",
+ "t_12_1745833943712": "Scan to follow the WeChat official account",
+ "t_13_1745833933630": "About the product",
+ "t_14_1745833932440": "SMTP server",
+ "t_15_1745833940280": "Please enter the SMTP server",
+ "t_16_1745833933819": "SMTP port",
+ "t_17_1745833935070": "Please enter the SMTP port",
+ "t_18_1745833933989": "SSL/TLS connection",
+ "t_0_1745887835267": "Please select message notification",
+ "t_1_1745887832941": "Notification",
+ "t_2_1745887834248": "Add notification channel",
+ "t_3_1745887835089": "Please enter the notification subject",
+ "t_4_1745887835265": "Please enter the notification content",
+ "t_0_1745895057404": "Modify email notification settings",
+ "t_0_1745920566646": "Notification Subject",
+ "t_1_1745920567200": "Notification content",
+ "t_0_1745936396853": "Click to get verification code",
+ "t_0_1745999035681": "remaining {days} days",
+ "t_1_1745999036289": "Expiring soon {days} days",
+ "t_0_1746000517848": "Expired",
+ "t_0_1746001199409": "Expired",
+ "t_0_1746004861782": "DNS provider is empty",
+ "t_1_1746004861166": "Add DNS provider",
+ "t_0_1746497662220": "Refresh",
+ "t_0_1746519384035": "Running",
+ "t_0_1746579648713": "Execution History Details",
+ "t_0_1746590054456": "Execution status",
+ "t_1_1746590060448": "Trigger Method",
+ "t_0_1746667592819": "Submitting information, please wait...",
+ "t_1_1746667588689": "Key",
+ "t_2_1746667592840": "Panel URL",
+ "t_3_1746667592270": "Ignore SSL/TLS certificate errors",
+ "t_4_1746667590873": "Form validation failed",
+ "t_5_1746667590676": "New workflow",
+ "t_6_1746667592831": "Submitting application, please wait...",
+ "t_7_1746667592468": "Please enter the correct domain name",
+ "t_8_1746667591924": "Please select the parsing method",
+ "t_9_1746667589516": "Refresh list",
+ "t_10_1746667589575": "Wildcard",
+ "t_11_1746667589598": "Multi-domain",
+ "t_12_1746667589733": "Popular",
+ "t_13_1746667599218": "is a widely used free SSL certificate provider, suitable for personal websites and testing environments.",
+ "t_14_1746667590827": "Number of supported domains",
+ "t_15_1746667588493": "piece",
+ "t_16_1746667591069": "Support wildcards",
+ "t_17_1746667588785": "support",
+ "t_18_1746667590113": "Not supported",
+ "t_19_1746667589295": "Validity period",
+ "t_20_1746667588453": "Day",
+ "t_21_1746667590834": "Support Mini Program",
+ "t_22_1746667591024": "Applicable websites",
+ "t_23_1746667591989": "*.example.com, *.demo.com",
+ "t_24_1746667583520": "*.example.com",
+ "t_25_1746667590147": "example.com、demo.com",
+ "t_26_1746667594662": "www.example.com, example.com",
+ "t_27_1746667589350": "Free",
+ "t_28_1746667590336": "Apply Now",
+ "t_29_1746667589773": "Project address",
+ "t_30_1746667591892": "Please enter the certificate file path",
+ "t_31_1746667593074": "Please enter the private key file path",
+ "t_0_1746673515941": "The current DNS provider is empty, please add a DNS provider first",
+ "t_0_1746676862189": "Test notification sending failed",
+ "t_1_1746676859550": "Add Configuration",
+ "t_2_1746676856700": "Not supported yet",
+ "t_3_1746676857930": "Email notification",
+ "t_4_1746676861473": "Send alert notifications via email",
+ "t_5_1746676856974": "DingTalk Notification",
+ "t_6_1746676860886": "Send alarm notifications via DingTalk robot",
+ "t_7_1746676857191": "WeChat Work Notification",
+ "t_8_1746676860457": "Send alarm notifications via WeCom bot",
+ "t_9_1746676857164": "Feishu Notification",
+ "t_10_1746676862329": "Send alarm notifications via Feishu bot",
+ "t_11_1746676859158": "WebHook Notification",
+ "t_12_1746676860503": "Send alarm notifications via WebHook",
+ "t_13_1746676856842": "Notification channel",
+ "t_14_1746676859019": "Configured notification channels",
+ "t_15_1746676856567": "Disabled",
+ "t_16_1746676855270": "Test",
+ "t_0_1746677882486": "Last execution status",
+ "t_0_1746697487119": "Domain name cannot be empty",
+ "t_1_1746697485188": "Email cannot be empty",
+ "t_2_1746697487164": "Alibaba Cloud OSS",
+ "t_0_1746754500246": "Hosting Provider",
+ "t_1_1746754499371": "API Source",
+ "t_2_1746754500270": "API type",
+ "t_0_1746760933542": "Request error",
+ "t_0_1746773350551": "{0} results",
+ "t_1_1746773348701": "Not executed",
+ "t_2_1746773350970": "Automated workflow",
+ "t_3_1746773348798": "Total quantity",
+ "t_4_1746773348957": "Execution failed",
+ "t_5_1746773349141": "Expiring soon",
+ "t_6_1746773349980": "Real-time monitoring",
+ "t_7_1746773349302": "Abnormal quantity",
+ "t_8_1746773351524": "Recent workflow execution records",
+ "t_9_1746773348221": "View all",
+ "t_10_1746773351576": "No workflow execution records",
+ "t_11_1746773349054": "Create workflow",
+ "t_12_1746773355641": "Click to create an automated workflow to improve efficiency",
+ "t_13_1746773349526": "Apply for certificate",
+ "t_14_1746773355081": "Click to apply for and manage SSL certificates to ensure security",
+ "t_15_1746773358151": "Click to set up website monitoring and keep track of the runtime status in real time",
+ "t_16_1746773356568": "Only one email notification channel can be configured at most",
+ "t_17_1746773351220": "Confirm {0} notification channel",
+ "t_18_1746773355467": "{0} notification channels will start sending alert notifications.",
+ "t_19_1746773352558": "The current notification channel does not support testing",
+ "t_20_1746773356060": "Sending test email, please wait...",
+ "t_21_1746773350759": "Test email",
+ "t_22_1746773360711": "Send a test email to the currently configured mailbox, continue?",
+ "t_23_1746773350040": "Delete Confirmation",
+ "t_24_1746773349367": "Confirm to delete",
+ "t_25_1746773349596": "Please enter name",
+ "t_26_1746773353409": "Please enter the correct SMTP port",
+ "t_27_1746773352584": "Please enter user password",
+ "t_28_1746773354048": "Please enter the correct sender email",
+ "t_29_1746773351834": "Please enter the correct receiving email",
+ "t_30_1746773350013": "Sender's email",
+ "t_31_1746773349857": "Receive Email",
+ "t_32_1746773348993": "DingTalk",
+ "t_33_1746773350932": "WeChat Work",
+ "t_34_1746773350153": "Feishu",
+ "t_35_1746773362992": "A comprehensive SSL certificate lifecycle management tool that integrates application, management, deployment, and monitoring.",
+ "t_36_1746773348989": "Certificate Application",
+ "t_37_1746773356895": "Support obtaining certificates from Let's Encrypt via ACME protocol",
+ "t_38_1746773349796": "Certificate Management",
+ "t_39_1746773358932": "Centralized management of all SSL certificates, including manually uploaded and automatically applied certificates",
+ "t_40_1746773352188": "Certificate deployment",
+ "t_41_1746773364475": "Support one-click certificate deployment to multiple platforms such as Alibaba Cloud, Tencent Cloud, Pagoda Panel, 1Panel, etc.",
+ "t_42_1746773348768": "Site monitoring",
+ "t_43_1746773359511": "Real-time monitoring of site SSL certificate status to provide early warning of certificate expiration",
+ "t_44_1746773352805": "Automation task:",
+ "t_45_1746773355717": "Support scheduled tasks, automatically renew certificates and deploy",
+ "t_46_1746773350579": "Multi-platform support",
+ "t_47_1746773360760": "Supports DNS verification methods for multiple DNS providers (Alibaba Cloud, Tencent Cloud, etc.)"
+}
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/locales/model/esAR.json b/frontend/apps/allin-ssl/src/locales/model/esAR.json
new file mode 100644
index 0000000..5ab64f3
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/locales/model/esAR.json
@@ -0,0 +1,490 @@
+{
+ "t_0_1746773763967": "¿Estás seguro de que deseas eliminar {0}, el canal de notificaciones?",
+ "t_1_1746773763643": "Let's Encrypt y otras CA solicitan automáticamente certificados gratuitos",
+ "t_0_1744098811152": "Advertencia: Ha ingresado a una zona desconocida, la página que intenta visitar no existe, por favor, haga clic en el botón para regresar a la página de inicio.",
+ "t_1_1744098801860": "Volver al inicio",
+ "t_2_1744098804908": "Consejo de seguridad: Si piensa que es un error, póngase en contacto con el administrador inmediatamente",
+ "t_3_1744098802647": "Expandir el menú principal",
+ "t_4_1744098802046": "Menú principal plegable",
+ "t_0_1744164843238": "Bienvenido a AllinSSL, gestión eficiente de certificados SSL",
+ "t_1_1744164835667": "AllinSSL",
+ "t_2_1744164839713": "Iniciar sesión en la cuenta",
+ "t_3_1744164839524": "Por favor, ingrese el nombre de usuario",
+ "t_4_1744164840458": "Por favor, ingrese la contraseña",
+ "t_5_1744164840468": "Recordar contraseña",
+ "t_6_1744164838900": "¿Olvidaste tu contraseña?",
+ "t_7_1744164838625": "Logueándose",
+ "t_8_1744164839833": "Iniciar sesión",
+ "t_0_1744168657526": "Salir",
+ "t_0_1744258111441": "Inicio",
+ "t_1_1744258113857": "Despliegue Automatizado",
+ "t_2_1744258111238": "Gestión de certificados",
+ "t_3_1744258111182": "Solicitud de certificado",
+ "t_4_1744258111238": "Gestión de API de autorización",
+ "t_5_1744258110516": "Monitoreo",
+ "t_6_1744258111153": "Ajustes",
+ "t_0_1744861190562": "Retornar lista de flujos de trabajo",
+ "t_1_1744861189113": "Ejecutar",
+ "t_2_1744861190040": "Guardar",
+ "t_3_1744861190932": "Seleccione un nodo para configurar",
+ "t_4_1744861194395": "Haga clic en el nodo del diagrama de flujo en la parte izquierda para configurarlo",
+ "t_5_1744861189528": "comenzar",
+ "t_6_1744861190121": "Nodo no seleccionado",
+ "t_7_1744861189625": "Configuración guardada",
+ "t_8_1744861189821": "Iniciar flujo de trabajo",
+ "t_9_1744861189580": "Nodo seleccionado:",
+ "t_0_1744870861464": "nodo",
+ "t_1_1744870861944": "Configuración de nodo",
+ "t_2_1744870863419": "Seleccione el nodo izquierdo para la configuración",
+ "t_3_1744870864615": "No se encontró el componente de configuración para este tipo de nodo",
+ "t_4_1744870861589": "Cancelar",
+ "t_5_1744870862719": "confirmar",
+ "t_0_1744875938285": "cada minuto",
+ "t_1_1744875938598": "cada hora",
+ "t_2_1744875938555": "cada día",
+ "t_3_1744875938310": "cada mes",
+ "t_4_1744875940750": "Ejecución automática",
+ "t_5_1744875940010": "Ejecución manual",
+ "t_0_1744879616135": "Test PID",
+ "t_1_1744879616555": "Por favor, ingrese el PID de prueba",
+ "t_2_1744879616413": "Período de ejecución",
+ "t_3_1744879615723": "minuto",
+ "t_4_1744879616168": "Por favor, ingrese minutos",
+ "t_5_1744879615277": "hora",
+ "t_6_1744879616944": "Por favor, introduzca las horas",
+ "t_7_1744879615743": "Fecha",
+ "t_8_1744879616493": "Seleccione una fecha",
+ "t_0_1744942117992": "cada semana",
+ "t_1_1744942116527": "lunes",
+ "t_2_1744942117890": "martes",
+ "t_3_1744942117885": "Miércoles",
+ "t_4_1744942117738": "jueves",
+ "t_5_1744942117167": "viernes",
+ "t_6_1744942117815": "sábado",
+ "t_7_1744942117862": "domingo",
+ "t_0_1744958839535": "Por favor, ingrese el nombre de dominio",
+ "t_1_1744958840747": "Por favor, ingrese su correo electrónico",
+ "t_2_1744958840131": "El formato del correo electrónico es incorrecto",
+ "t_3_1744958840485": "Seleccione el proveedor de DNS para la autorización",
+ "t_4_1744958838951": "Despliegue local",
+ "t_5_1744958839222": "Despliegue SSH",
+ "t_6_1744958843569": "Panel Bao Ta/1 panel (Desplegar en el certificado del panel)",
+ "t_7_1744958841708": "1pantalla (Despliegue al proyecto de sitio específico)",
+ "t_8_1744958841658": "Tencent Cloud CDN/AliCloud CDN",
+ "t_9_1744958840634": "WAF de Tencent Cloud",
+ "t_10_1744958860078": "WAF de AliCloud",
+ "t_11_1744958840439": "Este certificado aplicado automáticamente",
+ "t_12_1744958840387": "Lista de certificados opcionales",
+ "t_13_1744958840714": "PEM (*.pem, *.crt, *.key)",
+ "t_14_1744958839470": "PFX (*.pfx)",
+ "t_15_1744958840790": "JKS (*.jks)",
+ "t_16_1744958841116": "POSIX bash (Linux/macOS)",
+ "t_17_1744958839597": "CMD (Windows)",
+ "t_18_1744958839895": "PowerShell (Windows)",
+ "t_19_1744958839297": "Certificado 1",
+ "t_20_1744958839439": "Certificado 2",
+ "t_21_1744958839305": "Servidor 1",
+ "t_22_1744958841926": "Servidor 2",
+ "t_23_1744958838717": "Panel 1",
+ "t_24_1744958845324": "Panel 2",
+ "t_25_1744958839236": "Sitio 1",
+ "t_26_1744958839682": "Sitio 2",
+ "t_27_1744958840234": "Tencent Cloud 1",
+ "t_28_1744958839760": "Aliyun 1",
+ "t_29_1744958838904": "día",
+ "t_30_1744958843864": "El formato del certificado no es correcto, por favor revise si contiene las identificaciones de cabecera y pie completo",
+ "t_31_1744958844490": "El formato de la clave privada no es correcto, por favor verifique si contiene el identificador completo de la cabecera y el pie de página de la clave privada",
+ "t_0_1745215914686": "Nombre de automatización",
+ "t_2_1745215915397": "automático",
+ "t_3_1745215914237": "Manual",
+ "t_4_1745215914951": "Estado activo",
+ "t_5_1745215914671": "Activar",
+ "t_6_1745215914104": "Desactivar",
+ "t_7_1745215914189": "Tiempo de creación",
+ "t_8_1745215914610": "Operación",
+ "t_9_1745215914666": "Historial de ejecución",
+ "t_10_1745215914342": "ejecutar",
+ "t_11_1745215915429": "Editar",
+ "t_12_1745215914312": "Eliminar",
+ "t_13_1745215915455": "Ejecutar flujo de trabajo",
+ "t_14_1745215916235": "Ejecución del flujo de trabajo exitosa",
+ "t_15_1745215915743": "Fallo en la ejecución del flujo de trabajo",
+ "t_16_1745215915209": "Eliminar flujo de trabajo",
+ "t_17_1745215915985": "Eliminación del flujo de trabajo exitosa",
+ "t_18_1745215915630": "Fallo al eliminar el flujo de trabajo",
+ "t_0_1745227838699": "Despliegue automatizado nuevo",
+ "t_1_1745227838776": "Por favor, ingrese el nombre de automatización",
+ "t_2_1745227839794": "¿Está seguro de que desea ejecutar el flujo de trabajo {name}?",
+ "t_3_1745227841567": "¿Confirma la eliminación del flujo de trabajo {name}? Esta acción no se puede deshacer.",
+ "t_4_1745227838558": "Tiempo de ejecución",
+ "t_5_1745227839906": "Hora de finalización",
+ "t_6_1745227838798": "Método de ejecución",
+ "t_7_1745227838093": "Estado",
+ "t_8_1745227838023": "Éxito",
+ "t_9_1745227838305": "fallo",
+ "t_10_1745227838234": "En ejecución",
+ "t_11_1745227838422": "desconocido",
+ "t_12_1745227838814": "Detalles",
+ "t_13_1745227838275": "Subir certificado",
+ "t_14_1745227840904": "Ingrese el nombre de dominio del certificado o el nombre de la marca para buscar",
+ "t_15_1745227839354": "juntos",
+ "t_16_1745227838930": "pieza",
+ "t_17_1745227838561": "Nombre de dominio",
+ "t_18_1745227838154": "Marca",
+ "t_19_1745227839107": "Días restantes",
+ "t_20_1745227838813": "Tiempo de vencimiento",
+ "t_21_1745227837972": "Fuente",
+ "t_22_1745227838154": "Solicitud automática",
+ "t_23_1745227838699": "Carga manual",
+ "t_24_1745227839508": "Agregar tiempo",
+ "t_25_1745227838080": "Descargar",
+ "t_27_1745227838583": "Casi caducado",
+ "t_28_1745227837903": "normal",
+ "t_29_1745227838410": "Eliminar certificado",
+ "t_30_1745227841739": "¿Está seguro de que desea eliminar este certificado? Esta acción no se puede deshacer.",
+ "t_31_1745227838461": "Confirmar",
+ "t_32_1745227838439": "Nombre del certificado",
+ "t_33_1745227838984": "Por favor, ingrese el nombre del certificado",
+ "t_34_1745227839375": "Contenido del certificado (PEM)",
+ "t_35_1745227839208": "Por favor, ingrese el contenido del certificado",
+ "t_36_1745227838958": "Contenido de la clave privada (KEY)",
+ "t_37_1745227839669": "Por favor, ingrese el contenido de la clave privada",
+ "t_38_1745227838813": "Falla en la descarga",
+ "t_39_1745227838696": "Fallo en la subida",
+ "t_40_1745227838872": "Falla en la eliminación",
+ "t_0_1745289355714": "Agregar API de autorización",
+ "t_1_1745289356586": "Por favor, ingrese el nombre o el tipo de API autorizada",
+ "t_2_1745289353944": "Nombre",
+ "t_3_1745289354664": "Tipo de API de autorización",
+ "t_4_1745289354902": "API de autorización de edición",
+ "t_5_1745289355718": "Eliminar API de autorización",
+ "t_6_1745289358340": "¿Está seguro de que desea eliminar este API autorizado? Esta acción no se puede deshacer.",
+ "t_7_1745289355714": "Fallo al agregar",
+ "t_8_1745289354902": "Fallo en la actualización",
+ "t_9_1745289355714": "Vencido {days} días",
+ "t_10_1745289354650": "Gestión de monitoreo",
+ "t_11_1745289354516": "Agregar monitoreo",
+ "t_12_1745289356974": "Por favor, ingrese el nombre de monitoreo o el dominio para buscar",
+ "t_13_1745289354528": "Nombre del monitor",
+ "t_14_1745289354902": "Dominio del certificado",
+ "t_15_1745289355714": "Autoridad de certificación",
+ "t_16_1745289354902": "Estado del certificado",
+ "t_17_1745289355715": "Fecha de expiración del certificado",
+ "t_18_1745289354598": "Canales de alerta",
+ "t_19_1745289354676": "Última revisión",
+ "t_20_1745289354598": "Edición de monitoreo",
+ "t_21_1745289354598": "Confirmar eliminación",
+ "t_22_1745289359036": "Los elementos no se pueden recuperar después de su eliminación. ¿Está seguro de que desea eliminar este monitor?",
+ "t_23_1745289355716": "Fallo en la modificación",
+ "t_24_1745289355715": "Fallo en la configuración",
+ "t_25_1745289355721": "Por favor, ingrese el código de verificación",
+ "t_26_1745289358341": "Validación del formulario fallida, por favor revise el contenido ingresado",
+ "t_27_1745289355721": "Por favor, ingrese el nombre del API autorizado",
+ "t_28_1745289356040": "Seleccione el tipo de API de autorización",
+ "t_29_1745289355850": "Por favor, ingrese la IP del servidor",
+ "t_30_1745289355718": "Por favor, ingrese el puerto SSH",
+ "t_31_1745289355715": "Por favor, ingrese la clave SSH",
+ "t_32_1745289356127": "Por favor, ingrese la dirección de Baota",
+ "t_33_1745289355721": "Por favor, ingrese la clave de API",
+ "t_34_1745289356040": "Por favor, ingrese la dirección de 1panel",
+ "t_35_1745289355714": "Por favor, ingrese AccessKeyId",
+ "t_36_1745289355715": "Por favor, ingrese AccessKeySecret",
+ "t_37_1745289356041": "Por favor, ingrese SecretId",
+ "t_38_1745289356419": "Por favor, ingrese la Clave Secreta",
+ "t_39_1745289354902": "Actualización exitosa",
+ "t_40_1745289355715": "Añadido con éxito",
+ "t_41_1745289354902": "Tipo",
+ "t_42_1745289355715": "IP del servidor",
+ "t_43_1745289354598": "Puerto SSH",
+ "t_44_1745289354583": "Nombre de usuario",
+ "t_45_1745289355714": "Método de autenticación",
+ "t_46_1745289355723": "Autenticación por contraseña",
+ "t_47_1745289355715": "Autenticación de clave",
+ "t_48_1745289355714": "Contraseña",
+ "t_49_1745289355714": "Llave privada SSH",
+ "t_50_1745289355715": "Por favor, ingrese la clave privada SSH",
+ "t_51_1745289355714": "Contraseña de la clave privada",
+ "t_52_1745289359565": "Si la clave privada tiene una contraseña, ingrese",
+ "t_53_1745289356446": "Dirección del panel BaoTa",
+ "t_54_1745289358683": "Por favor, ingrese la dirección del panel Baota, por ejemplo: https://bt.example.com",
+ "t_55_1745289355715": "Clave API",
+ "t_56_1745289355714": "Dirección del panel 1",
+ "t_57_1745289358341": "Ingrese la dirección de 1panel, por ejemplo: https://1panel.example.com",
+ "t_58_1745289355721": "Ingrese el ID de AccessKey",
+ "t_59_1745289356803": "Por favor, ingrese el secreto de AccessKey",
+ "t_60_1745289355715": "Por favor, ingrese el nombre de monitoreo",
+ "t_61_1745289355878": "Por favor, ingrese el dominio/IP",
+ "t_62_1745289360212": "Por favor, seleccione el período de inspección",
+ "t_63_1745289354897": "5 minutos",
+ "t_64_1745289354670": "10 minutos",
+ "t_65_1745289354591": "15 minutos",
+ "t_66_1745289354655": "30 minutos",
+ "t_67_1745289354487": "60 minutos",
+ "t_68_1745289354676": "Correo electrónico",
+ "t_69_1745289355721": "SMS",
+ "t_70_1745289354904": "WeChat",
+ "t_71_1745289354583": "Dominio/IP",
+ "t_72_1745289355715": "Período de inspección",
+ "t_73_1745289356103": "Seleccione un canal de alerta",
+ "t_0_1745289808449": "Por favor, ingrese el nombre del API autorizado",
+ "t_0_1745294710530": "Eliminar monitoreo",
+ "t_0_1745295228865": "Fecha de actualización",
+ "t_0_1745317313835": "Formato incorrecto de la dirección IP del servidor",
+ "t_1_1745317313096": "Error de formato de puerto",
+ "t_2_1745317314362": "Error de formato en la dirección URL del panel",
+ "t_3_1745317313561": "Por favor, ingrese la clave API del panel",
+ "t_4_1745317314054": "Por favor, ingrese el AccessKeyId de Aliyun",
+ "t_5_1745317315285": "Por favor, ingrese el AccessKeySecret de Aliyun",
+ "t_6_1745317313383": "Por favor, ingrese el SecretId de Tencent Cloud",
+ "t_7_1745317313831": "Por favor, ingrese la SecretKey de Tencent Cloud",
+ "t_0_1745457486299": "Habilitado",
+ "t_1_1745457484314": "Detenido",
+ "t_2_1745457488661": "Cambiar a modo manual",
+ "t_3_1745457486983": "Cambiar a modo automático",
+ "t_4_1745457497303": "Después de cambiar al modo manual, el flujo de trabajo ya no se ejecutará automáticamente, pero aún se puede ejecutar manualmente",
+ "t_5_1745457494695": "Después de cambiar al modo automático, el flujo de trabajo se ejecutará automáticamente según el tiempo configurado",
+ "t_6_1745457487560": "Cerrar flujo de trabajo actual",
+ "t_7_1745457487185": "Habilitar flujo de trabajo actual",
+ "t_8_1745457496621": "Después de cerrar, el flujo de trabajo ya no se ejecutará automáticamente ni se podrá ejecutar manualmente. ¿Continuar?",
+ "t_9_1745457500045": "Después de habilitar, la configuración del flujo de trabajo se ejecutará automáticamente o manualmente. ¿Continuar?",
+ "t_10_1745457486451": "Error al añadir el flujo de trabajo",
+ "t_11_1745457488256": "Error al configurar el método de ejecución del flujo de trabajo",
+ "t_12_1745457489076": "Habilitar o deshabilitar falla del flujo de trabajo",
+ "t_13_1745457487555": "Error al ejecutar el flujo de trabajo",
+ "t_14_1745457488092": "Error al eliminar el flujo de trabajo",
+ "t_15_1745457484292": "Salir",
+ "t_16_1745457491607": "Estás a punto de cerrar sesión. ¿Seguro que quieres salir?",
+ "t_17_1745457488251": "Cerrando sesión, por favor espere...",
+ "t_18_1745457490931": "Agregar notificación por correo electrónico",
+ "t_19_1745457484684": "Guardado exitosamente",
+ "t_20_1745457485905": "Eliminado con éxito",
+ "t_0_1745464080226": "Error al obtener la configuración del sistema",
+ "t_1_1745464079590": "Error al guardar la configuración",
+ "t_2_1745464077081": "Error al obtener la configuración de notificaciones",
+ "t_3_1745464081058": "Error al guardar la configuración de notificaciones",
+ "t_4_1745464075382": "Error al obtener la lista de canales de notificación",
+ "t_5_1745464086047": "Error al agregar el canal de notificación por correo electrónico",
+ "t_6_1745464075714": "Error al actualizar el canal de notificación",
+ "t_7_1745464073330": "Error al eliminar el canal de notificación",
+ "t_8_1745464081472": "Error al comprobar la actualización de versión",
+ "t_9_1745464078110": "Guardar configuración",
+ "t_10_1745464073098": "Configuración básica",
+ "t_0_1745474945127": "Elegir plantilla",
+ "t_0_1745490735213": "Por favor ingrese el nombre del flujo de trabajo",
+ "t_1_1745490731990": "Configuración",
+ "t_2_1745490735558": "Por favor, ingrese el formato de correo electrónico",
+ "t_3_1745490735059": "Por favor, seleccione un proveedor de DNS",
+ "t_4_1745490735630": "Por favor, ingrese el intervalo de renovación",
+ "t_5_1745490738285": "Ingrese el nombre de dominio, el nombre de dominio no puede estar vacío",
+ "t_6_1745490738548": "Por favor ingrese el correo electrónico, el correo electrónico no puede estar vacío",
+ "t_7_1745490739917": "Por favor, seleccione un proveedor DNS, el proveedor DNS no puede estar vacío",
+ "t_8_1745490739319": "Ingrese el intervalo de renovación, el intervalo de renovación no puede estar vacío",
+ "t_0_1745553910661": "Formato de dominio incorrecto, ingrese el dominio correcto",
+ "t_1_1745553909483": "Formato de correo electrónico incorrecto, ingrese un correo correcto",
+ "t_2_1745553907423": "El intervalo de renovación no puede estar vacío",
+ "t_0_1745735774005": "Ingrese el nombre de dominio del certificado, varios nombres de dominio separados por comas",
+ "t_1_1745735764953": "Buzón",
+ "t_2_1745735773668": "Ingrese su correo electrónico para recibir notificaciones de la autoridad certificadora",
+ "t_3_1745735765112": "Proveedor de DNS",
+ "t_4_1745735765372": "Agregar",
+ "t_5_1745735769112": "Intervalo de Renovación (Días)",
+ "t_6_1745735765205": "Intervalo de renovación",
+ "t_7_1745735768326": "días, se renueva automáticamente al vencimiento",
+ "t_8_1745735765753": "Configurado",
+ "t_9_1745735765287": "No configurado",
+ "t_10_1745735765165": "Panel Pagoda",
+ "t_11_1745735766456": "Sitio web del Panel Pagoda",
+ "t_12_1745735765571": "Panel 1Panel",
+ "t_13_1745735766084": "1Panel sitio web",
+ "t_14_1745735766121": "Tencent Cloud CDN",
+ "t_15_1745735768976": "Tencent Cloud COS",
+ "t_16_1745735766712": "Alibaba Cloud CDN",
+ "t_18_1745735765638": "Tipo de despliegue",
+ "t_19_1745735766810": "Por favor, seleccione el tipo de despliegue",
+ "t_20_1745735768764": "Por favor, ingrese la ruta de despliegue",
+ "t_21_1745735769154": "Por favor, ingrese el comando de prefijo",
+ "t_22_1745735767366": "Por favor, ingrese el comando posterior",
+ "t_23_1745735766455": "Por favor, ingrese el nombre del sitio",
+ "t_24_1745735766826": "Por favor ingrese el ID del sitio",
+ "t_25_1745735766651": "Por favor, ingrese la región",
+ "t_26_1745735767144": "Por favor ingrese el cubo",
+ "t_27_1745735764546": "Próximo paso",
+ "t_28_1745735766626": "Seleccionar tipo de implementación",
+ "t_29_1745735768933": "Configurar parámetros de despliegue",
+ "t_30_1745735764748": "Modo de operación",
+ "t_31_1745735767891": "Modo de operación no configurado",
+ "t_32_1745735767156": "Ciclo de ejecución no configurado",
+ "t_33_1745735766532": "Tiempo de ejecución no configurado",
+ "t_34_1745735771147": "Archivo de certificado (formato PEM)",
+ "t_35_1745735781545": "Por favor, pegue el contenido del archivo de certificado, por ejemplo:\n-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
+ "t_36_1745735769443": "Archivo de clave privada (formato KEY)",
+ "t_37_1745735779980": "Pega el contenido del archivo de clave privada, por ejemplo:\n-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
+ "t_38_1745735769521": "El contenido de la clave privada del certificado no puede estar vacío",
+ "t_39_1745735768565": "El formato de la clave privada del certificado es incorrecto",
+ "t_40_1745735815317": "El contenido del certificado no puede estar vacío",
+ "t_41_1745735767016": "Formato de certificado incorrecto",
+ "t_0_1745738961258": "Anterior",
+ "t_1_1745738963744": "Enviar",
+ "t_2_1745738969878": "Configurar parámetros de despliegue, el tipo determina la configuración de parámetros",
+ "t_0_1745744491696": "Fuente del dispositivo de implementación",
+ "t_1_1745744495019": "Por favor seleccione la fuente del dispositivo de despliegue",
+ "t_2_1745744495813": "Por favor, seleccione el tipo de implementación y haga clic en Siguiente",
+ "t_0_1745744902975": "Fuente de implementación",
+ "t_1_1745744905566": "Seleccione la fuente de despliegue",
+ "t_2_1745744903722": "Agregar más dispositivos",
+ "t_0_1745748292337": "Agregar fuente de despliegue",
+ "t_1_1745748290291": "Fuente del certificado",
+ "t_2_1745748298902": "La fuente de implementación del tipo actual está vacía, agregue una fuente de implementación primero",
+ "t_3_1745748298161": "No hay ningún nodo de solicitud en el proceso actual, por favor agregue un nodo de solicitud primero",
+ "t_4_1745748290292": "Enviar contenido",
+ "t_0_1745765864788": "Haz clic para editar el título del flujo de trabajo",
+ "t_1_1745765875247": "Eliminar Nodo - 【{name}】",
+ "t_2_1745765875918": "El nodo actual tiene nodos hijos. Eliminarlo afectará a otros nodos. ¿Está seguro de que desea eliminarlo?",
+ "t_3_1745765920953": "El nodo actual tiene datos de configuración, ¿está seguro de que desea eliminarlo?",
+ "t_4_1745765868807": "Por favor, seleccione el tipo de implementación antes de continuar con el siguiente paso",
+ "t_0_1745833934390": "Por favor, seleccione el tipo",
+ "t_1_1745833931535": "Host",
+ "t_2_1745833931404": "puerto",
+ "t_3_1745833936770": "Error al obtener los datos de vista general de la página de inicio",
+ "t_4_1745833932780": "Información de versión",
+ "t_5_1745833933241": "Versión actual",
+ "t_6_1745833933523": "Método de actualización",
+ "t_7_1745833933278": "Última versión",
+ "t_8_1745833933552": "Registro de cambios",
+ "t_9_1745833935269": "Código QR de Servicio al Cliente",
+ "t_10_1745833941691": "Escanee el código QR para agregar servicio al cliente",
+ "t_11_1745833935261": "Cuenta Oficial de WeChat",
+ "t_12_1745833943712": "Escanea para seguir la cuenta oficial de WeChat",
+ "t_13_1745833933630": "Acerca del producto",
+ "t_14_1745833932440": "Servidor SMTP",
+ "t_15_1745833940280": "Por favor, ingrese el servidor SMTP",
+ "t_16_1745833933819": "Puerto SMTP",
+ "t_17_1745833935070": "Por favor, ingrese el puerto SMTP",
+ "t_18_1745833933989": "Conexión SSL/TLS",
+ "t_0_1745887835267": "Por favor, seleccione notificación de mensaje",
+ "t_1_1745887832941": "Notificación",
+ "t_2_1745887834248": "Agregar canal de notificación",
+ "t_3_1745887835089": "Ingrese el asunto de la notificación",
+ "t_4_1745887835265": "Por favor ingrese el contenido de la notificación",
+ "t_0_1745895057404": "Modificar configuración de notificaciones por correo electrónico",
+ "t_0_1745920566646": "Asunto de la notificación",
+ "t_1_1745920567200": "Contenido de la notificación",
+ "t_0_1745936396853": "Haz clic para obtener el código de verificación",
+ "t_0_1745999035681": "faltan {days} días",
+ "t_1_1745999036289": "Próximo a vencer {days} días",
+ "t_0_1746000517848": "Caducado",
+ "t_0_1746001199409": "Expirado",
+ "t_0_1746004861782": "El proveedor DNS está vacío",
+ "t_1_1746004861166": "Agregar proveedor de DNS",
+ "t_0_1746497662220": "Actualizar",
+ "t_0_1746519384035": "En ejecución",
+ "t_0_1746579648713": "Detalles del Historial de Ejecución",
+ "t_0_1746590054456": "Estado de ejecución",
+ "t_1_1746590060448": "Método de Activación",
+ "t_0_1746667592819": "Enviando información, por favor espere...",
+ "t_1_1746667588689": "Clave",
+ "t_2_1746667592840": "URL del panel",
+ "t_3_1746667592270": "Ignorar errores de certificado SSL/TLS",
+ "t_4_1746667590873": "Falló la validación del formulario",
+ "t_5_1746667590676": "Nuevo flujo de trabajo",
+ "t_6_1746667592831": "Enviando aplicación, por favor espere...",
+ "t_7_1746667592468": "Por favor ingrese el nombre de dominio correcto",
+ "t_8_1746667591924": "Por favor, seleccione el método de análisis",
+ "t_9_1746667589516": "Actualizar lista",
+ "t_10_1746667589575": "Comodín",
+ "t_11_1746667589598": "Multidominio",
+ "t_12_1746667589733": "Popular",
+ "t_13_1746667599218": "es un proveedor de certificados SSL gratuito ampliamente utilizado, adecuado para sitios web personales y entornos de prueba.",
+ "t_14_1746667590827": "Número de dominios soportados",
+ "t_15_1746667588493": "pieza",
+ "t_16_1746667591069": "Compatibilidad con caracteres comodín",
+ "t_17_1746667588785": "apoyo",
+ "t_18_1746667590113": "No soportado",
+ "t_19_1746667589295": "Período de validez",
+ "t_20_1746667588453": "día",
+ "t_21_1746667590834": "Soporte para Mini Programas",
+ "t_22_1746667591024": "Sitios aplicables",
+ "t_23_1746667591989": "*.example.com, *.demo.com",
+ "t_24_1746667583520": "*.example.com",
+ "t_25_1746667590147": "example.com、demo.com",
+ "t_26_1746667594662": "www.example.com, example.com",
+ "t_27_1746667589350": "Gratis",
+ "t_28_1746667590336": "Aplicar ahora",
+ "t_29_1746667589773": "Dirección del proyecto",
+ "t_30_1746667591892": "Ingrese la ruta del archivo de certificado",
+ "t_31_1746667593074": "Ingrese la ruta del archivo de clave privada",
+ "t_0_1746673515941": "El proveedor de DNS actual está vacío, por favor agregue un proveedor de DNS primero",
+ "t_0_1746676862189": "Error en el envío de notificación de prueba",
+ "t_1_1746676859550": "Agregar Configuración",
+ "t_2_1746676856700": "Aún no compatible",
+ "t_3_1746676857930": "Notificación por correo electrónico",
+ "t_4_1746676861473": "Enviar notificaciones de alerta por correo electrónico",
+ "t_5_1746676856974": "Notificación de DingTalk",
+ "t_6_1746676860886": "Enviar notificaciones de alarma a través del robot DingTalk",
+ "t_7_1746676857191": "Notificación de WeChat Work",
+ "t_8_1746676860457": "Enviar notificaciones de alarma a través del bot de WeCom",
+ "t_9_1746676857164": "Notificación de Feishu",
+ "t_10_1746676862329": "Enviar notificaciones de alarma a través del bot Feishu",
+ "t_11_1746676859158": "Notificación WebHook",
+ "t_12_1746676860503": "Enviar notificaciones de alarma a través de WebHook",
+ "t_13_1746676856842": "Canal de notificación",
+ "t_14_1746676859019": "Canales de notificación configurados",
+ "t_15_1746676856567": "Desactivado",
+ "t_16_1746676855270": "Prueba",
+ "t_0_1746677882486": "Último estado de ejecución",
+ "t_0_1746697487119": "El nombre de dominio no puede estar vacío",
+ "t_1_1746697485188": "El correo electrónico no puede estar vacío",
+ "t_2_1746697487164": "Alibaba Cloud OSS",
+ "t_0_1746754500246": "Proveedor de Alojamiento",
+ "t_1_1746754499371": "Fuente de la API",
+ "t_2_1746754500270": "Tipo de API",
+ "t_0_1746760933542": "Error de solicitud",
+ "t_0_1746773350551": "{0} en total",
+ "t_1_1746773348701": "No ejecutado",
+ "t_2_1746773350970": "Flujo de trabajo automatizado",
+ "t_3_1746773348798": "Cantidad total",
+ "t_4_1746773348957": "Falló la ejecución",
+ "t_5_1746773349141": "Próximo a expirar",
+ "t_6_1746773349980": "Monitoreo en tiempo real",
+ "t_7_1746773349302": "Cantidad anormal",
+ "t_8_1746773351524": "Registros recientes de ejecución de flujo de trabajo",
+ "t_9_1746773348221": "Ver todo",
+ "t_10_1746773351576": "No hay registros de ejecución de flujo de trabajo",
+ "t_11_1746773349054": "Crear flujo de trabajo",
+ "t_12_1746773355641": "Haz clic para crear un flujo de trabajo automatizado y mejorar la eficiencia",
+ "t_13_1746773349526": "Solicitar certificado",
+ "t_14_1746773355081": "Haz clic para solicitar y administrar certificados SSL para garantizar la seguridad",
+ "t_15_1746773358151": "Haz clic para configurar el monitoreo del sitio web y realiza un seguimiento del estado de ejecución en tiempo real",
+ "t_16_1746773356568": "Solo se puede configurar un canal de notificación por correo electrónico como máximo",
+ "t_17_1746773351220": "Confirmar canal de notificación {0}",
+ "t_18_1746773355467": "Los canales de notificación {0} comenzarán a enviar alertas.",
+ "t_19_1746773352558": "El canal de notificación actual no admite pruebas",
+ "t_20_1746773356060": "Enviando correo de prueba, por favor espere...",
+ "t_21_1746773350759": "Correo de prueba",
+ "t_22_1746773360711": "¿Enviar un correo de prueba al buzón configurado actualmente, continuar?",
+ "t_23_1746773350040": "Confirmación de eliminación",
+ "t_24_1746773349367": "Confirmar eliminación",
+ "t_25_1746773349596": "Por favor ingrese el nombre",
+ "t_26_1746773353409": "Por favor, ingrese el puerto SMTP correcto",
+ "t_27_1746773352584": "Por favor, ingrese la contraseña de usuario",
+ "t_28_1746773354048": "Por favor, ingrese el correo electrónico correcto del remitente",
+ "t_29_1746773351834": "Por favor, ingrese el correo electrónico de recepción correcto",
+ "t_30_1746773350013": "Correo electrónico del remitente",
+ "t_31_1746773349857": "Recibir correo electrónico",
+ "t_32_1746773348993": "DingTalk",
+ "t_33_1746773350932": "WeChat Work",
+ "t_34_1746773350153": "Feishu",
+ "t_35_1746773362992": "Una herramienta de gestión del ciclo de vida completo de certificados SSL que integra solicitud, gestión, implementación y monitoreo.",
+ "t_36_1746773348989": "Solicitud de Certificado",
+ "t_37_1746773356895": "Soporte para obtener certificados de Let's Encrypt a través del protocolo ACME",
+ "t_38_1746773349796": "Gestión de Certificados",
+ "t_39_1746773358932": "Gestión centralizada de todos los certificados SSL, incluidos los certificados cargados manualmente y aplicados automáticamente",
+ "t_40_1746773352188": "Implementación de certificado",
+ "t_41_1746773364475": "Soporte para implementar certificados con un clic en múltiples plataformas como Alibaba Cloud, Tencent Cloud, Pagoda Panel, 1Panel, etc.",
+ "t_42_1746773348768": "Monitoreo del sitio",
+ "t_43_1746773359511": "Monitoreo en tiempo real del estado de los certificados SSL del sitio para alertar sobre la expiración de los certificados",
+ "t_44_1746773352805": "Tarea automatizada:",
+ "t_45_1746773355717": "Admite tareas programadas, renovación automática de certificados e implementación",
+ "t_46_1746773350579": "Soporte multiplataforma",
+ "t_47_1746773360760": "Admite métodos de verificación DNS para múltiples proveedores de DNS (Alibaba Cloud, Tencent Cloud, etc.)"
+}
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/locales/model/frFR.json b/frontend/apps/allin-ssl/src/locales/model/frFR.json
new file mode 100644
index 0000000..054292e
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/locales/model/frFR.json
@@ -0,0 +1,490 @@
+{
+ "t_0_1746773763967": "Êtes-vous sûr de vouloir supprimer {0}, le canal de notification ?",
+ "t_1_1746773763643": "Let's Encrypt et d'autres CA demandent automatiquement des certificats gratuits",
+ "t_0_1744098811152": "Avertissement : Vous avez entré dans une zone inconnue, la page que vous visitez n'existe pas, veuillez cliquer sur le bouton pour revenir à la page d'accueil.",
+ "t_1_1744098801860": "Retour à l'accueil",
+ "t_2_1744098804908": "Avis de sécurité : Si vous pensez que c'est une erreur, veuillez contacter l'administrateur immédiatement",
+ "t_3_1744098802647": "Développer le menu principal",
+ "t_4_1744098802046": "Menu principal pliable",
+ "t_0_1744164843238": "Bienvenue dans AllinSSL, gestion efficace des certificats SSL",
+ "t_1_1744164835667": "AllinSSL",
+ "t_2_1744164839713": "Connexion du compte",
+ "t_3_1744164839524": "Veuillez saisir le nom d'utilisateur",
+ "t_4_1744164840458": "Veuillez saisir le mot de passe",
+ "t_5_1744164840468": "Rappelez-vous du mot de passe",
+ "t_6_1744164838900": "Oublié votre mot de passe?",
+ "t_7_1744164838625": "En cours de connexion",
+ "t_8_1744164839833": "Se connecter",
+ "t_0_1744168657526": "Déconnecter",
+ "t_0_1744258111441": "Accueil",
+ "t_1_1744258113857": "Déploiement Automatisé",
+ "t_2_1744258111238": "Gestion des certificats",
+ "t_3_1744258111182": "Demande de certificat",
+ "t_4_1744258111238": "Gestion de l'API d'autorisation",
+ "t_5_1744258110516": "Surveillance",
+ "t_6_1744258111153": "Paramètres",
+ "t_0_1744861190562": "Renvoyer la liste des flux de travail",
+ "t_1_1744861189113": "Exécuter",
+ "t_2_1744861190040": "Sauvegarder",
+ "t_3_1744861190932": "Veuillez sélectionner un nœud à configurer",
+ "t_4_1744861194395": "Clique sur le nœud dans le diagramme de flux de gauche pour le configurer",
+ "t_5_1744861189528": "commencer",
+ "t_6_1744861190121": "Aucun noeud sélectionné",
+ "t_7_1744861189625": "Configuration enregistrée",
+ "t_8_1744861189821": "Démarrer le processus",
+ "t_9_1744861189580": "Nœud sélectionné :",
+ "t_0_1744870861464": "nœud",
+ "t_1_1744870861944": "Configuration de noeud",
+ "t_2_1744870863419": "Veuillez sélectionner le nœud de gauche pour la configuration",
+ "t_3_1744870864615": "Composant de configuration pour ce type de noeud introuvable",
+ "t_4_1744870861589": "Annuler",
+ "t_5_1744870862719": "confirmer",
+ "t_0_1744875938285": "à chaque minute",
+ "t_1_1744875938598": "chaque heure",
+ "t_2_1744875938555": "chaque jour",
+ "t_3_1744875938310": "chaque mois",
+ "t_4_1744875940750": "Exécution automatique",
+ "t_5_1744875940010": "Exécution manuelle",
+ "t_0_1744879616135": "Test PID",
+ "t_1_1744879616555": "Veuillez saisir le PID de test",
+ "t_2_1744879616413": "Cycle d'exécution",
+ "t_3_1744879615723": "minute",
+ "t_4_1744879616168": "Veuillez saisir les minutes",
+ "t_5_1744879615277": "heure",
+ "t_6_1744879616944": "Veuillez saisir des heures",
+ "t_7_1744879615743": "Date",
+ "t_8_1744879616493": "Sélectionnez une date",
+ "t_0_1744942117992": "chaque semaine",
+ "t_1_1744942116527": "lundi",
+ "t_2_1744942117890": "mardi",
+ "t_3_1744942117885": "Mercredi",
+ "t_4_1744942117738": "jeudi",
+ "t_5_1744942117167": "vendredi",
+ "t_6_1744942117815": "samedi",
+ "t_7_1744942117862": "dimanche",
+ "t_0_1744958839535": "Veuillez saisir le nom de domaine",
+ "t_1_1744958840747": "Veuillez saisir votre adresse e-mail",
+ "t_2_1744958840131": "Le format de l'e-mail est incorrect",
+ "t_3_1744958840485": "Veuillez choisir le fournisseur de DNS pour l'autorisation",
+ "t_4_1744958838951": "Déploiement local",
+ "t_5_1744958839222": "Déploiement SSH",
+ "t_6_1744958843569": "Panneau Bao Ta/1 panneau (Déployer sur le certificat du panneau)",
+ "t_7_1744958841708": "1panneau (Déploiement sur le projet de site spécifié)",
+ "t_8_1744958841658": "Tencent Cloud CDN/AliCloud CDN",
+ "t_9_1744958840634": "WAF de Tencent Cloud",
+ "t_10_1744958860078": "WAF d'Alicloud",
+ "t_11_1744958840439": "Ce certificat appliqué automatiquement",
+ "t_12_1744958840387": "Liste des certificats optionnels",
+ "t_13_1744958840714": "PEM (*.pem, *.crt, *.key)",
+ "t_14_1744958839470": "PFX (*.pfx)",
+ "t_15_1744958840790": "JKS (*.jks)",
+ "t_16_1744958841116": "POSIX bash (Linux/macOS)",
+ "t_17_1744958839597": "CMD (Windows)",
+ "t_18_1744958839895": "PowerShell (Windows)",
+ "t_19_1744958839297": "Certificat 1",
+ "t_20_1744958839439": "Certificat 2",
+ "t_21_1744958839305": "Serveur 1",
+ "t_22_1744958841926": "Serveur 2",
+ "t_23_1744958838717": "Panneau 1",
+ "t_24_1744958845324": "Panneau 2",
+ "t_25_1744958839236": "Site 1",
+ "t_26_1744958839682": "Site 2",
+ "t_27_1744958840234": "Tencent Cloud 1",
+ "t_28_1744958839760": "Aliyun 1",
+ "t_29_1744958838904": "jour",
+ "t_30_1744958843864": "Le format du certificat est incorrect, veuillez vérifier s'il contient les identifiants d'en-tête et de pied de page complets",
+ "t_31_1744958844490": "Le format de la clé privée est incorrect, veuillez vérifier si elle contient l'identifiant complet de l'en-tête et du pied de page de la clé privée",
+ "t_0_1745215914686": "Nom d'automatisation",
+ "t_2_1745215915397": "automatique",
+ "t_3_1745215914237": "Manuel",
+ "t_4_1745215914951": "Statut activé",
+ "t_5_1745215914671": "Activer",
+ "t_6_1745215914104": "Désactiver",
+ "t_7_1745215914189": "Heure de création",
+ "t_8_1745215914610": "Opération",
+ "t_9_1745215914666": "Historique d'exécution",
+ "t_10_1745215914342": "exécuter",
+ "t_11_1745215915429": "Éditer",
+ "t_12_1745215914312": "Supprimer",
+ "t_13_1745215915455": "Exécuter le flux de travail",
+ "t_14_1745215916235": "Exécution du flux de travail réussie",
+ "t_15_1745215915743": "Échec de l'exécution du flux de travail",
+ "t_16_1745215915209": "Supprimer le flux de travail",
+ "t_17_1745215915985": "Suppression du flux de travail réussie",
+ "t_18_1745215915630": "Échec de la suppression du flux de travail",
+ "t_0_1745227838699": "Déploiement automatisé ajouté",
+ "t_1_1745227838776": "Veuillez saisir le nom de l'automatisation",
+ "t_2_1745227839794": "Êtes-vous sûr de vouloir exécuter le workflow {name}?",
+ "t_3_1745227841567": "Confirmez-vous la suppression du flux de travail {name} ? Cette action ne peut pas être annulée.",
+ "t_4_1745227838558": "Temps d'exécution",
+ "t_5_1745227839906": "Heure de fin",
+ "t_6_1745227838798": "Méthode d'exécution",
+ "t_7_1745227838093": "Statut",
+ "t_8_1745227838023": "Réussite",
+ "t_9_1745227838305": "échec",
+ "t_10_1745227838234": "En cours",
+ "t_11_1745227838422": "inconnu",
+ "t_12_1745227838814": "Détails",
+ "t_13_1745227838275": "Télécharger un certificat",
+ "t_14_1745227840904": "Saisissez le nom de domaine du certificat ou le nom de la marque pour la recherche",
+ "t_15_1745227839354": "ensemble",
+ "t_16_1745227838930": "unité",
+ "t_17_1745227838561": "Nom de domaine",
+ "t_18_1745227838154": "Marque",
+ "t_19_1745227839107": "Jours restants",
+ "t_20_1745227838813": "Heure d'expiration",
+ "t_21_1745227837972": "Source",
+ "t_22_1745227838154": "Demande automatique",
+ "t_23_1745227838699": "Téléversement manuel",
+ "t_24_1745227839508": "Ajouter une date",
+ "t_25_1745227838080": "Télécharger",
+ "t_27_1745227838583": "Bientôt expiré",
+ "t_28_1745227837903": "normal",
+ "t_29_1745227838410": "Supprimer le certificat",
+ "t_30_1745227841739": "Confirmez-vous que vous souhaitez supprimer ce certificat ? Cette action ne peut pas être annulée.",
+ "t_31_1745227838461": "Confirmer",
+ "t_32_1745227838439": "Nom du certificat",
+ "t_33_1745227838984": "Veuillez saisir le nom du certificat",
+ "t_34_1745227839375": "Contenu du certificat (PEM)",
+ "t_35_1745227839208": "Veuillez saisir le contenu du certificat",
+ "t_36_1745227838958": "Contenu de la clé privée (KEY)",
+ "t_37_1745227839669": "Veuillez saisir le contenu de la clé privée",
+ "t_38_1745227838813": "Échec du téléchargement",
+ "t_39_1745227838696": "Échec du téléversement",
+ "t_40_1745227838872": "Échec de la suppression",
+ "t_0_1745289355714": "Ajouter l'API d'autorisation",
+ "t_1_1745289356586": "Veuillez saisir le nom ou le type de l'API autorisée",
+ "t_2_1745289353944": "Nom",
+ "t_3_1745289354664": "Type d'API d'autorisation",
+ "t_4_1745289354902": "API d'édition d'autorisation",
+ "t_5_1745289355718": "Suppression de l'API d'autorisation",
+ "t_6_1745289358340": "Êtes-vous sûr de vouloir supprimer cet API autorisé ? Cette action ne peut pas être annulée.",
+ "t_7_1745289355714": "Échec de l'ajout",
+ "t_8_1745289354902": "Échec de mise à jour",
+ "t_9_1745289355714": "Expiré {days} jours",
+ "t_10_1745289354650": "Gestion de surveillance",
+ "t_11_1745289354516": "Ajouter une surveillance",
+ "t_12_1745289356974": "Veuillez saisir le nom de surveillance ou le domaine pour la recherche",
+ "t_13_1745289354528": "Nom du moniteur",
+ "t_14_1745289354902": "Domaine du certificat",
+ "t_15_1745289355714": "Autorité de certification",
+ "t_16_1745289354902": "Statut du certificat",
+ "t_17_1745289355715": "Date d'expiration du certificat",
+ "t_18_1745289354598": "Canaux d'alerte",
+ "t_19_1745289354676": "Dernière date de vérification",
+ "t_20_1745289354598": "Édition de surveillance",
+ "t_21_1745289354598": "Confirmez la suppression",
+ "t_22_1745289359036": "Les éléments ne peuvent pas être restaurés après suppression. Êtes-vous sûr de vouloir supprimer ce moniteur?",
+ "t_23_1745289355716": "Échec de la modification",
+ "t_24_1745289355715": "Échec de la configuration",
+ "t_25_1745289355721": "Veuillez saisir le code de vérification",
+ "t_26_1745289358341": "Échec de validation du formulaire, veuillez vérifier le contenu rempli",
+ "t_27_1745289355721": "Veuillez saisir le nom de l'API autorisée",
+ "t_28_1745289356040": "Veuillez sélectionner le type d'API d'autorisation",
+ "t_29_1745289355850": "Veuillez saisir l'IP du serveur",
+ "t_30_1745289355718": "S'il vous plaît, entrez le port SSH",
+ "t_31_1745289355715": "Veuillez saisir la clé SSH",
+ "t_32_1745289356127": "Veuillez saisir l'adresse de Baota",
+ "t_33_1745289355721": "Veuillez saisir la clé API",
+ "t_34_1745289356040": "Veuillez saisir l'adresse 1panel",
+ "t_35_1745289355714": "Veuillez saisir AccessKeyId",
+ "t_36_1745289355715": "Veuillez saisir AccessKeySecret",
+ "t_37_1745289356041": "S'il vous plaît, entrez SecretId",
+ "t_38_1745289356419": "Veuillez saisir la Clé Secrète",
+ "t_39_1745289354902": "Mise à jour réussie",
+ "t_40_1745289355715": "Ajout réussi",
+ "t_41_1745289354902": "Type",
+ "t_42_1745289355715": "IP du serveur",
+ "t_43_1745289354598": "Port SSH",
+ "t_44_1745289354583": "Nom d'utilisateur",
+ "t_45_1745289355714": "Méthode d'authentification",
+ "t_46_1745289355723": "Authentification par mot de passe",
+ "t_47_1745289355715": "Authentification par clé",
+ "t_48_1745289355714": "Mot de passe",
+ "t_49_1745289355714": "Clé privée SSH",
+ "t_50_1745289355715": "Veuillez saisir la clé privée SSH",
+ "t_51_1745289355714": "Mot de passe de la clé privée",
+ "t_52_1745289359565": "Si la clé privée a un mot de passe, veuillez saisir",
+ "t_53_1745289356446": "Adresse du panneau BaoTa",
+ "t_54_1745289358683": "Veuillez saisir l'adresse du panneau Baota, par exemple : https://bt.example.com",
+ "t_55_1745289355715": "Clé API",
+ "t_56_1745289355714": "Adresse du panneau 1",
+ "t_57_1745289358341": "Saisissez l'adresse 1panel, par exemple : https://1panel.example.com",
+ "t_58_1745289355721": "Saisissez l'ID AccessKey",
+ "t_59_1745289356803": "Veuillez saisir le secret d'AccessKey",
+ "t_60_1745289355715": "Veuillez saisir le nom de surveillance",
+ "t_61_1745289355878": "Veuillez saisir le domaine/IP",
+ "t_62_1745289360212": "Veuillez sélectionner le cycle d'inspection",
+ "t_63_1745289354897": "5 minutes",
+ "t_64_1745289354670": "10 minutes",
+ "t_65_1745289354591": "15 minutes",
+ "t_66_1745289354655": "30 minutes",
+ "t_67_1745289354487": "60 minutes",
+ "t_68_1745289354676": "E-mail",
+ "t_69_1745289355721": "SMS",
+ "t_70_1745289354904": "WeChat",
+ "t_71_1745289354583": "Domaine/IP",
+ "t_72_1745289355715": "Période de contrôle",
+ "t_73_1745289356103": "Sélectionnez un canal d'alerte",
+ "t_0_1745289808449": "Veuillez saisir le nom de l'API autorisée",
+ "t_0_1745294710530": "Supprimer la surveillance",
+ "t_0_1745295228865": "Heure de mise à jour",
+ "t_0_1745317313835": "Format de l'adresse IP du serveur incorrect",
+ "t_1_1745317313096": "Erreur de format de port",
+ "t_2_1745317314362": "Format incorrect de l'adresse URL du panneau",
+ "t_3_1745317313561": "Veuillez saisir la clé API du panneau",
+ "t_4_1745317314054": "Veuillez saisir le AccessKeyId d'Aliyun",
+ "t_5_1745317315285": "Veuillez saisir le AccessKeySecret d'Aliyun",
+ "t_6_1745317313383": "S'il vous plaît saisir le SecretId de Tencent Cloud",
+ "t_7_1745317313831": "Veuillez saisir la SecretKey de Tencent Cloud",
+ "t_0_1745457486299": "Activé",
+ "t_1_1745457484314": "Arrêté",
+ "t_2_1745457488661": "Passer en mode manuel",
+ "t_3_1745457486983": "Passer en mode automatique",
+ "t_4_1745457497303": "Après avoir basculé en mode manuel, le flux de travail ne s'exécutera plus automatiquement, mais peut toujours être exécuté manuellement",
+ "t_5_1745457494695": "Après être passé en mode automatique, le flux de travail s'exécutera automatiquement selon le temps configuré",
+ "t_6_1745457487560": "Fermer le flux de travail actuel",
+ "t_7_1745457487185": "Activer le flux de travail actuel",
+ "t_8_1745457496621": "Après la fermeture, le flux de travail ne s'exécutera plus automatiquement et ne pourra pas être exécuté manuellement. Continuer ?",
+ "t_9_1745457500045": "Après activation, la configuration du flux de travail s'exécutera automatiquement ou manuellement. Continuer ?",
+ "t_10_1745457486451": "Échec de l'ajout du flux de travail",
+ "t_11_1745457488256": "Échec de la définition du mode d'exécution du flux de travail",
+ "t_12_1745457489076": "Activer ou désactiver l'échec du flux de travail",
+ "t_13_1745457487555": "Échec de l'exécution du workflow",
+ "t_14_1745457488092": "Échec de la suppression du flux de travail",
+ "t_15_1745457484292": "Quitter",
+ "t_16_1745457491607": "Vous êtes sur le point de vous déconnecter. Êtes-vous sûr de vouloir quitter ?",
+ "t_17_1745457488251": "Déconnexion en cours, veuillez patienter...",
+ "t_18_1745457490931": "Ajouter une notification par e-mail",
+ "t_19_1745457484684": "Enregistré avec succès",
+ "t_20_1745457485905": "Supprimé avec succès",
+ "t_0_1745464080226": "Échec de la récupération des paramètres du système",
+ "t_1_1745464079590": "Échec de l'enregistrement des paramètres",
+ "t_2_1745464077081": "Échec de la récupération des paramètres de notification",
+ "t_3_1745464081058": "Échec de l'enregistrement des paramètres de notification",
+ "t_4_1745464075382": "Échec de la récupération de la liste des canaux de notification",
+ "t_5_1745464086047": "Échec de l'ajout du canal de notification par email",
+ "t_6_1745464075714": "Échec de la mise à jour du canal de notification",
+ "t_7_1745464073330": "Échec de la suppression du canal de notification",
+ "t_8_1745464081472": "Échec de la vérification de la mise à jour de version",
+ "t_9_1745464078110": "Enregistrer les paramètres",
+ "t_10_1745464073098": "Paramètres de base",
+ "t_0_1745474945127": "Choisir un modèle",
+ "t_0_1745490735213": "Veuillez saisir le nom du workflow",
+ "t_1_1745490731990": "Configuration",
+ "t_2_1745490735558": "Veuillez saisir le format d'e-mail",
+ "t_3_1745490735059": "Veuillez sélectionner un fournisseur DNS",
+ "t_4_1745490735630": "Veuillez saisir l'intervalle de renouvellement",
+ "t_5_1745490738285": "Veuillez entrer le nom de domaine, il ne peut pas être vide",
+ "t_6_1745490738548": "Veuillez entrer votre email, l'email ne peut pas être vide",
+ "t_7_1745490739917": "Veuillez sélectionner un fournisseur DNS, le fournisseur DNS ne peut pas être vide",
+ "t_8_1745490739319": "Veuillez saisir l'intervalle de renouvellement, l'intervalle de renouvellement ne peut pas être vide",
+ "t_0_1745553910661": "Format de domaine incorrect, veuillez entrer le bon domaine",
+ "t_1_1745553909483": "Format d'email incorrect, veuillez saisir un email valide",
+ "t_2_1745553907423": "L'intervalle de renouvellement ne peut pas être vide",
+ "t_0_1745735774005": "Veuillez saisir le nom de domaine du certificat, plusieurs noms de domaine séparés par des virgules",
+ "t_1_1745735764953": "Boîte aux lettres",
+ "t_2_1745735773668": "Veuillez saisir votre adresse e-mail pour recevoir les notifications de l'autorité de certification",
+ "t_3_1745735765112": "Fournisseur DNS",
+ "t_4_1745735765372": "Ajouter",
+ "t_5_1745735769112": "Intervalle de renouvellement (jours)",
+ "t_6_1745735765205": "Intervalle de renouvellement",
+ "t_7_1745735768326": "jour(s), renouvelé automatiquement à l'expiration",
+ "t_8_1745735765753": "Configuré",
+ "t_9_1745735765287": "Non configuré",
+ "t_10_1745735765165": "Panneau Pagode",
+ "t_11_1745735766456": "Site Web du Panneau Pagode",
+ "t_12_1745735765571": "Panneau 1Panel",
+ "t_13_1745735766084": "1Panel site web",
+ "t_14_1745735766121": "Tencent Cloud CDN",
+ "t_15_1745735768976": "Tencent Cloud COS",
+ "t_16_1745735766712": "Alibaba Cloud CDN",
+ "t_18_1745735765638": "Type de déploiement",
+ "t_19_1745735766810": "Veuillez sélectionner le type de déploiement",
+ "t_20_1745735768764": "Veuillez entrer le chemin de déploiement",
+ "t_21_1745735769154": "Veuillez saisir la commande de préfixe",
+ "t_22_1745735767366": "Veuillez entrer la commande postérieure",
+ "t_23_1745735766455": "Veuillez entrer le nom du site",
+ "t_24_1745735766826": "Veuillez entrer l'ID du site",
+ "t_25_1745735766651": "Veuillez entrer la région",
+ "t_26_1745735767144": "Veuillez entrer le seau",
+ "t_27_1745735764546": "Étape suivante",
+ "t_28_1745735766626": "Sélectionner le type de déploiement",
+ "t_29_1745735768933": "Configurer les paramètres de déploiement",
+ "t_30_1745735764748": "Mode de fonctionnement",
+ "t_31_1745735767891": "Mode de fonctionnement non configuré",
+ "t_32_1745735767156": "Cycle d'exécution non configuré",
+ "t_33_1745735766532": "Durée d'exécution non configurée",
+ "t_34_1745735771147": "Fichier de certificat (format PEM)",
+ "t_35_1745735781545": "Veuillez coller le contenu du fichier de certificat, par exemple :\n-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
+ "t_36_1745735769443": "Fichier de clé privée (format KEY)",
+ "t_37_1745735779980": "Collez le contenu du fichier de clé privée, par exemple:\n-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
+ "t_38_1745735769521": "Le contenu de la clé privée du certificat ne peut pas être vide",
+ "t_39_1745735768565": "Le format de la clé privée du certificat est incorrect",
+ "t_40_1745735815317": "Le contenu du certificat ne peut pas être vide",
+ "t_41_1745735767016": "Format du certificat incorrect",
+ "t_0_1745738961258": "Précédent",
+ "t_1_1745738963744": "Soumettre",
+ "t_2_1745738969878": "Configurer les paramètres de déploiement, le type détermine la configuration des paramètres",
+ "t_0_1745744491696": "Source de l'appareil de déploiement",
+ "t_1_1745744495019": "Veuillez sélectionner la source de l'appareil de déploiement",
+ "t_2_1745744495813": "Veuillez sélectionner le type de déploiement et cliquer sur Suivant",
+ "t_0_1745744902975": "Source de déploiement",
+ "t_1_1745744905566": "Veuillez sélectionner la source de déploiement",
+ "t_2_1745744903722": "Ajouter plus d'appareils",
+ "t_0_1745748292337": "Ajouter une source de déploiement",
+ "t_1_1745748290291": "Source du certificat",
+ "t_2_1745748298902": "La source de déploiement du type actuel est vide, veuillez d'abord ajouter une source de déploiement",
+ "t_3_1745748298161": "Il n'y a pas de nœud de demande dans le processus actuel, veuillez d'abord ajouter un nœud de demande",
+ "t_4_1745748290292": "Soumettre le contenu",
+ "t_0_1745765864788": "Cliquez pour modifier le titre du flux de travail",
+ "t_1_1745765875247": "Supprimer le nœud - 【{name}】",
+ "t_2_1745765875918": "Le nœud actuel contient des nœuds enfants. La suppression affectera d'autres nœuds. Confirmez-vous la suppression ?",
+ "t_3_1745765920953": "Le nœud actuel contient des données de configuration, êtes-vous sûr de vouloir le supprimer ?",
+ "t_4_1745765868807": "Veuillez sélectionner le type de déploiement avant de passer à l'étape suivante",
+ "t_0_1745833934390": "Veuillez sélectionner le type",
+ "t_1_1745833931535": "Hôte",
+ "t_2_1745833931404": "port",
+ "t_3_1745833936770": "Échec de la récupération des données de vue d'ensemble de la page d'accueil",
+ "t_4_1745833932780": "Information de version",
+ "t_5_1745833933241": "Version actuelle",
+ "t_6_1745833933523": "Méthode de mise à jour",
+ "t_7_1745833933278": "Dernière version",
+ "t_8_1745833933552": "Journal des modifications",
+ "t_9_1745833935269": "Code QR du Service Client",
+ "t_10_1745833941691": "Scannez le code QR pour ajouter le service client",
+ "t_11_1745833935261": "Compte officiel WeChat",
+ "t_12_1745833943712": "Scannez pour suivre le compte officiel WeChat",
+ "t_13_1745833933630": "À propos du produit",
+ "t_14_1745833932440": "Serveur SMTP",
+ "t_15_1745833940280": "Veuillez entrer le serveur SMTP",
+ "t_16_1745833933819": "Port SMTP",
+ "t_17_1745833935070": "Veuillez entrer le port SMTP",
+ "t_18_1745833933989": "Connexion SSL/TLS",
+ "t_0_1745887835267": "Veuillez sélectionner la notification de message",
+ "t_1_1745887832941": "Notification",
+ "t_2_1745887834248": "Ajouter un canal de notification",
+ "t_3_1745887835089": "Veuillez saisir le sujet de la notification",
+ "t_4_1745887835265": "Veuillez saisir le contenu de la notification",
+ "t_0_1745895057404": "Modifier les paramètres de notification par e-mail",
+ "t_0_1745920566646": "Sujet de la notification",
+ "t_1_1745920567200": "Contenu de la notification",
+ "t_0_1745936396853": "Cliquez pour obtenir le code de vérification",
+ "t_0_1745999035681": "il reste {days} jours",
+ "t_1_1745999036289": "Expiration prochaine {days} jours",
+ "t_0_1746000517848": "Expiré",
+ "t_0_1746001199409": "Expiré",
+ "t_0_1746004861782": "Le fournisseur DNS est vide",
+ "t_1_1746004861166": "Ajouter un fournisseur DNS",
+ "t_0_1746497662220": "Rafraîchir",
+ "t_0_1746519384035": "En cours",
+ "t_0_1746579648713": "Détails de l'historique d'exécution",
+ "t_0_1746590054456": "État d'exécution",
+ "t_1_1746590060448": "Méthode de Déclenchement",
+ "t_0_1746667592819": "Soumission des informations en cours, veuillez patienter...",
+ "t_1_1746667588689": "Clé",
+ "t_2_1746667592840": "URL du panneau",
+ "t_3_1746667592270": "Ignorer les erreurs de certificat SSL/TLS",
+ "t_4_1746667590873": "Échec de la validation du formulaire",
+ "t_5_1746667590676": "Nouveau flux de travail",
+ "t_6_1746667592831": "Soumission de la demande, veuillez patienter...",
+ "t_7_1746667592468": "Veuillez entrer le nom de domaine correct",
+ "t_8_1746667591924": "Veuillez sélectionner la méthode d'analyse",
+ "t_9_1746667589516": "Actualiser la liste",
+ "t_10_1746667589575": "Joker",
+ "t_11_1746667589598": "Multi-domaine",
+ "t_12_1746667589733": "Populaire",
+ "t_13_1746667599218": "est un fournisseur de certificats SSL gratuits largement utilisé, adapté aux sites personnels et aux environnements de test.",
+ "t_14_1746667590827": "Nombre de domaines pris en charge",
+ "t_15_1746667588493": "pièce",
+ "t_16_1746667591069": "Prise en charge des caractères génériques",
+ "t_17_1746667588785": "soutien",
+ "t_18_1746667590113": "Non pris en charge",
+ "t_19_1746667589295": "Période de validité",
+ "t_20_1746667588453": "jour",
+ "t_21_1746667590834": "Prise en charge des mini-programmes",
+ "t_22_1746667591024": "Sites applicables",
+ "t_23_1746667591989": "*.example.com, *.demo.com",
+ "t_24_1746667583520": "*.example.com",
+ "t_25_1746667590147": "example.com、demo.com",
+ "t_26_1746667594662": "www.example.com, example.com",
+ "t_27_1746667589350": "Gratuit",
+ "t_28_1746667590336": "Postuler maintenant",
+ "t_29_1746667589773": "Adresse du projet",
+ "t_30_1746667591892": "Veuillez entrer le chemin du fichier de certificat",
+ "t_31_1746667593074": "Veuillez entrer le chemin du fichier de clé privée",
+ "t_0_1746673515941": "Le fournisseur DNS actuel est vide, veuillez d'abord ajouter un fournisseur DNS",
+ "t_0_1746676862189": "Échec de l'envoi de la notification de test",
+ "t_1_1746676859550": "Ajouter une Configuration",
+ "t_2_1746676856700": "Pas encore pris en charge",
+ "t_3_1746676857930": "Notification par e-mail",
+ "t_4_1746676861473": "Envoyer des notifications d'alerte par e-mail",
+ "t_5_1746676856974": "Notification DingTalk",
+ "t_6_1746676860886": "Envoyer des notifications d'alarme via le robot DingTalk",
+ "t_7_1746676857191": "Notification WeChat Work",
+ "t_8_1746676860457": "Envoyer des notifications d'alarme via le bot WeCom",
+ "t_9_1746676857164": "Notification Feishu",
+ "t_10_1746676862329": "Envoyer des notifications d'alarme via le bot Feishu",
+ "t_11_1746676859158": "Notification WebHook",
+ "t_12_1746676860503": "Envoyer des notifications d'alarme via WebHook",
+ "t_13_1746676856842": "Canal de notification",
+ "t_14_1746676859019": "Canaux de notification configurés",
+ "t_15_1746676856567": "Désactivé",
+ "t_16_1746676855270": "Test",
+ "t_0_1746677882486": "Dernier état d'exécution",
+ "t_0_1746697487119": "Le nom de domaine ne peut pas être vide",
+ "t_1_1746697485188": "L'e-mail ne peut pas être vide",
+ "t_2_1746697487164": "Alibaba Cloud OSS",
+ "t_0_1746754500246": "Fournisseur d'hébergement",
+ "t_1_1746754499371": "Source de l'API",
+ "t_2_1746754500270": "Type d'API",
+ "t_0_1746760933542": "Erreur de requête",
+ "t_0_1746773350551": "{0} résultats",
+ "t_1_1746773348701": "Non exécuté",
+ "t_2_1746773350970": "Workflow automatisé",
+ "t_3_1746773348798": "Quantité totale",
+ "t_4_1746773348957": "Échec de l'exécution",
+ "t_5_1746773349141": "Expire bientôt",
+ "t_6_1746773349980": "Surveillance en temps réel",
+ "t_7_1746773349302": "Quantité anormale",
+ "t_8_1746773351524": "Récents enregistrements d'exécution de flux de travail",
+ "t_9_1746773348221": "Voir tout",
+ "t_10_1746773351576": "Aucun enregistrement d'exécution de flux de travail",
+ "t_11_1746773349054": "Créer un workflow",
+ "t_12_1746773355641": "Cliquez pour créer un flux de travail automatisé afin d'améliorer l'efficacité",
+ "t_13_1746773349526": "Demander un certificat",
+ "t_14_1746773355081": "Cliquez pour demander et gérer les certificats SSL afin d'assurer la sécurité",
+ "t_15_1746773358151": "Cliquez pour configurer la surveillance du site et suivre l'état d'exécution en temps réel",
+ "t_16_1746773356568": "Un seul canal de notification par e-mail peut être configuré au maximum",
+ "t_17_1746773351220": "Confirmer le canal de notification {0}",
+ "t_18_1746773355467": "Les canaux de notification {0} commenceront à envoyer des alertes.",
+ "t_19_1746773352558": "Le canal de notification actuel ne prend pas en charge les tests",
+ "t_20_1746773356060": "Envoi d'un e-mail de test, veuillez patienter...",
+ "t_21_1746773350759": "E-mail de test",
+ "t_22_1746773360711": "Envoyer un e-mail de test à la boîte mail configurée actuellement, continuer ?",
+ "t_23_1746773350040": "Confirmation de suppression",
+ "t_24_1746773349367": "Confirmer la suppression",
+ "t_25_1746773349596": "Veuillez entrer le nom",
+ "t_26_1746773353409": "Veuillez saisir le bon port SMTP",
+ "t_27_1746773352584": "Veuillez entrer le mot de passe utilisateur",
+ "t_28_1746773354048": "Veuillez entrer l'e-mail correct de l'expéditeur",
+ "t_29_1746773351834": "Veuillez entrer le bon e-mail de réception",
+ "t_30_1746773350013": "E-mail de l'expéditeur",
+ "t_31_1746773349857": "Recevoir un e-mail",
+ "t_32_1746773348993": "DingTalk",
+ "t_33_1746773350932": "WeChat Work",
+ "t_34_1746773350153": "Feishu",
+ "t_35_1746773362992": "Un outil de gestion du cycle de vie complet des certificats SSL intégrant la demande, la gestion, le déploiement et la surveillance.",
+ "t_36_1746773348989": "Demande de certificat",
+ "t_37_1746773356895": "Support pour obtenir des certificats de Let's Encrypt via le protocole ACME",
+ "t_38_1746773349796": "Gestion des certificats",
+ "t_39_1746773358932": "Gestion centralisée de tous les certificats SSL, y compris les certificats téléchargés manuellement et appliqués automatiquement",
+ "t_40_1746773352188": "Déploiement de certificat",
+ "t_41_1746773364475": "Prise en charge du déploiement de certificats en un clic sur plusieurs plateformes telles que Alibaba Cloud, Tencent Cloud, Pagoda Panel, 1Panel, etc.",
+ "t_42_1746773348768": "Surveillance du site",
+ "t_43_1746773359511": "Surveillance en temps réel de l'état des certificats SSL du site pour prévenir l'expiration des certificats",
+ "t_44_1746773352805": "Tâche automatisée :",
+ "t_45_1746773355717": "Prend en charge les tâches planifiées, renouvellement automatique des certificats et déploiement",
+ "t_46_1746773350579": "Prise en charge multiplateforme",
+ "t_47_1746773360760": "Prend en charge les méthodes de vérification DNS pour plusieurs fournisseurs DNS (Alibaba Cloud, Tencent Cloud, etc.)"
+}
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/locales/model/jaJP.json b/frontend/apps/allin-ssl/src/locales/model/jaJP.json
new file mode 100644
index 0000000..9717d0e
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/locales/model/jaJP.json
@@ -0,0 +1,490 @@
+{
+ "t_0_1746773763967": "{0}、通知チャネルを削除してもよろしいですか?",
+ "t_1_1746773763643": "Let's EncryptなどのCAが無料の証明書を自動的に申請する",
+ "t_0_1744098811152": "警告:未知のエリアに進入しました。アクセスしようとしたページは存在しません。ボタンをクリックしてホームページに戻ってください。",
+ "t_1_1744098801860": "ホームに戻る",
+ "t_2_1744098804908": "安全注意:これが誤りだと思われる場合は、すぐに管理者に連絡してください",
+ "t_3_1744098802647": "メインメニューを展開する",
+ "t_4_1744098802046": "折りたたみメインメニュー",
+ "t_0_1744164843238": "AllinSSLへようこそ、SSL証明書の効率的な管理",
+ "t_1_1744164835667": "AllinSSL",
+ "t_2_1744164839713": "アカウントログイン",
+ "t_3_1744164839524": "ユーザー名を入力してください",
+ "t_4_1744164840458": "パスワードを入力してください",
+ "t_5_1744164840468": "パスワードを覚える",
+ "t_6_1744164838900": "パスワードを忘れたら",
+ "t_7_1744164838625": "ログイン中",
+ "t_8_1744164839833": "ログイン",
+ "t_0_1744168657526": "ログアウト",
+ "t_0_1744258111441": "ホーム",
+ "t_1_1744258113857": "自動デプロイメント",
+ "t_2_1744258111238": "証明書管理",
+ "t_3_1744258111182": "証明書申請",
+ "t_4_1744258111238": "認証API管理",
+ "t_5_1744258110516": "監視",
+ "t_6_1744258111153": "設定",
+ "t_0_1744861190562": "ワークフローリストの返信",
+ "t_1_1744861189113": "実行",
+ "t_2_1744861190040": "保存する",
+ "t_3_1744861190932": "設定するノードを選んでください",
+ "t_4_1744861194395": "左側のフローウォークダイアグラムのノードをクリックして設定してください",
+ "t_5_1744861189528": "始めます",
+ "t_6_1744861190121": "ノードを選択していない",
+ "t_7_1744861189625": "設定が保存されました",
+ "t_8_1744861189821": "ワークフローの開始",
+ "t_9_1744861189580": "選択ノード:",
+ "t_0_1744870861464": "ノード",
+ "t_1_1744870861944": "ノード設定",
+ "t_2_1744870863419": "左側のノードを選択して設定してください",
+ "t_3_1744870864615": "このノードタイプの設定コンポーネントが見つかりませんでした",
+ "t_4_1744870861589": "キャンセル",
+ "t_5_1744870862719": "確定",
+ "t_0_1744875938285": "分ごとに",
+ "t_1_1744875938598": "毎時間",
+ "t_2_1744875938555": "毎日",
+ "t_3_1744875938310": "毎月",
+ "t_4_1744875940750": "自動実行",
+ "t_5_1744875940010": "手動実行",
+ "t_0_1744879616135": "テストPID",
+ "t_1_1744879616555": "テストPIDを入力してください",
+ "t_2_1744879616413": "実行サイクル",
+ "t_3_1744879615723": "分",
+ "t_4_1744879616168": "分を入力してください",
+ "t_5_1744879615277": "時間",
+ "t_6_1744879616944": "時間を入力してください",
+ "t_7_1744879615743": "日付",
+ "t_8_1744879616493": "日付を選択してください",
+ "t_0_1744942117992": "毎週",
+ "t_1_1744942116527": "月曜日",
+ "t_2_1744942117890": "火曜日",
+ "t_3_1744942117885": "水曜日",
+ "t_4_1744942117738": "木曜日",
+ "t_5_1744942117167": "金曜日",
+ "t_6_1744942117815": "土曜日",
+ "t_7_1744942117862": "日曜日",
+ "t_0_1744958839535": "ドメイン名を入力してください",
+ "t_1_1744958840747": "メールを入力してください",
+ "t_2_1744958840131": "メールフォーマットが不正です",
+ "t_3_1744958840485": "DNSプロバイダーの認証を選択してください",
+ "t_4_1744958838951": "ローカルデプロイメント",
+ "t_5_1744958839222": "SSHデプロイメント",
+ "t_6_1744958843569": "宝塔パネル/1パネル(パネル証明書にデプロイ)",
+ "t_7_1744958841708": "1パネル(指定のウェブサイトプロジェクトにデプロイ)",
+ "t_8_1744958841658": "テンセントクラウドCDN/アリクラウドCDN",
+ "t_9_1744958840634": "腾讯クラウドWAF",
+ "t_10_1744958860078": "アリクラウドWAF",
+ "t_11_1744958840439": "この自動申請証明書",
+ "t_12_1744958840387": "オプションの証明書リスト",
+ "t_13_1744958840714": "PEM(*.pem、*.crt、*.key)",
+ "t_14_1744958839470": "PFX(*.pfx)",
+ "t_15_1744958840790": "JKS (*.jks)",
+ "t_16_1744958841116": "POSIX bash(Linux/macOS)",
+ "t_17_1744958839597": "コマンドライン(Windows)",
+ "t_18_1744958839895": "PowerShell(ウィンドウズ)",
+ "t_19_1744958839297": "証明書1",
+ "t_20_1744958839439": "証明書2",
+ "t_21_1744958839305": "サーバー1",
+ "t_22_1744958841926": "サーバー2",
+ "t_23_1744958838717": "パネル1",
+ "t_24_1744958845324": "パネル2",
+ "t_25_1744958839236": "ウェブサイト1",
+ "t_26_1744958839682": "ウェブサイト2",
+ "t_27_1744958840234": "テンセントクラウド1",
+ "t_28_1744958839760": "アリyun 1",
+ "t_29_1744958838904": "日",
+ "t_30_1744958843864": "証明書のフォーマットが不正です。完全な証明書のヘッダおよびフッタ識別子が含まれているか確認してください。",
+ "t_31_1744958844490": "プライベートキーフォーマットが不正です。完全なプライベートキーヘッダおよびフッタ識別子が含まれているか確認してください。",
+ "t_0_1745215914686": "自動化名前",
+ "t_2_1745215915397": "自動",
+ "t_3_1745215914237": "手動",
+ "t_4_1745215914951": "有効状態",
+ "t_5_1745215914671": "有効にする",
+ "t_6_1745215914104": "停止",
+ "t_7_1745215914189": "作成時間",
+ "t_8_1745215914610": "操作",
+ "t_9_1745215914666": "実行履歴",
+ "t_10_1745215914342": "実行",
+ "t_11_1745215915429": "編集",
+ "t_12_1745215914312": "削除",
+ "t_13_1745215915455": "ワークフローの実行",
+ "t_14_1745215916235": "ワークフローエグゼクション成功",
+ "t_15_1745215915743": "ワークフローエクセキュション失敗",
+ "t_16_1745215915209": "ワークフローを削除する",
+ "t_17_1745215915985": "ワークフローの削除が成功しました",
+ "t_18_1745215915630": "ワークフローの削除に失敗しました",
+ "t_0_1745227838699": "新しい自動デプロイメント",
+ "t_1_1745227838776": "自動化名前を入力してください",
+ "t_2_1745227839794": "{name}ワークフローの実行を確認しますか?",
+ "t_3_1745227841567": "{name}のワークフローの削除を確認しますか?この操作は元に戻せません。",
+ "t_4_1745227838558": "実行時間",
+ "t_5_1745227839906": "終了時間",
+ "t_6_1745227838798": "実行方法",
+ "t_7_1745227838093": "状態",
+ "t_8_1745227838023": "成功",
+ "t_9_1745227838305": "失敗",
+ "t_10_1745227838234": "実行中",
+ "t_11_1745227838422": "不明",
+ "t_12_1745227838814": "詳細",
+ "t_13_1745227838275": "証明書のアップロード",
+ "t_14_1745227840904": "証明書ドメイン名またはブランド名を入力して検索してください",
+ "t_15_1745227839354": "共同に",
+ "t_16_1745227838930": "本",
+ "t_17_1745227838561": "ドメイン名",
+ "t_18_1745227838154": "ブランド",
+ "t_19_1745227839107": "残り日数",
+ "t_20_1745227838813": "期限時間",
+ "t_21_1745227837972": "出典",
+ "t_22_1745227838154": "自動申請",
+ "t_23_1745227838699": "手動アップロード",
+ "t_24_1745227839508": "時間を追加",
+ "t_25_1745227838080": "ダウンロード",
+ "t_27_1745227838583": "切れ替わります",
+ "t_28_1745227837903": "通常",
+ "t_29_1745227838410": "証明書を削除する",
+ "t_30_1745227841739": "この証明書を削除してもよろしいですか?この操作は元に戻せません。",
+ "t_31_1745227838461": "確認してください",
+ "t_32_1745227838439": "証明書名前",
+ "t_33_1745227838984": "証明書の名前を入力してください",
+ "t_34_1745227839375": "証明書の内容(PEM)",
+ "t_35_1745227839208": "証明書の内容を入力してください",
+ "t_36_1745227838958": "プライベートキー内容(KEY)",
+ "t_37_1745227839669": "プライベートキーの内容を入力してください",
+ "t_38_1745227838813": "ダウンロード失敗",
+ "t_39_1745227838696": "アップロードに失敗しました",
+ "t_40_1745227838872": "削除失敗",
+ "t_0_1745289355714": "認証APIを追加する",
+ "t_1_1745289356586": "認証APIの名前またはタイプを入力してください",
+ "t_2_1745289353944": "名称",
+ "t_3_1745289354664": "認証APIタイプ",
+ "t_4_1745289354902": "編集権限API",
+ "t_5_1745289355718": "認証APIの削除",
+ "t_6_1745289358340": "この認証されたAPIを削除してもよろしいですか?この操作は元に戻すことができません。",
+ "t_7_1745289355714": "追加失敗",
+ "t_8_1745289354902": "アップデート失敗",
+ "t_9_1745289355714": "{days}日経過",
+ "t_10_1745289354650": "監視管理",
+ "t_11_1745289354516": "監視を追加する",
+ "t_12_1745289356974": "監視名前缀またはドメインを入力して検索してください",
+ "t_13_1745289354528": "モニタ名称",
+ "t_14_1745289354902": "証明書ドメイン",
+ "t_15_1745289355714": "証明書発行機関",
+ "t_16_1745289354902": "証明書の状態",
+ "t_17_1745289355715": "証明書の有効期限",
+ "t_18_1745289354598": "警報チャネル",
+ "t_19_1745289354676": "最後のチェック時刻",
+ "t_20_1745289354598": "編集監視",
+ "t_21_1745289354598": "削除を確認してください",
+ "t_22_1745289359036": "削除後は復元できません。この監視を削除する場合は確定しますか?",
+ "t_23_1745289355716": "変更失敗",
+ "t_24_1745289355715": "設定失敗",
+ "t_25_1745289355721": "認証コードを入力してください",
+ "t_26_1745289358341": "フォームのバリデーションに失敗しました、記入内容を確認してください",
+ "t_27_1745289355721": "認証API名前を入力してください",
+ "t_28_1745289356040": "認証APIタイプを選択してください",
+ "t_29_1745289355850": "サーバーIPを入力してください",
+ "t_30_1745289355718": "SSHポートを入力してください",
+ "t_31_1745289355715": "SSHキーを入力してください",
+ "t_32_1745289356127": "宝塔アドレスを入力してください",
+ "t_33_1745289355721": "APIキーを入力してください",
+ "t_34_1745289356040": "1panelのアドレスを入力してください",
+ "t_35_1745289355714": "AccessKeyIdを入力してください",
+ "t_36_1745289355715": "AccessKeySecretを入力してください",
+ "t_37_1745289356041": "SecretIdを入力してください",
+ "t_38_1745289356419": "SecretKeyを入力してください",
+ "t_39_1745289354902": "更新成功",
+ "t_40_1745289355715": "追加成功",
+ "t_41_1745289354902": "タイプ",
+ "t_42_1745289355715": "サーバーIP",
+ "t_43_1745289354598": "SSHポート",
+ "t_44_1745289354583": "ユーザー名",
+ "t_45_1745289355714": "認証方法",
+ "t_46_1745289355723": "パスワード認証",
+ "t_47_1745289355715": "キー認証",
+ "t_48_1745289355714": "パスワード",
+ "t_49_1745289355714": "SSHプライベートキー",
+ "t_50_1745289355715": "SSHプライベートキーを入力してください",
+ "t_51_1745289355714": "プライベートキーワード",
+ "t_52_1745289359565": "プライベートキーにパスワードがある場合、入力してください",
+ "t_53_1745289356446": "宝塔パネルのアドレス",
+ "t_54_1745289358683": "宝塔パネルのアドレスを入力してください、例えば:https://bt.example.com",
+ "t_55_1745289355715": "APIキー",
+ "t_56_1745289355714": "1パネルのアドレス",
+ "t_57_1745289358341": "1panelのアドレスを入力してください、例えば:https://1panel.example.com",
+ "t_58_1745289355721": "アクセスキーIDを入力してください",
+ "t_59_1745289356803": "アクセスキーのシークレットを入力してください",
+ "t_60_1745289355715": "監視名前を入力してください",
+ "t_61_1745289355878": "ドメイン/IPを入力してください",
+ "t_62_1745289360212": "検査サイクルを選択してください",
+ "t_63_1745289354897": "5分",
+ "t_64_1745289354670": "10分",
+ "t_65_1745289354591": "15分",
+ "t_66_1745289354655": "30分",
+ "t_67_1745289354487": "60分",
+ "t_68_1745289354676": "メール",
+ "t_69_1745289355721": "ショートメッセージ",
+ "t_70_1745289354904": "ライン",
+ "t_71_1745289354583": "ドメイン/IP",
+ "t_72_1745289355715": "検査サイクル",
+ "t_73_1745289356103": "警報チャンネルを選択してください",
+ "t_0_1745289808449": "認証APIの名前を入力してください",
+ "t_0_1745294710530": "監視を削除する",
+ "t_0_1745295228865": "更新時刻",
+ "t_0_1745317313835": "サーバーIPアドレスの形式が不正です",
+ "t_1_1745317313096": "ポートフォーマットエラー",
+ "t_2_1745317314362": "パネルURLアドレスの形式が不正です",
+ "t_3_1745317313561": "パネルAPIキーを入力してください",
+ "t_4_1745317314054": "阿里云アクセスキーIDを入力してください",
+ "t_5_1745317315285": "阿里云のAccessKeySecretを入力してください",
+ "t_6_1745317313383": "腾讯云SecretIdを入力してください",
+ "t_7_1745317313831": "腾讯雲のSecretKeyを入力してください",
+ "t_0_1745457486299": "有効",
+ "t_1_1745457484314": "停止しました",
+ "t_2_1745457488661": "手動モードに切り替え",
+ "t_3_1745457486983": "自動モードに切り替える",
+ "t_4_1745457497303": "手動モードに切り替えた後、ワークフローは自動的に実行されなくなりますが、手動で実行することは可能です",
+ "t_5_1745457494695": "自動モードに切り替えた後、ワークフローは設定された時間に従って自動的に実行されます",
+ "t_6_1745457487560": "現在のワークフローを閉じる",
+ "t_7_1745457487185": "現在のワークフローを有効にする",
+ "t_8_1745457496621": "閉じると、ワークフローは自動的に実行されなくなり、手動でも実行できません。続行しますか?",
+ "t_9_1745457500045": "有効にすると、ワークフロー設定が自動的に実行されるか、手動で実行されます。続行しますか?",
+ "t_10_1745457486451": "ワークフローの追加に失敗しました",
+ "t_11_1745457488256": "ワークフローの実行方法の設定に失敗しました",
+ "t_12_1745457489076": "ワークフローの失敗を有効または無効にする",
+ "t_13_1745457487555": "ワークフローの実行に失敗しました",
+ "t_14_1745457488092": "ワークフローの削除に失敗しました",
+ "t_15_1745457484292": "終了",
+ "t_16_1745457491607": "ログアウトしようとしています。ログアウトしますか?",
+ "t_17_1745457488251": "ログアウト中です、少々お待ちください...",
+ "t_18_1745457490931": "メール通知を追加",
+ "t_19_1745457484684": "保存が成功しました",
+ "t_20_1745457485905": "削除に成功しました",
+ "t_0_1745464080226": "システム設定の取得に失敗しました",
+ "t_1_1745464079590": "設定の保存に失敗しました",
+ "t_2_1745464077081": "通知設定の取得に失敗しました",
+ "t_3_1745464081058": "通知設定の保存に失敗しました",
+ "t_4_1745464075382": "通知チャネルリストの取得に失敗しました",
+ "t_5_1745464086047": "メール通知チャネルの追加に失敗しました",
+ "t_6_1745464075714": "通知チャネルの更新に失敗しました",
+ "t_7_1745464073330": "通知チャネルの削除に失敗しました",
+ "t_8_1745464081472": "バージョン更新の確認に失敗しました",
+ "t_9_1745464078110": "設定を保存",
+ "t_10_1745464073098": "基本設定",
+ "t_0_1745474945127": "テンプレートを選択",
+ "t_0_1745490735213": "ワークフロー名を入力してください",
+ "t_1_1745490731990": "設定",
+ "t_2_1745490735558": "メール形式を入力してください",
+ "t_3_1745490735059": "DNSプロバイダーを選択してください",
+ "t_4_1745490735630": "更新間隔を入力してください",
+ "t_5_1745490738285": "ドメイン名を入力してください。ドメイン名は空にできません",
+ "t_6_1745490738548": "メールアドレスを入力してください、メールアドレスは空にできません",
+ "t_7_1745490739917": "DNSプロバイダーを選択してください。DNSプロバイダーは空にできません",
+ "t_8_1745490739319": "更新間隔を入力してください。更新間隔は空にできません",
+ "t_0_1745553910661": "ドメイン形式が間違っています。正しいドメインを入力してください",
+ "t_1_1745553909483": "メールの形式が正しくありません。正しいメールアドレスを入力してください",
+ "t_2_1745553907423": "更新間隔は空にできません",
+ "t_0_1745735774005": "証明書のドメイン名を入力してください。複数のドメイン名はカンマで区切ります",
+ "t_1_1745735764953": "メールボックス",
+ "t_2_1745735773668": "証明書発行機関からのメール通知を受け取るためにメールアドレスを入力してください",
+ "t_3_1745735765112": "DNSプロバイダー",
+ "t_4_1745735765372": "追加",
+ "t_5_1745735769112": "更新間隔 (日)",
+ "t_6_1745735765205": "更新間隔",
+ "t_7_1745735768326": "日、期限切れ後に自動更新",
+ "t_8_1745735765753": "設定済み",
+ "t_9_1745735765287": "未設定",
+ "t_10_1745735765165": "パゴダパネル",
+ "t_11_1745735766456": "宝塔パネルのウェブサイト",
+ "t_12_1745735765571": "1Panelパネル",
+ "t_13_1745735766084": "1Panelウェブサイト",
+ "t_14_1745735766121": "Tencent Cloud CDN",
+ "t_15_1745735768976": "Tencent Cloud COS",
+ "t_16_1745735766712": "阿里雲CDN",
+ "t_18_1745735765638": "展開タイプ",
+ "t_19_1745735766810": "展開タイプを選択してください",
+ "t_20_1745735768764": "展開パスを入力してください",
+ "t_21_1745735769154": "前置コマンドを入力してください",
+ "t_22_1745735767366": "後置コマンドを入力してください",
+ "t_23_1745735766455": "サイト名を入力してください",
+ "t_24_1745735766826": "サイトIDを入力してください",
+ "t_25_1745735766651": "地域を入力してください",
+ "t_26_1745735767144": "バケットを入力してください",
+ "t_27_1745735764546": "次のステップ",
+ "t_28_1745735766626": "展開タイプを選択",
+ "t_29_1745735768933": "展開パラメータを設定する",
+ "t_30_1745735764748": "動作モード",
+ "t_31_1745735767891": "動作モードが設定されていません",
+ "t_32_1745735767156": "実行周期が設定されていません",
+ "t_33_1745735766532": "実行時間が設定されていません",
+ "t_34_1745735771147": "証明書ファイル(PEM形式)",
+ "t_35_1745735781545": "証明書ファイルの内容を貼り付けてください。例:\n-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
+ "t_36_1745735769443": "秘密鍵ファイル(KEY 形式)",
+ "t_37_1745735779980": "秘密キーファイルの内容を貼り付けてください、例:\n-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
+ "t_38_1745735769521": "証明書の秘密鍵の内容は空にできません",
+ "t_39_1745735768565": "証明書の秘密鍵の形式が正しくありません",
+ "t_40_1745735815317": "証明書の内容は空にできません",
+ "t_41_1745735767016": "証明書の形式が正しくありません",
+ "t_0_1745738961258": "前へ",
+ "t_1_1745738963744": "提出",
+ "t_2_1745738969878": "展開パラメータを設定し、タイプによってパラメータの設定が決まる",
+ "t_0_1745744491696": "展開デバイスのソース",
+ "t_1_1745744495019": "展開デバイスのソースを選んでください",
+ "t_2_1745744495813": "展開タイプを選択して、次へをクリックしてください",
+ "t_0_1745744902975": "デプロイソース",
+ "t_1_1745744905566": "デプロイソースを選択してください",
+ "t_2_1745744903722": "さらにデバイスを追加",
+ "t_0_1745748292337": "デプロイソースの追加",
+ "t_1_1745748290291": "証明書の出所",
+ "t_2_1745748298902": "現在のタイプのデプロイソースが空です、デプロイソースを追加してください",
+ "t_3_1745748298161": "現在のプロセスには申請ノードがありません、まず申請ノードを追加してください",
+ "t_4_1745748290292": "提出内容",
+ "t_0_1745765864788": "ワークフロータイトルを編集するにはクリックします",
+ "t_1_1745765875247": "ノード削除 - 【{name}】",
+ "t_2_1745765875918": "現在のノードには子ノードが存在します。削除すると他のノードに影響を与えます。削除してもよろしいですか?",
+ "t_3_1745765920953": "現在のノードには設定データがあります。削除してもよろしいですか?",
+ "t_4_1745765868807": "デプロイメントタイプを選択してから、次に進んでください",
+ "t_0_1745833934390": "タイプを選択してください",
+ "t_1_1745833931535": "ホスト",
+ "t_2_1745833931404": "ポート",
+ "t_3_1745833936770": "ホームページの概要データの取得に失敗しました",
+ "t_4_1745833932780": "バージョン情報",
+ "t_5_1745833933241": "現在のバージョン",
+ "t_6_1745833933523": "更新方法",
+ "t_7_1745833933278": "最新バージョン",
+ "t_8_1745833933552": "更新履歴",
+ "t_9_1745833935269": "カスタマーサービスQRコード",
+ "t_10_1745833941691": "QRコードをスキャンしてカスタマーサービスを追加",
+ "t_11_1745833935261": "WeChat公式アカウント",
+ "t_12_1745833943712": "QRコードをスキャンしてWeChat公式アカウントをフォロー",
+ "t_13_1745833933630": "製品について",
+ "t_14_1745833932440": "SMTPサーバー",
+ "t_15_1745833940280": "SMTPサーバーを入力してください",
+ "t_16_1745833933819": "SMTPポート",
+ "t_17_1745833935070": "SMTPポートを入力してください",
+ "t_18_1745833933989": "SSL/TLS接続",
+ "t_0_1745887835267": "メッセージ通知を選択してください",
+ "t_1_1745887832941": "通知",
+ "t_2_1745887834248": "通知チャネルを追加",
+ "t_3_1745887835089": "通知の件名を入力してください",
+ "t_4_1745887835265": "通知内容を入力してください",
+ "t_0_1745895057404": "メール通知設定の変更",
+ "t_0_1745920566646": "通知主題",
+ "t_1_1745920567200": "通知内容",
+ "t_0_1745936396853": "確認コードを取得するにはクリックしてください",
+ "t_0_1745999035681": "残り{days}日",
+ "t_1_1745999036289": "まもなく期限切れ {days} 日",
+ "t_0_1746000517848": "期限切れ",
+ "t_0_1746001199409": "期限切れ",
+ "t_0_1746004861782": "DNSプロバイダーが空です",
+ "t_1_1746004861166": "DNSプロバイダーを追加",
+ "t_0_1746497662220": "更新",
+ "t_0_1746519384035": "実行中",
+ "t_0_1746579648713": "実行履歴の詳細",
+ "t_0_1746590054456": "実行状態",
+ "t_1_1746590060448": "トリガー方式",
+ "t_0_1746667592819": "情報を送信中、少々お待ちください...",
+ "t_1_1746667588689": "キー",
+ "t_2_1746667592840": "パネルURL",
+ "t_3_1746667592270": "SSL/TLS証明書のエラーを無視する",
+ "t_4_1746667590873": "フォーム検証失敗",
+ "t_5_1746667590676": "新しいワークフロー",
+ "t_6_1746667592831": "申請を提出しています、少々お待ちください...",
+ "t_7_1746667592468": "正しいドメイン名を入力してください",
+ "t_8_1746667591924": "解析方法を選択してください",
+ "t_9_1746667589516": "リストを更新",
+ "t_10_1746667589575": "ワイルドカード",
+ "t_11_1746667589598": "マルチドメイン",
+ "t_12_1746667589733": "人気",
+ "t_13_1746667599218": "広く使用されている無料のSSL証明書プロバイダーで、個人のウェブサイトやテスト環境に適しています。",
+ "t_14_1746667590827": "サポートされているドメインの数",
+ "t_15_1746667588493": "個",
+ "t_16_1746667591069": "ワイルドカードをサポート",
+ "t_17_1746667588785": "サポート",
+ "t_18_1746667590113": "サポートされていません",
+ "t_19_1746667589295": "有効期間",
+ "t_20_1746667588453": "天",
+ "t_21_1746667590834": "ミニプログラムをサポート",
+ "t_22_1746667591024": "対応サイト",
+ "t_23_1746667591989": "*.example.com、*.demo.com",
+ "t_24_1746667583520": "*.example.com",
+ "t_25_1746667590147": "example.com、demo.com",
+ "t_26_1746667594662": "www.example.com、example.com",
+ "t_27_1746667589350": "無料",
+ "t_28_1746667590336": "今すぐ申し込む",
+ "t_29_1746667589773": "プロジェクトアドレス",
+ "t_30_1746667591892": "証明書ファイルのパスを入力してください",
+ "t_31_1746667593074": "秘密鍵ファイルのパスを入力してください",
+ "t_0_1746673515941": "現在のDNSプロバイダーが空です。まずDNSプロバイダーを追加してください",
+ "t_0_1746676862189": "テスト通知の送信に失敗しました",
+ "t_1_1746676859550": "設定を追加",
+ "t_2_1746676856700": "まだサポートされていません",
+ "t_3_1746676857930": "メール通知",
+ "t_4_1746676861473": "メールでアラート通知を送信する",
+ "t_5_1746676856974": "DingTalk通知",
+ "t_6_1746676860886": "DingTalkロボットを通じてアラーム通知を送信する",
+ "t_7_1746676857191": "企業WeChat通知",
+ "t_8_1746676860457": "WeComボットでアラーム通知を送信",
+ "t_9_1746676857164": "Feishu通知",
+ "t_10_1746676862329": "飛書ロボットでアラーム通知を送信する",
+ "t_11_1746676859158": "WebHook通知",
+ "t_12_1746676860503": "WebHookを介してアラーム通知を送信する",
+ "t_13_1746676856842": "通知チャネル",
+ "t_14_1746676859019": "設定済みの通知チャネル",
+ "t_15_1746676856567": "無効化",
+ "t_16_1746676855270": "テスト",
+ "t_0_1746677882486": "最後の実行状態",
+ "t_0_1746697487119": "ドメイン名は空にできません",
+ "t_1_1746697485188": "メールアドレスは空にできません",
+ "t_2_1746697487164": "アリババクラウドOSS",
+ "t_0_1746754500246": "ホスティングプロバイダー",
+ "t_1_1746754499371": "APIソース",
+ "t_2_1746754500270": "APIタイプ",
+ "t_0_1746760933542": "リクエストエラー",
+ "t_0_1746773350551": "合計{0}件",
+ "t_1_1746773348701": "未実行",
+ "t_2_1746773350970": "自動化ワークフロー",
+ "t_3_1746773348798": "総数量",
+ "t_4_1746773348957": "実行に失敗しました",
+ "t_5_1746773349141": "まもなく期限切れ",
+ "t_6_1746773349980": "リアルタイム監視",
+ "t_7_1746773349302": "異常数量",
+ "t_8_1746773351524": "最近のワークフロー実行記録",
+ "t_9_1746773348221": "すべて表示",
+ "t_10_1746773351576": "ワークフロー実行記録がありません",
+ "t_11_1746773349054": "ワークフローの作成",
+ "t_12_1746773355641": "効率を向上させるために自動化されたワークフローを作成するにはクリックしてください",
+ "t_13_1746773349526": "証明書を申請する",
+ "t_14_1746773355081": "SSL証明書の申請と管理をクリックして、セキュリティを確保します",
+ "t_15_1746773358151": "クリックしてウェブサイトの監視を設定し、実行状態をリアルタイムで把握します",
+ "t_16_1746773356568": "最大で1つのメール通知チャネルしか設定できません",
+ "t_17_1746773351220": "{0}通知チャネルの確認",
+ "t_18_1746773355467": "{0}通知チャネルは、アラート通知の送信を開始します。",
+ "t_19_1746773352558": "現在の通知チャネルはテストをサポートしていません",
+ "t_20_1746773356060": "テストメールを送信しています、少々お待ちください...",
+ "t_21_1746773350759": "テストメール",
+ "t_22_1746773360711": "現在設定されているメールボックスにテストメールを送信します。続けますか?",
+ "t_23_1746773350040": "削除の確認",
+ "t_24_1746773349367": "削除しますか",
+ "t_25_1746773349596": "名前を入力してください",
+ "t_26_1746773353409": "正しいSMTPポートを入力してください",
+ "t_27_1746773352584": "ユーザーパスワードを入力してください",
+ "t_28_1746773354048": "正しい送信者のメールアドレスを入力してください",
+ "t_29_1746773351834": "正しい受信メールを入力してください",
+ "t_30_1746773350013": "送信者のメール",
+ "t_31_1746773349857": "受信メール",
+ "t_32_1746773348993": "ディンタン",
+ "t_33_1746773350932": "WeChat Work",
+ "t_34_1746773350153": "飛書",
+ "t_35_1746773362992": "SSL証明書の申請、管理、展開、監視を統合したライフサイクル管理ツール。",
+ "t_36_1746773348989": "証明書申請",
+ "t_37_1746773356895": "ACMEプロトコルを介してLet's Encryptから証明書を取得する",
+ "t_38_1746773349796": "証明書管理",
+ "t_39_1746773358932": "すべてのSSL証明書を一元管理、手動アップロードおよび自動申請の証明書を含む",
+ "t_40_1746773352188": "証明書の展開",
+ "t_41_1746773364475": "ワンクリックでの証明書のデプロイを複数のプラットフォームでサポート、例えばアリババクラウド、テンセントクラウド、Pagoda Panel、1Panelなど",
+ "t_42_1746773348768": "サイト監視",
+ "t_43_1746773359511": "サイトのSSL証明書の状態をリアルタイムで監視し、証明書の有効期限切れを事前に警告します",
+ "t_44_1746773352805": "自動化タスク:",
+ "t_45_1746773355717": "スケジュールされたタスクをサポートし、証明書を自動的に更新して展開します",
+ "t_46_1746773350579": "マルチプラットフォーム対応",
+ "t_47_1746773360760": "複数のDNSプロバイダー(アリババクラウド、テンセントクラウドなど)のDNS検証方法をサポート"
+}
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/locales/model/koKR.json b/frontend/apps/allin-ssl/src/locales/model/koKR.json
new file mode 100644
index 0000000..dcfc1f4
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/locales/model/koKR.json
@@ -0,0 +1,490 @@
+{
+ "t_0_1746773763967": "{0}, 알림 채널을 삭제하시겠습니까?",
+ "t_1_1746773763643": "Let's Encrypt 등의 CA에서 무료 인증서를 자동으로 신청",
+ "t_0_1744098811152": "경고: 알 수 없는 영역에 진입했습니다. 방문하려는 페이지가 존재하지 않습니다. 버튼을 클릭하여 홈페이지로 돌아가세요。",
+ "t_1_1744098801860": "홈으로 돌아가기",
+ "t_2_1744098804908": "안전 유의사항: 이가 오류라면 즉시 관리자에게 연락하십시오",
+ "t_3_1744098802647": "메인 메뉴 펼치기",
+ "t_4_1744098802046": "접기 메인 메뉴",
+ "t_0_1744164843238": "AllinSSL을 환영합니다, SSL 셀프리피켓 효율적 관리",
+ "t_1_1744164835667": "AllinSSL",
+ "t_2_1744164839713": "계정 로그인",
+ "t_3_1744164839524": "사용자 이름을 입력하세요",
+ "t_4_1744164840458": "비밀번호를 입력하세요",
+ "t_5_1744164840468": "암호를 기억하다",
+ "t_6_1744164838900": "비밀번호를 잊었나요?",
+ "t_7_1744164838625": "로그인 중",
+ "t_8_1744164839833": "로그인",
+ "t_0_1744168657526": "로그아웃",
+ "t_0_1744258111441": "홈",
+ "t_1_1744258113857": "자동 배포",
+ "t_2_1744258111238": "서비스 관리",
+ "t_3_1744258111182": "서류 신청",
+ "t_4_1744258111238": "인증 API 관리",
+ "t_5_1744258110516": "감시",
+ "t_6_1744258111153": "설정",
+ "t_0_1744861190562": "워크플로우 목록 반환",
+ "t_1_1744861189113": "실행",
+ "t_2_1744861190040": "저장",
+ "t_3_1744861190932": "구성할 노드를 선택하세요",
+ "t_4_1744861194395": "왼쪽의 프로세스 다이어그램에서 노드를 클릭하여 설정하세요",
+ "t_5_1744861189528": "시작",
+ "t_6_1744861190121": "노드를 선택하지 않았습니다",
+ "t_7_1744861189625": "설정이 저장되었습니다",
+ "t_8_1744861189821": "워크플로우 시작",
+ "t_9_1744861189580": "선택된 노드:",
+ "t_0_1744870861464": "노드",
+ "t_1_1744870861944": "노드 설정",
+ "t_2_1744870863419": "왼쪽 노드를 선택하여 설정하세요",
+ "t_3_1744870864615": "이 노드 유형의 구성 구성 요소를 찾을 수 없습니다",
+ "t_4_1744870861589": "취소",
+ "t_5_1744870862719": "확인",
+ "t_0_1744875938285": "분마다",
+ "t_1_1744875938598": "매 시간",
+ "t_2_1744875938555": "매일",
+ "t_3_1744875938310": "매월",
+ "t_4_1744875940750": "자동 실행",
+ "t_5_1744875940010": "수동 실행",
+ "t_0_1744879616135": "테스트PID",
+ "t_1_1744879616555": "테스트 PID를 입력하세요",
+ "t_2_1744879616413": "실행 주기",
+ "t_3_1744879615723": "분",
+ "t_4_1744879616168": "분을 입력하세요",
+ "t_5_1744879615277": "시간",
+ "t_6_1744879616944": "시간을 입력하세요",
+ "t_7_1744879615743": "날짜",
+ "t_8_1744879616493": "날짜를 선택하세요",
+ "t_0_1744942117992": "매 주",
+ "t_1_1744942116527": "월요일",
+ "t_2_1744942117890": "화요일",
+ "t_3_1744942117885": "수요일",
+ "t_4_1744942117738": "목요일",
+ "t_5_1744942117167": "금요일",
+ "t_6_1744942117815": "토요일",
+ "t_7_1744942117862": "일요일",
+ "t_0_1744958839535": "도메인 이름을 입력하세요",
+ "t_1_1744958840747": "이메일을 입력하세요",
+ "t_2_1744958840131": "이메일 형식이 틀립니다",
+ "t_3_1744958840485": "DNS 제공업체 인증을 선택하세요",
+ "t_4_1744958838951": "로컬 배포",
+ "t_5_1744958839222": "SSH 배포",
+ "t_6_1744958843569": "보타 패널/1 패널(패널 인증서로 배포)",
+ "t_7_1744958841708": "1판널(지정된 웹사이트 프로젝트로 배포)",
+ "t_8_1744958841658": "테encent 클라우드 CDN/알리 클라우드 CDN",
+ "t_9_1744958840634": "테니엔 클라우드 WAF",
+ "t_10_1744958860078": "아리 클라우드 WAF",
+ "t_11_1744958840439": "이 자동 신청 증명서",
+ "t_12_1744958840387": "선택 가능한 인증서 목록",
+ "t_13_1744958840714": "PEM (*.pem, *.crt, *.key)",
+ "t_14_1744958839470": "PFX (*.pfx)",
+ "t_15_1744958840790": "JKS (*.jks)",
+ "t_16_1744958841116": "POSIX bash (Linux/macOS)",
+ "t_17_1744958839597": "명령어 라인 (Windows)",
+ "t_18_1744958839895": "파워셀(윈도우)",
+ "t_19_1744958839297": "인증서1",
+ "t_20_1744958839439": "증명서 2",
+ "t_21_1744958839305": "서버1",
+ "t_22_1744958841926": "서버2",
+ "t_23_1744958838717": "판널 1",
+ "t_24_1744958845324": "판널 2",
+ "t_25_1744958839236": "웹사이트 1",
+ "t_26_1744958839682": "웹사이트 2",
+ "t_27_1744958840234": "테encent 클라우드 1",
+ "t_28_1744958839760": "阿里yun 1",
+ "t_29_1744958838904": "일",
+ "t_30_1744958843864": "서류 형식이 잘못되었습니다. 전체 서류 헤더 및 푸터 식별자가 포함되어 있는지 확인해 주세요.",
+ "t_31_1744958844490": "비밀키 형식이 잘못되었습니다. 완전한 비밀키 헤더 및 푸터 식별자가 포함되어 있는지 확인해 주세요.",
+ "t_0_1745215914686": "자동화 이름",
+ "t_2_1745215915397": "자동",
+ "t_3_1745215914237": "수동",
+ "t_4_1745215914951": "활성 상태",
+ "t_5_1745215914671": "활성화",
+ "t_6_1745215914104": "정지",
+ "t_7_1745215914189": "생성 시간",
+ "t_8_1745215914610": "操作",
+ "t_9_1745215914666": "실행 이력",
+ "t_10_1745215914342": "실行",
+ "t_11_1745215915429": "편집",
+ "t_12_1745215914312": "삭제",
+ "t_13_1745215915455": "워크플로우 실행",
+ "t_14_1745215916235": "워크플로우 실행 성공",
+ "t_15_1745215915743": "워크플로우 실행 실패",
+ "t_16_1745215915209": "워크플로우 제거",
+ "t_17_1745215915985": "워크플로우가 성공적으로 삭제되었습니다",
+ "t_18_1745215915630": "워크플로우 삭제 실패",
+ "t_0_1745227838699": "신규 자동 배포",
+ "t_1_1745227838776": "자동화 이름을 입력하세요",
+ "t_2_1745227839794": "{name} 작업 흐름을 실행하시겠습니까?",
+ "t_3_1745227841567": "{name} 작업流程을 정말로 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.",
+ "t_4_1745227838558": "실행 시간",
+ "t_5_1745227839906": "종료 시간",
+ "t_6_1745227838798": "실행 방식",
+ "t_7_1745227838093": "상태",
+ "t_8_1745227838023": "성공",
+ "t_9_1745227838305": "실패",
+ "t_10_1745227838234": "진행 중",
+ "t_11_1745227838422": "알 수 없음",
+ "t_12_1745227838814": "상세정보",
+ "t_13_1745227838275": "서명서 업로드",
+ "t_14_1745227840904": "자격증 도메인 이름 또는 브랜드 이름을 입력하여 검색하세요",
+ "t_15_1745227839354": "함께",
+ "t_16_1745227838930": "개",
+ "t_17_1745227838561": "도메인 이름",
+ "t_18_1745227838154": "브랜드",
+ "t_19_1745227839107": "남은 날짜",
+ "t_20_1745227838813": "만료 시간",
+ "t_21_1745227837972": "출처",
+ "t_22_1745227838154": "자동 신청",
+ "t_23_1745227838699": "수동 업로드",
+ "t_24_1745227839508": "시간 추가",
+ "t_25_1745227838080": "다운로드",
+ "t_27_1745227838583": "만료될 예정",
+ "t_28_1745227837903": "정상",
+ "t_29_1745227838410": "인증서 삭제",
+ "t_30_1745227841739": "이 증명서를 지우시겠습니까? 이 작업은 복구할 수 없습니다.",
+ "t_31_1745227838461": "확인하세요",
+ "t_32_1745227838439": "서명",
+ "t_33_1745227838984": "증명서 이름을 입력하세요",
+ "t_34_1745227839375": "인증서 내용(PEM)",
+ "t_35_1745227839208": "서류 내용을 입력하세요",
+ "t_36_1745227838958": "사용자 키 내용(KEY)",
+ "t_37_1745227839669": "비밀키 내용을 입력하세요",
+ "t_38_1745227838813": "다운로드 실패",
+ "t_39_1745227838696": "업로드 실패",
+ "t_40_1745227838872": "삭제 실패",
+ "t_0_1745289355714": "인증 API 추가",
+ "t_1_1745289356586": "인증 API 이름 또는 유형을 입력하세요",
+ "t_2_1745289353944": "이름",
+ "t_3_1745289354664": "인증 API 유형",
+ "t_4_1745289354902": "編집 권한 API",
+ "t_5_1745289355718": "인증 API 제거",
+ "t_6_1745289358340": "이 권한된 API를 정말로 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.",
+ "t_7_1745289355714": "추가 실패",
+ "t_8_1745289354902": "업데이트 실패",
+ "t_9_1745289355714": "{days}일 경과",
+ "t_10_1745289354650": "모니터링 관리",
+ "t_11_1745289354516": "모니터링 추가",
+ "t_12_1745289356974": "모니터링 이름이나 도메인을 입력하여 검색하세요",
+ "t_13_1745289354528": "모니터 이름",
+ "t_14_1745289354902": "인증서 도메인",
+ "t_15_1745289355714": "인증서 발급 기관",
+ "t_16_1745289354902": "서류 상태",
+ "t_17_1745289355715": "인증서 만료일",
+ "t_18_1745289354598": "알림 채널",
+ "t_19_1745289354676": "최근 점검 시간",
+ "t_20_1745289354598": "편집 모니터링",
+ "t_21_1745289354598": "삭제 확인",
+ "t_22_1745289359036": "삭제된 아이템은 복원할 수 없습니다. 이 모니터를 정말로 삭제하시겠습니까?",
+ "t_23_1745289355716": "변경 실패",
+ "t_24_1745289355715": "설정 실패",
+ "t_25_1745289355721": "인증 코드를 입력하세요",
+ "t_26_1745289358341": "양식 검증 실패, 입력 내용을 확인해 주세요",
+ "t_27_1745289355721": "인증 API 이름을 입력하세요",
+ "t_28_1745289356040": "인증 API 유형을 선택하세요",
+ "t_29_1745289355850": "서버 IP를 입력하세요",
+ "t_30_1745289355718": "SSH 포트를 입력하세요",
+ "t_31_1745289355715": "SSH 키를 입력하세요",
+ "t_32_1745289356127": "보타 주소를 입력하세요",
+ "t_33_1745289355721": "API 키를 입력하세요",
+ "t_34_1745289356040": "1panel 주소를 입력해 주세요",
+ "t_35_1745289355714": "AccessKeyId을 입력하세요",
+ "t_36_1745289355715": "AccessKeySecret을 입력하세요",
+ "t_37_1745289356041": "SecretId를 입력하세요",
+ "t_38_1745289356419": "SecretKey를 입력하세요",
+ "t_39_1745289354902": "업데이트 성공",
+ "t_40_1745289355715": "추가 성공",
+ "t_41_1745289354902": "타입",
+ "t_42_1745289355715": "서버 IP",
+ "t_43_1745289354598": "SSH 포트",
+ "t_44_1745289354583": "사용자 이름",
+ "t_45_1745289355714": "인증 방법",
+ "t_46_1745289355723": "암호 인증",
+ "t_47_1745289355715": "키 인증",
+ "t_48_1745289355714": "비밀번호",
+ "t_49_1745289355714": "SSH 비밀키",
+ "t_50_1745289355715": "SSH 프라이빗 키를 입력하세요",
+ "t_51_1745289355714": "private key 비밀번호",
+ "t_52_1745289359565": "비밀키에 비밀번호가 있으면 입력하세요",
+ "t_53_1745289356446": "보타 패널 주소",
+ "t_54_1745289358683": "보타 패널 주소를 입력하세요,예를 들어: https://bt.example.com",
+ "t_55_1745289355715": "API 키",
+ "t_56_1745289355714": "1판의 주소",
+ "t_57_1745289358341": "1panel 주소를 입력하세요, 예를 들어: https://1panel.example.com",
+ "t_58_1745289355721": "AccessKey ID를 입력하세요",
+ "t_59_1745289356803": "AccessKey 비밀번호를 입력하세요",
+ "t_60_1745289355715": "모니터링 이름을 입력하세요",
+ "t_61_1745289355878": "도메인/IP를 입력하세요",
+ "t_62_1745289360212": "검사 주기를 선택하세요",
+ "t_63_1745289354897": "5분",
+ "t_64_1745289354670": "10분",
+ "t_65_1745289354591": "15분",
+ "t_66_1745289354655": "30분",
+ "t_67_1745289354487": "60분",
+ "t_68_1745289354676": "이메일",
+ "t_69_1745289355721": "문자",
+ "t_70_1745289354904": "위챗",
+ "t_71_1745289354583": "도메인/IP",
+ "t_72_1745289355715": "점검 주기",
+ "t_73_1745289356103": "경고 채널을 선택해 주세요",
+ "t_0_1745289808449": "인증 API 이름을 입력하세요",
+ "t_0_1745294710530": "모니터링 삭제",
+ "t_0_1745295228865": "업데이트 시간",
+ "t_0_1745317313835": "서버 IP 주소 형식이 오류입니다",
+ "t_1_1745317313096": "포트 포맷 오류",
+ "t_2_1745317314362": "패널 URL 주소 형식이 잘못되었습니다",
+ "t_3_1745317313561": "패널 API 키를 입력하세요",
+ "t_4_1745317314054": "阿里云 접근키 ID를 입력하세요",
+ "t_5_1745317315285": "阿里yun AccessKeySecret을 입력하세요",
+ "t_6_1745317313383": "腾讯云 SecretId를 입력하세요",
+ "t_7_1745317313831": "腾讯云 SecretKey를 입력하세요",
+ "t_0_1745457486299": "활성화됨",
+ "t_1_1745457484314": "중지됨",
+ "t_2_1745457488661": "수동 모드로 전환",
+ "t_3_1745457486983": "자동 모드로 전환",
+ "t_4_1745457497303": "수동 모드로 전환한 후 워크플로우는 더 이상 자동으로 실행되지 않지만 수동으로 실행할 수 있습니다",
+ "t_5_1745457494695": "자동 모드로 전환한 후 워크플로우는 구성된 시간에 따라 자동으로 실행됩니다",
+ "t_6_1745457487560": "현재 워크플로우 닫기",
+ "t_7_1745457487185": "현재 워크플로우 활성화",
+ "t_8_1745457496621": "닫으면 워크플로우가 자동으로 실행되지 않고 수동으로도 실행할 수 없습니다. 계속하시겠습니까?",
+ "t_9_1745457500045": "활성화 후, 워크플로 구성이 자동 또는 수동으로 실행됩니다. 계속하시겠습니까?",
+ "t_10_1745457486451": "워크플로우 추가 실패",
+ "t_11_1745457488256": "워크플로우 실행 방식 설정 실패",
+ "t_12_1745457489076": "워크플로우 실패 활성화 또는 비활성화",
+ "t_13_1745457487555": "워크플로우 실행 실패",
+ "t_14_1745457488092": "워크플로우 삭제 실패",
+ "t_15_1745457484292": "종료",
+ "t_16_1745457491607": "로그아웃하려고 합니다. 로그아웃하시겠습니까?",
+ "t_17_1745457488251": "로그아웃 중입니다. 잠시만 기다려주세요...",
+ "t_18_1745457490931": "이메일 알림 추가",
+ "t_19_1745457484684": "저장 성공",
+ "t_20_1745457485905": "삭제 성공",
+ "t_0_1745464080226": "시스템 설정 가져오기 실패",
+ "t_1_1745464079590": "설정 저장 실패",
+ "t_2_1745464077081": "알림 설정 가져오기 실패",
+ "t_3_1745464081058": "알림 설정 저장 실패",
+ "t_4_1745464075382": "알림 채널 목록 가져오기 실패",
+ "t_5_1745464086047": "이메일 알림 채널 추가 실패",
+ "t_6_1745464075714": "알림 채널 업데이트 실패",
+ "t_7_1745464073330": "알림 채널 삭제 실패",
+ "t_8_1745464081472": "버전 업데이트 확인 실패",
+ "t_9_1745464078110": "설정 저장",
+ "t_10_1745464073098": "기본 설정",
+ "t_0_1745474945127": "템플릿 선택",
+ "t_0_1745490735213": "워크플로우 이름을 입력하세요",
+ "t_1_1745490731990": "설정",
+ "t_2_1745490735558": "이메일 형식을 입력하세요",
+ "t_3_1745490735059": "DNS 공급자를 선택하세요",
+ "t_4_1745490735630": "갱신 간격을 입력하세요",
+ "t_5_1745490738285": "도메인 이름을 입력하세요. 도메인 이름은 비워둘 수 없습니다",
+ "t_6_1745490738548": "이메일을 입력하세요, 이메일은 비워둘 수 없습니다",
+ "t_7_1745490739917": "DNS 공급자를 선택하십시오. DNS 공급자는 비워 둘 수 없습니다",
+ "t_8_1745490739319": "갱신 간격을 입력하세요. 갱신 간격은 비워둘 수 없습니다",
+ "t_0_1745553910661": "도메인 형식이 잘못되었습니다. 올바른 도메인을 입력하세요",
+ "t_1_1745553909483": "이메일 형식이 잘못되었습니다. 올바른 이메일을 입력하세요",
+ "t_2_1745553907423": "갱신 간격은 비워둘 수 없습니다",
+ "t_0_1745735774005": "인증서 도메인 이름을 입력하세요. 여러 도메인 이름은 쉼표로 구분합니다",
+ "t_1_1745735764953": "메일박스",
+ "t_2_1745735773668": "인증 기관의 메일 알림을 수신할 이메일을 입력해 주세요",
+ "t_3_1745735765112": "DNS 제공자",
+ "t_4_1745735765372": "추가",
+ "t_5_1745735769112": "갱신 간격 (일)",
+ "t_6_1745735765205": "갱신 간격",
+ "t_7_1745735768326": "일, 만료 후 자동 갱신",
+ "t_8_1745735765753": "구성됨",
+ "t_9_1745735765287": "구성되지 않음",
+ "t_10_1745735765165": "파고다 패널",
+ "t_11_1745735766456": "파고다 패널 웹사이트",
+ "t_12_1745735765571": "1Panel 패널",
+ "t_13_1745735766084": "1Panel 웹사이트",
+ "t_14_1745735766121": "텐센트 클라우드 CDN",
+ "t_15_1745735768976": "텐센트 클라우드 COS",
+ "t_16_1745735766712": "알리바바 클라우드 CDN",
+ "t_18_1745735765638": "배포 유형",
+ "t_19_1745735766810": "배포 유형을 선택하세요",
+ "t_20_1745735768764": "배포 경로를 입력하십시오",
+ "t_21_1745735769154": "앞에 명령어를 입력하세요",
+ "t_22_1745735767366": "후치 명령어를 입력하세요",
+ "t_23_1745735766455": "사이트 이름을 입력하세요",
+ "t_24_1745735766826": "사이트 ID를 입력하십시오",
+ "t_25_1745735766651": "지역을 입력하세요",
+ "t_26_1745735767144": "버킷을 입력하세요",
+ "t_27_1745735764546": "다음 단계",
+ "t_28_1745735766626": "배포 유형 선택",
+ "t_29_1745735768933": "배포 매개변수 구성",
+ "t_30_1745735764748": "운영 모드",
+ "t_31_1745735767891": "운영 모드가 구성되지 않았습니다",
+ "t_32_1745735767156": "실행 주기가 구성되지 않았습니다",
+ "t_33_1745735766532": "실행 시간이 구성되지 않았습니다",
+ "t_34_1745735771147": "인증서 파일 (PEM 포맷)",
+ "t_35_1745735781545": "인증서 파일 내용을 붙여넣으세요, 예:\n-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
+ "t_36_1745735769443": "개인 키 파일 (KEY 형식)",
+ "t_37_1745735779980": "개인 키 파일 내용을 붙여넣으세요, 예:\n-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
+ "t_38_1745735769521": "인증서 개인 키 내용은 비워둘 수 없습니다",
+ "t_39_1745735768565": "인증서 개인 키 형식이 올바르지 않습니다",
+ "t_40_1745735815317": "인증서 내용은 비울 수 없습니다",
+ "t_41_1745735767016": "인증서 형식이 올바르지 않습니다",
+ "t_0_1745738961258": "이전",
+ "t_1_1745738963744": "제출",
+ "t_2_1745738969878": "배포 매개변수 구성, 유형이 매개변수 구성을 결정함",
+ "t_0_1745744491696": "배포 장치 소스",
+ "t_1_1745744495019": "배포 장치 소스를 선택하십시오",
+ "t_2_1745744495813": "배포 유형을 선택하고 다음을 클릭하십시오",
+ "t_0_1745744902975": "배포 소스",
+ "t_1_1745744905566": "배포 소스를 선택하세요",
+ "t_2_1745744903722": "더 많은 기기 추가",
+ "t_0_1745748292337": "배포 소스 추가",
+ "t_1_1745748290291": "인증서 출처",
+ "t_2_1745748298902": "현재 유형의 배포 소스가 비어 있습니다. 배포 소스를 먼저 추가하십시오",
+ "t_3_1745748298161": "현재 프로세스에 신청 노드가 없습니다. 먼저 신청 노드를 추가하세요",
+ "t_4_1745748290292": "제출 내용",
+ "t_0_1745765864788": "작업 흐름 제목 편집을 클릭하세요",
+ "t_1_1745765875247": "노드 삭제 - 【{name}】",
+ "t_2_1745765875918": "현재 노드에 하위 노드가 존재합니다. 삭제하면 다른 노드에 영향을 미치게 됩니다. 삭제하시겠습니까?",
+ "t_3_1745765920953": "현재 노드에 구성 데이터가 있습니다. 삭제하시겠습니까?",
+ "t_4_1745765868807": "배포 유형을 선택한 후 다음 단계로 진행하십시오",
+ "t_0_1745833934390": "유형을 선택하십시오",
+ "t_1_1745833931535": "호스트",
+ "t_2_1745833931404": "포트",
+ "t_3_1745833936770": "홈페이지 개요 데이터 가져오기 실패",
+ "t_4_1745833932780": "버전 정보",
+ "t_5_1745833933241": "현재 버전",
+ "t_6_1745833933523": "업데이트 방법",
+ "t_7_1745833933278": "최신 버전",
+ "t_8_1745833933552": "업데이트 로그",
+ "t_9_1745833935269": "고객 서비스 QR 코드",
+ "t_10_1745833941691": "QR 코드를 스캔하여 고객 서비스 추가",
+ "t_11_1745833935261": "위챗 공식 계정",
+ "t_12_1745833943712": "QR 코드를 스캔하여 WeChat 공식 계정 팔로우",
+ "t_13_1745833933630": "제품 정보",
+ "t_14_1745833932440": "SMTP 서버",
+ "t_15_1745833940280": "SMTP 서버를 입력하세요",
+ "t_16_1745833933819": "SMTP 포트",
+ "t_17_1745833935070": "SMTP 포트를 입력하세요",
+ "t_18_1745833933989": "SSL/TLS 연결",
+ "t_0_1745887835267": "메시지 알림을 선택하세요",
+ "t_1_1745887832941": "알림",
+ "t_2_1745887834248": "알림 채널 추가",
+ "t_3_1745887835089": "알림 제목을 입력하세요",
+ "t_4_1745887835265": "알림 내용을 입력하세요",
+ "t_0_1745895057404": "이메일 알림 설정 수정",
+ "t_0_1745920566646": "공지 주제",
+ "t_1_1745920567200": "공지 내용",
+ "t_0_1745936396853": "인증 코드 받기",
+ "t_0_1745999035681": "남은 {days}일",
+ "t_1_1745999036289": "곧 만료됩니다 {days} 일",
+ "t_0_1746000517848": "만료됨",
+ "t_0_1746001199409": "만료됨",
+ "t_0_1746004861782": "DNS 공급자가 비어 있습니다",
+ "t_1_1746004861166": "DNS 공급자 추가",
+ "t_0_1746497662220": "새로 고침",
+ "t_0_1746519384035": "실행 중",
+ "t_0_1746579648713": "실행 내역 상세 정보",
+ "t_0_1746590054456": "실행 상태",
+ "t_1_1746590060448": "트리거 방식",
+ "t_0_1746667592819": "정보를 제출 중입니다. 잠시 기다려주세요...",
+ "t_1_1746667588689": "키",
+ "t_2_1746667592840": "패널 URL",
+ "t_3_1746667592270": "SSL/TLS 인증서 오류 무시",
+ "t_4_1746667590873": "양식 검증 실패",
+ "t_5_1746667590676": "새 워크플로우",
+ "t_6_1746667592831": "제출 중입니다. 잠시만 기다려 주세요...",
+ "t_7_1746667592468": "올바른 도메인 이름을 입력하세요",
+ "t_8_1746667591924": "파싱 방법을 선택하세요",
+ "t_9_1746667589516": "목록 새로 고침",
+ "t_10_1746667589575": "와일드카드",
+ "t_11_1746667589598": "멀티 도메인",
+ "t_12_1746667589733": "인기",
+ "t_13_1746667599218": "개인 웹사이트 및 테스트 환경에 적합한 널리 사용되는 무료 SSL 인증서 제공업체입니다.",
+ "t_14_1746667590827": "지원되는 도메인 수",
+ "t_15_1746667588493": "개",
+ "t_16_1746667591069": "와일드카드 지원",
+ "t_17_1746667588785": "지원",
+ "t_18_1746667590113": "지원되지 않음",
+ "t_19_1746667589295": "유효 기간",
+ "t_20_1746667588453": "하늘",
+ "t_21_1746667590834": "미니프로그램 지원",
+ "t_22_1746667591024": "적용 가능한 웹사이트",
+ "t_23_1746667591989": "*.example.com, *.demo.com",
+ "t_24_1746667583520": "*.example.com",
+ "t_25_1746667590147": "example.com、demo.com",
+ "t_26_1746667594662": "www.example.com, example.com",
+ "t_27_1746667589350": "무료",
+ "t_28_1746667590336": "지금 신청하기",
+ "t_29_1746667589773": "프로젝트 주소",
+ "t_30_1746667591892": "인증서 파일 경로를 입력하세요",
+ "t_31_1746667593074": "개인 키 파일 경로를 입력하세요",
+ "t_0_1746673515941": "현재 DNS 공급자가 비어 있습니다. 먼저 DNS 공급자를 추가하세요",
+ "t_0_1746676862189": "테스트 알림 전송 실패",
+ "t_1_1746676859550": "구성 추가",
+ "t_2_1746676856700": "아직 지원되지 않음",
+ "t_3_1746676857930": "이메일 알림",
+ "t_4_1746676861473": "이메일로 경고 알림 보내기",
+ "t_5_1746676856974": "DingTalk 알림",
+ "t_6_1746676860886": "DingTalk 봇을 통해 경고 알림 보내기",
+ "t_7_1746676857191": "기업 위챗 알림",
+ "t_8_1746676860457": "WeCom 봇을 통해 경고 알림 보내기",
+ "t_9_1746676857164": "Feishu 알림",
+ "t_10_1746676862329": "Feishu 봇을 통해 알림 알림 보내기",
+ "t_11_1746676859158": "WebHook 알림",
+ "t_12_1746676860503": "WebHook를 통해 알림 알림 보내기",
+ "t_13_1746676856842": "알림 채널",
+ "t_14_1746676859019": "구성된 알림 채널",
+ "t_15_1746676856567": "비활성화됨",
+ "t_16_1746676855270": "테스트",
+ "t_0_1746677882486": "마지막 실행 상태",
+ "t_0_1746697487119": "도메인 이름은 비워둘 수 없습니다",
+ "t_1_1746697485188": "이메일은 비워둘 수 없습니다",
+ "t_2_1746697487164": "알리바바 클라우드 OSS",
+ "t_0_1746754500246": "호스팅 제공업체",
+ "t_1_1746754499371": "API 소스",
+ "t_2_1746754500270": "API 유형",
+ "t_0_1746760933542": "요청 오류",
+ "t_0_1746773350551": "총 {0}건",
+ "t_1_1746773348701": "실행되지 않음",
+ "t_2_1746773350970": "자동화 워크플로우",
+ "t_3_1746773348798": "총 수량",
+ "t_4_1746773348957": "실행 실패",
+ "t_5_1746773349141": "곧 만료됩니다",
+ "t_6_1746773349980": "실시간 모니터링",
+ "t_7_1746773349302": "이상 수량",
+ "t_8_1746773351524": "최근 워크플로우 실행 기록",
+ "t_9_1746773348221": "모두 보기",
+ "t_10_1746773351576": "워크플로우 실행 기록 없음",
+ "t_11_1746773349054": "워크플로우 생성",
+ "t_12_1746773355641": "효율성을 높이기 위해 자동화된 워크플로우를 생성하려면 클릭하세요",
+ "t_13_1746773349526": "증명서 신청",
+ "t_14_1746773355081": "SSL 인증서를 신청하고 관리하여 보안을 보장합니다",
+ "t_15_1746773358151": "웹사이트 모니터링을 설정하려면 클릭하세요. 실시간으로 실행 상태를 확인할 수 있습니다",
+ "t_16_1746773356568": "최대 하나의 이메일 알림 채널만 구성할 수 있습니다",
+ "t_17_1746773351220": "{0} 알림 채널 확인",
+ "t_18_1746773355467": "{0} 알림 채널에서 경고 알림을 보내기 시작할 예정입니다.",
+ "t_19_1746773352558": "현재 알림 채널은 테스트를 지원하지 않습니다",
+ "t_20_1746773356060": "테스트 이메일을 보내는 중입니다. 잠시 기다려주세요...",
+ "t_21_1746773350759": "테스트 이메일",
+ "t_22_1746773360711": "현재 설정된 메일박스로 테스트 메일을 보내시겠습니까?",
+ "t_23_1746773350040": "삭제 확인",
+ "t_24_1746773349367": "삭제하시겠습니까",
+ "t_25_1746773349596": "이름을 입력하세요",
+ "t_26_1746773353409": "올바른 SMTP 포트를 입력하세요",
+ "t_27_1746773352584": "사용자 비밀번호를 입력하세요",
+ "t_28_1746773354048": "올바른 발신자 이메일을 입력하세요",
+ "t_29_1746773351834": "올바른 수신 이메일을 입력하세요",
+ "t_30_1746773350013": "보내는 사람 이메일",
+ "t_31_1746773349857": "이메일 수신",
+ "t_32_1746773348993": "딩톡",
+ "t_33_1746773350932": "위챗 워크",
+ "t_34_1746773350153": "페이슈",
+ "t_35_1746773362992": "SSL 인증서 신청, 관리, 배포 및 모니터링을 통합한 전 생애 주기 관리 도구.",
+ "t_36_1746773348989": "증명서 신청",
+ "t_37_1746773356895": "ACME 프로토콜을 통해 Let's Encrypt에서 인증서를 획득할 수 있도록 지원",
+ "t_38_1746773349796": "인증서 관리",
+ "t_39_1746773358932": "모든 SSL 인증서를 중앙에서 관리하며, 수동으로 업로드한 인증서와 자동으로 신청한 인증서를 포함합니다",
+ "t_40_1746773352188": "인증서 배포",
+ "t_41_1746773364475": "여러 플랫폼에 한 번의 클릭으로 인증서 배포 지원, 알리바바 클라우드, 텐센트 클라우드, Pagoda Panel, 1Panel 등",
+ "t_42_1746773348768": "사이트 모니터링",
+ "t_43_1746773359511": "사이트 SSL 인증서 상태를 실시간으로 모니터링하여 인증서 만료를 사전에 경고합니다",
+ "t_44_1746773352805": "자동화 작업:",
+ "t_45_1746773355717": "예약된 작업 지원, 인증서 자동 갱신 및 배포",
+ "t_46_1746773350579": "다중 플랫폼 지원",
+ "t_47_1746773360760": "다양한 DNS 제공업체(알리바바 클라우드, 텐센트 클라우드 등)의 DNS 확인 방법 지원"
+}
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/locales/model/ptBR.json b/frontend/apps/allin-ssl/src/locales/model/ptBR.json
new file mode 100644
index 0000000..d979d2c
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/locales/model/ptBR.json
@@ -0,0 +1,490 @@
+{
+ "t_0_1746773763967": "Tem certeza que deseja excluir {0}, o canal de notificação?",
+ "t_1_1746773763643": "Let's Encrypt e outras autoridades de certificação solicitam automaticamente certificados gratuitos",
+ "t_0_1744098811152": "Aviso: Você entrou em uma área desconhecida, a página que você está visitando não existe, por favor, clique no botão para voltar para a página inicial.",
+ "t_1_1744098801860": "Voltar para a homepage",
+ "t_2_1744098804908": "Dica de Segurança: Se você acha que isso é um erro, entre em contato com o administrador imediatamente",
+ "t_3_1744098802647": "Expandir o menu principal",
+ "t_4_1744098802046": "Menu principal dobrável",
+ "t_0_1744164843238": "Bem-vindo ao AllinSSL, gerenciamento eficiente de certificados SSL",
+ "t_1_1744164835667": "AllinSSL",
+ "t_2_1744164839713": "Login de Conta",
+ "t_3_1744164839524": "Por favor, insira o nome de usuário",
+ "t_4_1744164840458": "Por favor, insira a senha",
+ "t_5_1744164840468": "Lembrar senha",
+ "t_6_1744164838900": "Esqueceu sua senha?",
+ "t_7_1744164838625": "Entrando",
+ "t_8_1744164839833": "Entrar",
+ "t_0_1744168657526": "Sair",
+ "t_0_1744258111441": "Início",
+ "t_1_1744258113857": "Implantação Automatizada",
+ "t_2_1744258111238": "Gestão de Certificados",
+ "t_3_1744258111182": "Aplicação de certificado",
+ "t_4_1744258111238": "Gerenciamento de API de autorização",
+ "t_5_1744258110516": "Monitoramento",
+ "t_6_1744258111153": "Configurações",
+ "t_0_1744861190562": "Retornar lista de fluxos de trabalho",
+ "t_1_1744861189113": "Executar",
+ "t_2_1744861190040": "Salvar",
+ "t_3_1744861190932": "Selecione um nó para configurar",
+ "t_4_1744861194395": "Clique no nó do diagrama de workflow do lado esquerdo para configurá-lo",
+ "t_5_1744861189528": "iniciar",
+ "t_6_1744861190121": "Nenhum nó selected",
+ "t_7_1744861189625": "Configuração salva",
+ "t_8_1744861189821": "Iniciar fluxo de trabalho",
+ "t_9_1744861189580": "Nó selecionado:",
+ "t_0_1744870861464": "nó",
+ "t_1_1744870861944": "Configuração de nó",
+ "t_2_1744870863419": "Selecione o nó esquerdo para configuração",
+ "t_3_1744870864615": "Componente de configuração para esse tipo de nó não encontrado",
+ "t_4_1744870861589": "Cancelar",
+ "t_5_1744870862719": "confirmar",
+ "t_0_1744875938285": "a cada minuto",
+ "t_1_1744875938598": "a cada hora",
+ "t_2_1744875938555": "cada dia",
+ "t_3_1744875938310": "cada mês",
+ "t_4_1744875940750": "Execução automática",
+ "t_5_1744875940010": "Execução manual",
+ "t_0_1744879616135": "Teste PID",
+ "t_1_1744879616555": "Por favor, insira o PID de teste",
+ "t_2_1744879616413": "Período de execução",
+ "t_3_1744879615723": "minuto",
+ "t_4_1744879616168": "Por favor, insira os minutos",
+ "t_5_1744879615277": "hora",
+ "t_6_1744879616944": "Por favor, insira as horas",
+ "t_7_1744879615743": "Data",
+ "t_8_1744879616493": "Selecione a data",
+ "t_0_1744942117992": "cada semana",
+ "t_1_1744942116527": "segunda-feira",
+ "t_2_1744942117890": "terça-feira",
+ "t_3_1744942117885": "Quarta-feira",
+ "t_4_1744942117738": "quarta-feira",
+ "t_5_1744942117167": "quinta-feira",
+ "t_6_1744942117815": "sábado",
+ "t_7_1744942117862": "domingo",
+ "t_0_1744958839535": "Por favor, insira o nome do domínio",
+ "t_1_1744958840747": "Por favor, insira seu e-mail",
+ "t_2_1744958840131": "Formato de e-mail incorreto",
+ "t_3_1744958840485": "Selecione o provedor de DNS para autorização",
+ "t_4_1744958838951": "Implantação Local",
+ "t_5_1744958839222": "Desempenho SSH",
+ "t_6_1744958843569": "Painel Bota/1 painel (Instalar no certificado do painel)",
+ "t_7_1744958841708": "1painel (Deploiamento para o projeto de site especificado)",
+ "t_8_1744958841658": "Tencent Cloud CDN/AliCloud CDN",
+ "t_9_1744958840634": "WAF da Tencent Cloud",
+ "t_10_1744958860078": "Alicloud WAF",
+ "t_11_1744958840439": "Este certificado aplicado automaticamente",
+ "t_12_1744958840387": "Lista de certificados opcionais",
+ "t_13_1744958840714": "PEM (*.pem, *.crt, *.key)",
+ "t_14_1744958839470": "PFX (*.pfx)",
+ "t_15_1744958840790": "JKS (*.jks)",
+ "t_16_1744958841116": "POSIX bash (Linux/macOS)",
+ "t_17_1744958839597": "Linha de Comando (Windows)",
+ "t_18_1744958839895": "PowerShell (Windows)",
+ "t_19_1744958839297": "Certificado 1",
+ "t_20_1744958839439": "Certificado 2",
+ "t_21_1744958839305": "Servidor 1",
+ "t_22_1744958841926": "Servidor 2",
+ "t_23_1744958838717": "Painel 1",
+ "t_24_1744958845324": "Painel 2",
+ "t_25_1744958839236": "Site 1",
+ "t_26_1744958839682": "Site 2",
+ "t_27_1744958840234": "Tencent Cloud 1",
+ "t_28_1744958839760": "Aliyun 1",
+ "t_29_1744958838904": "dia",
+ "t_30_1744958843864": "O formato do certificado está incorreto, por favor verifique se ele contém os identificadores de cabeçalho e rodapé completos",
+ "t_31_1744958844490": "O formato da chave privada está incorreto, por favor, verifique se ele contém o identificador completo do cabeçalho e pé de página da chave privada",
+ "t_0_1745215914686": "Nome de automação",
+ "t_2_1745215915397": "automático",
+ "t_3_1745215914237": "Manual",
+ "t_4_1745215914951": "Estado ativado",
+ "t_5_1745215914671": "Ativar",
+ "t_6_1745215914104": "Desativar",
+ "t_7_1745215914189": "Hora de criação",
+ "t_8_1745215914610": "Operação",
+ "t_9_1745215914666": "Histórico de execução",
+ "t_10_1745215914342": "executar",
+ "t_11_1745215915429": "Editar",
+ "t_12_1745215914312": "Excluir",
+ "t_13_1745215915455": "Executar fluxo de trabalho",
+ "t_14_1745215916235": "Execução do fluxo de trabalho bem-sucedida",
+ "t_15_1745215915743": "Execução do fluxo de trabalho falhou",
+ "t_16_1745215915209": "Excluir workflow",
+ "t_17_1745215915985": "Deleção do fluxo de trabalho bem-sucedida",
+ "t_18_1745215915630": "Falha ao excluir fluxo de trabalho",
+ "t_0_1745227838699": "Novo deployment automatizado",
+ "t_1_1745227838776": "Por favor, insira o nome da automação",
+ "t_2_1745227839794": "Tem certeza de que deseja executar o workflow {name}?",
+ "t_3_1745227841567": "Confirma a exclusão do fluxo de trabalho {name}? Esta ação não pode ser revertida.",
+ "t_4_1745227838558": "Tempo de execução",
+ "t_5_1745227839906": "Hora de término",
+ "t_6_1745227838798": "Método de execução",
+ "t_7_1745227838093": "Status",
+ "t_8_1745227838023": "Sucesso",
+ "t_9_1745227838305": "fracasso",
+ "t_10_1745227838234": "Em andamento",
+ "t_11_1745227838422": "desconhecido",
+ "t_12_1745227838814": "Detalhes",
+ "t_13_1745227838275": "Enviar certificado",
+ "t_14_1745227840904": "Insira o nome do domínio do certificado ou o nome da marca para pesquisa",
+ "t_15_1745227839354": "juntos",
+ "t_16_1745227838930": "unidade",
+ "t_17_1745227838561": "Nome de domínio",
+ "t_18_1745227838154": "Marca",
+ "t_19_1745227839107": "Dias restantes",
+ "t_20_1745227838813": "Tempo de expiração",
+ "t_21_1745227837972": "Fonte",
+ "t_22_1745227838154": "Aplicação Automática",
+ "t_23_1745227838699": "Upload manual",
+ "t_24_1745227839508": "Adicionar tempo",
+ "t_25_1745227838080": "Baixar",
+ "t_27_1745227838583": "Próximo de expirar",
+ "t_28_1745227837903": "normal",
+ "t_29_1745227838410": "Excluir certificado",
+ "t_30_1745227841739": "Tem certeza de que deseja excluir este certificado? Esta ação não pode ser revertida.",
+ "t_31_1745227838461": "Confirmar",
+ "t_32_1745227838439": "Nome do Certificado",
+ "t_33_1745227838984": "Por favor, insira o nome do certificado",
+ "t_34_1745227839375": "Conteúdo do certificado (PEM)",
+ "t_35_1745227839208": "Por favor, insira o conteúdo do certificado",
+ "t_36_1745227838958": "Conteúdo da chave privada (KEY)",
+ "t_37_1745227839669": "Por favor, insira o conteúdo da chave privada",
+ "t_38_1745227838813": "Falha ao baixar",
+ "t_39_1745227838696": "Falha ao carregar",
+ "t_40_1745227838872": "Falha na exclusão",
+ "t_0_1745289355714": "Adicionar API de autorização",
+ "t_1_1745289356586": "Por favor, insira o nome ou o tipo do API autorizado",
+ "t_2_1745289353944": "Nome",
+ "t_3_1745289354664": "Tipo de API de autorização",
+ "t_4_1745289354902": "API de autorização de edição",
+ "t_5_1745289355718": "Remover API de autorização",
+ "t_6_1745289358340": "Tem certeza de que deseja excluir este API autorizado? Esta ação não pode ser revertida.",
+ "t_7_1745289355714": "Falha ao adicionar",
+ "t_8_1745289354902": "Falha na atualização",
+ "t_9_1745289355714": "Expirado há {days} dias",
+ "t_10_1745289354650": "Gestão de Monitoramento",
+ "t_11_1745289354516": "Adicionar monitoramento",
+ "t_12_1745289356974": "Por favor, insira o nome do monitoramento ou o domínio para pesquisar",
+ "t_13_1745289354528": "Nome do Monitor",
+ "t_14_1745289354902": "Domínio do certificado",
+ "t_15_1745289355714": "Autoridade de Certificação",
+ "t_16_1745289354902": "Status do certificado",
+ "t_17_1745289355715": "Data de expiração do certificado",
+ "t_18_1745289354598": "Canais de alerta",
+ "t_19_1745289354676": "Última data de verificação",
+ "t_20_1745289354598": "Edição de Monitoramento",
+ "t_21_1745289354598": "Confirmar exclusão",
+ "t_22_1745289359036": "Os itens não podem ser restaurados após a exclusão. Tem certeza de que deseja excluir este monitor?",
+ "t_23_1745289355716": "Falha na modificação",
+ "t_24_1745289355715": "Falha na configuração",
+ "t_25_1745289355721": "Por favor, insira o código de verificação",
+ "t_26_1745289358341": "Validação do formulário falhou, por favor, verifique o conteúdo preenchido",
+ "t_27_1745289355721": "Por favor, insira o nome do API autorizado",
+ "t_28_1745289356040": "Selecione o tipo de API de autorização",
+ "t_29_1745289355850": "Por favor, insira o IP do servidor",
+ "t_30_1745289355718": "Por favor, insira a porta SSH",
+ "t_31_1745289355715": "Por favor, insira a chave SSH",
+ "t_32_1745289356127": "Por favor, insira o endereço do Baota",
+ "t_33_1745289355721": "Por favor, insira a chave da API",
+ "t_34_1745289356040": "Por favor, insira o endereço do 1panel",
+ "t_35_1745289355714": "Por favor, insira AccessKeyId",
+ "t_36_1745289355715": "Por favor, insira AccessKeySecret",
+ "t_37_1745289356041": "Por favor, insira SecretId",
+ "t_38_1745289356419": "Por favor, insira a Chave Secreta",
+ "t_39_1745289354902": "Atualização bem-sucedida",
+ "t_40_1745289355715": "Adição bem-sucedida",
+ "t_41_1745289354902": "Tipo",
+ "t_42_1745289355715": "IP do Servidor",
+ "t_43_1745289354598": "Porta SSH",
+ "t_44_1745289354583": "Nome de usuário",
+ "t_45_1745289355714": "Método de autenticação",
+ "t_46_1745289355723": "Autenticação por senha",
+ "t_47_1745289355715": "Autenticação de chave",
+ "t_48_1745289355714": "Senha",
+ "t_49_1745289355714": "Chave privada SSH",
+ "t_50_1745289355715": "Por favor, insira a chave privada SSH",
+ "t_51_1745289355714": "Senha da chave privada",
+ "t_52_1745289359565": "Se a chave privada tiver uma senha, insira",
+ "t_53_1745289356446": "Endereço da tela BaoTa",
+ "t_54_1745289358683": "Por favor, insira o endereço do painel Baota, por exemplo: https://bt.example.com",
+ "t_55_1745289355715": "Chave API",
+ "t_56_1745289355714": "Endereço do painel 1",
+ "t_57_1745289358341": "Insira o endereço do 1panel, por exemplo: https://1panel.example.com",
+ "t_58_1745289355721": "Insira o ID do AccessKey",
+ "t_59_1745289356803": "Por favor, insira o segredo do AccessKey",
+ "t_60_1745289355715": "Por favor, insira o nome do monitoramento",
+ "t_61_1745289355878": "Por favor, insira o domínio/IP",
+ "t_62_1745289360212": "Selecione o período de inspeção",
+ "t_63_1745289354897": "5 minutos",
+ "t_64_1745289354670": "10 minutos",
+ "t_65_1745289354591": "15 minutos",
+ "t_66_1745289354655": "30 minutos",
+ "t_67_1745289354487": "60 minutos",
+ "t_68_1745289354676": "E-mail",
+ "t_69_1745289355721": "SMS",
+ "t_70_1745289354904": "WeChat",
+ "t_71_1745289354583": "Domínio/IP",
+ "t_72_1745289355715": "Período de inspeção",
+ "t_73_1745289356103": "Selecione o canal de alerta",
+ "t_0_1745289808449": "Por favor, insira o nome do API autorizado",
+ "t_0_1745294710530": "Excluir monitoramento",
+ "t_0_1745295228865": "Data de atualização",
+ "t_0_1745317313835": "Endereço IP do servidor está no formato incorreto",
+ "t_1_1745317313096": "Erro de formato de porta",
+ "t_2_1745317314362": "Formato de endereço da URL da página do painel incorreto",
+ "t_3_1745317313561": "Por favor, insira a chave API da panela",
+ "t_4_1745317314054": "Por favor, insira o AccessKeyId da Aliyun",
+ "t_5_1745317315285": "Por favor, insira o AccessKeySecret da Aliyun",
+ "t_6_1745317313383": "Por favor, insira o SecretId do Tencent Cloud",
+ "t_7_1745317313831": "Por favor, insira a SecretKey da Tencent Cloud",
+ "t_0_1745457486299": "Ativado",
+ "t_1_1745457484314": "Parado",
+ "t_2_1745457488661": "Mudar para o modo manual",
+ "t_3_1745457486983": "Mudar para o modo automático",
+ "t_4_1745457497303": "Ao mudar para o modo manual, o fluxo de trabalho não será mais executado automaticamente, mas ainda pode ser executado manualmente",
+ "t_5_1745457494695": "Após mudar para o modo automático, o fluxo de trabalho será executado automaticamente de acordo com o tempo configurado",
+ "t_6_1745457487560": "Fechar fluxo de trabalho atual",
+ "t_7_1745457487185": "Ativar fluxo de trabalho atual",
+ "t_8_1745457496621": "Após o fechamento, o fluxo de trabalho não será mais executado automaticamente e não poderá ser executado manualmente. Continuar?",
+ "t_9_1745457500045": "Após ativar, a configuração do fluxo de trabalho será executada automaticamente ou manualmente. Continuar?",
+ "t_10_1745457486451": "Falha ao adicionar fluxo de trabalho",
+ "t_11_1745457488256": "Falha ao definir o método de execução do fluxo de trabalho",
+ "t_12_1745457489076": "Ativar ou desativar falha no fluxo de trabalho",
+ "t_13_1745457487555": "Falha ao executar o fluxo de trabalho",
+ "t_14_1745457488092": "Falha ao excluir fluxo de trabalho",
+ "t_15_1745457484292": "Sair",
+ "t_16_1745457491607": "Você está prestes a sair. Tem certeza de que deseja sair?",
+ "t_17_1745457488251": "Saindo da conta, por favor aguarde...",
+ "t_18_1745457490931": "Adicionar notificação por e-mail",
+ "t_19_1745457484684": "Salvo com sucesso",
+ "t_20_1745457485905": "Excluído com sucesso",
+ "t_0_1745464080226": "Falha ao obter as configurações do sistema",
+ "t_1_1745464079590": "Falha ao salvar configurações",
+ "t_2_1745464077081": "Falha ao obter configurações de notificação",
+ "t_3_1745464081058": "Falha ao salvar configurações de notificação",
+ "t_4_1745464075382": "Falha ao obter a lista de canais de notificação",
+ "t_5_1745464086047": "Falha ao adicionar canal de notificação por e-mail",
+ "t_6_1745464075714": "Falha ao atualizar o canal de notificação",
+ "t_7_1745464073330": "Falha ao excluir o canal de notificação",
+ "t_8_1745464081472": "Falha ao verificar atualização de versão",
+ "t_9_1745464078110": "Salvar configurações",
+ "t_10_1745464073098": "Configurações básicas",
+ "t_0_1745474945127": "Escolher modelo",
+ "t_0_1745490735213": "Por favor, insira o nome do fluxo de trabalho",
+ "t_1_1745490731990": "Configuração",
+ "t_2_1745490735558": "Por favor, insira o formato de e-mail",
+ "t_3_1745490735059": "Por favor, selecione um provedor de DNS",
+ "t_4_1745490735630": "Por favor, insira o intervalo de renovação",
+ "t_5_1745490738285": "Digite o nome de domínio, o nome de domínio não pode estar vazio",
+ "t_6_1745490738548": "Por favor, insira o e-mail, o e-mail não pode estar vazio",
+ "t_7_1745490739917": "Por favor, selecione um provedor DNS, o provedor DNS não pode estar vazio",
+ "t_8_1745490739319": "Insira o intervalo de renovação, o intervalo de renovação não pode estar vazio",
+ "t_0_1745553910661": "Formato de domínio incorreto, insira o domínio correto",
+ "t_1_1745553909483": "Formato de e-mail inválido, por favor insira um e-mail correto",
+ "t_2_1745553907423": "O intervalo de renovação não pode estar vazio",
+ "t_0_1745735774005": "Digite o nome de domínio do certificado, vários nomes de domínio separados por vírgulas",
+ "t_1_1745735764953": "Caixa de correio",
+ "t_2_1745735773668": "Digite seu e-mail para receber notificações da autoridade certificadora",
+ "t_3_1745735765112": "Provedor de DNS",
+ "t_4_1745735765372": "Adicionar",
+ "t_5_1745735769112": "Intervalo de Renovação (Dias)",
+ "t_6_1745735765205": "Intervalo de renovação",
+ "t_7_1745735768326": "dias, renovado automaticamente após o vencimento",
+ "t_8_1745735765753": "Configurado",
+ "t_9_1745735765287": "Não configurado",
+ "t_10_1745735765165": "Painel Pagode",
+ "t_11_1745735766456": "Site do Painel Pagoda",
+ "t_12_1745735765571": "Painel 1Panel",
+ "t_13_1745735766084": "1Panel site",
+ "t_14_1745735766121": "Tencent Cloud CDN",
+ "t_15_1745735768976": "Tencent Cloud COS",
+ "t_16_1745735766712": "Alibaba Cloud CDN",
+ "t_18_1745735765638": "Tipo de Implantação",
+ "t_19_1745735766810": "Por favor, selecione o tipo de implantação",
+ "t_20_1745735768764": "Por favor, insira o caminho de implantação",
+ "t_21_1745735769154": "Por favor, insira o comando de prefixo",
+ "t_22_1745735767366": "Por favor, insira o comando pós",
+ "t_23_1745735766455": "Por favor, insira o nome do site",
+ "t_24_1745735766826": "Por favor, insira o ID do site",
+ "t_25_1745735766651": "Por favor, insira a região",
+ "t_26_1745735767144": "Por favor, insira o balde",
+ "t_27_1745735764546": "Próximo passo",
+ "t_28_1745735766626": "Selecionar tipo de implantação",
+ "t_29_1745735768933": "Configurar parâmetros de implantação",
+ "t_30_1745735764748": "Modo de operação",
+ "t_31_1745735767891": "Modo de operação não configurado",
+ "t_32_1745735767156": "Ciclo de execução não configurado",
+ "t_33_1745735766532": "Tempo de execução não configurado",
+ "t_34_1745735771147": "Arquivo de certificado (formato PEM)",
+ "t_35_1745735781545": "Por favor, cole o conteúdo do arquivo de certificado, por exemplo:\n-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
+ "t_36_1745735769443": "Arquivo de chave privada (formato KEY)",
+ "t_37_1745735779980": "Cole o conteúdo do arquivo de chave privada, por exemplo:\n-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
+ "t_38_1745735769521": "O conteúdo da chave privada do certificado não pode estar vazio",
+ "t_39_1745735768565": "O formato da chave privada do certificado está incorreto",
+ "t_40_1745735815317": "O conteúdo do certificado não pode estar vazio",
+ "t_41_1745735767016": "Formato do certificado incorreto",
+ "t_0_1745738961258": "Anterior",
+ "t_1_1745738963744": "Enviar",
+ "t_2_1745738969878": "Configurar parâmetros de implantação, o tipo determina a configuração do parâmetro",
+ "t_0_1745744491696": "Fonte do dispositivo de implantação",
+ "t_1_1745744495019": "Selecione a fonte do dispositivo de implantação",
+ "t_2_1745744495813": "Por favor, selecione o tipo de implantação e clique em Avançar",
+ "t_0_1745744902975": "Fonte de implantação",
+ "t_1_1745744905566": "Selecione a fonte de implantação",
+ "t_2_1745744903722": "Adicionar mais dispositivos",
+ "t_0_1745748292337": "Adicionar fonte de implantação",
+ "t_1_1745748290291": "Fonte do Certificado",
+ "t_2_1745748298902": "A origem da implantação do tipo atual está vazia, adicione uma origem de implantação primeiro",
+ "t_3_1745748298161": "Não há nó de aplicação no processo atual, por favor, adicione um nó de aplicação primeiro",
+ "t_4_1745748290292": "Enviar conteúdo",
+ "t_0_1745765864788": "Clique para editar o título do fluxo de trabalho",
+ "t_1_1745765875247": "Excluir Nó - 【{name}】",
+ "t_2_1745765875918": "O nó atual possui nós filhos. A exclusão afetará outros nós. Tem certeza de que deseja excluir?",
+ "t_3_1745765920953": "O nó atual possui dados de configuração, tem certeza que deseja excluí-lo?",
+ "t_4_1745765868807": "Por favor, selecione o tipo de implantação antes de prosseguir para a próxima etapa",
+ "t_0_1745833934390": "Por favor, selecione o tipo",
+ "t_1_1745833931535": "Host",
+ "t_2_1745833931404": "porta",
+ "t_3_1745833936770": "Falha ao obter dados de visão geral da página inicial",
+ "t_4_1745833932780": "Informações da versão",
+ "t_5_1745833933241": "Versão atual",
+ "t_6_1745833933523": "Método de atualização",
+ "t_7_1745833933278": "Última versão",
+ "t_8_1745833933552": "Registro de alterações",
+ "t_9_1745833935269": "Código QR do Atendimento ao Cliente",
+ "t_10_1745833941691": "Escaneie o código QR para adicionar atendimento ao cliente",
+ "t_11_1745833935261": "Conta Oficial do WeChat",
+ "t_12_1745833943712": "Escaneie para seguir a conta oficial do WeChat",
+ "t_13_1745833933630": "Sobre o produto",
+ "t_14_1745833932440": "Servidor SMTP",
+ "t_15_1745833940280": "Por favor, insira o servidor SMTP",
+ "t_16_1745833933819": "Porta SMTP",
+ "t_17_1745833935070": "Por favor, insira a porta SMTP",
+ "t_18_1745833933989": "Conexão SSL/TLS",
+ "t_0_1745887835267": "Por favor, selecione notificação de mensagem",
+ "t_1_1745887832941": "Notificação",
+ "t_2_1745887834248": "Adicionar canal de notificação",
+ "t_3_1745887835089": "Digite o assunto da notificação",
+ "t_4_1745887835265": "Por favor, insira o conteúdo da notificação",
+ "t_0_1745895057404": "Modificar configurações de notificação por e-mail",
+ "t_0_1745920566646": "Assunto da Notificação",
+ "t_1_1745920567200": "Conteúdo da notificação",
+ "t_0_1745936396853": "Clique para obter o código de verificação",
+ "t_0_1745999035681": "faltam {days} dias",
+ "t_1_1745999036289": "Expirando em breve {days} dias",
+ "t_0_1746000517848": "Expirado",
+ "t_0_1746001199409": "Expirado",
+ "t_0_1746004861782": "Provedor DNS está vazio",
+ "t_1_1746004861166": "Adicionar provedor de DNS",
+ "t_0_1746497662220": "Atualizar",
+ "t_0_1746519384035": "Em execução",
+ "t_0_1746579648713": "Detalhes do Histórico de Execução",
+ "t_0_1746590054456": "Status de execução",
+ "t_1_1746590060448": "Método de Ativação",
+ "t_0_1746667592819": "Enviando informações, por favor aguarde...",
+ "t_1_1746667588689": "Chave",
+ "t_2_1746667592840": "URL do painel",
+ "t_3_1746667592270": "Ignorar erros de certificado SSL/TLS",
+ "t_4_1746667590873": "Validação de formulário falhou",
+ "t_5_1746667590676": "Novo fluxo de trabalho",
+ "t_6_1746667592831": "Enviando aplicação, por favor aguarde...",
+ "t_7_1746667592468": "Por favor, insira o nome de domínio correto",
+ "t_8_1746667591924": "Por favor, selecione o método de análise",
+ "t_9_1746667589516": "Atualizar lista",
+ "t_10_1746667589575": "Curinga",
+ "t_11_1746667589598": "Multidomínio",
+ "t_12_1746667589733": "Popular",
+ "t_13_1746667599218": "é um fornecedor de certificados SSL gratuito amplamente utilizado, adequado para sites pessoais e ambientes de teste.",
+ "t_14_1746667590827": "Número de domínios suportados",
+ "t_15_1746667588493": "peça",
+ "t_16_1746667591069": "Suporte a curingas",
+ "t_17_1746667588785": "suporte",
+ "t_18_1746667590113": "Não suportado",
+ "t_19_1746667589295": "Validade",
+ "t_20_1746667588453": "dia",
+ "t_21_1746667590834": "Suporte para Mini Programas",
+ "t_22_1746667591024": "Sites aplicáveis",
+ "t_23_1746667591989": "*.example.com, *.demo.com",
+ "t_24_1746667583520": "*.example.com",
+ "t_25_1746667590147": "example.com、demo.com",
+ "t_26_1746667594662": "www.example.com, example.com",
+ "t_27_1746667589350": "Grátis",
+ "t_28_1746667590336": "Aplicar agora",
+ "t_29_1746667589773": "Endereço do projeto",
+ "t_30_1746667591892": "Digite o caminho do arquivo de certificado",
+ "t_31_1746667593074": "Digite o caminho do arquivo de chave privada",
+ "t_0_1746673515941": "O provedor de DNS atual está vazio, adicione um provedor de DNS primeiro",
+ "t_0_1746676862189": "Falha no envio da notificação de teste",
+ "t_1_1746676859550": "Adicionar Configuração",
+ "t_2_1746676856700": "Ainda não suportado",
+ "t_3_1746676857930": "Notificação por e-mail",
+ "t_4_1746676861473": "Enviar notificações de alerta por e-mail",
+ "t_5_1746676856974": "Notificação DingTalk",
+ "t_6_1746676860886": "Enviar notificações de alarme via robô DingTalk",
+ "t_7_1746676857191": "Notificação do WeChat Work",
+ "t_8_1746676860457": "Enviar notificações de alarme via bot do WeCom",
+ "t_9_1746676857164": "Notificação Feishu",
+ "t_10_1746676862329": "Enviar notificações de alarme via bot Feishu",
+ "t_11_1746676859158": "Notificação WebHook",
+ "t_12_1746676860503": "Enviar notificações de alarme via WebHook",
+ "t_13_1746676856842": "Canal de notificação",
+ "t_14_1746676859019": "Canais de notificação configurados",
+ "t_15_1746676856567": "Desativado",
+ "t_16_1746676855270": "Teste",
+ "t_0_1746677882486": "Último status de execução",
+ "t_0_1746697487119": "O nome do domínio não pode estar vazio",
+ "t_1_1746697485188": "O e-mail não pode estar vazio",
+ "t_2_1746697487164": "Alibaba Cloud OSS",
+ "t_0_1746754500246": "Provedor de Hospedagem",
+ "t_1_1746754499371": "Fonte da API",
+ "t_2_1746754500270": "Tipo de API",
+ "t_0_1746760933542": "Erro de solicitação",
+ "t_0_1746773350551": "Total de {0} itens",
+ "t_1_1746773348701": "Não executado",
+ "t_2_1746773350970": "Fluxo de trabalho automatizado",
+ "t_3_1746773348798": "Quantidade total",
+ "t_4_1746773348957": "Falha na execução",
+ "t_5_1746773349141": "Expirando em breve",
+ "t_6_1746773349980": "Monitoramento em tempo real",
+ "t_7_1746773349302": "Quantidade anormal",
+ "t_8_1746773351524": "Registros recentes de execução de fluxo de trabalho",
+ "t_9_1746773348221": "Ver tudo",
+ "t_10_1746773351576": "Nenhum registro de execução de fluxo de trabalho",
+ "t_11_1746773349054": "Criar fluxo de trabalho",
+ "t_12_1746773355641": "Clique para criar um fluxo de trabalho automatizado para melhorar a eficiência",
+ "t_13_1746773349526": "Solicitar certificado",
+ "t_14_1746773355081": "Clique para solicitar e gerenciar certificados SSL para garantir segurança",
+ "t_15_1746773358151": "Clique para configurar o monitoramento do site e acompanhar o status de execução em tempo real",
+ "t_16_1746773356568": "No máximo, apenas um canal de notificação por e-mail pode ser configurado",
+ "t_17_1746773351220": "Confirmar canal de notificação {0}",
+ "t_18_1746773355467": "Os canais de notificação {0} começarão a enviar alertas.",
+ "t_19_1746773352558": "O canal de notificação atual não suporta testes",
+ "t_20_1746773356060": "Enviando e-mail de teste, por favor aguarde...",
+ "t_21_1746773350759": "E-mail de teste",
+ "t_22_1746773360711": "Enviar um e-mail de teste para a caixa de correio configurada atualmente, continuar?",
+ "t_23_1746773350040": "Confirmação de exclusão",
+ "t_24_1746773349367": "Confirmar exclusão",
+ "t_25_1746773349596": "Por favor, insira o nome",
+ "t_26_1746773353409": "Por favor, insira a porta SMTP correta",
+ "t_27_1746773352584": "Por favor, insira a senha do usuário",
+ "t_28_1746773354048": "Por favor, insira o e-mail do remetente correto",
+ "t_29_1746773351834": "Por favor, insira o e-mail de recebimento correto",
+ "t_30_1746773350013": "E-mail do remetente",
+ "t_31_1746773349857": "Receber E-mail",
+ "t_32_1746773348993": "DingTalk",
+ "t_33_1746773350932": "WeChat Work",
+ "t_34_1746773350153": "Feishu",
+ "t_35_1746773362992": "Uma ferramenta de gerenciamento do ciclo de vida completo de certificados SSL que integra solicitação, gerenciamento, implantação e monitoramento.",
+ "t_36_1746773348989": "Pedido de Certificado",
+ "t_37_1746773356895": "Suporte à obtenção de certificados do Let's Encrypt através do protocolo ACME",
+ "t_38_1746773349796": "Gerenciamento de Certificados",
+ "t_39_1746773358932": "Gerenciamento centralizado de todos os certificados SSL, incluindo certificados carregados manualmente e aplicados automaticamente",
+ "t_40_1746773352188": "Implantaçã de certificado",
+ "t_41_1746773364475": "Suporte à implantação de certificados com um clique em várias plataformas, como Alibaba Cloud, Tencent Cloud, Pagoda Panel, 1Panel, etc.",
+ "t_42_1746773348768": "Monitoramento do site",
+ "t_43_1746773359511": "Monitoramento em tempo real do status do certificado SSL do site para alertar sobre a expiração do certificado",
+ "t_44_1746773352805": "Tarefa automatizada:",
+ "t_45_1746773355717": "Suporta tarefas agendadas, renova automaticamente os certificados e implanta",
+ "t_46_1746773350579": "Suporte multiplataforma",
+ "t_47_1746773360760": "Suporta métodos de verificação DNS para vários provedores de DNS (Alibaba Cloud, Tencent Cloud, etc.)"
+}
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/locales/model/ruRU.json b/frontend/apps/allin-ssl/src/locales/model/ruRU.json
new file mode 100644
index 0000000..495537d
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/locales/model/ruRU.json
@@ -0,0 +1,490 @@
+{
+ "t_0_1746773763967": "Вы уверены, что хотите удалить {0}, канал уведомлений?",
+ "t_1_1746773763643": "Let's Encrypt и другие центры сертификации автоматически подают заявки на бесплатные сертификаты",
+ "t_0_1744098811152": "Предупреждение: Вы вошли в неизвестную зону, посещаемая страница не существует, пожалуйста, нажмите кнопку, чтобы вернуться на главную страницу.",
+ "t_1_1744098801860": "Вернуться на главную",
+ "t_2_1744098804908": "Совет по безопасности: Если вы считаете, что это ошибка, немедленно свяжитесь с администратором",
+ "t_3_1744098802647": "Развернуть главное меню",
+ "t_4_1744098802046": "Сворачиваемое главное меню",
+ "t_0_1744164843238": "Добро пожаловать в AllinSSL, эффективное управление SSL-сертификатами",
+ "t_1_1744164835667": "AllinSSL",
+ "t_2_1744164839713": "Вход в аккаунт",
+ "t_3_1744164839524": "Введите имя пользователя",
+ "t_4_1744164840458": "Введіть пароль",
+ "t_5_1744164840468": "Запомнить пароль",
+ "t_6_1744164838900": "Забыли пароль?",
+ "t_7_1744164838625": "Вход в систему",
+ "t_8_1744164839833": "Вход",
+ "t_0_1744168657526": "Выйти из системы",
+ "t_0_1744258111441": "Главная",
+ "t_1_1744258113857": "Автоматическая部署",
+ "t_2_1744258111238": "Управление сертификатами",
+ "t_3_1744258111182": "Заявка на сертификат",
+ "t_4_1744258111238": "Управление API авторизации",
+ "t_5_1744258110516": "Мониторинг",
+ "t_6_1744258111153": "Настройки",
+ "t_0_1744861190562": "Возврат списка workflows",
+ "t_1_1744861189113": "Запуск",
+ "t_2_1744861190040": "Сохранить",
+ "t_3_1744861190932": "Выберите узел для конфигурации",
+ "t_4_1744861194395": "Нажмите на узел в левой части схематического процесса, чтобы настроить его",
+ "t_5_1744861189528": "начать",
+ "t_6_1744861190121": "Элемент не выбран",
+ "t_7_1744861189625": "Конфигурация сохранена",
+ "t_8_1744861189821": "Начать процесс",
+ "t_9_1744861189580": "Выбранный узел:",
+ "t_0_1744870861464": "узел",
+ "t_1_1744870861944": "Конфигурация узла",
+ "t_2_1744870863419": "Выберите левый узел для настройки",
+ "t_3_1744870864615": "Не найден компонент конфигурации для этого типа узла",
+ "t_4_1744870861589": "Отменить",
+ "t_5_1744870862719": "подтвердить",
+ "t_0_1744875938285": "каждую минуту",
+ "t_1_1744875938598": "каждый час",
+ "t_2_1744875938555": "каждый день",
+ "t_3_1744875938310": "каждый месяц",
+ "t_4_1744875940750": "Автоматическое выполнение",
+ "t_5_1744875940010": "Ручное выполнение",
+ "t_0_1744879616135": "Тест PID",
+ "t_1_1744879616555": "Введите тестовый PID",
+ "t_2_1744879616413": "Период выполнения",
+ "t_3_1744879615723": "минута",
+ "t_4_1744879616168": "Введите минуты",
+ "t_5_1744879615277": "час",
+ "t_6_1744879616944": "Введіть часы",
+ "t_7_1744879615743": "Дата",
+ "t_8_1744879616493": "Выберите дату",
+ "t_0_1744942117992": "каждую неделю",
+ "t_1_1744942116527": "понедельник",
+ "t_2_1744942117890": "вторник",
+ "t_3_1744942117885": "Среда",
+ "t_4_1744942117738": "четверг",
+ "t_5_1744942117167": "пятница",
+ "t_6_1744942117815": "суббота",
+ "t_7_1744942117862": "воскресенье",
+ "t_0_1744958839535": "Введите доменное имя",
+ "t_1_1744958840747": "Введите адрес электронной почты",
+ "t_2_1744958840131": "Неправильный формат электронной почты",
+ "t_3_1744958840485": "Выберите предоставление DNS-авторизации",
+ "t_4_1744958838951": "Локальная установка",
+ "t_5_1744958839222": "SSH-деплой",
+ "t_6_1744958843569": "Панель Баота/1 панель (Установить на панели сертификат)",
+ "t_7_1744958841708": "1панель (Деплой на указанный веб-проект)",
+ "t_8_1744958841658": "Кloud CDN/АлиCloud CDN",
+ "t_9_1744958840634": "Тencent Cloud WAF",
+ "t_10_1744958860078": "АлиCloud WAF",
+ "t_11_1744958840439": "Этот автоматически применяемый сертификат",
+ "t_12_1744958840387": "Список доступных сертификатов",
+ "t_13_1744958840714": "PEM (*.pem, *.crt, *.key)",
+ "t_14_1744958839470": "PFX (*.pfx)",
+ "t_15_1744958840790": "JKS (*.jks)",
+ "t_16_1744958841116": "POSIX bash (Linux/macOS)",
+ "t_17_1744958839597": "Комуンド лайн (Windows)",
+ "t_18_1744958839895": "PowerShell (Windows)",
+ "t_19_1744958839297": "Сертификат1",
+ "t_20_1744958839439": "Сертификат 2",
+ "t_21_1744958839305": "Сервер 1",
+ "t_22_1744958841926": "Сервер 2",
+ "t_23_1744958838717": "Панель 1",
+ "t_24_1744958845324": "PANEL 2",
+ "t_25_1744958839236": "Сайт 1",
+ "t_26_1744958839682": "Сайт 2",
+ "t_27_1744958840234": "Тencent Cloud 1",
+ "t_28_1744958839760": "Алиyun 1",
+ "t_29_1744958838904": "день",
+ "t_30_1744958843864": "Формат сертификата не правильный, пожалуйста, проверьте, содержит ли он полную информацию о заголовке и подзаголовке сертификата",
+ "t_31_1744958844490": "Формат私ного ключа incorrect, пожалуйста, проверьте, содержит ли он полный идентификатор заголовка и нижнего колонтитула частного ключа",
+ "t_0_1745215914686": "Название автоматизации",
+ "t_2_1745215915397": "автоматический",
+ "t_3_1745215914237": "ручной",
+ "t_4_1745215914951": "Активный статус",
+ "t_5_1745215914671": "Включить",
+ "t_6_1745215914104": "Отключение",
+ "t_7_1745215914189": "Время создания",
+ "t_8_1745215914610": "Операция",
+ "t_9_1745215914666": "История выполнения",
+ "t_10_1745215914342": "исполнение",
+ "t_11_1745215915429": "Редактировать",
+ "t_12_1745215914312": "Удалить",
+ "t_13_1745215915455": "Выполнение процесса",
+ "t_14_1745215916235": "Успешное выполнение рабочей流程",
+ "t_15_1745215915743": "Неудача выполнения процесса",
+ "t_16_1745215915209": "Удалить workflow",
+ "t_17_1745215915985": "Удаление рабочей схемы успешено",
+ "t_18_1745215915630": "Не удалось удалить рабочий процесс",
+ "t_0_1745227838699": "Новый автоматический部署",
+ "t_1_1745227838776": "Введите имя автоматизации",
+ "t_2_1745227839794": "Уверены, что хотите выполнить workflow {name}?",
+ "t_3_1745227841567": "Подтвердите удаление {name} потока работы? Это действие нельзя отменить.",
+ "t_4_1745227838558": "Время выполнения",
+ "t_5_1745227839906": "Время окончания",
+ "t_6_1745227838798": "Способ выполнения",
+ "t_7_1745227838093": "Состояние",
+ "t_8_1745227838023": "Успех",
+ "t_9_1745227838305": "неудача",
+ "t_10_1745227838234": "В процессе",
+ "t_11_1745227838422": "неизвестно",
+ "t_12_1745227838814": "Подробности",
+ "t_13_1745227838275": "Загрузить сертификат",
+ "t_14_1745227840904": "Введіть доменное имя сертификата или название бренда для поиска",
+ "t_15_1745227839354": "вместе",
+ "t_16_1745227838930": "шт",
+ "t_17_1745227838561": "Доменное имя",
+ "t_18_1745227838154": "Бренд",
+ "t_19_1745227839107": "Оставшиеся дни",
+ "t_20_1745227838813": "Время истечения",
+ "t_21_1745227837972": "Источник",
+ "t_22_1745227838154": "Автоматическая заявка",
+ "t_23_1745227838699": "Ручная загрузка",
+ "t_24_1745227839508": "Добавить время",
+ "t_25_1745227838080": "Загрузка",
+ "t_27_1745227838583": "Скоро закончится",
+ "t_28_1745227837903": "нормальный",
+ "t_29_1745227838410": "Удалить сертификат",
+ "t_30_1745227841739": "Вы уверены, что хотите удалить этот сертификат? Эта операция не может быть отменена.",
+ "t_31_1745227838461": "Подтвердите",
+ "t_32_1745227838439": "Название сертификата",
+ "t_33_1745227838984": "Введіть назву сертификата",
+ "t_34_1745227839375": "Содержание сертификата (PEM)",
+ "t_35_1745227839208": "Введіть содержимое сертификата",
+ "t_36_1745227838958": "Содержание частного ключа (KEY)",
+ "t_37_1745227839669": "Введіть содержимое частного ключа",
+ "t_38_1745227838813": "Не удалось загрузить",
+ "t_39_1745227838696": "Не удалось загрузить",
+ "t_40_1745227838872": "Удаление失败",
+ "t_0_1745289355714": "Добавить API авторизации",
+ "t_1_1745289356586": "Введите имя или тип авторизованного API",
+ "t_2_1745289353944": "Название",
+ "t_3_1745289354664": "Тип API авторизации",
+ "t_4_1745289354902": "API для редактирования разрешений",
+ "t_5_1745289355718": "Удаление API авторизации",
+ "t_6_1745289358340": "Уверены, что хотите удалить этот авторизованный API? Это действие нельзя отменить.",
+ "t_7_1745289355714": "Добавление失败",
+ "t_8_1745289354902": "Обновление失败",
+ "t_9_1745289355714": "Прошло {days} дней",
+ "t_10_1745289354650": "Мониторинг управления",
+ "t_11_1745289354516": "Добавить мониторинг",
+ "t_12_1745289356974": "Введите имя монитора или домен для поиска",
+ "t_13_1745289354528": "Название монитора",
+ "t_14_1745289354902": "Сертификат домена",
+ "t_15_1745289355714": "Аутентификационная служба",
+ "t_16_1745289354902": "Состояние сертификата",
+ "t_17_1745289355715": "Дата окончания действия сертификата",
+ "t_18_1745289354598": "Каналы оповещений",
+ "t_19_1745289354676": "Время последней проверки",
+ "t_20_1745289354598": "Редактирование мониторинга",
+ "t_21_1745289354598": "Подтвердите удаление",
+ "t_22_1745289359036": "Элементы нельзя восстановить после удаления. Вы уверены, что хотите удалить этот монитор?",
+ "t_23_1745289355716": "Не удалось изменить",
+ "t_24_1745289355715": "Сбой настройки",
+ "t_25_1745289355721": "Введите код подтверждения",
+ "t_26_1745289358341": "Проверка формы не пройдена, пожалуйста, проверьте填写的内容",
+ "t_27_1745289355721": "Введите имя авторизованного API",
+ "t_28_1745289356040": "Выберите тип авторизации API",
+ "t_29_1745289355850": "Введите IP-адрес сервера",
+ "t_30_1745289355718": "Введите порт SSH",
+ "t_31_1745289355715": "Введите SSH-ключ",
+ "t_32_1745289356127": "Введите адрес Ботты",
+ "t_33_1745289355721": "Введіть ключ API",
+ "t_34_1745289356040": "Введите адрес 1panel",
+ "t_35_1745289355714": "Введите AccessKeyId",
+ "t_36_1745289355715": "Введите AccessKeySecret",
+ "t_37_1745289356041": "Введіть SecretId",
+ "t_38_1745289356419": "Введите SecretKey",
+ "t_39_1745289354902": "Успешно обновлено",
+ "t_40_1745289355715": "Успешно добавлено",
+ "t_41_1745289354902": "Тип",
+ "t_42_1745289355715": "Сервер IP",
+ "t_43_1745289354598": "Порт SSH",
+ "t_44_1745289354583": "Имя пользователя",
+ "t_45_1745289355714": "Способ проверки",
+ "t_46_1745289355723": "Парольная аутентификация",
+ "t_47_1745289355715": "Ключевая аутентификация",
+ "t_48_1745289355714": "Пароль",
+ "t_49_1745289355714": "SSH частный ключ",
+ "t_50_1745289355715": "Введите SSH частный ключ",
+ "t_51_1745289355714": "Пароль私ного ключа",
+ "t_52_1745289359565": "Если у私ного ключа есть пароль, введите",
+ "t_53_1745289356446": "Адрес панели Баота",
+ "t_54_1745289358683": "Введіть адресс панели Baota, например: https://bt.example.com",
+ "t_55_1745289355715": "API ключ",
+ "t_56_1745289355714": "Адрес 1 панели",
+ "t_57_1745289358341": "Введіть адресс 1panel, например: https://1panel.example.com",
+ "t_58_1745289355721": "Введите ID AccessKey",
+ "t_59_1745289356803": "Введите секрет AccessKey",
+ "t_60_1745289355715": "Введите имя монитора",
+ "t_61_1745289355878": "Введите домен/IP",
+ "t_62_1745289360212": "Выберите период проверки",
+ "t_63_1745289354897": "5 минут",
+ "t_64_1745289354670": "10 минут",
+ "t_65_1745289354591": "15 минут",
+ "t_66_1745289354655": "30 минут",
+ "t_67_1745289354487": "60 минут",
+ "t_68_1745289354676": "Электронная почта",
+ "t_69_1745289355721": "СМС",
+ "t_70_1745289354904": "Вайбер",
+ "t_71_1745289354583": "Домен/IP",
+ "t_72_1745289355715": "Период проверки",
+ "t_73_1745289356103": "Выберите канал уведомлений",
+ "t_0_1745289808449": "Введите имя авторизованного API",
+ "t_0_1745294710530": "Удалить мониторинг",
+ "t_0_1745295228865": "Время обновления",
+ "t_0_1745317313835": "Ошибочный формат IP-адреса сервера",
+ "t_1_1745317313096": "Ошибка формата порта",
+ "t_2_1745317314362": "Ошибка формата URL адреса панели",
+ "t_3_1745317313561": "Введіть ключ API панелі",
+ "t_4_1745317314054": "Введите Aliyun AccessKeyId",
+ "t_5_1745317315285": "Ввведите секретный ключ AccessKey Aliyun",
+ "t_6_1745317313383": "Введите Tencent Cloud SecretId",
+ "t_7_1745317313831": "Введите SecretKey Tencent Cloud",
+ "t_0_1745457486299": "Включено",
+ "t_1_1745457484314": "Остановлено",
+ "t_2_1745457488661": "Переключиться в ручной режим",
+ "t_3_1745457486983": "Переключиться в автоматический режим",
+ "t_4_1745457497303": "После переключения в ручной режим рабочий процесс больше не будет выполняться автоматически, но его все равно можно выполнить вручную",
+ "t_5_1745457494695": "После переключения в автоматический режим рабочий процесс будет автоматически выполняться в соответствии с настроенным временем",
+ "t_6_1745457487560": "Закрыть текущий рабочий процесс",
+ "t_7_1745457487185": "Включить текущий рабочий процесс",
+ "t_8_1745457496621": "После закрытия рабочий процесс больше не будет выполняться автоматически и вручную его тоже невозможно будет выполнить. Продолжить?",
+ "t_9_1745457500045": "После включения конфигурация рабочего процесса будет выполняться автоматически или вручную. Продолжить?",
+ "t_10_1745457486451": "Не удалось добавить рабочий процесс",
+ "t_11_1745457488256": "Не удалось установить метод выполнения рабочего процесса",
+ "t_12_1745457489076": "Включение или отключение сбоя рабочего процесса",
+ "t_13_1745457487555": "Не удалось выполнить рабочий процесс",
+ "t_14_1745457488092": "Не удалось удалить рабочий процесс",
+ "t_15_1745457484292": "Выход",
+ "t_16_1745457491607": "Вы собираетесь выйти из системы. Вы уверены, что хотите выйти?",
+ "t_17_1745457488251": "Выход из системы, пожалуйста, подождите...",
+ "t_18_1745457490931": "Добавить уведомление по электронной почте",
+ "t_19_1745457484684": "Сохранено успешно",
+ "t_20_1745457485905": "Удалено успешно",
+ "t_0_1745464080226": "Не удалось получить настройки системы",
+ "t_1_1745464079590": "Не удалось сохранить настройки",
+ "t_2_1745464077081": "Не удалось получить настройки уведомлений",
+ "t_3_1745464081058": "Не удалось сохранить настройки уведомлений",
+ "t_4_1745464075382": "Не удалось получить список каналов уведомлений",
+ "t_5_1745464086047": "Не удалось добавить канал уведомлений по электронной почте",
+ "t_6_1745464075714": "Не удалось обновить канал уведомлений",
+ "t_7_1745464073330": "Не удалось удалить канал уведомлений",
+ "t_8_1745464081472": "Не удалось проверить обновление версии",
+ "t_9_1745464078110": "Сохранить настройки",
+ "t_10_1745464073098": "Основные настройки",
+ "t_0_1745474945127": "Выбрать шаблон",
+ "t_0_1745490735213": "Введите название рабочего процесса",
+ "t_1_1745490731990": "Конфигурация",
+ "t_2_1745490735558": "Пожалуйста, введите формат электронной почты",
+ "t_3_1745490735059": "Пожалуйста, выберите поставщика DNS",
+ "t_4_1745490735630": "Введите интервал продления",
+ "t_5_1745490738285": "Введите доменное имя, оно не может быть пустым",
+ "t_6_1745490738548": "Пожалуйста, введите адрес электронной почты, поле не может быть пустым",
+ "t_7_1745490739917": "Пожалуйста, выберите DNS-провайдера, DNS-провайдер не может быть пустым",
+ "t_8_1745490739319": "Введите интервал продления, интервал продления не может быть пустым",
+ "t_0_1745553910661": "Ошибка формата домена, введите правильный домен",
+ "t_1_1745553909483": "Неверный формат электронной почты, введите правильный адрес",
+ "t_2_1745553907423": "Интервал продления не может быть пустым",
+ "t_0_1745735774005": "Введите доменное имя сертификата, несколько доменных имен разделяются запятыми",
+ "t_1_1745735764953": "Почтовый ящик",
+ "t_2_1745735773668": "Введите адрес электронной почты для получения уведомлений от сертификационного органа",
+ "t_3_1745735765112": "Провайдер DNS",
+ "t_4_1745735765372": "Добавить",
+ "t_5_1745735769112": "Интервал продления (дни)",
+ "t_6_1745735765205": "Интервал продления",
+ "t_7_1745735768326": "дней, автоматически продлевается после истечения срока",
+ "t_8_1745735765753": "Настроено",
+ "t_9_1745735765287": "Не настроено",
+ "t_10_1745735765165": "Панель Пагода",
+ "t_11_1745735766456": "Веб-сайт панели Pagoda",
+ "t_12_1745735765571": "Панель 1Panel",
+ "t_13_1745735766084": "1Panel веб-сайт",
+ "t_14_1745735766121": "Tencent Cloud CDN",
+ "t_15_1745735768976": "Tencent Cloud COS",
+ "t_16_1745735766712": "Alibaba Cloud CDN",
+ "t_18_1745735765638": "Тип развертывания",
+ "t_19_1745735766810": "Пожалуйста, выберите тип развертывания",
+ "t_20_1745735768764": "Введите путь развертывания",
+ "t_21_1745735769154": "Пожалуйста, введите префиксную команду",
+ "t_22_1745735767366": "Пожалуйста, введите пост-команду",
+ "t_23_1745735766455": "Пожалуйста, введите название сайта",
+ "t_24_1745735766826": "Введите идентификатор сайта",
+ "t_25_1745735766651": "Пожалуйста, введите регион",
+ "t_26_1745735767144": "Пожалуйста, введите ведро",
+ "t_27_1745735764546": "Следующий шаг",
+ "t_28_1745735766626": "Выберите тип развертывания",
+ "t_29_1745735768933": "Настройка параметров развертывания",
+ "t_30_1745735764748": "Режим работы",
+ "t_31_1745735767891": "Режим работы не настроен",
+ "t_32_1745735767156": "Цикл выполнения не настроен",
+ "t_33_1745735766532": "Время выполнения не настроено",
+ "t_34_1745735771147": "Файл сертификата (формат PEM)",
+ "t_35_1745735781545": "Пожалуйста, вставьте содержимое файла сертификата, например:\n-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
+ "t_36_1745735769443": "Файл закрытого ключа (формат KEY)",
+ "t_37_1745735779980": "Вставьте содержимое файла закрытого ключа, например:\n-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
+ "t_38_1745735769521": "Содержимое закрытого ключа сертификата не может быть пустым",
+ "t_39_1745735768565": "Неверный формат закрытого ключа сертификата",
+ "t_40_1745735815317": "Содержимое сертификата не может быть пустым",
+ "t_41_1745735767016": "Неправильный формат сертификата",
+ "t_0_1745738961258": "Назад",
+ "t_1_1745738963744": "Отправить",
+ "t_2_1745738969878": "Настройка параметров развертывания, тип определяет конфигурацию параметров",
+ "t_0_1745744491696": "Источник устройства развертывания",
+ "t_1_1745744495019": "Пожалуйста, выберите источник устройства развертывания",
+ "t_2_1745744495813": "Пожалуйста, выберите тип развертывания и нажмите Далее",
+ "t_0_1745744902975": "Источник развертывания",
+ "t_1_1745744905566": "Выберите источник развертывания",
+ "t_2_1745744903722": "Добавить больше устройств",
+ "t_0_1745748292337": "Добавить источник развертывания",
+ "t_1_1745748290291": "Источник сертификата",
+ "t_2_1745748298902": "Источник развертывания текущего типа пуст, сначала добавьте источник развертывания",
+ "t_3_1745748298161": "В текущем процессе нет узла заявки, пожалуйста, сначала добавьте узел заявки",
+ "t_4_1745748290292": "Отправить содержание",
+ "t_0_1745765864788": "Нажмите, чтобы редактировать заголовок рабочего процесса",
+ "t_1_1745765875247": "Удалить узел - 【{name}】",
+ "t_2_1745765875918": "Текущий узел имеет дочерние узлы. Удаление повлияет на другие узлы. Вы уверены, что хотите удалить?",
+ "t_3_1745765920953": "Текущий узел содержит данные конфигурации, вы уверены, что хотите их удалить?",
+ "t_4_1745765868807": "Пожалуйста, выберите тип развертывания, прежде чем перейти к следующему шагу",
+ "t_0_1745833934390": "Пожалуйста, выберите тип",
+ "t_1_1745833931535": "Хост",
+ "t_2_1745833931404": "порт",
+ "t_3_1745833936770": "Не удалось получить обзорные данные главной страницы",
+ "t_4_1745833932780": "Информация о версии",
+ "t_5_1745833933241": "Текущая версия",
+ "t_6_1745833933523": "Метод обновления",
+ "t_7_1745833933278": "Последняя версия",
+ "t_8_1745833933552": "История изменений",
+ "t_9_1745833935269": "QR-код службы поддержки",
+ "t_10_1745833941691": "Сканируйте QR-код, чтобы добавить службу поддержки",
+ "t_11_1745833935261": "Официальный аккаунт WeChat",
+ "t_12_1745833943712": "Сканируйте QR-код, чтобы подписаться на официальный аккаунт WeChat",
+ "t_13_1745833933630": "О продукте",
+ "t_14_1745833932440": "SMTP сервер",
+ "t_15_1745833940280": "Пожалуйста, введите SMTP сервер",
+ "t_16_1745833933819": "SMTP порт",
+ "t_17_1745833935070": "Введите порт SMTP",
+ "t_18_1745833933989": "SSL/TLS соединение",
+ "t_0_1745887835267": "Пожалуйста, выберите уведомление о сообщении",
+ "t_1_1745887832941": "Уведомление",
+ "t_2_1745887834248": "Добавить канал уведомлений",
+ "t_3_1745887835089": "Введите тему уведомления",
+ "t_4_1745887835265": "Введите содержание уведомления",
+ "t_0_1745895057404": "Изменение настроек уведомлений по электронной почте",
+ "t_0_1745920566646": "Тема уведомления",
+ "t_1_1745920567200": "Содержание уведомления",
+ "t_0_1745936396853": "Нажмите, чтобы получить код подтверждения",
+ "t_0_1745999035681": "осталось {days} дней",
+ "t_1_1745999036289": "Скоро истекает срок действия {days} дней",
+ "t_0_1746000517848": "Истек срок",
+ "t_0_1746001199409": "Истекший",
+ "t_0_1746004861782": "DNS-провайдер пуст",
+ "t_1_1746004861166": "Добавить DNS-провайдера",
+ "t_0_1746497662220": "Обновить",
+ "t_0_1746519384035": "В работе",
+ "t_0_1746579648713": "Детали истории выполнения",
+ "t_0_1746590054456": "Статус выполнения",
+ "t_1_1746590060448": "Способ активации",
+ "t_0_1746667592819": "Отправка информации, пожалуйста, подождите...",
+ "t_1_1746667588689": "Ключ",
+ "t_2_1746667592840": "URL панели",
+ "t_3_1746667592270": "Игнорировать ошибки SSL/TLS сертификатов",
+ "t_4_1746667590873": "Проверка формы не удалась",
+ "t_5_1746667590676": "Новый рабочий процесс",
+ "t_6_1746667592831": "Отправка заявки, пожалуйста, подождите...",
+ "t_7_1746667592468": "Пожалуйста, введите правильное доменное имя",
+ "t_8_1746667591924": "Пожалуйста, выберите метод анализа",
+ "t_9_1746667589516": "Обновить список",
+ "t_10_1746667589575": "Подстановочный знак",
+ "t_11_1746667589598": "Мультидомен",
+ "t_12_1746667589733": "Популярные",
+ "t_13_1746667599218": "широко используемый бесплатный провайдер SSL-сертификатов, подходящий для личных веб-сайтов и тестовых сред.",
+ "t_14_1746667590827": "Количество поддерживаемых доменов",
+ "t_15_1746667588493": "штука",
+ "t_16_1746667591069": "Поддержка подстановочных знаков",
+ "t_17_1746667588785": "поддержка",
+ "t_18_1746667590113": "Не поддерживается",
+ "t_19_1746667589295": "Срок действия",
+ "t_20_1746667588453": "день",
+ "t_21_1746667590834": "Поддержка мини-программ",
+ "t_22_1746667591024": "Применимые веб-сайты",
+ "t_23_1746667591989": "*.example.com, *.demo.com",
+ "t_24_1746667583520": "*.example.com",
+ "t_25_1746667590147": "example.com、demo.com",
+ "t_26_1746667594662": "www.example.com, example.com",
+ "t_27_1746667589350": "Бесплатно",
+ "t_28_1746667590336": "Подать заявку сейчас",
+ "t_29_1746667589773": "Адрес проекта",
+ "t_30_1746667591892": "Введите путь к файлу сертификата",
+ "t_31_1746667593074": "Введите путь к файлу закрытого ключа",
+ "t_0_1746673515941": "Текущий DNS-провайдер отсутствует, сначала добавьте DNS-провайдера",
+ "t_0_1746676862189": "Не удалось отправить тестовое уведомление",
+ "t_1_1746676859550": "Добавить конфигурацию",
+ "t_2_1746676856700": "Пока не поддерживается",
+ "t_3_1746676857930": "Уведомление по электронной почте",
+ "t_4_1746676861473": "Отправка уведомлений о тревоге по электронной почте",
+ "t_5_1746676856974": "Уведомление DingTalk",
+ "t_6_1746676860886": "Отправка уведомлений о тревоге через робота DingTalk",
+ "t_7_1746676857191": "Уведомление WeChat Work",
+ "t_8_1746676860457": "Отправка уведомлений о тревоге через бота WeCom",
+ "t_9_1746676857164": "Уведомление Feishu",
+ "t_10_1746676862329": "Отправка уведомлений о тревоге через бота Feishu",
+ "t_11_1746676859158": "WebHook уведомление",
+ "t_12_1746676860503": "Отправка уведомлений о тревоге через WebHook",
+ "t_13_1746676856842": "Канал уведомлений",
+ "t_14_1746676859019": "Настроенные каналы уведомлений",
+ "t_15_1746676856567": "Отключено",
+ "t_16_1746676855270": "тест",
+ "t_0_1746677882486": "Последний статус выполнения",
+ "t_0_1746697487119": "Имя домена не может быть пустым",
+ "t_1_1746697485188": "Почта не может быть пустой",
+ "t_2_1746697487164": "Alibaba Cloud OSS",
+ "t_0_1746754500246": "Хостинг-провайдер",
+ "t_1_1746754499371": "Источник API",
+ "t_2_1746754500270": "Тип API",
+ "t_0_1746760933542": "Ошибка запроса",
+ "t_0_1746773350551": "Всего {0}",
+ "t_1_1746773348701": "Не выполнено",
+ "t_2_1746773350970": "Автоматизированный рабочий процесс",
+ "t_3_1746773348798": "Общее количество",
+ "t_4_1746773348957": "Ошибка выполнения",
+ "t_5_1746773349141": "Скоро истекает",
+ "t_6_1746773349980": "Мониторинг в реальном времени",
+ "t_7_1746773349302": "Аномальное количество",
+ "t_8_1746773351524": "Недавние записи выполнения рабочего процесса",
+ "t_9_1746773348221": "Просмотреть все",
+ "t_10_1746773351576": "Нет записей выполнения рабочего процесса",
+ "t_11_1746773349054": "Создание рабочего процесса",
+ "t_12_1746773355641": "Нажмите, чтобы создать автоматизированный рабочий процесс для повышения эффективности",
+ "t_13_1746773349526": "Подать заявку на сертификат",
+ "t_14_1746773355081": "Нажмите, чтобы подать заявку на SSL-сертификаты и управлять ими для обеспечения безопасности",
+ "t_15_1746773358151": "Нажмите, чтобы настроить мониторинг веб-сайта и отслеживать состояние работы в режиме реального времени",
+ "t_16_1746773356568": "Можно настроить только один канал уведомлений по электронной почте",
+ "t_17_1746773351220": "Подтвердить канал уведомлений {0}",
+ "t_18_1746773355467": "{0} каналы уведомлений начнут отправлять оповещения.",
+ "t_19_1746773352558": "Текущий канал уведомлений не поддерживает тестирование",
+ "t_20_1746773356060": "Отправка тестового письма, пожалуйста, подождите...",
+ "t_21_1746773350759": "Тестовое письмо",
+ "t_22_1746773360711": "Отправить тестовое письмо на текущий настроенный почтовый ящик, продолжить?",
+ "t_23_1746773350040": "Подтверждение удаления",
+ "t_24_1746773349367": "Подтвердите удаление",
+ "t_25_1746773349596": "Пожалуйста, введите имя",
+ "t_26_1746773353409": "Пожалуйста, введите правильный порт SMTP",
+ "t_27_1746773352584": "Введите пароль пользователя",
+ "t_28_1746773354048": "Пожалуйста, введите правильный адрес электронной почты отправителя",
+ "t_29_1746773351834": "Пожалуйста, введите правильную электронную почту",
+ "t_30_1746773350013": "Электронная почта отправителя",
+ "t_31_1746773349857": "Получить электронную почту",
+ "t_32_1746773348993": "ДинТолк",
+ "t_33_1746773350932": "WeChat Work",
+ "t_34_1746773350153": "Фэйшу",
+ "t_35_1746773362992": "Инструмент управления полным жизненным циклом SSL-сертификатов, объединяющий подачу заявки, управление, развертывание и мониторинг.",
+ "t_36_1746773348989": "Заявка на сертификат",
+ "t_37_1746773356895": "Поддержка получения сертификатов от Let's Encrypt через протокол ACME",
+ "t_38_1746773349796": "Управление сертификатами",
+ "t_39_1746773358932": "Централизованное управление всеми SSL-сертификатами, включая загруженные вручную и автоматически запрошенные сертификаты",
+ "t_40_1746773352188": "Развертывание сертификата",
+ "t_41_1746773364475": "Поддержка развертывания сертификатов в один клик на нескольких платформах, таких как Alibaba Cloud, Tencent Cloud, Pagoda Panel, 1Panel и др.",
+ "t_42_1746773348768": "Мониторинг сайта",
+ "t_43_1746773359511": "Мониторинг состояния SSL-сертификатов сайта в режиме реального времени с предупреждением об истечении срока действия сертификата",
+ "t_44_1746773352805": "Автоматизированная задача:",
+ "t_45_1746773355717": "Поддержка запланированных задач, автоматическое продление сертификатов и развертывание",
+ "t_46_1746773350579": "Поддержка нескольких платформ",
+ "t_47_1746773360760": "Поддерживает методы проверки DNS для нескольких поставщиков DNS (Alibaba Cloud, Tencent Cloud и др.)"
+}
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/locales/model/zhCN.json b/frontend/apps/allin-ssl/src/locales/model/zhCN.json
new file mode 100644
index 0000000..d4f594a
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/locales/model/zhCN.json
@@ -0,0 +1,490 @@
+{
+ "t_0_1746773763967": "确定要删除{0},通知渠道吗?",
+ "t_1_1746773763643": "Let's Encrypt等CA自动申请免费证书",
+ "t_0_1744098811152": "警告:您已进入未知区域,所访问的页面不存在,请点击按钮返回首页。",
+ "t_1_1744098801860": "返回首页",
+ "t_2_1744098804908": "安全提示:如果您认为这是个错误,请立即联系管理员",
+ "t_3_1744098802647": "展开主菜单",
+ "t_4_1744098802046": "折叠主菜单",
+ "t_0_1744164843238": "欢迎使用AllinSSL,高效管理SSL证书",
+ "t_1_1744164835667": "AllinSSL",
+ "t_2_1744164839713": "账号登录",
+ "t_3_1744164839524": "请输入用户名",
+ "t_4_1744164840458": "请输入密码",
+ "t_5_1744164840468": "记住密码",
+ "t_6_1744164838900": "忘记密码",
+ "t_7_1744164838625": "登录中",
+ "t_8_1744164839833": "登录",
+ "t_0_1744168657526": "退出登录",
+ "t_0_1744258111441": "首页",
+ "t_1_1744258113857": "自动化部署",
+ "t_2_1744258111238": "证书管理",
+ "t_3_1744258111182": "证书申请",
+ "t_4_1744258111238": "授权API管理",
+ "t_5_1744258110516": "监控",
+ "t_6_1744258111153": "设置",
+ "t_0_1744861190562": "返回工作流列表",
+ "t_1_1744861189113": "运行",
+ "t_2_1744861190040": "保存",
+ "t_3_1744861190932": "请选择一个节点进行配置",
+ "t_4_1744861194395": "点击左侧流程图中的节点来配置它",
+ "t_5_1744861189528": "开始",
+ "t_6_1744861190121": "未选择节点",
+ "t_7_1744861189625": "配置已保存",
+ "t_8_1744861189821": "开始运行流程",
+ "t_9_1744861189580": "选中节点:",
+ "t_0_1744870861464": "节点",
+ "t_1_1744870861944": "节点配置",
+ "t_2_1744870863419": "请选择左侧节点进行配置",
+ "t_3_1744870864615": "未找到该节点类型的配置组件",
+ "t_4_1744870861589": "取消",
+ "t_5_1744870862719": "确定",
+ "t_0_1744875938285": "每分钟",
+ "t_1_1744875938598": "每小时",
+ "t_2_1744875938555": "每天",
+ "t_3_1744875938310": "每月",
+ "t_4_1744875940750": "自动执行",
+ "t_5_1744875940010": "手动执行",
+ "t_0_1744879616135": "测试PID",
+ "t_1_1744879616555": "请输入测试PID",
+ "t_2_1744879616413": "执行周期",
+ "t_3_1744879615723": "分钟",
+ "t_4_1744879616168": "请输入分钟",
+ "t_5_1744879615277": "小时",
+ "t_6_1744879616944": "请输入小时",
+ "t_7_1744879615743": "日期",
+ "t_8_1744879616493": "请选择日期",
+ "t_0_1744942117992": "每周",
+ "t_1_1744942116527": "周一",
+ "t_2_1744942117890": "周二",
+ "t_3_1744942117885": "周三",
+ "t_4_1744942117738": "周四",
+ "t_5_1744942117167": "周五",
+ "t_6_1744942117815": "周六",
+ "t_7_1744942117862": "周日",
+ "t_0_1744958839535": "请输入域名",
+ "t_1_1744958840747": "请输入邮箱",
+ "t_2_1744958840131": "邮箱格式不正确",
+ "t_3_1744958840485": "请选择DNS提供商授权",
+ "t_4_1744958838951": "本地部署",
+ "t_5_1744958839222": "SSH部署",
+ "t_6_1744958843569": "宝塔面板/1面板(部署到面板证书)",
+ "t_7_1744958841708": "宝塔面板/1面板(部署到指定网站项目)",
+ "t_8_1744958841658": "腾讯云CDN/阿里云CDN",
+ "t_9_1744958840634": "腾讯云WAF",
+ "t_10_1744958860078": "阿里云WAF",
+ "t_11_1744958840439": "本次自动申请的证书",
+ "t_12_1744958840387": "可选证书列表",
+ "t_13_1744958840714": "PEM(*.pem,*.crt,*.key)",
+ "t_14_1744958839470": "PFX(*.pfx)",
+ "t_15_1744958840790": "JKS(*.jks)",
+ "t_16_1744958841116": "POSIX bash(Linux/MacOS)",
+ "t_17_1744958839597": "命令行(Windows)",
+ "t_18_1744958839895": "PowerShell(Windows)",
+ "t_19_1744958839297": "证书1",
+ "t_20_1744958839439": "证书2",
+ "t_21_1744958839305": "服务器1",
+ "t_22_1744958841926": "服务器2",
+ "t_23_1744958838717": "面板1",
+ "t_24_1744958845324": "面板2",
+ "t_25_1744958839236": "网站1",
+ "t_26_1744958839682": "网站2",
+ "t_27_1744958840234": "腾讯云1",
+ "t_28_1744958839760": "阿里云1",
+ "t_29_1744958838904": "日",
+ "t_30_1744958843864": "证书格式不正确,请检查是否包含完整的证书头尾标识",
+ "t_31_1744958844490": "私钥格式不正确,请检查是否包含完整的私钥头尾标识",
+ "t_0_1745215914686": "自动化名称",
+ "t_2_1745215915397": "自动",
+ "t_3_1745215914237": "手动",
+ "t_4_1745215914951": "启用状态",
+ "t_5_1745215914671": "启用",
+ "t_6_1745215914104": "停用",
+ "t_7_1745215914189": "创建时间",
+ "t_8_1745215914610": "操作",
+ "t_9_1745215914666": "执行历史",
+ "t_10_1745215914342": "执行",
+ "t_11_1745215915429": "编辑",
+ "t_12_1745215914312": "删除",
+ "t_13_1745215915455": "执行工作流",
+ "t_14_1745215916235": "工作流执行成功",
+ "t_15_1745215915743": "工作流执行失败",
+ "t_16_1745215915209": "删除工作流",
+ "t_17_1745215915985": "工作流删除成功",
+ "t_18_1745215915630": "工作流删除失败",
+ "t_0_1745227838699": "新增自动化部署",
+ "t_1_1745227838776": "请输入自动化名称",
+ "t_2_1745227839794": "确定要执行{name}工作流吗?",
+ "t_3_1745227841567": "确认要删除{name}工作流吗?此操作不可恢复。",
+ "t_4_1745227838558": "执行时间",
+ "t_5_1745227839906": "结束时间",
+ "t_6_1745227838798": "执行方式",
+ "t_7_1745227838093": "状态",
+ "t_8_1745227838023": "成功",
+ "t_9_1745227838305": "失败",
+ "t_10_1745227838234": "执行中",
+ "t_11_1745227838422": "未知",
+ "t_12_1745227838814": "详情",
+ "t_13_1745227838275": "上传证书",
+ "t_14_1745227840904": "请输入证书域名或品牌名称进行搜索",
+ "t_15_1745227839354": "共",
+ "t_16_1745227838930": "条",
+ "t_17_1745227838561": "域名",
+ "t_18_1745227838154": "品牌",
+ "t_19_1745227839107": "剩余天数",
+ "t_20_1745227838813": "到期时间",
+ "t_21_1745227837972": "来源",
+ "t_22_1745227838154": "自动申请",
+ "t_23_1745227838699": "手动上传",
+ "t_24_1745227839508": "添加时间",
+ "t_25_1745227838080": "下载",
+ "t_27_1745227838583": "即将过期",
+ "t_28_1745227837903": "正常",
+ "t_29_1745227838410": "删除证书",
+ "t_30_1745227841739": "确认要删除这个证书吗?此操作不可恢复。",
+ "t_31_1745227838461": "确认",
+ "t_32_1745227838439": "证书名称",
+ "t_33_1745227838984": "请输入证书名称",
+ "t_34_1745227839375": "证书内容(PEM)",
+ "t_35_1745227839208": "请输入证书内容",
+ "t_36_1745227838958": "私钥内容(KEY)",
+ "t_37_1745227839669": "请输入私钥内容",
+ "t_38_1745227838813": "下载失败",
+ "t_39_1745227838696": "上传失败",
+ "t_40_1745227838872": "删除失败",
+ "t_0_1745289355714": "添加授权API",
+ "t_1_1745289356586": "请输入授权API名称或类型",
+ "t_2_1745289353944": "名称",
+ "t_3_1745289354664": "授权API类型",
+ "t_4_1745289354902": "编辑授权API",
+ "t_5_1745289355718": "删除授权API",
+ "t_6_1745289358340": "确定删除该授权API吗?此操作不可恢复。",
+ "t_7_1745289355714": "添加失败",
+ "t_8_1745289354902": "更新失败",
+ "t_9_1745289355714": "已过期{days}天",
+ "t_10_1745289354650": "监控管理",
+ "t_11_1745289354516": "添加监控",
+ "t_12_1745289356974": "请输入监控名称或域名进行搜索",
+ "t_13_1745289354528": "监控名称",
+ "t_14_1745289354902": "证书域名",
+ "t_15_1745289355714": "证书颁发机构",
+ "t_16_1745289354902": "证书状态",
+ "t_17_1745289355715": "证书到期时间",
+ "t_18_1745289354598": "告警渠道",
+ "t_19_1745289354676": "上次检查时间",
+ "t_20_1745289354598": "编辑监控",
+ "t_21_1745289354598": "确认删除",
+ "t_22_1745289359036": "删除后将无法恢复,您确认要删除该监控吗?",
+ "t_23_1745289355716": "修改失败",
+ "t_24_1745289355715": "设置失败",
+ "t_25_1745289355721": "请输入验证码",
+ "t_26_1745289358341": "表单验证失败,请检查填写内容",
+ "t_27_1745289355721": "请输入授权API名称",
+ "t_28_1745289356040": "请选择授权API类型",
+ "t_29_1745289355850": "请输入服务器IP",
+ "t_30_1745289355718": "请输入SSH端口",
+ "t_31_1745289355715": "请输入SSH密钥",
+ "t_32_1745289356127": "请输入宝塔地址",
+ "t_33_1745289355721": "请输入API密钥",
+ "t_34_1745289356040": "请输入1panel地址",
+ "t_35_1745289355714": "请输入AccessKeyId",
+ "t_36_1745289355715": "请输入AccessKeySecret",
+ "t_37_1745289356041": "请输入SecretId",
+ "t_38_1745289356419": "请输入密钥",
+ "t_39_1745289354902": "更新成功",
+ "t_40_1745289355715": "添加成功",
+ "t_41_1745289354902": "类型",
+ "t_42_1745289355715": "服务器IP",
+ "t_43_1745289354598": "SSH端口",
+ "t_44_1745289354583": "用户名",
+ "t_45_1745289355714": "认证方式",
+ "t_46_1745289355723": "密码认证",
+ "t_47_1745289355715": "密钥认证",
+ "t_48_1745289355714": "密码",
+ "t_49_1745289355714": "SSH私钥",
+ "t_50_1745289355715": "请输入SSH私钥",
+ "t_51_1745289355714": "私钥密码",
+ "t_52_1745289359565": "如果私钥有密码,请输入",
+ "t_53_1745289356446": "宝塔面板地址",
+ "t_54_1745289358683": "请输入宝塔面板地址,例如:https://bt.example.com",
+ "t_55_1745289355715": "API密钥",
+ "t_56_1745289355714": "1面板地址",
+ "t_57_1745289358341": "请输入1panel地址,例如:https://1panel.example.com",
+ "t_58_1745289355721": "请输入AccessKey ID",
+ "t_59_1745289356803": "请输入访问密钥的秘密",
+ "t_60_1745289355715": "请输入监控名称",
+ "t_61_1745289355878": "请输入域名/IP",
+ "t_62_1745289360212": "请选择检查周期",
+ "t_63_1745289354897": "5分钟",
+ "t_64_1745289354670": "10分钟",
+ "t_65_1745289354591": "15分钟",
+ "t_66_1745289354655": "30分钟",
+ "t_67_1745289354487": "60分钟",
+ "t_68_1745289354676": "邮件",
+ "t_69_1745289355721": "短信",
+ "t_70_1745289354904": "微信",
+ "t_71_1745289354583": "域名/IP",
+ "t_72_1745289355715": "检查周期",
+ "t_73_1745289356103": "请选择告警渠道",
+ "t_0_1745289808449": "请输入授权API名称",
+ "t_0_1745294710530": "删除监控",
+ "t_0_1745295228865": "更新时间",
+ "t_0_1745317313835": "服务器IP地址格式错误",
+ "t_1_1745317313096": "端口格式错误",
+ "t_2_1745317314362": "面板URL地址格式错误",
+ "t_3_1745317313561": "请输入面板API密钥",
+ "t_4_1745317314054": "请输入阿里云AccessKeyId",
+ "t_5_1745317315285": "请输入阿里云AccessKeySecret",
+ "t_6_1745317313383": "请输入腾讯云SecretId",
+ "t_7_1745317313831": "请输入腾讯云SecretKey",
+ "t_0_1745457486299": "已启用",
+ "t_1_1745457484314": "已停止",
+ "t_2_1745457488661": "切换为手动模式",
+ "t_3_1745457486983": "切换为自动模式",
+ "t_4_1745457497303": "切换为手动模式后,工作流将不再自动执行,但仍可手动执行",
+ "t_5_1745457494695": "切换为自动模式后,工作流将按照配置的时间自动执行",
+ "t_6_1745457487560": "关闭当前工作流",
+ "t_7_1745457487185": "启用当前工作流",
+ "t_8_1745457496621": "关闭后,工作流将不再自动执行,手动也无法执行,是否继续?",
+ "t_9_1745457500045": "启用后,工作流配置自动执行,或手动执行,是否继续?",
+ "t_10_1745457486451": "添加工作流失败",
+ "t_11_1745457488256": "设置工作流运行方式失败",
+ "t_12_1745457489076": "启用或禁用工作流失败",
+ "t_13_1745457487555": "执行工作流失败",
+ "t_14_1745457488092": "删除工作流失败",
+ "t_15_1745457484292": "退出",
+ "t_16_1745457491607": "即将退出登录状态,确认退出吗?",
+ "t_17_1745457488251": "正在退出登录状态,请稍后...",
+ "t_18_1745457490931": "添加邮箱通知",
+ "t_19_1745457484684": "保存成功",
+ "t_20_1745457485905": "删除成功",
+ "t_0_1745464080226": "获取系统设置失败",
+ "t_1_1745464079590": "设置保存失败",
+ "t_2_1745464077081": "获取通知设置失败",
+ "t_3_1745464081058": "保存通知设置失败",
+ "t_4_1745464075382": "获取通知渠道列表失败",
+ "t_5_1745464086047": "添加邮箱通知渠道失败",
+ "t_6_1745464075714": "更新通知渠道失败",
+ "t_7_1745464073330": "删除通知渠道失败",
+ "t_8_1745464081472": "检查版本更新失败",
+ "t_9_1745464078110": "保存设置",
+ "t_10_1745464073098": "基础设置",
+ "t_0_1745474945127": "选择模板",
+ "t_0_1745490735213": "请输入工作流名称",
+ "t_1_1745490731990": "配置",
+ "t_2_1745490735558": "请输入邮箱格式",
+ "t_3_1745490735059": "请选择DNS提供商",
+ "t_4_1745490735630": "请输入续签间隔",
+ "t_5_1745490738285": "请输入域名,域名不能为空",
+ "t_6_1745490738548": "请输入邮箱,邮箱不能为空",
+ "t_7_1745490739917": "请选择DNS提供商,DNS提供商不能为空",
+ "t_8_1745490739319": "请输入续签间隔,续签间隔不能为空",
+ "t_0_1745553910661": "域名格式错误,请输入正确的域名",
+ "t_1_1745553909483": "邮箱格式错误,请输入正确的邮箱",
+ "t_2_1745553907423": "续签间隔不能为空",
+ "t_0_1745735774005": "请输入证书域名,多个域名用逗号分隔",
+ "t_1_1745735764953": "邮箱",
+ "t_2_1745735773668": "请输入邮箱,用于接收证书颁发机构的邮件通知",
+ "t_3_1745735765112": "DNS提供商",
+ "t_4_1745735765372": "添加",
+ "t_5_1745735769112": "续签间隔(天)",
+ "t_6_1745735765205": "续签间隔时间",
+ "t_7_1745735768326": "天,到期后自动续签",
+ "t_8_1745735765753": "已配置",
+ "t_9_1745735765287": "未配置",
+ "t_10_1745735765165": "宝塔面板",
+ "t_11_1745735766456": "宝塔面板网站",
+ "t_12_1745735765571": "1Panel面板",
+ "t_13_1745735766084": "1Panel网站",
+ "t_14_1745735766121": "腾讯云CDN",
+ "t_15_1745735768976": "腾讯云COS",
+ "t_16_1745735766712": "阿里云CDN",
+ "t_18_1745735765638": "部署类型",
+ "t_19_1745735766810": "请选择部署类型",
+ "t_20_1745735768764": "请输入部署路径",
+ "t_21_1745735769154": "请输入前置命令",
+ "t_22_1745735767366": "请输入后置命令",
+ "t_23_1745735766455": "请输入站点名称",
+ "t_24_1745735766826": "请输入站点ID",
+ "t_25_1745735766651": "请输入区域",
+ "t_26_1745735767144": "请输入存储桶",
+ "t_27_1745735764546": "下一步",
+ "t_28_1745735766626": "选择部署类型",
+ "t_29_1745735768933": "配置部署参数",
+ "t_30_1745735764748": "运行模式",
+ "t_31_1745735767891": "运行模式未配置",
+ "t_32_1745735767156": "运行周期未配置",
+ "t_33_1745735766532": "运行时间未配置",
+ "t_34_1745735771147": "证书文件(PEM 格式)",
+ "t_35_1745735781545": "请粘贴证书文件内容,例如:\n-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
+ "t_36_1745735769443": "私钥文件(KEY 格式)",
+ "t_37_1745735779980": "请粘贴私钥文件内容,例如:\n-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
+ "t_38_1745735769521": "证书私钥内容不能为空",
+ "t_39_1745735768565": "证书私钥格式不正确",
+ "t_40_1745735815317": "证书内容不能为空",
+ "t_41_1745735767016": "证书格式不正确",
+ "t_0_1745738961258": "上一步",
+ "t_1_1745738963744": "提交",
+ "t_2_1745738969878": "配置部署参数,类型决定参数配置",
+ "t_0_1745744491696": "部署设备来源",
+ "t_1_1745744495019": "请选择部署设备来源",
+ "t_2_1745744495813": "请选择部署类型后,点击下一步",
+ "t_0_1745744902975": "部署来源",
+ "t_1_1745744905566": "请选择部署来源",
+ "t_2_1745744903722": "添加更多设备",
+ "t_0_1745748292337": "添加部署来源",
+ "t_1_1745748290291": "证书来源",
+ "t_2_1745748298902": "当前类型部署来源为空,请先添加部署来源",
+ "t_3_1745748298161": "当前流程中没有申请节点,请先添加申请节点",
+ "t_4_1745748290292": "提交内容",
+ "t_0_1745765864788": "点击编辑工作流标题",
+ "t_1_1745765875247": "删除节点-【{name}】",
+ "t_2_1745765875918": "当前节点存在子节点,删除后会影响其他节点,是否确认删除?",
+ "t_3_1745765920953": "当前节点存在配置数据,是否确认删除?",
+ "t_4_1745765868807": "请选择部署类型后,再进行下一步",
+ "t_0_1745833934390": "请选择类型",
+ "t_1_1745833931535": "主机",
+ "t_2_1745833931404": "端口",
+ "t_3_1745833936770": "获取首页概览数据失败",
+ "t_4_1745833932780": "版本信息",
+ "t_5_1745833933241": "当前版本",
+ "t_6_1745833933523": "更新方式",
+ "t_7_1745833933278": "最新版本",
+ "t_8_1745833933552": "更新日志",
+ "t_9_1745833935269": "客服二维码",
+ "t_10_1745833941691": "扫码添加客服",
+ "t_11_1745833935261": "微信公众号",
+ "t_12_1745833943712": "扫码关注微信公众号",
+ "t_13_1745833933630": "关于产品",
+ "t_14_1745833932440": "SMTP服务器",
+ "t_15_1745833940280": "请输入SMTP服务器",
+ "t_16_1745833933819": "SMTP端口",
+ "t_17_1745833935070": "请输入SMTP端口",
+ "t_18_1745833933989": "SSL/TLS连接",
+ "t_0_1745887835267": "请选择消息通知",
+ "t_1_1745887832941": "消息通知",
+ "t_2_1745887834248": "添加通知渠道",
+ "t_3_1745887835089": "请输入通知主题",
+ "t_4_1745887835265": "请输入通知内容",
+ "t_0_1745895057404": "修改邮箱通知配置",
+ "t_0_1745920566646": "通知主题",
+ "t_1_1745920567200": "通知内容",
+ "t_0_1745936396853": "点击获取验证码",
+ "t_0_1745999035681": "剩余{days}天",
+ "t_1_1745999036289": "即将到期{days}天",
+ "t_0_1746000517848": "已过期",
+ "t_0_1746001199409": "已到期",
+ "t_0_1746004861782": "DNS提供商为空",
+ "t_1_1746004861166": "添加DNS提供商",
+ "t_0_1746497662220": "刷新",
+ "t_0_1746519384035": "运行中",
+ "t_0_1746579648713": "执行历史详情",
+ "t_0_1746590054456": "执行状态",
+ "t_1_1746590060448": "触发方式",
+ "t_0_1746667592819": "正在提交信息,请稍后...",
+ "t_1_1746667588689": "密钥",
+ "t_2_1746667592840": "面板URL",
+ "t_3_1746667592270": "忽略 SSL/TLS证书错误",
+ "t_4_1746667590873": "表单验证失败",
+ "t_5_1746667590676": "新建工作流",
+ "t_6_1746667592831": "正在提交申请,请稍后...",
+ "t_7_1746667592468": "请输入正确的域名",
+ "t_8_1746667591924": "请选择解析方式",
+ "t_9_1746667589516": "刷新列表",
+ "t_10_1746667589575": "通配符",
+ "t_11_1746667589598": "多域名",
+ "t_12_1746667589733": "热门",
+ "t_13_1746667599218": "是广泛使用的免费SSL证书提供商,适合个人网站和测试环境。",
+ "t_14_1746667590827": "支持域名数",
+ "t_15_1746667588493": "个",
+ "t_16_1746667591069": "支持通配符",
+ "t_17_1746667588785": "支持",
+ "t_18_1746667590113": "不支持",
+ "t_19_1746667589295": "有效期",
+ "t_20_1746667588453": "天",
+ "t_21_1746667590834": "支持小程序",
+ "t_22_1746667591024": "适用网站",
+ "t_23_1746667591989": "*.example.com、*.demo.com",
+ "t_24_1746667583520": "*.example.com",
+ "t_25_1746667590147": "example.com、demo.com",
+ "t_26_1746667594662": "www.example.com、example.com",
+ "t_27_1746667589350": "免费",
+ "t_28_1746667590336": "立即申请",
+ "t_29_1746667589773": "项目地址",
+ "t_30_1746667591892": "请输入证书文件路径",
+ "t_31_1746667593074": "请输入私钥文件路径",
+ "t_0_1746673515941": "当前DNS提供商为空,请先添加DNS提供商",
+ "t_0_1746676862189": "测试通知发送失败",
+ "t_1_1746676859550": "添加配置",
+ "t_2_1746676856700": "暂未支持",
+ "t_3_1746676857930": "邮件通知",
+ "t_4_1746676861473": "通过邮件发送告警通知",
+ "t_5_1746676856974": "钉钉通知",
+ "t_6_1746676860886": "通过钉钉机器人发送告警通知",
+ "t_7_1746676857191": "企业微信通知",
+ "t_8_1746676860457": "通过企业微信机器人发送告警通知",
+ "t_9_1746676857164": "飞书通知",
+ "t_10_1746676862329": "通过飞书机器人发送告警通知",
+ "t_11_1746676859158": "WebHook通知",
+ "t_12_1746676860503": "通过WebHook发送告警通知",
+ "t_13_1746676856842": "通知渠道",
+ "t_14_1746676859019": "已配置的通知渠道",
+ "t_15_1746676856567": "已停用",
+ "t_16_1746676855270": "测试",
+ "t_0_1746677882486": "最后一次执行状态",
+ "t_0_1746697487119": "域名不能为空",
+ "t_1_1746697485188": "邮箱不能为空",
+ "t_2_1746697487164": "阿里云OSS",
+ "t_0_1746754500246": "主机提供商",
+ "t_1_1746754499371": "API来源",
+ "t_2_1746754500270": "API 类型",
+ "t_0_1746760933542": "请求错误",
+ "t_0_1746773350551": "共{0}条",
+ "t_1_1746773348701": "未执行",
+ "t_2_1746773350970": "自动化工作流",
+ "t_3_1746773348798": "总数量",
+ "t_4_1746773348957": "执行失败",
+ "t_5_1746773349141": "即将到期",
+ "t_6_1746773349980": "实时监控",
+ "t_7_1746773349302": "异常数量",
+ "t_8_1746773351524": "最近工作流执行记录",
+ "t_9_1746773348221": "查看全部",
+ "t_10_1746773351576": "暂无工作流执行记录",
+ "t_11_1746773349054": "创建工作流",
+ "t_12_1746773355641": "点击创建自动化工作流程,提高效率",
+ "t_13_1746773349526": "申请证书",
+ "t_14_1746773355081": "点击申请和管理SSL证书,保障安全",
+ "t_15_1746773358151": "点击设置网站监控,实时掌握运行状态",
+ "t_16_1746773356568": "最多只能配置一个邮箱通知渠道",
+ "t_17_1746773351220": "确认{0}通知渠道",
+ "t_18_1746773355467": "{0}通知渠道,将开始发送告警通知。",
+ "t_19_1746773352558": "当前通知渠道不支持测试",
+ "t_20_1746773356060": "正在发送测试邮件,请稍后...",
+ "t_21_1746773350759": "测试邮件",
+ "t_22_1746773360711": "发送测试邮件到当前配置的邮箱,是否继续?",
+ "t_23_1746773350040": "删除确认",
+ "t_24_1746773349367": "确定要删除",
+ "t_25_1746773349596": "请输入名称",
+ "t_26_1746773353409": "请输入正确的SMTP端口",
+ "t_27_1746773352584": "请输入用户密码",
+ "t_28_1746773354048": "请输入正确的发送人邮箱",
+ "t_29_1746773351834": "请输入正确的接收邮箱",
+ "t_30_1746773350013": "发送人邮箱",
+ "t_31_1746773349857": "接收邮箱",
+ "t_32_1746773348993": "钉钉",
+ "t_33_1746773350932": "企业微信",
+ "t_34_1746773350153": "飞书",
+ "t_35_1746773362992": "一个集证书申请、管理、部署和监控于一体的SSL证书全生命周期管理工具。",
+ "t_36_1746773348989": "证书申请",
+ "t_37_1746773356895": "支持通过ACME协议从Let's Encrypt获取证书",
+ "t_38_1746773349796": "证书管理",
+ "t_39_1746773358932": "集中管理所有SSL证书,包括手动上传和自动申请的证书",
+ "t_40_1746773352188": "证书部署",
+ "t_41_1746773364475": "支持一键部署证书到多种平台,如阿里云、腾讯云、宝塔面板、1Panel等",
+ "t_42_1746773348768": "站点监控",
+ "t_43_1746773359511": "实时监控站点SSL证书状态,提前预警证书过期",
+ "t_44_1746773352805": "自动化任务:",
+ "t_45_1746773355717": "支持定时任务,自动续期证书并部署",
+ "t_46_1746773350579": "多平台支持",
+ "t_47_1746773360760": "支持多种DNS提供商(阿里云、腾讯云等)的DNS验证方式"
+}
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/locales/model/zhTW.json b/frontend/apps/allin-ssl/src/locales/model/zhTW.json
new file mode 100644
index 0000000..abf3c80
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/locales/model/zhTW.json
@@ -0,0 +1,489 @@
+{
+ "t_0_1746773763967": "確定要刪除{0},通知渠道嗎?",
+ "t_1_1746773763643": "Let's Encrypt等CA自動申請免費證書",
+ "t_0_1744098811152": "警告:您已進入未知區域,所訪問的頁面不存在,請點擊按鈕返回首頁。",
+ "t_1_1744098801860": "返回首頁",
+ "t_2_1744098804908": "安全提示:如果您認為這是個錯誤,請立即聯繫管理員",
+ "t_3_1744098802647": "展開主菜單",
+ "t_4_1744098802046": "折疊主菜單",
+ "t_0_1744164843238": "歡迎使用AllinSSL,高效管理SSL憑證",
+ "t_1_1744164835667": "AllinSSL",
+ "t_2_1744164839713": "帳號登錄",
+ "t_3_1744164839524": "請輸入用戶名",
+ "t_4_1744164840458": "請輸入密碼",
+ "t_5_1744164840468": "記住密碼",
+ "t_6_1744164838900": "忘記密碼",
+ "t_7_1744164838625": "登錄中",
+ "t_8_1744164839833": "登錄",
+ "t_0_1744168657526": "登出",
+ "t_0_1744258111441": "首頁",
+ "t_1_1744258113857": "自動部署",
+ "t_2_1744258111238": "證書管理",
+ "t_3_1744258111182": "證書申請",
+ "t_4_1744258111238": "授權API管理",
+ "t_5_1744258110516": "監控",
+ "t_6_1744258111153": "設定",
+ "t_0_1744861190562": "返回工作流程列表",
+ "t_1_1744861189113": "運行",
+ "t_2_1744861190040": "儲存",
+ "t_3_1744861190932": "請選擇一個節點進行配置",
+ "t_4_1744861194395": "點擊左側流程圖中的節點來配置它",
+ "t_5_1744861189528": "開始",
+ "t_6_1744861190121": "未選擇節點",
+ "t_7_1744861189625": "配置已保存",
+ "t_8_1744861189821": "開始執行流程",
+ "t_9_1744861189580": "選中節點:",
+ "t_0_1744870861464": "節點",
+ "t_1_1744870861944": "節點配置",
+ "t_2_1744870863419": "請選擇左側節點進行配置",
+ "t_3_1744870864615": "未找到該節點類型的配置組件",
+ "t_4_1744870861589": "取消",
+ "t_5_1744870862719": "確定",
+ "t_0_1744875938285": "每分鐘",
+ "t_1_1744875938598": "每小時",
+ "t_2_1744875938555": "每天",
+ "t_3_1744875938310": "每月",
+ "t_4_1744875940750": "自動執行",
+ "t_5_1744875940010": "手動執行",
+ "t_0_1744879616135": "測試PID",
+ "t_1_1744879616555": "請輸入測試PID",
+ "t_2_1744879616413": "執行周期",
+ "t_3_1744879615723": "分鐘",
+ "t_4_1744879616168": "請輸入分鐘",
+ "t_5_1744879615277": "小時",
+ "t_6_1744879616944": "請輸入小時",
+ "t_7_1744879615743": "日期",
+ "t_8_1744879616493": "請選擇日期",
+ "t_0_1744942117992": "每週",
+ "t_1_1744942116527": "星期一",
+ "t_2_1744942117890": "星期二",
+ "t_3_1744942117885": "星期三",
+ "t_4_1744942117738": "週四",
+ "t_5_1744942117167": "週五",
+ "t_6_1744942117815": "週六",
+ "t_7_1744942117862": "週日",
+ "t_0_1744958839535": "請輸入域名",
+ "t_1_1744958840747": "請輸入郵箱",
+ "t_2_1744958840131": "郵箱格式不正確",
+ "t_3_1744958840485": "請選擇DNS提供商授權",
+ "t_4_1744958838951": "本地部署",
+ "t_5_1744958839222": "SSH部署",
+ "t_6_1744958843569": "宝塔面板/1面板(部署至面板憑證)",
+ "t_7_1744958841708": "宝塔面板/1面板(部署至指定網站項目)",
+ "t_8_1744958841658": "腾讯雲CDN/阿里雲CDN",
+ "t_9_1744958840634": "腾讯雲WAF",
+ "t_10_1744958860078": "阿里雲WAF",
+ "t_11_1744958840439": "本次自動申請的證書",
+ "t_12_1744958840387": "可選證書清單",
+ "t_13_1744958840714": "PEM(*.pem,*.crt,*.key)",
+ "t_14_1744958839470": "PFX(*.pfx)",
+ "t_15_1744958840790": "JKS(*.jks)",
+ "t_16_1744958841116": "POSIX bash(Linux/macOS)",
+ "t_17_1744958839597": "命令行(Windows)",
+ "t_18_1744958839895": "PowerShell(Windows)",
+ "t_19_1744958839297": "證書1",
+ "t_20_1744958839439": "證書2",
+ "t_21_1744958839305": "伺服器1",
+ "t_22_1744958841926": "伺服器2",
+ "t_23_1744958838717": "面板1",
+ "t_24_1744958845324": "面板2",
+ "t_25_1744958839236": "網站1",
+ "t_26_1744958839682": "網站2",
+ "t_27_1744958840234": "腾讯雲1",
+ "t_28_1744958839760": "阿里雲1",
+ "t_29_1744958838904": "日",
+ "t_30_1744958843864": "證書格式不正確,請檢查是否包含完整的證書頭尾識別",
+ "t_31_1744958844490": "私钥格式不正確,請檢查是否包含完整的私钥頭尾識別",
+ "t_0_1745215914686": "自動化名稱",
+ "t_2_1745215915397": "自動",
+ "t_3_1745215914237": "手動",
+ "t_4_1745215914951": "啟用狀態",
+ "t_5_1745215914671": "啟用",
+ "t_6_1745215914104": "停用",
+ "t_7_1745215914189": "創建時間",
+ "t_8_1745215914610": "操作",
+ "t_9_1745215914666": "執行歷史",
+ "t_10_1745215914342": "執行",
+ "t_11_1745215915429": "編輯",
+ "t_12_1745215914312": "刪除",
+ "t_13_1745215915455": "執行工作流程",
+ "t_14_1745215916235": "工作流程執行成功",
+ "t_15_1745215915743": "工作流程執行失敗",
+ "t_16_1745215915209": "刪除工作流程",
+ "t_17_1745215915985": "工作流程刪除成功",
+ "t_18_1745215915630": "工作流程刪除失敗",
+ "t_0_1745227838699": "新增自動部署",
+ "t_1_1745227838776": "請輸入自動化名稱",
+ "t_2_1745227839794": "確定要執行{name}工作流程嗎?",
+ "t_3_1745227841567": "確認要刪除{name}工作流程嗎?此操作無法恢復。",
+ "t_4_1745227838558": "執行時間",
+ "t_5_1745227839906": "結束時間",
+ "t_6_1745227838798": "執行方式",
+ "t_7_1745227838093": "狀態",
+ "t_8_1745227838023": "成功",
+ "t_9_1745227838305": "失敗",
+ "t_10_1745227838234": "執行中",
+ "t_11_1745227838422": "未知",
+ "t_12_1745227838814": "詳細",
+ "t_13_1745227838275": "上傳證書",
+ "t_14_1745227840904": "請輸入證書域名或品牌名稱搜尋",
+ "t_15_1745227839354": "共",
+ "t_16_1745227838930": "條",
+ "t_17_1745227838561": "域名",
+ "t_18_1745227838154": "品牌",
+ "t_19_1745227839107": "剩餘天數",
+ "t_20_1745227838813": "到期時間",
+ "t_21_1745227837972": "來源",
+ "t_22_1745227838154": "自動申請",
+ "t_23_1745227838699": "手動上傳",
+ "t_24_1745227839508": "加入時間",
+ "t_25_1745227838080": "下載",
+ "t_27_1745227838583": "即將過期",
+ "t_28_1745227837903": "正常",
+ "t_29_1745227838410": "刪除證書",
+ "t_30_1745227841739": "確認要刪除這個證書嗎?此操作無法恢復。",
+ "t_31_1745227838461": "確認",
+ "t_32_1745227838439": "證書名稱",
+ "t_33_1745227838984": "請輸入證書名稱",
+ "t_34_1745227839375": "證書內容(PEM)",
+ "t_35_1745227839208": "請輸入證書內容",
+ "t_36_1745227838958": "私鑰內容(KEY)",
+ "t_37_1745227839669": "請輸入私鑰內容",
+ "t_38_1745227838813": "下載失敗",
+ "t_39_1745227838696": "上傳失敗",
+ "t_40_1745227838872": "刪除失敗",
+ "t_0_1745289355714": "添加授權API",
+ "t_1_1745289356586": "請輸入授權API名稱或類型",
+ "t_2_1745289353944": "名稱",
+ "t_3_1745289354664": "授權API類型",
+ "t_4_1745289354902": "編輯授權API",
+ "t_5_1745289355718": "刪除授權API",
+ "t_6_1745289358340": "確定刪除該授權API嗎?此操作無法恢復。",
+ "t_7_1745289355714": "添加失敗",
+ "t_8_1745289354902": "更新失敗",
+ "t_9_1745289355714": "已過期{days}天",
+ "t_10_1745289354650": "監控管理",
+ "t_11_1745289354516": "加入監控",
+ "t_12_1745289356974": "請輸入監控名稱或域名進行搜尋",
+ "t_13_1745289354528": "監控名稱",
+ "t_14_1745289354902": "證書域名",
+ "t_15_1745289355714": "證書發頒機構",
+ "t_16_1745289354902": "證書狀態",
+ "t_17_1745289355715": "證書到期時間",
+ "t_18_1745289354598": "告警管道",
+ "t_19_1745289354676": "上次檢查時間",
+ "t_20_1745289354598": "編輯監控",
+ "t_21_1745289354598": "確認刪除",
+ "t_22_1745289359036": "刪除後將無法恢復,您確定要刪除該監控嗎?",
+ "t_23_1745289355716": "修改失敗",
+ "t_24_1745289355715": "設定失敗",
+ "t_25_1745289355721": "請輸入驗證碼",
+ "t_26_1745289358341": "表單驗證失敗,請檢查填寫內容",
+ "t_27_1745289355721": "請輸入授權API名稱",
+ "t_28_1745289356040": "請選擇授權API類型",
+ "t_29_1745289355850": "請輸入伺服器IP",
+ "t_30_1745289355718": "請輸入SSH端口",
+ "t_31_1745289355715": "請輸入SSH金鑰",
+ "t_32_1745289356127": "請輸入寶塔地址",
+ "t_33_1745289355721": "請輸入API金鑰",
+ "t_34_1745289356040": "請輸入1panel地址",
+ "t_35_1745289355714": "請輸入AccessKeyId",
+ "t_36_1745289355715": "請輸入AccessKeySecret",
+ "t_37_1745289356041": "請輸入SecretId",
+ "t_38_1745289356419": "請輸入密鑰",
+ "t_39_1745289354902": "更新成功",
+ "t_40_1745289355715": "添加成功",
+ "t_41_1745289354902": "類型",
+ "t_42_1745289355715": "伺服器IP",
+ "t_43_1745289354598": "SSH端口",
+ "t_44_1745289354583": "用戶名",
+ "t_45_1745289355714": "認證方式",
+ "t_46_1745289355723": "密碼驗證",
+ "t_47_1745289355715": "密钥認證",
+ "t_48_1745289355714": "密碼",
+ "t_49_1745289355714": "SSH私鑰",
+ "t_50_1745289355715": "請輸入SSH私鑰",
+ "t_51_1745289355714": "私鍵密碼",
+ "t_52_1745289359565": "如果私钥有密碼,請輸入",
+ "t_53_1745289356446": "宝塔面板地址",
+ "t_54_1745289358683": "請輸入宝塔面板地址,例如:https://bt.example.com",
+ "t_55_1745289355715": "API金鑰",
+ "t_56_1745289355714": "1面板地址",
+ "t_57_1745289358341": "請輸入1panel地址,例如:https://1panel.example.com",
+ "t_58_1745289355721": "請輸入AccessKey ID",
+ "t_59_1745289356803": "請輸入AccessKey密碼",
+ "t_60_1745289355715": "請輸入監控名稱",
+ "t_61_1745289355878": "請輸入域名/IP",
+ "t_62_1745289360212": "請選擇檢查週期",
+ "t_63_1745289354897": "5分鐘",
+ "t_64_1745289354670": "10分鐘",
+ "t_65_1745289354591": "15分鐘",
+ "t_66_1745289354655": "30分鐘",
+ "t_67_1745289354487": "60分鐘",
+ "t_68_1745289354676": "郵件",
+ "t_69_1745289355721": "短信",
+ "t_70_1745289354904": "微信",
+ "t_71_1745289354583": "域名/IP",
+ "t_72_1745289355715": "檢查週期",
+ "t_73_1745289356103": "請選擇告警渠道",
+ "t_0_1745289808449": "請輸入授權API名稱",
+ "t_0_1745294710530": "刪除監控",
+ "t_0_1745295228865": "更新時間",
+ "t_0_1745317313835": "伺服器IP位址格式錯誤",
+ "t_1_1745317313096": "端口格式錯誤",
+ "t_2_1745317314362": "面板URL地址格式錯誤",
+ "t_3_1745317313561": "請輸入面板API金鑰",
+ "t_4_1745317314054": "請輸入阿里雲AccessKeyId",
+ "t_5_1745317315285": "請輸入阿里雲AccessKeySecret",
+ "t_6_1745317313383": "請輸入腾讯雲SecretId",
+ "t_7_1745317313831": "請輸入腾讯雲SecretKey",
+ "t_0_1745457486299": "已啟用",
+ "t_1_1745457484314": "已停止",
+ "t_2_1745457488661": "切換為手動模式",
+ "t_3_1745457486983": "切換為自動模式",
+ "t_4_1745457497303": "切換為手動模式後,工作流將不再自動執行,但仍可手動執行",
+ "t_5_1745457494695": "切換為自動模式後,工作流將按照配置的時間自動執行",
+ "t_6_1745457487560": "關閉當前工作流程",
+ "t_7_1745457487185": "啟用當前工作流程",
+ "t_8_1745457496621": "關閉後,工作流將不再自動執行,手動也無法執行,是否繼續?",
+ "t_9_1745457500045": "啟用後,工作流程配置自動執行,或手動執行,是否繼續?",
+ "t_10_1745457486451": "添加工作流程失敗",
+ "t_11_1745457488256": "設置工作流程運行方式失敗",
+ "t_12_1745457489076": "啟用或禁用工作流程失敗",
+ "t_13_1745457487555": "執行工作流程失敗",
+ "t_14_1745457488092": "刪除工作流失敗",
+ "t_15_1745457484292": "退出",
+ "t_16_1745457491607": "即將登出,確認要登出嗎?",
+ "t_17_1745457488251": "正在登出,請稍候...",
+ "t_18_1745457490931": "新增郵箱通知",
+ "t_19_1745457484684": "儲存成功",
+ "t_20_1745457485905": "刪除成功",
+ "t_0_1745464080226": "獲取系統設置失敗",
+ "t_1_1745464079590": "設定儲存失敗",
+ "t_2_1745464077081": "獲取通知設置失敗",
+ "t_3_1745464081058": "儲存通知設定失敗",
+ "t_4_1745464075382": "獲取通知渠道列表失敗",
+ "t_5_1745464086047": "添加郵箱通知渠道失敗",
+ "t_6_1745464075714": "更新通知渠道失敗",
+ "t_7_1745464073330": "刪除通知渠道失敗",
+ "t_8_1745464081472": "檢查版本更新失敗",
+ "t_9_1745464078110": "儲存設定",
+ "t_10_1745464073098": "基礎設定",
+ "t_0_1745474945127": "選擇範本",
+ "t_0_1745490735213": "請輸入工作流程名稱",
+ "t_1_1745490731990": "配置",
+ "t_2_1745490735558": "請輸入電郵格式",
+ "t_3_1745490735059": "請選擇DNS提供商",
+ "t_4_1745490735630": "請輸入續簽間隔",
+ "t_5_1745490738285": "請輸入域名,域名不能為空",
+ "t_6_1745490738548": "請輸入郵箱,郵箱不能為空",
+ "t_7_1745490739917": "請選擇DNS提供商,DNS提供商不能為空",
+ "t_8_1745490739319": "請輸入續簽間隔,續簽間隔不能為空",
+ "t_0_1745553910661": "域名格式錯誤,請輸入正確的域名",
+ "t_1_1745553909483": "郵箱格式錯誤,請輸入正確的郵箱",
+ "t_2_1745553907423": "續簽間隔不能為空",
+ "t_0_1745735774005": "請輸入證書域名,多個域名用逗號分隔",
+ "t_1_1745735764953": "信箱",
+ "t_2_1745735773668": "請輸入郵箱,用於接收證書頒發機構的郵件通知",
+ "t_3_1745735765112": "DNS提供商",
+ "t_4_1745735765372": "添加",
+ "t_5_1745735769112": "續簽間隔(天)",
+ "t_6_1745735765205": "續簽間隔時間",
+ "t_7_1745735768326": "天,到期後自動續簽",
+ "t_8_1745735765753": "已配置",
+ "t_9_1745735765287": "未配置",
+ "t_10_1745735765165": "寶塔面板",
+ "t_11_1745735766456": "寶塔面板網站",
+ "t_12_1745735765571": "1Panel面板",
+ "t_13_1745735766084": "1Panel網站",
+ "t_14_1745735766121": "騰訊雲CDN",
+ "t_15_1745735768976": "騰訊雲COS",
+ "t_16_1745735766712": "阿里雲CDN",
+ "t_18_1745735765638": "部署類型",
+ "t_19_1745735766810": "請選擇部署類型",
+ "t_20_1745735768764": "請輸入部署路徑",
+ "t_21_1745735769154": "請輸入前置命令",
+ "t_22_1745735767366": "請輸入後置命令",
+ "t_23_1745735766455": "請輸入站點名稱",
+ "t_24_1745735766826": "請輸入站點ID",
+ "t_25_1745735766651": "請輸入區域",
+ "t_26_1745735767144": "請輸入儲存桶",
+ "t_27_1745735764546": "下一步",
+ "t_28_1745735766626": "選擇部署類型",
+ "t_29_1745735768933": "配置部署參數",
+ "t_30_1745735764748": "運行模式",
+ "t_31_1745735767891": "運行模式未配置",
+ "t_32_1745735767156": "運行週期未配置",
+ "t_33_1745735766532": "運行時間未配置",
+ "t_34_1745735771147": "證書文件(PEM 格式)",
+ "t_35_1745735781545": "請貼上證書文件內容,例如:\n-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
+ "t_36_1745735769443": "私鑰文件(KEY 格式)",
+ "t_37_1745735779980": "請貼上私鑰文件內容,例如:\n-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
+ "t_38_1745735769521": "證書私鑰內容不能為空",
+ "t_39_1745735768565": "證書私鑰格式不正確",
+ "t_40_1745735815317": "證書內容不能為空",
+ "t_41_1745735767016": "證書格式不正確",
+ "t_0_1745738961258": "上一步",
+ "t_1_1745738963744": "提交",
+ "t_2_1745738969878": "配置部署參數,類型決定參數配置",
+ "t_0_1745744491696": "部署設備來源",
+ "t_1_1745744495019": "請選擇部署設備來源",
+ "t_2_1745744495813": "請選擇部署類型後,點擊下一步",
+ "t_0_1745744902975": "部署來源",
+ "t_1_1745744905566": "請選擇部署來源",
+ "t_2_1745744903722": "新增更多設備",
+ "t_0_1745748292337": "添加部署來源",
+ "t_1_1745748290291": "證書來源",
+ "t_2_1745748298902": "當前類型部署來源為空,請先添加部署來源",
+ "t_3_1745748298161": "當前流程中沒有申請節點,請先添加申請節點",
+ "t_4_1745748290292": "提交內容",
+ "t_0_1745765864788": "點擊編輯工作流程標題",
+ "t_1_1745765875247": "刪除節點-【{name}】",
+ "t_2_1745765875918": "當前節點存在子節點,刪除後會影響其他節點,是否確認刪除?",
+ "t_3_1745765920953": "目前節點存在配置數據,是否確認刪除?",
+ "t_4_1745765868807": "請選擇部署類型後,再進行下一步",
+ "t_0_1745833934390": "請選擇類型",
+ "t_1_1745833931535": "主機",
+ "t_2_1745833931404": "埠",
+ "t_3_1745833936770": "獲取首頁概覽數據失敗",
+ "t_4_1745833932780": "版本資訊",
+ "t_5_1745833933241": "目前版本",
+ "t_6_1745833933523": "更新方式",
+ "t_7_1745833933278": "最新版本",
+ "t_8_1745833933552": "更新日誌",
+ "t_9_1745833935269": "客服二維碼",
+ "t_10_1745833941691": "掃碼添加客服",
+ "t_11_1745833935261": "微信公眾號",
+ "t_12_1745833943712": "掃碼關注微信公眾號",
+ "t_13_1745833933630": "關於產品",
+ "t_14_1745833932440": "SMTP伺服器",
+ "t_15_1745833940280": "請輸入SMTP伺服器",
+ "t_16_1745833933819": "SMTP埠",
+ "t_17_1745833935070": "請輸入SMTP端口",
+ "t_18_1745833933989": "SSL/TLS連接",
+ "t_1_1745887832941": "訊息通知",
+ "t_2_1745887834248": "新增通知渠道",
+ "t_3_1745887835089": "請輸入通知主題",
+ "t_4_1745887835265": "請輸入通知內容",
+ "t_0_1745895057404": "修改郵箱通知配置",
+ "t_0_1745920566646": "通知主題",
+ "t_1_1745920567200": "通知內容",
+ "t_0_1745936396853": "點擊獲取驗證碼",
+ "t_0_1745999035681": "剩餘{days}天",
+ "t_1_1745999036289": "即將到期{days}天",
+ "t_0_1746000517848": "已過期",
+ "t_0_1746001199409": "已到期",
+ "t_0_1746004861782": "DNS提供商為空",
+ "t_1_1746004861166": "新增DNS供應商",
+ "t_0_1746497662220": "刷新",
+ "t_0_1746519384035": "運行中",
+ "t_0_1746579648713": "執行歷史詳情",
+ "t_0_1746590054456": "執行狀態",
+ "t_1_1746590060448": "觸發方式",
+ "t_0_1746667592819": "正在提交資訊,請稍後...",
+ "t_1_1746667588689": "密鑰",
+ "t_2_1746667592840": "面板URL",
+ "t_3_1746667592270": "忽略 SSL/TLS證書錯誤",
+ "t_4_1746667590873": "表單驗證失敗",
+ "t_5_1746667590676": "新增工作流程",
+ "t_6_1746667592831": "正在提交申請,請稍後...",
+ "t_7_1746667592468": "請輸入正確的域名",
+ "t_8_1746667591924": "請選擇解析方式",
+ "t_9_1746667589516": "刷新列表",
+ "t_10_1746667589575": "通配符",
+ "t_11_1746667589598": "多域名",
+ "t_12_1746667589733": "熱門",
+ "t_13_1746667599218": "是廣泛使用的免費SSL證書提供商,適合個人網站和測試環境。",
+ "t_14_1746667590827": "支持域名數",
+ "t_15_1746667588493": "個",
+ "t_16_1746667591069": "支援萬用字元",
+ "t_17_1746667588785": "支持",
+ "t_18_1746667590113": "不支援",
+ "t_19_1746667589295": "有效期",
+ "t_20_1746667588453": "天",
+ "t_21_1746667590834": "支援小程式",
+ "t_22_1746667591024": "適用網站",
+ "t_23_1746667591989": "*.example.com、*.demo.com",
+ "t_24_1746667583520": "*.example.com",
+ "t_25_1746667590147": "example.com、demo.com",
+ "t_26_1746667594662": "www.example.com、example.com",
+ "t_27_1746667589350": "免費",
+ "t_28_1746667590336": "立即申請",
+ "t_29_1746667589773": "專案地址",
+ "t_30_1746667591892": "請輸入憑證檔案路徑",
+ "t_31_1746667593074": "請輸入私鑰文件路徑",
+ "t_0_1746673515941": "當前DNS提供商為空,請先添加DNS提供商",
+ "t_0_1746676862189": "測試通知發送失敗",
+ "t_1_1746676859550": "新增配置",
+ "t_2_1746676856700": "暫不支持",
+ "t_3_1746676857930": "郵件通知",
+ "t_4_1746676861473": "透過郵件發送警報通知",
+ "t_5_1746676856974": "釘釘通知",
+ "t_6_1746676860886": "通過釘釘機器人發送警報通知",
+ "t_7_1746676857191": "企業微信通知",
+ "t_8_1746676860457": "通過企業微信機器人發送警報通知",
+ "t_9_1746676857164": "飛書通知",
+ "t_10_1746676862329": "通過飛書機器人發送告警通知",
+ "t_11_1746676859158": "WebHook通知",
+ "t_12_1746676860503": "通過WebHook發送警報通知",
+ "t_13_1746676856842": "通知渠道",
+ "t_14_1746676859019": "已配置的通知頻道",
+ "t_15_1746676856567": "已停用",
+ "t_16_1746676855270": "測試",
+ "t_0_1746677882486": "最後一次執行狀態",
+ "t_0_1746697487119": "域名不能為空",
+ "t_1_1746697485188": "郵箱不能為空",
+ "t_2_1746697487164": "阿里雲OSS",
+ "t_0_1746754500246": "主機供應商",
+ "t_1_1746754499371": "API來源",
+ "t_2_1746754500270": "API 類型",
+ "t_0_1746760933542": "請求錯誤",
+ "t_0_1746773350551": "共{0}條",
+ "t_1_1746773348701": "未執行",
+ "t_2_1746773350970": "自動化工作流程",
+ "t_3_1746773348798": "總數量",
+ "t_4_1746773348957": "執行失敗",
+ "t_5_1746773349141": "即將到期",
+ "t_6_1746773349980": "即時監控",
+ "t_7_1746773349302": "異常數量",
+ "t_8_1746773351524": "最近工作流程執行紀錄",
+ "t_9_1746773348221": "查看全部",
+ "t_10_1746773351576": "暫無工作流執行記錄",
+ "t_11_1746773349054": "建立工作流程",
+ "t_12_1746773355641": "點擊創建自動化工作流程,提高效率",
+ "t_13_1746773349526": "申請證書",
+ "t_14_1746773355081": "點擊申請和管理SSL證書,保障安全",
+ "t_15_1746773358151": "點擊設置網站監控,即時掌握運行狀態",
+ "t_16_1746773356568": "最多只能配置一個郵箱通知渠道",
+ "t_17_1746773351220": "確認{0}通知渠道",
+ "t_18_1746773355467": "{0}通知渠道,將開始發送告警通知。",
+ "t_19_1746773352558": "當前通知渠道不支援測試",
+ "t_20_1746773356060": "正在發送測試郵件,請稍後...",
+ "t_21_1746773350759": "測試郵件",
+ "t_22_1746773360711": "發送測試郵件到當前配置的郵箱,是否繼續?",
+ "t_23_1746773350040": "刪除確認",
+ "t_24_1746773349367": "確定要刪除",
+ "t_25_1746773349596": "請輸入名稱",
+ "t_26_1746773353409": "請輸入正確的SMTP端口",
+ "t_27_1746773352584": "請輸入使用者密碼",
+ "t_28_1746773354048": "請輸入正確的發件人郵箱",
+ "t_29_1746773351834": "請輸入正確的接收信箱",
+ "t_30_1746773350013": "寄件人信箱",
+ "t_31_1746773349857": "接收郵箱",
+ "t_32_1746773348993": "釘釘",
+ "t_33_1746773350932": "企業微信",
+ "t_34_1746773350153": "飛書",
+ "t_35_1746773362992": "一個集證書申請、管理、部署和監控於一體的SSL證書全生命週期管理工具。",
+ "t_36_1746773348989": "證書申請",
+ "t_37_1746773356895": "支援通過ACME協議從Let's Encrypt獲取證書",
+ "t_38_1746773349796": "證書管理",
+ "t_39_1746773358932": "集中管理所有SSL證書,包括手動上傳和自動申請的證書",
+ "t_40_1746773352188": "證書部署",
+ "t_41_1746773364475": "支援一鍵部署證書到多種平台,如阿里雲、騰訊雲、寶塔面板、1Panel等",
+ "t_42_1746773348768": "站點監控",
+ "t_43_1746773359511": "實時監控站點SSL證書狀態,提前預警證書過期",
+ "t_44_1746773352805": "自動化任務:",
+ "t_45_1746773355717": "支援定時任務,自動續期證書並部署",
+ "t_46_1746773350579": "多平台支援",
+ "t_47_1746773360760": "支援多種DNS提供商(阿里雲、騰訊雲等)的DNS驗證方式"
+}
\ No newline at end of file
diff --git a/frontend/apps/allin-ssl/src/main.ts b/frontend/apps/allin-ssl/src/main.ts
new file mode 100644
index 0000000..4968c9f
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/main.ts
@@ -0,0 +1,24 @@
+import { pinia } from '@baota/pinia'
+import { router } from '@router/index'
+import { i18n } from '@locales/index'
+import { useModalUseDiscrete } from '@baota/naive-ui/hooks'
+import App from './App' // 根组件
+
+import 'virtual:svg-icons-register'
+import 'normalize.css' // 样式修复一致性
+import '@styles/reset.css' // 重置样式
+import '@styles/variable.css' // 全局变量
+import '@styles/transition.css' // 过渡动画
+import '@styles/icon.css' // css 图标
+
+// 引入mock
+// import '../mock/access'
+
+const app = createApp(App)
+app.use(router) // 路由
+app.use(pinia) // 使用状态管理
+app.use(i18n) // 国际化
+app.mount('#app') // 挂载到DOM
+
+// 设置资源
+useModalUseDiscrete({ i18n, router, pinia })
diff --git a/frontend/apps/allin-ssl/src/router/each.tsx b/frontend/apps/allin-ssl/src/router/each.tsx
new file mode 100644
index 0000000..d9e7087
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/router/each.tsx
@@ -0,0 +1,31 @@
+import { createDiscreteApi } from 'naive-ui'
+
+import type { Router, RouteLocationNormalized, NavigationGuardNext } from '@baota/router/each'
+import { useCreateRouterEach } from '@baota/router/each' // 全局路由守卫
+
+// 创建离散API
+const { loadingBar } = createDiscreteApi(['loadingBar'])
+
+/**
+ * @description 全局路由守卫
+ * @param {Router} router 路由实例
+ * @return {void}
+ */
+const useRouterEach = (router: Router) =>
+ useCreateRouterEach(router, {
+ beforeEach: (to: RouteLocationNormalized, _: RouteLocationNormalized, next: NavigationGuardNext) => {
+ // 开始加载
+ loadingBar.start()
+ // 判断当前路由是否存在,如果不存在,则跳转到 404
+ if (!router.hasRoute(to.name as string)) {
+ if (!to.path.includes('/404')) return next({ path: '/404' })
+ }
+ next()
+ },
+ afterEach: (to: RouteLocationNormalized) => {
+ loadingBar.finish()
+ console.log('afterEach', to)
+ },
+ })
+
+export default useRouterEach
diff --git a/frontend/apps/allin-ssl/src/router/import.tsx b/frontend/apps/allin-ssl/src/router/import.tsx
new file mode 100644
index 0000000..f6b3b36
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/router/import.tsx
@@ -0,0 +1,17 @@
+import { getBuildRoutes } from '@baota/router/import'
+import routeConfig from '@config/route'
+
+/**
+ * @description 创建路由,动态获取路由配置
+ * @returns {RouteRecordRaw[]} 路由配置
+ */
+export const createRoutes = () => {
+ const modules = import.meta.glob('../views/*/index.tsx')
+ const childrenModules = import.meta.glob(`../views/*/children/*/index.tsx`)
+ return getBuildRoutes(modules, childrenModules, {
+ framework: routeConfig.frameworkRoute,
+ system: routeConfig.systemRoute,
+ sort: routeConfig.sortRoute,
+ disabled: routeConfig.disabledRoute,
+ })
+}
diff --git a/frontend/apps/allin-ssl/src/router/index.tsx b/frontend/apps/allin-ssl/src/router/index.tsx
new file mode 100644
index 0000000..3776f04
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/router/index.tsx
@@ -0,0 +1,17 @@
+import { createWebHistory, useCreateRouter } from '@baota/router' // 框架路由
+import { createRoutes } from './import' // 自动导入路由配置
+import useRouterEach from './each' // 全局路由守卫
+
+// 获取路由
+const { routeGroup, routes } = createRoutes() // 获取路由配置
+
+// 创建路由
+const router = useCreateRouter({
+ routes: routeGroup,
+ history: createWebHistory(),
+})
+
+// 全局路由守卫
+useRouterEach(router)
+
+export { router, routes }
diff --git a/frontend/apps/allin-ssl/src/styles/icon.css b/frontend/apps/allin-ssl/src/styles/icon.css
new file mode 100644
index 0000000..c013522
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/styles/icon.css
@@ -0,0 +1,97 @@
+.lucide--user-round {
+ display: inline-block;
+ width: 24px;
+ height: 24px;
+ --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Ccircle cx='12' cy='8' r='5'/%3E%3Cpath d='M20 21a8 8 0 0 0-16 0'/%3E%3C/g%3E%3C/svg%3E");
+ background-color: currentColor;
+ -webkit-mask-image: var(--svg);
+ mask-image: var(--svg);
+ -webkit-mask-repeat: no-repeat;
+ mask-repeat: no-repeat;
+ -webkit-mask-size: 100% 100%;
+ mask-size: 100% 100%;
+}
+
+.mynaui--lock-open-password {
+ display: inline-block;
+ width: 24px;
+ height: 24px;
+ --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M8 10V8c0-2.761 1.239-5 4-5c2.094 0 3.313 1.288 3.78 3.114M3.5 17.8v-4.6c0-1.12 0-1.68.218-2.107a2 2 0 0 1 .874-.875c.428-.217.988-.217 2.108-.217h10.6c1.12 0 1.68 0 2.108.217a2 2 0 0 1 .874.874c.218.428.218.988.218 2.108v4.6c0 1.12 0 1.68-.218 2.108a2 2 0 0 1-.874.874C18.98 21 18.42 21 17.3 21H6.7c-1.12 0-1.68 0-2.108-.218a2 2 0 0 1-.874-.874C3.5 19.481 3.5 18.921 3.5 17.8m8.5-2.05v-.5m4 .5v-.5m-8 .5v-.5'/%3E%3C/svg%3E");
+ background-color: currentColor;
+ -webkit-mask-image: var(--svg);
+ mask-image: var(--svg);
+ -webkit-mask-repeat: no-repeat;
+ mask-repeat: no-repeat;
+ -webkit-mask-size: 100% 100%;
+ mask-size: 100% 100%;
+}
+
+.solar--server-broken {
+ display: inline-block;
+ width: 24px;
+ height: 24px;
+ --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='%23000' stroke-linecap='round' stroke-width='1.5' d='M13 21H6c-1.886 0-2.828 0-3.414-.586S2 18.886 2 17s0-2.828.586-3.414S4.114 13 6 13h12c1.886 0 2.828 0 3.414.586S22 15.114 22 17s0 2.828-.586 3.414S19.886 21 18 21h-1M11 2h7c1.886 0 2.828 0 3.414.586S22 4.114 22 6s0 2.828-.586 3.414S19.886 10 18 10H6c-1.886 0-2.828 0-3.414-.586S2 7.886 2 6s0-2.828.586-3.414S4.114 2 6 2h1m4 4h7M6 6h2m3 11h7M6 17h2'/%3E%3C/svg%3E");
+ background-color: currentColor;
+ -webkit-mask-image: var(--svg);
+ mask-image: var(--svg);
+ -webkit-mask-repeat: no-repeat;
+ mask-repeat: no-repeat;
+ -webkit-mask-size: 100% 100%;
+ mask-size: 100% 100%;
+}
+
+.icon-park-outline--alarm {
+ display: inline-block;
+ width: 48px;
+ height: 48px;
+ --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48'%3E%3Cg fill='none' stroke='%23000' stroke-linejoin='round' stroke-width='4'%3E%3Cpath d='M14 25c0-5.523 4.477-10 10-10s10 4.477 10 10v16H14z'/%3E%3Cpath stroke-linecap='round' d='M24 5v3m11.892 1.328l-1.929 2.298m8.256 8.661l-2.955.521m-33.483-.521l2.955.521m3.373-11.48l1.928 2.298M6 41h37'/%3E%3C/g%3E%3C/svg%3E");
+ background-color: currentColor;
+ -webkit-mask-image: var(--svg);
+ mask-image: var(--svg);
+ -webkit-mask-repeat: no-repeat;
+ mask-repeat: no-repeat;
+ -webkit-mask-size: 100% 100%;
+ mask-size: 100% 100%;
+}
+
+.bitcoin-icons--exit-filled {
+ display: inline-block;
+ width: 24px;
+ height: 24px;
+ --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='%23000' fill-rule='evenodd' clip-rule='evenodd'%3E%3Cpath d='M15.99 7.823a.75.75 0 0 1 1.061.021l3.49 3.637a.75.75 0 0 1 0 1.038l-3.49 3.637a.75.75 0 0 1-1.082-1.039l2.271-2.367h-6.967a.75.75 0 0 1 0-1.5h6.968l-2.272-2.367a.75.75 0 0 1 .022-1.06'/%3E%3Cpath d='M3.25 4A.75.75 0 0 1 4 3.25h9.455a.75.75 0 0 1 .75.75v3a.75.75 0 1 1-1.5 0V4.75H4.75v14.5h7.954V17a.75.75 0 0 1 1.5 0v3a.75.75 0 0 1-.75.75H4a.75.75 0 0 1-.75-.75z'/%3E%3C/g%3E%3C/svg%3E");
+ background-color: currentColor;
+ -webkit-mask-image: var(--svg);
+ mask-image: var(--svg);
+ -webkit-mask-repeat: no-repeat;
+ mask-repeat: no-repeat;
+ -webkit-mask-size: 100% 100%;
+ mask-size: 100% 100%;
+}
+
+.lucide--settings {
+ display: inline-block;
+ width: 24px;
+ height: 24px;
+ --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Cpath d='M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2'/%3E%3Ccircle cx='12' cy='12' r='3'/%3E%3C/g%3E%3C/svg%3E");
+ background-color: currentColor;
+ -webkit-mask-image: var(--svg);
+ mask-image: var(--svg);
+ -webkit-mask-repeat: no-repeat;
+ mask-repeat: no-repeat;
+ -webkit-mask-size: 100% 100%;
+ mask-size: 100% 100%;
+}
+
+.pajamas--log {
+ display: inline-block;
+ width: 16px;
+ height: 16px;
+ --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23000' fill-rule='evenodd' d='M3.5 2.5v11h9v-11zM3 1a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1zm5 10a.75.75 0 0 1 .75-.75h1.75a.75.75 0 0 1 0 1.5H8.75A.75.75 0 0 1 8 11m-2 1a1 1 0 1 0 0-2a1 1 0 0 0 0 2m2-4a.75.75 0 0 1 .75-.75h1.75a.75.75 0 0 1 0 1.5H8.75A.75.75 0 0 1 8 8M6 9a1 1 0 1 0 0-2a1 1 0 0 0 0 2m2-4a.75.75 0 0 1 .75-.75h1.75a.75.75 0 0 1 0 1.5H8.75A.75.75 0 0 1 8 5M6 6a1 1 0 1 0 0-2a1 1 0 0 0 0 2' clip-rule='evenodd'/%3E%3C/svg%3E");
+ background-color: currentColor;
+ -webkit-mask-image: var(--svg);
+ mask-image: var(--svg);
+ -webkit-mask-repeat: no-repeat;
+ mask-repeat: no-repeat;
+ -webkit-mask-size: 100% 100%;
+ mask-size: 100% 100%;
+}
diff --git a/frontend/apps/allin-ssl/src/styles/naive-override.css b/frontend/apps/allin-ssl/src/styles/naive-override.css
new file mode 100644
index 0000000..06e88d0
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/styles/naive-override.css
@@ -0,0 +1,23 @@
+.n-tabs .n-tabs-nav {
+ background-color: var(--bt-card-bg-color) !important;
+ border-radius: 0.8rem;
+}
+.n-tabs .n-tabs-nav .n-tabs-tab-pad {
+ display: none;
+}
+.n-tabs .n-tabs-nav .n-tabs-tab-wrapper {
+ border-radius: 0.8rem 0.8rem 0.8rem 0.8rem;
+}
+.n-tabs .n-tabs-tab {
+ padding: 0 2.2rem;
+ height: 5.2rem;
+}
+.n-tabs .n-tabs-tab.n-tabs-tab--active {
+ background-color: var(--bt-card-bg-color-active) !important;
+}
+.n-tabs .n-tabs-tab:first-child {
+ border-radius: 0.8rem 0 0 0.8rem;
+}
+.n-tabs .n-tabs-tab:last-child {
+ border-radius: 0 0.8rem 0.8rem 0;
+}
diff --git a/frontend/apps/allin-ssl/src/styles/reset.css b/frontend/apps/allin-ssl/src/styles/reset.css
new file mode 100644
index 0000000..669dbb2
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/styles/reset.css
@@ -0,0 +1,72 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+html,
+body,
+#app {
+ @apply relative m-0 w-full h-full min-h-full text-[62.5%];
+}
+
+/* 视图全局配置 */
+.n-config-provider,
+.n-layout {
+ @apply h-full;
+}
+/* end */
+
+/* 图片预处理 */
+img {
+ /* 图片预处理 */
+ image-rendering: -o-crisp-edges; /* Opera */
+ image-rendering: -moz-crisp-edges; /* Firefox */
+ image-rendering: -webkit-optimize-contrast; /*Webkit (non-standard naming) */
+ image-rendering: crisp-edges;
+ -ms-interpolation-mode: nearest-neighbor; /* IE (non-standard property) */
+}
+/* end */
+
+/** 滚动条覆盖 */
+[data-scroll-top='true']::after,
+[data-scroll-bottom='true']::before {
+ @apply content-[''] absolute w-full h-[.6rem] z-[100];
+}
+[data-scroll-top='true']::after {
+ background-image: -webkit-linear-gradient(top, rgba(220, 220, 220, 0.2), rgba(255, 255, 255, 0));
+ top: 0;
+}
+[data-scroll-bottom='true']::before {
+ background-image: -webkit-linear-gradient(top, rgba(255, 255, 255, 0), rgba(220, 220, 220, 0.2));
+ bottom: 0;
+}
+/* end */
+
+/** 自定义Tab样式 */
+.n-tabs-nav--segment {
+ background-color: transparent;
+ padding: 0;
+}
+
+.n-tabs-tab.n-tabs-tab--active {
+ background-color: #fff;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+ font-weight: 600;
+ width: 100%;
+}
+
+.n-tabs-tab {
+ padding: 8px 16px;
+ transition: all 0.3s ease;
+ width: 100%;
+ height: 45px;
+ font-size: 18px;
+ text-align: center;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.n-tabs-tab-wrapper{
+ flex: 1 !important;
+}
+/* end */
diff --git a/frontend/apps/allin-ssl/src/styles/transition.css b/frontend/apps/allin-ssl/src/styles/transition.css
new file mode 100644
index 0000000..fd8196e
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/styles/transition.css
@@ -0,0 +1,91 @@
+.fade-enter-active,
+.fade-leave-active {
+ transition: opacity 0.3s ease;
+}
+
+.fade-enter-from,
+.fade-leave-to {
+ opacity: 0;
+}
+
+/* 从右侧滑入 */
+.slide-right-enter-active,
+.slide-right-leave-active {
+ transition: all 0.3s ease-out;
+}
+
+.slide-right-enter-from {
+ opacity: 0;
+ transform: translateX(-20px);
+}
+
+.slide-right-leave-to {
+ opacity: 0;
+ transform: translateX(20px);
+}
+
+/* 从左侧滑入 */
+.slide-left-enter-active,
+.slide-left-leave-active {
+ transition: all 0.3s ease-out;
+}
+
+.slide-left-enter-from {
+ opacity: 0;
+ transform: translateX(20px);
+}
+
+.slide-left-leave-to {
+ opacity: 0;
+ transform: translateX(-20px);
+}
+
+/* 从底部滑入 */
+.slide-up-enter-active,
+.slide-up-leave-active {
+ transition: all 0.3s ease-out;
+}
+
+.slide-up-enter-from {
+ opacity: 0;
+ transform: translateY(20px);
+}
+
+.slide-up-leave-to {
+ opacity: 0;
+ transform: translateY(-20px);
+}
+
+/* 缩放过渡 */
+.scale-enter-active,
+.scale-leave-active {
+ transition: all 0.3s ease;
+}
+
+.scale-enter-from,
+.scale-leave-to {
+ opacity: 0;
+ transform: scale(0.9);
+}
+
+/* 从左到右的渐显动画 */
+
+.route-slide-enter-active,
+.route-slide-leave-active {
+ transition:
+ opacity 0.35s ease-out,
+ transform 0.5s ease;
+}
+
+.route-slide-enter-from {
+ opacity: 0;
+ transform: translateX(-40px);
+}
+
+.route-slide-leave-to {
+ opacity: 0;
+ transition:
+ opacity 0.2s ease-in,
+ transform 0.35s ease-in;
+ transform: translateX(40px);
+}
diff --git a/frontend/apps/allin-ssl/src/styles/variable.css b/frontend/apps/allin-ssl/src/styles/variable.css
new file mode 100644
index 0000000..cfc8f6a
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/styles/variable.css
@@ -0,0 +1,10 @@
+:root {
+ --n-sider-width: 22rem; /* 侧边栏宽度,已经弃用,naive sider props width 替代 */
+ --n-sider-login-height: var(--n-header-height); /* 侧边栏登录栏高度 */
+ --n-header-height: 5rem; /* 顶部栏高度 */
+ --n-footer-height: 4rem; /* 底部栏高度 */
+ --n-main-diff-height: calc(var(--n-header-height)); /* 顶部栏和底部栏高度之和 */
+ --n-content-margin: 1.2rem; /* 内容区内边距 */
+ --n-content-padding: 1.2rem; /* 内容区内边距 */
+ --n-dialog-title-padding: 0; /* 对话框标题内边距 */
+}
diff --git a/frontend/apps/allin-ssl/src/types/access.d.ts b/frontend/apps/allin-ssl/src/types/access.d.ts
new file mode 100644
index 0000000..0c1d03f
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/types/access.d.ts
@@ -0,0 +1,110 @@
+import { AxiosResponseData } from './public'
+
+/** 授权列表请求参数 */
+export interface AccessListParams {
+ search?: string
+ p?: number
+ limit?: number
+}
+
+/** 授权项 */
+export interface AccessItem {
+ id: string
+ name: string
+ type: string
+ access_type: ('dns' | 'host')[]
+ create_time: string
+ update_time: string
+ config: string
+}
+
+/** 授权列表响应 */
+export interface AccessListResponse extends AxiosResponseData {
+ data: AccessItem[]
+}
+
+/** 授权类型 */
+export interface AccessType {
+ key: string
+ name: string
+}
+
+/** 授权类型列表响应 */
+export interface AccessTypesResponse extends AxiosResponseData {
+ data: AccessType[]
+}
+
+/** 新增授权请求参数 */
+export interface AddAccessParams<
+ T = SshAccessConfig | AliyunAccessConfig | TencentCloudAccessConfig | PanelAccessConfig,
+> {
+ name: string
+ type: string
+ config: T
+}
+
+/** 修改授权请求参数 */
+export interface UpdateAccessParams<
+ T = SshAccessConfig | AliyunAccessConfig | TencentCloudAccessConfig | PanelAccessConfig,
+> {
+ id: string
+ type: string
+ name: string
+ config: T
+}
+
+/**
+ * ssh 授权配置
+ */
+type SshAccessConfig = {
+ host: string
+ port: number
+ user: string
+} & ({ mode: 'password'; password: string; key?: never } | { mode: 'key'; key: string; password?: never })
+
+/**
+ * 阿里云授权配置
+ */
+export interface AliyunAccessConfig {
+ access_key_id: string
+ access_key_secret: string
+}
+
+/**
+ * 腾讯云授权配置
+ */
+export interface TencentCloudAccessConfig {
+ secret_id: string
+ secret_key: string
+}
+
+/**
+ * 面板授权(1panel、宝塔)
+ */
+export interface PanelAccessConfig {
+ url: string
+ api_key: string
+ ignore_ssl: '0' | '1'
+}
+
+/** 删除授权请求参数 */
+export interface DeleteAccessParams {
+ id: string
+}
+
+/** 获取DNS提供商列表请求参数 */
+export interface GetAccessAllListParams {
+ type: string
+}
+
+/** 工作流 dns 配置项 */
+export interface AccessAllItem {
+ id: number
+ name: string
+ type: string
+}
+
+/** 获取工作流 dns 配置响应 */
+export interface GetAccessAllListResponse extends AxiosResponseData {
+ data: AccessAllItem[]
+}
diff --git a/frontend/apps/allin-ssl/src/types/cert.d.ts b/frontend/apps/allin-ssl/src/types/cert.d.ts
new file mode 100644
index 0000000..1d2f978
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/types/cert.d.ts
@@ -0,0 +1,74 @@
+import { AxiosResponseData } from './public'
+
+/** 证书列表请求参数 */
+export interface CertListParams {
+ p?: number
+ limit?: number
+ search?: string
+}
+
+/** 证书项 */
+export interface CertItem {
+ id: string
+ name: string
+ domains: string
+ issuer: string
+ create_time: string
+ expire_time: string
+ status: number
+ source: 'upload' | 'apply'
+ end_day: string
+}
+
+/** 证书列表响应 */
+export interface CertListResponse extends AxiosResponseData {
+ data: CertItem[]
+}
+
+/** 申请证书请求参数 */
+export interface ApplyCertParams {
+ name: string
+ domain: string
+ access_id: string
+}
+
+/** 申请证书响应 */
+export interface ApplyCertResponse extends AxiosResponseData {
+ data: {
+ id: string
+ }
+}
+
+/** 上传证书请求参数 */
+export interface UploadCertParams {
+ // name: string
+ cert: string
+ key: string
+}
+
+/** 上传证书响应 */
+export interface UploadCertResponse extends AxiosResponseData {
+ data: {
+ id: string
+ }
+}
+
+/** 删除证书请求参数 */
+export interface DeleteCertParams {
+ id: string
+}
+
+/** 删除证书响应 */
+export interface DeleteCertResponse extends AxiosResponseData {
+ data: null
+}
+
+/** 下载证书请求参数 */
+export interface DownloadCertParams {
+ id: string
+}
+
+/** 下载证书响应 */
+export interface DownloadCertResponse extends AxiosResponseData {
+ data: string
+}
diff --git a/frontend/apps/allin-ssl/src/types/form.ts b/frontend/apps/allin-ssl/src/types/form.ts
new file mode 100644
index 0000000..7b15220
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/types/form.ts
@@ -0,0 +1,5 @@
+export interface FormItem {
+ name: string
+ type: string
+ description?: string
+}
diff --git a/frontend/apps/allin-ssl/src/types/login.d.ts b/frontend/apps/allin-ssl/src/types/login.d.ts
new file mode 100644
index 0000000..0749330
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/types/login.d.ts
@@ -0,0 +1,42 @@
+/**
+ * 登录响应数据接口
+ */
+export interface LoginResponse {
+ /** JWT token */
+ message: string
+ code: number
+ status: boolean
+ /** 用户信息 */
+ data: null
+}
+
+/**
+ * 用户信息接口
+ */
+export interface UserInfo {
+ username: string
+}
+
+/**
+ * 登录参数接口
+ */
+export interface LoginParams {
+ /** 用户名 */
+ username: string
+ /** 密码 */
+ password: string
+}
+
+/**
+ * 登录状态接口
+ */
+export interface LoginState {
+ loading: boolean
+ error: string | null
+ user: UserInfo | null
+ token: string | null
+ username: string
+ password: string
+ rememberMe: boolean
+ forgotPasswordRef: HTMLAnchorElement | null
+}
diff --git a/frontend/apps/allin-ssl/src/types/monitor.d.ts b/frontend/apps/allin-ssl/src/types/monitor.d.ts
new file mode 100644
index 0000000..321e43a
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/types/monitor.d.ts
@@ -0,0 +1,55 @@
+import { AxiosResponseData } from './public'
+
+/** 站点监控列表请求参数 */
+export interface SiteMonitorListParams {
+ p?: number
+ limit?: number
+ search?: string
+}
+
+/** 站点监控项 */
+export interface SiteMonitorItem {
+ active: number
+ ca: string
+ cert_domain: string
+ create_time: string
+ cycle: number
+ end_day: string
+ end_time: string
+ except_end_time: string
+ id: number
+ last_time: string
+ name: string
+ report_type: string
+ site_domain: string
+ state: string
+ update_time: string
+}
+
+/** 站点监控列表响应 */
+export interface SiteMonitorListResponse extends AxiosResponseData {
+ data: SiteMonitorItem[]
+}
+
+/** 新增站点监控请求参数 */
+export interface AddSiteMonitorParams {
+ name: string
+ domain: string
+ cycle: number
+ report_type: string
+}
+
+/** 修改站点监控请求参数 */
+export interface UpdateSiteMonitorParams extends AddSiteMonitorParams {
+ id: number
+}
+/** 删除站点监控请求参数 */
+export interface DeleteSiteMonitorParams {
+ id: number
+}
+
+/** 启用/禁用站点监控请求参数 */
+export interface SetSiteMonitorParams {
+ id: number
+ active: number
+}
diff --git a/frontend/apps/allin-ssl/src/types/public.d.ts b/frontend/apps/allin-ssl/src/types/public.d.ts
new file mode 100644
index 0000000..0159766
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/types/public.d.ts
@@ -0,0 +1,78 @@
+/**
+ * 返回数据
+ */
+export interface AxiosResponseData {
+ code: number
+ count: number
+ data: T
+ message: string
+ status: boolean
+}
+
+/** 登录参数 */
+export interface loginParams {
+ /** 用户名 */
+ username: string
+ /** 密码 */
+ password: string
+ /** 验证码 */
+ code?: string
+}
+
+/** 登录响应 */
+export interface loginResponse extends AxiosResponseData {
+ data: null
+}
+
+/** 首页概览请求参数 */
+export interface GetOverviewsParams {
+ // 没有参数
+}
+
+/** 工作流概览数据 */
+export interface WorkflowOverview {
+ count: number
+ active: number
+ failure: number
+}
+
+/** 证书概览数据 */
+export interface CertOverview {
+ count: number
+ will: number
+ end: number
+}
+
+/** 站点监控概览数据 */
+export interface SiteMonitorOverview {
+ count: number
+ exception: number
+}
+
+/** 工作流历史记录项 */
+export interface WorkflowHistoryItem {
+ name: string
+ state: number
+ mode: string
+ exec_time: string
+}
+
+/** 首页概览响应数据 */
+export interface OverviewData {
+ workflow: WorkflowOverview
+ cert: CertOverview
+ site_monitor: SiteMonitorOverview
+ workflow_history: WorkflowHistoryItem[]
+}
+
+/** 首页概览响应 */
+export interface GetOverviewsResponse extends AxiosResponseData {
+ data: OverviewData
+}
+
+/** 登录验证码响应 */
+export interface loginCodeResponse {
+ data: string
+}
+
+
diff --git a/frontend/apps/allin-ssl/src/types/setting.d.ts b/frontend/apps/allin-ssl/src/types/setting.d.ts
new file mode 100644
index 0000000..bfb5388
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/types/setting.d.ts
@@ -0,0 +1,108 @@
+import { AxiosResponseData } from './public'
+
+/** 获取设置请求参数 */
+export interface GetSettingParams {
+ // 无参数
+}
+
+/** 系统设置 */
+export interface SystemSetting {
+ timeout: number // 超时时间
+ secure: string // 协议
+ https: 0 | 1 // 是否开启https
+ key: string // 证书密钥
+ cert: string // 证书
+ username: string // 用户
+ password: string // 密码
+}
+
+/** 获取设置响应 */
+export interface GetSettingResponse extends AxiosResponseData {
+ data: SystemSetting
+}
+
+/** 保存设置请求参数 */
+export interface SaveSettingParams extends SystemSetting {
+ // 无参数
+}
+
+/** 获取告警类型请求参数 */
+export interface GetReportListParams {
+ search: string
+ p: number
+ limit: number
+}
+
+/** 获取告警类型响应 */
+export interface ReportType {
+ config: T
+ create_time: string
+ id: number
+ name: string
+ type: string
+ update_time: string
+}
+
+/** 获取告警类型响应 */
+export interface GetReportListResponse extends AxiosResponseData {
+ data: ReportType[]
+}
+
+export interface ReportMail {
+ name?: string
+ enabled: string
+ password: string
+ receiver: string
+ sender: string
+ smtpHost: string
+ smtpPort: string
+ smtpTLS: 'true' | 'false'
+ // username: string
+}
+
+/** 添加告警请求参数 */
+export interface AddReportParams {
+ name: string
+ type: string
+ config: T
+}
+
+/** 系统更新请求参数 */
+export interface UpdateReportParams extends AddReportParams {
+ id: number
+}
+
+/** 系统更新请求参数 */
+export interface DeleteReportParams {
+ id: number
+}
+
+/** 测试告警请求参数 */
+export interface TestReportParams {
+ id: number
+}
+
+/** 消息通知选项 */
+export interface NotifyProviderOption {
+ label: string
+ value: string
+ type: string
+}
+
+/** DNS提供商选项 */
+export interface DnsProviderOption {
+ label: string
+ value: string
+ type: string
+}
+
+/** 通知渠道 */
+export interface Channel {
+ id: string
+ type: string
+ name: string
+ sender?: string
+ host?: string
+ port?: number
+ receiver?: string
+}
diff --git a/frontend/apps/allin-ssl/src/types/workflow.d.ts b/frontend/apps/allin-ssl/src/types/workflow.d.ts
new file mode 100644
index 0000000..fa2b9b2
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/types/workflow.d.ts
@@ -0,0 +1,114 @@
+import { AxiosResponseData } from './public'
+
+/** 工作流列表请求参数 */
+export interface WorkflowListParams {
+ search?: string
+ p?: number
+ limit?: number
+}
+
+/** 工作流项 */
+export interface WorkflowItem {
+ id: string // 工作流ID
+ name: string // 工作流名称
+ active: string // 是否启用
+ content: string // 工作流脚本
+ exec_type: 'manual' | 'auto' // 执行类型
+ exec_time: string // 执行时间配置
+ last_run_status: 'success' | 'failed' | 'running' // 最后执行状态
+ cron: string // 执行时间
+ update_time: string // 更新时间
+ create_time: string | null // 创建时间
+}
+
+/** 工作流列表响应 */
+export interface WorkflowListResponse extends AxiosResponseData {
+ data: WorkflowItem[]
+}
+
+/** 添加工作流请求参数 */
+export interface AddWorkflowParams {
+ name: string
+ exec_type: 'manual' | 'auto' | '' // 执行类型
+ active: string // 是否启用
+ // exec_time: string // 执行时间 (请求前保持 json 结构)
+ content: string // 工作流脚本 (请求前保持 json 结构)
+}
+
+// /** 添加工作流响应 */
+// export interface AddWorkflowResponse extends AxiosResponseData {
+// data: null
+// }
+
+/** 修改工作流请求参数 */
+export interface UpdateWorkflowParams extends AddWorkflowParams {
+ id: string
+}
+
+/** 修改工作流响应 */
+// export interface UpdateWorkflowResponse extends AxiosResponseData {
+// data: {
+// id: string
+// }
+// }
+
+/** 删除工作流请求参数 */
+export interface DeleteWorkflowParams {
+ id: string
+}
+
+/** 删除工作流响应 */
+export interface DeleteWorkflowResponse extends AxiosResponseData {
+ data: null
+}
+
+/** 工作流执行历史请求参数 */
+export interface WorkflowHistoryParams {
+ id: string
+ p?: number
+ limit?: number
+}
+
+/** 工作流执行历史详情请求参数 */
+export interface WorkflowHistoryDetailParams {
+ id: string
+}
+
+
+/** 工作流历史执行记录 */
+export interface WorkflowHistoryItem {
+ id: string
+ create_time: number
+ end_time: string
+ exec_type: 'auto' | 'manual'
+ status: 'success' | 'failed' | 'pending'
+ workflow_id: string
+}
+
+/** 工作流执行历史响应 */
+export interface WorkflowHistoryResponse extends AxiosResponseData {
+ data: WorkflowHistoryItem[]
+}
+
+/** 手动执行工作流请求参数 */
+export interface ExecuteWorkflowParams {
+ id: string
+}
+
+/** 手动执行工作流响应 */
+// export interface ExecuteWorkflowResponse extends AxiosResponseData {
+// data: null
+// }
+
+/** 修改工作流执行方式请求参数 */
+export interface UpdateWorkflowExecTypeParams {
+ id: string
+ exec_type: 'manual' | 'auto'
+}
+
+/** 启用工作流或禁用工作流请求参数 */
+export interface EnableWorkflowParams {
+ id: string
+ active: string
+}
+
diff --git a/frontend/apps/allin-ssl/src/views/404/index.tsx b/frontend/apps/allin-ssl/src/views/404/index.tsx
new file mode 100644
index 0000000..ad72e37
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/views/404/index.tsx
@@ -0,0 +1,67 @@
+import { useRouter, type Router } from 'vue-router'
+import { NButton } from 'naive-ui'
+import { useThemeCssVar } from '@baota/naive-ui/theme'
+import { $t } from '@locales/index' // 引入 $t
+
+// import LocalesTips from '@baota/naive-ui/components/localesTips'
+// import ThemeTips from '@baota/naive-ui/components/themeTips'
+
+// 错误图标
+const errorIcon = (size: number = 16, color: string = 'var(--n-warning-color)') => {
+ return (
+
+ )
+}
+
+export default defineComponent({
+ setup() {
+ // 路由实例
+ const router: Router = useRouter()
+
+ // 获取主题变量
+ const cssVar = useThemeCssVar([
+ 'cardColor',
+ 'warningColor',
+ 'textColorSecondary',
+ 'textColorDisabled',
+ 'textColorInverse',
+ 'warningColorHover',
+ ])
+
+ return () => (
+
+ {/*
+
+
+
*/}
+
+
+ 404
+
+
{errorIcon(60)}
+
+ {$t('t_0_1744098811152')}
+
+
router.push('/')}>
+ {$t('t_1_1744098801860')}
+
+
+ {$t('t_2_1744098804908')}
+
+
+
+ )
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/views/authApiManage/components/apiManageForm.tsx b/frontend/apps/allin-ssl/src/views/authApiManage/components/apiManageForm.tsx
new file mode 100644
index 0000000..6c64d94
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/views/authApiManage/components/apiManageForm.tsx
@@ -0,0 +1,20 @@
+import { useApiFormController } from '../useController'
+import type { AccessItem } from '@/types/access'
+
+export default defineComponent({
+ name: 'AddApiForm',
+ props: {
+ data: {
+ type: Object as PropType,
+ default: () => {},
+ },
+ },
+ setup(props) {
+ const { ApiManageForm } = useApiFormController(props)
+ return () => (
+
+ )
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/views/authApiManage/index.tsx b/frontend/apps/allin-ssl/src/views/authApiManage/index.tsx
new file mode 100644
index 0000000..30361a0
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/views/authApiManage/index.tsx
@@ -0,0 +1,74 @@
+import { NInput, NButton } from 'naive-ui'
+import { PlusOutlined } from '@vicons/antd'
+import { Search } from '@vicons/carbon'
+import { $t } from '@locales/index'
+import { useThemeCssVar } from '@baota/naive-ui/theme'
+import { useController } from './useController'
+
+import BaseComponent from '@components/baseComponent'
+
+/**
+ * 授权API管理页面组件
+ */
+export default defineComponent({
+ name: 'AuthApiManage',
+ setup() {
+ const { ApiTable, ApiTablePage, param, fetch, data, openAddForm } = useController()
+ const cssVar = useThemeCssVar(['contentPadding', 'borderColor', 'headerHeight', 'iconColorHover'])
+
+ return () => (
+
+
+
(
+
+
+ {$t('t_0_1745289355714')}
+
+ ),
+ headerRight: () => (
+ {
+ if (e.key === 'Enter') fetch()
+ }}
+ onClear={() => useTimeoutFn(() => fetch(), 100)}
+ placeholder={$t('t_0_1745289808449')}
+ clearable
+ size="large"
+ class="min-w-[300px]"
+ v-slots={{
+ suffix: () => (
+
+
+
+ ),
+ }}
+ >
+ ),
+ content: () => (
+
+ ),
+ footerRight: () => (
+
+
(
+
+ {$t('t_15_1745227839354')} {data.value.total} {$t('t_16_1745227838930')}
+
+ ),
+ }}
+ />
+
+ ),
+ }}
+ >
+
+
+ )
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/views/authApiManage/useController.tsx b/frontend/apps/allin-ssl/src/views/authApiManage/useController.tsx
new file mode 100644
index 0000000..b86c92f
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/views/authApiManage/useController.tsx
@@ -0,0 +1,518 @@
+import {
+ FormInst,
+ FormItemRule,
+ FormRules,
+ NButton,
+ NFlex,
+ NFormItem,
+ NFormItemGi,
+ NGrid,
+ NInput,
+ NSelect,
+ NSpace,
+ NTag,
+ NText,
+ type DataTableColumns,
+} from 'naive-ui'
+import {
+ useModal,
+ useDialog,
+ useTable,
+ useTablePage,
+ useModalHooks,
+ useFormHooks,
+ useForm,
+ useLoadingMask,
+} from '@baota/naive-ui/hooks'
+import { useError } from '@baota/hooks/error'
+import { isIp, isPort, isUrl } from '@baota/utils/business'
+import { $t } from '@locales/index'
+import { useStore } from './useStore'
+
+import type { AccessItem, AccessListParams, AddAccessParams, SshAccessConfig, UpdateAccessParams } from '@/types/access'
+import type { FormConfig } from '@baota/naive-ui/types/form'
+
+import ApiManageForm from './components/apiManageForm'
+import SvgIcon from '@components/svgIcon'
+import TypeIcon from '@components/typeIcon'
+
+// 状态和方法
+const { accessTypes, apiFormProps, fetchAccessList, deleteExistingAccess, addNewAccess, updateExistingAccess } =
+ useStore()
+// 消息和对话框
+const { handleError } = useError()
+
+/**
+ * @description 授权API管理业务逻辑控制器
+ * @returns {Object} 返回授权API相关的状态数据和处理方法
+ */
+export const useController = () => {
+ // 表格列配置
+ const accessTypeMap = {
+ dns: $t('t_3_1745735765112'),
+ host: $t('t_0_1746754500246'),
+ }
+
+ /**
+ * @description 创建表格列配置
+ * @returns {DataTableColumns} 返回表格列配置数组
+ */
+ const createColumns = (): DataTableColumns => [
+ {
+ title: $t('t_2_1745289353944'),
+ key: 'name',
+ width: 200,
+ ellipsis: {
+ tooltip: true,
+ },
+ },
+ {
+ title: $t('t_1_1746754499371'),
+ key: 'type',
+ width: 180,
+ render: (row) => ,
+ },
+ {
+ title: $t('t_2_1746754500270'),
+ key: 'type',
+ width: 180,
+ render: (row) => (
+
+ {row.access_type.map((type) => {
+ return (
+
+ {accessTypeMap[type]}
+
+ )
+ })}
+
+ ),
+ },
+ {
+ title: $t('t_7_1745215914189'),
+ key: 'create_time',
+ width: 180,
+ },
+ {
+ title: $t('t_0_1745295228865'),
+ key: 'update_time',
+ width: 180,
+ },
+ {
+ title: $t('t_8_1745215914610'),
+ key: 'actions',
+ width: 180,
+ align: 'right',
+ fixed: 'right',
+ render: (row) => {
+ return (
+
+ openEditForm(row)}>
+ {$t('t_11_1745215915429')}
+
+ confirmDelete(row.id)}>
+ {$t('t_12_1745215914312')}
+
+
+ )
+ },
+ },
+ ]
+
+ // 表格实例
+ const {
+ component: ApiTable,
+ loading,
+ param,
+ data,
+ total,
+ fetch,
+ } = useTable({
+ config: createColumns(),
+ request: fetchAccessList,
+ defaultValue: {
+ p: 1,
+ limit: 10,
+ search: '',
+ },
+ watchValue: ['p', 'limit'],
+ })
+
+ // 分页实例
+ const { component: ApiTablePage } = useTablePage({
+ param,
+ total,
+ alias: {
+ page: 'p',
+ pageSize: 'limit',
+ },
+ })
+
+ /**
+ * @description 打开添加授权API弹窗
+ */
+ const openAddForm = () => {
+ useModal({
+ title: $t('t_0_1745289355714'),
+ area: 500,
+ component: ApiManageForm,
+ footer: true,
+ onUpdateShow: (show) => {
+ if (!show) fetch()
+ },
+ })
+ }
+
+ /**
+ * @description 打开编辑授权API弹窗
+ * @param {AccessItem} row - 授权API信息
+ */
+ const openEditForm = (row: AccessItem) => {
+ useModal({
+ title: $t('t_4_1745289354902'),
+ area: 500,
+ component: ApiManageForm,
+ componentProps: { data: row },
+ footer: true,
+ onUpdateShow: (show) => {
+ if (!show) fetch()
+ },
+ })
+ }
+
+ /**
+ * @description 确认删除授权API
+ * @param {number} id - 授权API ID
+ */
+ const confirmDelete = (id: string) => {
+ useDialog({
+ title: $t('t_5_1745289355718'),
+ content: $t('t_6_1745289358340'),
+ confirmText: $t('t_5_1744870862719'),
+ cancelText: $t('t_4_1744870861589'),
+ onPositiveClick: async () => {
+ await deleteExistingAccess(id)
+ await fetch()
+ },
+ })
+ }
+
+ // 挂载时,获取数据
+ onMounted(fetch)
+
+ return {
+ loading,
+ fetch,
+ ApiTable,
+ ApiTablePage,
+ param,
+ data,
+ accessTypes,
+ openAddForm,
+ }
+}
+
+/**
+ * @description 授权API表单控制器
+ * @returns {object} 返回controller对象
+ */
+export const useApiFormController = (props: { data: AccessItem }) => {
+ const { confirm } = useModalHooks() // 弹窗挂载方法
+ const { open: openLoad, close: closeLoad } = useLoadingMask({ text: $t('t_0_1746667592819') })
+ const { useFormInput, useFormRadioButton, useFormSwitch, useFormTextarea, useFormCustom } = useFormHooks()
+ const param = (props.data?.id ? ref({ ...props.data, config: JSON.parse(props.data.config) }) : apiFormProps) as Ref<
+ AddAccessParams | UpdateAccessParams
+ >
+ // 表单规则
+ const rules = {
+ name: {
+ required: true,
+ message: $t('t_27_1745289355721'),
+ trigger: 'input',
+ },
+ type: {
+ required: true,
+ message: $t('t_28_1745289356040'),
+ trigger: 'change',
+ },
+ config: {
+ host: {
+ required: true,
+ trigger: 'input',
+ validator: (rule: FormItemRule, value: string, callback: (error?: Error) => void) => {
+ if (!isIp(value)) {
+ return callback(new Error($t('t_0_1745317313835')))
+ }
+ callback()
+ },
+ },
+ port: {
+ required: true,
+ trigger: 'input',
+ validator: (rule: FormItemRule, value: number, callback: (error?: Error) => void) => {
+ if (!isPort(value.toString())) {
+ return callback(new Error($t('t_1_1745317313096')))
+ }
+ callback()
+ },
+ },
+ user: {
+ required: true,
+ trigger: 'input',
+ message: $t('t_3_1744164839524'),
+ },
+ password: {
+ required: true,
+ message: $t('t_4_1744164840458'),
+ trigger: 'input',
+ },
+ key: {
+ required: true,
+ message: $t('t_31_1745289355715'),
+ trigger: 'input',
+ },
+ url: {
+ required: true,
+ trigger: 'input',
+ validator: (rule: FormItemRule, value: string, callback: (error?: Error) => void) => {
+ if (!isUrl(value)) {
+ return callback(new Error($t('t_2_1745317314362')))
+ }
+ callback()
+ },
+ },
+ api_key: {
+ required: true,
+ message: $t('t_3_1745317313561'),
+ trigger: 'input',
+ },
+ access_key_id: {
+ required: true,
+ message: $t('t_4_1745317314054'),
+ trigger: 'input',
+ },
+ access_key_secret: {
+ required: true,
+ message: $t('t_5_1745317315285'),
+ trigger: 'input',
+ },
+ secret_id: {
+ required: true,
+ message: $t('t_6_1745317313383'),
+ trigger: 'input',
+ },
+ secret_key: {
+ required: true,
+ message: $t('t_7_1745317313831'),
+ trigger: 'input',
+ },
+ },
+ }
+
+ // 类型列表
+ const typeList = Object.entries(accessTypes.value).map(([key, value]) => ({ label: value, value: key }))
+
+ // 表单配置
+ const config = computed(() => {
+ const items: FormConfig = [
+ useFormInput($t('t_2_1745289353944'), 'name'),
+ useFormCustom(() => {
+ return (
+
+ {
+ return {$t('t_0_1745833934390')}
+ },
+ }}
+ />
+
+ )
+ }),
+ ]
+ switch (param.value.type) {
+ case 'ssh':
+ items.push(
+ useFormCustom(() => {
+ return (
+
+
+
+
+
+
+
+
+ )
+ }),
+ useFormInput($t('t_44_1745289354583'), 'config.user'),
+ useFormRadioButton($t('t_45_1745289355714'), 'config.mode', [
+ { label: $t('t_48_1745289355714'), value: 'password' },
+ { label: $t('t_1_1746667588689'), value: 'key' },
+ ]),
+ (param.value.config as SshAccessConfig)?.mode === 'password'
+ ? useFormInput($t('t_48_1745289355714'), 'config.password')
+ : useFormTextarea($t('t_1_1746667588689'), 'config.key', {
+ rows: 3,
+ placeholder: $t('t_3_1745317313561'),
+ }),
+ )
+ break
+ case '1panel':
+ case 'btpanel':
+ items.push(
+ useFormInput($t('t_2_1746667592840'), 'config.url'),
+ useFormInput($t('t_55_1745289355715'), 'config.api_key'),
+ useFormSwitch(
+ $t('t_3_1746667592270'),
+ 'config.ignore_ssl',
+ {
+ checkedValue: '1',
+ uncheckedValue: '0',
+ },
+ {
+ showRequireMark: false,
+ },
+ ),
+ )
+ break
+
+ case 'aliyun':
+ items.push(
+ useFormInput('AccessKeyId', 'config.access_key'),
+ useFormInput('AccessKeySecret', 'config.access_secret'),
+ )
+ break
+ case 'tencentcloud':
+ items.push(useFormInput('SecretId', 'config.secret_id'), useFormInput('SecretKey', 'config.secret_key'))
+ break
+ default:
+ break
+ }
+ return items
+ })
+
+ // 切换类型时,重置表单
+ watch(
+ () => param.value.type,
+ (newVal) => {
+ switch (newVal) {
+ case 'ssh':
+ param.value.config = {
+ host: '',
+ port: 22,
+ user: 'root',
+ mode: 'password',
+ password: '',
+ }
+ break
+ case '1panel':
+ case 'btpanel':
+ param.value.config = {
+ url: '',
+ api_key: '',
+ ignore_ssl: '0',
+ }
+ break
+ case 'aliyun':
+ param.value.config = {
+ access_key_id: '',
+ access_key_secret: '',
+ }
+ break
+ case 'tencentcloud':
+ param.value.config = {
+ secret_id: '',
+ secret_key: '',
+ }
+ break
+ }
+ },
+ )
+
+ /**
+ * @description 渲染单选标签
+ * @param {Record} option - 选项
+ * @returns {VNode} 渲染后的VNode
+ */
+ const renderSingleSelectTag = ({ option }: Record): VNode => {
+ return (
+
+ {option.label ? (
+
+
+ {option.label}
+
+ ) : (
+ {$t('t_0_1745833934390')}
+ )}
+
+ )
+ }
+
+ /**
+ * @description 渲染标签
+ * @param {Record} option - 选项
+ * @returns {VNode} 渲染后的VNode
+ */
+ const renderLabel = (option: { value: string; label: string }): VNode => {
+ return (
+
+
+ {option.label}
+
+ )
+ }
+
+ /**
+ * @description 提交授权API表单
+ * @param {UpdateAccessParams | AddAccessParams} param 请求参数
+ * @param {Ref} formRef 表单实例
+ */
+ const submitApiManageForm = async (param: UpdateAccessParams | AddAccessParams, formRef: Ref) => {
+ try {
+ const data = { ...param, config: JSON.stringify(param.config) } as UpdateAccessParams
+ if ('id' in param) {
+ const { id, name, config } = data // 解构出 id, name, config
+ await updateExistingAccess({ id: id.toString(), name, config } as UpdateAccessParams)
+ } else {
+ await addNewAccess(data as AddAccessParams)
+ }
+ } catch (_) {
+ return handleError(new Error($t('t_4_1746667590873')))
+ }
+ }
+
+ // 使用表单hooks
+ const { component: ApiManageForm, fetch } = useForm({
+ config,
+ defaultValue: param,
+ request: submitApiManageForm,
+ rules: rules as FormRules,
+ })
+
+ // 关联确认按钮
+ confirm(async (close) => {
+ try {
+ openLoad()
+ await fetch()
+ close()
+ } catch (error) {
+ return handleError(error)
+ } finally {
+ closeLoad()
+ }
+ })
+
+ return {
+ ApiManageForm,
+ }
+}
diff --git a/frontend/apps/allin-ssl/src/views/authApiManage/useStore.tsx b/frontend/apps/allin-ssl/src/views/authApiManage/useStore.tsx
new file mode 100644
index 0000000..2a9a0bc
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/views/authApiManage/useStore.tsx
@@ -0,0 +1,146 @@
+import { getAccessList, addAccess, updateAccess, deleteAccess } from '@api/access'
+import { useError } from '@baota/hooks/error'
+import { useMessage } from '@baota/naive-ui/hooks'
+import { $t } from '@locales/index'
+
+import type { AccessItem, AccessListParams, AddAccessParams, UpdateAccessParams } from '@/types/access'
+import type { TableResponse } from '@baota/naive-ui/types/table'
+
+const { handleError } = useError() // 导入错误处理钩子
+const message = useMessage() // 导入消息钩子
+
+/**
+ * 授权API管理状态 Store
+ * @description 用于管理授权API相关的状态和操作,包括API列表、类型、分页等
+ */
+export const useAuthApiManageStore = defineStore('auth-api-manage-store', () => {
+ // -------------------- 状态定义 --------------------
+ const accessTypes = ref({
+ ssh: 'SSH',
+ aliyun: '阿里云',
+ tencentcloud: '腾讯云',
+ btpanel: '宝塔',
+ '1panel': '1Panel',
+ })
+
+ /** 添加/编辑API表单 */
+ const apiFormProps = ref({
+ name: '',
+ type: 'btpanel',
+ config: {
+ url: '',
+ api_key: '',
+ ignore_ssl: '0',
+ },
+ })
+
+ // -------------------- 请求方法 --------------------
+ /**
+ * 获取授权API列表
+ * @description 根据分页和关键词获取授权API列表数据
+ * @param {Object} params - 查询参数
+ * @returns {Promise>} 返回列表数据和总数
+ */
+ const fetchAccessList = async (params: AccessListParams): Promise> => {
+ try {
+ const res = await getAccessList(params).fetch()
+ return {
+ list: (res.data || []) as T[],
+ total: res.count,
+ }
+ } catch (error) {
+ handleError(error)
+ return { list: [] as T[], total: 0 }
+ }
+ }
+
+ /**
+ * 新增授权API
+ * @description 创建新的授权API配置
+ * @param {AddAccessParams} params - 授权API参数
+ * @returns {Promise<{status: boolean, message: string}>} 操作结果
+ */
+ const addNewAccess = async (params: AddAccessParams) => {
+ try {
+ const { fetch, message } = addAccess(params)
+ message.value = true
+ await fetch()
+ resetApiForm()
+ } catch (error) {
+ if (handleError(error)) message.error($t('t_8_1745289354902'))
+ }
+ }
+
+ /**
+ * 更新授权API
+ * @description 更新指定的授权API配置信息
+ * @param {UpdateAccessParams} params - 授权API更新参数
+ * @returns {Promise<{status: boolean, message: string}>} 操作结果
+ */
+ const updateExistingAccess = async (params: UpdateAccessParams) => {
+ try {
+ const { fetch, message } = updateAccess(params)
+ message.value = true
+ await fetch()
+ resetApiForm()
+ } catch (error) {
+ if (handleError(error)) message.error($t('t_40_1745227838872'))
+ }
+ }
+
+ /**
+ * 删除授权API
+ * @description 删除指定的授权API配置
+ * @param {number} id - 授权API ID
+ * @returns {Promise<{status: boolean, message: string}>} 操作结果
+ */
+ const deleteExistingAccess = async (id: string) => {
+ try {
+ const { fetch, message } = deleteAccess({ id })
+ message.value = true
+ await fetch()
+ resetApiForm()
+ } catch (error) {
+ if (handleError(error)) message.error($t('t_40_1745227838872'))
+ }
+ }
+
+ /**
+ * 重置API表单
+ * @description 重置表单数据为初始状态
+ */
+ const resetApiForm = () => {
+ apiFormProps.value = {
+ name: '',
+ type: 'btpanel',
+ config: {
+ url: '',
+ api_key: '',
+ ignore_ssl: '0',
+ },
+ }
+ }
+
+ return {
+ // 状态
+ accessTypes,
+ apiFormProps,
+
+ // 方法
+ fetchAccessList,
+ addNewAccess,
+ updateExistingAccess,
+ deleteExistingAccess,
+ resetApiForm,
+ }
+})
+
+/**
+ * 组合式 API 使用 Store
+ * @description 提供对授权API管理 Store 的访问,并返回响应式引用
+ * @returns {Object} 包含所有 store 状态和方法的对象
+ */
+export const useStore = () => {
+ const store = useAuthApiManageStore()
+ return { ...store, ...storeToRefs(store) }
+}
diff --git a/frontend/apps/allin-ssl/src/views/autoDeploy/children/workflowView/index.tsx b/frontend/apps/allin-ssl/src/views/autoDeploy/children/workflowView/index.tsx
new file mode 100644
index 0000000..65fc09b
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/views/autoDeploy/children/workflowView/index.tsx
@@ -0,0 +1,11 @@
+import FlowChart from '@components/flowChart'
+import { useStore } from './useStore'
+import { useController } from './useController'
+export default defineComponent({
+ setup() {
+ const { init } = useController()
+ const { workflowType, workDefalutNodeData, isEdit } = useStore()
+ onMounted(init)
+ return () =>
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/views/autoDeploy/children/workflowView/useController.tsx b/frontend/apps/allin-ssl/src/views/autoDeploy/children/workflowView/useController.tsx
new file mode 100644
index 0000000..7481663
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/views/autoDeploy/children/workflowView/useController.tsx
@@ -0,0 +1,38 @@
+import { useStore } from './useStore'
+/**
+ * useController
+ * @description 组合式API使用store
+ * @returns {object} store - 返回store对象
+ */
+export const useController = () => {
+ const { workflowType, detectionRefresh } = useStore()
+ const route = useRoute()
+ const router = useRouter()
+
+ // 监听页面刷新
+ const beforeUnload = (event: any) => {
+ event.preventDefault()
+ event.returnValue = '您确定要刷新页面吗?数据可能会丢失哦!'
+ return '您确定要刷新页面吗?数据可能会丢失哦!'
+ }
+
+ // 初始化
+ const init = () => {
+ // 监听页面刷新
+ window.addEventListener('beforeunload', beforeUnload)
+ // 获取路由参数
+ const type = route.query.type
+ if (type) workflowType.value = type as 'quick' | 'advanced'
+ // 如果检测刷新为false,则跳转至自动部署页面
+ if (!detectionRefresh.value && route.path !== '/auto-deploy') router.push('/auto-deploy')
+ }
+
+ // 卸载
+ onUnmounted(() => {
+ window.removeEventListener('beforeunload', beforeUnload)
+ })
+
+ return {
+ init,
+ }
+}
diff --git a/frontend/apps/allin-ssl/src/views/autoDeploy/children/workflowView/useStore.tsx b/frontend/apps/allin-ssl/src/views/autoDeploy/children/workflowView/useStore.tsx
new file mode 100644
index 0000000..c5cf110
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/views/autoDeploy/children/workflowView/useStore.tsx
@@ -0,0 +1,117 @@
+import { addWorkflow, updateWorkflow } from '@api/workflow'
+import { useError } from '@baota/hooks/error'
+import { $t } from '@locales/index'
+
+import type { FlowNode } from '@components/flowChart/types'
+import type { AddWorkflowParams, UpdateWorkflowParams } from '@/types/workflow'
+
+export const useWorkEditViewStore = defineStore('work-edit-view-store', () => {
+ const { handleError } = useError()
+ const isEdit = ref(false) // 是否编辑
+ const detectionRefresh = ref(false) // 检测是否刷新, 用于检测是否刷新页面
+ // 工作流数据
+ const workflowData = ref({
+ id: '',
+ name: '',
+ content: '',
+ active: '1',
+ exec_type: 'manual',
+ })
+
+ // 工作流类型
+ const workflowType = ref<'quick' | 'advanced'>('quick')
+
+ // 工作流默认节点数据
+ const workDefalutNodeData = ref({
+ id: '',
+ name: '',
+ childNode: {
+ id: 'start-1',
+ name: '开始',
+ type: 'start',
+ config: {
+ exec_type: 'manual',
+ },
+ childNode: null,
+ },
+ })
+
+ /**
+ * @description 重置工作流数据
+ */
+ const resetWorkflowData = () => {
+ workflowData.value = {
+ id: '',
+ name: '',
+ content: '',
+ active: '1',
+ exec_type: 'manual',
+ }
+ workDefalutNodeData.value = {
+ id: '',
+ name: '',
+ childNode: {
+ id: 'start-1',
+ name: '开始',
+ type: 'start',
+ config: {
+ exec_type: 'manual',
+ },
+ childNode: null,
+ },
+ }
+ workflowType.value = 'quick'
+ isEdit.value = false
+ }
+ /**
+ * 添加新工作流
+ * @description 创建新的工作流配置
+ * @param {AddWorkflowParams} params - 工作流参数
+ * @returns {Promise} 是否添加成功
+ */
+ const addNewWorkflow = async (params: AddWorkflowParams) => {
+ try {
+ const { message, fetch } = addWorkflow(params)
+ message.value = true
+ await fetch()
+ } catch (error) {
+ handleError(error).default($t('t_10_1745457486451'))
+ }
+ }
+
+ /**
+ * 设置工作流运行方式
+ * @description 设置工作流运行方式
+ * @param {number} id - 工作流ID
+ * @param {number} execType - 运行方式
+ */
+ const updateWorkflowData = async (param: UpdateWorkflowParams) => {
+ try {
+ const { message, fetch } = updateWorkflow(param)
+ message.value = true
+ await fetch()
+ } catch (error) {
+ handleError(error).default($t('t_11_1745457488256'))
+ }
+ }
+ return {
+ isEdit,
+ detectionRefresh,
+ workflowData,
+ workflowType,
+ workDefalutNodeData,
+ resetWorkflowData,
+ addNewWorkflow,
+ updateWorkflowData,
+ }
+})
+
+/**
+ * useStore
+ * @description 组合式API使用store
+ * @returns {object} store - 返回store对象
+ */
+export const useStore = () => {
+ const store = useWorkEditViewStore()
+ return { ...store, ...storeToRefs(store) }
+}
diff --git a/frontend/apps/allin-ssl/src/views/autoDeploy/components/historyLogsModal.tsx b/frontend/apps/allin-ssl/src/views/autoDeploy/components/historyLogsModal.tsx
new file mode 100644
index 0000000..25618f9
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/views/autoDeploy/components/historyLogsModal.tsx
@@ -0,0 +1,50 @@
+import { getWorkflowHistoryDetail } from '@/api/workflow'
+import LogViewer from '@components/logViewer'
+
+export default defineComponent({
+ name: 'HistoryLogsModal',
+ props: {
+ id: {
+ type: [String] as PropType,
+ required: true,
+ },
+ },
+ setup(props) {
+ const loading = ref(false)
+ const logContent = ref('')
+
+ // 获取日志数据
+ const fetchLogs = async () => {
+ loading.value = true
+ try {
+ const { data } = await getWorkflowHistoryDetail({ id: props.id }).fetch()
+ if (data) {
+ logContent.value = data
+ } else {
+ logContent.value = '没有日志数据'
+ }
+ return logContent.value
+ } catch (error) {
+ console.error('获取日志详情失败:', error)
+ return '获取日志失败: ' + (error instanceof Error ? error.message : String(error))
+ } finally {
+ loading.value = false
+ }
+ }
+
+ // 组件挂载时自动获取日志
+ onMounted(() => {
+ fetchLogs()
+ console.log('mounted')
+ })
+
+ return () => (
+
+ )
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/views/autoDeploy/components/historyModal.tsx b/frontend/apps/allin-ssl/src/views/autoDeploy/components/historyModal.tsx
new file mode 100644
index 0000000..3e575c8
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/views/autoDeploy/components/historyModal.tsx
@@ -0,0 +1,40 @@
+import { useHistoryController } from '@autoDeploy/useController'
+import BaseComponent from '@components/baseComponent'
+import { $t } from '@locales/index'
+import { NButton } from 'naive-ui'
+
+/**
+ * 工作流执行历史模态框组件
+ */
+export default defineComponent({
+ name: 'HistoryModal',
+ props: {
+ id: {
+ type: String,
+ required: true,
+ },
+ },
+ setup(props) {
+ const { WorkflowHistoryTable, WorkflowHistoryTablePage, fetch } = useHistoryController(props.id)
+ onMounted(() => {
+ fetch()
+ })
+ return () => (
+
+
(
+
+ fetch()}>
+ {$t('t_9_1746667589516')}
+
+
+ ),
+ content: () => ,
+ footerRight: () => ,
+ }}
+ >
+
+ )
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/views/autoDeploy/components/workflowModal.tsx b/frontend/apps/allin-ssl/src/views/autoDeploy/components/workflowModal.tsx
new file mode 100644
index 0000000..30e295c
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/views/autoDeploy/components/workflowModal.tsx
@@ -0,0 +1,55 @@
+import { NCard, NSpace, NFormItem, NRadio } from 'naive-ui'
+import { useStore } from '@autoDeploy/useStore'
+import { useAddWorkflowController } from '@autoDeploy/useController'
+import { $t } from '@locales/index'
+
+/**
+ * 添加工作流模态框组件
+ */
+export default defineComponent({
+ name: 'AddWorkflowModal',
+ setup() {
+ const { workflowTemplateOptions, workflowFormData } = useStore()
+ const { AddWorkflowForm } = useAddWorkflowController()
+ return () => (
+
+ {
+ return (
+
+
+ {workflowTemplateOptions.value.map((item) => (
+ {
+ workflowFormData.value.templateType = item.value
+ }}
+ >
+
+
+
+
{item.label}
+
{item.description}
+
+
+
+
+
+ ))}
+
+
+ )
+ },
+ }}
+ />
+
+ )
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/views/autoDeploy/index.tsx b/frontend/apps/allin-ssl/src/views/autoDeploy/index.tsx
new file mode 100644
index 0000000..5ff8b08
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/views/autoDeploy/index.tsx
@@ -0,0 +1,99 @@
+import { NInput, NButton } from 'naive-ui'
+import { $t } from '@/locales'
+import { useThemeCssVar } from '@baota/naive-ui/theme'
+import { RouterView } from '@baota/router'
+import { PlusOutlined } from '@vicons/antd'
+import { Search } from '@vicons/carbon'
+import { useController } from './useController'
+import BaseComponent from '@components/baseComponent'
+import { useRouter } from 'vue-router'
+
+/**
+ * 工作流页面组件
+ */
+export default defineComponent({
+ name: 'WorkflowManager',
+ setup() {
+ const {
+ WorkflowTable,
+ WorkflowTablePage,
+ isDetectionAddWorkflow,
+ handleAddWorkflow,
+ hasChildRoutes,
+ param,
+ fetch,
+ data,
+ } = useController()
+ const router = useRouter()
+ // 获取主题变量
+ const cssVar = useThemeCssVar(['contentPadding', 'borderColor', 'headerHeight', 'iconColorHover'])
+
+ watch(
+ () => router.currentRoute.value.path,
+ (val) => {
+ if (val === '/auto-deploy') fetch()
+ },
+ )
+
+ // 挂载时获取数据
+ onMounted(() => {
+ isDetectionAddWorkflow()
+ fetch()
+ })
+
+ return () => (
+
+
+ {hasChildRoutes.value ? (
+
+ ) : (
+
(
+
+
+ {$t('t_0_1745227838699')}
+
+ ),
+ headerRight: () => (
+ {
+ if (e.key === 'Enter') fetch()
+ }}
+ onClear={() => useTimeoutFn(fetch, 100)}
+ placeholder={$t('t_1_1745227838776')}
+ clearable
+ size="large"
+ class="min-w-[300px]"
+ v-slots={{
+ suffix: () => (
+
+
+
+ ),
+ }}
+ >
+ ),
+ content: () => (
+
+
+
+ ),
+ footerRight: () => (
+
+ {$t('t_0_1746773350551', [data.value.total])},
+ }}
+ />
+
+ ),
+ }}
+ >
+ )}
+
+
+ )
+ },
+})
diff --git a/frontend/apps/allin-ssl/src/views/autoDeploy/useController.tsx b/frontend/apps/allin-ssl/src/views/autoDeploy/useController.tsx
new file mode 100644
index 0000000..683b258
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/views/autoDeploy/useController.tsx
@@ -0,0 +1,477 @@
+import { NSwitch, NTag, NButton, NSpace } from 'naive-ui'
+import { useRoute, useRouter } from 'vue-router'
+import { useStore } from '@autoDeploy/useStore'
+import {
+ useDialog,
+ useTable,
+ useTablePage,
+ useModal,
+ useFormHooks,
+ useForm,
+ useModalHooks,
+} from '@baota/naive-ui/hooks'
+import { useStore as useWorkflowViewStore } from '@autoDeploy/children/workflowView/useStore'
+import { useError } from '@baota/hooks/error'
+import AddWorkflowModal from './components/workflowModal'
+import HistoryModal from './components/historyModal'
+import HistoryLogsModal from './components/historyLogsModal'
+import { $t } from '@/locales'
+import { router } from '@router/index'
+
+import type { WorkflowItem, WorkflowListParams, WorkflowHistoryParams, WorkflowHistoryItem } from '@/types/workflow'
+import type { DataTableColumn } from 'naive-ui'
+import { TableColumn } from 'naive-ui/es/data-table/src/interface'
+
+const {
+ fetchWorkflowList,
+ fetchWorkflowHistory,
+ workflowFormData,
+ deleteExistingWorkflow,
+ executeExistingWorkflow,
+ setWorkflowActive,
+ setWorkflowExecType,
+} = useStore()
+const { isEdit, workDefalutNodeData, resetWorkflowData, workflowData, detectionRefresh } = useWorkflowViewStore()
+const { handleError } = useError()
+const { useFormSlot } = useFormHooks()
+
+/**
+ * @description 状态列
+ * @param {string} key - 状态列的key
+ * @returns {DataTableColumn[]} 返回状态列配置数组
+ */
+const statusCol = (key: string, title: string): TableColumn => ({
+ title,
+ key,
+ width: 100,
+ render: (row: T) => {
+ const statusMap: Record = {
+ success: { type: 'success', text: $t('t_8_1745227838023') },
+ fail: { type: 'error', text: $t('t_9_1745227838305') },
+ running: { type: 'warning', text: $t('t_0_1746519384035') },
+ }
+ const status = statusMap[row[key] as keyof Record] || {
+ type: 'default',
+ text: $t('t_1_1746773348701'),
+ }
+ return (
+
+ {status.text}
+
+ )
+ },
+})
+
+/**
+ * @description 工作流业务逻辑控制器
+ * @function useController
+ */
+export const useController = () => {
+ // 获取当前路由
+ const route = useRoute()
+ // 获取路由实例
+ const router = useRouter()
+
+ // 判断是否为子路由
+ const hasChildRoutes = computed(() => route.path !== '/auto-deploy')
+
+ /**
+ * @description 创建表格列配置
+ * @returns {DataTableColumn[]} 返回表格列配置数组
+ */
+ const createColumns = (): DataTableColumn[] => [
+ {
+ title: $t('t_0_1745215914686'),
+ key: 'name',
+ width: 200,
+ ellipsis: {
+ tooltip: true,
+ },
+ },
+ {
+ title: $t('t_1_1746590060448'),
+ key: 'type',
+ width: 100,
+ render: (row: WorkflowItem) => (
+
+ {
+ handleSetWorkflowExecType(row)
+ }}
+ checkedValue={'auto'}
+ uncheckedValue={'manual'}
+ />
+ {row.exec_type === 'auto' ? $t('t_2_1745215915397') : $t('t_3_1745215914237')}
+
+ ),
+ },
+ // {
+ // title: $t('t_4_1745215914951'),
+ // key: 'active',
+ // width: 100,
+ // render: (row: WorkflowItem) => (
+ // {
+ // handleChangeActive(row)
+ // }}
+ // checkedValue={1}
+ // uncheckedValue={0}
+ // checked-text={$t('t_0_1745457486299')}
+ // unchecked-text={$t('t_1_1745457484314')}
+ // />
+ // ),
+ // },
+ {
+ title: $t('t_7_1745215914189'),
+ key: 'created_at',
+ width: 180,
+ render: (row: WorkflowItem) => row.create_time || '-',
+ },
+ statusCol('last_run_status', $t('t_0_1746677882486')),
+ {
+ title: $t('t_8_1745215914610'),
+ key: 'actions',
+ fixed: 'right',
+ align: 'right',
+ width: 220,
+ render: (row: WorkflowItem) => (
+
+ handleViewHistory(row)}
+ >
+ {$t('t_9_1745215914666')}
+
+ handleExecuteWorkflow(row)}>
+ {$t('t_10_1745215914342')}
+
+ handleEditWorkflow(row)}>
+ {$t('t_11_1745215915429')}
+
+ handleDeleteWorkflow(row)}>
+ {$t('t_12_1745215914312')}
+
+
+ ),
+ },
+ ]
+
+ // 表格实例
+ const {
+ component: WorkflowTable,
+ loading,
+ param,
+ data,
+ total,
+ fetch,
+ } = useTable({
+ config: createColumns(),
+ request: fetchWorkflowList,
+ defaultValue: {
+ p: 1,
+ limit: 10,
+ search: '',
+ },
+ watchValue: ['p', 'limit'],
+ })
+
+ // 分页实例
+ const { component: WorkflowTablePage } = useTablePage({
+ param,
+ total,
+ alias: {
+ page: 'p',
+ pageSize: 'limit',
+ },
+ })
+
+ /**
+ * @description 打开添加工作流弹窗
+ */
+ const handleAddWorkflow = () => {
+ detectionRefresh.value = true
+ useModal({
+ title: $t('t_5_1746667590676'),
+ component: AddWorkflowModal,
+ footer: true,
+ area: 500,
+ onUpdateShow(show) {
+ if (!show) fetch()
+ },
+ })
+ }
+
+ /**
+ * @description 查看工作流执行历史
+ * @param {number} workflowId - 工作流ID
+ */
+ const handleViewHistory = async (workflow: WorkflowItem) => {
+ useModal({
+ title: workflow ? `${workflow.name} - ${$t('t_9_1745215914666')}` : $t('t_9_1745215914666'),
+ component: HistoryModal,
+ area: 800,
+ componentProps: { id: workflow.id },
+ })
+ }
+
+ /**
+ * @description 执行工作流
+ * @param {WorkflowItem} workflow - 工作流对象
+ */
+ const handleExecuteWorkflow = async ({ name, id }: WorkflowItem) => {
+ useDialog({
+ title: $t('t_13_1745215915455'),
+ content: $t('t_2_1745227839794', { name }),
+ onPositiveClick: async () => {
+ await executeExistingWorkflow(id)
+ await fetch()
+ },
+ })
+ }
+
+ /**
+ * @description 设置工作流运行方式
+ * @param {WorkflowItem} workflow - 工作流对象
+ */
+ const handleSetWorkflowExecType = ({ id, exec_type }: WorkflowItem) => {
+ useDialog({
+ title: exec_type === 'manual' ? $t('t_2_1745457488661') : $t('t_3_1745457486983'),
+ content: exec_type === 'manual' ? $t('t_4_1745457497303') : $t('t_5_1745457494695'),
+ onPositiveClick: () => setWorkflowExecType({ id, exec_type }),
+ onNegativeClick: fetch,
+ onClose: fetch,
+ })
+ }
+
+ /**
+ * @description 切换工作流状态
+ * @param active - 工作流状态
+ */
+ const handleChangeActive = ({ id, active }: WorkflowItem) => {
+ useDialog({
+ title: !active ? $t('t_6_1745457487560') : $t('t_7_1745457487185'),
+ content: !active ? $t('t_8_1745457496621') : $t('t_9_1745457500045'),
+ onPositiveClick: () => setWorkflowActive({ id, active }),
+ onNegativeClick: fetch,
+ onClose: fetch,
+ })
+ }
+
+ /**
+ * @description 编辑工作流
+ * @param {WorkflowItem} workflow - 工作流对象
+ * @todo 实现工作流编辑功能
+ */
+ const handleEditWorkflow = (workflow: WorkflowItem) => {
+ const content = JSON.parse(workflow.content)
+ isEdit.value = true
+ workflowData.value = {
+ id: workflow.id,
+ name: workflow.name,
+ content: content,
+ exec_type: workflow.exec_type,
+ active: workflow.active,
+ }
+ workDefalutNodeData.value = {
+ id: workflow.id,
+ name: workflow.name,
+ childNode: content,
+ }
+ detectionRefresh.value = true
+ router.push(`/auto-deploy/workflow-view?isEdit=true`)
+ }
+
+ /**
+ * @description 删除工作流
+ * @param {WorkflowItem} workflow - 工作流对象
+ */
+ const handleDeleteWorkflow = (workflow: WorkflowItem) => {
+ useDialog({
+ title: $t('t_16_1745215915209'),
+ content: $t('t_3_1745227841567', { name: workflow.name }),
+ onPositiveClick: async () => {
+ await deleteExistingWorkflow(workflow.id)
+ await fetch()
+ },
+ })
+ }
+
+ /**
+ * @description 检测是否需要添加工作流
+ */
+ const isDetectionAddWorkflow = () => {
+ const { type } = route.query
+ if (type?.includes('create')) {
+ handleAddWorkflow()
+ router.push({ query: {} })
+ }
+ }
+
+ return {
+ WorkflowTable,
+ WorkflowTablePage,
+ isDetectionAddWorkflow,
+ handleViewHistory, // 查看工作流执行历史
+ handleAddWorkflow, // 打开添加工作流弹窗
+ handleChangeActive, // 切换工作流状态
+ handleSetWorkflowExecType, // 设置工作流运行方式
+ handleExecuteWorkflow, // 执行工作流
+ handleEditWorkflow, // 编辑工作流
+ handleDeleteWorkflow, // 删除工作流
+ hasChildRoutes,
+ fetch,
+ data,
+ loading,
+ param,
+ }
+}
+
+/**
+ * @description 添加工作流业务逻辑控制器
+ * @returns {Object} 返回添加工作流业务逻辑控制器实例
+ */
+export const useAddWorkflowController = () => {
+ const { confirm } = useModalHooks()
+ // 表单配置
+ const config = computed(() => [useFormSlot('template')])
+
+ // 表单实例
+ const { component: AddWorkflowForm, data } = useForm({
+ config,
+ rules: {},
+ defaultValue: workflowFormData,
+ })
+
+ // 确认添加工作流
+ confirm(async (close) => {
+ try {
+ close()
+ resetWorkflowData()
+ router.push(`/auto-deploy/workflow-view?type=${data.value.templateType}`)
+ } catch (error) {
+ handleError(error)
+ }
+ })
+ return { AddWorkflowForm }
+}
+
+/**
+ * @description 工作流历史记录业务逻辑控制器
+ * @param {number} workflowId - 工作流ID
+ * @returns {Object} 返回工作流历史记录业务逻辑控制器实例
+ */
+export const useHistoryController = (id: string) => {
+ /**
+ * @description 工作流历史详情
+ * @param {number} workflowId - 工作流ID
+ */
+ const handleViewHistoryDetail = async (workflowId: string) => {
+ useModal({
+ title: $t('t_0_1746579648713'),
+ component: HistoryLogsModal,
+ area: 730,
+ componentProps: { id: workflowId },
+ })
+ }
+
+ /**
+ * @description 创建历史记录表格列配置
+ * @returns {DataTableColumn[]} 返回表格列配置数组
+ */
+ const createColumns = (): DataTableColumn[] => [
+ {
+ title: $t('t_4_1745227838558'),
+ key: 'create_time',
+ width: 230,
+ render: (row: WorkflowHistoryItem) => {
+ // 处理数字类型的时间戳
+ return row.create_time ? row.create_time : '-'
+ },
+ },
+ {
+ title: $t('t_5_1745227839906'),
+ key: 'end_time',
+ width: 230,
+ render: (row: WorkflowHistoryItem) => {
+ // 处理数字类型的时间戳
+ return row.end_time ? row.end_time : '-'
+ },
+ },
+ {
+ title: $t('t_6_1745227838798'),
+ key: 'exec_type',
+ width: 110,
+ render: (row: WorkflowHistoryItem) => (
+
+ {row.exec_type === 'auto' ? $t('t_2_1745215915397') : $t('t_3_1745215914237')}
+
+ ),
+ },
+ statusCol('status', $t('t_7_1745227838093')),
+ {
+ title: $t('t_8_1745215914610'),
+ key: 'actions',
+ fixed: 'right',
+ align: 'right',
+ width: 80,
+ render: (row: WorkflowHistoryItem) => (
+
+ handleViewHistoryDetail(row.id.toString())}
+ >
+ {$t('t_12_1745227838814')}
+
+
+ ),
+ },
+ ]
+
+ // 表格实例
+ const {
+ component: WorkflowHistoryTable,
+ loading,
+ param,
+ data,
+ total,
+ fetch,
+ } = useTable({
+ config: createColumns(),
+ request: fetchWorkflowHistory,
+ defaultValue: {
+ id,
+ p: 1,
+ limit: 10,
+ },
+ watchValue: ['p', 'limit'],
+ })
+
+ const { component: WorkflowHistoryTablePage } = useTablePage({
+ param,
+ total,
+ alias: {
+ page: 'p',
+ pageSize: 'limit',
+ },
+ })
+
+ return {
+ WorkflowHistoryTable,
+ WorkflowHistoryTablePage,
+ loading,
+ param,
+ data,
+ total,
+ fetch,
+ }
+}
diff --git a/frontend/apps/allin-ssl/src/views/autoDeploy/useStore.tsx b/frontend/apps/allin-ssl/src/views/autoDeploy/useStore.tsx
new file mode 100644
index 0000000..5c85fb8
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/views/autoDeploy/useStore.tsx
@@ -0,0 +1,163 @@
+import {
+ getWorkflowList,
+ addWorkflow,
+ deleteWorkflow,
+ getWorkflowHistory,
+ executeWorkflow,
+ updateWorkflowExecType,
+ enableWorkflow,
+} from '@/api/workflow'
+import { useError } from '@baota/hooks/error'
+// import { useMessage } from '@baota/naive-ui/hooks'
+import { $t } from '@locales/index'
+import type {
+ AddWorkflowParams,
+ WorkflowListParams,
+ WorkflowHistoryParams,
+ WorkflowHistoryItem,
+ WorkflowItem,
+ UpdateWorkflowExecTypeParams,
+ EnableWorkflowParams,
+} from '@/types/workflow'
+
+const { handleError } = useError()
+
+/**
+ * 工作流状态管理 Store
+ * @description 用于管理工作流相关的状态和操作,包括工作流列表、历史记录、分页等
+ */
+export const useWorkflowStore = defineStore('workflow-store', () => {
+ const isEditWorkFlow = ref(false) // 是否编辑工作流
+ // 表单数据
+ const workflowFormData = ref({
+ name: '',
+ templateType: 'quick',
+ })
+
+ // 模板选项
+ const workflowTemplateOptions = ref([
+ { label: '快速部署模板', value: 'quick', description: '快速上线应用,简化流程' },
+ { label: '高级自定义模板', value: 'advanced', description: '完全自定义的部署流程' },
+ ])
+
+ // -------------------- 工具方法 --------------------
+ /**
+ * 获取工作流列表
+ * @description 根据分页参数获取工作流列表数据
+ * @returns {Promise}
+ */
+ const fetchWorkflowList = async ({ p, limit, search }: WorkflowListParams) => {
+ try {
+ const { data, count } = await getWorkflowList({ p, limit, search }).fetch()
+ return { list: (data || []) as T[], total: count }
+ } catch (error) {
+ handleError(error)
+ return { list: [], total: 0 }
+ }
+ }
+
+ /**
+ * 获取工作流历史记录
+ * @description 根据工作流ID获取其历史执行记录
+ * @param {number} workflowId - 工作流ID
+ * @returns {Promise}
+ */
+ const fetchWorkflowHistory = async ({ id, p, limit }: WorkflowHistoryParams) => {
+ try {
+ const res = await getWorkflowHistory({ id, p, limit }).fetch()
+ return { list: (res.data || []) as T[], total: res.count }
+ } catch (error) {
+ handleError(error)
+ return { list: [], total: 0 }
+ }
+ }
+
+ /**
+ * 设置工作流运行方式
+ * @description 设置工作流运行方式
+ * @param {number} id - 工作流ID
+ * @param {number} execType - 运行方式
+ */
+ const setWorkflowExecType = async ({ id, exec_type }: UpdateWorkflowExecTypeParams) => {
+ try {
+ const { message, fetch } = updateWorkflowExecType({ id, exec_type })
+ message.value = true
+ await fetch()
+ } catch (error) {
+ handleError(error).default($t('t_11_1745457488256'))
+ }
+ }
+
+ /**
+ * 启用或禁用工作流
+ * @description 启用或禁用指定工作流
+ * @param {number} id - 工作流ID
+ * @param {boolean} active - 是否启用
+ */
+ const setWorkflowActive = async ({ id, active }: EnableWorkflowParams) => {
+ try {
+ const { message, fetch } = enableWorkflow({ id, active })
+ message.value = true
+ await fetch()
+ } catch (error) {
+ handleError(error).default($t('t_12_1745457489076'))
+ }
+ }
+
+ /**
+ * 执行工作流
+ * @description 触发指定工作流的执行
+ * @param {number} id - 工作流ID
+ * @returns {Promise} 是否执行成功
+ */
+ const executeExistingWorkflow = async (id: string) => {
+ try {
+ const { message, fetch } = executeWorkflow({ id })
+ message.value = true
+ await fetch()
+ } catch (error) {
+ handleError(error).default($t('t_13_1745457487555'))
+ }
+ }
+
+ /**
+ * 删除工作流
+ * @description 删除指定的工作流配置
+ * @param {number} id - 工作流ID
+ * @returns {Promise} 是否删除成功
+ */
+ const deleteExistingWorkflow = async (id: string) => {
+ try {
+ const { message, fetch } = deleteWorkflow({ id: id.toString() })
+ message.value = true
+ await fetch()
+ } catch (error) {
+ handleError(error).default($t('t_14_1745457488092'))
+ }
+ }
+
+ return {
+ // 状态
+ isEditWorkFlow,
+ workflowFormData,
+ workflowTemplateOptions,
+
+ // 方法
+ fetchWorkflowList,
+ fetchWorkflowHistory,
+ deleteExistingWorkflow,
+ executeExistingWorkflow,
+ setWorkflowActive,
+ setWorkflowExecType,
+ }
+})
+
+/**
+ * 组合式 API 使用 Store
+ * @description 提供对工作流 Store 的访问,并返回响应式引用
+ * @returns {Object} 包含所有 store 状态和方法的对象
+ */
+export const useStore = () => {
+ const store = useWorkflowStore()
+ return { ...store, ...storeToRefs(store) }
+}
diff --git a/frontend/apps/allin-ssl/src/views/certApply/components/freeProductCard.tsx b/frontend/apps/allin-ssl/src/views/certApply/components/freeProductCard.tsx
new file mode 100644
index 0000000..f4b3387
--- /dev/null
+++ b/frontend/apps/allin-ssl/src/views/certApply/components/freeProductCard.tsx
@@ -0,0 +1,142 @@
+import { NButton, NImage, NBadge } from 'naive-ui'
+import { $t } from '@locales/index'
+interface FreeProductCardProps {
+ product: {
+ pid: number
+ brand: string
+ type: string
+ title: string
+ code: string
+ num: number
+ valid_days: number
+ features: string[]
+ }
+ onApply: (id: number) => void
+}
+
+/**
+ * 免费SSL证书产品卡片组件
+ * @param product - 产品信息
+ * @param onApply - 申请按钮点击处理函数
+ */
+export default defineComponent({
+ name: 'FreeProductCard',
+ props: {
+ product: {
+ type: Object as PropType,
+ required: true,
+ },
+ onApply: {
+ type: Function as PropType,
+ required: true,
+ },
+ },
+ setup(props) {
+ // 判断是否为通配符证书
+ const isWildcard = computed(() => {
+ return props.product.title.toLowerCase().includes($t('t_10_1746667589575'))
+ })
+
+ // 判断是否为多域名证书
+ const isMultiDomain = computed(() => {
+ return props.product.title.toLowerCase().includes($t('t_11_1746667589598'))
+ })
+
+ // 处理申请按钮点击
+ const handleApply = () => {
+ props.onApply(props.product.pid)
+ }
+
+ // 获取品牌图标
+ const getBrandIcon = (brand: string) => {
+ const brandLower = brand.toLowerCase()
+ const brandIconMap: Record = {
+ sectigo: '/static/icons/sectigo-ico.png',
+ positive: '/static/icons/positive-ico.png',
+ ssltrus: '/static/icons/ssltrus-ico.png',
+ "let's encrypt": '/static/icons/letsencrypt-icon.svg',
+ }
+ return Object.keys(brandIconMap).find((key) => brandLower.includes(key))
+ ? brandIconMap[Object.keys(brandIconMap).find((key) => brandLower.includes(key)) as string]
+ : undefined
+ }
+
+ return () => (
+