mirror of
https://github.com/certd/certd.git
synced 2026-05-01 10:27:31 +08:00
Compare commits
12 Commits
v1.39.12
...
codex_i18n
| Author | SHA1 | Date | |
|---|---|---|---|
| 146098d9ce | |||
| 519743dbdb | |||
| 7ab661ecd7 | |||
| bb46cb08f7 | |||
| 028932c04a | |||
| 73e6480853 | |||
| aa176b081a | |||
| 267243e71b | |||
| 33fbef8380 | |||
| 45a128a050 | |||
| 2ddc668954 | |||
| ad76c5177c |
Symlink
+1
@@ -0,0 +1 @@
|
||||
../.trae/skills
|
||||
@@ -0,0 +1,207 @@
|
||||
# Certd 开发 Agent 上下文
|
||||
|
||||
这个文件是给在本仓库工作的开发 agent 看的常驻项目说明。后续会话进入仓库后,应先读取它,再按任务需要查看具体代码,避免每次都重新全量扫描项目。
|
||||
|
||||
## 项目用途
|
||||
|
||||
Certd 是一个支持私有化部署的 SSL/TLS 证书自动化管理平台。它提供 Web 管理台和后端服务,用于证书申请、续期、部署、监控、通知和开放 API 集成。
|
||||
|
||||
它不只是一个简单的 ACME 客户端。项目的核心产品模型是“证书流水线”:
|
||||
|
||||
- 通过 ACME 申请证书
|
||||
- 支持 DNS-01、HTTP-01、CNAME 代理以及各类服务商集成来完成域名验证
|
||||
- 支持将证书转换或导出为 pem、pfx、der、jks、p7b 等格式
|
||||
- 支持把证书部署到主机、Nginx、Kubernetes、CDN、云厂商、面板等目标
|
||||
- 支持通知用户,并监控站点证书过期时间
|
||||
|
||||
由于系统会保存证书、云厂商凭据、SSH 信息、API Key 等敏感数据,产品定位上强烈建议私有化/本地部署。
|
||||
|
||||
## 仓库结构
|
||||
|
||||
这是一个 pnpm + lerna 的 monorepo。
|
||||
|
||||
- `package.json`:根脚本和 workspace 元信息
|
||||
- `pnpm-workspace.yaml`:workspace 包匹配规则
|
||||
- `lerna.json`:lerna-lite 配置
|
||||
- `docs/`:VitePress 文档站
|
||||
- `docker/`:Docker 安装和运行相关文件
|
||||
- `packages/core/acme-client/`:ACME 协议客户端,风格接近 node-acme-client
|
||||
- `packages/core/basic/`:共享基础工具和基础设施
|
||||
- `packages/core/pipeline/`:流水线核心、注册表、装饰器、插件模型、上下文、服务、通知等
|
||||
- `packages/libs/`:共享集成与辅助库,例如 server、Huawei、JDCloud、Kubernetes、iframe
|
||||
- `packages/plugins/plugin-lib/`:通用插件辅助能力和证书相关共享代码
|
||||
- `packages/plugins/plugin-cert/`:证书流水线插件包
|
||||
- `packages/pro/`:商业版/专业版相关包
|
||||
- `packages/ui/certd-server/`:后端服务
|
||||
- `packages/ui/certd-client/`:前端 Web 管理台
|
||||
|
||||
## 后端
|
||||
|
||||
主要后端包:`packages/ui/certd-server`。
|
||||
|
||||
技术栈:
|
||||
|
||||
- Node.js、ESM、TypeScript
|
||||
- MidwayJS 3
|
||||
- Koa
|
||||
- TypeORM
|
||||
- 默认使用 better-sqlite3,同时支持 PostgreSQL 和 MySQL
|
||||
- 通过 `@certd/midway-flyway-js` 使用类似 Flyway 的 SQL 迁移机制
|
||||
|
||||
重要位置:
|
||||
|
||||
- `packages/ui/certd-server/src/config/config.default.ts`:默认服务、静态文件、数据库、定时任务、认证、上传、Swagger 配置
|
||||
- `packages/ui/certd-server/src/config/`:环境与配置加载逻辑
|
||||
- `packages/ui/certd-server/src/configuration.ts`:Midway 应用配置、中间件注册、组件导入
|
||||
- `packages/ui/certd-server/src/modules/`:业务模块,例如 pipeline、cert、cron、monitor、login、open API、sys、plugin、cname、notification
|
||||
- `packages/ui/certd-server/src/controller/`:按 API 领域划分的控制器
|
||||
- `packages/ui/certd-server/src/plugins/`:后端内置的具体服务商、部署、通知等插件
|
||||
- `packages/ui/certd-server/db/migration/`:数据库迁移 SQL
|
||||
- `packages/ui/certd-server/data/`:本地运行数据,例如 SQLite 数据库和生成文件
|
||||
- `packages/ui/certd-server/logs/`:运行日志
|
||||
|
||||
已观察到的默认开发配置:
|
||||
|
||||
- HTTP 端口:`7001`
|
||||
- HTTPS 端口:`7002`
|
||||
- 默认 SQLite 数据库:`./data/db.sqlite`
|
||||
- 默认文件根目录:`./data/files`
|
||||
|
||||
常用脚本:
|
||||
|
||||
- 根目录 `pnpm run start:server`:以生产模式启动后端包
|
||||
- 后端 `pnpm run dev`:启动 Midway watch/dev 服务
|
||||
- 后端 `pnpm run test`:运行后端 mocha 测试
|
||||
- 后端 `pnpm run build`:构建后端并导出插件元数据
|
||||
|
||||
## 前端
|
||||
|
||||
主要前端包:`packages/ui/certd-client`。
|
||||
|
||||
技术栈:
|
||||
|
||||
- Vue 3
|
||||
- Vite
|
||||
- TypeScript
|
||||
- Ant Design Vue
|
||||
- Fast Crud
|
||||
- Pinia
|
||||
- vue-router
|
||||
- vue-i18n
|
||||
- Tailwind/Windi 相关样式工具
|
||||
|
||||
重要位置:
|
||||
|
||||
- `packages/ui/certd-client/src/main.ts`:前端启动入口
|
||||
- `packages/ui/certd-client/src/App.vue`:根组件
|
||||
- `packages/ui/certd-client/src/api/`:API 调用封装
|
||||
- `packages/ui/certd-client/src/router/`:路由
|
||||
- `packages/ui/certd-client/src/store/`:Pinia store
|
||||
- `packages/ui/certd-client/src/views/certd/`:核心产品页面,例如流水线、证书、授权、监控、通知、开放 API、项目、支付、插件
|
||||
- `packages/ui/certd-client/src/components/`:共享 UI 组件
|
||||
- `packages/ui/certd-client/src/locales/`:国际化
|
||||
|
||||
常用脚本:
|
||||
|
||||
- 前端 `pnpm dev`:启动 Vite 开发服务
|
||||
- 前端 `pnpm build`:生产构建
|
||||
- 前端 `pnpm tsc`:类型检查
|
||||
- 前端 `pnpm test:unit`:Vitest 单元测试
|
||||
|
||||
## 流水线与插件模型
|
||||
|
||||
项目最关键的架构概念是证书流水线。
|
||||
|
||||
可以从 `packages/core/pipeline/src/index.ts` 入手,它导出:
|
||||
|
||||
- `core`
|
||||
- `dt`
|
||||
- `access`
|
||||
- `registry`
|
||||
- `plugin`
|
||||
- `context`
|
||||
- `decorator`
|
||||
- `service`
|
||||
- `notification`
|
||||
|
||||
插件是核心能力,不是边缘功能。新增服务商、DNS 验证、证书部署、通知方式等能力,通常应该放在插件包里,或放在 `packages/ui/certd-server/src/plugins/<plugin-name>/` 下。
|
||||
|
||||
后端已看到的插件类型包括:
|
||||
|
||||
- DNS 和注册商服务商:Aliyun、Tencent、Cloudflare、Huawei、JDCloud、AWS、Azure、Google、GoDaddy、Namesilo、Xinnet、West、UCloud、Qiniu、Upyun、Volcengine 等
|
||||
- 部署目标:host、Kubernetes、Nginx Proxy Manager、APISIX、Proxmox、QNAP、Dokploy、GoEdge、各类 CDN、各类面板
|
||||
- 系统/产品插件:notification、captcha、oauth、admin、plus/pro、demo/template
|
||||
|
||||
当修改证书申请、验证、部署或通知行为时,先判断改动属于哪里:
|
||||
|
||||
- ACME client 代码
|
||||
- pipeline 核心抽象
|
||||
- 后端 module/service/entity/controller
|
||||
- 某个具体插件实现
|
||||
- 前端 view/form/schema
|
||||
|
||||
如果只是某个服务商或部署目标的问题,不要轻易修改共享 pipeline/core 行为,除非确实是可复用的公共能力。
|
||||
|
||||
## 数据与迁移
|
||||
|
||||
后端使用 TypeORM 实体加 SQL 迁移。
|
||||
|
||||
重点查看:
|
||||
|
||||
- `packages/ui/certd-server/src/modules/**/entity/*.ts`
|
||||
- `packages/ui/certd-server/db/migration/*.sql`
|
||||
|
||||
默认配置中 `synchronize: false`,所以涉及表结构变更时,通常应该添加或更新迁移脚本,而不是依赖 TypeORM 自动同步。
|
||||
|
||||
## 开发注意事项
|
||||
|
||||
- 中文 README 在部分 PowerShell 环境中可能显示乱码;`README_en.md` 可读性更好,且包含同样的高层项目说明。
|
||||
- 初次整理时观察到当前分支为 `v2-dev`。
|
||||
- 根包管理器是 pnpm,不要引入 npm/yarn lockfile。
|
||||
- 优先沿用现有模块、插件、服务模式,再考虑新增抽象。
|
||||
- `packages/ui/certd-server/data/`、`logs/`、生成的 metadata/dist 等通常视为运行时或构建产物,除非任务明确要求处理它们。
|
||||
- 注意本地数据和配置里可能包含凭据、证书材料等敏感信息。
|
||||
|
||||
## 插件开发技能
|
||||
|
||||
仓库内置了 Certd 插件开发技能,供 Trae 和 Codex 共用:
|
||||
|
||||
- Trae 入口:`.trae/skills`
|
||||
- Codex 入口:`.codex/skills`
|
||||
|
||||
其中 `.codex/skills` 是指向 `.trae/skills` 的目录链接,不要复制出第二份技能内容。更新技能时只维护 `.trae/skills` 下的原始文件,Codex 会通过 `.codex/skills` 读取同一份内容。
|
||||
|
||||
当前技能包括:
|
||||
|
||||
- `access-plugin-dev`:开发 Access 授权插件
|
||||
- `dns-provider-dev`:开发 DNS Provider 插件
|
||||
- `task-plugin-dev`:开发 Task 部署任务插件
|
||||
- `plugin-converter`:将插件转换为 YAML 配置
|
||||
|
||||
做插件相关任务时,先读取对应技能目录下的 `SKILL.md`,再进入具体实现。若用户在插件开发中指出更好的做法,应总结并更新对应技能。
|
||||
|
||||
## 快速定向命令
|
||||
|
||||
进入项目后,优先使用这些有目标的读取命令,而不是立刻全仓库扫描:
|
||||
|
||||
```powershell
|
||||
Get-Content package.json
|
||||
Get-Content pnpm-workspace.yaml
|
||||
Get-Content lerna.json
|
||||
Get-Content README_en.md -TotalCount 180
|
||||
Get-Content packages\ui\certd-server\package.json
|
||||
Get-Content packages\ui\certd-client\package.json
|
||||
Get-ChildItem packages\ui\certd-server\src\modules
|
||||
Get-ChildItem packages\ui\certd-server\src\plugins
|
||||
Get-ChildItem packages\ui\certd-client\src\views\certd
|
||||
```
|
||||
|
||||
## 本仓库 Agent 工作方式
|
||||
|
||||
- 先读本文件,再按用户任务查看相关 package/module。
|
||||
- 做后端任务时,先定位 `packages/ui/certd-server/src/modules` 下的模块,以及相关 entity/service/controller。
|
||||
- 做前端任务时,先定位 `packages/ui/certd-client/src/views/certd` 下的页面,再找对应 `src/api`。
|
||||
- 做服务商、DNS、部署、通知相关任务时,先看 `packages/ui/certd-server/src/plugins`,再看 `packages/plugins/plugin-lib` 里的共享辅助能力。
|
||||
- 做数据库结构变更时,添加或更新迁移脚本,不要依赖 TypeORM 自动同步。
|
||||
- 前端 TS/Vue/locale 等文件改动后,优先只对本次改动文件运行项目现有自动格式化/修复,例如 `corepack pnpm --dir packages\ui\certd-client exec prettier --write <files>` 和 `corepack pnpm --dir packages\ui\certd-client exec eslint --fix <files>`;不要为了格式化无关文件而扩大 diff。项目保留了 `tslint` 依赖,但当前主要使用 ESLint + Prettier。
|
||||
- 优先对改动包运行聚焦的测试或类型检查;只有跨包影响明显时再考虑全 monorepo 构建。
|
||||
@@ -3,6 +3,21 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.39.12](https://github.com/certd/certd/compare/v1.39.11...v1.39.12) (2026-04-29)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 调整手机版首页标题被挤开的bug ([eab66e2](https://github.com/certd/certd/commit/eab66e2d1988635985745f2d1b227b958969ee00))
|
||||
* 修复腾讯云clb部署报缺少sslmode参数的bug ([2f1ad72](https://github.com/certd/certd/commit/2f1ad7201f5ed9e00368a28b9e40907d4b415852))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 524错误时重试3次 ([00e6d58](https://github.com/certd/certd/commit/00e6d580c2f54af70fe96a214aff87c4b96426c2))
|
||||
* 阿里云证书订单支持获取2.0的订单 ([64b3184](https://github.com/certd/certd/commit/64b3184b286fee996002d857b0de588452abdadd))
|
||||
* 优化流水线执行时的状态保存性能 ([e00830b](https://github.com/certd/certd/commit/e00830bebcfe6344499e490bc174de96f9fb22d6))
|
||||
* 增加权威NS检查开关,某些用户服务器禁止向黑名单NS服务器发请求 ([1aa50cf](https://github.com/certd/certd/commit/1aa50cf53a0deab752f35ec973912e41ab8161b6))
|
||||
* 支持页脚自定义 ([c985a13](https://github.com/certd/certd/commit/c985a13544aa31b0eb0783f9a3193a7e8bdc6ed6))
|
||||
|
||||
## [1.39.11](https://github.com/certd/certd/compare/v1.39.10...v1.39.11) (2026-04-26)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -70,5 +70,5 @@
|
||||
"bugs": {
|
||||
"url": "https://github.com/publishlab/node-acme-client/issues"
|
||||
},
|
||||
"gitHead": "ec466dc818eace59825d8ae2ebbc9fc75a94a6b0"
|
||||
"gitHead": "898bc9b9f2f75df11ea0803b144862ba98b7511a"
|
||||
}
|
||||
|
||||
@@ -47,5 +47,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "ec466dc818eace59825d8ae2ebbc9fc75a94a6b0"
|
||||
"gitHead": "898bc9b9f2f75df11ea0803b144862ba98b7511a"
|
||||
}
|
||||
|
||||
@@ -45,5 +45,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "ec466dc818eace59825d8ae2ebbc9fc75a94a6b0"
|
||||
"gitHead": "898bc9b9f2f75df11ea0803b144862ba98b7511a"
|
||||
}
|
||||
|
||||
@@ -24,5 +24,5 @@
|
||||
"prettier": "^2.8.8",
|
||||
"tslib": "^2.8.1"
|
||||
},
|
||||
"gitHead": "ec466dc818eace59825d8ae2ebbc9fc75a94a6b0"
|
||||
"gitHead": "898bc9b9f2f75df11ea0803b144862ba98b7511a"
|
||||
}
|
||||
|
||||
@@ -31,5 +31,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "ec466dc818eace59825d8ae2ebbc9fc75a94a6b0"
|
||||
"gitHead": "898bc9b9f2f75df11ea0803b144862ba98b7511a"
|
||||
}
|
||||
|
||||
@@ -56,5 +56,5 @@
|
||||
"fetch"
|
||||
]
|
||||
},
|
||||
"gitHead": "ec466dc818eace59825d8ae2ebbc9fc75a94a6b0"
|
||||
"gitHead": "898bc9b9f2f75df11ea0803b144862ba98b7511a"
|
||||
}
|
||||
|
||||
@@ -33,5 +33,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "ec466dc818eace59825d8ae2ebbc9fc75a94a6b0"
|
||||
"gitHead": "898bc9b9f2f75df11ea0803b144862ba98b7511a"
|
||||
}
|
||||
|
||||
@@ -64,5 +64,5 @@
|
||||
"typeorm": "^0.3.11",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "ec466dc818eace59825d8ae2ebbc9fc75a94a6b0"
|
||||
"gitHead": "898bc9b9f2f75df11ea0803b144862ba98b7511a"
|
||||
}
|
||||
|
||||
@@ -46,5 +46,5 @@
|
||||
"typeorm": "^0.3.11",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "ec466dc818eace59825d8ae2ebbc9fc75a94a6b0"
|
||||
"gitHead": "898bc9b9f2f75df11ea0803b144862ba98b7511a"
|
||||
}
|
||||
|
||||
@@ -38,5 +38,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "ec466dc818eace59825d8ae2ebbc9fc75a94a6b0"
|
||||
"gitHead": "898bc9b9f2f75df11ea0803b144862ba98b7511a"
|
||||
}
|
||||
|
||||
@@ -57,5 +57,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "ec466dc818eace59825d8ae2ebbc9fc75a94a6b0"
|
||||
"gitHead": "898bc9b9f2f75df11ea0803b144862ba98b7511a"
|
||||
}
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
<template>
|
||||
<div class="flex">
|
||||
<a-input :value="valueRef" placeholder="请输入图片验证码" autocomplete="off" @update:value="onChange">
|
||||
<a-input :value="valueRef" :placeholder="t('certd.captcha.inputImageCode')" autocomplete="off" @update:value="onChange">
|
||||
<template #prefix>
|
||||
<fs-icon icon="ion:image-outline"></fs-icon>
|
||||
</template>
|
||||
</a-input>
|
||||
<div class="input-right pointer" title="点击刷新">
|
||||
<div class="input-right pointer" :title="t('certd.captcha.refresh')">
|
||||
<img class="image-code" :src="imageCodeSrc" @click="resetImageCode" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: any;
|
||||
@@ -20,6 +21,7 @@ const props = defineProps<{
|
||||
defineOptions({
|
||||
name: "ImageCaptcha",
|
||||
});
|
||||
const { t } = useI18n();
|
||||
const emit = defineEmits(["update:modelValue", "change"]);
|
||||
|
||||
const valueRef = ref("");
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
<div class="sweep-animation"></div>
|
||||
<div class="box-content">
|
||||
<div class="box-icon">✓</div>
|
||||
<span v-if="modelValue == null" class="status-text">点击进行验证</span>
|
||||
<span v-else class="status-text">验证成功</span>
|
||||
<span v-if="modelValue == null" class="status-text">{{ t("certd.captcha.clickToVerify") }}</span>
|
||||
<span v-else class="status-text">{{ t("certd.captcha.verifySuccess") }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -13,8 +13,10 @@
|
||||
<script setup lang="ts">
|
||||
import { notification } from "ant-design-vue";
|
||||
import { ref, Ref, watch } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
import { loadScript } from "vue-plugin-load-script";
|
||||
const { t } = useI18n();
|
||||
const loaded = ref(false);
|
||||
async function loadCaptchaScript() {
|
||||
// 加载验证码js
|
||||
@@ -56,7 +58,7 @@ function callback(res: { ret: number; ticket: string; randstr: string; errorCode
|
||||
|
||||
if (res.errorCode && res.errorCode > 0) {
|
||||
notification.error({
|
||||
message: `验证码验证失败:${res.errorMessage || res.errorCode}`,
|
||||
message: t("certd.captcha.verifyFailed", { message: res.errorMessage || res.errorCode }),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -83,13 +85,13 @@ function loadErrorCallback(error: any) {
|
||||
// errorMessage: "jsload_error",
|
||||
// });
|
||||
notification.error({
|
||||
message: `验证码加载失败:${error?.message || error}`,
|
||||
message: t("certd.captcha.loadFailed", { message: error?.message || error }),
|
||||
});
|
||||
}
|
||||
async function triggerCaptcha() {
|
||||
if (!loaded.value) {
|
||||
notification.error({
|
||||
message: "验证码还未加载完成,请稍后再试",
|
||||
message: t("certd.captcha.notLoaded"),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
+13
-11
@@ -4,7 +4,7 @@
|
||||
<!-- <td class="domain">-->
|
||||
<!-- {{ props.domain }}-->
|
||||
<!-- </td>-->
|
||||
<td class="host-record" :title="'域名:' + props.domain">
|
||||
<td class="host-record" :title="t('certd.verifyPlan.domainTitle', { domain: props.domain })">
|
||||
<fs-copyable v-model="cnameRecord.hostRecord"></fs-copyable>
|
||||
</td>
|
||||
<td style="text-align: center">CNAME</td>
|
||||
@@ -16,17 +16,17 @@
|
||||
<a-tooltip v-if="cnameRecord.error" :title="cnameRecord.error">
|
||||
<fs-icon class="ml-5 color-red" icon="ion:warning-outline"></fs-icon>
|
||||
</a-tooltip>
|
||||
<a-tooltip v-if="cnameRecord.status === 'valid'" title="重置校验状态,重新校验">
|
||||
<a-tooltip v-if="cnameRecord.status === 'valid'" :title="t('certd.verifyPlan.resetStatusTooltip')">
|
||||
<fs-icon class="ml-2 color-yellow text-md pointer" icon="solar:undo-left-square-bold" @click="resetStatus"></fs-icon>
|
||||
</a-tooltip>
|
||||
</td>
|
||||
<td class="center">
|
||||
<template v-if="cnameRecord.status !== 'valid'">
|
||||
<a-button type="primary" size="small" :loading="loading" @click="doVerify">点击验证</a-button>
|
||||
<a-button type="primary" size="small" :loading="loading" @click="doVerify">{{ t("certd.verifyPlan.clickToValidate") }}</a-button>
|
||||
<cname-tip :record="cnameRecord"></cname-tip>
|
||||
</template>
|
||||
|
||||
<div v-else class="helper" title="后续自动申请证书需要">不要删除CNAME</div>
|
||||
<div v-else class="helper" :title="t('certd.verifyPlan.keepCnameTitle')">{{ t("certd.verifyPlan.keepCname") }}</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -35,18 +35,20 @@
|
||||
<script lang="ts" setup>
|
||||
import { CnameRecord, GetByDomain } from "/@/components/plugins/cert/domains-verify-plan-editor/api";
|
||||
import { ref, watch } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { dict } from "@fast-crud/fast-crud";
|
||||
import * as api from "./api.js";
|
||||
import CnameTip from "./cname-tip.vue";
|
||||
import { Modal } from "ant-design-vue";
|
||||
import { utils } from "/@/utils/index.js";
|
||||
const { t } = useI18n();
|
||||
const statusDict = dict({
|
||||
data: [
|
||||
{ label: "待设置CNAME", value: "cname", color: "warning" },
|
||||
{ label: "验证中", value: "validating", color: "blue" },
|
||||
{ label: "验证成功", value: "valid", color: "green" },
|
||||
{ label: "验证失败", value: "failed", color: "red" },
|
||||
{ label: "验证超时", value: "timeout", color: "red" },
|
||||
{ label: t("certd.verifyPlan.status.pendingCname"), value: "cname", color: "warning" },
|
||||
{ label: t("certd.verifyPlan.status.validating"), value: "validating", color: "blue" },
|
||||
{ label: t("certd.verifyPlan.status.valid"), value: "valid", color: "green" },
|
||||
{ label: t("certd.verifyPlan.status.failed"), value: "failed", color: "red" },
|
||||
{ label: t("certd.verifyPlan.status.timeout"), value: "timeout", color: "red" },
|
||||
],
|
||||
});
|
||||
|
||||
@@ -125,8 +127,8 @@ async function doVerify() {
|
||||
|
||||
async function resetStatus() {
|
||||
Modal.confirm({
|
||||
title: "重置状态",
|
||||
content: "确定要重置校验状态吗?",
|
||||
title: t("certd.verifyPlan.resetStatus"),
|
||||
content: t("certd.verifyPlan.confirmResetStatus"),
|
||||
onOk: async () => {
|
||||
await api.ResetStatus(cnameRecord.value.id);
|
||||
await loadRecord();
|
||||
|
||||
+9
-7
@@ -2,17 +2,17 @@
|
||||
<a-tooltip :overlay-style="{ maxWidth: '400px' }">
|
||||
<template #title>
|
||||
<div>
|
||||
<div>多试几次,如果仍然无法验证通过,请按如下步骤排查问题:</div>
|
||||
<div>1. 解析记录应该添加在{{ record.domain }}域名下</div>
|
||||
<div>2. 要添加的是CNAME类型的记录,不是TXT</div>
|
||||
<div>3. 核对记录值是否是:{{ record.recordValue }}</div>
|
||||
<div>{{ t("certd.verifyPlan.cnameTip.intro") }}</div>
|
||||
<div>{{ t("certd.verifyPlan.cnameTip.step1", { domain: record.domain }) }}</div>
|
||||
<div>{{ t("certd.verifyPlan.cnameTip.step2") }}</div>
|
||||
<div>{{ t("certd.verifyPlan.cnameTip.step3", { value: record.recordValue }) }}</div>
|
||||
<div>
|
||||
4. 在验证中状态下,运行下面的命令,查看cname和txt解析是否正确
|
||||
{{ t("certd.verifyPlan.cnameTip.step4") }}
|
||||
<fs-copyable :style="{ color: '#52c41a' }" :model-value="nslookupCmd"></fs-copyable>
|
||||
或者
|
||||
{{ t("certd.verifyPlan.cnameTip.or") }}
|
||||
<fs-copyable :style="{ color: '#52c41a' }" :model-value="digCmd"></fs-copyable>
|
||||
</div>
|
||||
<div>5. 如果以上检查都没有问题,则可能是DNS解析生效时间比较慢,某些提供商延迟可能高达几个小时</div>
|
||||
<div>{{ t("certd.verifyPlan.cnameTip.step5") }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<fs-icon class="ml-5 pointer" icon="mingcute:question-line"></fs-icon>
|
||||
@@ -21,9 +21,11 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
const props = defineProps<{
|
||||
record: any;
|
||||
}>();
|
||||
const { t } = useI18n();
|
||||
|
||||
const nslookupCmd = computed(() => {
|
||||
return `nslookup -q=txt _acme-challenge.${props.record.domain}`;
|
||||
|
||||
+8
-5
@@ -2,11 +2,11 @@
|
||||
<table class="cname-verify-plan">
|
||||
<thead>
|
||||
<tr>
|
||||
<td style="width: 160px">主机记录</td>
|
||||
<td style="width: 100px; text-align: center">记录类型</td>
|
||||
<td style="width: 250px">请设置CNAME记录(验证成功以后不要删除)</td>
|
||||
<td style="width: 120px" class="center">状态</td>
|
||||
<td style="width: 90px" class="center">操作</td>
|
||||
<td style="width: 160px">{{ t("certd.verifyPlan.hostRecord") }}</td>
|
||||
<td style="width: 100px; text-align: center">{{ t("certd.verifyPlan.recordType") }}</td>
|
||||
<td style="width: 250px">{{ t("certd.verifyPlan.setCnameRecord") }}</td>
|
||||
<td style="width: 120px" class="center">{{ t("certd.status") }}</td>
|
||||
<td style="width: 90px" class="center">{{ t("certd.verifyPlan.operation") }}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<template v-for="key in domains" :key="key">
|
||||
@@ -19,11 +19,14 @@
|
||||
import { CnameRecord } from "/@/components/plugins/cert/domains-verify-plan-editor/api";
|
||||
import CnameRecordInfo from "/@/components/plugins/cert/domains-verify-plan-editor/cname-record-info.vue";
|
||||
import { computed } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
defineOptions({
|
||||
name: "CnameVerifyPlan",
|
||||
});
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const emit = defineEmits(["update:modelValue", "change"]);
|
||||
|
||||
const props = defineProps<{
|
||||
|
||||
+8
-5
@@ -2,10 +2,10 @@
|
||||
<table class="http-verify-plan">
|
||||
<thead>
|
||||
<tr>
|
||||
<td style="width: 160px">网站域名</td>
|
||||
<td style="width: 100px; text-align: center">上传方式</td>
|
||||
<td style="width: 150px">上传授权</td>
|
||||
<td style="width: 200px">网站根目录路径</td>
|
||||
<td style="width: 160px">{{ t("certd.verifyPlan.websiteDomain") }}</td>
|
||||
<td style="width: 100px; text-align: center">{{ t("certd.verifyPlan.uploadMethod") }}</td>
|
||||
<td style="width: 150px">{{ t("certd.verifyPlan.uploadAccess") }}</td>
|
||||
<td style="width: 200px">{{ t("certd.verifyPlan.websiteRootPath") }}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody v-if="records" class="http-record-body">
|
||||
@@ -21,7 +21,7 @@
|
||||
<access-selector v-model="item.httpUploaderAccess" :type="item.httpUploaderType" @change="onRecordChange"></access-selector>
|
||||
</td>
|
||||
<td>
|
||||
<a-input v-model:value="item.httpUploadRootDir" placeholder="网站根目录,如:/www/wwwroot" @change="onRecordChange"></a-input>
|
||||
<a-input v-model:value="item.httpUploadRootDir" :placeholder="t('certd.verifyPlan.websiteRootPlaceholder')" @change="onRecordChange"></a-input>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { Ref, ref, watch, nextTick } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { HttpRecord } from "/@/components/plugins/cert/domains-verify-plan-editor/type";
|
||||
import { dict } from "@fast-crud/fast-crud";
|
||||
import { Dicts } from "/@/components/plugins/lib/dicts";
|
||||
@@ -39,6 +40,8 @@ defineOptions({
|
||||
name: "HttpVerifyPlan",
|
||||
});
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const emit = defineEmits(["update:modelValue", "change"]);
|
||||
|
||||
const props = defineProps<{
|
||||
|
||||
+15
-12
@@ -5,7 +5,7 @@
|
||||
<div class="plan-box bg-white dark:bg-neutral-700">
|
||||
<div class="fullscreen-button pointer flex-center" @click="fullscreen = !fullscreen">
|
||||
<span v-if="!fullscreen" style="font-size: 10px" class="flex-center">
|
||||
这里可以放大
|
||||
{{ t("certd.verifyPlan.expandTip") }}
|
||||
<fs-icon icon="ion:arrow-forward-outline"></fs-icon>
|
||||
</span>
|
||||
<fs-icon :icon="fullscreen ? 'material-symbols:fullscreen-exit' : 'material-symbols:fullscreen'"></fs-icon>
|
||||
@@ -13,9 +13,9 @@
|
||||
<table class="plan-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="min-width: 100px">主域名</th>
|
||||
<th>验证方式</th>
|
||||
<th>验证计划</th>
|
||||
<th style="min-width: 100px">{{ t("certd.verifyPlan.mainDomain") }}</th>
|
||||
<th>{{ t("certd.verifyPlan.challengeType") }}</th>
|
||||
<th>{{ t("certd.verifyPlan.challengePlan") }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -30,13 +30,13 @@
|
||||
<div class="plan">
|
||||
<div v-if="item.type === 'dns'" class="plan-dns">
|
||||
<div class="form-item">
|
||||
<span class="label">DNS类型:</span>
|
||||
<span class="label">{{ t("certd.verifyPlan.dnsType") }}:</span>
|
||||
<span class="input">
|
||||
<fs-dict-select
|
||||
v-model:value="item.dnsProviderType"
|
||||
size="small"
|
||||
:dict="dnsProviderTypeDict"
|
||||
placeholder="DNS提供商"
|
||||
:placeholder="t('certd.verifyPlan.dnsProvider')"
|
||||
@change="onPlanChanged"
|
||||
@selected-change="onDnsProviderChange(item, $event)"
|
||||
></fs-dict-select>
|
||||
@@ -44,9 +44,9 @@
|
||||
</div>
|
||||
<a-divider type="vertical" />
|
||||
<div class="form-item">
|
||||
<span class="label">DNS授权:</span>
|
||||
<span class="label">{{ t("certd.verifyPlan.dnsAccess") }}:</span>
|
||||
<span class="input">
|
||||
<access-selector v-model="item.dnsProviderAccessId" size="small" :type="item.dnsProviderAccessType || item.dnsProviderType" placeholder="请选择" @change="onPlanChanged"></access-selector>
|
||||
<access-selector v-model="item.dnsProviderAccessId" size="small" :type="item.dnsProviderAccessType || item.dnsProviderType" :placeholder="t('certd.verifyPlan.pleaseSelect')" @change="onPlanChanged"></access-selector>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -55,7 +55,7 @@
|
||||
</div>
|
||||
<div v-if="item.type === 'http'" class="plan-http">
|
||||
<http-verify-plan v-model="item.httpVerifyPlan" @change="onPlanChanged" />
|
||||
<div class="helper">证书颁发机构将请求 https://yourdomain/.well-known/acme-challenge/xxxxxx 来验证域名所有权。</div>
|
||||
<div class="helper">{{ t("certd.verifyPlan.httpHelper") }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
@@ -72,6 +72,7 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { dict, FsDictSelect } from "@fast-crud/fast-crud";
|
||||
import AccessSelector from "/@/views/certd/access/access-selector/index.vue";
|
||||
import CnameVerifyPlan from "./cname-verify-plan.vue";
|
||||
@@ -84,17 +85,19 @@ defineOptions({
|
||||
name: "DomainsVerifyPlanEditor",
|
||||
});
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const challengeTypeOptions = ref<any[]>([
|
||||
{
|
||||
label: "DNS验证",
|
||||
label: t("certd.verifyPlan.dnsChallenge"),
|
||||
value: "dns",
|
||||
},
|
||||
{
|
||||
label: "CNAME验证",
|
||||
label: t("certd.verifyPlan.cnameChallenge"),
|
||||
value: "cname",
|
||||
},
|
||||
{
|
||||
label: "HTTP验证",
|
||||
label: t("certd.verifyPlan.httpChallenge"),
|
||||
value: "http",
|
||||
},
|
||||
]);
|
||||
|
||||
+7
-6
@@ -1,5 +1,6 @@
|
||||
import Validator from "async-validator";
|
||||
import { DomainsVerifyPlanInput } from "./type";
|
||||
import { $t } from "/@/locales";
|
||||
|
||||
function checkDomainVerifyPlan(rule: any, value: DomainsVerifyPlanInput) {
|
||||
if (value == null) {
|
||||
@@ -13,7 +14,7 @@ function checkDomainVerifyPlan(rule: any, value: DomainsVerifyPlanInput) {
|
||||
for (const subDomain of subDomains) {
|
||||
const plan = value[domain].cnameVerifyPlan[subDomain];
|
||||
if (plan.status !== "valid") {
|
||||
throw new Error(`域名${subDomain}的CNAME未验证通过,请先设置CNAME记录,点击验证按钮`);
|
||||
throw new Error($t("certd.verifyPlan.errors.cnameNotValid", { domain: subDomain }));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,7 +23,7 @@ function checkDomainVerifyPlan(rule: any, value: DomainsVerifyPlanInput) {
|
||||
for (const item of domains) {
|
||||
//如果有通配符域名则不允许使用http校验
|
||||
if (item.startsWith("*.")) {
|
||||
throw new Error(`域名${item}为通配符域名,不支持HTTP校验`);
|
||||
throw new Error($t("certd.verifyPlan.errors.wildcardNotSupportHttp", { domain: item }));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,19 +32,19 @@ function checkDomainVerifyPlan(rule: any, value: DomainsVerifyPlanInput) {
|
||||
for (const subDomain of subDomains) {
|
||||
const plan = value[domain].httpVerifyPlan[subDomain];
|
||||
if (!plan.httpUploaderType) {
|
||||
throw new Error(`域名${subDomain}的上传方式必须填写`);
|
||||
throw new Error($t("certd.verifyPlan.errors.uploadMethodRequired", { domain: subDomain }));
|
||||
}
|
||||
if (!plan.httpUploaderAccess) {
|
||||
throw new Error(`域名${subDomain}的上传授权信息必须填写`);
|
||||
throw new Error($t("certd.verifyPlan.errors.uploadAccessRequired", { domain: subDomain }));
|
||||
}
|
||||
if (!plan.httpUploadRootDir) {
|
||||
throw new Error(`域名${subDomain}的网站根路径必须填写`);
|
||||
throw new Error($t("certd.verifyPlan.errors.websiteRootRequired", { domain: subDomain }));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (type === "dns") {
|
||||
if (!value[domain].dnsProviderType || !value[domain].dnsProviderAccessId) {
|
||||
throw new Error(`DNS模式下,域名${domain}的DNS类型和授权信息必须填写`);
|
||||
throw new Error($t("certd.verifyPlan.errors.dnsProviderRequired", { domain }));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="api-test">
|
||||
<div>
|
||||
<fs-button :loading="loading" type="primary" text="测试" icon="ion:refresh-outline" @click="doTest"></fs-button>
|
||||
<fs-button :loading="loading" type="primary" :text="t('certd.pluginCommon.test')" icon="ion:refresh-outline" @click="doTest"></fs-button>
|
||||
</div>
|
||||
|
||||
<div class="helper" :class="{ error: hasError }">
|
||||
@@ -12,6 +12,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ComponentPropsType, doRequest } from "/@/components/plugins/lib";
|
||||
import { ref, inject } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { Form } from "ant-design-vue";
|
||||
import { getInputFromForm } from "./utils";
|
||||
|
||||
@@ -19,6 +20,8 @@ defineOptions({
|
||||
name: "ApiTest",
|
||||
});
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const fromType: any = inject("getFromType");
|
||||
const getScope: any = inject("get:scope");
|
||||
const getPluginType: any = inject("get:plugin:type", () => {
|
||||
@@ -61,14 +64,14 @@ const doTest = async () => {
|
||||
{
|
||||
onError(err: any) {
|
||||
hasError.value = true;
|
||||
message.value = `错误:${err.message}`;
|
||||
message.value = t("certd.pluginCommon.errorWithMessage", { message: err.message });
|
||||
},
|
||||
showErrorNotify: false,
|
||||
}
|
||||
);
|
||||
message.value = "测试请求成功";
|
||||
message.value = t("certd.pluginCommon.testRequestSuccess");
|
||||
if (res) {
|
||||
message.value += `,返回:${JSON.stringify(res)}`;
|
||||
message.value += t("certd.pluginCommon.responseSuffix", { response: JSON.stringify(res) });
|
||||
}
|
||||
} finally {
|
||||
loading.value = false;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { inject, ref, watch } from "vue";
|
||||
import { useI18n } from "/@/locales";
|
||||
|
||||
defineOptions({
|
||||
name: "CertDomainsGetter",
|
||||
@@ -24,6 +25,7 @@ const emit = defineEmits<{
|
||||
}>();
|
||||
|
||||
const pipeline: any = inject("pipeline");
|
||||
const { t } = useI18n();
|
||||
|
||||
function findStepFromPipeline(targetStepId: string) {
|
||||
for (const stage of pipeline.value.stages) {
|
||||
@@ -40,7 +42,7 @@ function findStepFromPipeline(targetStepId: string) {
|
||||
const errorRef = ref("");
|
||||
function getStepIdFromInputKey(inputKey: string) {
|
||||
if (!inputKey) {
|
||||
errorRef.value = "请先选择域名证书";
|
||||
errorRef.value = t("certd.pluginCommon.selectCertFirst");
|
||||
return;
|
||||
}
|
||||
return inputKey.split(".")[1];
|
||||
@@ -49,7 +51,7 @@ function getDomainFromPipeline(inputKey: string) {
|
||||
let targetStepId = getStepIdFromInputKey(inputKey);
|
||||
let certStep = findStepFromPipeline(targetStepId);
|
||||
if (!certStep) {
|
||||
errorRef.value = "找不到目标步骤,请先选择域名证书";
|
||||
errorRef.value = t("certd.pluginCommon.targetStepNotFound");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -58,7 +60,7 @@ function getDomainFromPipeline(inputKey: string) {
|
||||
targetStepId = getStepIdFromInputKey(firstLevelValue);
|
||||
certStep = findStepFromPipeline(targetStepId);
|
||||
if (!certStep) {
|
||||
errorRef.value = "找不到目标步骤,请先选择域名证书";
|
||||
errorRef.value = t("certd.pluginCommon.targetStepNotFound");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,12 +17,12 @@
|
||||
<template v-if="search">
|
||||
<div class="flex w-full items-center justify-between flex-wrap" style="padding: 4px 8px">
|
||||
<div class="flex-1 flex flex-row items-center">
|
||||
<a-input ref="inputRef" v-model:value="searchKeyRef" class="flex-1" allow-clear placeholder="这里可以搜索域名(数据来自“设置->域名管理”),您也可以直接在上面输入框输入" @keydown.enter="doSearch" />
|
||||
<fs-button type="primary" class="m-1" :loading="loading" icon="mingcute:search-2-line" @click="doSearch"> 查询 </fs-button>
|
||||
<a-input ref="inputRef" v-model:value="searchKeyRef" class="flex-1" allow-clear :placeholder="t('certd.pluginCommon.domainSearchPlaceholder')" @keydown.enter="doSearch" />
|
||||
<fs-button type="primary" class="m-1" :loading="loading" icon="mingcute:search-2-line" @click="doSearch">{{ t("certd.pluginCommon.search") }}</fs-button>
|
||||
</div>
|
||||
<div class="manager flex flex-row items-center">
|
||||
<fs-button type="primary" class="m-1" icon="mingcute:vip-1-line" @click="openDomainImportDialog">导入域名</fs-button>
|
||||
<fs-button class="m-1" type="primary" icon="carbon:gui-management" @click="openDomainManager">管理域名</fs-button>
|
||||
<fs-button type="primary" class="m-1" icon="mingcute:vip-1-line" @click="openDomainImportDialog">{{ t("certd.pluginCommon.importDomain") }}</fs-button>
|
||||
<fs-button class="m-1" type="primary" icon="carbon:gui-management" @click="openDomainManager">{{ t("certd.pluginCommon.manageDomain") }}</fs-button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="hasError" class="helper p-2" :class="{ error: hasError }">
|
||||
@@ -47,7 +47,7 @@
|
||||
</template>
|
||||
</a-select>
|
||||
<div class="ml-5">
|
||||
<fs-button :loading="loading" title="刷新我的域名列表" icon="ion:refresh-outline" @click="refreshOptions"></fs-button>
|
||||
<fs-button :loading="loading" :title="t('certd.pluginCommon.refreshMyDomains')" icon="ion:refresh-outline" @click="refreshOptions"></fs-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="helper" :class="{ error: hasError }">
|
||||
@@ -57,6 +57,7 @@
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { computed, defineComponent, onMounted, ref, Ref, useAttrs } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useRouter } from "vue-router";
|
||||
import { Dicts } from "../lib/dicts";
|
||||
import { request } from "/@/api/service";
|
||||
@@ -67,6 +68,8 @@ defineOptions({
|
||||
name: "DomainSelector",
|
||||
});
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const VNodes = defineComponent({
|
||||
props: {
|
||||
vnodes: {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<a-auto-complete class="remote-auto-complete-input" :filter-option="filterOption" :options="optionsRef" :value="value" v-bind="attrs" @click="onClick" @update:value="emit('update:value', $event)">
|
||||
</a-auto-complete>
|
||||
<div class="ml-5">
|
||||
<fs-button :loading="loading" title="刷新选项" icon="ion:refresh-outline" @click="refreshOptions"></fs-button>
|
||||
<fs-button :loading="loading" :title="t('certd.pluginCommon.refreshOptions')" icon="ion:refresh-outline" @click="refreshOptions"></fs-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="helper" :class="{ error: hasError }">
|
||||
@@ -15,6 +15,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ComponentPropsType, doRequest } from "/@/components/plugins/lib";
|
||||
import { defineComponent, inject, ref, useAttrs, watch, Ref } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { PluginDefine } from "@certd/pipeline";
|
||||
import { getInputFromForm } from "./utils";
|
||||
|
||||
@@ -22,6 +23,8 @@ defineOptions({
|
||||
name: "RemoteAutoComplete",
|
||||
});
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const props = defineProps<
|
||||
{
|
||||
watches?: string[];
|
||||
@@ -93,16 +96,16 @@ const getOptions = async () => {
|
||||
{
|
||||
onError(err: any) {
|
||||
hasError.value = true;
|
||||
message.value = `获取选项出错:${err.message}`;
|
||||
message.value = t("certd.pluginCommon.getOptionsError", { message: err.message });
|
||||
},
|
||||
showErrorNotify: false,
|
||||
}
|
||||
);
|
||||
const list = res?.list || res || [];
|
||||
if (list.length > 0) {
|
||||
message.value = "获取数据成功,请从下拉框中选择";
|
||||
message.value = t("certd.pluginCommon.getDataSuccessSelect");
|
||||
} else {
|
||||
message.value = "获取数据成功,没有数据";
|
||||
message.value = t("certd.pluginCommon.getDataSuccessEmpty");
|
||||
}
|
||||
optionsRef.value = list;
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<script setup lang="ts">
|
||||
import { doRequest } from "/@/components/plugins/lib";
|
||||
import { inject, ref, useAttrs } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useFormWrapper } from "@fast-crud/fast-crud";
|
||||
import { notification } from "ant-design-vue";
|
||||
import { getInputFromForm } from "./utils";
|
||||
@@ -15,6 +16,7 @@ defineOptions({
|
||||
name: "RemoteInput",
|
||||
});
|
||||
const { openCrudFormDialog } = useFormWrapper();
|
||||
const { t } = useI18n();
|
||||
const props = defineProps<{
|
||||
modelValue: string;
|
||||
title: string;
|
||||
@@ -53,7 +55,7 @@ async function openDialog() {
|
||||
saveRemind: false,
|
||||
},
|
||||
afterSubmit() {
|
||||
notification.success({ message: "操作成功" });
|
||||
notification.success({ message: t("certd.operationSuccess") });
|
||||
},
|
||||
async doSubmit({ form }: any) {
|
||||
return await doPluginFormSubmit(form);
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
<template #dropdownRender="{ menuNode: menu }">
|
||||
<template v-if="search">
|
||||
<div class="flex w-full" style="padding: 4px 8px">
|
||||
<a-input ref="inputRef" v-model:value="searchKeyRef" class="flex-1" allow-clear placeholder="查询关键字" @keydown.enter="doSearch" />
|
||||
<a-input ref="inputRef" v-model:value="searchKeyRef" class="flex-1" allow-clear :placeholder="t('certd.pluginCommon.searchKeyword')" @keydown.enter="doSearch" />
|
||||
<a-button class="ml-2" :loading="loading" type="text" @click="doSearch">
|
||||
<template #icon>
|
||||
<search-outlined />
|
||||
</template>
|
||||
查询
|
||||
{{ t("certd.pluginCommon.search") }}
|
||||
</a-button>
|
||||
</div>
|
||||
<div v-if="hasError" class="helper p-2" :class="{ error: hasError }">
|
||||
@@ -26,7 +26,7 @@
|
||||
</template>
|
||||
</a-select>
|
||||
<div class="ml-5 flex flex-row no-wrap">
|
||||
<fs-button :loading="loading" title="刷新选项" icon="ion:refresh-outline" @click="refreshOptions"></fs-button>
|
||||
<fs-button :loading="loading" :title="t('certd.pluginCommon.refreshOptions')" icon="ion:refresh-outline" @click="refreshOptions"></fs-button>
|
||||
<UploadCert v-if="uploadCert" class="ml-5" v-bind="uploadCert" @submit="refreshOptions"></UploadCert>
|
||||
</div>
|
||||
</div>
|
||||
@@ -38,6 +38,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ComponentPropsType, doRequest } from "/@/components/plugins/lib";
|
||||
import { defineComponent, inject, ref, useAttrs, watch, Ref } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { PluginDefine } from "@certd/pipeline";
|
||||
import { getInputFromForm } from "./utils";
|
||||
import UploadCert from "./upload-cert.vue";
|
||||
@@ -47,6 +48,8 @@ defineOptions({
|
||||
name: "RemoteSelect",
|
||||
});
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const selectRef = ref(null);
|
||||
|
||||
const VNodes = defineComponent({
|
||||
@@ -161,7 +164,7 @@ const getOptions = async () => {
|
||||
{
|
||||
onError(err: any) {
|
||||
hasError.value = true;
|
||||
message.value = `获取选项出错:${err.message}`;
|
||||
message.value = t("certd.pluginCommon.getOptionsError", { message: err.message });
|
||||
optionsRef.value = [];
|
||||
},
|
||||
showErrorNotify: false,
|
||||
@@ -169,9 +172,9 @@ const getOptions = async () => {
|
||||
);
|
||||
let list = res?.list || res || [];
|
||||
if (list.length > 0) {
|
||||
message.value = "获取数据成功,请从下拉框中选择";
|
||||
message.value = t("certd.pluginCommon.getDataSuccessSelect");
|
||||
} else {
|
||||
message.value = "获取数据成功,没有数据";
|
||||
message.value = t("certd.pluginCommon.getDataSuccessEmpty");
|
||||
}
|
||||
list = list.map((item: any) => {
|
||||
return {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<div class="flex flex-row">
|
||||
<a-tree-select class="remote-tree-select-input" :tree-data="optionsRef" :value="value" tree-checkable allow-clear v-bind="attrs" @click="onClick" @update:value="emit('update:value', $event)"> </a-tree-select>
|
||||
<div class="ml-5">
|
||||
<fs-button :loading="loading" title="刷新选项" icon="ion:refresh-outline" @click="refreshOptions"></fs-button>
|
||||
<fs-button :loading="loading" :title="t('certd.pluginCommon.refreshOptions')" icon="ion:refresh-outline" @click="refreshOptions"></fs-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="helper" :class="{ error: hasError }">
|
||||
@@ -14,6 +14,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ComponentPropsType, doRequest } from "/@/components/plugins/lib";
|
||||
import { defineComponent, inject, ref, useAttrs, watch, Ref } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { PluginDefine } from "@certd/pipeline";
|
||||
import { getInputFromForm } from "./utils";
|
||||
|
||||
@@ -21,6 +22,8 @@ defineOptions({
|
||||
name: "RemoteTreeSelect",
|
||||
});
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const props = defineProps<
|
||||
{
|
||||
watches: string[];
|
||||
@@ -104,16 +107,16 @@ const getOptions = async () => {
|
||||
{
|
||||
onError(err: any) {
|
||||
hasError.value = true;
|
||||
message.value = `获取选项出错:${err.message}`;
|
||||
message.value = t("certd.pluginCommon.getOptionsError", { message: err.message });
|
||||
},
|
||||
showErrorNotify: false,
|
||||
}
|
||||
);
|
||||
const list = res?.list || res || [];
|
||||
if (list.length > 0) {
|
||||
message.value = "获取数据成功,请从下拉框中选择";
|
||||
message.value = t("certd.pluginCommon.getDataSuccessSelect");
|
||||
} else {
|
||||
message.value = "获取数据成功,没有数据";
|
||||
message.value = t("certd.pluginCommon.getDataSuccessEmpty");
|
||||
}
|
||||
optionsRef.value = list;
|
||||
pagerRef.value.total = list.length;
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
<template>
|
||||
<div class="upload-cert">
|
||||
<fs-button v-model:loading="loading" type="primary" text="上传" v-bind="props.button" @click="openUploadCertDialog"></fs-button>
|
||||
<fs-button v-model:loading="loading" type="primary" :text="t('certd.pluginCommon.upload')" v-bind="props.button" @click="openUploadCertDialog"></fs-button>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { message } from "ant-design-vue";
|
||||
import { useFormDialog } from "../../../use/use-dialog";
|
||||
import { computed, inject, ref } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { doRequest } from "../lib";
|
||||
import { getInputFromForm } from "./utils";
|
||||
import { UploadCertProps } from "./types";
|
||||
@@ -14,6 +15,7 @@ import { merge } from "lodash-es";
|
||||
|
||||
const props = defineProps<UploadCertProps>();
|
||||
const loading = ref(false);
|
||||
const { t } = useI18n();
|
||||
|
||||
const emit = defineEmits(["submit"]);
|
||||
const { openFormDialog } = useFormDialog();
|
||||
@@ -28,18 +30,18 @@ const getScope: any = inject("get:scope", () => {
|
||||
const getPluginType: any = inject("get:plugin:type", () => {
|
||||
return "plugin";
|
||||
});
|
||||
const title = computed(() => props.title || "上传证书");
|
||||
const title = computed(() => props.title || t("certd.pluginCommon.uploadCert"));
|
||||
function openUploadCertDialog() {
|
||||
const columns = merge(
|
||||
{
|
||||
certName: {
|
||||
title: "证书名称",
|
||||
title: t("certd.pluginCommon.certName"),
|
||||
form: {
|
||||
component: {
|
||||
name: "a-input",
|
||||
vModel: "value",
|
||||
},
|
||||
helper: "上传后证书显示名称",
|
||||
helper: t("certd.pluginCommon.certNameHelper"),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -49,7 +51,7 @@ function openUploadCertDialog() {
|
||||
title: title.value,
|
||||
columns: {
|
||||
certName: {
|
||||
title: "证书名称",
|
||||
title: t("certd.pluginCommon.certName"),
|
||||
form: {
|
||||
component: {
|
||||
name: "a-input",
|
||||
@@ -84,7 +86,7 @@ function openUploadCertDialog() {
|
||||
showErrorNotify: true,
|
||||
}
|
||||
);
|
||||
message.success("上传成功");
|
||||
message.success(t("certd.pluginCommon.uploadSuccess"));
|
||||
emit("submit");
|
||||
} finally {
|
||||
loading.value = false;
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
import { dict } from "@fast-crud/fast-crud";
|
||||
import { $t } from "/@/locales";
|
||||
|
||||
export const Dicts = {
|
||||
sslProviderDict: dict({
|
||||
data: [
|
||||
{ value: "letsencrypt", label: "Let‘s Encrypt" },
|
||||
{ value: "letsencrypt", label: "Let's Encrypt" },
|
||||
{ value: "zerossl", label: "ZeroSSL" },
|
||||
],
|
||||
}),
|
||||
challengeTypeDict: dict({
|
||||
data: [
|
||||
{ value: "dns", label: "DNS校验", color: "green" },
|
||||
{ value: "cname", label: "CNAME代理校验", color: "blue" },
|
||||
{ value: "http", label: "HTTP校验", color: "yellow" },
|
||||
{ value: "dns", label: $t("certd.verifyPlan.dnsChallenge"), color: "green" },
|
||||
{ value: "cname", label: $t("certd.verifyPlan.cnameProxyChallenge"), color: "blue" },
|
||||
{ value: "http", label: $t("certd.verifyPlan.httpChallenge"), color: "yellow" },
|
||||
],
|
||||
}),
|
||||
dnsProviderTypeDict: dict({
|
||||
@@ -22,17 +23,17 @@ export const Dicts = {
|
||||
{ label: "SFTP", value: "sftp" },
|
||||
{ label: "SCP", value: "scp" },
|
||||
{ label: "FTP", value: "ftp" },
|
||||
{ label: "阿里云OSS", value: "alioss" },
|
||||
{ label: "腾讯云COS", value: "tencentcos" },
|
||||
{ label: "七牛OSS", value: "qiniuoss" },
|
||||
{ label: $t("certd.verifyPlan.uploader.aliyunOss"), value: "alioss" },
|
||||
{ label: $t("certd.verifyPlan.uploader.tencentCos"), value: "tencentcos" },
|
||||
{ label: $t("certd.verifyPlan.uploader.qiniuOss"), value: "qiniuoss" },
|
||||
{ label: "S3/Minio", value: "s3" },
|
||||
{ label: "SSH(已废弃,请选择SFTP方式)", value: "ssh", disabled: true },
|
||||
{ label: $t("certd.verifyPlan.uploader.sshDeprecated"), value: "ssh", disabled: true },
|
||||
],
|
||||
}),
|
||||
domainFromTypeDict: dict({
|
||||
data: [
|
||||
{ value: "manual", label: "手动" },
|
||||
{ value: "auto", label: "自动" },
|
||||
{ value: "manual", label: $t("certd.verifyPlan.domainFrom.manual") },
|
||||
{ value: "auto", label: $t("certd.verifyPlan.domainFrom.auto") },
|
||||
],
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -1,873 +1,46 @@
|
||||
//注意: @符号是保留字符,需要用{'@'}替换, AI请务必提醒我修改
|
||||
import common from "./certd/common";
|
||||
import navigation from "./certd/navigation";
|
||||
import dashboard from "./certd/dashboard";
|
||||
import pipeline from "./certd/pipeline";
|
||||
import history from "./certd/history";
|
||||
import monitor from "./certd/monitor";
|
||||
import certdomain from "./certd/cert-domain";
|
||||
import cname from "./certd/cname";
|
||||
import access from "./certd/access";
|
||||
import open from "./certd/open";
|
||||
import mine from "./certd/mine";
|
||||
import notification from "./certd/notification";
|
||||
import addon from "./certd/addon";
|
||||
import suite from "./certd/suite";
|
||||
import project from "./certd/project";
|
||||
import syssettings from "./certd/sys-settings";
|
||||
import sysplugin from "./certd/sys-plugin";
|
||||
import sysauthority from "./certd/sys-authority";
|
||||
import syscname from "./certd/sys-cname";
|
||||
import tutorial from "./certd/tutorial";
|
||||
import cron from "./certd/cron";
|
||||
|
||||
// Note: @ is reserved in locale messages; use {'@'} when needed.
|
||||
export default {
|
||||
app: {
|
||||
crud: {
|
||||
i18n: {
|
||||
name: "name",
|
||||
city: "city",
|
||||
status: "status",
|
||||
},
|
||||
},
|
||||
},
|
||||
fs: {
|
||||
rowHandle: {
|
||||
title: "Operation",
|
||||
},
|
||||
},
|
||||
pipelinePage: {
|
||||
addMore: "Add More Pipelines",
|
||||
aliyunSubscriptionPipeline: "Aliyun Subscription Pipeline",
|
||||
legoCertPipeline: "Lego Certificate Pipeline",
|
||||
customPipeline: "Custom Pipeline",
|
||||
batchAddPipeline: "Add Pipeline Use Template",
|
||||
myPipelinesDesc: "Pipeline Mode: Apply -> Deploy -> Schedule",
|
||||
},
|
||||
order: {
|
||||
confirmTitle: "Order Confirmation",
|
||||
package: "Package",
|
||||
description: "Description",
|
||||
specifications: "Specifications",
|
||||
pipeline: "Pipeline",
|
||||
domain: "Domain",
|
||||
deployTimes: "Deployments",
|
||||
monitorCount: "DomainMonitors",
|
||||
duration: "Duration",
|
||||
price: "Price",
|
||||
paymentMethod: "Payment Method",
|
||||
free: "Free",
|
||||
unit: {
|
||||
pieces: "pieces",
|
||||
count: "count",
|
||||
times: "times",
|
||||
},
|
||||
},
|
||||
framework: {
|
||||
title: "Framework",
|
||||
home: "Home",
|
||||
},
|
||||
helpDocLink: "Help Docs",
|
||||
title: "Certificate Automation",
|
||||
pipeline: "Pipeline",
|
||||
pipelineEdit: "Edit Pipeline",
|
||||
history: "Execution History",
|
||||
certStore: "Certificate Repository",
|
||||
siteMonitor: "Site Certificate Monitor",
|
||||
settings: "Settings",
|
||||
accessManager: "Access Management",
|
||||
cnameRecord: "CNAME Record Management",
|
||||
subDomain: "Subdomain Delegation Settings",
|
||||
pipelineGroup: "Pipeline Group Management",
|
||||
openKey: "Open API Key",
|
||||
notification: "Notification Settings",
|
||||
siteMonitorSetting: "Site Monitor Settings",
|
||||
userSecurity: "Security Settings",
|
||||
userProfile: "Account Info",
|
||||
userGrant: "Grant Delegation",
|
||||
suite: "Suite",
|
||||
mySuite: "My Suite",
|
||||
suiteBuy: "Suite Purchase",
|
||||
myTrade: "My Orders",
|
||||
paymentReturn: "Payment Return",
|
||||
hasExpired: "Expired",
|
||||
user: {
|
||||
greeting: "Hello",
|
||||
profile: "Account Info",
|
||||
logout: "Logout",
|
||||
setting: {
|
||||
grantSetting: "Grant Settings",
|
||||
saveSuccess: "Save Success",
|
||||
allowAdminViewCerts: "Allow Admin view and download Certs",
|
||||
allowAdminViewCertsHelper: "Allow admin view and download all certificates",
|
||||
},
|
||||
},
|
||||
dashboard: {
|
||||
greeting: "Hello, {name}, welcome to 【{site}】",
|
||||
latestVersion: "Latest version: {version}",
|
||||
validUntil: "Valid until:",
|
||||
tutorialTooltip: "Click to view detailed tutorial",
|
||||
tutorialText: "Only 3 steps to automatically apply and deploy certificates",
|
||||
alertMessage: "Certificates and credentials are sensitive. Do not use untrusted online Certd services or images. Always self-host and use official release channels:",
|
||||
helpDoc: "Help Docs",
|
||||
pipelineCount: "Number of Certificate Pipelines",
|
||||
noPipeline: "You have no certificate pipelines yet",
|
||||
enabledCount: "Enabled",
|
||||
disabledCount: "Disabled",
|
||||
certCount: "Number of Certificates",
|
||||
noCert: "You have no certificates yet",
|
||||
manageCert: "View Certificates",
|
||||
certExpiringCount: "Soon-to-Expire",
|
||||
certExpiredCount: "Expired",
|
||||
certNoExpireCount: "Not Expired",
|
||||
createNow: "Create Now",
|
||||
managePipeline: "Manage Pipelines",
|
||||
pipelineStatus: "Pipeline Status",
|
||||
recentRun: "Recent Run Statistics",
|
||||
runCount: "Run Count",
|
||||
expiringCerts: "Soon-to-Expire Certificates",
|
||||
supportedTasks: "Overview of Supported Deployment Tasks",
|
||||
changeLog: "Change Log",
|
||||
},
|
||||
steps: {
|
||||
createPipeline: "Create Certificate Pipeline",
|
||||
addTask: "Add Deployment Task",
|
||||
scheduledRun: "Scheduled Run",
|
||||
},
|
||||
customPipeline: "Custom Pipeline",
|
||||
createCertdPipeline: "Create Certificate Pipeline",
|
||||
commercialCertHosting: "Commercial Certificate Hosting",
|
||||
tooltip: {
|
||||
manualUploadOwnCert: "Manually upload your own certificate for automatic deployment",
|
||||
noAutoApplyCommercialCert: "Does not automatically apply for commercial certificates",
|
||||
manualUploadOnUpdate: "Must manually upload once when the certificate is updated",
|
||||
},
|
||||
table: {
|
||||
confirmDeleteTitle: "Are you sure you want to delete?",
|
||||
confirmDeleteMessage: "This will delete all data related to the pipeline, including execution history, certificate files, and certificate repository records.",
|
||||
},
|
||||
play: {
|
||||
runPipeline: "Run Pipeline",
|
||||
confirm: "Confirm",
|
||||
confirmTrigger: "Are you sure you want to trigger the run?",
|
||||
pipelineStarted: "Pipeline has started running",
|
||||
},
|
||||
actions: {
|
||||
editPipeline: "Edit Pipeline",
|
||||
editConfigGroup: "Modify Configuration/Group",
|
||||
viewCertificate: "View Certificate",
|
||||
downloadCertificate: "Download Certificate",
|
||||
},
|
||||
fields: {
|
||||
userId: "User ID",
|
||||
pipelineName: "Pipeline Name",
|
||||
keyword: "Keyword",
|
||||
required: "This field is required",
|
||||
pipelineContent: "Pipeline Content",
|
||||
scheduledTaskCount: "Scheduled Task Count",
|
||||
deployTaskCount: "Deployment Task Count",
|
||||
remainingValidity: "Remaining Validity",
|
||||
effectiveTime: "Effective time",
|
||||
expiryTime: "Expiry Time",
|
||||
status: "Status",
|
||||
lastRun: "Last Run",
|
||||
enabled: "Enabled",
|
||||
enabledLabel: "Enabled",
|
||||
disabledLabel: "Disabled",
|
||||
group: "Group",
|
||||
type: "Type",
|
||||
order: "Order Number",
|
||||
keepHistoryCount: "History Record Retention Count",
|
||||
keepHistoryHelper: "Number of history records to keep; excess will be deleted",
|
||||
createTime: "Creation Time",
|
||||
updateTime: "Update Time",
|
||||
triggerType: "Trigger Type",
|
||||
pipelineId: "Pipeline Id",
|
||||
nextRunTime: "Next Run Time",
|
||||
projectName: "Project",
|
||||
adminId: "Admin",
|
||||
},
|
||||
|
||||
pi: {
|
||||
validTime: "Piepline Valid Time",
|
||||
validTimeHelper: "Not filled in means permanent validity",
|
||||
},
|
||||
types: {
|
||||
certApply: "Cert Apply",
|
||||
certUpload: "Cert Upload",
|
||||
custom: "Custom",
|
||||
template: "Template",
|
||||
},
|
||||
myPipelines: "My Pipelines",
|
||||
selectedCount: "Selected {count} items",
|
||||
batchDelete: "Batch Delete",
|
||||
batchForceRerun: "Force Rerun",
|
||||
batchRerun: "Rerun",
|
||||
applyCertificate: "Apply for Certificate",
|
||||
pipelineExecutionRecords: "Pipeline Execution Records",
|
||||
confirm: "Confirm",
|
||||
confirmBatchDeleteContent: "Are you sure you want to batch delete these {count} records?",
|
||||
deleteSuccess: "Delete successful",
|
||||
pleaseSelectRecords: "Please select records first",
|
||||
triggerTypes: {
|
||||
manual: "Manual Execution",
|
||||
timer: "Scheduled Execution",
|
||||
},
|
||||
sysResources: {
|
||||
sysRoot: "System Management",
|
||||
sysConsole: "Console",
|
||||
sysSettings: "System Settings",
|
||||
cnameSetting: "CNAME Service Settings",
|
||||
emailSetting: "Email Server Settings",
|
||||
siteSetting: "Site Personalization",
|
||||
headerMenus: "Top Menu Settings",
|
||||
sysAccess: "System-level Authorization",
|
||||
sysPlugin: "Plugin Management",
|
||||
sysPluginEdit: "Edit Plugin",
|
||||
sysPluginConfig: "Certificate Plugin Configuration",
|
||||
accountBind: "Account Binding",
|
||||
permissionManager: "Permission Management",
|
||||
roleManager: "Role Management",
|
||||
userManager: "User Management",
|
||||
suiteManager: "Suite Management",
|
||||
suiteSetting: "Suite Settings",
|
||||
orderManager: "Order Management",
|
||||
userSuites: "User Suites",
|
||||
netTest: "Network Test",
|
||||
|
||||
enterpriseSetting: "Enterprise Settings",
|
||||
projectManager: "Project Management",
|
||||
projectUserManager: "Project User Management",
|
||||
myProjectManager: "My Projects",
|
||||
myProjectDetail: "Project Detail",
|
||||
projectJoin: "Join Project",
|
||||
currentProject: "Current Project",
|
||||
projectMemberManager: "Project Member",
|
||||
domainMonitorSetting: "Domain Monitor Settings",
|
||||
},
|
||||
certificateRepo: {
|
||||
title: "Certificate Repository",
|
||||
sub: "Certificates generated from pipeline",
|
||||
},
|
||||
|
||||
certificateNotGenerated: "Certificate not yet generated, please run the pipeline first",
|
||||
viewCertificateTitle: "View Certificate",
|
||||
close: "Close",
|
||||
viewCert: {
|
||||
title: "View Certificate",
|
||||
},
|
||||
download: {
|
||||
title: "Download Certificate",
|
||||
},
|
||||
source: "Source Code",
|
||||
github: "GitHub",
|
||||
gitee: "Gitee",
|
||||
cron: {
|
||||
clearTip: "Clear Selection",
|
||||
nextTrigger: "Next Trigger Time",
|
||||
tip: "Please set a valid cron expression first",
|
||||
},
|
||||
cronForm: {
|
||||
title: "Scheduled Script",
|
||||
helper: "Click the button above to select the time for daily execution.\nIt is recommended to run once a day. Tasks will be skipped if the certificate is not expiring.",
|
||||
required: "This field is required",
|
||||
},
|
||||
email: {
|
||||
title: "Recipient Email",
|
||||
helper: "Enter your recipient email addresses. Multiple addresses are supported.",
|
||||
required: "This field is required",
|
||||
},
|
||||
plugin: {
|
||||
selectTitle: "Certificate Apply Plugin",
|
||||
jsAcme: "JS-ACME: Easy to use, powerful features [Recommended]",
|
||||
legoAcme: "Lego-ACME: Based on Lego, supports a wide range of DNS providers, suitable for users familiar with Lego",
|
||||
aliyunOrder: "Aliyun-Order: Get certificate from Aliyun certificate order",
|
||||
},
|
||||
pipelineForm: {
|
||||
createTitle: "Create Certificate Pipeline",
|
||||
moreParams: "More Parameters",
|
||||
triggerCronTitle: "Scheduled Trigger",
|
||||
triggerCronHelper:
|
||||
"Click the button above to choose a daily execution time.\nIt is recommended to trigger once per day. The task will be skipped if the certificate has not expired and will not be executed repeatedly.",
|
||||
notificationTitle: "Failure Notification",
|
||||
notificationWhen: "Notification Timing",
|
||||
notificationHelper: "Get real-time alerts when the task fails",
|
||||
groupIdTitle: "Pipeline Group",
|
||||
|
||||
addToMonitorEnabled: "Add to Cert Monitor",
|
||||
addToMonitorDomains: "Add to Monitor Domains",
|
||||
|
||||
webhookEnabled: "Webhook Enabled",
|
||||
webhookEnabledHelper: "Support webhook trigger pipeline, please check webhook address in trigger source",
|
||||
},
|
||||
notificationDefault: "Use Default Notification",
|
||||
checkStatus: {
|
||||
success: "Success",
|
||||
checking: "Checking",
|
||||
error: "Error",
|
||||
},
|
||||
domainList: {
|
||||
title: "Domain List",
|
||||
helper: "Format: domain:port:name:remark, one per line. Port and name are optional.\nExamples:\nwww.baidu.com:443:Baidu:remarkText\nwww.taobao.com::Taobao\nwww.google.com",
|
||||
required: "Please enter domains to import",
|
||||
placeholder: "www.baidu.com:443:Baidu\nwww.taobao.com::Taobao\nwww.google.com\n",
|
||||
},
|
||||
accountInfo: "Account Information",
|
||||
securitySettings: "Security & Settings",
|
||||
confirmDisable2FA: "Are you sure you want to disable two-factor authentication login?",
|
||||
disabledSuccess: "Disabled successfully",
|
||||
saveSuccess: "Saved successfully",
|
||||
twoFactorAuth: "2FA Two-Factor Authentication Login",
|
||||
rebind: "Rebind",
|
||||
twoFactorAuthHelper: "Enable or disable two-factor authentication login",
|
||||
bindDevice: "Bind Device",
|
||||
step1: "1. Install any authenticator app, for example:",
|
||||
tooltipGoogleServiceError: "If you get a Google service not found error, you can install KK Google Assistant",
|
||||
step2: "2. Scan the QR code to add the account",
|
||||
step3: "3. Enter the verification code",
|
||||
inputVerifyCode: "Please enter the verification code",
|
||||
cancel: "Cancel",
|
||||
authorizationManagement: "Authorization Management",
|
||||
manageThirdPartyAuth: "Manage third-party system authorization information",
|
||||
name: "Name",
|
||||
pleaseEnterName: "Please enter the name",
|
||||
nameHelper: "Fill in as you like, useful to distinguish when multiple authorizations of the same type exist",
|
||||
level: "Level",
|
||||
system: "System",
|
||||
usera: "User",
|
||||
nickName: "Nickname",
|
||||
max50Chars: "Maximum 50 characters",
|
||||
myInfo: "My Information",
|
||||
save: "Save",
|
||||
editSchedule: "Edit Schedule",
|
||||
timerTrigger: "Timer Trigger",
|
||||
schedule: "Schedule",
|
||||
selectCron: "Please select a schedule Cron",
|
||||
batchEditSchedule: "Batch Edit Schedule",
|
||||
editTrigger: "Edit Trigger",
|
||||
triggerName: "Trigger Name",
|
||||
requiredField: "This field is required",
|
||||
type: "Type",
|
||||
enterName: "Please enter a name",
|
||||
confirmDeleteTrigger: "Are you sure you want to delete this trigger?",
|
||||
notificationType: "Notification Type",
|
||||
selectNotificationType: "Please select a notification type",
|
||||
notificationName: "Notification Name",
|
||||
helperNotificationName: "Fill freely, helps to distinguish when multiple notifications of the same type exist",
|
||||
isDefault: "Is Default",
|
||||
yes: "Yes",
|
||||
no: "No",
|
||||
selectIsDefault: "Please select if default",
|
||||
prompt: "Prompt",
|
||||
confirmSetDefaultNotification: "Are you sure to set as default notification?",
|
||||
test: "Test",
|
||||
scope: "Scope",
|
||||
scopeOpenApiOnly: "Open API Only",
|
||||
scopeFullAccount: "Full Account Permissions",
|
||||
required: "This field is required",
|
||||
scopeHelper: "Open API only allows access to open APIs; full account permissions allow access to all APIs",
|
||||
add: "Generate New Key",
|
||||
gen: {
|
||||
text: "API Test",
|
||||
title: "x-certd-token",
|
||||
okText: "Confirm",
|
||||
contentPart1: "Test the x-certd-token below, you can use it within 3 minutes to test ",
|
||||
openApi: "Open API",
|
||||
contentPart2: " request testing",
|
||||
},
|
||||
pending_cname_setup: "Pending CNAME setup",
|
||||
validating: "Validating",
|
||||
validation_successful: "Validation successful",
|
||||
validation_failed: "Validation failed",
|
||||
validation_timed_out: "Validation timed out",
|
||||
proxied_domain: "Proxied Domain",
|
||||
host_record: "Host Record",
|
||||
please_set_cname: "Please set CNAME",
|
||||
cname_service: "CNAME Service",
|
||||
default_public_cname: "Default public CNAME service, you can also ",
|
||||
customize_cname: "Customize CNAME Service",
|
||||
public_cname: "Public CNAME",
|
||||
custom_cname: "Custom CNAME",
|
||||
validate: "Validate",
|
||||
validation_started: "Validation started, please wait patiently",
|
||||
click_to_validate: "Click to Validate",
|
||||
all: "All",
|
||||
cname_feature_guide: "CNAME feature principle and usage guide",
|
||||
batch_delete: "Batch Delete",
|
||||
confirm_delete_count: "Are you sure to delete these {count} records in batch?",
|
||||
delete_successful: "Delete successful",
|
||||
please_select_records: "Please select records first",
|
||||
edit_notification: "Edit Notification",
|
||||
other_notification_method: "Other Notification Method",
|
||||
trigger_time: "Trigger Time",
|
||||
start_time: "At Start",
|
||||
success_time: "On Success",
|
||||
fail_to_success_time: "Fail to Success",
|
||||
fail_time: "On Failure",
|
||||
helper_suggest_fail_only: "It is recommended to select only 'On Failure' and 'Fail to Success'",
|
||||
notification_config: "Notification Configuration",
|
||||
please_select_notification: "Please select a notification method",
|
||||
please_select_type: "Please select type",
|
||||
please_select_trigger_time: "Please select notification trigger time",
|
||||
please_select_notification_config: "Please select notification configuration",
|
||||
confirm_delete_trigger: "Are you sure you want to delete this trigger?",
|
||||
gift_package: "Gift Package",
|
||||
package_name: "Package Name",
|
||||
click_to_select: "Click to select",
|
||||
please_select_package: "Please select a package",
|
||||
package: "Package",
|
||||
addon_package: "Addon Package",
|
||||
domain_count: "Domain Count",
|
||||
unit_count: "pcs",
|
||||
field_required: "This field is required",
|
||||
pipeline_count: "Pipeline Count",
|
||||
unit_item: "items",
|
||||
deploy_count: "Deploy Count",
|
||||
unit_times: "times",
|
||||
monitor_count: "Certificate Monitor Count",
|
||||
duration: "Duration",
|
||||
status: "Status",
|
||||
active_time: "Activation Time",
|
||||
expires_time: "Expiration Time",
|
||||
is_present: "Is Present",
|
||||
is_present_yes: "Yes",
|
||||
is_present_no: "No",
|
||||
basicInfo: "Basic Information",
|
||||
titlea: "Title",
|
||||
disabled: "Disabled",
|
||||
ordera: "Order",
|
||||
supportBuy: "Support Purchase",
|
||||
intro: "Introduction",
|
||||
packageContent: "Package Content",
|
||||
maxDomainCount: "Max Domain Count",
|
||||
maxPipelineCount: "Max Pipeline Count",
|
||||
maxDeployCount: "Max Deploy Count",
|
||||
maxMonitorCount: "Max Monitor Count",
|
||||
price: "Price",
|
||||
durationPrices: "Duration Prices",
|
||||
packageName: "Package Name",
|
||||
addon: "Addon",
|
||||
typeHelper: "Suite: Only the most recently purchased one is active at a time\nAddon: Multiple can be purchased, effective immediately without affecting the suite\nThe quantities of suite and addon can be accumulated",
|
||||
domainCount: "Domain Count",
|
||||
pipelineCount: "Pipeline Count",
|
||||
unitPipeline: "pipelines",
|
||||
deployCount: "Deployment Count",
|
||||
unitDeploy: "times",
|
||||
monitorCount: "Certificate Monitor Count",
|
||||
unitCount: "pcs",
|
||||
durationPriceTitle: "Duration and Price",
|
||||
selectDuration: "Select Duration",
|
||||
supportPurchase: "Support Purchase",
|
||||
cannotPurchase: "Cannot Purchase",
|
||||
shelfStatus: "Shelf Status",
|
||||
onShelf: "On Shelf",
|
||||
offShelf: "Off Shelf",
|
||||
orderHelper: "Smaller values appear first",
|
||||
description: "Description",
|
||||
createTime: "Creation Time",
|
||||
updateTime: "Update Time",
|
||||
mainDomain: "Main Domain",
|
||||
edit: "Edit",
|
||||
groupName: "Group Name",
|
||||
enterGroupName: "Please enter group name",
|
||||
subdomainHosting: "Subdomain Hosting",
|
||||
subdomainHostingHint: "When your domain has subdomain hosting set, you need to create records here, otherwise certificate application will fail",
|
||||
batchDeleteConfirm: "Are you sure to batch delete these {count} records?",
|
||||
selectRecordFirst: "Please select records first",
|
||||
subdomainHosted: "Hosted Subdomain",
|
||||
subdomainHelpText: "If you don't understand what subdomain hosting is,Do not set it randomly, as it may result in the inability to apply for the certificate. please refer to the documentation ",
|
||||
subdomainHelpSupportStart: "Supports * wildcard, indicating that all subdomains of the domain are hosted (free subdomains)",
|
||||
subdomainManagement: "Subdomain Management",
|
||||
isDisabled: "Is Disabled",
|
||||
enabled: "Enabled",
|
||||
uploadCustomCert: "Upload Custom Certificate",
|
||||
sourcee: "Source",
|
||||
sourcePipeline: "Cert Apply Pipeline",
|
||||
sourceManualUpload: "Hosted Pipeline",
|
||||
domains: "Domains",
|
||||
enterDomain: "Please enter domain",
|
||||
validDays: "Valid Days",
|
||||
expires: " expires",
|
||||
days: " days",
|
||||
effectiveTime: "Effective Time",
|
||||
expireTime: "Expiration Time",
|
||||
certIssuer: "Certificate Issuer",
|
||||
applyTime: "Application Time",
|
||||
relatedPipeline: "Related Pipeline",
|
||||
statusSuccess: "Success",
|
||||
statusChecking: "Checking",
|
||||
statusError: "Error",
|
||||
actionImportBatch: "Batch Import",
|
||||
actionSyncIp: "Sync IP",
|
||||
modalTitleSyncIp: "Sync IP",
|
||||
modalContentSyncIp: "Are you sure to sync IP?",
|
||||
notificationSyncComplete: "Sync Complete",
|
||||
actionCheckAll: "Check All",
|
||||
modalTitleConfirm: "Confirm",
|
||||
modalContentCheckAll: "Confirm to trigger checking all IP site's certificates?",
|
||||
notificationCheckSubmitted: "Check task submitted",
|
||||
notificationCheckDescription: "Please refresh later to see results",
|
||||
tooltipCheckNow: "Check Now",
|
||||
notificationCheckSubmittedPleaseRefresh: "Check task submitted, please refresh later",
|
||||
columnId: "ID",
|
||||
columnIp: "IP",
|
||||
helperIpCname: "Supports entering CNAME domain name or source site domain name",
|
||||
ruleIpRequired: "Please enter IP",
|
||||
columnCertDomains: "Certificate Domains",
|
||||
columnCertProvider: "Issuer",
|
||||
columnCertStatus: "Certificate Status",
|
||||
statusNormal: "Normal",
|
||||
statusExpired: "Expired",
|
||||
columnCertExpiresTime: "Certificate Expiration Time",
|
||||
expired: "expired",
|
||||
columnCheckStatus: "Check Status",
|
||||
columnLastCheckTime: "Last Check Time",
|
||||
columnSource: "Source",
|
||||
sourceSync: "Sync",
|
||||
sourceManual: "Manual",
|
||||
sourceImport: "Import",
|
||||
columnDisabled: "Enabled/Disabled",
|
||||
columnRemark: "Remark",
|
||||
pluginFile: "Plugin File",
|
||||
selectPluginFile: "Select plugin file",
|
||||
overrideSameName: "Override same name",
|
||||
override: "Override",
|
||||
noOverride: "No override",
|
||||
overrideHelper: "If a plugin with the same name exists, override it directly",
|
||||
importPlugin: "Import Plugin",
|
||||
operationSuccess: "Operation successful",
|
||||
customPlugin: "Custom Plugin",
|
||||
import: "Import",
|
||||
export: "Export",
|
||||
pluginType: "Plugin Type",
|
||||
auth: "Authorization",
|
||||
dns: "DNS",
|
||||
deployPlugin: "Deploy Plugin",
|
||||
icon: "Icon",
|
||||
pluginName: "Plugin Name",
|
||||
pluginNameHelper: "Must be English letters or digits, camelCase with type prefix\nExample: AliyunDeployToCDN\nDo not modify name once plugin is used",
|
||||
pluginNameRuleMsg: "Must be English letters or digits, camelCase with type prefix",
|
||||
author: "Author",
|
||||
authorHelper: "Used as prefix when uploading to plugin store, e.g., greper/pluginName",
|
||||
authorRuleMsg: "Must be English letters or digits",
|
||||
titleHelper: "Plugin name in Chinese",
|
||||
descriptionHelper: "Description of the plugin",
|
||||
builtIn: "Built-in",
|
||||
custom: "Custom",
|
||||
store: "Store",
|
||||
version: "Version",
|
||||
pluginDependencies: "Plugin Dependencies",
|
||||
pluginDependenciesHelper: "Dependencies to install first in format: [author/]pluginName[:version]",
|
||||
editableRunStrategy: "Editable Run Strategy",
|
||||
editable: "Editable",
|
||||
notEditable: "Not Editable",
|
||||
runStrategy: "Run Strategy",
|
||||
normalRun: "Normal Run",
|
||||
skipOnSuccess: "Skip on success (Deploy task)",
|
||||
defaultRunStrategyHelper: "Default run strategy",
|
||||
enableDisable: "Enable/Disable",
|
||||
clickToToggle: "Click to toggle enable/disable",
|
||||
confirmToggle: "Are you sure to",
|
||||
disable: "disable",
|
||||
enable: "enable",
|
||||
pluginGroup: "Plugin Group",
|
||||
icpRegistrationNumber: "ICP Registration Number",
|
||||
icpPlaceholder: "Guangdong ICP xxxxxxx Number",
|
||||
publicSecurityRegistrationNumber: "Public Security Registration Number",
|
||||
publicSecurityPlaceholder: "Beijing Public Security xxxxxxx Number",
|
||||
enableAssistant: "Enable Assistant",
|
||||
allowCrawlers: "Allow Crawlers",
|
||||
httpProxy: "HTTP Proxy",
|
||||
httpProxyPlaceholder: "http://192.168.1.2:18010/",
|
||||
httpProxyHelper: "Configure when some websites are blocked",
|
||||
httpsProxy: "HTTPS Proxy",
|
||||
httpsProxyPlaceholder: "http://192.168.1.2:18010/",
|
||||
saveThenTestTitle: "Save first, then click test",
|
||||
testButton: "Test",
|
||||
httpsProxyHelper: "Usually both proxies are the same, save first then test",
|
||||
dualStackNetwork: "Dual Stack Network",
|
||||
default: "Default",
|
||||
ipv4Priority: "IPv4 Priority",
|
||||
ipv6Priority: "IPv6 Priority",
|
||||
dualStackNetworkHelper: "If IPv6 priority is selected, enable IPv6 in docker-compose.yaml",
|
||||
enableCommonCnameService: "Enable Public CNAME Service",
|
||||
commonCnameHelper: "Allow use of public CNAME service. If disabled and no <a href='#/sys/cname/provider'>custom CNAME service</a> is set, CNAME proxy certificate application will not work.",
|
||||
enableCommonSelfServicePasswordRetrieval: "Enable self-service password recovery",
|
||||
saveButton: "Save",
|
||||
stopSuccess: "Stopped successfully",
|
||||
google: "Google",
|
||||
baidu: "Baidu",
|
||||
success: "Success",
|
||||
testFailed: "Test Failed",
|
||||
testCompleted: "Test Completed",
|
||||
manageOtherUserPipeline: "Manage other users' pipelines",
|
||||
limitUserPipelineCount: "Limit user pipeline count",
|
||||
limitUserPipelineCountHelper: "0 means no limit",
|
||||
enableSelfRegistration: "Enable self-registration",
|
||||
enableUserValidityPeriod: "Enable user validity period",
|
||||
userValidityPeriodHelper: "Users can use normally within validity; pipelines disabled after expiry",
|
||||
enableUsernameRegistration: "Enable username registration",
|
||||
enableEmailRegistration: "Enable email registration",
|
||||
proFeature: "Pro feature",
|
||||
emailServerSetup: "Set up email server",
|
||||
enableSmsLoginRegister: "Enable SMS login and registration",
|
||||
commFeature: "Commercial feature",
|
||||
smsProvider: "SMS provider",
|
||||
aliyunSms: "Aliyun SMS",
|
||||
tencentSms: "Tencent SMS",
|
||||
yfySms: "YFY SMS",
|
||||
smsTest: "SMS test",
|
||||
testMobilePlaceholder: "Enter test mobile number",
|
||||
saveThenTest: "Save first then test",
|
||||
enterTestMobile: "Please enter test mobile number",
|
||||
sendSuccess: "Sent successfully",
|
||||
atLeastOneLoginRequired: "At least one of password login or SMS login must be enabled",
|
||||
fieldRequired: "This field is required",
|
||||
siteHide: "Site Hide",
|
||||
enableSiteHide: "Enable Site Hide",
|
||||
siteHideDescription: "You can disable site accessibility normally and enable it when needed to enhance site security",
|
||||
helpDoc: "Help Document",
|
||||
randomAddress: "Random Address",
|
||||
siteHideUrlHelper: "After the site is hidden, you need to visit this URL to unlock to access normally",
|
||||
fullUnlockUrl: "Full Unlock URL",
|
||||
saveThisUrl: "Please save this URL carefully",
|
||||
unlockPassword: "Unlock Password",
|
||||
unlockPasswordHelper: "Password needed to unlock the hide; set on first time or reset when filled",
|
||||
autoHideTime: "Auto Hide Time",
|
||||
autoHideTimeHelper: "Minutes without requests before auto hiding",
|
||||
hideOpenApi: "Hide Open API",
|
||||
hideOpenApiHelper: "Whether to hide open APIs; whether to hide /api/v1 prefixed endpoints",
|
||||
hideSiteImmediately: "Hide Site Immediately",
|
||||
hideImmediately: "Hide Immediately",
|
||||
confirmHideSiteTitle: "Are you sure to hide the site immediately?",
|
||||
confirmHideSiteContent: "After hiding, the site will be inaccessible. Please operate cautiously.",
|
||||
siteHiddenSuccess: "Site has been hidden",
|
||||
emailServerSettings: "Email Server Settings",
|
||||
setEmailSendingServer: "Set the email sending server",
|
||||
useCustomEmailServer: "Use Custom Email Server",
|
||||
smtpDomain: "SMTP Domain",
|
||||
pleaseEnterSmtpDomain: "Please enter SMTP domain or IP",
|
||||
smtpPort: "SMTP Port",
|
||||
pleaseEnterSmtpPort: "Please enter SMTP port",
|
||||
username: "Username",
|
||||
pleaseEnterUsername: "Please enter username",
|
||||
password: "Password",
|
||||
pleaseEnterPassword: "Please enter password",
|
||||
qqEmailAuthCodeHelper: "If using QQ email, get an authorization code in QQ email settings as the password",
|
||||
senderEmailHelper: "You can use the format: Name<Email> to set the sender name, e.g.: autossl<certd{'@'}example.com>",
|
||||
senderEmail: "Sender Email",
|
||||
pleaseEnterSenderEmail: "Please enter sender email",
|
||||
useSsl: "Use SSL",
|
||||
sslPortNote: "SSL and non-SSL SMTP ports are different, please adjust port accordingly",
|
||||
ignoreCertValidation: "Ignore Certificate Validation",
|
||||
useOfficialEmailServer: "Use Official Email Server",
|
||||
useOfficialEmailServerHelper: "Send emails directly using the official server to avoid complicated setup",
|
||||
testReceiverEmail: "Test Receiver Email",
|
||||
pleaseEnterTestReceiverEmail: "Please enter test receiver email",
|
||||
saveBeforeTest: "Save before testing",
|
||||
sendFailHelpDoc: "Failed to send??? ",
|
||||
emailConfigHelpDoc: "Email configuration help document",
|
||||
tryOfficialEmailServer: "You can also try using the official email server ↗↗↗↗↗↗↗↗",
|
||||
pluginManagement: "Plugin Management",
|
||||
pluginBetaWarning: "Custom plugins are in BETA and may have breaking changes in future",
|
||||
pleaseSelectRecord: "Please select records first",
|
||||
permissionManagement: "Permission Management",
|
||||
adda: "Add",
|
||||
rootNode: "Root Node",
|
||||
permissionName: "Permission Name",
|
||||
enterPermissionName: "Please enter permission name",
|
||||
permissionCode: "Permission Code",
|
||||
enterPermissionCode: "Please enter permission code",
|
||||
max100Chars: "Maximum 100 characters",
|
||||
examplePermissionCode: "e.g.: sys:user:view",
|
||||
sortOrder: "Sort Order",
|
||||
sortRequired: "Sort order is required",
|
||||
parentNode: "Parent Node",
|
||||
roleManagement: "Role Management",
|
||||
assignPermissions: "Assign Permissions",
|
||||
roleName: "Role Name",
|
||||
enterRoleName: "Please enter role name",
|
||||
unlockLogin: "Unlock Login",
|
||||
notice: "Notice",
|
||||
confirmUnlock: "Are you sure you want to unlock this user's login?",
|
||||
unlockSuccess: "Unlock successful",
|
||||
enterUsername: "Please enter username",
|
||||
modifyPasswordIfFilled: "Fill in to change the password",
|
||||
emaila: "Email",
|
||||
mobile: "Mobile",
|
||||
avatar: "Avatar",
|
||||
validTime: "Valid Time",
|
||||
remark: "Remark",
|
||||
roles: "Roles",
|
||||
cnameTitle: "CNAME Service Configuration",
|
||||
cnameDescription:
|
||||
"The domain name configured here serves as a proxy for verifying other domains. When other domains apply for certificates, they map to this domain via CNAME for ownership verification. The advantage is that any domain can apply for a certificate this way without providing an AccessSecret.",
|
||||
cnameLinkText: "CNAME principle and usage instructions",
|
||||
confirmTitle: "Confirm",
|
||||
confirmDeleteBatch: "Are you sure you want to delete these {count} records?",
|
||||
selectRecordsFirst: "Please select records first",
|
||||
cnameDomain: "CNAME Domain",
|
||||
cnameDomainPlaceholder: "cname.handsfree.work",
|
||||
cnameDomainHelper:
|
||||
"Requires a domain registered with a DNS provider on the right (or you can transfer other domain DNS servers here).\nOnce the CNAME domain is set, it cannot be changed. It is recommended to use a first-level subdomain.",
|
||||
cnameDomainPattern: "Domain name cannot contain *",
|
||||
dnsProvider: "DNS Provider",
|
||||
dnsProviderAuthorization: "DNS Provider Authorization",
|
||||
setDefault: "Set Default",
|
||||
confirmSetDefault: "Are you sure to set as default?",
|
||||
setAsDefault: "Set as Default",
|
||||
disabledLabel: "Disabled",
|
||||
confirmToggleStatus: "Are you sure to {action}?",
|
||||
template: {
|
||||
title: "Pipeline Template",
|
||||
edit: "Pipeline Template Edit",
|
||||
importCreate: "Pipeline Batch Create",
|
||||
// intro: "可根据模版批量创建流水线",
|
||||
intro: "Batch create pipeline based on template",
|
||||
createTemplate: "Create Template",
|
||||
useTemplate: "Use This Template",
|
||||
batchCreate: "Batch Create Pipeline",
|
||||
singleCreate: "Create Single Pipeline",
|
||||
templateName: "Template Name",
|
||||
enterTemplateName: "Please enter template name",
|
||||
copyPipelineConfig: "Copy this pipeline configuration as template source",
|
||||
pipeline: "Pipeline",
|
||||
},
|
||||
|
||||
addonType: "Type",
|
||||
addonName: "Name",
|
||||
addonNameHelper: "Fill freely, helps to distinguish when multiple same type exist",
|
||||
addonTypeSelect: "Select type",
|
||||
dates: {
|
||||
years: "{count} years",
|
||||
months: "{count} months",
|
||||
},
|
||||
sys: {
|
||||
setting: {
|
||||
baseSetting: "Base Settings",
|
||||
registerSetting: "Register Settings",
|
||||
safeSetting: "Safe Settings",
|
||||
paymentSetting: "Payment Settings",
|
||||
captchaSetting: "Captcha Setting",
|
||||
pipelineSetting: "Pipeline Settings",
|
||||
oauthSetting: "Login Settings",
|
||||
networkSetting: "Network Settings",
|
||||
adminModeSetting: "Admin Mode Settings",
|
||||
adminModeHelper: "enterprise mode : allow to create and manage pipelines, roles, users, etc.\n saas mode : only allow to create and manage pipelines",
|
||||
enterpriseMode: "Enterprise Mode",
|
||||
saasMode: "SaaS Mode",
|
||||
|
||||
showRunStrategy: "Show RunStrategy",
|
||||
showRunStrategyHelper: "Allow modify the run strategy of the task",
|
||||
|
||||
captchaEnabled: "Enable Login Captcha",
|
||||
captchaHelper: "Whether to enable captcha verification for login",
|
||||
captchaType: "Captcha Setting",
|
||||
captchaTest: "Captcha Test",
|
||||
// 保存后再点击测试,请务必测试通过了,再开启登录验证码
|
||||
captchaTestHelper: "Save and click test, please make sure the test is passed before enabling login captcha",
|
||||
|
||||
pipelineValidTimeEnabled: "Enable Pipeline Valid Time",
|
||||
pipelineValidTimeEnabledHelper: "Whether to enable the valid time of the pipeline",
|
||||
certDomainAddToMonitorEnabled: "Add Domain to Certificate Monitor",
|
||||
certDomainAddToMonitorEnabledHelper: "Whether to add the domain to the certificate monitor",
|
||||
|
||||
defaultCertRenewDays: "Default Certificate Renew Days",
|
||||
defaultCertRenewDaysHelper: "Default certificate renewal days, helpful for table list progress bar display",
|
||||
defaultCertRenewDaysRecommend: "Recommend 15",
|
||||
|
||||
pipelineMaxRunningCount: "Max Running Count",
|
||||
pipelineMaxRunningCountHelper: "Max running count of the pipeline",
|
||||
pipelineMaxRunningCountRecommend: "Recommend 5-15, default 10",
|
||||
|
||||
acmeWalkFromAuthoritative: "Check TXT Record from Authoritative NS",
|
||||
acmeWalkFromAuthoritativeHelper: "Apply certificate when whether to check the TXT record from authoritative NS server first",
|
||||
|
||||
fixedCertExpireDays: "Fixed Cert Expire Days",
|
||||
fixedCertExpireDaysHelper: "Fixed cert expiration days, helpful for table list progress bar display",
|
||||
fixedCertExpireDaysRecommend: "Recommend 90",
|
||||
|
||||
enableOauth: "Enable OAuth2 Login",
|
||||
oauthEnabledHelper: "Whether to enable OAuth2 login",
|
||||
oauthProviders: "OAuth2 Login Providers",
|
||||
oauthType: "OAuth2 Login Type",
|
||||
oauthConfig: "OAuth2 Login Config",
|
||||
oauthProviderSelectorPlaceholder: "Not Configured",
|
||||
oauthCallback: "Callback URL",
|
||||
oauthCallbackHelper: "Copy this URL to the callback address of the OAuth2 login provider",
|
||||
oauthCallbackCopy: "Copy Callback URL",
|
||||
oauthAutoRegister: "Auto Register User",
|
||||
oauthAutoRegisterCheckedText: "Auto Register",
|
||||
oauthAutoRegisterUnCheckedText: "User Select",
|
||||
oauthAutoRegisterHelper: "Whether to auto register user when login",
|
||||
oauthAutoRedirect: "Auto Redirect to OAuth2 Login",
|
||||
oauthAutoRedirectHelper: "Whether to auto redirect to OAuth2 login when login (using the first enabled OAuth2 login type)",
|
||||
oauthOnly: "OAuth2 Login Only",
|
||||
oauthOnlyHelper: "Whether to only allow OAuth2 login, disable password login",
|
||||
enablePasskey: "Enable Passkey Login",
|
||||
passkeyHostnameNotSame: "Passkey hostname must be the same as the main domain",
|
||||
passkeyEnabledHelper:
|
||||
"1、Site must enable https \n2、Domain name must not change, otherwise the registered passkey will be invalid \n3、Domain name must be the same as the main domain, otherwise the registered passkey will be invalid",
|
||||
|
||||
email: {
|
||||
templates: "Email Templates",
|
||||
templateType: "Template Type",
|
||||
templateProvider: "Template Config",
|
||||
|
||||
templateSetting: "Email Template Setting",
|
||||
serverSetting: "Email Server Setting",
|
||||
sendTest: "Send Test",
|
||||
|
||||
templateProviderSelectorPlaceholder: "Not Configured",
|
||||
},
|
||||
notice: "System Notice",
|
||||
noticeHelper: "System notice, will be displayed on the login page",
|
||||
noticePlaceholder: "System notice",
|
||||
|
||||
reverseProxy: "Reverse Proxy List",
|
||||
reverseProxyHelper: "Reverse proxy for ACME address, used when applying for certificate",
|
||||
reverseProxyPlaceholder: "http://le.px.handfree.work",
|
||||
reverseProxyEmpty: "No reverse proxy list configured",
|
||||
environmentVars: "Environment Variables",
|
||||
environmentVarsHelper: "configure the runtime environment variables, one per line, format: KEY=VALUE",
|
||||
|
||||
bindUrl: "Bind URL",
|
||||
},
|
||||
},
|
||||
modal: {
|
||||
close: "Close",
|
||||
viewCertificateTitle: "View Certificate",
|
||||
},
|
||||
domain: {
|
||||
domainManager: "Domain Manager",
|
||||
domainDescription: "used to auto apply for certificate", //管理域名的校验方式,用于申请证书时自动选择验证方式
|
||||
domain: "Domain",
|
||||
challengeType: "Challenge Type",
|
||||
dnsProviderType: "DNS Provider Type",
|
||||
dnsProviderAccess: "DNS Provider Access",
|
||||
httpUploaderType: "HTTP Uploader Type",
|
||||
httpUploaderAccess: "HTTP Uploader Access",
|
||||
httpUploadRootDir: "HTTP Upload Root Dir",
|
||||
disabled: "Disabled",
|
||||
challengeSetting: "Challenge Setting",
|
||||
gotoCnameTip: "Please go to CNAME Record Page",
|
||||
fromType: "From Type",
|
||||
expirationDate: "Expiration Date",
|
||||
},
|
||||
ent: {
|
||||
projectName: "Project Name",
|
||||
projectDescription: "Project Description",
|
||||
projectDetailManager: "Project Detail",
|
||||
projectDetailDescription: "Manage Project Members",
|
||||
projectPermission: "Permission",
|
||||
permission: {
|
||||
read: "Read",
|
||||
write: "Write",
|
||||
admin: "Admin",
|
||||
},
|
||||
projectMemberStatus: "Member Status",
|
||||
|
||||
isSystem: "Is System Project",
|
||||
isSystemHelper: "System-level projects allow running admin plugins",
|
||||
},
|
||||
project: {
|
||||
noProjectJoined: "You haven't joined any projects yet",
|
||||
applyToJoin: "Please apply to join a project to start using",
|
||||
systemProjects: "System Project List",
|
||||
createdAt: "Created At",
|
||||
applyJoin: "Apply to Join",
|
||||
noSystemProjects: "No system projects available",
|
||||
fetchFailed: "Failed to fetch project list",
|
||||
applySuccess: "Application successful, waiting for admin approval",
|
||||
applyFailed: "Application failed, please try again later",
|
||||
leave: "Leave Project",
|
||||
leaveSuccess: "Leave project successful",
|
||||
leaveFailed: "Leave project failed, please try again later",
|
||||
applyJoinConfirm: "Are you sure you want to apply to join this project?",
|
||||
leaveConfirm: "Are you sure you want to leave this project?",
|
||||
viewDetail: "View Detail",
|
||||
projectManage: "Project Manage",
|
||||
},
|
||||
addonSelector: {
|
||||
select: "Select",
|
||||
placeholder: "select please",
|
||||
},
|
||||
...common,
|
||||
...navigation,
|
||||
...dashboard,
|
||||
...pipeline,
|
||||
...history,
|
||||
...monitor,
|
||||
...certdomain,
|
||||
...cname,
|
||||
...access,
|
||||
...open,
|
||||
...mine,
|
||||
...notification,
|
||||
...addon,
|
||||
...suite,
|
||||
...project,
|
||||
...syssettings,
|
||||
...sysplugin,
|
||||
...sysauthority,
|
||||
...syscname,
|
||||
...tutorial,
|
||||
...cron,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
export default {
|
||||
authorizationManagement: "Authorization Management",
|
||||
manageThirdPartyAuth: "Manage third-party system authorization information",
|
||||
nameHelper: "Fill in as you like, useful to distinguish when multiple authorizations of the same type exist",
|
||||
level: "Level",
|
||||
system: "System",
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
export default {
|
||||
addonType: "Type",
|
||||
addonName: "Name",
|
||||
addonNameHelper: "Fill freely, helps to distinguish when multiple same type exist",
|
||||
addonTypeSelect: "Select type",
|
||||
addonSelector: {
|
||||
select: "Select",
|
||||
placeholder: "select please",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,106 @@
|
||||
export default {
|
||||
domain: {
|
||||
domainManager: "Domain Manager",
|
||||
domainDescription: "used to auto apply for certificate", //管理域名的校验方式,用于申请证书时自动选择验证方式
|
||||
domain: "Domain",
|
||||
challengeType: "Challenge Type",
|
||||
dnsProviderType: "DNS Provider Type",
|
||||
dnsProviderAccess: "DNS Provider Access",
|
||||
httpUploaderType: "HTTP Uploader Type",
|
||||
httpUploaderAccess: "HTTP Uploader Access",
|
||||
httpUploadRootDir: "HTTP Upload Root Dir",
|
||||
disabled: "Disabled",
|
||||
challengeSetting: "Challenge Setting",
|
||||
gotoCnameTip: "Please go to CNAME Record Page",
|
||||
fromType: "From Type",
|
||||
expirationDate: "Expiration Date",
|
||||
cnameManagedInCnamePage: "For CNAME mode, please manage records on the CNAME Records page.",
|
||||
subdomainConfirmTitle: "Subdomain Confirmation",
|
||||
subdomainConfirmContent: "{domain} appears to be a subdomain. Only delegated subdomains and free second-level subdomains need to be maintained here. Otherwise certificate application may fail. Continue?",
|
||||
importFromProvider: "Import from Domain Provider",
|
||||
syncExpirationDate: "Sync Domain Expiration Time",
|
||||
syncTaskSubmitted: "Sync task submitted",
|
||||
expirationMonitorSetting: "Domain Expiration Monitor Settings",
|
||||
subdomainDnsHelper: "Note: In DNS validation mode, subdomains do not need to be maintained here, otherwise certificate application may be affected (except delegated subdomains or free second-level domains).",
|
||||
path: "Path",
|
||||
addImportTask: "Add Import Task",
|
||||
refresh: "Refresh",
|
||||
progress: "Progress",
|
||||
operation: "Operation",
|
||||
total: "Total",
|
||||
skipped: "Skipped",
|
||||
failed: "Failed",
|
||||
notExecuted: "Not executed",
|
||||
execute: "Run",
|
||||
delete: "Delete",
|
||||
confirmDelete: "Confirm deletion?",
|
||||
domainProvider: "Domain Provider",
|
||||
domainProviderAccessType: "Domain Provider Access Type",
|
||||
domainProviderAccess: "Domain Provider Access",
|
||||
},
|
||||
verifyPlan: {
|
||||
expandTip: "Click to enlarge",
|
||||
mainDomain: "Main Domain",
|
||||
challengeType: "Challenge Method",
|
||||
challengePlan: "Challenge Plan",
|
||||
dnsType: "DNS Type",
|
||||
dnsProvider: "DNS Provider",
|
||||
dnsAccess: "DNS Access",
|
||||
pleaseSelect: "Please select",
|
||||
httpHelper: "The CA will request https://yourdomain/.well-known/acme-challenge/xxxxxx to verify domain ownership.",
|
||||
dnsChallenge: "DNS Challenge",
|
||||
cnameChallenge: "CNAME Challenge",
|
||||
cnameProxyChallenge: "CNAME Proxy Challenge",
|
||||
httpChallenge: "HTTP Challenge",
|
||||
domainTitle: "Domain: {domain}",
|
||||
resetStatusTooltip: "Reset validation status and validate again",
|
||||
clickToValidate: "Validate",
|
||||
keepCnameTitle: "Required for future automatic certificate applications",
|
||||
keepCname: "Do not delete CNAME",
|
||||
resetStatus: "Reset Status",
|
||||
confirmResetStatus: "Are you sure you want to reset the validation status?",
|
||||
hostRecord: "Host Record",
|
||||
recordType: "Record Type",
|
||||
setCnameRecord: "Set the CNAME record. Do not delete it after validation succeeds.",
|
||||
operation: "Operation",
|
||||
websiteDomain: "Website Domain",
|
||||
uploadMethod: "Upload Method",
|
||||
uploadAccess: "Upload Access",
|
||||
websiteRootPath: "Website Root Path",
|
||||
websiteRootPlaceholder: "Website root path, e.g. /www/wwwroot",
|
||||
status: {
|
||||
pendingCname: "Pending CNAME Setup",
|
||||
validating: "Validating",
|
||||
valid: "Validation Successful",
|
||||
failed: "Validation Failed",
|
||||
timeout: "Validation Timed Out",
|
||||
},
|
||||
cnameTip: {
|
||||
intro: "Try a few more times. If validation still fails, troubleshoot with these steps:",
|
||||
step1: "1. The DNS record should be added under {domain}.",
|
||||
step2: "2. Add a CNAME record, not a TXT record.",
|
||||
step3: "3. Check whether the record value is: {value}",
|
||||
step4: "4. While validating, run the command below to check whether CNAME and TXT resolution are correct.",
|
||||
or: "or",
|
||||
step5: "5. If all checks pass, DNS propagation may be slow. Some providers can take several hours.",
|
||||
},
|
||||
errors: {
|
||||
cnameNotValid: "The CNAME for domain {domain} has not been validated. Set the CNAME record first, then click Validate.",
|
||||
wildcardNotSupportHttp: "Domain {domain} is a wildcard domain and does not support HTTP validation.",
|
||||
uploadMethodRequired: "The upload method for domain {domain} is required.",
|
||||
uploadAccessRequired: "The upload access for domain {domain} is required.",
|
||||
websiteRootRequired: "The website root path for domain {domain} is required.",
|
||||
dnsProviderRequired: "In DNS mode, the DNS type and access information for domain {domain} are required.",
|
||||
},
|
||||
uploader: {
|
||||
aliyunOss: "Alibaba Cloud OSS",
|
||||
tencentCos: "Tencent Cloud COS",
|
||||
qiniuOss: "Qiniu OSS",
|
||||
sshDeprecated: "SSH (deprecated, use SFTP instead)",
|
||||
},
|
||||
domainFrom: {
|
||||
manual: "Manual",
|
||||
auto: "Automatic",
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
export default {
|
||||
pending_cname_setup: "Pending CNAME setup",
|
||||
validating: "Validating",
|
||||
validation_successful: "Validation successful",
|
||||
validation_failed: "Validation failed",
|
||||
validation_timed_out: "Validation timed out",
|
||||
proxied_domain: "Proxied Domain",
|
||||
host_record: "Host Record",
|
||||
please_set_cname: "Please set CNAME",
|
||||
cname_service: "CNAME Service",
|
||||
default_public_cname: "Default public CNAME service, you can also ",
|
||||
customize_cname: "Customize CNAME Service",
|
||||
public_cname: "Public CNAME",
|
||||
custom_cname: "Custom CNAME",
|
||||
validate: "Validate",
|
||||
validation_started: "Validation started, please wait patiently",
|
||||
click_to_validate: "Click to Validate",
|
||||
cname_feature_guide: "CNAME feature principle and usage guide",
|
||||
mainDomain: "Main Domain",
|
||||
cnameRecord: "CNAME Record Management",
|
||||
importRecords: "Import CNAME Records",
|
||||
batchImport: "Batch Import",
|
||||
exportRecordsTip: "After exporting CNAME records, you can batch import CNAME DNS records to the domain registrar.",
|
||||
batchExport: "Batch Export",
|
||||
resetStatus: "Reset Status",
|
||||
confirmResetStatus: "Are you sure you want to reset the validation status?",
|
||||
resetStatusTooltip: "Reset validation status and validate again",
|
||||
cname: {
|
||||
importRecords: "Import CNAME Records",
|
||||
batchImport: "Batch Import",
|
||||
exportRecordsTip: "After exporting CNAME records, you can batch import CNAME DNS records to the domain registrar.",
|
||||
batchExport: "Batch Export",
|
||||
resetStatus: "Reset Status",
|
||||
confirmResetStatus: "Are you sure you want to reset the validation status?",
|
||||
resetStatusTooltip: "Reset validation status and validate again",
|
||||
domainList: "Domain List",
|
||||
domainListHelper: "One domain per line for batch import\nRemove *. from wildcard domains\nExisting records will be skipped automatically",
|
||||
cnameService: "CNAME Service",
|
||||
importTaskSubmitted: "Import task submitted",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,148 @@
|
||||
export default {
|
||||
usera: "User",
|
||||
disabledSuccess: "Disabled successfully",
|
||||
app: {
|
||||
crud: {
|
||||
i18n: {
|
||||
name: "name",
|
||||
city: "city",
|
||||
status: "status",
|
||||
},
|
||||
},
|
||||
},
|
||||
fs: {
|
||||
rowHandle: {
|
||||
title: "Operation",
|
||||
},
|
||||
},
|
||||
close: "Close",
|
||||
confirm: "Confirm",
|
||||
save: "Save",
|
||||
add: "Generate New Key",
|
||||
edit: "Edit",
|
||||
deleteSuccess: "Delete successful",
|
||||
saveSuccess: "Saved successfully",
|
||||
cancel: "Cancel",
|
||||
yes: "Yes",
|
||||
no: "No",
|
||||
all: "All",
|
||||
required: "This field is required",
|
||||
requiredField: "This field is required",
|
||||
fieldRequired: "This field is required",
|
||||
field_required: "This field is required",
|
||||
name: "Name",
|
||||
pleaseEnterName: "Please enter the name",
|
||||
type: "Type",
|
||||
status: "Status",
|
||||
description: "Description",
|
||||
createTime: "Creation Time",
|
||||
updateTime: "Update Time",
|
||||
basicInfo: "Basic Information",
|
||||
disabled: "Disabled",
|
||||
enabled: "Enabled",
|
||||
default: "Default",
|
||||
success: "Success",
|
||||
test: "Test",
|
||||
testButton: "Test",
|
||||
operationSuccess: "Operation successful",
|
||||
batch_delete: "Batch Delete",
|
||||
confirm_delete_count: "Are you sure to delete these {count} records in batch?",
|
||||
delete_successful: "Delete successful",
|
||||
please_select_records: "Please select records first",
|
||||
groupName: "Group Name",
|
||||
enterGroupName: "Please enter group name",
|
||||
batchDeleteConfirm: "Are you sure to batch delete these {count} records?",
|
||||
selectRecordFirst: "Please select records first",
|
||||
confirmTitle: "Confirm",
|
||||
confirmDeleteBatch: "Are you sure you want to delete these {count} records?",
|
||||
selectRecordsFirst: "Please select records first",
|
||||
setDefault: "Set Default",
|
||||
confirmSetDefault: "Are you sure to set as default?",
|
||||
setAsDefault: "Set as Default",
|
||||
disabledLabel: "Disabled",
|
||||
confirmToggleStatus: "Are you sure to {action}?",
|
||||
batchDelete: "Batch Delete",
|
||||
sourcee: "Source",
|
||||
clickToToggle: "Click to toggle enable/disable",
|
||||
nickName: "Nickname",
|
||||
avatar: "Avatar",
|
||||
expires: " expires",
|
||||
days: " days",
|
||||
isDefault: "Is Default",
|
||||
selectIsDefault: "Please select if default",
|
||||
isDisabled: "Is Disabled",
|
||||
fields: {
|
||||
userId: "User ID",
|
||||
pipelineName: "Pipeline Name",
|
||||
keyword: "Keyword",
|
||||
required: "This field is required",
|
||||
pipelineContent: "Pipeline Content",
|
||||
scheduledTaskCount: "Scheduled Task Count",
|
||||
deployTaskCount: "Deployment Task Count",
|
||||
remainingValidity: "Remaining Validity",
|
||||
effectiveTime: "Effective time",
|
||||
expiryTime: "Expiry Time",
|
||||
status: "Status",
|
||||
lastRun: "Last Run",
|
||||
enabled: "Enabled",
|
||||
enabledLabel: "Enabled",
|
||||
disabledLabel: "Disabled",
|
||||
group: "Group",
|
||||
type: "Type",
|
||||
order: "Order Number",
|
||||
keepHistoryCount: "History Record Retention Count",
|
||||
keepHistoryHelper: "Number of history records to keep; excess will be deleted",
|
||||
createTime: "Creation Time",
|
||||
updateTime: "Update Time",
|
||||
triggerType: "Trigger Type",
|
||||
pipelineId: "Pipeline Id",
|
||||
nextRunTime: "Next Run Time",
|
||||
projectName: "Project",
|
||||
adminId: "Admin",
|
||||
},
|
||||
enterName: "Please enter a name",
|
||||
prompt: "Prompt",
|
||||
domainCount: "Domain Count",
|
||||
import: "Import",
|
||||
export: "Export",
|
||||
disable: "disable",
|
||||
enable: "enable",
|
||||
username: "Username",
|
||||
password: "Password",
|
||||
expired: "expired",
|
||||
helpDocLink: "Help Docs",
|
||||
suite: "Suite",
|
||||
helpDoc: "Help Document",
|
||||
pluginCommon: {
|
||||
test: "Test",
|
||||
errorWithMessage: "Error: {message}",
|
||||
testRequestSuccess: "Test request succeeded",
|
||||
responseSuffix: ", response: {response}",
|
||||
searchKeyword: "Search keyword",
|
||||
search: "Search",
|
||||
refreshOptions: "Refresh options",
|
||||
getOptionsError: "Failed to get options: {message}",
|
||||
getDataSuccessSelect: "Data loaded. Please select from the dropdown.",
|
||||
getDataSuccessEmpty: "Data loaded. No data found.",
|
||||
domainSearchPlaceholder: "Search domains here (from Settings -> Domain Management), or type directly in the input above",
|
||||
importDomain: "Import Domains",
|
||||
manageDomain: "Manage Domains",
|
||||
refreshMyDomains: "Refresh my domain list",
|
||||
upload: "Upload",
|
||||
uploadCert: "Upload Certificate",
|
||||
certName: "Certificate Name",
|
||||
certNameHelper: "Display name after upload",
|
||||
uploadSuccess: "Upload successful",
|
||||
selectCertFirst: "Please select a domain certificate first",
|
||||
targetStepNotFound: "Target step not found. Please select a domain certificate first.",
|
||||
},
|
||||
captcha: {
|
||||
inputImageCode: "Please enter the image captcha",
|
||||
refresh: "Refresh captcha",
|
||||
clickToVerify: "Click to verify",
|
||||
verifySuccess: "Verification successful",
|
||||
verifyFailed: "Verification failed. Please try again.",
|
||||
loadFailed: "Failed to load captcha",
|
||||
notLoaded: "Captcha is not loaded yet",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,7 @@
|
||||
export default {
|
||||
cron: {
|
||||
clearTip: "Clear Selection",
|
||||
nextTrigger: "Next Trigger Time",
|
||||
tip: "Please set a valid cron expression first",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
export default {
|
||||
dashboard: {
|
||||
greeting: "Hello, {name}, welcome to 【{site}】",
|
||||
latestVersion: "Latest version: {version}",
|
||||
validUntil: "Valid until:",
|
||||
tutorialTooltip: "Click to view detailed tutorial",
|
||||
tutorialText: "Only 3 steps to automatically apply and deploy certificates",
|
||||
alertMessage: "Certificates and credentials are sensitive. Do not use untrusted online Certd services or images. Always self-host and use official release channels:",
|
||||
helpDoc: "Help Docs",
|
||||
pipelineCount: "Number of Certificate Pipelines",
|
||||
noPipeline: "You have no certificate pipelines yet",
|
||||
enabledCount: "Enabled",
|
||||
disabledCount: "Disabled",
|
||||
certCount: "Number of Certificates",
|
||||
noCert: "You have no certificates yet",
|
||||
manageCert: "View Certificates",
|
||||
certExpiringCount: "Soon-to-Expire",
|
||||
certExpiredCount: "Expired",
|
||||
certNoExpireCount: "Not Expired",
|
||||
createNow: "Create Now",
|
||||
managePipeline: "Manage Pipelines",
|
||||
pipelineStatus: "Pipeline Status",
|
||||
recentRun: "Recent Run Statistics",
|
||||
runCount: "Run Count",
|
||||
expiringCerts: "Soon-to-Expire Certificates",
|
||||
supportedTasks: "Overview of Supported Deployment Tasks",
|
||||
changeLog: "Change Log",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
export default {
|
||||
pipelineExecutionRecords: "Pipeline Execution Records",
|
||||
confirmBatchDeleteContent: "Are you sure you want to batch delete these {count} records?",
|
||||
pleaseSelectRecords: "Please select records first",
|
||||
triggerTypes: {
|
||||
manual: "Manual Execution",
|
||||
timer: "Scheduled Execution",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
export default {
|
||||
accountInfo: "Account Information",
|
||||
securitySettings: "Security & Settings",
|
||||
confirmDisable2FA: "Are you sure you want to disable two-factor authentication login?",
|
||||
twoFactorAuth: "2FA Two-Factor Authentication Login",
|
||||
rebind: "Rebind",
|
||||
twoFactorAuthHelper: "Enable or disable two-factor authentication login",
|
||||
bindDevice: "Bind Device",
|
||||
step1: "1. Install any authenticator app, for example:",
|
||||
tooltipGoogleServiceError: "If you get a Google service not found error, you can install KK Google Assistant",
|
||||
step2: "2. Scan the QR code to add the account",
|
||||
step3: "3. Enter the verification code",
|
||||
inputVerifyCode: "Please enter the verification code",
|
||||
myInfo: "My Information",
|
||||
user: {
|
||||
greeting: "Hello",
|
||||
profile: "Account Info",
|
||||
logout: "Logout",
|
||||
setting: {
|
||||
grantSetting: "Grant Settings",
|
||||
saveSuccess: "Save Success",
|
||||
allowAdminViewCerts: "Allow Admin view and download Certs",
|
||||
allowAdminViewCertsHelper: "Allow admin view and download all certificates",
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,73 @@
|
||||
export default {
|
||||
certificateRepo: {
|
||||
title: "Certificate Repository",
|
||||
sub: "Certificates generated from pipeline",
|
||||
},
|
||||
actionImportBatch: "Batch Import",
|
||||
actionSyncIp: "Sync IP",
|
||||
modalTitleSyncIp: "Sync IP",
|
||||
modalContentSyncIp: "Are you sure to sync IP?",
|
||||
notificationSyncComplete: "Sync Complete",
|
||||
actionCheckAll: "Check All",
|
||||
modalTitleConfirm: "Confirm",
|
||||
modalContentCheckAll: "Confirm to trigger checking all IP site's certificates?",
|
||||
notificationCheckSubmitted: "Check task submitted",
|
||||
notificationCheckDescription: "Please refresh later to see results",
|
||||
tooltipCheckNow: "Check Now",
|
||||
notificationCheckSubmittedPleaseRefresh: "Check task submitted, please refresh later",
|
||||
columnId: "ID",
|
||||
columnIp: "IP",
|
||||
helperIpCname: "Supports entering CNAME domain name or source site domain name",
|
||||
ruleIpRequired: "Please enter IP",
|
||||
columnCertDomains: "Certificate Domains",
|
||||
columnCertProvider: "Issuer",
|
||||
columnCertStatus: "Certificate Status",
|
||||
statusNormal: "Normal",
|
||||
statusExpired: "Expired",
|
||||
columnCertExpiresTime: "Certificate Expiration Time",
|
||||
columnCheckStatus: "Check Status",
|
||||
columnLastCheckTime: "Last Check Time",
|
||||
columnSource: "Source",
|
||||
sourceSync: "Sync",
|
||||
sourceManual: "Manual",
|
||||
sourceImport: "Import",
|
||||
columnDisabled: "Enabled/Disabled",
|
||||
columnRemark: "Remark",
|
||||
certificateNotGenerated: "Certificate not yet generated, please run the pipeline first",
|
||||
viewCertificateTitle: "View Certificate",
|
||||
viewCert: {
|
||||
title: "View Certificate",
|
||||
},
|
||||
download: {
|
||||
title: "Download Certificate",
|
||||
},
|
||||
checkStatus: {
|
||||
success: "Success",
|
||||
checking: "Checking",
|
||||
error: "Error",
|
||||
},
|
||||
uploadCustomCert: "Upload Custom Certificate",
|
||||
sourcePipeline: "Cert Apply Pipeline",
|
||||
sourceManualUpload: "Hosted Pipeline",
|
||||
domains: "Domains",
|
||||
enterDomain: "Please enter domain",
|
||||
validDays: "Valid Days",
|
||||
effectiveTime: "Effective Time",
|
||||
expireTime: "Expiration Time",
|
||||
certIssuer: "Certificate Issuer",
|
||||
applyTime: "Application Time",
|
||||
relatedPipeline: "Related Pipeline",
|
||||
statusSuccess: "Success",
|
||||
statusChecking: "Checking",
|
||||
statusError: "Error",
|
||||
modal: {
|
||||
close: "Close",
|
||||
viewCertificateTitle: "View Certificate",
|
||||
},
|
||||
domainList: {
|
||||
title: "Domain List",
|
||||
helper: "Format: domain:port:name:remark, one per line. Port and name are optional.\nExamples:\nwww.baidu.com:443:Baidu:remarkText\nwww.taobao.com::Taobao\nwww.google.com",
|
||||
required: "Please enter domains to import",
|
||||
placeholder: "www.baidu.com:443:Baidu\nwww.taobao.com::Taobao\nwww.google.com\n",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,61 @@
|
||||
export default {
|
||||
framework: {
|
||||
title: "Framework",
|
||||
home: "Home",
|
||||
},
|
||||
title: "Certificate Automation",
|
||||
pipeline: "Pipeline",
|
||||
pipelineEdit: "Edit Pipeline",
|
||||
history: "Execution History",
|
||||
certStore: "Certificate Repository",
|
||||
siteMonitor: "Site Certificate Monitor",
|
||||
settings: "Settings",
|
||||
accessManager: "Access Management",
|
||||
subDomain: "Subdomain Delegation Settings",
|
||||
pipelineGroup: "Pipeline Group Management",
|
||||
openKey: "Open API Key",
|
||||
notification: "Notification Settings",
|
||||
siteMonitorSetting: "Site Monitor Settings",
|
||||
userSecurity: "Security Settings",
|
||||
userProfile: "Account Info",
|
||||
userGrant: "Grant Delegation",
|
||||
mySuite: "My Suite",
|
||||
suiteBuy: "Suite Purchase",
|
||||
myTrade: "My Orders",
|
||||
paymentReturn: "Payment Return",
|
||||
source: "Source Code",
|
||||
github: "GitHub",
|
||||
gitee: "Gitee",
|
||||
sysResources: {
|
||||
sysRoot: "System Management",
|
||||
sysConsole: "Console",
|
||||
sysSettings: "System Settings",
|
||||
cnameSetting: "CNAME Service Settings",
|
||||
emailSetting: "Email Server Settings",
|
||||
siteSetting: "Site Personalization",
|
||||
headerMenus: "Top Menu Settings",
|
||||
sysAccess: "System-level Authorization",
|
||||
sysPlugin: "Plugin Management",
|
||||
sysPluginEdit: "Edit Plugin",
|
||||
sysPluginConfig: "Certificate Plugin Configuration",
|
||||
accountBind: "Account Binding",
|
||||
permissionManager: "Permission Management",
|
||||
roleManager: "Role Management",
|
||||
userManager: "User Management",
|
||||
suiteManager: "Suite Management",
|
||||
suiteSetting: "Suite Settings",
|
||||
orderManager: "Order Management",
|
||||
userSuites: "User Suites",
|
||||
netTest: "Network Test",
|
||||
|
||||
enterpriseSetting: "Enterprise Settings",
|
||||
projectManager: "Project Management",
|
||||
projectUserManager: "Project User Management",
|
||||
myProjectManager: "My Projects",
|
||||
myProjectDetail: "Project Detail",
|
||||
projectJoin: "Join Project",
|
||||
currentProject: "Current Project",
|
||||
projectMemberManager: "Project Member",
|
||||
domainMonitorSetting: "Domain Monitor Settings",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
export default {
|
||||
email: {
|
||||
title: "Recipient Email",
|
||||
helper: "Enter your recipient email addresses. Multiple addresses are supported.",
|
||||
required: "This field is required",
|
||||
},
|
||||
notificationDefault: "Use Default Notification",
|
||||
notificationType: "Notification Type",
|
||||
selectNotificationType: "Please select a notification type",
|
||||
confirmSetDefaultNotification: "Are you sure to set as default notification?",
|
||||
edit_notification: "Edit Notification",
|
||||
other_notification_method: "Other Notification Method",
|
||||
notificationName: "Notification Name",
|
||||
helperNotificationName: "Fill freely, helps to distinguish when multiple notifications of the same type exist",
|
||||
};
|
||||
@@ -0,0 +1,14 @@
|
||||
export default {
|
||||
scope: "Scope",
|
||||
scopeOpenApiOnly: "Open API Only",
|
||||
scopeFullAccount: "Full Account Permissions",
|
||||
scopeHelper: "Open API only allows access to open APIs; full account permissions allow access to all APIs",
|
||||
gen: {
|
||||
text: "API Test",
|
||||
title: "x-certd-token",
|
||||
okText: "Confirm",
|
||||
contentPart1: "Test the x-certd-token below, you can use it within 3 minutes to test ",
|
||||
openApi: "Open API",
|
||||
contentPart2: " request testing",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,124 @@
|
||||
export default {
|
||||
hasExpired: "Expired",
|
||||
subdomainHosting: "Subdomain Hosting",
|
||||
subdomainHostingHint: "When your domain has subdomain hosting set, you need to create records here, otherwise certificate application will fail",
|
||||
subdomainHosted: "Hosted Subdomain",
|
||||
subdomainHelpText: "If you don't understand what subdomain hosting is,Do not set it randomly, as it may result in the inability to apply for the certificate. please refer to the documentation ",
|
||||
subdomainHelpSupportStart: "Supports * wildcard, indicating that all subdomains of the domain are hosted (free subdomains)",
|
||||
subdomainManagement: "Subdomain Management",
|
||||
pipelinePage: {
|
||||
addMore: "Add More Pipelines",
|
||||
aliyunSubscriptionPipeline: "Aliyun Subscription Pipeline",
|
||||
legoCertPipeline: "Lego Certificate Pipeline",
|
||||
customPipeline: "Custom Pipeline",
|
||||
batchAddPipeline: "Add Pipeline Use Template",
|
||||
myPipelinesDesc: "Pipeline Mode: Apply -> Deploy -> Schedule",
|
||||
},
|
||||
customPipeline: "Custom Pipeline",
|
||||
createCertdPipeline: "Create Certificate Pipeline",
|
||||
commercialCertHosting: "Commercial Certificate Hosting",
|
||||
tooltip: {
|
||||
manualUploadOwnCert: "Manually upload your own certificate for automatic deployment",
|
||||
noAutoApplyCommercialCert: "Does not automatically apply for commercial certificates",
|
||||
manualUploadOnUpdate: "Must manually upload once when the certificate is updated",
|
||||
},
|
||||
table: {
|
||||
confirmDeleteTitle: "Are you sure you want to delete?",
|
||||
confirmDeleteMessage: "This will delete all data related to the pipeline, including execution history, certificate files, and certificate repository records.",
|
||||
},
|
||||
play: {
|
||||
runPipeline: "Run Pipeline",
|
||||
confirm: "Confirm",
|
||||
confirmTrigger: "Are you sure you want to trigger the run?",
|
||||
pipelineStarted: "Pipeline has started running",
|
||||
},
|
||||
actions: {
|
||||
editPipeline: "Edit Pipeline",
|
||||
editConfigGroup: "Modify Configuration/Group",
|
||||
viewCertificate: "View Certificate",
|
||||
downloadCertificate: "Download Certificate",
|
||||
},
|
||||
pi: {
|
||||
validTime: "Piepline Valid Time",
|
||||
validTimeHelper: "Not filled in means permanent validity",
|
||||
},
|
||||
types: {
|
||||
certApply: "Cert Apply",
|
||||
certUpload: "Cert Upload",
|
||||
custom: "Custom",
|
||||
template: "Template",
|
||||
},
|
||||
myPipelines: "My Pipelines",
|
||||
selectedCount: "Selected {count} items",
|
||||
batchForceRerun: "Force Rerun",
|
||||
batchRerun: "Rerun",
|
||||
applyCertificate: "Apply for Certificate",
|
||||
cronForm: {
|
||||
title: "Scheduled Script",
|
||||
helper: "Click the button above to select the time for daily execution.\nIt is recommended to run once a day. Tasks will be skipped if the certificate is not expiring.",
|
||||
required: "This field is required",
|
||||
},
|
||||
plugin: {
|
||||
selectTitle: "Certificate Apply Plugin",
|
||||
jsAcme: "JS-ACME: Easy to use, powerful features [Recommended]",
|
||||
legoAcme: "Lego-ACME: Based on Lego, supports a wide range of DNS providers, suitable for users familiar with Lego",
|
||||
aliyunOrder: "Aliyun-Order: Get certificate from Aliyun certificate order",
|
||||
},
|
||||
pipelineForm: {
|
||||
createTitle: "Create Certificate Pipeline",
|
||||
moreParams: "More Parameters",
|
||||
triggerCronTitle: "Scheduled Trigger",
|
||||
triggerCronHelper:
|
||||
"Click the button above to choose a daily execution time.\nIt is recommended to trigger once per day. The task will be skipped if the certificate has not expired and will not be executed repeatedly.",
|
||||
notificationTitle: "Failure Notification",
|
||||
notificationWhen: "Notification Timing",
|
||||
notificationHelper: "Get real-time alerts when the task fails",
|
||||
groupIdTitle: "Pipeline Group",
|
||||
|
||||
addToMonitorEnabled: "Add to Cert Monitor",
|
||||
addToMonitorDomains: "Add to Monitor Domains",
|
||||
|
||||
webhookEnabled: "Webhook Enabled",
|
||||
webhookEnabledHelper: "Support webhook trigger pipeline, please check webhook address in trigger source",
|
||||
},
|
||||
template: {
|
||||
title: "Pipeline Template",
|
||||
edit: "Pipeline Template Edit",
|
||||
importCreate: "Pipeline Batch Create",
|
||||
// intro: "可根据模版批量创建流水线",
|
||||
intro: "Batch create pipeline based on template",
|
||||
createTemplate: "Create Template",
|
||||
useTemplate: "Use This Template",
|
||||
batchCreate: "Batch Create Pipeline",
|
||||
singleCreate: "Create Single Pipeline",
|
||||
templateName: "Template Name",
|
||||
enterTemplateName: "Please enter template name",
|
||||
copyPipelineConfig: "Copy this pipeline configuration as template source",
|
||||
pipeline: "Pipeline",
|
||||
},
|
||||
editSchedule: "Edit Schedule",
|
||||
webhook: "Webhook",
|
||||
timerTrigger: "Timer Trigger",
|
||||
schedule: "Schedule",
|
||||
selectCron: "Please select a schedule Cron",
|
||||
batchEditSchedule: "Batch Edit Schedule",
|
||||
editTrigger: "Edit Trigger",
|
||||
triggerName: "Trigger Name",
|
||||
confirmDeleteTrigger: "Are you sure you want to delete this trigger?",
|
||||
trigger_time: "Trigger Time",
|
||||
start_time: "At Start",
|
||||
success_time: "On Success",
|
||||
fail_to_success_time: "Fail to Success",
|
||||
fail_time: "On Failure",
|
||||
helper_suggest_fail_only: "It is recommended to select only 'On Failure' and 'Fail to Success'",
|
||||
notification_config: "Notification Configuration",
|
||||
please_select_notification: "Please select a notification method",
|
||||
please_select_type: "Please select type",
|
||||
please_select_trigger_time: "Please select notification trigger time",
|
||||
please_select_notification_config: "Please select notification configuration",
|
||||
confirm_delete_trigger: "Are you sure you want to delete this trigger?",
|
||||
dates: {
|
||||
years: "{count} years",
|
||||
months: "{count} months",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
export default {
|
||||
ent: {
|
||||
projectName: "Project Name",
|
||||
projectDescription: "Project Description",
|
||||
projectDetailManager: "Project Detail",
|
||||
projectDetailDescription: "Manage Project Members",
|
||||
projectPermission: "Permission",
|
||||
permission: {
|
||||
read: "Read",
|
||||
write: "Write",
|
||||
admin: "Admin",
|
||||
},
|
||||
projectMemberStatus: "Member Status",
|
||||
|
||||
isSystem: "Is System Project",
|
||||
isSystemHelper: "System-level projects allow running admin plugins",
|
||||
},
|
||||
project: {
|
||||
noProjectJoined: "You haven't joined any projects yet",
|
||||
applyToJoin: "Please apply to join a project to start using",
|
||||
projectList: "Project List",
|
||||
systemProjects: "System Project List",
|
||||
createdAt: "Created At",
|
||||
applyJoin: "Apply to Join",
|
||||
noSystemProjects: "No system projects available",
|
||||
fetchFailed: "Failed to fetch project list",
|
||||
applySuccess: "Application successful, waiting for admin approval",
|
||||
applyFailed: "Application failed, please try again later",
|
||||
leave: "Leave Project",
|
||||
leaveSuccess: "Leave project successful",
|
||||
leaveFailed: "Leave project failed, please try again later",
|
||||
applyJoinConfirm: "Are you sure you want to apply to join this project?",
|
||||
leaveConfirm: "Are you sure you want to leave this project?",
|
||||
viewDetail: "View Detail",
|
||||
projectManage: "Project Manage",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,67 @@
|
||||
export default {
|
||||
order: {
|
||||
confirmTitle: "Order Confirmation",
|
||||
package: "Package",
|
||||
description: "Description",
|
||||
specifications: "Specifications",
|
||||
pipeline: "Pipeline",
|
||||
domain: "Domain",
|
||||
deployTimes: "Deployments",
|
||||
monitorCount: "DomainMonitors",
|
||||
duration: "Duration",
|
||||
price: "Price",
|
||||
paymentMethod: "Payment Method",
|
||||
free: "Free",
|
||||
unit: {
|
||||
pieces: "pieces",
|
||||
count: "count",
|
||||
times: "times",
|
||||
},
|
||||
},
|
||||
gift_package: "Gift Package",
|
||||
package_name: "Package Name",
|
||||
click_to_select: "Click to select",
|
||||
please_select_package: "Please select a package",
|
||||
package: "Package",
|
||||
addon_package: "Addon Package",
|
||||
domain_count: "Domain Count",
|
||||
unit_count: "pcs",
|
||||
pipeline_count: "Pipeline Count",
|
||||
unit_item: "items",
|
||||
deploy_count: "Deploy Count",
|
||||
unit_times: "times",
|
||||
monitor_count: "Certificate Monitor Count",
|
||||
duration: "Duration",
|
||||
active_time: "Activation Time",
|
||||
expires_time: "Expiration Time",
|
||||
is_present: "Is Present",
|
||||
is_present_yes: "Yes",
|
||||
is_present_no: "No",
|
||||
ordera: "Order",
|
||||
supportBuy: "Support Purchase",
|
||||
intro: "Introduction",
|
||||
packageContent: "Package Content",
|
||||
maxDomainCount: "Max Domain Count",
|
||||
maxPipelineCount: "Max Pipeline Count",
|
||||
maxDeployCount: "Max Deploy Count",
|
||||
maxMonitorCount: "Max Monitor Count",
|
||||
price: "Price",
|
||||
durationPrices: "Duration Prices",
|
||||
packageName: "Package Name",
|
||||
addon: "Addon",
|
||||
typeHelper: "Suite: Only the most recently purchased one is active at a time\nAddon: Multiple can be purchased, effective immediately without affecting the suite\nThe quantities of suite and addon can be accumulated",
|
||||
pipelineCount: "Pipeline Count",
|
||||
unitPipeline: "pipelines",
|
||||
deployCount: "Deployment Count",
|
||||
unitDeploy: "times",
|
||||
monitorCount: "Certificate Monitor Count",
|
||||
unitCount: "pcs",
|
||||
durationPriceTitle: "Duration and Price",
|
||||
selectDuration: "Select Duration",
|
||||
supportPurchase: "Support Purchase",
|
||||
cannotPurchase: "Cannot Purchase",
|
||||
shelfStatus: "Shelf Status",
|
||||
onShelf: "On Shelf",
|
||||
offShelf: "Off Shelf",
|
||||
orderHelper: "Smaller values appear first",
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
export default {
|
||||
max50Chars: "Maximum 50 characters",
|
||||
permissionManagement: "Permission Management",
|
||||
adda: "Add",
|
||||
rootNode: "Root Node",
|
||||
permissionName: "Permission Name",
|
||||
enterPermissionName: "Please enter permission name",
|
||||
permissionCode: "Permission Code",
|
||||
enterPermissionCode: "Please enter permission code",
|
||||
max100Chars: "Maximum 100 characters",
|
||||
examplePermissionCode: "e.g.: sys:user:view",
|
||||
sortOrder: "Sort Order",
|
||||
sortRequired: "Sort order is required",
|
||||
parentNode: "Parent Node",
|
||||
roleManagement: "Role Management",
|
||||
assignPermissions: "Assign Permissions",
|
||||
roleName: "Role Name",
|
||||
enterRoleName: "Please enter role name",
|
||||
unlockLogin: "Unlock Login",
|
||||
notice: "Notice",
|
||||
confirmUnlock: "Are you sure you want to unlock this user's login?",
|
||||
unlockSuccess: "Unlock successful",
|
||||
enterUsername: "Please enter username",
|
||||
modifyPasswordIfFilled: "Fill in to change the password",
|
||||
emaila: "Email",
|
||||
mobile: "Mobile",
|
||||
validTime: "Valid Time",
|
||||
remark: "Remark",
|
||||
roles: "Roles",
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
export default {
|
||||
cnameTitle: "CNAME Service Configuration",
|
||||
cnameDescription:
|
||||
"The domain name configured here serves as a proxy for verifying other domains. When other domains apply for certificates, they map to this domain via CNAME for ownership verification. The advantage is that any domain can apply for a certificate this way without providing an AccessSecret.",
|
||||
cnameLinkText: "CNAME principle and usage instructions",
|
||||
cnameDomain: "CNAME Domain",
|
||||
cnameDomainPlaceholder: "cname.handsfree.work",
|
||||
cnameDomainHelper:
|
||||
"Requires a domain registered with a DNS provider on the right (or you can transfer other domain DNS servers here).\nOnce the CNAME domain is set, it cannot be changed. It is recommended to use a first-level subdomain.",
|
||||
cnameDomainPattern: "Domain name cannot contain *",
|
||||
dnsProvider: "DNS Provider",
|
||||
dnsProviderAuthorization: "DNS Provider Authorization",
|
||||
};
|
||||
@@ -0,0 +1,43 @@
|
||||
export default {
|
||||
titlea: "Title",
|
||||
pluginFile: "Plugin File",
|
||||
selectPluginFile: "Select plugin file",
|
||||
overrideSameName: "Override same name",
|
||||
override: "Override",
|
||||
noOverride: "No override",
|
||||
overrideHelper: "If a plugin with the same name exists, override it directly",
|
||||
importPlugin: "Import Plugin",
|
||||
customPlugin: "Custom Plugin",
|
||||
pluginType: "Plugin Type",
|
||||
auth: "Authorization",
|
||||
dns: "DNS",
|
||||
deployPlugin: "Deploy Plugin",
|
||||
icon: "Icon",
|
||||
pluginName: "Plugin Name",
|
||||
pluginNameHelper: "Must be English letters or digits, camelCase with type prefix\nExample: AliyunDeployToCDN\nDo not modify name once plugin is used",
|
||||
pluginNameRuleMsg: "Must be English letters or digits, camelCase with type prefix",
|
||||
author: "Author",
|
||||
authorHelper: "Used as prefix when uploading to plugin store, e.g., greper/pluginName",
|
||||
authorRuleMsg: "Must be English letters or digits",
|
||||
titleHelper: "Plugin name in Chinese",
|
||||
descriptionHelper: "Description of the plugin",
|
||||
builtIn: "Built-in",
|
||||
custom: "Custom",
|
||||
store: "Store",
|
||||
version: "Version",
|
||||
pluginDependencies: "Plugin Dependencies",
|
||||
pluginDependenciesHelper: "Dependencies to install first in format: [author/]pluginName[:version]",
|
||||
editableRunStrategy: "Editable Run Strategy",
|
||||
editable: "Editable",
|
||||
notEditable: "Not Editable",
|
||||
runStrategy: "Run Strategy",
|
||||
normalRun: "Normal Run",
|
||||
skipOnSuccess: "Skip on success (Deploy task)",
|
||||
defaultRunStrategyHelper: "Default run strategy",
|
||||
enableDisable: "Enable/Disable",
|
||||
confirmToggle: "Are you sure to",
|
||||
pluginGroup: "Plugin Group",
|
||||
pluginManagement: "Plugin Management",
|
||||
pluginBetaWarning: "Custom plugins are in BETA and may have breaking changes in future",
|
||||
pleaseSelectRecord: "Please select records first",
|
||||
};
|
||||
@@ -0,0 +1,188 @@
|
||||
export default {
|
||||
sys: {
|
||||
setting: {
|
||||
baseSetting: "Base Settings",
|
||||
registerSetting: "Register Settings",
|
||||
safeSetting: "Safe Settings",
|
||||
paymentSetting: "Payment Settings",
|
||||
captchaSetting: "Captcha Setting",
|
||||
pipelineSetting: "Pipeline Settings",
|
||||
oauthSetting: "Login Settings",
|
||||
networkSetting: "Network Settings",
|
||||
adminModeSetting: "Admin Mode Settings",
|
||||
adminModeHelper: "enterprise mode : allow to create and manage pipelines, roles, users, etc.\n saas mode : only allow to create and manage pipelines",
|
||||
enterpriseMode: "Enterprise Mode",
|
||||
saasMode: "SaaS Mode",
|
||||
|
||||
showRunStrategy: "Show RunStrategy",
|
||||
showRunStrategyHelper: "Allow modify the run strategy of the task",
|
||||
|
||||
captchaEnabled: "Enable Login Captcha",
|
||||
captchaHelper: "Whether to enable captcha verification for login",
|
||||
captchaType: "Captcha Setting",
|
||||
captchaTest: "Captcha Test",
|
||||
// 保存后再点击测试,请务必测试通过了,再开启登录验证码
|
||||
captchaTestHelper: "Save and click test, please make sure the test is passed before enabling login captcha",
|
||||
|
||||
pipelineValidTimeEnabled: "Enable Pipeline Valid Time",
|
||||
pipelineValidTimeEnabledHelper: "Whether to enable the valid time of the pipeline",
|
||||
certDomainAddToMonitorEnabled: "Add Domain to Certificate Monitor",
|
||||
certDomainAddToMonitorEnabledHelper: "Whether to add the domain to the certificate monitor",
|
||||
|
||||
defaultCertRenewDays: "Default Certificate Renew Days",
|
||||
defaultCertRenewDaysHelper: "Default certificate renewal days, helpful for table list progress bar display",
|
||||
defaultCertRenewDaysRecommend: "Recommend 15",
|
||||
|
||||
pipelineMaxRunningCount: "Max Running Count",
|
||||
pipelineMaxRunningCountHelper: "Max running count of the pipeline",
|
||||
pipelineMaxRunningCountRecommend: "Recommend 5-15, default 10",
|
||||
|
||||
acmeWalkFromAuthoritative: "Check TXT Record from Authoritative NS",
|
||||
acmeWalkFromAuthoritativeHelper: "Apply certificate when whether to check the TXT record from authoritative NS server first",
|
||||
|
||||
fixedCertExpireDays: "Fixed Cert Expire Days",
|
||||
fixedCertExpireDaysHelper: "Fixed cert expiration days, helpful for table list progress bar display",
|
||||
fixedCertExpireDaysRecommend: "Recommend 90",
|
||||
|
||||
enableOauth: "Enable OAuth2 Login",
|
||||
oauthEnabledHelper: "Whether to enable OAuth2 login",
|
||||
oauthProviders: "OAuth2 Login Providers",
|
||||
oauthType: "OAuth2 Login Type",
|
||||
oauthConfig: "OAuth2 Login Config",
|
||||
oauthProviderSelectorPlaceholder: "Not Configured",
|
||||
oauthCallback: "Callback URL",
|
||||
oauthCallbackHelper: "Copy this URL to the callback address of the OAuth2 login provider",
|
||||
oauthCallbackCopy: "Copy Callback URL",
|
||||
oauthAutoRegister: "Auto Register User",
|
||||
oauthAutoRegisterCheckedText: "Auto Register",
|
||||
oauthAutoRegisterUnCheckedText: "User Select",
|
||||
oauthAutoRegisterHelper: "Whether to auto register user when login",
|
||||
oauthAutoRedirect: "Auto Redirect to OAuth2 Login",
|
||||
oauthAutoRedirectHelper: "Whether to auto redirect to OAuth2 login when login (using the first enabled OAuth2 login type)",
|
||||
oauthOnly: "OAuth2 Login Only",
|
||||
oauthOnlyHelper: "Whether to only allow OAuth2 login, disable password login",
|
||||
enablePasskey: "Enable Passkey Login",
|
||||
passkeyHostnameNotSame: "Passkey hostname must be the same as the main domain",
|
||||
passkeyEnabledHelper:
|
||||
"1、Site must enable https \n2、Domain name must not change, otherwise the registered passkey will be invalid \n3、Domain name must be the same as the main domain, otherwise the registered passkey will be invalid",
|
||||
|
||||
email: {
|
||||
templates: "Email Templates",
|
||||
templateType: "Template Type",
|
||||
templateProvider: "Template Config",
|
||||
|
||||
templateSetting: "Email Template Setting",
|
||||
serverSetting: "Email Server Setting",
|
||||
sendTest: "Send Test",
|
||||
|
||||
templateProviderSelectorPlaceholder: "Not Configured",
|
||||
},
|
||||
notice: "System Notice",
|
||||
noticeHelper: "System notice, will be displayed on the login page",
|
||||
noticePlaceholder: "System notice",
|
||||
customFooter: "Custom Footer",
|
||||
customFooterHelper: "Custom site footer, displayed at the bottom of the page, support HTML format",
|
||||
customFooterPlaceholder: "Custom footer content",
|
||||
|
||||
reverseProxy: "Reverse Proxy List",
|
||||
reverseProxyHelper: "Reverse proxy for ACME address, used when applying for certificate",
|
||||
reverseProxyPlaceholder: "http://le.px.handfree.work",
|
||||
reverseProxyEmpty: "No reverse proxy list configured",
|
||||
environmentVars: "Environment Variables",
|
||||
environmentVarsHelper: "configure the runtime environment variables, one per line, format: KEY=VALUE",
|
||||
|
||||
bindUrl: "Bind URL",
|
||||
bindUrlHelper: "Bind URL, used as your site URL in notifications",
|
||||
},
|
||||
},
|
||||
icpRegistrationNumber: "ICP Registration Number",
|
||||
icpPlaceholder: "Guangdong ICP xxxxxxx Number",
|
||||
publicSecurityRegistrationNumber: "Public Security Registration Number",
|
||||
publicSecurityPlaceholder: "Beijing Public Security xxxxxxx Number",
|
||||
enableAssistant: "Enable Assistant",
|
||||
allowCrawlers: "Allow Crawlers",
|
||||
httpProxy: "HTTP Proxy",
|
||||
httpProxyPlaceholder: "http://192.168.1.2:18010/",
|
||||
httpProxyHelper: "Configure when some websites are blocked",
|
||||
httpsProxy: "HTTPS Proxy",
|
||||
httpsProxyPlaceholder: "http://192.168.1.2:18010/",
|
||||
saveThenTestTitle: "Save first, then click test",
|
||||
httpsProxyHelper: "Usually both proxies are the same, save first then test",
|
||||
dualStackNetwork: "Dual Stack Network",
|
||||
ipv4Priority: "IPv4 Priority",
|
||||
ipv6Priority: "IPv6 Priority",
|
||||
dualStackNetworkHelper: "If IPv6 priority is selected, enable IPv6 in docker-compose.yaml",
|
||||
enableCommonCnameService: "Enable Public CNAME Service",
|
||||
commonCnameHelper: "Allow use of public CNAME service. If disabled and no <a href='#/sys/cname/provider'>custom CNAME service</a> is set, CNAME proxy certificate application will not work.",
|
||||
enableCommonSelfServicePasswordRetrieval: "Enable self-service password recovery",
|
||||
saveButton: "Save",
|
||||
stopSuccess: "Stopped successfully",
|
||||
google: "Google",
|
||||
baidu: "Baidu",
|
||||
testFailed: "Test Failed",
|
||||
testCompleted: "Test Completed",
|
||||
manageOtherUserPipeline: "Manage other users' pipelines",
|
||||
limitUserPipelineCount: "Limit user pipeline count",
|
||||
limitUserPipelineCountHelper: "0 means no limit",
|
||||
enableSelfRegistration: "Enable self-registration",
|
||||
enableUserValidityPeriod: "Enable user validity period",
|
||||
userValidityPeriodHelper: "Users can use normally within validity; pipelines disabled after expiry",
|
||||
enableUsernameRegistration: "Enable username registration",
|
||||
enableEmailRegistration: "Enable email registration",
|
||||
proFeature: "Pro feature",
|
||||
emailServerSetup: "Set up email server",
|
||||
enableSmsLoginRegister: "Enable SMS login and registration",
|
||||
commFeature: "Commercial feature",
|
||||
smsProvider: "SMS provider",
|
||||
aliyunSms: "Aliyun SMS",
|
||||
tencentSms: "Tencent SMS",
|
||||
yfySms: "YFY SMS",
|
||||
smsTest: "SMS test",
|
||||
testMobilePlaceholder: "Enter test mobile number",
|
||||
saveThenTest: "Save first then test",
|
||||
enterTestMobile: "Please enter test mobile number",
|
||||
sendSuccess: "Sent successfully",
|
||||
atLeastOneLoginRequired: "At least one of password login or SMS login must be enabled",
|
||||
siteHide: "Site Hide",
|
||||
enableSiteHide: "Enable Site Hide",
|
||||
siteHideDescription: "You can disable site accessibility normally and enable it when needed to enhance site security",
|
||||
randomAddress: "Random Address",
|
||||
siteHideUrlHelper: "After the site is hidden, you need to visit this URL to unlock to access normally",
|
||||
fullUnlockUrl: "Full Unlock URL",
|
||||
saveThisUrl: "Please save this URL carefully",
|
||||
unlockPassword: "Unlock Password",
|
||||
unlockPasswordHelper: "Password needed to unlock the hide; set on first time or reset when filled",
|
||||
autoHideTime: "Auto Hide Time",
|
||||
autoHideTimeHelper: "Minutes without requests before auto hiding",
|
||||
hideOpenApi: "Hide Open API",
|
||||
hideOpenApiHelper: "Whether to hide open APIs; whether to hide /api/v1 prefixed endpoints",
|
||||
hideSiteImmediately: "Hide Site Immediately",
|
||||
hideImmediately: "Hide Immediately",
|
||||
confirmHideSiteTitle: "Are you sure to hide the site immediately?",
|
||||
confirmHideSiteContent: "After hiding, the site will be inaccessible. Please operate cautiously.",
|
||||
siteHiddenSuccess: "Site has been hidden",
|
||||
emailServerSettings: "Email Server Settings",
|
||||
setEmailSendingServer: "Set the email sending server",
|
||||
useCustomEmailServer: "Use Custom Email Server",
|
||||
smtpDomain: "SMTP Domain",
|
||||
pleaseEnterSmtpDomain: "Please enter SMTP domain or IP",
|
||||
smtpPort: "SMTP Port",
|
||||
pleaseEnterSmtpPort: "Please enter SMTP port",
|
||||
pleaseEnterUsername: "Please enter username",
|
||||
pleaseEnterPassword: "Please enter password",
|
||||
qqEmailAuthCodeHelper: "If using QQ email, get an authorization code in QQ email settings as the password",
|
||||
senderEmailHelper: "You can use the format: Name<Email> to set the sender name, e.g.: autossl<certd{'@'}example.com>",
|
||||
senderEmail: "Sender Email",
|
||||
pleaseEnterSenderEmail: "Please enter sender email",
|
||||
useSsl: "Use SSL",
|
||||
sslPortNote: "SSL and non-SSL SMTP ports are different, please adjust port accordingly",
|
||||
ignoreCertValidation: "Ignore Certificate Validation",
|
||||
useOfficialEmailServer: "Use Official Email Server",
|
||||
useOfficialEmailServerHelper: "Send emails directly using the official server to avoid complicated setup",
|
||||
testReceiverEmail: "Test Receiver Email",
|
||||
pleaseEnterTestReceiverEmail: "Please enter test receiver email",
|
||||
saveBeforeTest: "Save before testing",
|
||||
sendFailHelpDoc: "Failed to send??? ",
|
||||
emailConfigHelpDoc: "Email configuration help document",
|
||||
tryOfficialEmailServer: "You can also try using the official email server ↗↗↗↗↗↗↗↗",
|
||||
};
|
||||
@@ -0,0 +1,7 @@
|
||||
export default {
|
||||
steps: {
|
||||
createPipeline: "Create Certificate Pipeline",
|
||||
addTask: "Add Deployment Task",
|
||||
scheduledRun: "Scheduled Run",
|
||||
},
|
||||
};
|
||||
@@ -7,8 +7,13 @@ export default {
|
||||
settingLink: "Site Monitoring Settings",
|
||||
limitInfo: "Basic edition limited to 1, professional and above unlimited, current",
|
||||
checkAll: "Check All",
|
||||
checkNow: "Check Now",
|
||||
batchDelete: "Batch Delete",
|
||||
confirmTitle: "Confirm",
|
||||
confirmContent: "Confirm to trigger check for all site certificates?",
|
||||
batchDeleteConfirm: "Are you sure you want to batch delete these {count} records?",
|
||||
deleteSuccess: "Delete successful",
|
||||
selectRecordsFirst: "Please select records first",
|
||||
checkSubmitted: "Check task submitted",
|
||||
pleaseRefresh: "Please refresh the page later to see the results",
|
||||
siteName: "Site Name",
|
||||
@@ -39,6 +44,10 @@ export default {
|
||||
ipCheckHelper: "Enable to check certificate expiration time on each IP (or source site domain) ",
|
||||
ipSyncAuto: "Enable IP Sync Auto",
|
||||
ipSyncMode: "IP Sync Mode",
|
||||
ipSyncModeHelper: "Choose whether to check only IPv4, only IPv6, or all IPs.",
|
||||
ipSyncModeAll: "Check all IPs",
|
||||
ipSyncModeIPV4Only: "Check IPv4 only",
|
||||
ipSyncModeIPV6Only: "Check IPv6 only",
|
||||
ipIgnoreCoherence: "Ignore Certificate Coherence",
|
||||
ipIgnoreCoherenceHelper: "Enable to ignore certificate coherence check, only check certificate expiration time",
|
||||
selectRequired: "Please select",
|
||||
@@ -49,6 +58,10 @@ export default {
|
||||
certInfoId: "Certificate ID",
|
||||
checkSubmittedRefresh: "Check task submitted. Please refresh later to view the result.",
|
||||
ipManagement: "IP Management",
|
||||
siteIpMonitor: "Site IP Monitor",
|
||||
ipList: "IP List",
|
||||
ipListHelper: "One IP or CNAME domain per line",
|
||||
enterImportIpOrDomain: "Please enter the IPs or domains to import",
|
||||
bulkImport: "Bulk Import",
|
||||
basicLimitError: "Basic version allows only one monitoring site. Please upgrade to the Pro version.",
|
||||
limitExceeded: "Sorry, you can only create up to {max} monitoring records. Please purchase or upgrade your plan.",
|
||||
|
||||
@@ -1,877 +1,46 @@
|
||||
//注意: @符号是保留字符,需要用{'@'}替换, AI请务必提醒我修改
|
||||
import common from "./certd/common";
|
||||
import navigation from "./certd/navigation";
|
||||
import dashboard from "./certd/dashboard";
|
||||
import pipeline from "./certd/pipeline";
|
||||
import history from "./certd/history";
|
||||
import monitor from "./certd/monitor";
|
||||
import certdomain from "./certd/cert-domain";
|
||||
import cname from "./certd/cname";
|
||||
import access from "./certd/access";
|
||||
import open from "./certd/open";
|
||||
import mine from "./certd/mine";
|
||||
import notification from "./certd/notification";
|
||||
import addon from "./certd/addon";
|
||||
import suite from "./certd/suite";
|
||||
import project from "./certd/project";
|
||||
import syssettings from "./certd/sys-settings";
|
||||
import sysplugin from "./certd/sys-plugin";
|
||||
import sysauthority from "./certd/sys-authority";
|
||||
import syscname from "./certd/sys-cname";
|
||||
import tutorial from "./certd/tutorial";
|
||||
import cron from "./certd/cron";
|
||||
|
||||
// Note: @ is reserved in locale messages; use {'@'} when needed.
|
||||
export default {
|
||||
app: {
|
||||
crud: {
|
||||
i18n: {
|
||||
name: "姓名",
|
||||
city: "城市",
|
||||
status: "状态",
|
||||
},
|
||||
},
|
||||
login: {
|
||||
logoutTip: "确认",
|
||||
logoutMessage: "确定要注销登录吗?",
|
||||
},
|
||||
},
|
||||
fs: {
|
||||
rowHandle: {
|
||||
title: "操作列",
|
||||
},
|
||||
},
|
||||
pipelinePage: {
|
||||
addMore: "添加更多流水线",
|
||||
aliyunSubscriptionPipeline: "阿里云订阅流水线",
|
||||
legoCertPipeline: "Lego证书流水线",
|
||||
customPipeline: "自定义流水线",
|
||||
batchAddPipeline: "模版批量创建流水线",
|
||||
myPipelinesDesc: "流水线模式:申请证书->部署证书->定时运行",
|
||||
},
|
||||
order: {
|
||||
confirmTitle: "订单确认",
|
||||
package: "套餐",
|
||||
description: "说明",
|
||||
specifications: "规格",
|
||||
pipeline: "流水线",
|
||||
domain: "域名",
|
||||
deployTimes: "部署次数",
|
||||
monitorCount: "域名监控数",
|
||||
duration: "时长",
|
||||
price: "价格",
|
||||
paymentMethod: "支付方式",
|
||||
free: "免费",
|
||||
unit: {
|
||||
pieces: "条",
|
||||
count: "个",
|
||||
times: "次",
|
||||
},
|
||||
},
|
||||
framework: {
|
||||
title: "框架",
|
||||
home: "首页",
|
||||
},
|
||||
helpDocLink: "帮助文档",
|
||||
title: "证书自动化",
|
||||
pipeline: "证书自动化流水线",
|
||||
pipelineEdit: "编辑流水线",
|
||||
history: "执行历史记录",
|
||||
certStore: "证书仓库",
|
||||
siteMonitor: "站点证书监控",
|
||||
settings: "设置",
|
||||
accessManager: "授权管理",
|
||||
cnameRecord: "CNAME记录管理",
|
||||
subDomain: "子域名托管设置",
|
||||
pipelineGroup: "流水线分组管理",
|
||||
openKey: "开放接口密钥",
|
||||
notification: "通知设置",
|
||||
siteMonitorSetting: "站点监控设置",
|
||||
userSecurity: "认证安全设置",
|
||||
userProfile: "账号信息",
|
||||
userGrant: "授权委托",
|
||||
suite: "套餐",
|
||||
mySuite: "我的套餐",
|
||||
suiteBuy: "套餐购买",
|
||||
myTrade: "我的订单",
|
||||
paymentReturn: "支付返回",
|
||||
hasExpired: "已过期",
|
||||
|
||||
user: {
|
||||
greeting: "您好",
|
||||
profile: "账号信息",
|
||||
logout: "注销登录",
|
||||
|
||||
setting: {
|
||||
grantSetting: "授权委托设置",
|
||||
saveSuccess: "保存成功",
|
||||
allowAdminViewCerts: "授权管理员查看和下载证书",
|
||||
allowAdminViewCertsHelper: "允许管理员查看和下载我的所有证书",
|
||||
},
|
||||
},
|
||||
dashboard: {
|
||||
greeting: "您好,{name},欢迎使用 【{site}】",
|
||||
latestVersion: "最新版本: {version}",
|
||||
validUntil: "账户有效期:",
|
||||
tutorialTooltip: "点击查看详细教程",
|
||||
tutorialText: "仅需3步,全自动申请部署证书",
|
||||
alertMessage: "证书和授权为敏感信息,不要使用来历不明的在线Certd服务和镜像,以免泄露;请务必私有化部署使用,认准官方版本发布渠道:",
|
||||
helpDoc: "帮助文档",
|
||||
pipelineCount: "证书流水线数量",
|
||||
enabledCount: "已启用",
|
||||
disabledCount: "已禁用",
|
||||
noPipeline: "您还没有证书流水线",
|
||||
certCount: "证书数量",
|
||||
certExpiringCount: "即将过期",
|
||||
certExpiredCount: "已过期",
|
||||
certNoExpireCount: "未过期",
|
||||
noCert: "还没有证书",
|
||||
manageCert: "查看证书",
|
||||
|
||||
createNow: "立即创建",
|
||||
managePipeline: "管理流水线",
|
||||
pipelineStatus: "流水线状态",
|
||||
recentRun: "最近运行统计",
|
||||
runCount: "运行次数",
|
||||
expiringCerts: "最快到期证书",
|
||||
supportedTasks: "已支持的部署任务总览",
|
||||
changeLog: "更新日志",
|
||||
},
|
||||
steps: {
|
||||
createPipeline: "创建证书流水线",
|
||||
addTask: "添加部署任务",
|
||||
scheduledRun: "定时运行",
|
||||
},
|
||||
customPipeline: "自定义流水线",
|
||||
createCertdPipeline: "创建证书流水线",
|
||||
commercialCertHosting: "已有证书托管",
|
||||
tooltip: {
|
||||
manualUploadOwnCert: "手动上传自有证书,执行自动部署",
|
||||
noAutoApplyCommercialCert: "并不能自动申请商业证书",
|
||||
manualUploadOnUpdate: "证书有更新时,都需要手动上传一次",
|
||||
},
|
||||
table: {
|
||||
confirmDeleteTitle: "确定要删除吗?",
|
||||
confirmDeleteMessage: "将删除该流水线相关的所有数据,包括执行历史、证书文件、证书仓库记录等",
|
||||
},
|
||||
play: {
|
||||
runPipeline: "运行流水线",
|
||||
confirm: "确认",
|
||||
confirmTrigger: "确定要触发运行吗?",
|
||||
pipelineStarted: "管道已经开始运行",
|
||||
},
|
||||
actions: {
|
||||
editPipeline: "编辑流水线",
|
||||
editConfigGroup: "修改配置/分组",
|
||||
viewCertificate: "查看证书",
|
||||
downloadCertificate: "下载证书",
|
||||
},
|
||||
fields: {
|
||||
userId: "用户Id",
|
||||
pipelineName: "流水线名称",
|
||||
keyword: "关键字",
|
||||
required: "此项必填",
|
||||
pipelineContent: "流水线内容",
|
||||
scheduledTaskCount: "定时任务数",
|
||||
deployTaskCount: "部署任务数",
|
||||
remainingValidity: "到期剩余",
|
||||
effectiveTime: "生效时间",
|
||||
expiryTime: "过期时间",
|
||||
status: "状态",
|
||||
lastRun: "最后运行",
|
||||
enabled: "启用",
|
||||
enabledLabel: "启用",
|
||||
disabledLabel: "禁用",
|
||||
group: "分组",
|
||||
type: "类型",
|
||||
order: "排序号",
|
||||
keepHistoryCount: "历史记录保持数",
|
||||
keepHistoryHelper: "历史记录保持条数,多余的会被删除",
|
||||
createTime: "创建时间",
|
||||
updateTime: "更新时间",
|
||||
triggerType: "触发类型",
|
||||
pipelineId: "流水线Id",
|
||||
nextRunTime: "下次运行时间",
|
||||
projectName: "项目",
|
||||
adminId: "管理员",
|
||||
},
|
||||
pi: {
|
||||
validTime: "流水线有效期",
|
||||
validTimeHelper: "不填则为永久有效",
|
||||
},
|
||||
types: {
|
||||
certApply: "证书申请",
|
||||
certUpload: "证书上传",
|
||||
custom: "自定义",
|
||||
template: "模版",
|
||||
},
|
||||
myPipelines: "我的流水线",
|
||||
selectedCount: "已选择 {count} 项",
|
||||
batchDelete: "批量删除",
|
||||
batchForceRerun: "强制重新运行",
|
||||
batchRerun: "重新运行",
|
||||
applyCertificate: "申请证书",
|
||||
pipelineExecutionRecords: "流水线执行记录",
|
||||
confirm: "确认",
|
||||
confirmBatchDeleteContent: "确定要批量删除这{count}条记录吗",
|
||||
deleteSuccess: "删除成功",
|
||||
pleaseSelectRecords: "请先勾选记录",
|
||||
triggerTypes: {
|
||||
manual: "手动执行",
|
||||
timer: "定时执行",
|
||||
},
|
||||
sysResources: {
|
||||
sysRoot: "系统管理",
|
||||
sysConsole: "控制台",
|
||||
sysSettings: "系统设置",
|
||||
cnameSetting: "CNAME服务设置",
|
||||
emailSetting: "邮件服务器设置",
|
||||
siteSetting: "站点个性化",
|
||||
headerMenus: "顶部菜单设置",
|
||||
sysAccess: "系统级授权",
|
||||
sysPlugin: "插件管理",
|
||||
sysPluginEdit: "编辑插件",
|
||||
sysPluginConfig: "证书插件配置",
|
||||
accountBind: "账号绑定",
|
||||
permissionManager: "权限管理",
|
||||
roleManager: "角色管理",
|
||||
userManager: "用户管理",
|
||||
suiteManager: "套餐管理",
|
||||
suiteSetting: "套餐设置",
|
||||
orderManager: "订单管理",
|
||||
userSuites: "用户套餐",
|
||||
netTest: "网络测试",
|
||||
enterpriseManager: "企业管理设置",
|
||||
projectManager: "项目管理",
|
||||
enterpriseSetting: "企业设置",
|
||||
myProjectManager: "我的项目",
|
||||
myProjectDetail: "项目详情",
|
||||
projectJoin: "加入项目",
|
||||
currentProject: "当前项目",
|
||||
projectMemberManager: "项目成员管理",
|
||||
domainMonitorSetting: "域名监控设置",
|
||||
jobHistory: "监控执行记录",
|
||||
},
|
||||
certificateRepo: {
|
||||
title: "证书仓库",
|
||||
sub: "从流水线生成的证书",
|
||||
},
|
||||
|
||||
certificateNotGenerated: "证书还未生成,请先运行流水线",
|
||||
viewCertificateTitle: "查看证书",
|
||||
close: "关闭",
|
||||
viewCert: {
|
||||
title: "查看证书",
|
||||
},
|
||||
download: {
|
||||
title: "下载证书",
|
||||
},
|
||||
source: "源码",
|
||||
github: "github",
|
||||
gitee: "gitee",
|
||||
cron: {
|
||||
clearTip: "清除选择",
|
||||
nextTrigger: "下次触发时间",
|
||||
tip: "请先设置正确的cron表达式",
|
||||
},
|
||||
cronForm: {
|
||||
title: "定时脚本",
|
||||
helper: "点击上面的按钮,选择每天几点定时执行。\n建议设置为每天触发一次,证书未到期之前任务会跳过,不会重复执行",
|
||||
required: "此项必填",
|
||||
},
|
||||
email: {
|
||||
title: "收件邮箱",
|
||||
helper: "输入你的收件邮箱地址,支持多个邮箱",
|
||||
required: "此项必填",
|
||||
},
|
||||
plugin: {
|
||||
selectTitle: "证书申请插件",
|
||||
jsAcme: "JS-ACME:使用简单方便,功能强大【推荐】",
|
||||
legoAcme: "Lego-ACME:基于Lego实现,支持海量DNS提供商,熟悉LEGO的用户可以使用",
|
||||
aliyunOrder: "Aliyun-Order:从阿里云证书订单中获取证书更新",
|
||||
},
|
||||
pipelineForm: {
|
||||
createTitle: "创建证书流水线",
|
||||
moreParams: "更多参数",
|
||||
triggerCronTitle: "定时触发",
|
||||
triggerCronHelper: "点击上面的按钮,选择每天几点定时执行。\n建议设置为每天触发一次,证书未到期之前任务会跳过,不会重复执行",
|
||||
notificationTitle: "失败通知",
|
||||
notificationWhen: "通知时机",
|
||||
notificationHelper: "任务执行失败实时提醒",
|
||||
groupIdTitle: "流水线分组",
|
||||
addToMonitorEnabled: "添加到证书监控",
|
||||
addToMonitorDomains: "添加到监控域名",
|
||||
webhookEnabled: "开启Webhook",
|
||||
webhookEnabledHelper: "支持webhook触发流水线,请在触发源中查看webhook地址",
|
||||
},
|
||||
notificationDefault: "使用默认通知",
|
||||
checkStatus: {
|
||||
success: "成功",
|
||||
checking: "检查中",
|
||||
error: "异常",
|
||||
},
|
||||
domainList: {
|
||||
title: "域名列表",
|
||||
helper: "格式【域名:端口:名称:备注】,一行一个,其中端口、名称、备注可以省略\n比如:\nwww.baidu.com:443:百度:备注文本\nwww.taobao.com::淘宝\nwww.google.com",
|
||||
required: "请输入要导入的域名",
|
||||
placeholder: "www.baidu.com:443:百度:备注文本\nwww.taobao.com::淘宝\nwww.google.com\n",
|
||||
},
|
||||
accountInfo: "账号信息",
|
||||
securitySettings: "认证安全设置",
|
||||
confirmDisable2FA: "确定要关闭多重验证登录吗?",
|
||||
disabledSuccess: "关闭成功",
|
||||
saveSuccess: "保存成功",
|
||||
twoFactorAuth: "2FA多重验证登录",
|
||||
rebind: "重新绑定",
|
||||
twoFactorAuthHelper: "是否开启多重验证登录",
|
||||
bindDevice: "绑定设备",
|
||||
step1: "1. 安装任意一款支持Authenticator的验证APP,比如:",
|
||||
tooltipGoogleServiceError: "如果报没有找到谷歌服务的错误,您可以安装KK谷歌助手",
|
||||
step2: "2. 扫描二维码添加账号",
|
||||
step3: "3. 输入验证码",
|
||||
inputVerifyCode: "请输入验证码",
|
||||
cancel: "取消",
|
||||
authorizationManagement: "授权管理",
|
||||
manageThirdPartyAuth: "管理第三方系统授权信息",
|
||||
name: "名称",
|
||||
pleaseEnterName: "请填写名称",
|
||||
nameHelper: "随便填,当多个相同类型的授权时,便于区分",
|
||||
level: "级别",
|
||||
system: "系统",
|
||||
usera: "用户",
|
||||
nickName: "昵称",
|
||||
max50Chars: "最大50个字符",
|
||||
myInfo: "我的信息",
|
||||
|
||||
save: "保存",
|
||||
editSchedule: "修改定时",
|
||||
timerTrigger: "定时触发",
|
||||
schedule: "定时",
|
||||
webhook: "Webhook",
|
||||
selectCron: "请选择定时Cron",
|
||||
batchEditSchedule: "批量修改定时",
|
||||
editTrigger: "编辑触发器",
|
||||
triggerName: "触发器名称",
|
||||
requiredField: "此项必填",
|
||||
type: "类型",
|
||||
enterName: "请输入名称",
|
||||
confirmDeleteTrigger: "确定要删除此触发器吗?",
|
||||
notificationType: "通知类型",
|
||||
selectNotificationType: "请选择通知类型",
|
||||
notificationName: "通知名称",
|
||||
helperNotificationName: "随便填,当多个相同类型的通知时,便于区分",
|
||||
isDefault: "是否默认",
|
||||
yes: "是",
|
||||
no: "否",
|
||||
selectIsDefault: "请选择是否默认",
|
||||
prompt: "提示",
|
||||
confirmSetDefaultNotification: "确定设置为默认通知?",
|
||||
test: "测试",
|
||||
scope: "权限范围",
|
||||
scopeOpenApiOnly: "仅开放接口",
|
||||
scopeFullAccount: "账户所有权限",
|
||||
required: "此项必填",
|
||||
scopeHelper: "仅开放接口只可以访问开放接口,账户所有权限可以访问所有接口",
|
||||
add: "生成新的Key",
|
||||
gen: {
|
||||
text: "接口测试",
|
||||
title: "x-certd-token",
|
||||
okText: "确定",
|
||||
contentPart1: "测试x-certd-token如下,您可以在3分钟内使用它进行",
|
||||
openApi: "开放接口",
|
||||
contentPart2: "请求测试",
|
||||
},
|
||||
pending_cname_setup: "待设置CNAME",
|
||||
validating: "验证中",
|
||||
validation_successful: "验证成功",
|
||||
validation_failed: "验证失败",
|
||||
validation_timed_out: "验证超时",
|
||||
proxied_domain: "被代理域名",
|
||||
host_record: "主机记录",
|
||||
please_set_cname: "请设置CNAME",
|
||||
cname_service: "CNAME服务",
|
||||
default_public_cname: "默认提供公共CNAME服务,您还可以",
|
||||
customize_cname: "自定义CNAME服务",
|
||||
public_cname: "公共CNAME",
|
||||
custom_cname: "自定义CNAME",
|
||||
validate: "验证",
|
||||
validation_started: "开始验证,请耐心等待",
|
||||
click_to_validate: "点击验证",
|
||||
all: "全部",
|
||||
cname_feature_guide: "CNAME功能原理及使用说明",
|
||||
batch_delete: "批量删除",
|
||||
confirm_delete_count: "确定要批量删除这{count}条记录吗",
|
||||
delete_successful: "删除成功",
|
||||
please_select_records: "请先勾选记录",
|
||||
edit_notification: "编辑通知",
|
||||
other_notification_method: "其他通知方式",
|
||||
trigger_time: "触发时机",
|
||||
start_time: "开始时",
|
||||
success_time: "成功时",
|
||||
fail_to_success_time: "失败转成功时",
|
||||
fail_time: "失败时",
|
||||
helper_suggest_fail_only: "建议仅选择'失败时'和'失败转成功'两种即可",
|
||||
notification_config: "通知配置",
|
||||
please_select_notification: "请选择通知方式",
|
||||
please_select_type: "请选择类型",
|
||||
please_select_trigger_time: "请选择通知时机",
|
||||
please_select_notification_config: "请选择通知配置",
|
||||
confirm_delete_trigger: "确定要删除此触发器吗?",
|
||||
gift_package: "赠送套餐",
|
||||
package_name: "套餐名称",
|
||||
click_to_select: "点击选择",
|
||||
please_select_package: "请选择套餐",
|
||||
package: "套餐",
|
||||
addon_package: "加量包",
|
||||
domain_count: "域名数量",
|
||||
unit_count: "个",
|
||||
field_required: "此项必填",
|
||||
pipeline_count: "流水线数量",
|
||||
unit_item: "条",
|
||||
deploy_count: "部署次数",
|
||||
unit_times: "次",
|
||||
monitor_count: "证书监控数量",
|
||||
duration: "时长",
|
||||
status: "状态",
|
||||
active_time: "激活时间",
|
||||
expires_time: "过期时间",
|
||||
is_present: "是否赠送",
|
||||
is_present_yes: "是",
|
||||
is_present_no: "否",
|
||||
basicInfo: "基础信息",
|
||||
titlea: "名称",
|
||||
disabled: "禁用",
|
||||
ordera: "排序",
|
||||
supportBuy: "支持购买",
|
||||
intro: "介绍",
|
||||
packageContent: "套餐内容",
|
||||
maxDomainCount: "最大域名数",
|
||||
maxPipelineCount: "最大流水线数",
|
||||
maxDeployCount: "最大部署数",
|
||||
maxMonitorCount: "最大监控数",
|
||||
price: "价格",
|
||||
durationPrices: "时长价格",
|
||||
packageName: "套餐名称",
|
||||
addon: "加量包",
|
||||
typeHelper: "套餐:同一时间只有最新购买的一个生效\n加量包:可购买多个,购买后立即生效,不影响套餐\n套餐和加量包数量可叠加",
|
||||
domainCount: "域名数量",
|
||||
pipelineCount: "流水线数量",
|
||||
unitPipeline: "条",
|
||||
deployCount: "部署次数",
|
||||
unitDeploy: "次",
|
||||
monitorCount: "证书监控数量",
|
||||
unitCount: "个",
|
||||
durationPriceTitle: "时长及价格",
|
||||
selectDuration: "选择时长",
|
||||
supportPurchase: "支持购买",
|
||||
cannotPurchase: "不能购买",
|
||||
shelfStatus: "上下架",
|
||||
onShelf: "上架",
|
||||
offShelf: "下架",
|
||||
orderHelper: "越小越靠前",
|
||||
description: "说明",
|
||||
createTime: "创建时间",
|
||||
updateTime: "更新时间",
|
||||
mainDomain: "主域名",
|
||||
edit: "编辑",
|
||||
groupName: "分组名称",
|
||||
enterGroupName: "请输入分组名称",
|
||||
subdomainHosting: "子域名托管",
|
||||
subdomainHostingHint: "当你的域名设置了子域名托管,需要在此处创建记录,否则申请证书将失败",
|
||||
batchDeleteConfirm: "确定要批量删除这{count}条记录吗",
|
||||
selectRecordFirst: "请先勾选记录",
|
||||
subdomainHosted: "托管的子域名",
|
||||
subdomainHelpText: "如果您不理解什么是子域托管,请不要随意设置(可能导致证书无法申请,以前设置过的cname记录也需要重新配置),可以参考文档",
|
||||
subdomainHelpSupportStart: "支持*号通配符,表示该域名下的子域名都是托管的(免费子域名)",
|
||||
subdomainManagement: "子域管理",
|
||||
isDisabled: "是否禁用",
|
||||
enabled: "启用",
|
||||
uploadCustomCert: "上传自定义证书",
|
||||
sourcee: "来源",
|
||||
sourcePipeline: "证书流水线",
|
||||
sourceManualUpload: "托管流水线",
|
||||
domains: "域名",
|
||||
enterDomain: "请输入域名",
|
||||
validDays: "有效天数",
|
||||
expires: "过期",
|
||||
days: "天",
|
||||
effectiveTime: "生效时间",
|
||||
expireTime: "过期时间",
|
||||
certIssuer: "证书颁发机构",
|
||||
applyTime: "申请时间",
|
||||
relatedPipeline: "关联流水线",
|
||||
statusSuccess: "成功",
|
||||
statusChecking: "检查中",
|
||||
statusError: "异常",
|
||||
actionImportBatch: "批量导入",
|
||||
actionSyncIp: "同步IP",
|
||||
modalTitleSyncIp: "同步IP",
|
||||
modalContentSyncIp: "确定要同步IP吗?",
|
||||
notificationSyncComplete: "同步完成",
|
||||
actionCheckAll: "检查全部",
|
||||
modalTitleConfirm: "确认",
|
||||
modalContentCheckAll: "确认触发检查全部IP站点的证书吗?",
|
||||
notificationCheckSubmitted: "检查任务已提交",
|
||||
notificationCheckDescription: "请稍后刷新页面查看结果",
|
||||
tooltipCheckNow: "立即检查",
|
||||
notificationCheckSubmittedPleaseRefresh: "检查任务已提交,请稍后刷新查看结果",
|
||||
columnId: "ID",
|
||||
columnIp: "IP",
|
||||
helperIpCname: "也支持填写CNAME域名,源站域名",
|
||||
ruleIpRequired: "请输入IP",
|
||||
columnCertDomains: "证书域名",
|
||||
columnCertProvider: "颁发机构",
|
||||
columnCertStatus: "证书状态",
|
||||
statusNormal: "正常",
|
||||
statusExpired: "过期",
|
||||
columnCertExpiresTime: "证书到期时间",
|
||||
expired: "过期",
|
||||
columnCheckStatus: "检查状态",
|
||||
columnLastCheckTime: "上次检查时间",
|
||||
columnSource: "来源",
|
||||
sourceSync: "同步",
|
||||
sourceManual: "手动",
|
||||
sourceImport: "导入",
|
||||
columnDisabled: "禁用启用",
|
||||
columnRemark: "备注",
|
||||
pluginFile: "插件文件",
|
||||
selectPluginFile: "选择插件文件",
|
||||
overrideSameName: "同名覆盖",
|
||||
override: "覆盖",
|
||||
noOverride: "不覆盖",
|
||||
overrideHelper: "如果已有相同名称插件,直接覆盖",
|
||||
importPlugin: "导入插件",
|
||||
operationSuccess: "操作成功",
|
||||
customPlugin: "自定义插件",
|
||||
import: "导入",
|
||||
export: "导出",
|
||||
pluginType: "插件类型",
|
||||
auth: "授权",
|
||||
dns: "DNS",
|
||||
deployPlugin: "部署插件",
|
||||
icon: "图标",
|
||||
pluginName: "插件名称",
|
||||
pluginNameHelper: "必须为英文或数字,驼峰命名,类型作为前缀\n示例:AliyunDeployToCDN\n插件使用后,名称不可修改",
|
||||
pluginNameRuleMsg: "必须为英文或数字,驼峰命名,类型作为前缀",
|
||||
author: "作者",
|
||||
authorHelper: "上传插件市场时作为前缀,如 greper/pluginName",
|
||||
authorRuleMsg: "必须为英文或数字",
|
||||
titleHelper: "插件中文名称",
|
||||
descriptionHelper: "插件描述",
|
||||
builtIn: "内置",
|
||||
custom: "自定义",
|
||||
store: "市场",
|
||||
version: "版本",
|
||||
pluginDependencies: "插件依赖",
|
||||
pluginDependenciesHelper: "格式: [作者/]插件名[:版本],需先安装依赖插件",
|
||||
editableRunStrategy: "可编辑运行策略",
|
||||
editable: "可编辑",
|
||||
notEditable: "不可编辑",
|
||||
runStrategy: "运行策略",
|
||||
normalRun: "正常运行",
|
||||
skipOnSuccess: "成功跳过(部署任务)",
|
||||
defaultRunStrategyHelper: "默认运行策略",
|
||||
enableDisable: "启用/禁用",
|
||||
clickToToggle: "点击切换启用/禁用",
|
||||
confirmToggle: "确认要",
|
||||
disable: "禁用",
|
||||
enable: "启用",
|
||||
pluginGroup: "插件分组",
|
||||
icpRegistrationNumber: "ICP备案号",
|
||||
icpPlaceholder: "粤ICP备xxxxxxx号",
|
||||
publicSecurityRegistrationNumber: "网安备案号",
|
||||
publicSecurityPlaceholder: "京公网安备xxxxxxx号",
|
||||
enableAssistant: "开启小助手",
|
||||
allowCrawlers: "允许爬虫",
|
||||
httpProxy: "HTTP代理",
|
||||
httpProxyPlaceholder: "http://192.168.1.2:18010/",
|
||||
httpProxyHelper: "当某些网站被墙时可以配置",
|
||||
httpsProxy: "HTTPS代理",
|
||||
httpsProxyPlaceholder: "http://192.168.1.2:18010/",
|
||||
saveThenTestTitle: "保存后,再点击测试",
|
||||
testButton: "测试",
|
||||
httpsProxyHelper: "一般这两个代理填一样的,保存后再测试",
|
||||
dualStackNetwork: "双栈网络",
|
||||
default: "默认",
|
||||
ipv4Priority: "IPV4优先",
|
||||
ipv6Priority: "IPV6优先",
|
||||
dualStackNetworkHelper: "如果选择IPv6优先,需要在docker-compose.yaml中启用ipv6",
|
||||
enableCommonCnameService: "启用公共CNAME服务",
|
||||
commonCnameHelper: "是否可以使用公共CNAME服务,如果禁用,且没有设置<a href='#/sys/cname/provider'>自定义CNAME服务</a>,则无法使用CNAME代理方式申请证书",
|
||||
enableCommonSelfServicePasswordRetrieval: "启用自助找回密码",
|
||||
saveButton: "保存",
|
||||
stopSuccess: "停止成功",
|
||||
google: "Google",
|
||||
baidu: "百度",
|
||||
success: "成功",
|
||||
testFailed: "测试失败",
|
||||
testCompleted: "测试完成",
|
||||
manageOtherUserPipeline: "管理其他用户流水线",
|
||||
limitUserPipelineCount: "限制用户流水线数量",
|
||||
limitUserPipelineCountHelper: "0为不限制",
|
||||
enableSelfRegistration: "开启自助注册",
|
||||
enableUserValidityPeriod: "开启用户有效期",
|
||||
userValidityPeriodHelper: "有效期内用户可正常使用,失效后用户的流水线将被停用",
|
||||
enableUsernameRegistration: "开启用户名注册",
|
||||
enableEmailRegistration: "开启邮箱注册",
|
||||
proFeature: "Certd专业版功能",
|
||||
emailServerSetup: "设置邮箱服务器",
|
||||
enableSmsLoginRegister: "开启手机号登录、注册",
|
||||
defaultLoginType: "默认登录方式",
|
||||
commFeature: "Certd商业版功能",
|
||||
smsProvider: "短信提供商",
|
||||
aliyunSms: "阿里云短信",
|
||||
tencentSms: "腾讯云短信",
|
||||
yfySms: "易发云短信",
|
||||
smsTest: "短信测试",
|
||||
testMobilePlaceholder: "输入测试手机号",
|
||||
saveThenTest: "保存后再点击测试",
|
||||
enterTestMobile: "请输入测试手机号",
|
||||
sendSuccess: "发送成功",
|
||||
atLeastOneLoginRequired: "密码登录和手机号登录至少开启一个",
|
||||
fieldRequired: "此项必填",
|
||||
siteHide: "站点隐藏",
|
||||
enableSiteHide: "启用站点隐藏",
|
||||
siteHideDescription: "可以在平时关闭站点的可访问性,需要时再打开,增强站点安全性",
|
||||
helpDoc: "帮助说明",
|
||||
randomAddress: "随机地址",
|
||||
siteHideUrlHelper: "站点被隐藏后,需要访问此URL解锁,才能正常访问",
|
||||
fullUnlockUrl: "完整解除隐藏地址",
|
||||
saveThisUrl: "请保存好此地址",
|
||||
unlockPassword: "解除密码",
|
||||
unlockPasswordHelper: "解除隐藏时需要输入密码,第一次需要设置密码,填写则重置密码",
|
||||
autoHideTime: "自动隐藏时间",
|
||||
autoHideTimeHelper: "多少分钟内无请求自动隐藏",
|
||||
hideOpenApi: "隐藏开放接口",
|
||||
hideOpenApiHelper: "是否隐藏开放接口,是否同时隐藏/api/v1开头的接口",
|
||||
hideSiteImmediately: "立即隐藏站点",
|
||||
hideImmediately: "立即隐藏",
|
||||
confirmHideSiteTitle: "确定要立即隐藏站点吗?",
|
||||
confirmHideSiteContent: "隐藏后,将无法访问站点,请谨慎操作",
|
||||
siteHiddenSuccess: "站点已隐藏",
|
||||
emailServerSettings: "邮件服务器设置",
|
||||
setEmailSendingServer: "设置邮件发送服务器",
|
||||
useCustomEmailServer: "使用自定义邮件服务器",
|
||||
smtpDomain: "SMTP域名",
|
||||
pleaseEnterSmtpDomain: "请输入smtp域名或ip",
|
||||
smtpPort: "SMTP端口",
|
||||
pleaseEnterSmtpPort: "请输入smtp端口号",
|
||||
username: "用户名",
|
||||
pleaseEnterUsername: "请输入用户名",
|
||||
password: "密码",
|
||||
pleaseEnterPassword: "请输入密码",
|
||||
qqEmailAuthCodeHelper: "如果是qq邮箱,需要到qq邮箱的设置里面申请授权码作为密码",
|
||||
senderEmailHelper: "您可以使用 名称<邮箱> 的格式,来修改发件人名称,例如: autossl<certd{'@'}example.com>",
|
||||
senderEmail: "发件邮箱",
|
||||
pleaseEnterSenderEmail: "请输入发件邮箱",
|
||||
useSsl: "是否ssl",
|
||||
sslPortNote: "ssl和非ssl的smtp端口是不一样的,注意修改端口",
|
||||
ignoreCertValidation: "忽略证书校验",
|
||||
useOfficialEmailServer: "使用官方邮件服务器",
|
||||
useOfficialEmailServerHelper: "使用官方邮箱服务器直接发邮件,免除繁琐的配置",
|
||||
testReceiverEmail: "测试收件邮箱",
|
||||
pleaseEnterTestReceiverEmail: "请输入测试收件邮箱",
|
||||
saveBeforeTest: "保存后再点击测试",
|
||||
sendFailHelpDoc: "发送失败???",
|
||||
emailConfigHelpDoc: "邮件配置帮助文档",
|
||||
tryOfficialEmailServer: "您还可以试试使用官方邮件服务器↗↗↗↗↗↗↗↗",
|
||||
pluginManagement: "插件管理",
|
||||
pluginBetaWarning: "自定义插件处于BETA测试版,后续可能会有破坏性变更",
|
||||
pleaseSelectRecord: "请先勾选记录",
|
||||
permissionManagement: "权限管理",
|
||||
adda: "添加",
|
||||
rootNode: "根节点",
|
||||
permissionName: "权限名称",
|
||||
enterPermissionName: "请输入权限名称",
|
||||
permissionCode: "权限代码",
|
||||
enterPermissionCode: "请输入权限代码",
|
||||
max100Chars: "最大100个字符",
|
||||
examplePermissionCode: "例如:sys:user:view",
|
||||
sortOrder: "排序",
|
||||
sortRequired: "排序号必填",
|
||||
parentNode: "父节点",
|
||||
roleManagement: "角色管理",
|
||||
assignPermissions: "分配权限",
|
||||
roleName: "角色名称",
|
||||
enterRoleName: "请输入角色名称",
|
||||
unlockLogin: "解除登录锁定",
|
||||
notice: "提示",
|
||||
confirmUnlock: "确定要解除该用户的登录锁定吗?",
|
||||
unlockSuccess: "解除成功",
|
||||
enterUsername: "请输入用户名",
|
||||
modifyPasswordIfFilled: "填写则修改密码",
|
||||
emaila: "邮箱",
|
||||
mobile: "手机号",
|
||||
avatar: "头像",
|
||||
validTime: "有效期",
|
||||
remark: "备注",
|
||||
roles: "角色",
|
||||
cnameTitle: "CNAME服务配置",
|
||||
cnameDescription: "此处配置的域名作为其他域名校验的代理,当别的域名需要申请证书时,通过CNAME映射到此域名上来验证所有权。好处是任何域名都可以通过此方式申请证书,也无需填写AccessSecret。",
|
||||
cnameLinkText: "CNAME功能原理及使用说明",
|
||||
confirmTitle: "确认",
|
||||
confirmDeleteBatch: "确定要批量删除这{count}条记录吗",
|
||||
selectRecordsFirst: "请先勾选记录",
|
||||
cnameDomain: "CNAME域名",
|
||||
cnameDomainPlaceholder: "cname.handsfree.work",
|
||||
cnameDomainHelper: "需要一个右边DNS提供商注册的域名(也可以将其他域名的dns服务器转移到这几家来)。\nCNAME域名一旦确定不可修改,建议使用一级子域名",
|
||||
cnameDomainPattern: "域名不能使用星号",
|
||||
dnsProvider: "DNS提供商",
|
||||
dnsProviderAuthorization: "DNS提供商授权",
|
||||
setDefault: "设置默认",
|
||||
confirmSetDefault: "确定要设置为默认吗?",
|
||||
setAsDefault: "设为默认",
|
||||
disabledLabel: "禁用",
|
||||
confirmToggleStatus: "确定要{action}吗?",
|
||||
addonType: "类型",
|
||||
addonName: "名称",
|
||||
addonNameHelper: "随意填写,相同类型助于区分即可",
|
||||
addonTypeSelect: "请选择",
|
||||
template: {
|
||||
title: "流水线模版",
|
||||
edit: "流水线模版编辑",
|
||||
importCreate: "流水线模版批量创建",
|
||||
intro: "可根据模版批量创建流水线",
|
||||
createTemplate: "创建模版",
|
||||
useTemplate: "使用此模板",
|
||||
batchCreate: "批量创建流水线",
|
||||
singleCreate: "创建单个流水线",
|
||||
templateName: "模板名称",
|
||||
enterTemplateName: "请输入模板名称",
|
||||
copyPipelineConfig: "复制该流水线配置作为模板来源",
|
||||
pipeline: "流水线",
|
||||
},
|
||||
dates: {
|
||||
years: "{count}年",
|
||||
months: "{count}月",
|
||||
},
|
||||
sys: {
|
||||
setting: {
|
||||
baseSetting: "基本设置",
|
||||
registerSetting: "注册设置",
|
||||
safeSetting: "安全设置",
|
||||
paymentSetting: "支付设置",
|
||||
captchaSetting: "验证码设置",
|
||||
pipelineSetting: "流水线设置",
|
||||
oauthSetting: "第三方登录",
|
||||
networkSetting: "网络设置",
|
||||
adminModeSetting: "管理模式",
|
||||
adminModeHelper: "企业管理模式: 企业内部使用,通过项目来隔离权限,流水线、授权数据属于项目。\nsaas模式:供外部用户注册使用,各个用户之间数据隔离,流水线、授权数据属于用户。",
|
||||
|
||||
adminMode: "管理模式",
|
||||
enterpriseMode: "企业模式",
|
||||
saasMode: "SaaS模式",
|
||||
|
||||
showRunStrategy: "显示运行策略选择",
|
||||
showRunStrategyHelper: "任务设置中是否允许选择运行策略",
|
||||
|
||||
captchaEnabled: "启用登录验证码",
|
||||
captchaHelper: "登录时是否启用验证码",
|
||||
captchaType: "验证码配置",
|
||||
captchaTest: "测试验证码",
|
||||
captchaTestHelper: "保存后再点击测试,请务必测试通过了,再开启登录验证码",
|
||||
|
||||
pipelineValidTimeEnabled: "启用流水线有效期",
|
||||
pipelineValidTimeEnabledHelper: "是否启用流水线有效期",
|
||||
certDomainAddToMonitorEnabled: "证书域名添加到证书监控",
|
||||
certDomainAddToMonitorEnabledHelper: "创建证书流水线时是否可以选择将域名添加到证书监控",
|
||||
|
||||
defaultCertRenewDays: "默认到期前更新天数",
|
||||
defaultCertRenewDaysHelper: "创建证书流水线时,默认的证书到期前更新天数",
|
||||
defaultCertRenewDaysRecommend: "默认值15",
|
||||
|
||||
pipelineMaxRunningCount: "同时最大运行流水线数量",
|
||||
pipelineMaxRunningCountHelper: "同一个用户同时运行的最大流水线数量,避免同时触发太多导致ACME账户被限制",
|
||||
pipelineMaxRunningCountRecommend: "推荐5-15,默认10",
|
||||
acmeWalkFromAuthoritative: "从权威NS检查TXT记录",
|
||||
acmeWalkFromAuthoritativeHelper: "申请证书时,是否从权威NS服务器检查TXT记录,如果影响申请证书,可以关闭",
|
||||
|
||||
fixedCertExpireDays: "固定证书有效期天数",
|
||||
fixedCertExpireDaysHelper: "固定证书有效期天数,有助于列表进度条整齐显示",
|
||||
fixedCertExpireDaysRecommend: "推荐90",
|
||||
|
||||
enableOauth: "启用第三方登录",
|
||||
oauthEnabledHelper: "是否启用第三方登录",
|
||||
oauthProviders: "第三方登录提供商",
|
||||
oauthType: "第三方登录类型",
|
||||
oauthConfig: "第三方登录配置",
|
||||
oauthProviderSelectorPlaceholder: "未配置",
|
||||
oauthCallback: "回调地址",
|
||||
oauthCallbackHelper: "复制回调地址,配置到对应提供商的回调地址中",
|
||||
oauthCallbackCopy: "复制回调地址",
|
||||
oauthAutoRegister: "自动注册用户",
|
||||
oauthAutoRegisterHelper: "当第三方账户未绑定本站账号时,是否自动注册用户,默认由用户选择",
|
||||
oauthAutoRegisterCheckedText: "自动注册",
|
||||
oauthAutoRegisterUnCheckedText: "用户选择",
|
||||
oauthAutoRedirect: "自动跳转第三方登录",
|
||||
oauthAutoRedirectHelper: "是否自动跳转第三方登录(使用第一个已启用的第三方登录类型)",
|
||||
oauthOnly: "仅使用第三方登录",
|
||||
oauthOnlyHelper: "是否仅使用第三方登录,关闭密码登录(注意:请务必在测试第三方登录功能正常后再开启,否则会导致无法登录)\n 如果无法登录,请访问 http://你的certd地址/#/login?oauthOnly=false 来临时关闭此模式",
|
||||
enablePasskey: "启用Passkey登录",
|
||||
passkeyHostnameNotSame: "当前域名与主绑定域名不同",
|
||||
passkeyEnabledHelper: "1、站点必须启用https \n2、passkey的rpId以主绑定域名为准,当前主域名:{0} \n3、站点域名不能变,否则会导致已注册的passkey失效。",
|
||||
email: {
|
||||
templates: "邮件模板",
|
||||
templateType: "模板类型",
|
||||
templateProvider: "模板配置",
|
||||
|
||||
templateSetting: "邮件模板设置",
|
||||
serverSetting: "邮件服务器设置",
|
||||
sendTest: "发送测试",
|
||||
|
||||
templateProviderSelectorPlaceholder: "未配置",
|
||||
},
|
||||
notice: "系统公告",
|
||||
noticeHelper: "系统公告,将在首页显示",
|
||||
noticePlaceholder: "系统公告",
|
||||
|
||||
customFooter: "自定义页脚",
|
||||
customFooterHelper: "自定义页脚,支持HTML",
|
||||
customFooterPlaceholder: "自定义页脚",
|
||||
|
||||
reverseProxy: "反向代理列表",
|
||||
reverseProxyHelper: "证书颁发机构ACME地址的反向代理,在申请证书时自动使用",
|
||||
reverseProxyPlaceholder: "http://le.px.handfree.work",
|
||||
reverseProxyEmpty: "未配置反向代理",
|
||||
environmentVars: "环境变量",
|
||||
environmentVarsHelper: "配置运行时环境变量,每行一个,格式:KEY=VALUE",
|
||||
bindUrl: "绑定URL",
|
||||
bindUrlHelper: "绑定URL,在各类通知中显示你的站点URL",
|
||||
},
|
||||
},
|
||||
modal: {
|
||||
close: "关闭",
|
||||
viewCertificateTitle: "查看证书",
|
||||
},
|
||||
domain: {
|
||||
domainManager: "域名管理",
|
||||
domainDescription: "流水线校验方式选择“自动选择”时此处配置才有用,支持自动导入;注意:这里只需要管理主域名即可,子域名不要填写(子域名托管和免费二级子域名除外)",
|
||||
domain: "域名",
|
||||
challengeType: "校验类型",
|
||||
dnsProviderType: "DNS提供商类型",
|
||||
dnsProviderAccess: "DNS提供商授权",
|
||||
httpUploaderType: "上传方式",
|
||||
httpUploaderAccess: "上传授权信息",
|
||||
httpUploadRootDir: "网站根路径",
|
||||
disabled: "禁用/启用",
|
||||
challengeSetting: "校验配置",
|
||||
gotoCnameTip: "CNAME域名配置请前往CNAME记录页面添加",
|
||||
fromType: "来源类型",
|
||||
expirationDate: "到期时间",
|
||||
},
|
||||
addonSelector: {
|
||||
select: "选择",
|
||||
placeholder: "请选择",
|
||||
},
|
||||
ent: {
|
||||
projectName: "项目名称",
|
||||
projectDescription: "项目描述",
|
||||
projectDetailManager: "项目详情",
|
||||
projectDetailDescription: "管理项目成员",
|
||||
projectPermission: "权限",
|
||||
permission: {
|
||||
read: "查看",
|
||||
write: "修改",
|
||||
admin: "管理员",
|
||||
},
|
||||
projectMemberStatus: "成员状态",
|
||||
|
||||
isSystem: "是否系统项目",
|
||||
isSystemHelper: "系统级项目允许运行管理员插件",
|
||||
},
|
||||
project: {
|
||||
noProjectJoined: "您还没有加入任何项目",
|
||||
applyToJoin: "请申请加入项目以开始使用",
|
||||
projectList: "项目列表",
|
||||
createdAt: "创建时间",
|
||||
applyJoin: "申请加入",
|
||||
noProjects: "暂无项目",
|
||||
fetchFailed: "获取项目列表失败",
|
||||
applySuccess: "申请成功,等待管理员审核",
|
||||
applyFailed: "申请失败,请稍后重试",
|
||||
leave: "退出项目",
|
||||
leaveSuccess: "退出项目成功",
|
||||
leaveFailed: "退出项目失败,请稍后重试",
|
||||
applyJoinConfirm: "确认加入项目?",
|
||||
leaveConfirm: "确认退出项目?",
|
||||
viewDetail: "查看详情",
|
||||
projectManage: "项目管理",
|
||||
},
|
||||
...common,
|
||||
...navigation,
|
||||
...dashboard,
|
||||
...pipeline,
|
||||
...history,
|
||||
...monitor,
|
||||
...certdomain,
|
||||
...cname,
|
||||
...access,
|
||||
...open,
|
||||
...mine,
|
||||
...notification,
|
||||
...addon,
|
||||
...suite,
|
||||
...project,
|
||||
...syssettings,
|
||||
...sysplugin,
|
||||
...sysauthority,
|
||||
...syscname,
|
||||
...tutorial,
|
||||
...cron,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
export default {
|
||||
authorizationManagement: "授权管理",
|
||||
manageThirdPartyAuth: "管理第三方系统授权信息",
|
||||
nameHelper: "随便填,当多个相同类型的授权时,便于区分",
|
||||
level: "级别",
|
||||
system: "系统",
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
export default {
|
||||
addonType: "类型",
|
||||
addonName: "名称",
|
||||
addonNameHelper: "随意填写,相同类型助于区分即可",
|
||||
addonTypeSelect: "请选择",
|
||||
addonSelector: {
|
||||
select: "选择",
|
||||
placeholder: "请选择",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,106 @@
|
||||
export default {
|
||||
domain: {
|
||||
domainManager: "域名管理",
|
||||
domainDescription: "流水线校验方式选择“自动选择”时此处配置才有用,支持自动导入;注意:这里只需要管理主域名即可,子域名不要填写(子域名托管和免费二级子域名除外)",
|
||||
domain: "域名",
|
||||
challengeType: "校验类型",
|
||||
dnsProviderType: "DNS提供商类型",
|
||||
dnsProviderAccess: "DNS提供商授权",
|
||||
httpUploaderType: "上传方式",
|
||||
httpUploaderAccess: "上传授权信息",
|
||||
httpUploadRootDir: "网站根路径",
|
||||
disabled: "禁用/启用",
|
||||
challengeSetting: "校验配置",
|
||||
gotoCnameTip: "CNAME域名配置请前往CNAME记录页面添加",
|
||||
fromType: "来源类型",
|
||||
expirationDate: "到期时间",
|
||||
cnameManagedInCnamePage: "CNAME方式请前往CNAME记录页面进行管理",
|
||||
subdomainConfirmTitle: "子域名确认",
|
||||
subdomainConfirmContent: "检测到{domain}为子域名,只有托管子域名和免费二级子域名才需要在此处维护,否则会导致申请证书失败,请确认是否继续?",
|
||||
importFromProvider: "从域名提供商导入",
|
||||
syncExpirationDate: "同步域名过期时间",
|
||||
syncTaskSubmitted: "同步任务已提交",
|
||||
expirationMonitorSetting: "域名过期监控设置",
|
||||
subdomainDnsHelper: "注意:DNS校验方式下,子域名不需要在此处维护,否则会影响证书申请(子域名托管或免费二级域名除外)",
|
||||
path: "路径",
|
||||
addImportTask: "添加导入任务",
|
||||
refresh: "刷新",
|
||||
progress: "进度",
|
||||
operation: "操作",
|
||||
total: "总数",
|
||||
skipped: "跳过",
|
||||
failed: "失败",
|
||||
notExecuted: "未执行",
|
||||
execute: "执行",
|
||||
delete: "删除",
|
||||
confirmDelete: "确认删除吗?",
|
||||
domainProvider: "域名提供商",
|
||||
domainProviderAccessType: "域名提供商访问类型",
|
||||
domainProviderAccess: "域名提供商授权",
|
||||
},
|
||||
verifyPlan: {
|
||||
expandTip: "这里可以放大",
|
||||
mainDomain: "主域名",
|
||||
challengeType: "验证方式",
|
||||
challengePlan: "验证计划",
|
||||
dnsType: "DNS类型",
|
||||
dnsProvider: "DNS提供商",
|
||||
dnsAccess: "DNS授权",
|
||||
pleaseSelect: "请选择",
|
||||
httpHelper: "证书颁发机构将请求 https://yourdomain/.well-known/acme-challenge/xxxxxx 来验证域名所有权。",
|
||||
dnsChallenge: "DNS验证",
|
||||
cnameChallenge: "CNAME验证",
|
||||
cnameProxyChallenge: "CNAME代理验证",
|
||||
httpChallenge: "HTTP验证",
|
||||
domainTitle: "域名:{domain}",
|
||||
resetStatusTooltip: "重置校验状态,重新校验",
|
||||
clickToValidate: "点击验证",
|
||||
keepCnameTitle: "后续自动申请证书需要",
|
||||
keepCname: "不要删除CNAME",
|
||||
resetStatus: "重置状态",
|
||||
confirmResetStatus: "确定要重置校验状态吗?",
|
||||
hostRecord: "主机记录",
|
||||
recordType: "记录类型",
|
||||
setCnameRecord: "请设置CNAME记录(验证成功以后不要删除)",
|
||||
operation: "操作",
|
||||
websiteDomain: "网站域名",
|
||||
uploadMethod: "上传方式",
|
||||
uploadAccess: "上传授权",
|
||||
websiteRootPath: "网站根目录路径",
|
||||
websiteRootPlaceholder: "网站根目录,如:/www/wwwroot",
|
||||
status: {
|
||||
pendingCname: "待设置CNAME",
|
||||
validating: "验证中",
|
||||
valid: "验证成功",
|
||||
failed: "验证失败",
|
||||
timeout: "验证超时",
|
||||
},
|
||||
cnameTip: {
|
||||
intro: "多试几次,如果仍然无法验证通过,请按如下步骤排查问题:",
|
||||
step1: "1. 解析记录应该添加在{domain}域名下",
|
||||
step2: "2. 要添加的是CNAME类型的记录,不是TXT",
|
||||
step3: "3. 核对记录值是否是:{value}",
|
||||
step4: "4. 在验证中状态下,运行下面的命令,查看cname和txt解析是否正确",
|
||||
or: "或者",
|
||||
step5: "5. 如果以上检查都没有问题,则可能是DNS解析生效时间比较慢,某些提供商延迟可能高达几个小时",
|
||||
},
|
||||
errors: {
|
||||
cnameNotValid: "域名{domain}的CNAME未验证通过,请先设置CNAME记录,点击验证按钮",
|
||||
wildcardNotSupportHttp: "域名{domain}为通配符域名,不支持HTTP校验",
|
||||
uploadMethodRequired: "域名{domain}的上传方式必须填写",
|
||||
uploadAccessRequired: "域名{domain}的上传授权信息必须填写",
|
||||
websiteRootRequired: "域名{domain}的网站根路径必须填写",
|
||||
dnsProviderRequired: "DNS模式下,域名{domain}的DNS类型和授权信息必须填写",
|
||||
},
|
||||
uploader: {
|
||||
aliyunOss: "阿里云OSS",
|
||||
tencentCos: "腾讯云COS",
|
||||
qiniuOss: "七牛OSS",
|
||||
sshDeprecated: "SSH(已废弃,请选择SFTP方式)",
|
||||
},
|
||||
domainFrom: {
|
||||
manual: "手动",
|
||||
auto: "自动",
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
export default {
|
||||
pending_cname_setup: "待设置CNAME",
|
||||
validating: "验证中",
|
||||
validation_successful: "验证成功",
|
||||
validation_failed: "验证失败",
|
||||
validation_timed_out: "验证超时",
|
||||
proxied_domain: "被代理域名",
|
||||
host_record: "主机记录",
|
||||
please_set_cname: "请设置CNAME",
|
||||
cname_service: "CNAME服务",
|
||||
default_public_cname: "默认提供公共CNAME服务,您还可以",
|
||||
customize_cname: "自定义CNAME服务",
|
||||
public_cname: "公共CNAME",
|
||||
custom_cname: "自定义CNAME",
|
||||
validate: "验证",
|
||||
validation_started: "开始验证,请耐心等待",
|
||||
click_to_validate: "点击验证",
|
||||
cname_feature_guide: "CNAME功能原理及使用说明",
|
||||
mainDomain: "主域名",
|
||||
cnameRecord: "CNAME记录管理",
|
||||
importRecords: "导入CNAME记录",
|
||||
batchImport: "批量导入",
|
||||
exportRecordsTip: "导出CNAME记录之后,可用于批量导入cname解析到域名注册商",
|
||||
batchExport: "批量导出",
|
||||
resetStatus: "重置状态",
|
||||
confirmResetStatus: "确定要重置校验状态吗?",
|
||||
resetStatusTooltip: "重置校验状态,重新校验",
|
||||
cname: {
|
||||
importRecords: "导入CNAME记录",
|
||||
batchImport: "批量导入",
|
||||
exportRecordsTip: "导出CNAME记录之后,可用于批量导入cname解析到域名注册商",
|
||||
batchExport: "批量导出",
|
||||
resetStatus: "重置状态",
|
||||
confirmResetStatus: "确定要重置校验状态吗?",
|
||||
resetStatusTooltip: "重置校验状态,重新校验",
|
||||
domainList: "域名列表",
|
||||
domainListHelper: "每个域名一行,批量导入\n泛域名请去掉*.\n已经存在的会自动跳过",
|
||||
cnameService: "CNAME服务",
|
||||
importTaskSubmitted: "导入任务已提交",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,152 @@
|
||||
export default {
|
||||
usera: "用户",
|
||||
disabledSuccess: "关闭成功",
|
||||
app: {
|
||||
crud: {
|
||||
i18n: {
|
||||
name: "姓名",
|
||||
city: "城市",
|
||||
status: "状态",
|
||||
},
|
||||
},
|
||||
login: {
|
||||
logoutTip: "确认",
|
||||
logoutMessage: "确定要注销登录吗?",
|
||||
},
|
||||
},
|
||||
fs: {
|
||||
rowHandle: {
|
||||
title: "操作列",
|
||||
},
|
||||
},
|
||||
close: "关闭",
|
||||
confirm: "确认",
|
||||
save: "保存",
|
||||
add: "生成新的Key",
|
||||
edit: "编辑",
|
||||
deleteSuccess: "删除成功",
|
||||
saveSuccess: "保存成功",
|
||||
cancel: "取消",
|
||||
yes: "是",
|
||||
no: "否",
|
||||
all: "全部",
|
||||
required: "此项必填",
|
||||
requiredField: "此项必填",
|
||||
fieldRequired: "此项必填",
|
||||
field_required: "此项必填",
|
||||
name: "名称",
|
||||
pleaseEnterName: "请填写名称",
|
||||
type: "类型",
|
||||
status: "状态",
|
||||
description: "说明",
|
||||
createTime: "创建时间",
|
||||
updateTime: "更新时间",
|
||||
basicInfo: "基础信息",
|
||||
disabled: "禁用",
|
||||
enabled: "启用",
|
||||
default: "默认",
|
||||
success: "成功",
|
||||
test: "测试",
|
||||
testButton: "测试",
|
||||
operationSuccess: "操作成功",
|
||||
batch_delete: "批量删除",
|
||||
confirm_delete_count: "确定要批量删除这{count}条记录吗",
|
||||
delete_successful: "删除成功",
|
||||
please_select_records: "请先勾选记录",
|
||||
groupName: "分组名称",
|
||||
enterGroupName: "请输入分组名称",
|
||||
batchDeleteConfirm: "确定要批量删除这{count}条记录吗",
|
||||
selectRecordFirst: "请先勾选记录",
|
||||
confirmTitle: "确认",
|
||||
confirmDeleteBatch: "确定要批量删除这{count}条记录吗",
|
||||
selectRecordsFirst: "请先勾选记录",
|
||||
setDefault: "设置默认",
|
||||
confirmSetDefault: "确定要设置为默认吗?",
|
||||
setAsDefault: "设为默认",
|
||||
disabledLabel: "禁用",
|
||||
confirmToggleStatus: "确定要{action}吗?",
|
||||
batchDelete: "批量删除",
|
||||
sourcee: "来源",
|
||||
clickToToggle: "点击切换启用/禁用",
|
||||
nickName: "昵称",
|
||||
avatar: "头像",
|
||||
expires: "过期",
|
||||
days: "天",
|
||||
isDefault: "是否默认",
|
||||
selectIsDefault: "请选择是否默认",
|
||||
isDisabled: "是否禁用",
|
||||
fields: {
|
||||
userId: "用户Id",
|
||||
pipelineName: "流水线名称",
|
||||
keyword: "关键字",
|
||||
required: "此项必填",
|
||||
pipelineContent: "流水线内容",
|
||||
scheduledTaskCount: "定时任务数",
|
||||
deployTaskCount: "部署任务数",
|
||||
remainingValidity: "到期剩余",
|
||||
effectiveTime: "生效时间",
|
||||
expiryTime: "过期时间",
|
||||
status: "状态",
|
||||
lastRun: "最后运行",
|
||||
enabled: "启用",
|
||||
enabledLabel: "启用",
|
||||
disabledLabel: "禁用",
|
||||
group: "分组",
|
||||
type: "类型",
|
||||
order: "排序号",
|
||||
keepHistoryCount: "历史记录保持数",
|
||||
keepHistoryHelper: "历史记录保持条数,多余的会被删除",
|
||||
createTime: "创建时间",
|
||||
updateTime: "更新时间",
|
||||
triggerType: "触发类型",
|
||||
pipelineId: "流水线Id",
|
||||
nextRunTime: "下次运行时间",
|
||||
projectName: "项目",
|
||||
adminId: "管理员",
|
||||
},
|
||||
enterName: "请输入名称",
|
||||
prompt: "提示",
|
||||
domainCount: "域名数量",
|
||||
import: "导入",
|
||||
export: "导出",
|
||||
disable: "禁用",
|
||||
enable: "启用",
|
||||
username: "用户名",
|
||||
password: "密码",
|
||||
expired: "过期",
|
||||
helpDocLink: "帮助文档",
|
||||
suite: "套餐",
|
||||
helpDoc: "帮助说明",
|
||||
pluginCommon: {
|
||||
test: "测试",
|
||||
errorWithMessage: "错误:{message}",
|
||||
testRequestSuccess: "测试请求成功",
|
||||
responseSuffix: ",返回:{response}",
|
||||
searchKeyword: "查询关键字",
|
||||
search: "查询",
|
||||
refreshOptions: "刷新选项",
|
||||
getOptionsError: "获取选项出错:{message}",
|
||||
getDataSuccessSelect: "获取数据成功,请从下拉框中选择",
|
||||
getDataSuccessEmpty: "获取数据成功,没有数据",
|
||||
domainSearchPlaceholder: "这里可以搜索域名(数据来自“设置->域名管理”),您也可以直接在上面输入框输入",
|
||||
importDomain: "导入域名",
|
||||
manageDomain: "管理域名",
|
||||
refreshMyDomains: "刷新我的域名列表",
|
||||
upload: "上传",
|
||||
uploadCert: "上传证书",
|
||||
certName: "证书名称",
|
||||
certNameHelper: "上传后证书显示名称",
|
||||
uploadSuccess: "上传成功",
|
||||
selectCertFirst: "请先选择域名证书",
|
||||
targetStepNotFound: "找不到目标步骤,请先选择域名证书",
|
||||
},
|
||||
captcha: {
|
||||
inputImageCode: "请输入图形验证码",
|
||||
refresh: "刷新验证码",
|
||||
clickToVerify: "点击验证",
|
||||
verifySuccess: "验证成功",
|
||||
verifyFailed: "验证失败,请重试",
|
||||
loadFailed: "加载验证码失败",
|
||||
notLoaded: "验证码未加载完成",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,7 @@
|
||||
export default {
|
||||
cron: {
|
||||
clearTip: "清除选择",
|
||||
nextTrigger: "下次触发时间",
|
||||
tip: "请先设置正确的cron表达式",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
export default {
|
||||
dashboard: {
|
||||
greeting: "您好,{name},欢迎使用 【{site}】",
|
||||
latestVersion: "最新版本: {version}",
|
||||
validUntil: "账户有效期:",
|
||||
tutorialTooltip: "点击查看详细教程",
|
||||
tutorialText: "仅需3步,全自动申请部署证书",
|
||||
alertMessage: "证书和授权为敏感信息,不要使用来历不明的在线Certd服务和镜像,以免泄露;请务必私有化部署使用,认准官方版本发布渠道:",
|
||||
helpDoc: "帮助文档",
|
||||
pipelineCount: "证书流水线数量",
|
||||
enabledCount: "已启用",
|
||||
disabledCount: "已禁用",
|
||||
noPipeline: "您还没有证书流水线",
|
||||
certCount: "证书数量",
|
||||
certExpiringCount: "即将过期",
|
||||
certExpiredCount: "已过期",
|
||||
certNoExpireCount: "未过期",
|
||||
noCert: "还没有证书",
|
||||
manageCert: "查看证书",
|
||||
|
||||
createNow: "立即创建",
|
||||
managePipeline: "管理流水线",
|
||||
pipelineStatus: "流水线状态",
|
||||
recentRun: "最近运行统计",
|
||||
runCount: "运行次数",
|
||||
expiringCerts: "最快到期证书",
|
||||
supportedTasks: "已支持的部署任务总览",
|
||||
changeLog: "更新日志",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
export default {
|
||||
pipelineExecutionRecords: "流水线执行记录",
|
||||
confirmBatchDeleteContent: "确定要批量删除这{count}条记录吗",
|
||||
pleaseSelectRecords: "请先勾选记录",
|
||||
triggerTypes: {
|
||||
manual: "手动执行",
|
||||
timer: "定时执行",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,27 @@
|
||||
export default {
|
||||
accountInfo: "账号信息",
|
||||
securitySettings: "认证安全设置",
|
||||
confirmDisable2FA: "确定要关闭多重验证登录吗?",
|
||||
twoFactorAuth: "2FA多重验证登录",
|
||||
rebind: "重新绑定",
|
||||
twoFactorAuthHelper: "是否开启多重验证登录",
|
||||
bindDevice: "绑定设备",
|
||||
step1: "1. 安装任意一款支持Authenticator的验证APP,比如:",
|
||||
tooltipGoogleServiceError: "如果报没有找到谷歌服务的错误,您可以安装KK谷歌助手",
|
||||
step2: "2. 扫描二维码添加账号",
|
||||
step3: "3. 输入验证码",
|
||||
inputVerifyCode: "请输入验证码",
|
||||
myInfo: "我的信息",
|
||||
user: {
|
||||
greeting: "您好",
|
||||
profile: "账号信息",
|
||||
logout: "注销登录",
|
||||
|
||||
setting: {
|
||||
grantSetting: "授权委托设置",
|
||||
saveSuccess: "保存成功",
|
||||
allowAdminViewCerts: "授权管理员查看和下载证书",
|
||||
allowAdminViewCertsHelper: "允许管理员查看和下载我的所有证书",
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,73 @@
|
||||
export default {
|
||||
certificateRepo: {
|
||||
title: "证书仓库",
|
||||
sub: "从流水线生成的证书",
|
||||
},
|
||||
actionImportBatch: "批量导入",
|
||||
actionSyncIp: "同步IP",
|
||||
modalTitleSyncIp: "同步IP",
|
||||
modalContentSyncIp: "确定要同步IP吗?",
|
||||
notificationSyncComplete: "同步完成",
|
||||
actionCheckAll: "检查全部",
|
||||
modalTitleConfirm: "确认",
|
||||
modalContentCheckAll: "确认触发检查全部IP站点的证书吗?",
|
||||
notificationCheckSubmitted: "检查任务已提交",
|
||||
notificationCheckDescription: "请稍后刷新页面查看结果",
|
||||
tooltipCheckNow: "立即检查",
|
||||
notificationCheckSubmittedPleaseRefresh: "检查任务已提交,请稍后刷新查看结果",
|
||||
columnId: "ID",
|
||||
columnIp: "IP",
|
||||
helperIpCname: "也支持填写CNAME域名,源站域名",
|
||||
ruleIpRequired: "请输入IP",
|
||||
columnCertDomains: "证书域名",
|
||||
columnCertProvider: "颁发机构",
|
||||
columnCertStatus: "证书状态",
|
||||
statusNormal: "正常",
|
||||
statusExpired: "过期",
|
||||
columnCertExpiresTime: "证书到期时间",
|
||||
columnCheckStatus: "检查状态",
|
||||
columnLastCheckTime: "上次检查时间",
|
||||
columnSource: "来源",
|
||||
sourceSync: "同步",
|
||||
sourceManual: "手动",
|
||||
sourceImport: "导入",
|
||||
columnDisabled: "禁用启用",
|
||||
columnRemark: "备注",
|
||||
certificateNotGenerated: "证书还未生成,请先运行流水线",
|
||||
viewCertificateTitle: "查看证书",
|
||||
viewCert: {
|
||||
title: "查看证书",
|
||||
},
|
||||
download: {
|
||||
title: "下载证书",
|
||||
},
|
||||
checkStatus: {
|
||||
success: "成功",
|
||||
checking: "检查中",
|
||||
error: "异常",
|
||||
},
|
||||
uploadCustomCert: "上传自定义证书",
|
||||
sourcePipeline: "证书流水线",
|
||||
sourceManualUpload: "托管流水线",
|
||||
domains: "域名",
|
||||
enterDomain: "请输入域名",
|
||||
validDays: "有效天数",
|
||||
effectiveTime: "生效时间",
|
||||
expireTime: "过期时间",
|
||||
certIssuer: "证书颁发机构",
|
||||
applyTime: "申请时间",
|
||||
relatedPipeline: "关联流水线",
|
||||
statusSuccess: "成功",
|
||||
statusChecking: "检查中",
|
||||
statusError: "异常",
|
||||
modal: {
|
||||
close: "关闭",
|
||||
viewCertificateTitle: "查看证书",
|
||||
},
|
||||
domainList: {
|
||||
title: "域名列表",
|
||||
helper: "格式【域名:端口:名称:备注】,一行一个,其中端口、名称、备注可以省略\n比如:\nwww.baidu.com:443:百度:备注文本\nwww.taobao.com::淘宝\nwww.google.com",
|
||||
required: "请输入要导入的域名",
|
||||
placeholder: "www.baidu.com:443:百度:备注文本\nwww.taobao.com::淘宝\nwww.google.com\n",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,61 @@
|
||||
export default {
|
||||
framework: {
|
||||
title: "框架",
|
||||
home: "首页",
|
||||
},
|
||||
title: "证书自动化",
|
||||
pipeline: "证书自动化流水线",
|
||||
pipelineEdit: "编辑流水线",
|
||||
history: "执行历史记录",
|
||||
certStore: "证书仓库",
|
||||
siteMonitor: "站点证书监控",
|
||||
settings: "设置",
|
||||
accessManager: "授权管理",
|
||||
subDomain: "子域名托管设置",
|
||||
pipelineGroup: "流水线分组管理",
|
||||
openKey: "开放接口密钥",
|
||||
notification: "通知设置",
|
||||
siteMonitorSetting: "站点监控设置",
|
||||
userSecurity: "认证安全设置",
|
||||
userProfile: "账号信息",
|
||||
userGrant: "授权委托",
|
||||
mySuite: "我的套餐",
|
||||
suiteBuy: "套餐购买",
|
||||
myTrade: "我的订单",
|
||||
paymentReturn: "支付返回",
|
||||
source: "源码",
|
||||
github: "github",
|
||||
gitee: "gitee",
|
||||
sysResources: {
|
||||
sysRoot: "系统管理",
|
||||
sysConsole: "控制台",
|
||||
sysSettings: "系统设置",
|
||||
cnameSetting: "CNAME服务设置",
|
||||
emailSetting: "邮件服务器设置",
|
||||
siteSetting: "站点个性化",
|
||||
headerMenus: "顶部菜单设置",
|
||||
sysAccess: "系统级授权",
|
||||
sysPlugin: "插件管理",
|
||||
sysPluginEdit: "编辑插件",
|
||||
sysPluginConfig: "证书插件配置",
|
||||
accountBind: "账号绑定",
|
||||
permissionManager: "权限管理",
|
||||
roleManager: "角色管理",
|
||||
userManager: "用户管理",
|
||||
suiteManager: "套餐管理",
|
||||
suiteSetting: "套餐设置",
|
||||
orderManager: "订单管理",
|
||||
userSuites: "用户套餐",
|
||||
netTest: "网络测试",
|
||||
enterpriseManager: "企业管理设置",
|
||||
projectManager: "项目管理",
|
||||
enterpriseSetting: "企业设置",
|
||||
myProjectManager: "我的项目",
|
||||
myProjectDetail: "项目详情",
|
||||
projectJoin: "加入项目",
|
||||
currentProject: "当前项目",
|
||||
projectMemberManager: "项目成员管理",
|
||||
domainMonitorSetting: "域名监控设置",
|
||||
jobHistory: "监控执行记录",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
export default {
|
||||
email: {
|
||||
title: "收件邮箱",
|
||||
helper: "输入你的收件邮箱地址,支持多个邮箱",
|
||||
required: "此项必填",
|
||||
},
|
||||
notificationDefault: "使用默认通知",
|
||||
notificationType: "通知类型",
|
||||
selectNotificationType: "请选择通知类型",
|
||||
confirmSetDefaultNotification: "确定设置为默认通知?",
|
||||
edit_notification: "编辑通知",
|
||||
other_notification_method: "其他通知方式",
|
||||
notificationName: "通知名称",
|
||||
helperNotificationName: "随便填,当多个相同类型的通知时,便于区分",
|
||||
};
|
||||
@@ -0,0 +1,14 @@
|
||||
export default {
|
||||
scope: "权限范围",
|
||||
scopeOpenApiOnly: "仅开放接口",
|
||||
scopeFullAccount: "账户所有权限",
|
||||
scopeHelper: "仅开放接口只可以访问开放接口,账户所有权限可以访问所有接口",
|
||||
gen: {
|
||||
text: "接口测试",
|
||||
title: "x-certd-token",
|
||||
okText: "确定",
|
||||
contentPart1: "测试x-certd-token如下,您可以在3分钟内使用它进行",
|
||||
openApi: "开放接口",
|
||||
contentPart2: "请求测试",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,120 @@
|
||||
export default {
|
||||
hasExpired: "已过期",
|
||||
subdomainHosting: "子域名托管",
|
||||
subdomainHostingHint: "当你的域名设置了子域名托管,需要在此处创建记录,否则申请证书将失败",
|
||||
subdomainHosted: "托管的子域名",
|
||||
subdomainHelpText: "如果您不理解什么是子域托管,请不要随意设置(可能导致证书无法申请,以前设置过的cname记录也需要重新配置),可以参考文档",
|
||||
subdomainHelpSupportStart: "支持*号通配符,表示该域名下的子域名都是托管的(免费子域名)",
|
||||
subdomainManagement: "子域管理",
|
||||
pipelinePage: {
|
||||
addMore: "添加更多流水线",
|
||||
aliyunSubscriptionPipeline: "阿里云订阅流水线",
|
||||
legoCertPipeline: "Lego证书流水线",
|
||||
customPipeline: "自定义流水线",
|
||||
batchAddPipeline: "模版批量创建流水线",
|
||||
myPipelinesDesc: "流水线模式:申请证书->部署证书->定时运行",
|
||||
},
|
||||
customPipeline: "自定义流水线",
|
||||
createCertdPipeline: "创建证书流水线",
|
||||
commercialCertHosting: "已有证书托管",
|
||||
tooltip: {
|
||||
manualUploadOwnCert: "手动上传自有证书,执行自动部署",
|
||||
noAutoApplyCommercialCert: "并不能自动申请商业证书",
|
||||
manualUploadOnUpdate: "证书有更新时,都需要手动上传一次",
|
||||
},
|
||||
table: {
|
||||
confirmDeleteTitle: "确定要删除吗?",
|
||||
confirmDeleteMessage: "将删除该流水线相关的所有数据,包括执行历史、证书文件、证书仓库记录等",
|
||||
},
|
||||
play: {
|
||||
runPipeline: "运行流水线",
|
||||
confirm: "确认",
|
||||
confirmTrigger: "确定要触发运行吗?",
|
||||
pipelineStarted: "管道已经开始运行",
|
||||
},
|
||||
actions: {
|
||||
editPipeline: "编辑流水线",
|
||||
editConfigGroup: "修改配置/分组",
|
||||
viewCertificate: "查看证书",
|
||||
downloadCertificate: "下载证书",
|
||||
},
|
||||
pi: {
|
||||
validTime: "流水线有效期",
|
||||
validTimeHelper: "不填则为永久有效",
|
||||
},
|
||||
types: {
|
||||
certApply: "证书申请",
|
||||
certUpload: "证书上传",
|
||||
custom: "自定义",
|
||||
template: "模版",
|
||||
},
|
||||
myPipelines: "我的流水线",
|
||||
selectedCount: "已选择 {count} 项",
|
||||
batchForceRerun: "强制重新运行",
|
||||
batchRerun: "重新运行",
|
||||
applyCertificate: "申请证书",
|
||||
cronForm: {
|
||||
title: "定时脚本",
|
||||
helper: "点击上面的按钮,选择每天几点定时执行。\n建议设置为每天触发一次,证书未到期之前任务会跳过,不会重复执行",
|
||||
required: "此项必填",
|
||||
},
|
||||
plugin: {
|
||||
selectTitle: "证书申请插件",
|
||||
jsAcme: "JS-ACME:使用简单方便,功能强大【推荐】",
|
||||
legoAcme: "Lego-ACME:基于Lego实现,支持海量DNS提供商,熟悉LEGO的用户可以使用",
|
||||
aliyunOrder: "Aliyun-Order:从阿里云证书订单中获取证书更新",
|
||||
},
|
||||
pipelineForm: {
|
||||
createTitle: "创建证书流水线",
|
||||
moreParams: "更多参数",
|
||||
triggerCronTitle: "定时触发",
|
||||
triggerCronHelper: "点击上面的按钮,选择每天几点定时执行。\n建议设置为每天触发一次,证书未到期之前任务会跳过,不会重复执行",
|
||||
notificationTitle: "失败通知",
|
||||
notificationWhen: "通知时机",
|
||||
notificationHelper: "任务执行失败实时提醒",
|
||||
groupIdTitle: "流水线分组",
|
||||
addToMonitorEnabled: "添加到证书监控",
|
||||
addToMonitorDomains: "添加到监控域名",
|
||||
webhookEnabled: "开启Webhook",
|
||||
webhookEnabledHelper: "支持webhook触发流水线,请在触发源中查看webhook地址",
|
||||
},
|
||||
template: {
|
||||
title: "流水线模版",
|
||||
edit: "流水线模版编辑",
|
||||
importCreate: "流水线模版批量创建",
|
||||
intro: "可根据模版批量创建流水线",
|
||||
createTemplate: "创建模版",
|
||||
useTemplate: "使用此模板",
|
||||
batchCreate: "批量创建流水线",
|
||||
singleCreate: "创建单个流水线",
|
||||
templateName: "模板名称",
|
||||
enterTemplateName: "请输入模板名称",
|
||||
copyPipelineConfig: "复制该流水线配置作为模板来源",
|
||||
pipeline: "流水线",
|
||||
},
|
||||
editSchedule: "修改定时",
|
||||
timerTrigger: "定时触发",
|
||||
schedule: "定时",
|
||||
webhook: "Webhook",
|
||||
selectCron: "请选择定时Cron",
|
||||
batchEditSchedule: "批量修改定时",
|
||||
editTrigger: "编辑触发器",
|
||||
triggerName: "触发器名称",
|
||||
confirmDeleteTrigger: "确定要删除此触发器吗?",
|
||||
trigger_time: "触发时机",
|
||||
start_time: "开始时",
|
||||
success_time: "成功时",
|
||||
fail_to_success_time: "失败转成功时",
|
||||
fail_time: "失败时",
|
||||
helper_suggest_fail_only: "建议仅选择'失败时'和'失败转成功'两种即可",
|
||||
notification_config: "通知配置",
|
||||
please_select_notification: "请选择通知方式",
|
||||
please_select_type: "请选择类型",
|
||||
please_select_trigger_time: "请选择通知时机",
|
||||
please_select_notification_config: "请选择通知配置",
|
||||
confirm_delete_trigger: "确定要删除此触发器吗?",
|
||||
dates: {
|
||||
years: "{count}年",
|
||||
months: "{count}月",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,36 @@
|
||||
export default {
|
||||
ent: {
|
||||
projectName: "项目名称",
|
||||
projectDescription: "项目描述",
|
||||
projectDetailManager: "项目详情",
|
||||
projectDetailDescription: "管理项目成员",
|
||||
projectPermission: "权限",
|
||||
permission: {
|
||||
read: "查看",
|
||||
write: "修改",
|
||||
admin: "管理员",
|
||||
},
|
||||
projectMemberStatus: "成员状态",
|
||||
|
||||
isSystem: "是否系统项目",
|
||||
isSystemHelper: "系统级项目允许运行管理员插件",
|
||||
},
|
||||
project: {
|
||||
noProjectJoined: "您还没有加入任何项目",
|
||||
applyToJoin: "请申请加入项目以开始使用",
|
||||
projectList: "项目列表",
|
||||
createdAt: "创建时间",
|
||||
applyJoin: "申请加入",
|
||||
noProjects: "暂无项目",
|
||||
fetchFailed: "获取项目列表失败",
|
||||
applySuccess: "申请成功,等待管理员审核",
|
||||
applyFailed: "申请失败,请稍后重试",
|
||||
leave: "退出项目",
|
||||
leaveSuccess: "退出项目成功",
|
||||
leaveFailed: "退出项目失败,请稍后重试",
|
||||
applyJoinConfirm: "确认加入项目?",
|
||||
leaveConfirm: "确认退出项目?",
|
||||
viewDetail: "查看详情",
|
||||
projectManage: "项目管理",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,67 @@
|
||||
export default {
|
||||
order: {
|
||||
confirmTitle: "订单确认",
|
||||
package: "套餐",
|
||||
description: "说明",
|
||||
specifications: "规格",
|
||||
pipeline: "流水线",
|
||||
domain: "域名",
|
||||
deployTimes: "部署次数",
|
||||
monitorCount: "域名监控数",
|
||||
duration: "时长",
|
||||
price: "价格",
|
||||
paymentMethod: "支付方式",
|
||||
free: "免费",
|
||||
unit: {
|
||||
pieces: "条",
|
||||
count: "个",
|
||||
times: "次",
|
||||
},
|
||||
},
|
||||
gift_package: "赠送套餐",
|
||||
package_name: "套餐名称",
|
||||
click_to_select: "点击选择",
|
||||
please_select_package: "请选择套餐",
|
||||
package: "套餐",
|
||||
addon_package: "加量包",
|
||||
domain_count: "域名数量",
|
||||
unit_count: "个",
|
||||
pipeline_count: "流水线数量",
|
||||
unit_item: "条",
|
||||
deploy_count: "部署次数",
|
||||
unit_times: "次",
|
||||
monitor_count: "证书监控数量",
|
||||
duration: "时长",
|
||||
active_time: "激活时间",
|
||||
expires_time: "过期时间",
|
||||
is_present: "是否赠送",
|
||||
is_present_yes: "是",
|
||||
is_present_no: "否",
|
||||
ordera: "排序",
|
||||
supportBuy: "支持购买",
|
||||
intro: "介绍",
|
||||
packageContent: "套餐内容",
|
||||
maxDomainCount: "最大域名数",
|
||||
maxPipelineCount: "最大流水线数",
|
||||
maxDeployCount: "最大部署数",
|
||||
maxMonitorCount: "最大监控数",
|
||||
price: "价格",
|
||||
durationPrices: "时长价格",
|
||||
packageName: "套餐名称",
|
||||
addon: "加量包",
|
||||
typeHelper: "套餐:同一时间只有最新购买的一个生效\n加量包:可购买多个,购买后立即生效,不影响套餐\n套餐和加量包数量可叠加",
|
||||
pipelineCount: "流水线数量",
|
||||
unitPipeline: "条",
|
||||
deployCount: "部署次数",
|
||||
unitDeploy: "次",
|
||||
monitorCount: "证书监控数量",
|
||||
unitCount: "个",
|
||||
durationPriceTitle: "时长及价格",
|
||||
selectDuration: "选择时长",
|
||||
supportPurchase: "支持购买",
|
||||
cannotPurchase: "不能购买",
|
||||
shelfStatus: "上下架",
|
||||
onShelf: "上架",
|
||||
offShelf: "下架",
|
||||
orderHelper: "越小越靠前",
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
export default {
|
||||
max50Chars: "最大50个字符",
|
||||
permissionManagement: "权限管理",
|
||||
adda: "添加",
|
||||
rootNode: "根节点",
|
||||
permissionName: "权限名称",
|
||||
enterPermissionName: "请输入权限名称",
|
||||
permissionCode: "权限代码",
|
||||
enterPermissionCode: "请输入权限代码",
|
||||
max100Chars: "最大100个字符",
|
||||
examplePermissionCode: "例如:sys:user:view",
|
||||
sortOrder: "排序",
|
||||
sortRequired: "排序号必填",
|
||||
parentNode: "父节点",
|
||||
roleManagement: "角色管理",
|
||||
assignPermissions: "分配权限",
|
||||
roleName: "角色名称",
|
||||
enterRoleName: "请输入角色名称",
|
||||
unlockLogin: "解除登录锁定",
|
||||
notice: "提示",
|
||||
confirmUnlock: "确定要解除该用户的登录锁定吗?",
|
||||
unlockSuccess: "解除成功",
|
||||
enterUsername: "请输入用户名",
|
||||
modifyPasswordIfFilled: "填写则修改密码",
|
||||
emaila: "邮箱",
|
||||
mobile: "手机号",
|
||||
validTime: "有效期",
|
||||
remark: "备注",
|
||||
roles: "角色",
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
export default {
|
||||
cnameTitle: "CNAME服务配置",
|
||||
cnameDescription: "此处配置的域名作为其他域名校验的代理,当别的域名需要申请证书时,通过CNAME映射到此域名上来验证所有权。好处是任何域名都可以通过此方式申请证书,也无需填写AccessSecret。",
|
||||
cnameLinkText: "CNAME功能原理及使用说明",
|
||||
cnameDomain: "CNAME域名",
|
||||
cnameDomainPlaceholder: "cname.handsfree.work",
|
||||
cnameDomainHelper: "需要一个右边DNS提供商注册的域名(也可以将其他域名的dns服务器转移到这几家来)。\nCNAME域名一旦确定不可修改,建议使用一级子域名",
|
||||
cnameDomainPattern: "域名不能使用星号",
|
||||
dnsProvider: "DNS提供商",
|
||||
dnsProviderAuthorization: "DNS提供商授权",
|
||||
};
|
||||
@@ -0,0 +1,43 @@
|
||||
export default {
|
||||
titlea: "名称",
|
||||
pluginFile: "插件文件",
|
||||
selectPluginFile: "选择插件文件",
|
||||
overrideSameName: "同名覆盖",
|
||||
override: "覆盖",
|
||||
noOverride: "不覆盖",
|
||||
overrideHelper: "如果已有相同名称插件,直接覆盖",
|
||||
importPlugin: "导入插件",
|
||||
customPlugin: "自定义插件",
|
||||
pluginType: "插件类型",
|
||||
auth: "授权",
|
||||
dns: "DNS",
|
||||
deployPlugin: "部署插件",
|
||||
icon: "图标",
|
||||
pluginName: "插件名称",
|
||||
pluginNameHelper: "必须为英文或数字,驼峰命名,类型作为前缀\n示例:AliyunDeployToCDN\n插件使用后,名称不可修改",
|
||||
pluginNameRuleMsg: "必须为英文或数字,驼峰命名,类型作为前缀",
|
||||
author: "作者",
|
||||
authorHelper: "上传插件市场时作为前缀,如 greper/pluginName",
|
||||
authorRuleMsg: "必须为英文或数字",
|
||||
titleHelper: "插件中文名称",
|
||||
descriptionHelper: "插件描述",
|
||||
builtIn: "内置",
|
||||
custom: "自定义",
|
||||
store: "市场",
|
||||
version: "版本",
|
||||
pluginDependencies: "插件依赖",
|
||||
pluginDependenciesHelper: "格式: [作者/]插件名[:版本],需先安装依赖插件",
|
||||
editableRunStrategy: "可编辑运行策略",
|
||||
editable: "可编辑",
|
||||
notEditable: "不可编辑",
|
||||
runStrategy: "运行策略",
|
||||
normalRun: "正常运行",
|
||||
skipOnSuccess: "成功跳过(部署任务)",
|
||||
defaultRunStrategyHelper: "默认运行策略",
|
||||
enableDisable: "启用/禁用",
|
||||
confirmToggle: "确认要",
|
||||
pluginGroup: "插件分组",
|
||||
pluginManagement: "插件管理",
|
||||
pluginBetaWarning: "自定义插件处于BETA测试版,后续可能会有破坏性变更",
|
||||
pleaseSelectRecord: "请先勾选记录",
|
||||
};
|
||||
@@ -0,0 +1,186 @@
|
||||
export default {
|
||||
sys: {
|
||||
setting: {
|
||||
baseSetting: "基本设置",
|
||||
registerSetting: "注册设置",
|
||||
safeSetting: "安全设置",
|
||||
paymentSetting: "支付设置",
|
||||
captchaSetting: "验证码设置",
|
||||
pipelineSetting: "流水线设置",
|
||||
oauthSetting: "第三方登录",
|
||||
networkSetting: "网络设置",
|
||||
adminModeSetting: "管理模式",
|
||||
adminModeHelper: "企业管理模式: 企业内部使用,通过项目来隔离权限,流水线、授权数据属于项目。\nsaas模式:供外部用户注册使用,各个用户之间数据隔离,流水线、授权数据属于用户。",
|
||||
|
||||
adminMode: "管理模式",
|
||||
enterpriseMode: "企业模式",
|
||||
saasMode: "SaaS模式",
|
||||
|
||||
showRunStrategy: "显示运行策略选择",
|
||||
showRunStrategyHelper: "任务设置中是否允许选择运行策略",
|
||||
|
||||
captchaEnabled: "启用登录验证码",
|
||||
captchaHelper: "登录时是否启用验证码",
|
||||
captchaType: "验证码配置",
|
||||
captchaTest: "测试验证码",
|
||||
captchaTestHelper: "保存后再点击测试,请务必测试通过了,再开启登录验证码",
|
||||
|
||||
pipelineValidTimeEnabled: "启用流水线有效期",
|
||||
pipelineValidTimeEnabledHelper: "是否启用流水线有效期",
|
||||
certDomainAddToMonitorEnabled: "证书域名添加到证书监控",
|
||||
certDomainAddToMonitorEnabledHelper: "创建证书流水线时是否可以选择将域名添加到证书监控",
|
||||
|
||||
defaultCertRenewDays: "默认到期前更新天数",
|
||||
defaultCertRenewDaysHelper: "创建证书流水线时,默认的证书到期前更新天数",
|
||||
defaultCertRenewDaysRecommend: "默认值15",
|
||||
|
||||
pipelineMaxRunningCount: "同时最大运行流水线数量",
|
||||
pipelineMaxRunningCountHelper: "同一个用户同时运行的最大流水线数量,避免同时触发太多导致ACME账户被限制",
|
||||
pipelineMaxRunningCountRecommend: "推荐5-15,默认10",
|
||||
acmeWalkFromAuthoritative: "从权威NS检查TXT记录",
|
||||
acmeWalkFromAuthoritativeHelper: "申请证书时,是否从权威NS服务器检查TXT记录,如果影响申请证书,可以关闭",
|
||||
|
||||
fixedCertExpireDays: "固定证书有效期天数",
|
||||
fixedCertExpireDaysHelper: "固定证书有效期天数,有助于列表进度条整齐显示",
|
||||
fixedCertExpireDaysRecommend: "推荐90",
|
||||
|
||||
enableOauth: "启用第三方登录",
|
||||
oauthEnabledHelper: "是否启用第三方登录",
|
||||
oauthProviders: "第三方登录提供商",
|
||||
oauthType: "第三方登录类型",
|
||||
oauthConfig: "第三方登录配置",
|
||||
oauthProviderSelectorPlaceholder: "未配置",
|
||||
oauthCallback: "回调地址",
|
||||
oauthCallbackHelper: "复制回调地址,配置到对应提供商的回调地址中",
|
||||
oauthCallbackCopy: "复制回调地址",
|
||||
oauthAutoRegister: "自动注册用户",
|
||||
oauthAutoRegisterHelper: "当第三方账户未绑定本站账号时,是否自动注册用户,默认由用户选择",
|
||||
oauthAutoRegisterCheckedText: "自动注册",
|
||||
oauthAutoRegisterUnCheckedText: "用户选择",
|
||||
oauthAutoRedirect: "自动跳转第三方登录",
|
||||
oauthAutoRedirectHelper: "是否自动跳转第三方登录(使用第一个已启用的第三方登录类型)",
|
||||
oauthOnly: "仅使用第三方登录",
|
||||
oauthOnlyHelper: "是否仅使用第三方登录,关闭密码登录(注意:请务必在测试第三方登录功能正常后再开启,否则会导致无法登录)\n 如果无法登录,请访问 http://你的certd地址/#/login?oauthOnly=false 来临时关闭此模式",
|
||||
enablePasskey: "启用Passkey登录",
|
||||
passkeyHostnameNotSame: "当前域名与主绑定域名不同",
|
||||
passkeyEnabledHelper: "1、站点必须启用https \n2、passkey的rpId以主绑定域名为准,当前主域名:{0} \n3、站点域名不能变,否则会导致已注册的passkey失效。",
|
||||
email: {
|
||||
templates: "邮件模板",
|
||||
templateType: "模板类型",
|
||||
templateProvider: "模板配置",
|
||||
|
||||
templateSetting: "邮件模板设置",
|
||||
serverSetting: "邮件服务器设置",
|
||||
sendTest: "发送测试",
|
||||
|
||||
templateProviderSelectorPlaceholder: "未配置",
|
||||
},
|
||||
notice: "系统公告",
|
||||
noticeHelper: "系统公告,将在首页显示",
|
||||
noticePlaceholder: "系统公告",
|
||||
customFooter: "自定义页脚",
|
||||
customFooterHelper: "自定义站点页脚,将在页面底部显示,支持HTML格式",
|
||||
customFooterPlaceholder: "自定义页脚内容",
|
||||
|
||||
reverseProxy: "反向代理列表",
|
||||
reverseProxyHelper: "证书颁发机构ACME地址的反向代理,在申请证书时自动使用",
|
||||
reverseProxyPlaceholder: "http://le.px.handfree.work",
|
||||
reverseProxyEmpty: "未配置反向代理",
|
||||
environmentVars: "环境变量",
|
||||
environmentVarsHelper: "配置运行时环境变量,每行一个,格式:KEY=VALUE",
|
||||
bindUrl: "绑定URL",
|
||||
bindUrlHelper: "绑定URL,在各类通知中显示你的站点URL",
|
||||
},
|
||||
},
|
||||
icpRegistrationNumber: "ICP备案号",
|
||||
icpPlaceholder: "粤ICP备xxxxxxx号",
|
||||
publicSecurityRegistrationNumber: "网安备案号",
|
||||
publicSecurityPlaceholder: "京公网安备xxxxxxx号",
|
||||
enableAssistant: "开启小助手",
|
||||
allowCrawlers: "允许爬虫",
|
||||
httpProxy: "HTTP代理",
|
||||
httpProxyPlaceholder: "http://192.168.1.2:18010/",
|
||||
httpProxyHelper: "当某些网站被墙时可以配置",
|
||||
httpsProxy: "HTTPS代理",
|
||||
httpsProxyPlaceholder: "http://192.168.1.2:18010/",
|
||||
saveThenTestTitle: "保存后,再点击测试",
|
||||
httpsProxyHelper: "一般这两个代理填一样的,保存后再测试",
|
||||
dualStackNetwork: "双栈网络",
|
||||
ipv4Priority: "IPV4优先",
|
||||
ipv6Priority: "IPV6优先",
|
||||
dualStackNetworkHelper: "如果选择IPv6优先,需要在docker-compose.yaml中启用ipv6",
|
||||
enableCommonCnameService: "启用公共CNAME服务",
|
||||
commonCnameHelper: "是否可以使用公共CNAME服务,如果禁用,且没有设置<a href='#/sys/cname/provider'>自定义CNAME服务</a>,则无法使用CNAME代理方式申请证书",
|
||||
enableCommonSelfServicePasswordRetrieval: "启用自助找回密码",
|
||||
saveButton: "保存",
|
||||
stopSuccess: "停止成功",
|
||||
google: "Google",
|
||||
baidu: "百度",
|
||||
testFailed: "测试失败",
|
||||
testCompleted: "测试完成",
|
||||
manageOtherUserPipeline: "管理其他用户流水线",
|
||||
limitUserPipelineCount: "限制用户流水线数量",
|
||||
limitUserPipelineCountHelper: "0为不限制",
|
||||
enableSelfRegistration: "开启自助注册",
|
||||
enableUserValidityPeriod: "开启用户有效期",
|
||||
userValidityPeriodHelper: "有效期内用户可正常使用,失效后用户的流水线将被停用",
|
||||
enableUsernameRegistration: "开启用户名注册",
|
||||
enableEmailRegistration: "开启邮箱注册",
|
||||
proFeature: "Certd专业版功能",
|
||||
emailServerSetup: "设置邮箱服务器",
|
||||
enableSmsLoginRegister: "开启手机号登录、注册",
|
||||
defaultLoginType: "默认登录方式",
|
||||
commFeature: "Certd商业版功能",
|
||||
smsProvider: "短信提供商",
|
||||
aliyunSms: "阿里云短信",
|
||||
tencentSms: "腾讯云短信",
|
||||
yfySms: "易发云短信",
|
||||
smsTest: "短信测试",
|
||||
testMobilePlaceholder: "输入测试手机号",
|
||||
saveThenTest: "保存后再点击测试",
|
||||
enterTestMobile: "请输入测试手机号",
|
||||
sendSuccess: "发送成功",
|
||||
atLeastOneLoginRequired: "密码登录和手机号登录至少开启一个",
|
||||
siteHide: "站点隐藏",
|
||||
enableSiteHide: "启用站点隐藏",
|
||||
siteHideDescription: "可以在平时关闭站点的可访问性,需要时再打开,增强站点安全性",
|
||||
randomAddress: "随机地址",
|
||||
siteHideUrlHelper: "站点被隐藏后,需要访问此URL解锁,才能正常访问",
|
||||
fullUnlockUrl: "完整解除隐藏地址",
|
||||
saveThisUrl: "请保存好此地址",
|
||||
unlockPassword: "解除密码",
|
||||
unlockPasswordHelper: "解除隐藏时需要输入密码,第一次需要设置密码,填写则重置密码",
|
||||
autoHideTime: "自动隐藏时间",
|
||||
autoHideTimeHelper: "多少分钟内无请求自动隐藏",
|
||||
hideOpenApi: "隐藏开放接口",
|
||||
hideOpenApiHelper: "是否隐藏开放接口,是否同时隐藏/api/v1开头的接口",
|
||||
hideSiteImmediately: "立即隐藏站点",
|
||||
hideImmediately: "立即隐藏",
|
||||
confirmHideSiteTitle: "确定要立即隐藏站点吗?",
|
||||
confirmHideSiteContent: "隐藏后,将无法访问站点,请谨慎操作",
|
||||
siteHiddenSuccess: "站点已隐藏",
|
||||
emailServerSettings: "邮件服务器设置",
|
||||
setEmailSendingServer: "设置邮件发送服务器",
|
||||
useCustomEmailServer: "使用自定义邮件服务器",
|
||||
smtpDomain: "SMTP域名",
|
||||
pleaseEnterSmtpDomain: "请输入smtp域名或ip",
|
||||
smtpPort: "SMTP端口",
|
||||
pleaseEnterSmtpPort: "请输入smtp端口号",
|
||||
pleaseEnterUsername: "请输入用户名",
|
||||
pleaseEnterPassword: "请输入密码",
|
||||
qqEmailAuthCodeHelper: "如果是qq邮箱,需要到qq邮箱的设置里面申请授权码作为密码",
|
||||
senderEmailHelper: "您可以使用 名称<邮箱> 的格式,来修改发件人名称,例如: autossl<certd{'@'}example.com>",
|
||||
senderEmail: "发件邮箱",
|
||||
pleaseEnterSenderEmail: "请输入发件邮箱",
|
||||
useSsl: "是否ssl",
|
||||
sslPortNote: "ssl和非ssl的smtp端口是不一样的,注意修改端口",
|
||||
ignoreCertValidation: "忽略证书校验",
|
||||
useOfficialEmailServer: "使用官方邮件服务器",
|
||||
useOfficialEmailServerHelper: "使用官方邮箱服务器直接发邮件,免除繁琐的配置",
|
||||
testReceiverEmail: "测试收件邮箱",
|
||||
pleaseEnterTestReceiverEmail: "请输入测试收件邮箱",
|
||||
saveBeforeTest: "保存后再点击测试",
|
||||
sendFailHelpDoc: "发送失败???",
|
||||
emailConfigHelpDoc: "邮件配置帮助文档",
|
||||
tryOfficialEmailServer: "您还可以试试使用官方邮件服务器↗↗↗↗↗↗↗↗",
|
||||
};
|
||||
@@ -0,0 +1,7 @@
|
||||
export default {
|
||||
steps: {
|
||||
createPipeline: "创建证书流水线",
|
||||
addTask: "添加部署任务",
|
||||
scheduledRun: "定时运行",
|
||||
},
|
||||
};
|
||||
@@ -7,8 +7,13 @@ export default {
|
||||
settingLink: "站点监控设置",
|
||||
limitInfo: "基础版限制1条,专业版以上无限制,当前",
|
||||
checkAll: "检查全部",
|
||||
checkNow: "立即检查",
|
||||
batchDelete: "批量删除",
|
||||
confirmTitle: "确认",
|
||||
confirmContent: "确认触发检查全部站点证书吗?",
|
||||
batchDeleteConfirm: "确定要批量删除这{count}条记录吗",
|
||||
deleteSuccess: "删除成功",
|
||||
selectRecordsFirst: "请先勾选记录",
|
||||
checkSubmitted: "检查任务已提交",
|
||||
pleaseRefresh: "请稍后刷新页面查看结果",
|
||||
siteName: "站点名称",
|
||||
@@ -53,6 +58,10 @@ export default {
|
||||
certInfoId: "证书ID",
|
||||
checkSubmittedRefresh: "检查任务已提交,请稍后刷新查看结果",
|
||||
ipManagement: "IP管理",
|
||||
siteIpMonitor: "站点IP监控",
|
||||
ipList: "IP列表",
|
||||
ipListHelper: "IP或者CNAME域名,一行一个",
|
||||
enterImportIpOrDomain: "请输入要导入的IP或域名",
|
||||
bulkImport: "批量导入",
|
||||
basicLimitError: "基础版只能添加一个监控站点,请赞助升级专业版",
|
||||
limitExceeded: "对不起,您最多只能创建条{max}监控记录,请购买或升级套餐",
|
||||
|
||||
@@ -89,15 +89,15 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
form: {
|
||||
async beforeSubmit({ form }) {
|
||||
if (form.challengeType === "cname") {
|
||||
throw new Error("CNAME方式请前往CNAME记录页面进行管理");
|
||||
throw new Error(t("certd.domain.cnameManagedInCnamePage"));
|
||||
}
|
||||
if (form.challengeType === "dns") {
|
||||
const isSubdomain = await api.IsSubdomain({ domain: form.domain });
|
||||
if (isSubdomain && !subdomainConfirmed.value) {
|
||||
Modal.confirm({
|
||||
title: "子域名确认",
|
||||
content: `检测到${form.domain}为子域名,只有托管子域名和免费二级子域名才需要在此处维护,否则会导致申请证书失败,请确认是否继续?`,
|
||||
okText: "确认",
|
||||
title: t("certd.domain.subdomainConfirmTitle"),
|
||||
content: t("certd.domain.subdomainConfirmContent", { domain: form.domain }),
|
||||
okText: t("common.confirm"),
|
||||
okType: "danger",
|
||||
onOk: () => {
|
||||
subdomainConfirmed.value = true;
|
||||
@@ -119,9 +119,9 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
},
|
||||
import: {
|
||||
show: hasActionPermission("write"),
|
||||
title: "从域名提供商导入域名",
|
||||
title: t("certd.domain.importFromProvider"),
|
||||
type: "primary",
|
||||
text: "从域名提供商导入",
|
||||
text: t("certd.domain.importFromProvider"),
|
||||
needPlus: true,
|
||||
color: "gold",
|
||||
icon: "mingcute:vip-1-line",
|
||||
@@ -135,14 +135,14 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
},
|
||||
syncExpirationDate: {
|
||||
show: hasActionPermission("write"),
|
||||
title: "同步域名过期时间",
|
||||
title: t("certd.domain.syncExpirationDate"),
|
||||
type: "primary",
|
||||
icon: "ion:refresh-outline",
|
||||
text: "同步域名过期时间",
|
||||
text: t("certd.domain.syncExpirationDate"),
|
||||
click: async () => {
|
||||
await api.SyncExpirationStart();
|
||||
notification.success({
|
||||
message: "同步任务已提交",
|
||||
message: t("certd.domain.syncTaskSubmitted"),
|
||||
});
|
||||
setTimeout(() => {
|
||||
crudExpose.doRefresh();
|
||||
@@ -151,10 +151,10 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
},
|
||||
monitorSettingSave: {
|
||||
show: hasActionPermission("write"),
|
||||
title: "域名过期监控设置",
|
||||
title: t("certd.domain.expirationMonitorSetting"),
|
||||
type: "primary",
|
||||
icon: "ion:save-outline",
|
||||
text: "域名过期监控设置",
|
||||
text: t("certd.domain.expirationMonitorSetting"),
|
||||
click: async () => {
|
||||
router.push({
|
||||
path: "/certd/cert/domain/setting",
|
||||
@@ -184,7 +184,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
},
|
||||
form: {
|
||||
required: true,
|
||||
helper: "注意:DNS校验方式下,子域名不需要在此处维护,否则会影响证书申请(子域名托管或免费二级域名除外)",
|
||||
helper: t("certd.domain.subdomainDnsHelper"),
|
||||
},
|
||||
editForm: {
|
||||
component: {
|
||||
@@ -361,7 +361,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
<fs-values-format modelValue={row.challengeType} dict={Dicts.challengeTypeDict} color={"auto"}></fs-values-format>
|
||||
<fs-values-format modelValue={row.httpUploaderType} dict={httpUploaderTypeDict} color={"auto"}></fs-values-format>
|
||||
<fs-values-format class={"ml-5"} modelValue={row.httpUploaderAccess} dict={accessDict} color={"auto"}></fs-values-format>
|
||||
<a-tag class={"ml-5 flex items-center"}>路径:{row.httpUploadRootDir}</a-tag>
|
||||
<a-tag class={"ml-5 flex items-center"}>{t("certd.domain.path")}: {row.httpUploadRootDir}</a-tag>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
<template>
|
||||
<div class="domain-import-task-status min-h-[300px]">
|
||||
<div class="action mb-5">
|
||||
<fs-button type="primary" icon="mingcute:vip-1-line" @click="addTask">添加导入任务</fs-button>
|
||||
<fs-button type="primary" icon="ion:refresh-outline" class="ml-2" @click="loadImportTaskStatus">刷新</fs-button>
|
||||
<fs-button type="primary" icon="mingcute:vip-1-line" @click="addTask">{{ t("certd.domain.addImportTask") }}</fs-button>
|
||||
<fs-button type="primary" icon="ion:refresh-outline" class="ml-2" @click="loadImportTaskStatus">{{ t("certd.domain.refresh") }}</fs-button>
|
||||
</div>
|
||||
<div class="table-container overflow-auto mb-10">
|
||||
<table class="cd-table border-gray-300 w-full">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="w-[220px]">来源</th>
|
||||
<th class="">进度</th>
|
||||
<th class="w-[220px]">操作</th>
|
||||
<th class="w-[220px]">{{ t("certd.sourcee") }}</th>
|
||||
<th class="">{{ t("certd.domain.progress") }}</th>
|
||||
<th class="w-[220px]">{{ t("certd.domain.operation") }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -27,23 +27,23 @@
|
||||
<td>
|
||||
<div v-if="item.task">
|
||||
<div>
|
||||
<a-tag color="blue">总数:{{ item.task?.total }}</a-tag>
|
||||
<a-tag color="success" class="ml-2">成功:{{ item.task?.successCount }}</a-tag>
|
||||
<a-tag type="info" class="ml-2">跳过:{{ item.task?.skipCount }}</a-tag>
|
||||
<a-tag color="blue">{{ t("certd.domain.total") }}:{{ item.task?.total }}</a-tag>
|
||||
<a-tag color="success" class="ml-2">{{ t("certd.success") }}:{{ item.task?.successCount }}</a-tag>
|
||||
<a-tag type="info" class="ml-2">{{ t("certd.domain.skipped") }}:{{ item.task?.skipCount }}</a-tag>
|
||||
<a-tooltip v-if="item.task?.errors.length > 0">
|
||||
<template #title>
|
||||
<div v-for="error in item.task?.errors" :key="error">{{ error }}</div>
|
||||
</template>
|
||||
<a-tag color="red" class="ml-2">失败:{{ item.task?.errors.length }}</a-tag>
|
||||
<a-tag color="red" class="ml-2">{{ t("certd.domain.failed") }}:{{ item.task?.errors.length }}</a-tag>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<a-progress :percent="item.task?.progress" size="small" status="active" />
|
||||
</div>
|
||||
<div v-else>未执行</div>
|
||||
<div v-else>{{ t("certd.domain.notExecuted") }}</div>
|
||||
</td>
|
||||
<td>
|
||||
<fs-button type="primary" icon="ion:play-outline" :disabled="item.task?.status === 'running'" @click="startTask(item)">执行</fs-button>
|
||||
<fs-button type="primary" class="ml-2" danger icon="ion:trash-outline" @click="deleteTask(item)">删除</fs-button>
|
||||
<fs-button type="primary" icon="ion:play-outline" :disabled="item.task?.status === 'running'" @click="startTask(item)">{{ t("certd.domain.execute") }}</fs-button>
|
||||
<fs-button type="primary" class="ml-2" danger icon="ion:trash-outline" @click="deleteTask(item)">{{ t("certd.domain.delete") }}</fs-button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -58,11 +58,13 @@ import { onMounted, onUnmounted, ref } from "vue";
|
||||
import * as api from "./api";
|
||||
import { useDomainImport } from "./use";
|
||||
import { useSettingStore } from "/@/store/settings";
|
||||
import { useI18n } from "/@/locales";
|
||||
defineOptions({
|
||||
name: "DomainImportTaskStatus",
|
||||
});
|
||||
|
||||
const list = ref([]);
|
||||
const { t } = useI18n();
|
||||
|
||||
async function loadImportTaskStatus() {
|
||||
const res = await api.ImportTaskStatus();
|
||||
@@ -77,8 +79,8 @@ async function startTask(item: any) {
|
||||
|
||||
async function deleteTask(item: any) {
|
||||
Modal.confirm({
|
||||
title: "确认删除吗?",
|
||||
okText: "确认",
|
||||
title: t("certd.domain.confirmDelete"),
|
||||
okText: t("common.confirm"),
|
||||
okType: "danger",
|
||||
onOk: async () => {
|
||||
await api.ImportTaskDelete(item.key);
|
||||
|
||||
@@ -5,12 +5,14 @@ import { compute } from "@fast-crud/fast-crud";
|
||||
import { Dicts } from "/@/components/plugins/lib/dicts";
|
||||
import { useSettingStore } from "/@/store/settings";
|
||||
import DomainImportTaskStatus from "./import.vue";
|
||||
import { useI18n } from "/@/locales";
|
||||
export function useDomainImport() {
|
||||
const { openFormDialog } = useFormDialog();
|
||||
const { t } = useI18n();
|
||||
|
||||
const columns = {
|
||||
dnsProviderType: {
|
||||
title: "域名提供商",
|
||||
title: t("certd.domain.domainProvider"),
|
||||
type: "text",
|
||||
form: {
|
||||
component: {
|
||||
@@ -29,14 +31,14 @@ export function useDomainImport() {
|
||||
},
|
||||
},
|
||||
dnsProviderAccessType: {
|
||||
title: "域名提供商访问类型",
|
||||
title: t("certd.domain.domainProviderAccessType"),
|
||||
type: "text",
|
||||
form: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
dnsProviderAccessId: {
|
||||
title: "域名提供商授权",
|
||||
title: t("certd.domain.domainProviderAccess"),
|
||||
type: "text",
|
||||
form: {
|
||||
component: {
|
||||
@@ -52,7 +54,7 @@ export function useDomainImport() {
|
||||
|
||||
return function openDomainImportDialog(req: { afterSubmit?: (res?: any) => void; form?: any }) {
|
||||
openFormDialog({
|
||||
title: "从域名提供商导入域名",
|
||||
title: t("certd.domain.importFromProvider"),
|
||||
columns: columns,
|
||||
initialForm: {
|
||||
...req.form,
|
||||
@@ -73,10 +75,11 @@ export function useDomainImport() {
|
||||
|
||||
export function useDomainImportManage() {
|
||||
const { openFormDialog } = useFormDialog();
|
||||
const { t } = useI18n();
|
||||
const settingStore = useSettingStore();
|
||||
return async function openDomainImportManageDialog(req: { afterSubmit?: (res?: any) => void; form?: any; zIndex?: number }) {
|
||||
await openFormDialog({
|
||||
title: "从域名提供商导入域名",
|
||||
title: t("certd.domain.importFromProvider"),
|
||||
body: () => {
|
||||
return <DomainImportTaskStatus />;
|
||||
},
|
||||
|
||||
@@ -79,9 +79,9 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
},
|
||||
import: {
|
||||
show: hasActionPermission("write"),
|
||||
title: "导入CNAME记录",
|
||||
title: t("certd.cname.importRecords"),
|
||||
type: "primary",
|
||||
text: "批量导入",
|
||||
text: t("certd.cname.batchImport"),
|
||||
icon: "mingcute:vip-1-line",
|
||||
click: () => {
|
||||
settingStore.checkPlus();
|
||||
@@ -95,9 +95,9 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
},
|
||||
},
|
||||
export: {
|
||||
title: "导出CNAME记录之后,可用于批量导入cname解析到域名注册商",
|
||||
title: t("certd.cname.exportRecordsTip"),
|
||||
type: "primary",
|
||||
text: "批量导出",
|
||||
text: t("certd.cname.batchExport"),
|
||||
icon: "mingcute:vip-1-line",
|
||||
click: () => {
|
||||
settingStore.checkPlus();
|
||||
@@ -235,8 +235,8 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
cellRender({ value, row }) {
|
||||
async function resetStatus() {
|
||||
Modal.confirm({
|
||||
title: "重置状态",
|
||||
content: "确定要重置校验状态吗?",
|
||||
title: t("certd.cname.resetStatus"),
|
||||
content: t("certd.cname.confirmResetStatus"),
|
||||
onOk: async () => {
|
||||
await api.ResetStatus(row.id);
|
||||
await crudExpose.doRefresh();
|
||||
@@ -253,7 +253,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
)}
|
||||
|
||||
{row.status === "valid" && (
|
||||
<a-tooltip title={"重置校验状态,重新校验"}>
|
||||
<a-tooltip title={t("certd.cname.resetStatusTooltip")}>
|
||||
<fs-icon class={"ml-5 pointer "} icon="solar:undo-left-square-bold" onClick={resetStatus}></fs-icon>
|
||||
</a-tooltip>
|
||||
)}
|
||||
|
||||
@@ -2,6 +2,7 @@ import { dict } from "@fast-crud/fast-crud";
|
||||
import { message } from "ant-design-vue";
|
||||
import * as api from "./api";
|
||||
import { useFormDialog } from "/@/use/use-dialog";
|
||||
import { useI18n } from "/@/locales";
|
||||
|
||||
export const cnameProviderDict = dict({
|
||||
url: "/cname/provider/list",
|
||||
@@ -10,10 +11,11 @@ export const cnameProviderDict = dict({
|
||||
});
|
||||
export function useCnameImport() {
|
||||
const { openFormDialog } = useFormDialog();
|
||||
const { t } = useI18n();
|
||||
|
||||
const columns = {
|
||||
domainList: {
|
||||
title: "域名列表",
|
||||
title: t("certd.cname.domainList"),
|
||||
type: "text",
|
||||
form: {
|
||||
component: {
|
||||
@@ -24,11 +26,11 @@ export function useCnameImport() {
|
||||
span: 24,
|
||||
},
|
||||
required: true,
|
||||
helper: "每个域名一行,批量导入\n泛域名请去掉*.\n已经存在的会自动跳过",
|
||||
helper: t("certd.cname.domainListHelper"),
|
||||
},
|
||||
},
|
||||
cnameProviderId: {
|
||||
title: "CNAME服务",
|
||||
title: t("certd.cname.cnameService"),
|
||||
type: "dict-select",
|
||||
dict: cnameProviderDict,
|
||||
form: {
|
||||
@@ -39,14 +41,14 @@ export function useCnameImport() {
|
||||
|
||||
return function openCnameImportDialog(req: { afterSubmit?: () => void }) {
|
||||
openFormDialog({
|
||||
title: "导入CNAME记录",
|
||||
title: t("certd.cname.importRecords"),
|
||||
columns: columns,
|
||||
onSubmit: async (form: any) => {
|
||||
await api.Import({
|
||||
domainList: form.domainList,
|
||||
cnameProviderId: form.cnameProviderId,
|
||||
});
|
||||
message.success("导入任务已提交");
|
||||
message.success(t("certd.cname.importTaskSubmitted"));
|
||||
if (req.afterSubmit) {
|
||||
req.afterSubmit();
|
||||
}
|
||||
|
||||
@@ -69,17 +69,17 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
const handleBatchDelete = () => {
|
||||
if (selectedRowKeys.value?.length > 0) {
|
||||
Modal.confirm({
|
||||
title: "确认",
|
||||
content: `确定要批量删除这${selectedRowKeys.value.length}条记录吗`,
|
||||
title: t("monitor.confirmTitle"),
|
||||
content: t("monitor.batchDeleteConfirm", { count: selectedRowKeys.value.length }),
|
||||
async onOk() {
|
||||
await api.BatchDelObj(selectedRowKeys.value);
|
||||
message.info("删除成功");
|
||||
message.info(t("monitor.deleteSuccess"));
|
||||
crudExpose.doRefresh();
|
||||
selectedRowKeys.value = [];
|
||||
},
|
||||
});
|
||||
} else {
|
||||
message.error("请先勾选记录");
|
||||
message.error(t("monitor.selectRecordsFirst"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -265,7 +265,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
type: "link",
|
||||
text: null,
|
||||
tooltip: {
|
||||
title: "立即检查",
|
||||
title: t("monitor.checkNow"),
|
||||
},
|
||||
icon: "ion:play-sharp",
|
||||
click: async ({ row }) => {
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
</template>
|
||||
<fs-crud ref="crudRef" v-bind="crudBinding">
|
||||
<template #pagination-left>
|
||||
<a-tooltip title="批量删除">
|
||||
<a-tooltip :title="t('monitor.batchDelete')">
|
||||
<fs-button icon="DeleteOutlined" @click="handleBatchDelete"></fs-button>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
|
||||
@@ -2,14 +2,16 @@ import { useFormWrapper } from "@fast-crud/fast-crud";
|
||||
|
||||
import SiteIpCertMonitor from "./index.vue";
|
||||
import { siteIpApi } from "/@/views/certd/monitor/site/ip/api";
|
||||
import { useI18n } from "/@/locales";
|
||||
|
||||
export function useSiteIpMonitor() {
|
||||
const { openDialog, openCrudFormDialog } = useFormWrapper();
|
||||
const { t } = useI18n();
|
||||
|
||||
async function openSiteIpMonitorDialog(opts: { siteId: number }) {
|
||||
await openDialog({
|
||||
wrapper: {
|
||||
title: "站点IP监控",
|
||||
title: t("monitor.siteIpMonitor"),
|
||||
width: "80%",
|
||||
is: "a-modal",
|
||||
footer: false,
|
||||
@@ -40,10 +42,10 @@ export function useSiteIpMonitor() {
|
||||
columns: {
|
||||
text: {
|
||||
type: "textarea",
|
||||
title: "IP列表",
|
||||
title: t("monitor.ipList"),
|
||||
form: {
|
||||
helper: "IP或者CNAME域名,一行一个",
|
||||
rules: [{ required: true, message: "请输入要导入的IP或域名" }],
|
||||
helper: t("monitor.ipListHelper"),
|
||||
rules: [{ required: true, message: t("monitor.enterImportIpOrDomain") }],
|
||||
component: {
|
||||
placeholder: "192.168.1.2\ncname.foo.com",
|
||||
rows: 8,
|
||||
|
||||
+12
-12
@@ -102,7 +102,9 @@ export class CertApplyGetFormAliyunPlugin extends CertApplyBasePlugin {
|
||||
if (!this.orderId) {
|
||||
throw new Error("请先输入证书实例 ID");
|
||||
}
|
||||
const certDetail = await this.getCertDetailV2(client, this.orderId);
|
||||
const certificateId = await this.getOrderDetailV2(client, this.orderId);
|
||||
this.logger.info(`获取到证书 ID:${certificateId}`);
|
||||
const certDetail = await this.getCertDetail(client, certificateId);
|
||||
this.logger.info(`获取到证书:${certDetail.getAllDomains()}, 过期时间:${dayjs(certDetail.expires).format("YYYY-MM-DD HH:mm:ss")}`);
|
||||
return certDetail;
|
||||
}
|
||||
@@ -133,9 +135,9 @@ export class CertApplyGetFormAliyunPlugin extends CertApplyBasePlugin {
|
||||
});
|
||||
}
|
||||
|
||||
async getCertDetailV2(client: any, instanceId: string) {
|
||||
const res = await client.doRequest({
|
||||
action: "GetUserCertificateDetail",
|
||||
async getOrderDetailV2(client: any, instanceId: string) {
|
||||
const instanceDetail = await client.doRequest({
|
||||
action: "GetInstanceDetail",
|
||||
version: "2020-04-07",
|
||||
protocol: "HTTPS",
|
||||
method: "POST",
|
||||
@@ -144,19 +146,17 @@ export class CertApplyGetFormAliyunPlugin extends CertApplyBasePlugin {
|
||||
pathname: `/`,
|
||||
data: {
|
||||
query: {
|
||||
CertId: instanceId,
|
||||
InstanceId: instanceId,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const crt = res.Cert;
|
||||
const key = res.Key;
|
||||
const certificateId = instanceDetail.CertificateId;
|
||||
if (!certificateId) {
|
||||
throw new Error(`未找到证书 ID,实例详情:${JSON.stringify(instanceDetail)}`);
|
||||
}
|
||||
|
||||
return new CertReader({
|
||||
crt,
|
||||
key,
|
||||
csr: "",
|
||||
});
|
||||
return certificateId;
|
||||
}
|
||||
|
||||
async getCertificateState(client: any, orderId: any): Promise<{ CertId: string; Type: string; Domain: string }> {
|
||||
|
||||
@@ -6,3 +6,4 @@ export * from './plugin-deploy-to-live.js'
|
||||
export * from './plugin-deploy-to-dcdn.js'
|
||||
export * from './plugin-deploy-to-vod.js'
|
||||
export * from './plugin-deploy-to-tos.js'
|
||||
export * from './plugin-deploy-to-vke.js'
|
||||
|
||||
+356
@@ -0,0 +1,356 @@
|
||||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
|
||||
import { createCertDomainGetterInputDefine, createRemoteSelectInputDefine } from "@certd/plugin-lib";
|
||||
import { CertApplyPluginNames, CertInfo } from "@certd/plugin-cert";
|
||||
import { VolcengineAccess } from "../access.js";
|
||||
import { VolcengineClient } from "../ve-client.js";
|
||||
import { utils } from "@certd/basic";
|
||||
|
||||
const regionOptions = [
|
||||
{ label: "北京", value: "cn-beijing" },
|
||||
{ label: "上海", value: "cn-shanghai" },
|
||||
{ label: "广州", value: "cn-guangzhou" },
|
||||
{ label: "香港", value: "cn-hongkong" },
|
||||
{ label: "柔佛", value: "ap-southeast-1" },
|
||||
{ label: "雅加达", value: "ap-southeast-3" }
|
||||
];
|
||||
|
||||
@IsTaskPlugin({
|
||||
name: "VolcengineDeployToVKE",
|
||||
title: "火山引擎-替换VKE证书",
|
||||
icon: "svg:icon-volcengine",
|
||||
group: pluginGroups.volcengine.key,
|
||||
desc: "替换火山引擎VKE集群中的TLS Secret证书",
|
||||
default: {
|
||||
strategy: {
|
||||
runStrategy: RunStrategy.SkipWhenSucceed
|
||||
}
|
||||
}
|
||||
})
|
||||
export class VolcengineDeployToVKE extends AbstractTaskPlugin {
|
||||
@TaskInput({
|
||||
title: "域名证书",
|
||||
helper: "请选择前置任务输出的域名证书",
|
||||
component: {
|
||||
name: "output-selector",
|
||||
from: [...CertApplyPluginNames]
|
||||
},
|
||||
required: true
|
||||
})
|
||||
cert!: CertInfo;
|
||||
|
||||
@TaskInput(createCertDomainGetterInputDefine({ props: { required: false } }))
|
||||
certDomains!: string[];
|
||||
|
||||
@TaskInput({
|
||||
title: "Access授权",
|
||||
helper: "火山引擎AccessKeyId、AccessKeySecret",
|
||||
component: {
|
||||
name: "access-selector",
|
||||
type: "volcengine"
|
||||
},
|
||||
required: true
|
||||
})
|
||||
accessId!: string;
|
||||
|
||||
@TaskInput({
|
||||
title: "Region",
|
||||
helper: "VKE集群所在地域",
|
||||
component: {
|
||||
name: "a-select",
|
||||
options: regionOptions
|
||||
},
|
||||
value: "cn-beijing",
|
||||
required: true
|
||||
})
|
||||
regionId!: string;
|
||||
|
||||
@TaskInput(
|
||||
createRemoteSelectInputDefine({
|
||||
title: "VKE集群",
|
||||
helper: "选择要替换证书的VKE集群,也可以手动输入集群ID",
|
||||
action: VolcengineDeployToVKE.prototype.onGetClusterList.name,
|
||||
watches: ["accessId", "regionId"],
|
||||
required: true
|
||||
})
|
||||
)
|
||||
clusterId!: string;
|
||||
|
||||
@TaskInput({
|
||||
title: "Kubeconfig类型",
|
||||
helper: "Public需要集群API Server已开启公网访问;Private需要Certd能访问集群私网地址",
|
||||
component: {
|
||||
name: "a-select",
|
||||
options: [
|
||||
{ label: "公网", value: "Public" },
|
||||
{ label: "私网", value: "Private" },
|
||||
{ label: "集群内", value: "TargetCluster" }
|
||||
]
|
||||
},
|
||||
value: "Public",
|
||||
required: true
|
||||
})
|
||||
kubeconfigType!: "Public" | "Private" | "TargetCluster";
|
||||
|
||||
@TaskInput({
|
||||
title: "命名空间",
|
||||
value: "default",
|
||||
component: {
|
||||
placeholder: "命名空间"
|
||||
},
|
||||
required: true
|
||||
})
|
||||
namespace!: string;
|
||||
|
||||
@TaskInput({
|
||||
title: "替换方式",
|
||||
helper: "按Ingress会自动读取spec.tls[].secretName;按Secret需要手动填写Secret名称",
|
||||
component: {
|
||||
name: "a-select",
|
||||
options: [
|
||||
{ label: "按Ingress替换", value: "ingress" },
|
||||
{ label: "按Secret替换", value: "secret" }
|
||||
]
|
||||
},
|
||||
value: "ingress",
|
||||
required: true
|
||||
})
|
||||
targetType!: "ingress" | "secret";
|
||||
|
||||
@TaskInput({
|
||||
title: "IngressName",
|
||||
required: true,
|
||||
helper: "根据Ingress名称查找TLS Secret并替换",
|
||||
mergeScript: `
|
||||
return {
|
||||
show: ctx.compute(({form}) => form.targetType === 'ingress'),
|
||||
required: ctx.compute(({form}) => form.targetType === 'ingress')
|
||||
}
|
||||
`
|
||||
})
|
||||
ingressName!: string;
|
||||
|
||||
@TaskInput({
|
||||
title: "Secret名称",
|
||||
required: true,
|
||||
helper: "存储TLS证书的Secret名称,可填写多个",
|
||||
component: {
|
||||
name: "a-select",
|
||||
vModel: "value",
|
||||
mode: "tags",
|
||||
open: false
|
||||
},
|
||||
mergeScript: `
|
||||
return {
|
||||
show: ctx.compute(({form}) => form.targetType === 'secret'),
|
||||
required: ctx.compute(({form}) => form.targetType === 'secret')
|
||||
}
|
||||
`
|
||||
})
|
||||
secretName!: string | string[];
|
||||
|
||||
@TaskInput({
|
||||
title: "Secret自动创建",
|
||||
helper: "如果Secret不存在,则创建kubernetes.io/tls类型Secret",
|
||||
value: false,
|
||||
component: {
|
||||
name: "a-switch",
|
||||
vModel: "checked"
|
||||
}
|
||||
})
|
||||
createOnNotFound!: boolean;
|
||||
|
||||
@TaskInput({
|
||||
title: "忽略证书校验",
|
||||
helper: "连接Kubernetes API Server时跳过TLS校验",
|
||||
value: false,
|
||||
component: {
|
||||
name: "a-switch",
|
||||
vModel: "checked"
|
||||
}
|
||||
})
|
||||
skipTLSVerify!: boolean;
|
||||
|
||||
K8sClient: any;
|
||||
|
||||
async onInstance() {
|
||||
const sdk = await import("@certd/lib-k8s");
|
||||
this.K8sClient = sdk.K8sClient;
|
||||
}
|
||||
|
||||
async execute(): Promise<void> {
|
||||
this.logger.info("开始替换火山引擎VKE证书");
|
||||
const access = await this.getAccess<VolcengineAccess>(this.accessId);
|
||||
const vkeService = await this.getVkeService(access);
|
||||
const kubeconfigId = await this.createKubeconfig(vkeService);
|
||||
|
||||
try {
|
||||
const kubeconfig = await this.getKubeconfig(vkeService, kubeconfigId);
|
||||
const k8sClient = new this.K8sClient({
|
||||
kubeConfigStr: kubeconfig,
|
||||
logger: this.logger,
|
||||
skipTLSVerify: this.skipTLSVerify
|
||||
});
|
||||
const secretNames = await this.getTargetSecretNames(k8sClient);
|
||||
await this.patchCertSecret({ cert: this.cert, k8sClient, secretNames });
|
||||
} catch (e) {
|
||||
if (e.response?.body) {
|
||||
throw new Error(JSON.stringify(e.response.body));
|
||||
}
|
||||
throw e;
|
||||
} finally {
|
||||
await this.deleteKubeconfig(vkeService, kubeconfigId);
|
||||
}
|
||||
|
||||
await utils.sleep(5000);
|
||||
this.logger.info("VKE证书替换完成");
|
||||
}
|
||||
|
||||
private async getVkeService(access: VolcengineAccess) {
|
||||
const client = new VolcengineClient({
|
||||
logger: this.logger,
|
||||
access,
|
||||
http: this.http
|
||||
});
|
||||
return await client.getVkeService({ region: this.regionId });
|
||||
}
|
||||
|
||||
private async createKubeconfig(vkeService: any) {
|
||||
const res = await vkeService.request({
|
||||
action: "CreateKubeconfig",
|
||||
method: "POST",
|
||||
body: {
|
||||
ClusterId: this.clusterId,
|
||||
Type: this.kubeconfigType,
|
||||
ValidDuration: 3600
|
||||
}
|
||||
});
|
||||
const kubeconfigId = res.Result?.Id || res.Id;
|
||||
if (!kubeconfigId) {
|
||||
throw new Error(`生成VKE Kubeconfig失败:${JSON.stringify(res)}`);
|
||||
}
|
||||
this.logger.info(`已生成临时Kubeconfig:${kubeconfigId}`);
|
||||
return kubeconfigId;
|
||||
}
|
||||
|
||||
private async getKubeconfig(vkeService: any, kubeconfigId: string) {
|
||||
const res = await vkeService.request({
|
||||
action: "ListKubeconfigs",
|
||||
method: "POST",
|
||||
body: {
|
||||
Filter: {
|
||||
ClusterIds: [this.clusterId],
|
||||
Ids: [kubeconfigId],
|
||||
Types: [this.kubeconfigType]
|
||||
},
|
||||
PageNumber: 1,
|
||||
PageSize: 10
|
||||
}
|
||||
});
|
||||
const items = res.Result?.Items || res.Items || [];
|
||||
const item = items.find((it: any) => it.Id === kubeconfigId) || items[0];
|
||||
const kubeconfig = item?.Kubeconfig;
|
||||
if (!kubeconfig) {
|
||||
throw new Error(`获取VKE Kubeconfig失败:${JSON.stringify(res)}`);
|
||||
}
|
||||
return kubeconfig;
|
||||
}
|
||||
|
||||
private async deleteKubeconfig(vkeService: any, kubeconfigId?: string) {
|
||||
if (!kubeconfigId) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await vkeService.request({
|
||||
action: "DeleteKubeconfigs",
|
||||
method: "POST",
|
||||
body: {
|
||||
ClusterId: this.clusterId,
|
||||
Ids: [kubeconfigId]
|
||||
}
|
||||
});
|
||||
this.logger.info(`已删除临时Kubeconfig:${kubeconfigId}`);
|
||||
} catch (e) {
|
||||
this.logger.warn(`删除临时Kubeconfig失败:${e.message || e}`);
|
||||
}
|
||||
}
|
||||
|
||||
private async getTargetSecretNames(k8sClient: any) {
|
||||
if (this.targetType === "secret") {
|
||||
if (typeof this.secretName === "string") {
|
||||
return [this.secretName];
|
||||
}
|
||||
return this.secretName || [];
|
||||
}
|
||||
|
||||
const ingressList = await k8sClient.getIngressList({
|
||||
namespace: this.namespace
|
||||
});
|
||||
const ingress = ingressList.items.find((item: any) => item.metadata.name === this.ingressName);
|
||||
if (!ingress) {
|
||||
throw new Error(`Ingress不存在:${this.ingressName}`);
|
||||
}
|
||||
const secretNames = ingress.spec?.tls?.map((tls: any) => tls.secretName).filter(Boolean) || [];
|
||||
if (secretNames.length === 0) {
|
||||
throw new Error(`Ingress:${this.ingressName} 未找到TLS Secret`);
|
||||
}
|
||||
return secretNames;
|
||||
}
|
||||
|
||||
private async patchCertSecret(options: { cert: CertInfo; k8sClient: any; secretNames: string[] }) {
|
||||
const { cert, k8sClient, secretNames } = options;
|
||||
if (!secretNames || secretNames.length === 0) {
|
||||
throw new Error("Secret名称不能为空");
|
||||
}
|
||||
|
||||
const body: any = {
|
||||
data: {
|
||||
"tls.crt": Buffer.from(cert.crt).toString("base64"),
|
||||
"tls.key": Buffer.from(cert.key).toString("base64")
|
||||
},
|
||||
metadata: {
|
||||
labels: {
|
||||
certd: this.appendTimeSuffix("certd")
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for (const secretName of secretNames) {
|
||||
body.metadata.name = secretName;
|
||||
this.logger.info(`开始更新VKE Secret:${secretName}`);
|
||||
await k8sClient.patchSecret({
|
||||
namespace: this.namespace,
|
||||
secretName,
|
||||
body,
|
||||
createOnNotFound: this.createOnNotFound
|
||||
});
|
||||
this.logger.info(`VKE Secret已更新:${secretName}`);
|
||||
}
|
||||
|
||||
if (this.targetType === "ingress" && this.ingressName) {
|
||||
await k8sClient.restartIngress(this.namespace, [this.ingressName], { certd: this.appendTimeSuffix("certd") });
|
||||
}
|
||||
}
|
||||
|
||||
async onGetClusterList() {
|
||||
if (!this.accessId) {
|
||||
throw new Error("请选择Access授权");
|
||||
}
|
||||
const access = await this.getAccess<VolcengineAccess>(this.accessId);
|
||||
const service = await this.getVkeService(access);
|
||||
const res = await service.request({
|
||||
action: "ListClusters",
|
||||
method: "POST",
|
||||
body: {
|
||||
PageNumber: 1,
|
||||
PageSize: 100
|
||||
}
|
||||
});
|
||||
const list = res.Result?.Items || res.Items || [];
|
||||
return list.map((item: any) => ({
|
||||
label: `${item.Name || item.Id}<${item.Id}>`,
|
||||
value: item.Id
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
new VolcengineDeployToVKE();
|
||||
@@ -112,6 +112,20 @@ export class VolcengineClient {
|
||||
return service;
|
||||
}
|
||||
|
||||
async getVkeService(opts: { region?: string }) {
|
||||
const CommonService = await this.getServiceCls();
|
||||
|
||||
const service = new CommonService({
|
||||
serviceName: "vke",
|
||||
defaultVersion: "2022-05-12"
|
||||
});
|
||||
service.setAccessKeyId(this.opts.access.accessKeyId);
|
||||
service.setSecretKey(this.opts.access.secretAccessKey);
|
||||
service.setRegion(opts.region);
|
||||
|
||||
return service;
|
||||
}
|
||||
|
||||
async getDCDNService( opts?: { }) {
|
||||
const CommonService = await this.getServiceCls();
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
13:33
|
||||
23:11
|
||||
|
||||
@@ -1 +1 @@
|
||||
14:09
|
||||
23:28
|
||||
|
||||
Reference in New Issue
Block a user