mirror of
https://github.com/certd/certd.git
synced 2026-04-10 02:10:59 +08:00
Compare commits
51 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5c251ee774 | ||
|
|
ddda691552 | ||
|
|
ba73090d53 | ||
|
|
a080b606ab | ||
|
|
7c0f43c8a3 | ||
|
|
4fad1aee6b | ||
|
|
19aec5bc8d | ||
|
|
33ee60736c | ||
|
|
c1bccb970f | ||
|
|
481cc029fa | ||
|
|
bdaf58a3c4 | ||
|
|
0f64671dc0 | ||
|
|
60f055f293 | ||
|
|
c67a9215e3 | ||
|
|
a0e9df6d6d | ||
|
|
8341749c04 | ||
|
|
66d1886663 | ||
|
|
710e1fc278 | ||
|
|
4cf98584da | ||
|
|
3fb3cee423 | ||
|
|
2d1504a057 | ||
|
|
4fcfd089d8 | ||
|
|
04422a4637 | ||
|
|
37e6548246 | ||
|
|
a761989f3e | ||
|
|
acaa8b1731 | ||
|
|
082f47663d | ||
|
|
92f42154d5 | ||
|
|
fc1084ce33 | ||
|
|
adc3ab7e0a | ||
|
|
dcc8c56969 | ||
|
|
0b3472d227 | ||
|
|
b50121ad0b | ||
|
|
dfddfc3e06 | ||
|
|
34ec6210c6 | ||
|
|
daaef316e9 | ||
|
|
cdac12bb2f | ||
|
|
3ab99647aa | ||
|
|
529482a83e | ||
|
|
29906ec057 | ||
|
|
9296ba7492 | ||
|
|
821c6d807d | ||
|
|
991b741cbe | ||
|
|
2559f0e822 | ||
|
|
8bb1ed3e95 | ||
|
|
56ba3fcb92 | ||
|
|
e99a20a120 | ||
|
|
f1a25b21a6 | ||
|
|
cf9595ce58 | ||
|
|
2b3b75a4a5 | ||
|
|
26b395110c |
21
CHANGELOG.md
21
CHANGELOG.md
@@ -3,6 +3,27 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.36.0](https://github.com/certd/certd/compare/v1.35.5...v1.36.0) (2025-07-01)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 支持自定义证书生成插件 ([481cc02](https://github.com/certd/certd/commit/481cc029fafaf280aa844cd3ca30f4653ec35d55))
|
||||
|
||||
### Features
|
||||
|
||||
* 支持模版创建流水线 ([2559f0e](https://github.com/certd/certd/commit/2559f0e822db095d1d26a7f1d517622dce22a5c2))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 阿里云waf cname站点选择支持翻页及域名查询 ([4cf9858](https://github.com/certd/certd/commit/4cf98584dacc5999752732f136246647a2f1f07d))
|
||||
* 部署到ssh主机命令支持前置命令 ([991b741](https://github.com/certd/certd/commit/991b741cbe223b342f534157da63b71e81661f8e))
|
||||
* 模版导入流水线 ([dcc8c56](https://github.com/certd/certd/commit/dcc8c569693432579709ce63656665a76bcf9a44))
|
||||
* 添加用户资料编辑功能 ([7c0f43c](https://github.com/certd/certd/commit/7c0f43c8a3052f73afee3e93c9fcbc43c44ab690))
|
||||
* 优化阿里云waf的日志信息 ([821c6d8](https://github.com/certd/certd/commit/821c6d807d4b3cc5092d09a6282b8cbafb9e7c9f))
|
||||
* 优化中英文翻译与切换 ([acaa8b1](https://github.com/certd/certd/commit/acaa8b173183b4423584ee070e6e332e0ac0eb2d))
|
||||
* 站点IP监控前先同步一下IP ([a080b60](https://github.com/certd/certd/commit/a080b606ab6e289d96b17ef7d2879b4603f889ba))
|
||||
* 支持选择运行策略设置 ([60f055f](https://github.com/certd/certd/commit/60f055f293ce237c21cd9050333dad9609eceac1))
|
||||
|
||||
## [1.35.5](https://github.com/certd/certd/compare/v1.35.4...v1.35.5) (2025-06-20)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
44
README.md
44
README.md
@@ -1,9 +1,10 @@
|
||||
# Certd
|
||||
|
||||
Certd® 是一个免费的全自动证书管理系统,让你的网站证书永不过期。
|
||||
首创流水线申请部署证书模式,已被多个项目“借鉴”,被抄也是一种成功。
|
||||
Certd® 是一个免费的全自动证书管理系统,让你的网站证书永不过期。
|
||||
后缀d取自linux守护进程的命名风格,意为证书守护进程
|
||||
|
||||
|
||||
>后缀d取自linux守护进程的命名风格,意为证书守护进程。
|
||||
>首创流水线申请部署证书模式,已被多个项目“借鉴”,被抄也是一种成功。
|
||||
|
||||
> 关于证书续期:
|
||||
>* 实际上没有办法不改变证书文件本身情况下直接续期或者续签。
|
||||
@@ -21,13 +22,14 @@ Certd® 是一个免费的全自动证书管理系统,让你的网站证书永
|
||||
* 全自动部署更新证书(目前支持部署到主机、阿里云、腾讯云等70+部署插件)
|
||||
* 支持通配符域名/泛域名,支持多个域名打到一个证书上,支持pem、pfx、der、jks等多种证书格式
|
||||
* 邮件通知、webhook通知、企微、钉钉、飞书、anpush等多种通知方式
|
||||
* 私有化部署,数据保存本地,安装升级非常简单快捷
|
||||
* 镜像由Github Actions构建,过程公开透明
|
||||
* 私有化部署,数据保存本地,安装简单快捷,镜像由Github Actions构建,过程公开透明
|
||||
* 授权加密,站点隐藏,2FA,密码防爆破等多重安全保障
|
||||
* 支持SQLite,PostgreSQL、MySQL多种数据库
|
||||
* 开放接口支持
|
||||
* 站点证书监控
|
||||
* 多用户管理
|
||||
* 多语言支持(中英双语切换)
|
||||
* 各版本向下兼容,一键无忧升级
|
||||
|
||||
|
||||

|
||||
@@ -80,10 +82,12 @@ https://certd.handfree.work/
|
||||
|
||||
您可以根据实际情况从如下方式中选择一种方式进行私有化部署:
|
||||
|
||||
1. [宝塔面板方式部署 推荐](https://certd.docmirror.cn/guide/install/docker/)
|
||||
2. [1Panel面板方式部署 推荐](https://certd.docmirror.cn/guide/install/1panel/)
|
||||
3. [Docker方式部署 推荐](https://certd.docmirror.cn/guide/install/docker/)
|
||||
4. [源码方式部署 不建议](https://certd.docmirror.cn/guide/install/source/)
|
||||
1. 【推荐】[Docker方式部署 ](https://certd.docmirror.cn/guide/install/docker/)
|
||||
2. 【推荐】[宝塔面板方式部署 ](https://certd.docmirror.cn/guide/install/docker/)
|
||||
3. 【推荐】[1Panel面板方式部署](https://certd.docmirror.cn/guide/install/1panel/)
|
||||
4. 【推荐】[雨云一键部署](https://app.rainyun.com/apps/rca/store/6646/?ref=NzExMDQ2_) : 首充翻倍,每月仅需2.2元
|
||||
[<img src="https://rainyun-apps.cn-nb1.rains3.com/materials/deploy-on-rainyun-cn.svg">](https://app.rainyun.com/apps/rca/store/6646/?ref=NzExMDQ2_)
|
||||
5. 【不推荐】[源码方式部署 ](https://certd.docmirror.cn/guide/install/source/)
|
||||
|
||||
#### Docker镜像说明:
|
||||
* 国内镜像地址:
|
||||
@@ -111,7 +115,17 @@ https://certd.handfree.work/
|
||||
> * [更多安全生产建议点我](https://certd.docmirror.cn/guide/feature/safe/)
|
||||
|
||||
|
||||
## 五、更多帮助
|
||||
## 五、生态
|
||||
|
||||
### 1. 客户端工具 SSL-Assistant
|
||||
`SSL Assistant` 是一个运行于主机上的证书部署管理助手客户端。
|
||||
支持自动扫描主机`Nginx`配置,然后从`Certd`拉取证书并部署。
|
||||
在不想暴露ssh主机密码情况下,该工具非常好用。
|
||||
|
||||
开源地址: https://github.com/Youngxj/SSL-Assistant
|
||||
|
||||
|
||||
## 六、更多帮助
|
||||
请访问官方文档:[https://certd.docmirror.cn/](https://certd.docmirror.cn/guide/)
|
||||
|
||||
* 升级方法:[升级方法](https://certd.docmirror.cn/guide/install/upgrade/)
|
||||
@@ -121,7 +135,7 @@ https://certd.handfree.work/
|
||||
* 更新日志:[CHANGELOG](./CHANGELOG.md)
|
||||
|
||||
|
||||
## 六、联系作者
|
||||
## 七、联系作者
|
||||
如有疑问,欢迎加入群聊(请备注certd)
|
||||
|
||||
| 加群 | 微信群 | QQ群 |
|
||||
@@ -135,7 +149,7 @@ https://certd.handfree.work/
|
||||
| 二维码 | <img height="230" src="./docs/guide/contact/images/me.png"> |
|
||||
|
||||
|
||||
## 七、捐赠
|
||||
## 八、捐赠
|
||||
************************
|
||||
支持开源,为爱发电,我已入驻爱发电
|
||||
https://afdian.com/a/greper
|
||||
@@ -159,7 +173,7 @@ https://afdian.com/a/greper
|
||||
|
||||
************************
|
||||
|
||||
## 八、贡献代码
|
||||
## 九、贡献代码
|
||||
|
||||
1. 本地开发请参考 [贡献插件向导](https://certd.docmirror.cn/guide/development/)
|
||||
2. 作为贡献者,代表您同意您贡献的代码如下许可:
|
||||
@@ -172,14 +186,14 @@ https://afdian.com/a/greper
|
||||
<img src="https://contrib.rocks/image?repo=certd/certd" />
|
||||
</a>
|
||||
|
||||
## 九、 开源许可
|
||||
## 十、 开源许可
|
||||
* 本项目遵循 GNU Affero General Public License(AGPL)开源协议。
|
||||
* 允许个人和公司内部自由使用、复制、修改和分发本项目,未获得商业授权情况下禁止任何形式的商业用途
|
||||
* 未获得商业授权情况下,禁止任何对logo、版权信息及授权许可相关代码的修改。
|
||||
* 如需商业授权,请联系作者。
|
||||
|
||||
|
||||
## 十、我的其他项目(求Star)
|
||||
## 十一、我的其他项目(求Star)
|
||||
|
||||
| 项目名称 | stars | 项目描述 |
|
||||
|---------------------------------------------------------|-------------------------------------------------------------------------------------------------------|-----------------------------------|
|
||||
|
||||
@@ -1 +1 @@
|
||||
12:23
|
||||
17:16
|
||||
|
||||
@@ -3,6 +3,18 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.35.5](https://github.com/certd/certd/compare/v1.35.4...v1.35.5) (2025-06-20)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 腾讯云授权支持设置是否国际站,部署到EO插件支持国际站 ([5cd3968](https://github.com/certd/certd/commit/5cd3968929acef333cf30d3b20cf21cea6c82c5f))
|
||||
* 修复邮箱包含.号校验失败的bug ([65dcae7](https://github.com/certd/certd/commit/65dcae79f8faa7a6cb425e10a0fdb6758b0719f3))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 首次打开任务日志查看页面,自动滚动到底部 ([43fee42](https://github.com/certd/certd/commit/43fee42198e8697185b427b1fa3eb79409603393))
|
||||
* 支持批量修改通知和定时 ([e11b3be](https://github.com/certd/certd/commit/e11b3becfd4abe6547e84d09adc38ebd6e1c4b87))
|
||||
|
||||
## [1.35.4](https://github.com/certd/certd/compare/v1.35.3...v1.35.4) (2025-06-13)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
@@ -18,4 +18,13 @@ header中传入x-certd-token即可调用开放接口
|
||||
4、然后将content和sign分别base64后用.号连接: x-certd-token = base64(content) +"."+base64(sign)
|
||||
|
||||
## SDK
|
||||
待开发
|
||||
待开发
|
||||
|
||||
## 客户端工具
|
||||
|
||||
### SSL-Assistant
|
||||
`SSL Assistant` 是一个基于 Go 语言开发的跨平台证书部署管理助手。
|
||||
支持自动扫描主机`Nginx`配置,然后从Certd拉取证书并部署。
|
||||
在不想暴露ssh主机密码情况下,该工具非常好用。
|
||||
|
||||
开源地址: https://github.com/Youngxj/SSL-Assistant
|
||||
@@ -9,5 +9,5 @@
|
||||
}
|
||||
},
|
||||
"npmClient": "pnpm",
|
||||
"version": "1.35.5"
|
||||
"version": "1.36.0"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.36.0](https://github.com/publishlab/node-acme-client/compare/v1.35.5...v1.36.0) (2025-07-01)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.35.5](https://github.com/publishlab/node-acme-client/compare/v1.35.4...v1.35.5) (2025-06-20)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"description": "Simple and unopinionated ACME client",
|
||||
"private": false,
|
||||
"author": "nmorsman",
|
||||
"version": "1.35.5",
|
||||
"version": "1.36.0",
|
||||
"type": "module",
|
||||
"module": "scr/index.js",
|
||||
"main": "src/index.js",
|
||||
@@ -18,7 +18,7 @@
|
||||
"types"
|
||||
],
|
||||
"dependencies": {
|
||||
"@certd/basic": "^1.35.5",
|
||||
"@certd/basic": "^1.36.0",
|
||||
"@peculiar/x509": "^1.11.0",
|
||||
"asn1js": "^3.0.5",
|
||||
"axios": "^1.7.2",
|
||||
@@ -69,5 +69,5 @@
|
||||
"bugs": {
|
||||
"url": "https://github.com/publishlab/node-acme-client/issues"
|
||||
},
|
||||
"gitHead": "93017c044d4533ce40a2aab525f10b82761d09d0"
|
||||
"gitHead": "7feece597a0d323c929b315f99750f1832b7a063"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.36.0](https://github.com/certd/certd/compare/v1.35.5...v1.36.0) (2025-07-01)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
## [1.35.5](https://github.com/certd/certd/compare/v1.35.4...v1.35.5) (2025-06-20)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
@@ -1 +1 @@
|
||||
17:10
|
||||
23:22
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/basic",
|
||||
"private": false,
|
||||
"version": "1.35.5",
|
||||
"version": "1.36.0",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -45,5 +45,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "93017c044d4533ce40a2aab525f10b82761d09d0"
|
||||
"gitHead": "7feece597a0d323c929b315f99750f1832b7a063"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,13 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.36.0](https://github.com/certd/certd/compare/v1.35.5...v1.36.0) (2025-07-01)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 阿里云waf cname站点选择支持翻页及域名查询 ([4cf9858](https://github.com/certd/certd/commit/4cf98584dacc5999752732f136246647a2f1f07d))
|
||||
* 支持选择运行策略设置 ([60f055f](https://github.com/certd/certd/commit/60f055f293ce237c21cd9050333dad9609eceac1))
|
||||
|
||||
## [1.35.5](https://github.com/certd/certd/compare/v1.35.4...v1.35.5) (2025-06-20)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/pipeline",
|
||||
"private": false,
|
||||
"version": "1.35.5",
|
||||
"version": "1.36.0",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -17,8 +17,8 @@
|
||||
"pub": "npm publish"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/basic": "^1.35.5",
|
||||
"@certd/plus-core": "^1.35.5",
|
||||
"@certd/basic": "^1.36.0",
|
||||
"@certd/plus-core": "^1.36.0",
|
||||
"dayjs": "^1.11.7",
|
||||
"lodash-es": "^4.17.21",
|
||||
"reflect-metadata": "^0.1.13"
|
||||
@@ -44,5 +44,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "93017c044d4533ce40a2aab525f10b82761d09d0"
|
||||
"gitHead": "7feece597a0d323c929b315f99750f1832b7a063"
|
||||
}
|
||||
|
||||
@@ -3,17 +3,35 @@ import { IContext } from "../core/index.js";
|
||||
export type UserContext = IContext;
|
||||
export type PipelineContext = IContext;
|
||||
|
||||
export type PageReq = {
|
||||
offset?: number;
|
||||
limit?: number;
|
||||
export type PageSearch = {
|
||||
pageNo?: number;
|
||||
pageSize?: number;
|
||||
searchKey?: string;
|
||||
// sortBy?: string;
|
||||
// sortOrder?: "asc" | "desc";
|
||||
};
|
||||
|
||||
|
||||
export type PageRes = {
|
||||
offset?: number;
|
||||
limit?: number;
|
||||
pageNo?: number;
|
||||
pageSize?: number;
|
||||
total?: string;
|
||||
list: any[];
|
||||
};
|
||||
|
||||
export class Pager {
|
||||
pageNo: number;
|
||||
pageSize: number;
|
||||
constructor(req: PageSearch) {
|
||||
this.pageNo = req.pageNo ?? 1;
|
||||
this.pageSize = req.pageSize || 50;
|
||||
}
|
||||
|
||||
getOffset() {
|
||||
return (this.pageNo - 1) * (this.pageSize ?? 50);
|
||||
}
|
||||
|
||||
setOffset(offset: number) {
|
||||
this.pageNo = Math.ceil(offset / (this.pageSize ?? 50)) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.36.0](https://github.com/certd/certd/compare/v1.35.5...v1.36.0) (2025-07-01)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.35.5](https://github.com/certd/certd/compare/v1.35.4...v1.35.5) (2025-06-20)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-huawei",
|
||||
"private": false,
|
||||
"version": "1.35.5",
|
||||
"version": "1.36.0",
|
||||
"main": "./dist/bundle.js",
|
||||
"module": "./dist/bundle.js",
|
||||
"types": "./dist/d/index.d.ts",
|
||||
@@ -24,5 +24,5 @@
|
||||
"prettier": "^2.8.8",
|
||||
"tslib": "^2.8.1"
|
||||
},
|
||||
"gitHead": "93017c044d4533ce40a2aab525f10b82761d09d0"
|
||||
"gitHead": "7feece597a0d323c929b315f99750f1832b7a063"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.36.0](https://github.com/certd/certd/compare/v1.35.5...v1.36.0) (2025-07-01)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.35.5](https://github.com/certd/certd/compare/v1.35.4...v1.35.5) (2025-06-20)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-iframe",
|
||||
"private": false,
|
||||
"version": "1.35.5",
|
||||
"version": "1.36.0",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -31,5 +31,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "93017c044d4533ce40a2aab525f10b82761d09d0"
|
||||
"gitHead": "7feece597a0d323c929b315f99750f1832b7a063"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.36.0](https://github.com/certd/certd/compare/v1.35.5...v1.36.0) (2025-07-01)
|
||||
|
||||
**Note:** Version bump only for package @certd/jdcloud
|
||||
|
||||
## [1.35.5](https://github.com/certd/certd/compare/v1.35.4...v1.35.5) (2025-06-20)
|
||||
|
||||
**Note:** Version bump only for package @certd/jdcloud
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/jdcloud",
|
||||
"version": "1.35.5",
|
||||
"version": "1.36.0",
|
||||
"description": "jdcloud openApi sdk",
|
||||
"main": "./dist/bundle.js",
|
||||
"module": "./dist/bundle.js",
|
||||
@@ -61,5 +61,5 @@
|
||||
"fetch"
|
||||
]
|
||||
},
|
||||
"gitHead": "93017c044d4533ce40a2aab525f10b82761d09d0"
|
||||
"gitHead": "7feece597a0d323c929b315f99750f1832b7a063"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.36.0](https://github.com/certd/certd/compare/v1.35.5...v1.36.0) (2025-07-01)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
## [1.35.5](https://github.com/certd/certd/compare/v1.35.4...v1.35.5) (2025-06-20)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-k8s",
|
||||
"private": false,
|
||||
"version": "1.35.5",
|
||||
"version": "1.36.0",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -17,7 +17,7 @@
|
||||
"pub": "npm publish"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/basic": "^1.35.5",
|
||||
"@certd/basic": "^1.36.0",
|
||||
"@kubernetes/client-node": "0.21.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -32,5 +32,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "93017c044d4533ce40a2aab525f10b82761d09d0"
|
||||
"gitHead": "7feece597a0d323c929b315f99750f1832b7a063"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.36.0](https://github.com/certd/certd/compare/v1.35.5...v1.36.0) (2025-07-01)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-server
|
||||
|
||||
## [1.35.5](https://github.com/certd/certd/compare/v1.35.4...v1.35.5) (2025-06-20)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/lib-server",
|
||||
"version": "1.35.5",
|
||||
"version": "1.36.0",
|
||||
"description": "midway with flyway, sql upgrade way ",
|
||||
"private": false,
|
||||
"type": "module",
|
||||
@@ -27,10 +27,10 @@
|
||||
],
|
||||
"license": "AGPL",
|
||||
"dependencies": {
|
||||
"@certd/acme-client": "^1.35.5",
|
||||
"@certd/basic": "^1.35.5",
|
||||
"@certd/pipeline": "^1.35.5",
|
||||
"@certd/plus-core": "^1.35.5",
|
||||
"@certd/acme-client": "^1.36.0",
|
||||
"@certd/basic": "^1.36.0",
|
||||
"@certd/pipeline": "^1.36.0",
|
||||
"@certd/plus-core": "^1.36.0",
|
||||
"@midwayjs/cache": "~3.14.0",
|
||||
"@midwayjs/core": "~3.20.3",
|
||||
"@midwayjs/i18n": "~3.20.3",
|
||||
@@ -61,5 +61,5 @@
|
||||
"typeorm": "^0.3.11",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "93017c044d4533ce40a2aab525f10b82761d09d0"
|
||||
"gitHead": "7feece597a0d323c929b315f99750f1832b7a063"
|
||||
}
|
||||
|
||||
@@ -84,6 +84,7 @@ export abstract class BaseService<T> {
|
||||
...where,
|
||||
});
|
||||
await this.modifyAfter(idArr);
|
||||
return ids
|
||||
}
|
||||
|
||||
resolveIdArr(ids: string | any[]) {
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.36.0](https://github.com/certd/certd/compare/v1.35.5...v1.36.0) (2025-07-01)
|
||||
|
||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||
|
||||
## [1.35.5](https://github.com/certd/certd/compare/v1.35.4...v1.35.5) (2025-06-20)
|
||||
|
||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/midway-flyway-js",
|
||||
"version": "1.35.5",
|
||||
"version": "1.36.0",
|
||||
"description": "midway with flyway, sql upgrade way ",
|
||||
"private": false,
|
||||
"type": "module",
|
||||
@@ -46,5 +46,5 @@
|
||||
"typeorm": "^0.3.11",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "93017c044d4533ce40a2aab525f10b82761d09d0"
|
||||
"gitHead": "7feece597a0d323c929b315f99750f1832b7a063"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.36.0](https://github.com/certd/certd/compare/v1.35.5...v1.36.0) (2025-07-01)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 模版导入流水线 ([dcc8c56](https://github.com/certd/certd/commit/dcc8c569693432579709ce63656665a76bcf9a44))
|
||||
|
||||
## [1.35.5](https://github.com/certd/certd/compare/v1.35.4...v1.35.5) (2025-06-20)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-cert
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/plugin-cert",
|
||||
"private": false,
|
||||
"version": "1.35.5",
|
||||
"version": "1.36.0",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -16,10 +16,10 @@
|
||||
"pub": "npm publish"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/acme-client": "^1.35.5",
|
||||
"@certd/basic": "^1.35.5",
|
||||
"@certd/pipeline": "^1.35.5",
|
||||
"@certd/plugin-lib": "^1.35.5",
|
||||
"@certd/acme-client": "^1.36.0",
|
||||
"@certd/basic": "^1.36.0",
|
||||
"@certd/pipeline": "^1.36.0",
|
||||
"@certd/plugin-lib": "^1.36.0",
|
||||
"@google-cloud/publicca": "^1.3.0",
|
||||
"dayjs": "^1.11.7",
|
||||
"jszip": "^3.10.1",
|
||||
@@ -43,5 +43,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "93017c044d4533ce40a2aab525f10b82761d09d0"
|
||||
"gitHead": "7feece597a0d323c929b315f99750f1832b7a063"
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ export const EVENT_CERT_APPLY_SUCCESS = "CertApply.success";
|
||||
|
||||
export abstract class CertApplyBaseConvertPlugin extends AbstractTaskPlugin {
|
||||
@TaskInput({
|
||||
title: "域名",
|
||||
title: "证书域名",
|
||||
component: {
|
||||
name: "a-select",
|
||||
vModel: "value",
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.36.0](https://github.com/certd/certd/compare/v1.35.5...v1.36.0) (2025-07-01)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-lib
|
||||
|
||||
## [1.35.5](https://github.com/certd/certd/compare/v1.35.4...v1.35.5) (2025-06-20)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/plugin-lib",
|
||||
"private": false,
|
||||
"version": "1.35.5",
|
||||
"version": "1.36.0",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -21,8 +21,8 @@
|
||||
"@alicloud/pop-core": "^1.7.10",
|
||||
"@alicloud/tea-util": "^1.4.10",
|
||||
"@aws-sdk/client-s3": "^3.787.0",
|
||||
"@certd/basic": "^1.35.5",
|
||||
"@certd/pipeline": "^1.35.5",
|
||||
"@certd/basic": "^1.36.0",
|
||||
"@certd/pipeline": "^1.36.0",
|
||||
"@kubernetes/client-node": "0.21.0",
|
||||
"ali-oss": "^6.22.0",
|
||||
"basic-ftp": "^5.0.5",
|
||||
@@ -53,5 +53,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "93017c044d4533ce40a2aab525f10b82761d09d0"
|
||||
"gitHead": "7feece597a0d323c929b315f99750f1832b7a063"
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ export function createCertDomainGetterInputDefine(opts?: { certInputKey?: string
|
||||
}
|
||||
}
|
||||
`,
|
||||
template:false,
|
||||
required: true,
|
||||
},
|
||||
opts?.props
|
||||
|
||||
@@ -41,7 +41,7 @@ export class TencentAccess extends BaseAccess {
|
||||
},
|
||||
],
|
||||
},
|
||||
encrypt: true,
|
||||
encrypt: false,
|
||||
rules: [{ required: true, message: "该项必填" }],
|
||||
})
|
||||
accountType: string;
|
||||
|
||||
@@ -3,6 +3,22 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.36.0](https://github.com/certd/certd/compare/v1.35.5...v1.36.0) (2025-07-01)
|
||||
|
||||
### Features
|
||||
|
||||
* 支持模版创建流水线 ([2559f0e](https://github.com/certd/certd/commit/2559f0e822db095d1d26a7f1d517622dce22a5c2))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 阿里云waf cname站点选择支持翻页及域名查询 ([4cf9858](https://github.com/certd/certd/commit/4cf98584dacc5999752732f136246647a2f1f07d))
|
||||
* 模版导入流水线 ([dcc8c56](https://github.com/certd/certd/commit/dcc8c569693432579709ce63656665a76bcf9a44))
|
||||
* 添加用户资料编辑功能 ([7c0f43c](https://github.com/certd/certd/commit/7c0f43c8a3052f73afee3e93c9fcbc43c44ab690))
|
||||
* 优化阿里云waf的日志信息 ([821c6d8](https://github.com/certd/certd/commit/821c6d807d4b3cc5092d09a6282b8cbafb9e7c9f))
|
||||
* 优化中英文翻译与切换 ([acaa8b1](https://github.com/certd/certd/commit/acaa8b173183b4423584ee070e6e332e0ac0eb2d))
|
||||
* 站点IP监控前先同步一下IP ([a080b60](https://github.com/certd/certd/commit/a080b606ab6e289d96b17ef7d2879b4603f889ba))
|
||||
* 支持选择运行策略设置 ([60f055f](https://github.com/certd/certd/commit/60f055f293ce237c21cd9050333dad9609eceac1))
|
||||
|
||||
## [1.35.5](https://github.com/certd/certd/compare/v1.35.4...v1.35.5) (2025-06-20)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/ui-client",
|
||||
"version": "1.35.5",
|
||||
"version": "1.36.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite --open",
|
||||
@@ -15,7 +15,8 @@
|
||||
"serve": "vite preview",
|
||||
"preview": "vite preview",
|
||||
"pretty-quick": "pretty-quick",
|
||||
"lint-fix": "eslint --fix --ext .js --ext .jsx --ext .vue src/",
|
||||
"lint-fix": "eslint --fix --ext .js --ext .jsx --ext .vue --ext .ts --ext .tsx src/",
|
||||
"format": "prettier --write src",
|
||||
"upgrade": "yarn upgrade-interactive --latest",
|
||||
"tsc": "vue-tsc --noEmit --skipLibCheck",
|
||||
"circle:check": "pnpm dependency-cruise --validate --output-type err-html -f dependency-report.html src",
|
||||
@@ -102,8 +103,8 @@
|
||||
"zod-defaults": "^0.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@certd/lib-iframe": "^1.35.5",
|
||||
"@certd/pipeline": "^1.35.5",
|
||||
"@certd/lib-iframe": "^1.36.0",
|
||||
"@certd/pipeline": "^1.36.0",
|
||||
"@rollup/plugin-commonjs": "^25.0.7",
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@types/chai": "^4.3.12",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<AConfigProvider :locale="locale" :theme="tokenTheme">
|
||||
<AConfigProvider :locale="antdvLocale" :theme="tokenTheme">
|
||||
<FsFormProvider>
|
||||
<contextHolder />
|
||||
<router-view />
|
||||
@@ -8,46 +8,22 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import zhCN from "ant-design-vue/es/locale/zh_CN";
|
||||
import enUS from "ant-design-vue/es/locale/en_US";
|
||||
import { computed, onMounted, provide, ref } from "vue";
|
||||
import "dayjs/locale/zh-cn";
|
||||
import "dayjs/locale/en";
|
||||
import dayjs from "dayjs";
|
||||
import { usePreferences, preferences } from "/@/vben/preferences";
|
||||
import { computed, provide, ref } from "vue";
|
||||
import { preferences, usePreferences } from "/@/vben/preferences";
|
||||
import { useAntdDesignTokens } from "/@/vben/hooks";
|
||||
import { theme } from "ant-design-vue";
|
||||
import { Modal, theme } from "ant-design-vue";
|
||||
import AConfigProvider from "ant-design-vue/es/config-provider";
|
||||
import { Modal } from "ant-design-vue";
|
||||
import MaxKBChat from "/@/components/ai/index.vue";
|
||||
import { util } from "/@/utils";
|
||||
import { useSettingStore } from "/@/store/settings";
|
||||
import { antdvLocale } from "./locales/antdv";
|
||||
import { setI18nLanguage } from "/@/locales";
|
||||
defineOptions({
|
||||
name: "App",
|
||||
});
|
||||
|
||||
const [modal, contextHolder] = Modal.useModal();
|
||||
provide("modal", modal);
|
||||
//刷新页面方法
|
||||
const locale = ref(zhCN);
|
||||
async function reload() {}
|
||||
localeChanged("zh-cn");
|
||||
provide("fn:router.reload", reload);
|
||||
provide("fn:locale.changed", localeChanged);
|
||||
//刷新页面方法
|
||||
function localeChanged(value: any) {
|
||||
console.log("locale changed:", value);
|
||||
if (value === "zh-cn") {
|
||||
locale.value = zhCN;
|
||||
dayjs.locale("zh-cn");
|
||||
} else if (value === "en") {
|
||||
locale.value = enUS;
|
||||
dayjs.locale("en");
|
||||
}
|
||||
}
|
||||
localeChanged("zh-cn");
|
||||
provide("fn:router.reload", reload);
|
||||
provide("fn:locale.changed", localeChanged);
|
||||
|
||||
const locale = preferences.app.locale;
|
||||
setI18nLanguage(locale);
|
||||
|
||||
const { isDark } = usePreferences();
|
||||
const { tokens } = useAntdDesignTokens();
|
||||
@@ -65,13 +41,4 @@ const tokenTheme = computed(() => {
|
||||
token: tokens,
|
||||
};
|
||||
});
|
||||
//其他初始化
|
||||
// const resourceStore = useResourceStore();
|
||||
// resourceStore.init();
|
||||
// const pageStore = usePageStore();
|
||||
// pageStore.init();
|
||||
// const settingStore = useSettingStore();
|
||||
// settingStore.init();
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
@@ -10,6 +10,10 @@ import { cloneDeep, debounce as lodashDebounce } from "lodash-es";
|
||||
import { initWorkers } from "./workers";
|
||||
import { importJavascriptContribution, importJsonContribution, importMonacoYaml, importYamlContribution } from "./async-import";
|
||||
|
||||
defineOptions({
|
||||
name: "CodeEditor",
|
||||
});
|
||||
|
||||
/**
|
||||
* config:
|
||||
* value: '', // 编辑器初始文本
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "PiContainer"
|
||||
name: "PiContainer",
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
</div>
|
||||
<div class="mt-5 flex">
|
||||
<a-input :disabled="true" :readonly="readonly" :value="modelValue" @change="onChange"></a-input>
|
||||
<fs-icon icon="ion:close-circle" class="pointer fs-16 ml-5 color-gray" title="清除选择" @click="onClear"></fs-icon>
|
||||
<fs-icon icon="ion:close-circle" class="pointer fs-16 ml-5 color-gray" :title="t('certd.cron.clearTip')" @click="onClear"></fs-icon>
|
||||
</div>
|
||||
<div class="helper">下次触发时间:{{ nextTime }}</div>
|
||||
<div class="helper">{{ t("certd.cron.nextTrigger") }}:{{ nextTime }}</div>
|
||||
<div class="fs-helper">{{ errorMessage }}</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -16,6 +16,9 @@
|
||||
import parser from "cron-parser";
|
||||
import { computed, ref } from "vue";
|
||||
import dayjs from "dayjs";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
const { t } = useI18n();
|
||||
import { getCronNextTimes } from "/@/components/cron-editor/utils";
|
||||
defineOptions({
|
||||
name: "CronEditor",
|
||||
@@ -83,7 +86,7 @@ const onClear = () => {
|
||||
|
||||
const nextTime = computed(() => {
|
||||
if (props.modelValue == null) {
|
||||
return "请先设置正确的cron表达式";
|
||||
return t("certd.cron.tip");
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -91,7 +94,7 @@ const nextTime = computed(() => {
|
||||
return nextTimes.join(",");
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return "请先设置正确的cron表达式";
|
||||
return t("certd.cron.tip");
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -99,18 +102,22 @@ const nextTime = computed(() => {
|
||||
.cron-editor {
|
||||
.cron-ant {
|
||||
flex-wrap: wrap;
|
||||
|
||||
&* > {
|
||||
margin-bottom: 2px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.vcron-select-list {
|
||||
min-width: 56px;
|
||||
}
|
||||
|
||||
.vcron-select-input {
|
||||
min-height: 22px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.vcron-select-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -26,7 +26,9 @@
|
||||
import { defineComponent, onMounted, ref } from "vue";
|
||||
import * as api from "./api";
|
||||
import { Modal, notification } from "ant-design-vue";
|
||||
|
||||
defineOptions({
|
||||
name: "EmailEditor",
|
||||
});
|
||||
const props = defineProps<{}>();
|
||||
const VNodes = defineComponent({
|
||||
props: {
|
||||
@@ -63,7 +65,6 @@ async function addItem() {
|
||||
return;
|
||||
}
|
||||
|
||||
debugger;
|
||||
if (emails.value.find(item => item.value === email)) {
|
||||
notification.warning({
|
||||
message: "此邮箱已存在",
|
||||
|
||||
@@ -16,7 +16,7 @@ import dayjs from "dayjs";
|
||||
import { computed } from "vue";
|
||||
|
||||
defineOptions({
|
||||
name: "ExpiresTimeText"
|
||||
name: "ExpiresTimeText",
|
||||
});
|
||||
|
||||
const props = defineProps<{
|
||||
|
||||
@@ -15,7 +15,7 @@ Author: Pedro Oliveira <kanytu@gmail . com>
|
||||
.hljs-literal,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #6897BB;
|
||||
color: #6897bb;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
@@ -42,7 +42,7 @@ Author: Pedro Oliveira <kanytu@gmail . com>
|
||||
.hljs-string,
|
||||
.hljs-attribute,
|
||||
.hljs-addition {
|
||||
color: #6A8759;
|
||||
color: #6a8759;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
|
||||
@@ -8,7 +8,7 @@ Arduino® Light Theme - Stefania Mellai <s.mellai@arduino.cc>
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #FFFFFF;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.hljs,
|
||||
@@ -21,7 +21,7 @@ Arduino® Light Theme - Stefania Mellai <s.mellai@arduino.cc>
|
||||
.hljs-selector-tag,
|
||||
.hljs-doctag,
|
||||
.hljs-name {
|
||||
color: #00979D;
|
||||
color: #00979d;
|
||||
}
|
||||
|
||||
.hljs-built_in,
|
||||
@@ -29,7 +29,7 @@ Arduino® Light Theme - Stefania Mellai <s.mellai@arduino.cc>
|
||||
.hljs-bullet,
|
||||
.hljs-code,
|
||||
.hljs-addition {
|
||||
color: #D35400;
|
||||
color: #d35400;
|
||||
}
|
||||
|
||||
.hljs-regexp,
|
||||
@@ -39,7 +39,7 @@ Arduino® Light Theme - Stefania Mellai <s.mellai@arduino.cc>
|
||||
.hljs-link,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo {
|
||||
color: #00979D;
|
||||
color: #00979d;
|
||||
}
|
||||
|
||||
.hljs-type,
|
||||
@@ -49,7 +49,7 @@ Arduino® Light Theme - Stefania Mellai <s.mellai@arduino.cc>
|
||||
.hljs-quote,
|
||||
.hljs-template-tag,
|
||||
.hljs-deletion {
|
||||
color: #005C5F;
|
||||
color: #005c5f;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
@@ -59,15 +59,15 @@ Arduino® Light Theme - Stefania Mellai <s.mellai@arduino.cc>
|
||||
}
|
||||
|
||||
.hljs-comment {
|
||||
color: rgba(149,165,166,.8);
|
||||
color: rgba(149, 165, 166, 0.8);
|
||||
}
|
||||
|
||||
.hljs-meta-keyword {
|
||||
color: #728E00;
|
||||
color: #728e00;
|
||||
}
|
||||
|
||||
.hljs-meta {
|
||||
color: #728E00;
|
||||
color: #728e00;
|
||||
color: #434f54;
|
||||
}
|
||||
|
||||
@@ -80,9 +80,9 @@ Arduino® Light Theme - Stefania Mellai <s.mellai@arduino.cc>
|
||||
}
|
||||
|
||||
.hljs-function {
|
||||
color: #728E00;
|
||||
color: #728e00;
|
||||
}
|
||||
|
||||
.hljs-number {
|
||||
color: #8A7B52;
|
||||
color: #8a7b52;
|
||||
}
|
||||
|
||||
@@ -8,14 +8,14 @@ Brown Paper style from goldblog.com.ua (c) Zaripov Yura <yur4ik7@ukr.net>
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background:#b7a68e url(./brown-papersq.png);
|
||||
background: #b7a68e url(./brown-papersq.png);
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-literal {
|
||||
color:#005599;
|
||||
font-weight:bold;
|
||||
color: #005599;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs,
|
||||
|
||||
@@ -45,8 +45,6 @@ Ported by Fabrício Tavares de Oliveira
|
||||
color: #88f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-title,
|
||||
|
||||
@@ -4,7 +4,6 @@ Darcula color scheme from the JetBrains family of IDEs
|
||||
|
||||
*/
|
||||
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
Please use darcula.css instead.
|
||||
*/
|
||||
|
||||
@import url('darcula.css');
|
||||
@import url("darcula.css");
|
||||
|
||||
@@ -8,10 +8,9 @@ Original highlight.js style (c) Ivan Sagalaev <maniac@softwaremaniacs.org>
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #F0F0F0;
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
|
||||
/* Base color: saturation 0; */
|
||||
|
||||
.hljs,
|
||||
@@ -32,7 +31,6 @@ Original highlight.js style (c) Ivan Sagalaev <maniac@softwaremaniacs.org>
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
/* User color: hue: 0 */
|
||||
|
||||
.hljs-type,
|
||||
@@ -59,14 +57,13 @@ Original highlight.js style (c) Ivan Sagalaev <maniac@softwaremaniacs.org>
|
||||
.hljs-link,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo {
|
||||
color: #BC6060;
|
||||
color: #bc6060;
|
||||
}
|
||||
|
||||
|
||||
/* Language color: hue: 90; */
|
||||
|
||||
.hljs-literal {
|
||||
color: #78A960;
|
||||
color: #78a960;
|
||||
}
|
||||
|
||||
.hljs-built_in,
|
||||
@@ -76,7 +73,6 @@ Original highlight.js style (c) Ivan Sagalaev <maniac@softwaremaniacs.org>
|
||||
color: #397300;
|
||||
}
|
||||
|
||||
|
||||
/* Meta color: hue: 200 */
|
||||
|
||||
.hljs-meta {
|
||||
@@ -87,7 +83,6 @@ Original highlight.js style (c) Ivan Sagalaev <maniac@softwaremaniacs.org>
|
||||
color: #4d99bf;
|
||||
}
|
||||
|
||||
|
||||
/* Misc effects */
|
||||
|
||||
.hljs-emphasis {
|
||||
|
||||
@@ -10,7 +10,8 @@ Date: 2013-04-02
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #eee; color: black;
|
||||
background: #eee;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.hljs-link,
|
||||
|
||||
@@ -68,7 +68,7 @@ Google Code style (c) Aahan Krish <geekpanth3r@gmail.com>
|
||||
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #9B703F
|
||||
color: #9b703f;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
|
||||
@@ -60,8 +60,8 @@ grayscale style (c) MY Sun <simonmysun@gmail.com>
|
||||
}
|
||||
|
||||
.hljs-regexp {
|
||||
color: #333;
|
||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAICAYAAADA+m62AAAAPUlEQVQYV2NkQAN37979r6yszIgujiIAU4RNMVwhuiQ6H6wQl3XI4oy4FMHcCJPHcDS6J2A2EqUQpJhohQDexSef15DBCwAAAABJRU5ErkJggg==) repeat;
|
||||
color: #333;
|
||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAICAYAAADA+m62AAAAPUlEQVQYV2NkQAN37979r6yszIgujiIAU4RNMVwhuiQ6H6wQl3XI4oy4FMHcCJPHcDS6J2A2EqUQpJhohQDexSef15DBCwAAAABJRU5ErkJggg==) repeat;
|
||||
}
|
||||
|
||||
.hljs-symbol,
|
||||
@@ -84,7 +84,7 @@ grayscale style (c) MY Sun <simonmysun@gmail.com>
|
||||
|
||||
.hljs-deletion {
|
||||
color: #fff;
|
||||
background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAADCAYAAABS3WWCAAAAE0lEQVQIW2MMDQ39zzhz5kwIAQAyxweWgUHd1AAAAABJRU5ErkJggg==) repeat;
|
||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAADCAYAAABS3WWCAAAAE0lEQVQIW2MMDQ39zzhz5kwIAQAyxweWgUHd1AAAAABJRU5ErkJggg==) repeat;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
|
||||
@@ -47,7 +47,7 @@ vim-hybrid theme by w0ng (https://github.com/w0ng/vim-hybrid)
|
||||
.hljs-literal,
|
||||
.hljs-deletion,
|
||||
.hljs-link {
|
||||
color: #cc6666
|
||||
color: #cc6666;
|
||||
}
|
||||
|
||||
/*color: fg_green*/
|
||||
@@ -64,7 +64,7 @@ vim-hybrid theme by w0ng (https://github.com/w0ng/vim-hybrid)
|
||||
.hljs-attribute,
|
||||
.hljs-code,
|
||||
.hljs-selector-id {
|
||||
color: #b294bb;
|
||||
color: #b294bb;
|
||||
}
|
||||
|
||||
/*color: fg_blue*/
|
||||
@@ -72,7 +72,7 @@ vim-hybrid theme by w0ng (https://github.com/w0ng/vim-hybrid)
|
||||
.hljs-selector-tag,
|
||||
.hljs-bullet,
|
||||
.hljs-tag {
|
||||
color: #81a2be;
|
||||
color: #81a2be;
|
||||
}
|
||||
|
||||
/*color: fg_aqua*/
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
|
||||
.hljs-number,
|
||||
.hljs-deletion {
|
||||
color:#ff73fd;
|
||||
color: #ff73fd;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
|
||||
@@ -6,7 +6,8 @@ Monokai style - ported by Luigi Maselli - http://grigio.org
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #272822; color: #ddd;
|
||||
background: #272822;
|
||||
color: #ddd;
|
||||
}
|
||||
|
||||
.hljs-tag,
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
}
|
||||
|
||||
.hljs-selector-class {
|
||||
color: #A082BD
|
||||
color: #a082bd;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
|
||||
@@ -21,12 +21,13 @@ NOTE_2: Color names provided in comments were derived using "Name that Color" on
|
||||
http://chir.ag/projects/name-that-color
|
||||
*/
|
||||
|
||||
.hljs { /* Common set of rules required by highlight.js (don'r remove!) */
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #FFFFDF; /* Half and Half (approx.) */
|
||||
/* --- Uncomment to add PureBASIC native IDE styled font!
|
||||
.hljs {
|
||||
/* Common set of rules required by highlight.js (don'r remove!) */
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #ffffdf; /* Half and Half (approx.) */
|
||||
/* --- Uncomment to add PureBASIC native IDE styled font!
|
||||
font-family: Consolas;
|
||||
*/
|
||||
}
|
||||
@@ -39,7 +40,7 @@ NOTE_2: Color names provided in comments were derived using "Name that Color" on
|
||||
.hljs-attr,
|
||||
.hljs-params,
|
||||
.hljs-subst {
|
||||
color: #000000; /* Black */
|
||||
color: #000000; /* Black */
|
||||
}
|
||||
|
||||
.hljs-comment, /* --- used for PureBASIC Comments --- */
|
||||
@@ -47,14 +48,14 @@ NOTE_2: Color names provided in comments were derived using "Name that Color" on
|
||||
.hljs-section,
|
||||
.hljs-selector-pseudo,
|
||||
.hljs-addition {
|
||||
color: #00AAAA; /* Persian Green (approx.) */
|
||||
color: #00aaaa; /* Persian Green (approx.) */
|
||||
}
|
||||
|
||||
.hljs-title, /* --- used for PureBASIC Procedures Names --- */
|
||||
.hljs-tag,
|
||||
.hljs-variable,
|
||||
.hljs-code {
|
||||
color: #006666; /* Blue Stone (approx.) */
|
||||
.hljs-code {
|
||||
color: #006666; /* Blue Stone (approx.) */
|
||||
}
|
||||
|
||||
.hljs-keyword, /* --- used for PureBASIC Keywords --- */
|
||||
@@ -63,34 +64,34 @@ NOTE_2: Color names provided in comments were derived using "Name that Color" on
|
||||
.hljs-selector-class,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name {
|
||||
color: #006666; /* Blue Stone (approx.) */
|
||||
font-weight: bold;
|
||||
color: #006666; /* Blue Stone (approx.) */
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-string, /* --- used for PureBASIC Strings --- */
|
||||
.hljs-selector-attr {
|
||||
color: #0080FF; /* Azure Radiance (approx.) */
|
||||
color: #0080ff; /* Azure Radiance (approx.) */
|
||||
}
|
||||
|
||||
.hljs-symbol, /* --- used for PureBASIC Constants --- */
|
||||
.hljs-link,
|
||||
.hljs-deletion,
|
||||
.hljs-attribute {
|
||||
color: #924B72; /* Cannon Pink (approx.) */
|
||||
color: #924b72; /* Cannon Pink (approx.) */
|
||||
}
|
||||
|
||||
.hljs-meta,
|
||||
.hljs-literal,
|
||||
.hljs-selector-id {
|
||||
color: #924B72; /* Cannon Pink (approx.) */
|
||||
font-weight: bold;
|
||||
color: #924b72; /* Cannon Pink (approx.) */
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-strong,
|
||||
.hljs-name {
|
||||
font-weight: bold;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ Qt Creator dark color scheme
|
||||
|
||||
*/
|
||||
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
@@ -32,8 +31,7 @@ Qt Creator dark color scheme
|
||||
color: #ff55ff;
|
||||
}
|
||||
|
||||
.hljs-code
|
||||
.hljs-selector-class {
|
||||
.hljs-code .hljs-selector-class {
|
||||
color: #aaaaff;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ Qt Creator light color scheme
|
||||
|
||||
*/
|
||||
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
@@ -32,8 +31,7 @@ Qt Creator light color scheme
|
||||
color: #000080;
|
||||
}
|
||||
|
||||
.hljs-code
|
||||
.hljs-selector-class {
|
||||
.hljs-code .hljs-selector-class {
|
||||
color: #800080;
|
||||
}
|
||||
|
||||
@@ -59,7 +57,7 @@ Qt Creator light color scheme
|
||||
.hljs-variable,
|
||||
.hljs-params,
|
||||
.hljs-class .hljs-title {
|
||||
color: #0055AF;
|
||||
color: #0055af;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
|
||||
@@ -44,7 +44,6 @@ Railscasts-like style (c) Visoft, Inc. (Damien White)
|
||||
color: #da4939;
|
||||
}
|
||||
|
||||
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-built_in,
|
||||
|
||||
@@ -12,7 +12,6 @@ Style with support for rainbow parens
|
||||
color: #d1d9e1;
|
||||
}
|
||||
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #969896;
|
||||
@@ -50,7 +49,7 @@ Style with support for rainbow parens
|
||||
.hljs-template-variable,
|
||||
.hljs-selector-id,
|
||||
.hljs-class .hljs-title {
|
||||
color: #ffcc66;
|
||||
color: #ffcc66;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #F0F0F0;
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
/* Base color: saturation 0; */
|
||||
@@ -31,15 +31,15 @@
|
||||
}
|
||||
|
||||
.hljs-attribute {
|
||||
color: #0E9A00;
|
||||
}
|
||||
color: #0e9a00;
|
||||
}
|
||||
|
||||
.hljs-function {
|
||||
color: #99069A;
|
||||
color: #99069a;
|
||||
}
|
||||
|
||||
.hljs-builtin-name {
|
||||
color: #99069A;
|
||||
color: #99069a;
|
||||
}
|
||||
|
||||
/* User color: hue: 0 */
|
||||
@@ -68,24 +68,22 @@
|
||||
.hljs-link,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo {
|
||||
color: #BC6060;
|
||||
color: #bc6060;
|
||||
}
|
||||
|
||||
|
||||
/* Language color: hue: 90; */
|
||||
|
||||
.hljs-literal {
|
||||
color: #78A960;
|
||||
color: #78a960;
|
||||
}
|
||||
|
||||
.hljs-built_in,
|
||||
.hljs-bullet,
|
||||
.hljs-code,
|
||||
.hljs-addition {
|
||||
color: #0C9A9A;
|
||||
color: #0c9a9a;
|
||||
}
|
||||
|
||||
|
||||
/* Meta color: hue: 200 */
|
||||
|
||||
.hljs-meta {
|
||||
@@ -96,7 +94,6 @@
|
||||
color: #4d99bf;
|
||||
}
|
||||
|
||||
|
||||
/* Misc effects */
|
||||
|
||||
.hljs-emphasis {
|
||||
|
||||
@@ -9,11 +9,11 @@ School Book style from goldblog.com.ua (c) Zaripov Yura <yur4ik7@ukr.net>
|
||||
overflow-x: auto;
|
||||
padding: 15px 0.5em 0.5em 30px;
|
||||
font-size: 11px;
|
||||
line-height:16px;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
pre{
|
||||
background:#f6f6ae url(./school-book.png);
|
||||
pre {
|
||||
background: #f6f6ae url(./school-book.png);
|
||||
border-top: solid 2px #d2e8b9;
|
||||
border-bottom: solid 1px #d2e8b9;
|
||||
}
|
||||
@@ -21,8 +21,8 @@ pre{
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-literal {
|
||||
color:#005599;
|
||||
font-weight:bold;
|
||||
color: #005599;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs,
|
||||
|
||||
@@ -58,7 +58,6 @@ Visual Studio-like style based on original C# coloring by Jason Diamond <jason@d
|
||||
color: #00b0e8;
|
||||
}
|
||||
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@@ -7,39 +7,39 @@
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #1E1E1E;
|
||||
color: #DCDCDC;
|
||||
background: #1e1e1e;
|
||||
color: #dcdcdc;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-literal,
|
||||
.hljs-symbol,
|
||||
.hljs-name {
|
||||
color: #569CD6;
|
||||
color: #569cd6;
|
||||
}
|
||||
.hljs-link {
|
||||
color: #569CD6;
|
||||
color: #569cd6;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.hljs-built_in,
|
||||
.hljs-type {
|
||||
color: #4EC9B0;
|
||||
color: #4ec9b0;
|
||||
}
|
||||
|
||||
.hljs-number,
|
||||
.hljs-class {
|
||||
color: #B8D7A3;
|
||||
color: #b8d7a3;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-meta-string {
|
||||
color: #D69D85;
|
||||
color: #d69d85;
|
||||
}
|
||||
|
||||
.hljs-regexp,
|
||||
.hljs-template-tag {
|
||||
color: #9A5334;
|
||||
color: #9a5334;
|
||||
}
|
||||
|
||||
.hljs-subst,
|
||||
@@ -47,34 +47,34 @@
|
||||
.hljs-title,
|
||||
.hljs-params,
|
||||
.hljs-formula {
|
||||
color: #DCDCDC;
|
||||
color: #dcdcdc;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #57A64A;
|
||||
color: #57a64a;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-doctag {
|
||||
color: #608B4E;
|
||||
color: #608b4e;
|
||||
}
|
||||
|
||||
.hljs-meta,
|
||||
.hljs-meta-keyword,
|
||||
.hljs-tag {
|
||||
color: #9B9B9B;
|
||||
color: #9b9b9b;
|
||||
}
|
||||
|
||||
.hljs-variable,
|
||||
.hljs-template-variable {
|
||||
color: #BD63C5;
|
||||
color: #bd63c5;
|
||||
}
|
||||
|
||||
.hljs-attr,
|
||||
.hljs-attribute,
|
||||
.hljs-builtin-name {
|
||||
color: #9CDCFE;
|
||||
color: #9cdcfe;
|
||||
}
|
||||
|
||||
.hljs-section {
|
||||
@@ -99,7 +99,7 @@
|
||||
.hljs-selector-class,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo {
|
||||
color: #D7BA7D;
|
||||
color: #d7ba7d;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
/*
|
||||
xt256.css
|
||||
|
||||
|
||||
@@ -70,7 +70,6 @@ based on dark.css by Ivan Sagalaev
|
||||
color: #7f9f7f;
|
||||
}
|
||||
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@@ -18,18 +18,18 @@ export default defineComponent({
|
||||
code: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: ""
|
||||
default: "",
|
||||
},
|
||||
formatHtml: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
default: false,
|
||||
},
|
||||
lang: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: ""
|
||||
}
|
||||
default: "",
|
||||
},
|
||||
},
|
||||
setup(props: any, ctx: any) {
|
||||
const highlightHTMLRef: Ref = ref("");
|
||||
@@ -42,7 +42,7 @@ export default defineComponent({
|
||||
doHighlight();
|
||||
},
|
||||
{
|
||||
immediate: true
|
||||
immediate: true,
|
||||
}
|
||||
);
|
||||
|
||||
@@ -52,9 +52,9 @@ export default defineComponent({
|
||||
}
|
||||
return {
|
||||
highlightHTMLRef,
|
||||
doHighlight
|
||||
doHighlight,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -3,40 +3,40 @@
|
||||
// 功能
|
||||
// 将HTML字符串格式化
|
||||
|
||||
const format = (function() {
|
||||
const format = (function () {
|
||||
function style_html(html_source, indent_size, indent_character, max_char) {
|
||||
var Parser, multi_parser;
|
||||
function Parser() {
|
||||
this.pos = 0;
|
||||
this.token = '';
|
||||
this.current_mode = 'CONTENT';
|
||||
this.token = "";
|
||||
this.current_mode = "CONTENT";
|
||||
this.tags = {
|
||||
parent: 'parent1',
|
||||
parent: "parent1",
|
||||
parentcount: 1,
|
||||
parent1: ''
|
||||
parent1: "",
|
||||
};
|
||||
this.tag_type = '';
|
||||
this.token_text = this.last_token = this.last_text = this.token_type = '';
|
||||
this.tag_type = "";
|
||||
this.token_text = this.last_token = this.last_text = this.token_type = "";
|
||||
this.Utils = {
|
||||
whitespace: "\n\r\t ".split(''),
|
||||
single_token: 'br,input,link,meta,!doctype,basefont,base,area,hr,wbr,param,img,isindex,?xml,embed'.split(','),
|
||||
extra_liners: 'head,body,/html'.split(','),
|
||||
in_array: function(what, arr) {
|
||||
whitespace: "\n\r\t ".split(""),
|
||||
single_token: "br,input,link,meta,!doctype,basefont,base,area,hr,wbr,param,img,isindex,?xml,embed".split(","),
|
||||
extra_liners: "head,body,/html".split(","),
|
||||
in_array: function (what, arr) {
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
if (what === arr[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
this.get_content = function() {
|
||||
var char = '';
|
||||
},
|
||||
};
|
||||
this.get_content = function () {
|
||||
var char = "";
|
||||
var content = [];
|
||||
var space = false;
|
||||
while (this.input.charAt(this.pos) !== '<') {
|
||||
while (this.input.charAt(this.pos) !== "<") {
|
||||
if (this.pos >= this.input.length) {
|
||||
return content.length ? content.join('') : ['', 'TK_EOF'];
|
||||
return content.length ? content.join("") : ["", "TK_EOF"];
|
||||
}
|
||||
char = this.input.charAt(this.pos);
|
||||
this.pos++;
|
||||
@@ -49,78 +49,78 @@ const format = (function() {
|
||||
continue;
|
||||
} else if (space) {
|
||||
if (this.line_char_count >= this.max_char) {
|
||||
content.push('\n');
|
||||
content.push("\n");
|
||||
for (var i = 0; i < this.indent_level; i++) {
|
||||
content.push(this.indent_string);
|
||||
}
|
||||
this.line_char_count = 0;
|
||||
} else {
|
||||
content.push(' ');
|
||||
content.push(" ");
|
||||
this.line_char_count++;
|
||||
}
|
||||
space = false;
|
||||
}
|
||||
content.push(char);
|
||||
}
|
||||
return content.length ? content.join('') : '';
|
||||
}
|
||||
this.get_script = function() {
|
||||
var char = '';
|
||||
return content.length ? content.join("") : "";
|
||||
};
|
||||
this.get_script = function () {
|
||||
var char = "";
|
||||
var content = [];
|
||||
var reg_match = new RegExp('\<\/script' + '\>', 'igm');
|
||||
var reg_match = new RegExp("</script" + ">", "igm");
|
||||
reg_match.lastIndex = this.pos;
|
||||
var reg_array = reg_match.exec(this.input);
|
||||
var end_script = reg_array ? reg_array.index: this.input.length;
|
||||
var end_script = reg_array ? reg_array.index : this.input.length;
|
||||
while (this.pos < end_script) {
|
||||
if (this.pos >= this.input.length) {
|
||||
return content.length ? content.join('') : ['', 'TK_EOF'];
|
||||
return content.length ? content.join("") : ["", "TK_EOF"];
|
||||
}
|
||||
char = this.input.charAt(this.pos);
|
||||
this.pos++;
|
||||
content.push(char);
|
||||
}
|
||||
return content.length ? content.join('') : '';
|
||||
}
|
||||
this.record_tag = function(tag) {
|
||||
if (this.tags[tag + 'count']) {
|
||||
this.tags[tag + 'count']++;
|
||||
this.tags[tag + this.tags[tag + 'count']] = this.indent_level;
|
||||
return content.length ? content.join("") : "";
|
||||
};
|
||||
this.record_tag = function (tag) {
|
||||
if (this.tags[tag + "count"]) {
|
||||
this.tags[tag + "count"]++;
|
||||
this.tags[tag + this.tags[tag + "count"]] = this.indent_level;
|
||||
} else {
|
||||
this.tags[tag + 'count'] = 1;
|
||||
this.tags[tag + this.tags[tag + 'count']] = this.indent_level;
|
||||
this.tags[tag + "count"] = 1;
|
||||
this.tags[tag + this.tags[tag + "count"]] = this.indent_level;
|
||||
}
|
||||
this.tags[tag + this.tags[tag + 'count'] + 'parent'] = this.tags.parent;
|
||||
this.tags.parent = tag + this.tags[tag + 'count'];
|
||||
}
|
||||
this.retrieve_tag = function(tag) {
|
||||
if (this.tags[tag + 'count']) {
|
||||
this.tags[tag + this.tags[tag + "count"] + "parent"] = this.tags.parent;
|
||||
this.tags.parent = tag + this.tags[tag + "count"];
|
||||
};
|
||||
this.retrieve_tag = function (tag) {
|
||||
if (this.tags[tag + "count"]) {
|
||||
var temp_parent = this.tags.parent;
|
||||
while (temp_parent) {
|
||||
if (tag + this.tags[tag + 'count'] === temp_parent) {
|
||||
if (tag + this.tags[tag + "count"] === temp_parent) {
|
||||
break;
|
||||
}
|
||||
temp_parent = this.tags[temp_parent + 'parent'];
|
||||
temp_parent = this.tags[temp_parent + "parent"];
|
||||
}
|
||||
if (temp_parent) {
|
||||
this.indent_level = this.tags[tag + this.tags[tag + 'count']];
|
||||
this.tags.parent = this.tags[temp_parent + 'parent'];
|
||||
this.indent_level = this.tags[tag + this.tags[tag + "count"]];
|
||||
this.tags.parent = this.tags[temp_parent + "parent"];
|
||||
}
|
||||
delete this.tags[tag + this.tags[tag + 'count'] + 'parent'];
|
||||
delete this.tags[tag + this.tags[tag + 'count']];
|
||||
if (this.tags[tag + 'count'] == 1) {
|
||||
delete this.tags[tag + 'count'];
|
||||
delete this.tags[tag + this.tags[tag + "count"] + "parent"];
|
||||
delete this.tags[tag + this.tags[tag + "count"]];
|
||||
if (this.tags[tag + "count"] == 1) {
|
||||
delete this.tags[tag + "count"];
|
||||
} else {
|
||||
this.tags[tag + 'count']--;
|
||||
this.tags[tag + "count"]--;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.get_tag = function() {
|
||||
var char = '';
|
||||
};
|
||||
this.get_tag = function () {
|
||||
var char = "";
|
||||
var content = [];
|
||||
var space = false;
|
||||
do {
|
||||
if (this.pos >= this.input.length) {
|
||||
return content.length ? content.join('') : ['', 'TK_EOF'];
|
||||
return content.length ? content.join("") : ["", "TK_EOF"];
|
||||
}
|
||||
char = this.input.charAt(this.pos);
|
||||
this.pos++;
|
||||
@@ -131,92 +131,92 @@ const format = (function() {
|
||||
continue;
|
||||
}
|
||||
if (char === "'" || char === '"') {
|
||||
if (!content[1] || content[1] !== '!') {
|
||||
if (!content[1] || content[1] !== "!") {
|
||||
char += this.get_unformatted(char);
|
||||
space = true;
|
||||
}
|
||||
}
|
||||
if (char === '=') {
|
||||
if (char === "=") {
|
||||
space = false;
|
||||
}
|
||||
if (content.length && content[content.length - 1] !== '=' && char !== '>' && space) {
|
||||
if (content.length && content[content.length - 1] !== "=" && char !== ">" && space) {
|
||||
if (this.line_char_count >= this.max_char) {
|
||||
this.print_newline(false, content);
|
||||
this.line_char_count = 0;
|
||||
} else {
|
||||
content.push(' ');
|
||||
content.push(" ");
|
||||
this.line_char_count++;
|
||||
}
|
||||
space = false;
|
||||
}
|
||||
content.push(char);
|
||||
} while ( char !== '>');
|
||||
var tag_complete = content.join('');
|
||||
} while (char !== ">");
|
||||
var tag_complete = content.join("");
|
||||
var tag_index;
|
||||
if (tag_complete.indexOf(' ') != -1) {
|
||||
tag_index = tag_complete.indexOf(' ');
|
||||
if (tag_complete.indexOf(" ") != -1) {
|
||||
tag_index = tag_complete.indexOf(" ");
|
||||
} else {
|
||||
tag_index = tag_complete.indexOf('>');
|
||||
tag_index = tag_complete.indexOf(">");
|
||||
}
|
||||
var tag_check = tag_complete.substring(1, tag_index).toLowerCase();
|
||||
if (tag_complete.charAt(tag_complete.length - 2) === '/' || this.Utils.in_array(tag_check, this.Utils.single_token)) {
|
||||
this.tag_type = 'SINGLE';
|
||||
} else if (tag_check === 'script') {
|
||||
if (tag_complete.charAt(tag_complete.length - 2) === "/" || this.Utils.in_array(tag_check, this.Utils.single_token)) {
|
||||
this.tag_type = "SINGLE";
|
||||
} else if (tag_check === "script") {
|
||||
this.record_tag(tag_check);
|
||||
this.tag_type = 'SCRIPT';
|
||||
} else if (tag_check === 'style') {
|
||||
this.tag_type = "SCRIPT";
|
||||
} else if (tag_check === "style") {
|
||||
this.record_tag(tag_check);
|
||||
this.tag_type = 'STYLE';
|
||||
} else if (tag_check.charAt(0) === '!') {
|
||||
if (tag_check.indexOf('[if') != -1) {
|
||||
if (tag_complete.indexOf('!IE') != -1) {
|
||||
var comment = this.get_unformatted('-->', tag_complete);
|
||||
this.tag_type = "STYLE";
|
||||
} else if (tag_check.charAt(0) === "!") {
|
||||
if (tag_check.indexOf("[if") != -1) {
|
||||
if (tag_complete.indexOf("!IE") != -1) {
|
||||
var comment = this.get_unformatted("-->", tag_complete);
|
||||
content.push(comment);
|
||||
}
|
||||
this.tag_type = 'START';
|
||||
} else if (tag_check.indexOf('[endif') != -1) {
|
||||
this.tag_type = 'END';
|
||||
this.tag_type = "START";
|
||||
} else if (tag_check.indexOf("[endif") != -1) {
|
||||
this.tag_type = "END";
|
||||
this.unindent();
|
||||
} else if (tag_check.indexOf('[cdata[') != -1) {
|
||||
var comment = this.get_unformatted(']]>', tag_complete);
|
||||
} else if (tag_check.indexOf("[cdata[") != -1) {
|
||||
var comment = this.get_unformatted("]]>", tag_complete);
|
||||
content.push(comment);
|
||||
this.tag_type = 'SINGLE';
|
||||
this.tag_type = "SINGLE";
|
||||
} else {
|
||||
var comment = this.get_unformatted('-->', tag_complete);
|
||||
var comment = this.get_unformatted("-->", tag_complete);
|
||||
content.push(comment);
|
||||
this.tag_type = 'SINGLE';
|
||||
this.tag_type = "SINGLE";
|
||||
}
|
||||
} else {
|
||||
if (tag_check.charAt(0) === '/') {
|
||||
if (tag_check.charAt(0) === "/") {
|
||||
this.retrieve_tag(tag_check.substring(1));
|
||||
this.tag_type = 'END';
|
||||
this.tag_type = "END";
|
||||
} else {
|
||||
this.record_tag(tag_check);
|
||||
this.tag_type = 'START';
|
||||
this.tag_type = "START";
|
||||
}
|
||||
if (this.Utils.in_array(tag_check, this.Utils.extra_liners)) {
|
||||
this.print_newline(true, this.output);
|
||||
}
|
||||
}
|
||||
return content.join('');
|
||||
}
|
||||
this.get_unformatted = function(delimiter, orig_tag) {
|
||||
return content.join("");
|
||||
};
|
||||
this.get_unformatted = function (delimiter, orig_tag) {
|
||||
if (orig_tag && orig_tag.indexOf(delimiter) != -1) {
|
||||
return '';
|
||||
return "";
|
||||
}
|
||||
var char = '';
|
||||
var content = '';
|
||||
var char = "";
|
||||
var content = "";
|
||||
var space = true;
|
||||
do {
|
||||
char = this.input.charAt(this.pos);
|
||||
this.pos++
|
||||
this.pos++;
|
||||
if (this.Utils.in_array(char, this.Utils.whitespace)) {
|
||||
if (!space) {
|
||||
this.line_char_count--;
|
||||
continue;
|
||||
}
|
||||
if (char === '\n' || char === '\r') {
|
||||
content += '\n';
|
||||
if (char === "\n" || char === "\r") {
|
||||
content += "\n";
|
||||
for (var i = 0; i < this.indent_level; i++) {
|
||||
content += this.indent_string;
|
||||
}
|
||||
@@ -228,44 +228,43 @@ const format = (function() {
|
||||
content += char;
|
||||
this.line_char_count++;
|
||||
space = true;
|
||||
|
||||
} while ( content . indexOf ( delimiter ) == -1);
|
||||
} while (content.indexOf(delimiter) == -1);
|
||||
return content;
|
||||
}
|
||||
this.get_token = function() {
|
||||
};
|
||||
this.get_token = function () {
|
||||
var token;
|
||||
if (this.last_token === 'TK_TAG_SCRIPT') {
|
||||
if (this.last_token === "TK_TAG_SCRIPT") {
|
||||
var temp_token = this.get_script();
|
||||
if (typeof temp_token !== 'string') {
|
||||
if (typeof temp_token !== "string") {
|
||||
return temp_token;
|
||||
}
|
||||
//token = js_beautify(temp_token, this.indent_size, this.indent_character, this.indent_level);
|
||||
//return [token, 'TK_CONTENT'];
|
||||
return [temp_token, 'TK_CONTENT'];
|
||||
return [temp_token, "TK_CONTENT"];
|
||||
}
|
||||
if (this.current_mode === 'CONTENT') {
|
||||
if (this.current_mode === "CONTENT") {
|
||||
token = this.get_content();
|
||||
if (typeof token !== 'string') {
|
||||
if (typeof token !== "string") {
|
||||
return token;
|
||||
} else {
|
||||
return [token, 'TK_CONTENT'];
|
||||
return [token, "TK_CONTENT"];
|
||||
}
|
||||
}
|
||||
if (this.current_mode === 'TAG') {
|
||||
if (this.current_mode === "TAG") {
|
||||
token = this.get_tag();
|
||||
if (typeof token !== 'string') {
|
||||
if (typeof token !== "string") {
|
||||
return token;
|
||||
} else {
|
||||
var tag_name_type = 'TK_TAG_' + this.tag_type;
|
||||
var tag_name_type = "TK_TAG_" + this.tag_type;
|
||||
return [token, tag_name_type];
|
||||
}
|
||||
}
|
||||
}
|
||||
this.printer = function(js_source, indent_character, indent_size, max_char) {
|
||||
this.input = js_source || '';
|
||||
};
|
||||
this.printer = function (js_source, indent_character, indent_size, max_char) {
|
||||
this.input = js_source || "";
|
||||
this.output = [];
|
||||
this.indent_character = indent_character || ' ';
|
||||
this.indent_string = '';
|
||||
this.indent_character = indent_character || " ";
|
||||
this.indent_string = "";
|
||||
this.indent_size = indent_size || 2;
|
||||
this.indent_level = 0;
|
||||
this.max_char = max_char || 70;
|
||||
@@ -273,7 +272,7 @@ const format = (function() {
|
||||
for (var i = 0; i < this.indent_size; i++) {
|
||||
this.indent_string += this.indent_character;
|
||||
}
|
||||
this.print_newline = function(ignore, arr) {
|
||||
this.print_newline = function (ignore, arr) {
|
||||
this.line_char_count = 0;
|
||||
if (!arr || !arr.length) {
|
||||
return;
|
||||
@@ -283,23 +282,23 @@ const format = (function() {
|
||||
arr.pop();
|
||||
}
|
||||
}
|
||||
arr.push('\n');
|
||||
arr.push("\n");
|
||||
for (var i = 0; i < this.indent_level; i++) {
|
||||
arr.push(this.indent_string);
|
||||
}
|
||||
}
|
||||
this.print_token = function(text) {
|
||||
};
|
||||
this.print_token = function (text) {
|
||||
this.output.push(text);
|
||||
}
|
||||
this.indent = function() {
|
||||
};
|
||||
this.indent = function () {
|
||||
this.indent_level++;
|
||||
}
|
||||
this.unindent = function() {
|
||||
};
|
||||
this.unindent = function () {
|
||||
if (this.indent_level > 0) {
|
||||
this.indent_level--;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
return this;
|
||||
}
|
||||
multi_parser = new Parser();
|
||||
@@ -308,58 +307,56 @@ const format = (function() {
|
||||
var t = multi_parser.get_token();
|
||||
multi_parser.token_text = t[0];
|
||||
multi_parser.token_type = t[1];
|
||||
if (multi_parser.token_type === 'TK_EOF') {
|
||||
if (multi_parser.token_type === "TK_EOF") {
|
||||
break;
|
||||
}
|
||||
switch (multi_parser.token_type) {
|
||||
case 'TK_TAG_START':
|
||||
case 'TK_TAG_SCRIPT':
|
||||
case 'TK_TAG_STYLE':
|
||||
multi_parser.print_newline(false, multi_parser.output);
|
||||
multi_parser.print_token(multi_parser.token_text);
|
||||
multi_parser.indent();
|
||||
multi_parser.current_mode = 'CONTENT';
|
||||
break;
|
||||
case 'TK_TAG_END':
|
||||
multi_parser.print_newline(true, multi_parser.output);
|
||||
multi_parser.print_token(multi_parser.token_text);
|
||||
multi_parser.current_mode = 'CONTENT';
|
||||
break;
|
||||
case 'TK_TAG_SINGLE':
|
||||
multi_parser.print_newline(false, multi_parser.output);
|
||||
multi_parser.print_token(multi_parser.token_text);
|
||||
multi_parser.current_mode = 'CONTENT';
|
||||
break;
|
||||
case 'TK_CONTENT':
|
||||
if (multi_parser.token_text !== '') {
|
||||
case "TK_TAG_START":
|
||||
case "TK_TAG_SCRIPT":
|
||||
case "TK_TAG_STYLE":
|
||||
multi_parser.print_newline(false, multi_parser.output);
|
||||
multi_parser.print_token(multi_parser.token_text);
|
||||
}
|
||||
multi_parser.current_mode = 'TAG';
|
||||
break;
|
||||
multi_parser.indent();
|
||||
multi_parser.current_mode = "CONTENT";
|
||||
break;
|
||||
case "TK_TAG_END":
|
||||
multi_parser.print_newline(true, multi_parser.output);
|
||||
multi_parser.print_token(multi_parser.token_text);
|
||||
multi_parser.current_mode = "CONTENT";
|
||||
break;
|
||||
case "TK_TAG_SINGLE":
|
||||
multi_parser.print_newline(false, multi_parser.output);
|
||||
multi_parser.print_token(multi_parser.token_text);
|
||||
multi_parser.current_mode = "CONTENT";
|
||||
break;
|
||||
case "TK_CONTENT":
|
||||
if (multi_parser.token_text !== "") {
|
||||
multi_parser.print_newline(false, multi_parser.output);
|
||||
multi_parser.print_token(multi_parser.token_text);
|
||||
}
|
||||
multi_parser.current_mode = "TAG";
|
||||
break;
|
||||
}
|
||||
multi_parser.last_token = multi_parser.token_type;
|
||||
multi_parser.last_text = multi_parser.token_text;
|
||||
}
|
||||
return multi_parser.output.join('');
|
||||
return multi_parser.output.join("");
|
||||
}
|
||||
return function(data) {
|
||||
var dataHolder = ['__dataHolder_', [Math.random(), Math.random(), Math.random(), Math.random()].join('_').replace(/[^0-9]/g, '_'), '_'].join('_');
|
||||
return function (data) {
|
||||
var dataHolder = ["__dataHolder_", [Math.random(), Math.random(), Math.random(), Math.random()].join("_").replace(/[^0-9]/g, "_"), "_"].join("_");
|
||||
var dataHolders = {};
|
||||
var index = 0;
|
||||
data = data.replace(/(\")(data:[^\"]*)(\")/g,
|
||||
function($0, $1, $2, $3) {
|
||||
data = data.replace(/(\")(data:[^\"]*)(\")/g, function ($0, $1, $2, $3) {
|
||||
var name = dataHolder + index++;
|
||||
dataHolders[name] = $2;
|
||||
return $1 + name + $3;
|
||||
})
|
||||
data = style_html(data, 2, ' ', 0x10000000);
|
||||
data = data.replace(new RegExp(dataHolder + '[0-9]+', 'g'),
|
||||
function($0) {
|
||||
});
|
||||
data = style_html(data, 2, " ", 0x10000000);
|
||||
data = data.replace(new RegExp(dataHolder + "[0-9]+", "g"), function ($0) {
|
||||
return dataHolders[$0];
|
||||
});
|
||||
return data;
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
export default format
|
||||
export default format;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<a-select>
|
||||
<a-select-option v-for="item of options" :keu="item.value" :value="item.value" :label="item.label">
|
||||
<a-select-option v-for="item of options" :key="item.value" :value="item.value" :label="item.label">
|
||||
<span class="flex-o">
|
||||
<fs-icon :icon="item.icon" class="fs-16 color-blue mr-5" />
|
||||
{{ item.label }}
|
||||
|
||||
@@ -19,7 +19,9 @@ defineOptions({
|
||||
});
|
||||
|
||||
const getScope: any = inject("get:scope");
|
||||
const getPluginType: any = inject("get:plugin:type");
|
||||
const getPluginType: any = inject("get:plugin:type", () => {
|
||||
return "access";
|
||||
});
|
||||
const formItemContext = Form.useInjectFormItemContext();
|
||||
const props = defineProps<{} & ComponentPropsType>();
|
||||
|
||||
|
||||
@@ -10,12 +10,12 @@ export default {
|
||||
props: {
|
||||
modelValue: {
|
||||
type: String,
|
||||
default: undefined
|
||||
default: undefined,
|
||||
},
|
||||
// eslint-disable-next-line vue/require-default-prop
|
||||
from: {
|
||||
type: [String, Array]
|
||||
}
|
||||
type: [String, Array],
|
||||
},
|
||||
},
|
||||
emits: ["update:modelValue"],
|
||||
setup(props: any, ctx: any) {
|
||||
@@ -35,7 +35,7 @@ export default {
|
||||
currentStageIndex: currentStageIndex.value,
|
||||
currentTaskIndex: currentTaskIndex.value,
|
||||
currentStepIndex: currentStepIndex.value,
|
||||
currentTask: currentTask.value
|
||||
currentTask: currentTask.value,
|
||||
});
|
||||
if (props.from) {
|
||||
if (typeof props.from === "string") {
|
||||
@@ -73,9 +73,9 @@ export default {
|
||||
}
|
||||
return {
|
||||
options,
|
||||
onChanged
|
||||
onChanged,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@@ -27,7 +27,9 @@ const emit = defineEmits<{
|
||||
}>();
|
||||
|
||||
const getScope: any = inject("get:scope");
|
||||
const getPluginType: any = inject("get:plugin:type");
|
||||
const getPluginType: any = inject("get:plugin:type", () => {
|
||||
return "plugin";
|
||||
});
|
||||
|
||||
const attrs = useAttrs();
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<v-nodes :vnodes="menu" />
|
||||
|
||||
<div v-if="pager === true" class="pager text-center p-5">
|
||||
<a-pagination v-model:current="pagerRef.current" simple :total="pagerRef.total" :page-size="pagerRef.limit" />
|
||||
<a-pagination v-model:current="pagerRef.pageNo" simple :total="pagerRef.total" :page-size="pagerRef.pageSize" @change="onPageChange" />
|
||||
</div>
|
||||
</template>
|
||||
</a-select>
|
||||
@@ -69,9 +69,15 @@ const emit = defineEmits<{
|
||||
|
||||
const attrs = useAttrs();
|
||||
|
||||
const getCurrentPluginDefine: any = inject("getCurrentPluginDefine");
|
||||
const getScope: any = inject("get:scope");
|
||||
const getPluginType: any = inject("get:plugin:type");
|
||||
const getCurrentPluginDefine: any = inject("getCurrentPluginDefine", () => {
|
||||
return {};
|
||||
});
|
||||
const getScope: any = inject("get:scope", () => {
|
||||
return {};
|
||||
});
|
||||
const getPluginType: any = inject("get:plugin:type", () => {
|
||||
return "plugin";
|
||||
});
|
||||
|
||||
const searchKeyRef = ref("");
|
||||
const optionsRef = ref([]);
|
||||
@@ -96,7 +102,7 @@ const getOptions = async () => {
|
||||
}
|
||||
const pluginType = getPluginType();
|
||||
const { form } = getScope();
|
||||
const input = pluginType === "plugin" ? form.input : form;
|
||||
const input = (pluginType === "plugin" ? form?.input : form) || {};
|
||||
|
||||
for (let key in define.input) {
|
||||
const inWatches = props.watches.includes(key);
|
||||
@@ -113,9 +119,8 @@ const getOptions = async () => {
|
||||
message.value = "";
|
||||
hasError.value = false;
|
||||
loading.value = true;
|
||||
optionsRef.value = [];
|
||||
|
||||
const offset = (pagerRef.value.current - 1) * (pagerRef.value.limit ?? 100);
|
||||
const pageNo = pagerRef.value.pageNo;
|
||||
const pageSize = pagerRef.value.pageSize;
|
||||
try {
|
||||
const res = await doRequest(
|
||||
{
|
||||
@@ -125,8 +130,8 @@ const getOptions = async () => {
|
||||
input,
|
||||
data: {
|
||||
searchKey: props.search ? searchKeyRef.value : "",
|
||||
offset: offset,
|
||||
limit: pagerRef.value.limit,
|
||||
pageNo,
|
||||
pageSize,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -144,17 +149,15 @@ const getOptions = async () => {
|
||||
optionsRef.value = list;
|
||||
pagerRef.value.total = list.length;
|
||||
if (props.pager) {
|
||||
if (res.offset != null) {
|
||||
pagerRef.value.offset = res.offset ?? 0;
|
||||
if (res.pageNo != null) {
|
||||
pagerRef.value.pageNo = res.pageNo ?? 1;
|
||||
}
|
||||
if (res.limit != null) {
|
||||
pagerRef.value.limit = res.limit ?? 100;
|
||||
if (res.pageSize != null) {
|
||||
pagerRef.value.pageSize = res.pageSize ?? 100;
|
||||
}
|
||||
if (res.total != null) {
|
||||
pagerRef.value.total = res.total ?? list.length;
|
||||
}
|
||||
const { offset, limit } = pagerRef.value;
|
||||
pagerRef.value.current = offset % limit === 0 ? offset / limit + 1 : offset / limit;
|
||||
}
|
||||
|
||||
return res;
|
||||
@@ -178,7 +181,7 @@ async function refreshOptions() {
|
||||
}
|
||||
|
||||
async function doSearch() {
|
||||
pagerRef.value.current = 1;
|
||||
pagerRef.value.pageNo = 1;
|
||||
await refreshOptions();
|
||||
}
|
||||
|
||||
@@ -186,9 +189,10 @@ watch(
|
||||
() => {
|
||||
const pluginType = getPluginType();
|
||||
const { form, key } = getScope();
|
||||
const input = pluginType === "plugin" ? form.input : form;
|
||||
const input = (pluginType === "plugin" ? form?.input : form) || {};
|
||||
const watches = {};
|
||||
for (const key of props.watches) {
|
||||
//@ts-ignore
|
||||
watches[key] = input[key];
|
||||
}
|
||||
return {
|
||||
@@ -198,10 +202,11 @@ watch(
|
||||
},
|
||||
async (value, oldValue) => {
|
||||
const { form } = value;
|
||||
const oldForm = oldValue.form;
|
||||
const oldForm: any = oldValue?.form;
|
||||
let changed = oldForm == null || optionsRef.value.length == 0;
|
||||
for (const key of props.watches) {
|
||||
if (form[key] != oldForm[key]) {
|
||||
//@ts-ignore
|
||||
if (oldForm && form[key] != oldForm[key]) {
|
||||
changed = true;
|
||||
break;
|
||||
}
|
||||
@@ -214,6 +219,10 @@ watch(
|
||||
immediate: true,
|
||||
}
|
||||
);
|
||||
|
||||
async function onPageChange(current: any) {
|
||||
await refreshOptions();
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less"></style>
|
||||
|
||||
@@ -27,7 +27,9 @@ const attrs = useAttrs();
|
||||
|
||||
const otpCodeRef = ref("");
|
||||
const getScope: any = inject("get:scope");
|
||||
const getPluginType: any = inject("get:plugin:type");
|
||||
const getPluginType: any = inject("get:plugin:type", () => {
|
||||
return "access";
|
||||
});
|
||||
|
||||
async function loginWithOTPCode(otpCode: string) {
|
||||
const { form } = getScope();
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
import { ref } from "vue";
|
||||
import TutorialSteps from "/@/components/tutorial/tutorial-steps.vue";
|
||||
|
||||
defineOptions({
|
||||
name: "TutorialModal",
|
||||
});
|
||||
|
||||
const props = defineProps<{
|
||||
showIcon?: boolean;
|
||||
}>();
|
||||
@@ -17,11 +21,11 @@ const slots = defineSlots();
|
||||
<div class="tutorial-button pointer" @click="open">
|
||||
<template v-if="!slots.default">
|
||||
<fs-icon v-if="showIcon === false" icon="ant-design:question-circle-outlined" class="mr-0.5"></fs-icon>
|
||||
<div class="hidden md:block">使用教程</div>
|
||||
<div class="hidden md:block">{{ $t("tutorial.title") }}</div>
|
||||
</template>
|
||||
<slot></slot>
|
||||
<a-modal v-model:open="openedRef" class="tutorial-modal" width="90%">
|
||||
<template #title> 使用教程 </template>
|
||||
<template #title>{{ $t("tutorial.title") }}</template>
|
||||
<tutorial-steps v-if="openedRef" />
|
||||
<template #footer></template>
|
||||
</a-modal>
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { useRouter } from "vue-router";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
type Step = {
|
||||
title: string;
|
||||
@@ -12,17 +15,7 @@ type Step = {
|
||||
|
||||
import { ref } from "vue";
|
||||
|
||||
const steps = ref<Step[]>([
|
||||
{
|
||||
title: "创建证书流水线"
|
||||
},
|
||||
{
|
||||
title: "添加部署任务"
|
||||
},
|
||||
{
|
||||
title: "定时运行"
|
||||
}
|
||||
]);
|
||||
const steps = ref<Step[]>([{ title: t("certd.steps.createPipeline") }, { title: t("certd.steps.addTask") }, { title: t("certd.steps.scheduledRun") }]);
|
||||
|
||||
const router = useRouter();
|
||||
function goPipeline() {
|
||||
|
||||
@@ -20,14 +20,17 @@
|
||||
</div>
|
||||
|
||||
<div class="flex-center actions">
|
||||
<fs-button class="m-10" icon="ion:arrow-back-outline" @click="prev()">上一步</fs-button>
|
||||
<fs-button class="m-10" type="primary" icon-right="ion:arrow-forward-outline" @click="next()">下一步</fs-button>
|
||||
<fs-button class="m-10" icon="ion:arrow-back-outline" @click="prev()">{{ t("guide.buttons.prev") }}</fs-button>
|
||||
<fs-button class="m-10" type="primary" icon-right="ion:arrow-forward-outline" @click="next()">{{ t("guide.buttons.next") }}</fs-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="tsx">
|
||||
import { FsRender } from "@fast-crud/fast-crud";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
const { t } = useI18n();
|
||||
import SimpleSteps from "./simple-steps.vue";
|
||||
type Step = {
|
||||
title: string;
|
||||
@@ -46,126 +49,126 @@ import { computed, nextTick, ref } from "vue";
|
||||
|
||||
const steps = ref<Step[]>([
|
||||
{
|
||||
title: "创建证书申请流水线",
|
||||
description: "演示证书申请任务如何配置",
|
||||
title: t("guide.createCertPipeline.title"),
|
||||
description: t("guide.createCertPipeline.description"),
|
||||
items: [
|
||||
{
|
||||
title: "教程演示内容",
|
||||
descriptions: ["本教程演示如何自动申请证书并部署到Nginx上", "仅需3步,全自动申请部署证书"],
|
||||
title: t("guide.createCertPipeline.items.tutorialTitle"),
|
||||
descriptions: [t("guide.createCertPipeline.items.tutorialDesc1"), t("guide.createCertPipeline.items.tutorialDesc2")],
|
||||
body: () => {
|
||||
return <SimpleSteps></SimpleSteps>;
|
||||
},
|
||||
},
|
||||
{
|
||||
image: "/static/doc/images/1-add.png",
|
||||
title: "创建证书流水线",
|
||||
descriptions: ["点击添加证书流水线,填写证书申请信息"],
|
||||
title: t("guide.createCertPipeline.items.createTitle"),
|
||||
descriptions: [t("guide.createCertPipeline.items.createDesc")],
|
||||
},
|
||||
{
|
||||
image: "/static/doc/images/3-add-success.png",
|
||||
title: "流水线创建成功",
|
||||
descriptions: ["点击手动触发即可申请证书"],
|
||||
title: t("guide.createCertPipeline.items.successTitle"),
|
||||
descriptions: [t("guide.createCertPipeline.items.successDesc")],
|
||||
},
|
||||
{
|
||||
title: "接下来演示如何自动部署证书",
|
||||
descriptions: ["如果您只需要申请证书,那么到这一步就可以了"],
|
||||
title: t("guide.createCertPipeline.items.nextTitle"),
|
||||
descriptions: [t("guide.createCertPipeline.items.nextDesc")],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "添加部署证书任务",
|
||||
description: "这里演示部署证书到Nginx",
|
||||
title: t("guide.addDeployTask.title"),
|
||||
description: t("guide.addDeployTask.description"),
|
||||
items: [
|
||||
{
|
||||
image: "/static/doc/images/5-1-add-host.png",
|
||||
title: "添加证书部署任务",
|
||||
descriptions: ["这里演示自动部署证书到nginx", "本系统提供海量部署插件,满足您的各种部署需求"],
|
||||
title: t("guide.addDeployTask.items.addTaskTitle"),
|
||||
descriptions: [t("guide.addDeployTask.items.addTaskDesc1"), t("guide.addDeployTask.items.addTaskDesc2")],
|
||||
},
|
||||
{
|
||||
image: "/static/doc/images/5-2-add-host.png",
|
||||
title: "填写任务参数",
|
||||
descriptions: ["填写主机上证书文件的路径", "选择主机ssh登录授权"],
|
||||
title: t("guide.addDeployTask.items.fillParamsTitle"),
|
||||
descriptions: [t("guide.addDeployTask.items.fillParamsDesc1"), t("guide.addDeployTask.items.fillParamsDesc2")],
|
||||
},
|
||||
{
|
||||
image: "/static/doc/images/5-3-add-host.png",
|
||||
title: "让新证书生效",
|
||||
descriptions: ["执行重启脚本", "让证书生效"],
|
||||
title: t("guide.addDeployTask.items.activateCertTitle"),
|
||||
descriptions: [t("guide.addDeployTask.items.activateCertDesc1"), t("guide.addDeployTask.items.activateCertDesc2")],
|
||||
},
|
||||
{
|
||||
image: "/static/doc/images/5-4-add-host.png",
|
||||
title: "部署任务添加成功",
|
||||
descriptions: ["现在可以运行"],
|
||||
title: t("guide.addDeployTask.items.taskSuccessTitle"),
|
||||
descriptions: [t("guide.addDeployTask.items.taskSuccessDesc")],
|
||||
},
|
||||
{
|
||||
image: "/static/doc/images/5-5-plugin-list.png",
|
||||
title: "本系统提供茫茫多的部署插件",
|
||||
descriptions: ["您可以根据自身需求将证书部署到各种应用和平台"],
|
||||
title: t("guide.addDeployTask.items.pluginsTitle"),
|
||||
descriptions: [t("guide.addDeployTask.items.pluginsDesc")],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "运行与测试",
|
||||
description: "演示流水线运行,查看日志,成功后跳过等",
|
||||
title: t("guide.runAndTestTask.runAndTestTitle"),
|
||||
description: t("guide.runAndTestTask.runAndTestDescription"),
|
||||
items: [
|
||||
{
|
||||
image: "/static/doc/images/9-start.png",
|
||||
title: "运行测试一下",
|
||||
descriptions: ["点击手动触发按钮,即可测试运行"],
|
||||
title: t("guide.runAndTestTask.runTestOnce"),
|
||||
descriptions: [t("guide.runAndTestTask.clickManualTriggerToTest")],
|
||||
},
|
||||
{
|
||||
image: "/static/doc/images/10-1-log.png",
|
||||
title: "查看日志",
|
||||
descriptions: ["点击任务可以查看状态和日志"],
|
||||
title: t("guide.runAndTestTask.viewLogs"),
|
||||
descriptions: [t("guide.runAndTestTask.clickTaskToViewStatusAndLogs")],
|
||||
},
|
||||
{
|
||||
image: "/static/doc/images/11-1-error.png",
|
||||
title: "执行失败如何排查",
|
||||
descriptions: ["查看错误日志"],
|
||||
title: t("guide.runAndTestTask.howToTroubleshootFailure"),
|
||||
descriptions: [t("guide.runAndTestTask.viewErrorLogs")],
|
||||
},
|
||||
{
|
||||
image: "/static/doc/images/11-2-error.png",
|
||||
title: "执行失败如何排查",
|
||||
descriptions: ["查看错误日志", "这里报的是nginx容器不存在,修改命令,改成正确的nginx容器名称即可"],
|
||||
title: t("guide.runAndTestTask.howToTroubleshootFailure"),
|
||||
descriptions: [t("guide.runAndTestTask.viewErrorLogs"), t("guide.runAndTestTask.nginxContainerNotExistFix")],
|
||||
},
|
||||
{
|
||||
image: "/static/doc/images/12-1-log-success.png",
|
||||
title: "执行成功",
|
||||
descriptions: ["修改正确后,重新点击手动触发,重新运行一次,执行成功"],
|
||||
title: t("guide.runAndTestTask.executionSuccess"),
|
||||
descriptions: [t("guide.runAndTestTask.retryAfterFix")],
|
||||
},
|
||||
{
|
||||
image: "/static/doc/images/12-2-skip-log.png",
|
||||
title: "成功后自动跳过",
|
||||
descriptions: ["可以看到成功过的将会自动跳过,不会重复执行,只有当参数变更或者证书更新了,才会重新运行"],
|
||||
title: t("guide.runAndTestTask.autoSkipAfterSuccess"),
|
||||
descriptions: [t("guide.runAndTestTask.successSkipExplanation")],
|
||||
},
|
||||
{
|
||||
image: "/static/doc/images/13-1-result.png",
|
||||
title: "查看证书部署成功",
|
||||
descriptions: ["访问nginx上的网站,可以看到证书已经部署成功"],
|
||||
title: t("guide.runAndTestTask.viewCertDeploymentSuccess"),
|
||||
descriptions: [t("guide.runAndTestTask.visitNginxToSeeCert")],
|
||||
},
|
||||
{
|
||||
image: "/static/doc/images/13-3-download.png",
|
||||
title: "还可以下载证书,手动部署",
|
||||
descriptions: ["如果还没有好用的部署插件,没办法自动部署,你还可以下载证书,手动部署"],
|
||||
title: t("guide.runAndTestTask.downloadCertManualDeploy"),
|
||||
descriptions: [t("guide.runAndTestTask.downloadIfNoAutoDeployPlugin")],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "设置定时执行和邮件通知",
|
||||
description: "自动运行",
|
||||
title: t("guide.scheduleAndEmailTask.title"),
|
||||
description: t("guide.scheduleAndEmailTask.description"),
|
||||
items: [
|
||||
{
|
||||
image: "/static/doc/images/14-timer.png",
|
||||
title: "设置定时执行",
|
||||
descriptions: ["流水线测试成功,接下来配置定时触发,以后每天定时执行就不用管了", "推荐配置每天运行一次,在到期前35天才会重新申请新证书并部署,没到期前会自动跳过,不会重复申请。"],
|
||||
title: t("guide.scheduleAndEmailTask.setSchedule"),
|
||||
descriptions: [t("guide.scheduleAndEmailTask.pipelineSuccessThenSchedule"), t("guide.scheduleAndEmailTask.recommendDailyRun")],
|
||||
},
|
||||
{
|
||||
image: "/static/doc/images/15-1-email.png",
|
||||
title: "设置邮件通知",
|
||||
descriptions: ["建议选择监听'错误时'和'错误转成功'两种即可,在意外失败时可以尽快去排查问题,(基础版需要配置邮件服务器)"],
|
||||
title: t("guide.scheduleAndEmailTask.setEmailNotification"),
|
||||
descriptions: [t("guide.scheduleAndEmailTask.suggestErrorAndRecoveryEmails"), t("guide.scheduleAndEmailTask.basicVersionNeedsMailServer")],
|
||||
},
|
||||
{
|
||||
title: "教程结束",
|
||||
descriptions: ["感谢观看,希望对你有所帮助"],
|
||||
title: t("guide.scheduleAndEmailTask.tutorialEndTitle"),
|
||||
descriptions: [t("guide.scheduleAndEmailTask.thanksForWatching")],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -10,7 +10,7 @@ export default {
|
||||
function checkPlus() {
|
||||
// 事件处理代码
|
||||
notification.warn({
|
||||
message: "此为专业版功能,请升级到专业版"
|
||||
message: "此为专业版功能,请升级到专业版",
|
||||
});
|
||||
}
|
||||
el.addEventListener("click", function (event: any) {
|
||||
@@ -20,5 +20,5 @@ export default {
|
||||
checkPlus();
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -20,6 +20,9 @@ import { useSettingStore } from "/@/store/settings";
|
||||
import { useRouter } from "vue-router";
|
||||
import { useUserStore } from "/@/store/user";
|
||||
import { mitter } from "/@/utils/util.mitt";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const settingStore = useSettingStore();
|
||||
const props = withDefaults(
|
||||
@@ -39,56 +42,56 @@ const text = computed<Text>(() => {
|
||||
const map = {
|
||||
isComm: {
|
||||
comm: {
|
||||
name: `${vipLabel}已开通`,
|
||||
title: "到期时间:" + expireTime.value,
|
||||
name: t("vip.comm.name", { vipLabel }),
|
||||
title: t("vip.comm.title", { expire: expireTime.value }),
|
||||
},
|
||||
button: {
|
||||
name: `${vipLabel}已开通`,
|
||||
title: "到期时间:" + expireTime.value,
|
||||
name: t("vip.comm.name", { vipLabel }),
|
||||
title: t("vip.comm.title", { expire: expireTime.value }),
|
||||
},
|
||||
icon: {
|
||||
name: "",
|
||||
title: `${vipLabel}已开通`,
|
||||
title: t("vip.comm.name", { vipLabel }),
|
||||
},
|
||||
nav: {
|
||||
name: `${vipLabel}`,
|
||||
title: "到期时间:" + expireTime.value,
|
||||
name: t("vip.comm.nav", { vipLabel }),
|
||||
title: t("vip.comm.title", { expire: expireTime.value }),
|
||||
},
|
||||
},
|
||||
isPlus: {
|
||||
comm: {
|
||||
name: "商业版功能",
|
||||
title: "升级商业版,获取商业授权",
|
||||
name: t("vip.plus.name"),
|
||||
title: t("vip.plus.title"),
|
||||
},
|
||||
button: {
|
||||
name: `${vipLabel}已开通`,
|
||||
title: "到期时间:" + expireTime.value,
|
||||
name: t("vip.comm.name", { vipLabel }),
|
||||
title: t("vip.comm.title", { expire: expireTime.value }),
|
||||
},
|
||||
icon: {
|
||||
name: "",
|
||||
title: `${vipLabel}已开通`,
|
||||
title: t("vip.comm.name", { vipLabel }),
|
||||
},
|
||||
nav: {
|
||||
name: `${vipLabel}`,
|
||||
title: "到期时间:" + expireTime.value,
|
||||
name: t("vip.comm.nav", { vipLabel }),
|
||||
title: t("vip.comm.title", { expire: expireTime.value }),
|
||||
},
|
||||
},
|
||||
free: {
|
||||
comm: {
|
||||
name: "商业版功能",
|
||||
title: "升级商业版,获取商业授权",
|
||||
name: t("vip.free.comm.name"),
|
||||
title: t("vip.free.comm.title"),
|
||||
},
|
||||
button: {
|
||||
name: "专业版功能",
|
||||
title: "升级专业版,享受更多VIP特权",
|
||||
name: t("vip.free.button.name"),
|
||||
title: t("vip.free.button.title"),
|
||||
},
|
||||
icon: {
|
||||
name: "",
|
||||
title: "专业版功能",
|
||||
title: t("vip.free.button.name"),
|
||||
},
|
||||
nav: {
|
||||
name: "基础版",
|
||||
title: "升级专业版,享受更多VIP特权",
|
||||
name: t("vip.free.nav.name"),
|
||||
title: t("vip.free.nav.title"),
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -125,22 +128,24 @@ const formState = reactive({
|
||||
const router = useRouter();
|
||||
async function doActive() {
|
||||
if (!formState.code) {
|
||||
message.error("请输入激活码");
|
||||
throw new Error("请输入激活码");
|
||||
message.error(t("vip.enterCode"));
|
||||
throw new Error(t("vip.enterCode"));
|
||||
}
|
||||
const res = await api.doActive(formState);
|
||||
if (res) {
|
||||
await settingStore.init();
|
||||
const vipLabel = settingStore.vipLabel;
|
||||
Modal.success({
|
||||
title: "激活成功",
|
||||
content: `您已成功激活${vipLabel},有效期至:${dayjs(settingStore.plusInfo.expireTime).format("YYYY-MM-DD")}`,
|
||||
title: t("vip.successTitle"),
|
||||
content: t("vip.successContent", {
|
||||
vipLabel,
|
||||
expireDate: dayjs(settingStore.plusInfo.expireTime).format("YYYY-MM-DD"),
|
||||
}),
|
||||
onOk() {
|
||||
if (!(settingStore.installInfo.bindUserId > 0)) {
|
||||
//未绑定账号
|
||||
Modal.confirm({
|
||||
title: "是否绑定袖手账号",
|
||||
content: "绑定账号后,可以避免License丢失,强烈建议绑定",
|
||||
title: t("vip.bindAccountTitle"),
|
||||
content: t("vip.bindAccountContent"),
|
||||
onOk() {
|
||||
router.push("/sys/account");
|
||||
},
|
||||
@@ -162,7 +167,7 @@ function goAccount() {
|
||||
|
||||
async function getVipTrial() {
|
||||
const res = await api.getVipTrial();
|
||||
message.success(`恭喜,您已获得专业版${res.duration}天试用`);
|
||||
message.success(t("vip.congratulations_vip_trial", { duration: res.duration }));
|
||||
await settingStore.init();
|
||||
}
|
||||
|
||||
@@ -170,8 +175,8 @@ function openTrialModal() {
|
||||
Modal.destroyAll();
|
||||
|
||||
modal.confirm({
|
||||
title: "7天专业版试用获取",
|
||||
okText: "立即获取",
|
||||
title: t("vip.trial_modal_title"),
|
||||
okText: t("vip.trial_modal_ok_text"),
|
||||
onOk() {
|
||||
getVipTrial();
|
||||
},
|
||||
@@ -179,8 +184,8 @@ function openTrialModal() {
|
||||
content: () => {
|
||||
return (
|
||||
<div class="flex-col mt-10 mb-10">
|
||||
<div>感谢您对开源项目的支持</div>
|
||||
<div>点击确认,即可获取7天专业版试用</div>
|
||||
<div>{t("vip.trial_modal_thanks")}</div>
|
||||
<div>{t("vip.trial_modal_click_confirm")}</div>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
@@ -194,8 +199,8 @@ function openStarModal() {
|
||||
};
|
||||
|
||||
modal.confirm({
|
||||
title: "7天专业版试用获取",
|
||||
okText: "立即去Star",
|
||||
title: t("vip.get_7_day_pro_trial"),
|
||||
okText: t("vip.star_now"),
|
||||
onOk() {
|
||||
goGithub();
|
||||
openTrialModal();
|
||||
@@ -204,7 +209,7 @@ function openStarModal() {
|
||||
content: () => {
|
||||
return (
|
||||
<div class="flex mt-10 mb-10">
|
||||
<div>可以先请您帮忙点个star吗?感谢感谢</div>
|
||||
<div>{t("vip.please_help_star")}</div>
|
||||
<img class="ml-5" src="https://img.shields.io/github/stars/certd/certd?logo=github" />
|
||||
</div>
|
||||
);
|
||||
@@ -214,63 +219,63 @@ function openStarModal() {
|
||||
|
||||
function openUpgrade() {
|
||||
if (!userStore.isAdmin) {
|
||||
message.info("仅限管理员操作");
|
||||
message.info(t("vip.admin_only_operation"));
|
||||
return;
|
||||
}
|
||||
const placeholder = "请输入激活码";
|
||||
const placeholder = t("vip.enter_activation_code");
|
||||
const isPlus = settingStore.isPlus;
|
||||
let title = "激活专业版/商业版";
|
||||
let title = t("vip.activate_pro_business");
|
||||
if (settingStore.isComm) {
|
||||
title = "续期商业版";
|
||||
title = t("vip.renew_business");
|
||||
} else if (settingStore.isPlus) {
|
||||
title = "续期专业版/升级商业版";
|
||||
title = t("vip.renew_pro_upgrade_business");
|
||||
}
|
||||
|
||||
const productInfo = settingStore.productInfo;
|
||||
const vipTypeDefine = {
|
||||
free: {
|
||||
title: "基础版",
|
||||
desc: "社区免费版",
|
||||
title: t("vip.basic_edition"),
|
||||
desc: t("vip.community_free_version"),
|
||||
type: "free",
|
||||
icon: "lucide:package-open",
|
||||
privilege: ["证书申请无限制", "域名数量无限制", "证书流水线数量无限制", "常用的主机、云平台、cdn、宝塔、1Panel等部署插件", "邮件、webhook通知方式"],
|
||||
privilege: [t("vip.unlimited_certificate_application"), t("vip.unlimited_domain_count"), t("vip.unlimited_certificate_pipelines"), t("vip.common_deployment_plugins"), t("vip.email_webhook_notifications")],
|
||||
},
|
||||
plus: {
|
||||
title: "专业版",
|
||||
desc: "开源需要您的赞助支持",
|
||||
title: t("vip.professional_edition"),
|
||||
desc: t("vip.open_source_support"),
|
||||
type: "plus",
|
||||
privilege: ["可加VIP群,您的需求将优先实现", "站点证书监控无限制", "更多通知方式", "插件全开放,群辉等更多插件"],
|
||||
privilege: [t("vip.vip_group_priority"), t("vip.unlimited_site_certificate_monitoring"), t("vip.more_notification_methods"), t("vip.plugins_fully_open")],
|
||||
trial: {
|
||||
title: "点击获取7天试用",
|
||||
title: t("vip.click_to_get_7_day_trial"),
|
||||
click: () => {
|
||||
openStarModal();
|
||||
},
|
||||
},
|
||||
icon: "stash:thumb-up",
|
||||
price: productInfo.plus.price,
|
||||
price3: `¥${productInfo.plus.price3}/3年`,
|
||||
price3: `¥${productInfo.plus.price3}/3${t("vip.years")}`,
|
||||
tooltip: productInfo.plus.tooltip,
|
||||
get() {
|
||||
return (
|
||||
<a-tooltip title="爱发电赞助“VIP会员”后获取一年期专业版激活码,开源需要您的支持">
|
||||
<a-tooltip title={t("vip.afdian_support_vip")}>
|
||||
<a-button size="small" type="primary" href="https://afdian.com/a/greper" target="_blank">
|
||||
爱发电赞助后获取
|
||||
{t("vip.get_after_support")}
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
);
|
||||
},
|
||||
},
|
||||
comm: {
|
||||
title: "商业版",
|
||||
desc: "商业授权,可对外运营",
|
||||
title: t("vip.business_edition"),
|
||||
desc: t("vip.commercial_license"),
|
||||
type: "comm",
|
||||
icon: "vaadin:handshake",
|
||||
privilege: ["拥有专业版所有特权", "允许商用,可修改logo、标题", "数据统计", "插件管理", "多用户无限制", "支持用户支付"],
|
||||
privilege: [t("vip.all_pro_privileges"), t("vip.allow_commercial_use_modify_logo_title"), t("vip.data_statistics"), t("vip.plugin_management"), t("vip.unlimited_multi_users"), t("vip.support_user_payment")],
|
||||
price: productInfo.comm.price,
|
||||
price3: `¥${productInfo.comm.price3}/3年`,
|
||||
price3: `¥${productInfo.comm.price3}/3${t("vip.years")}`,
|
||||
tooltip: productInfo.comm.tooltip,
|
||||
get() {
|
||||
return <a-button size="small">请联系作者获取试用</a-button>;
|
||||
return <a-button size="small">{t("vip.contact_author_for_trial")}</a-button>;
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -281,15 +286,15 @@ function openUpgrade() {
|
||||
return await doActive();
|
||||
},
|
||||
maskClosable: true,
|
||||
okText: "激活",
|
||||
width: 1000,
|
||||
okText: t("vip.activate"),
|
||||
width: 1100,
|
||||
content: () => {
|
||||
let activationCodeGetWay = (
|
||||
<span>
|
||||
<a href="https://afdian.com/a/greper" target="_blank">
|
||||
爱发电赞助“VIP会员”后获取一年期专业版激活码
|
||||
{t("vip.get_pro_code_after_support")}
|
||||
</a>
|
||||
<span> 商业版请直接联系作者</span>
|
||||
<span> {t("vip.business_contact_author")}</span>
|
||||
</span>
|
||||
);
|
||||
const vipLabel = settingStore.vipLabel;
|
||||
@@ -328,7 +333,8 @@ function openUpgrade() {
|
||||
{item.price && (
|
||||
<span class="flex">
|
||||
<span class="-text">¥{item.price}</span>
|
||||
<span>/年</span>
|
||||
<span>/</span>
|
||||
{t("vip.year")}
|
||||
<a-tooltip class="ml-5" title={item.price3}>
|
||||
<fs-icon class="pointer color-red" icon="ic:outline-discount"></fs-icon>
|
||||
</a-tooltip>
|
||||
@@ -336,7 +342,7 @@ function openUpgrade() {
|
||||
)}
|
||||
{!item.price && (
|
||||
<span>
|
||||
<span class="price-text">免费</span>
|
||||
<span class="price-text">{t("vip.freee")}</span>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
@@ -357,23 +363,24 @@ function openUpgrade() {
|
||||
<a-row gutter={20}>{slots}</a-row>
|
||||
</div>
|
||||
<div class="mt-10">
|
||||
<h3 class="block-header">{isPlus ? "续期" : "立刻激活"}</h3>
|
||||
<div>{isPlus ? `当前${vipLabel}已激活,到期时间` + dayjs(settingStore.plusInfo.expireTime).format("YYYY-MM-DD") : ""}</div>
|
||||
<h3 class="block-header">{isPlus ? t("vip.renew") : t("vip.activate_immediately")}</h3>
|
||||
<div>{isPlus ? `${t("vip.current")} ${vipLabel} ${t("vip.activated_expire_time")}` + dayjs(settingStore.plusInfo.expireTime).format("YYYY-MM-DD") : ""}</div>
|
||||
<div class="mt-10">
|
||||
<div class="flex-o w-100">
|
||||
<span>站点ID:</span>
|
||||
<span>{t("vip.site_id")}:</span>
|
||||
<fs-copyable class="flex-1" v-model={computedSiteId.value}></fs-copyable>
|
||||
</div>
|
||||
<a-input class="mt-10" v-model:value={formState.code} placeholder={placeholder} />
|
||||
<a-input class="mt-10" v-model:value={formState.inviteCode} placeholder={"邀请码【选填】,可额外获得专业版30天/商业版15天时长"} />
|
||||
<a-input class="mt-10" v-model:value={formState.inviteCode} placeholder={t("vip.invite_code_optional")} />
|
||||
</div>
|
||||
|
||||
<div class="mt-10">
|
||||
没有激活码?
|
||||
{t("vip.no_activation_code")}
|
||||
{activationCodeGetWay}
|
||||
</div>
|
||||
<div class="mt-10">
|
||||
激活码使用过一次之后,不可再次使用,如果要更换站点,请<a onClick={goAccount}>绑定账号</a>,然后"转移VIP"即可
|
||||
{t("vip.activation_code_one_use")}
|
||||
<a onClick={goAccount}>{t("vip.bind_account")}</a>,{t("vip.transfer_vip")}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -412,15 +419,18 @@ onMounted(() => {
|
||||
padding: 10px;
|
||||
border: 1px solid #eee;
|
||||
border-radius: 5px;
|
||||
height: 250px;
|
||||
height: 275px;
|
||||
|
||||
//background-color: rgba(250, 237, 167, 0.79);
|
||||
&.current {
|
||||
border-color: green;
|
||||
}
|
||||
|
||||
.block-header {
|
||||
padding: 0px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.trial {
|
||||
font-size: 12px;
|
||||
font-wight: 400;
|
||||
@@ -431,6 +441,7 @@ onMounted(() => {
|
||||
padding-top: 5px;
|
||||
margin-top: 0px;
|
||||
border-top: 1px solid #eee;
|
||||
|
||||
.price-text {
|
||||
font-size: 18px;
|
||||
color: red;
|
||||
@@ -443,15 +454,18 @@ onMounted(() => {
|
||||
margin-left: 0px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.color-green {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.vip-type-vs {
|
||||
.privilege {
|
||||
.fs-icon {
|
||||
color: green;
|
||||
}
|
||||
}
|
||||
|
||||
.fs-icon {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
import en from "./locale/en";
|
||||
import zh from "./locale/zh_CN";
|
||||
import { SupportedLanguagesType } from "/@/vben/locales";
|
||||
export const messages = {
|
||||
"en-US": {
|
||||
label: "English",
|
||||
...en
|
||||
},
|
||||
"zh-CN": {
|
||||
label: "简体中文",
|
||||
...zh
|
||||
}
|
||||
};
|
||||
|
||||
// export default createI18n({
|
||||
// legacy: false,
|
||||
// locale: "zh-cn",
|
||||
// fallbackLocale: "zh-cn",
|
||||
// messages
|
||||
// });
|
||||
|
||||
export async function loadMessages(lang: SupportedLanguagesType) {
|
||||
return messages[lang];
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
export default {
|
||||
app: { crud: { i18n: { name: "name", city: "city", status: "status" } } },
|
||||
fs: {
|
||||
rowHandle: {
|
||||
title: "Operation"
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,14 +0,0 @@
|
||||
export default {
|
||||
app: {
|
||||
crud: { i18n: { name: "姓名", city: "城市", status: "状态" } },
|
||||
login: {
|
||||
logoutTip: "确认",
|
||||
logoutMessage: "确定要注销登录吗?",
|
||||
},
|
||||
},
|
||||
fs: {
|
||||
rowHandle: {
|
||||
title: "操作列",
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -35,7 +35,7 @@ export default {
|
||||
forEach(map, (item, key) => {
|
||||
list.push({
|
||||
key,
|
||||
label: item.label
|
||||
label: item.label,
|
||||
});
|
||||
});
|
||||
return list;
|
||||
@@ -54,9 +54,9 @@ export default {
|
||||
return {
|
||||
languages,
|
||||
current,
|
||||
changeLocale
|
||||
changeLocale,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
.fs-menu-wrapper{
|
||||
.fs-menu-wrapper {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
&.fs-menu-better-scroll{
|
||||
&.fs-menu-better-scroll {
|
||||
overflow-y: hidden;
|
||||
}
|
||||
.menu-item-title{
|
||||
.menu-item-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.fs-icon{
|
||||
font-size: 16px !important;
|
||||
min-width: 16px !important;
|
||||
.fs-icon {
|
||||
font-size: 16px !important;
|
||||
min-width: 16px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import { utils } from "@fast-crud/fast-crud";
|
||||
import * as _ from "lodash-es";
|
||||
|
||||
defineOptions({
|
||||
name: "FsMenu"
|
||||
name: "FsMenu",
|
||||
});
|
||||
|
||||
const props = defineProps<{
|
||||
@@ -37,7 +37,7 @@ function buildItemMenus(menus: any) {
|
||||
title: sub.title,
|
||||
icon: () => {
|
||||
return <fsIcon icon={sub.icon ?? sub.meta?.icon} />;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
list.push(item);
|
||||
@@ -50,7 +50,7 @@ function buildItemMenus(menus: any) {
|
||||
|
||||
watch(
|
||||
() => props.menus,
|
||||
(menus) => {
|
||||
menus => {
|
||||
items.value = buildItemMenus(menus);
|
||||
},
|
||||
{ immediate: true }
|
||||
@@ -77,7 +77,7 @@ function openSelectedParents(fullPath: any) {
|
||||
return;
|
||||
}
|
||||
if (value.path === fullPath) {
|
||||
_.forEach(context.parents, (item) => {
|
||||
_.forEach(context.parents, item => {
|
||||
if (item.value instanceof Array) {
|
||||
return;
|
||||
}
|
||||
@@ -99,7 +99,7 @@ watch(
|
||||
() => {
|
||||
return route.fullPath;
|
||||
},
|
||||
(path) => {
|
||||
path => {
|
||||
// path = route.fullPath;
|
||||
selectedKeys.value = [path];
|
||||
const changed = openSelectedParents(path);
|
||||
@@ -108,7 +108,7 @@ watch(
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true
|
||||
immediate: true,
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
@@ -6,7 +6,7 @@ import "./index.less";
|
||||
import { utils } from "@fast-crud/fast-crud";
|
||||
import { routerUtils } from "/@/utils/util.router";
|
||||
|
||||
defineOptions()
|
||||
defineOptions();
|
||||
|
||||
export default defineComponent({
|
||||
name: "FsMenu",
|
||||
@@ -14,9 +14,9 @@ export default defineComponent({
|
||||
props: {
|
||||
menus: {},
|
||||
expandSelected: {
|
||||
default: false
|
||||
default: false,
|
||||
},
|
||||
scroll: {}
|
||||
scroll: {},
|
||||
},
|
||||
setup(props, ctx) {
|
||||
async function onSelect(item: any) {
|
||||
@@ -37,7 +37,7 @@ export default defineComponent({
|
||||
title: sub.title,
|
||||
icon: () => {
|
||||
return <fsIcon icon={sub.icon ?? sub.meta?.icon} />;
|
||||
}
|
||||
},
|
||||
};
|
||||
list.push(item);
|
||||
if (sub.children && sub.children.length > 0) {
|
||||
@@ -80,7 +80,7 @@ export default defineComponent({
|
||||
default: () => {
|
||||
return buildMenus(sub.children);
|
||||
},
|
||||
title
|
||||
title,
|
||||
};
|
||||
function onTitleClick() {
|
||||
if (sub.path && ctx.attrs.mode === "horizontal") {
|
||||
@@ -101,7 +101,7 @@ export default defineComponent({
|
||||
const slots = {
|
||||
default() {
|
||||
return buildMenus(props.menus);
|
||||
}
|
||||
},
|
||||
};
|
||||
const selectedKeys = ref([]);
|
||||
const openKeys = ref([]);
|
||||
@@ -123,7 +123,7 @@ export default defineComponent({
|
||||
return;
|
||||
}
|
||||
if (value.path === fullPath) {
|
||||
_.forEach(context.parents, (item) => {
|
||||
_.forEach(context.parents, item => {
|
||||
if (item.value instanceof Array) {
|
||||
return;
|
||||
}
|
||||
@@ -148,7 +148,7 @@ export default defineComponent({
|
||||
() => {
|
||||
return route.fullPath;
|
||||
},
|
||||
(path) => {
|
||||
path => {
|
||||
// path = route.fullPath;
|
||||
selectedKeys.value = [path];
|
||||
const changed = openSelectedParents(path);
|
||||
@@ -157,7 +157,7 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true
|
||||
immediate: true,
|
||||
}
|
||||
);
|
||||
return () => {
|
||||
@@ -170,7 +170,7 @@ export default defineComponent({
|
||||
// onOpenChange={onOpenChange}
|
||||
v-models={[
|
||||
[openKeys.value, "openKeys"],
|
||||
[selectedKeys.value, "selectedKeys"]
|
||||
[selectedKeys.value, "selectedKeys"],
|
||||
]}
|
||||
items={items.value}
|
||||
inlineCollapsed={!props.expandSelected}
|
||||
@@ -179,5 +179,5 @@ export default defineComponent({
|
||||
const classNames = { "fs-menu-wrapper": true, "fs-menu-better-scroll": props.scroll };
|
||||
return <div>{menu}</div>;
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -17,7 +17,7 @@ export default defineComponent({
|
||||
() => {
|
||||
return router.currentRoute.value.fullPath;
|
||||
},
|
||||
(value) => {
|
||||
value => {
|
||||
showSourceLink.value = value !== "/index";
|
||||
},
|
||||
{ immediate: true }
|
||||
@@ -29,9 +29,9 @@ export default defineComponent({
|
||||
}
|
||||
return {
|
||||
goSource,
|
||||
showSourceLink
|
||||
showSourceLink,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -2,14 +2,7 @@
|
||||
<div class="fs-multiple-page-control-group">
|
||||
<div class="fs-multiple-page-control-content">
|
||||
<div class="fs-multiple-page-control-content-inner">
|
||||
<a-tabs
|
||||
class="fs-multiple-page-control fs-multiple-page-sort"
|
||||
:active-key="page.getCurrent"
|
||||
type="editable-card"
|
||||
hide-add
|
||||
@tab-click="handleClick"
|
||||
@edit="handleTabEdit"
|
||||
>
|
||||
<a-tabs class="fs-multiple-page-control fs-multiple-page-sort" :active-key="page.getCurrent" type="editable-card" hide-add @tab-click="handleClick" @edit="handleTabEdit">
|
||||
<a-tab-pane v-for="item in page.getOpened" :key="item.fullPath" :name="item.fullPath" :closable="isTabClosable(item)">
|
||||
<template #tab>
|
||||
<span class="flex-o">
|
||||
@@ -75,7 +68,7 @@ export default {
|
||||
closeRight: pageStore.closeRight,
|
||||
closeOther: pageStore.closeOther,
|
||||
closeAll: pageStore.closeAll,
|
||||
openedSort: pageStore.openedSort
|
||||
openedSort: pageStore.openedSort,
|
||||
};
|
||||
const computeOpened = computed(() => {
|
||||
return pageStore.getOpened;
|
||||
@@ -84,7 +77,7 @@ export default {
|
||||
return {
|
||||
page: pageStore,
|
||||
...actions,
|
||||
computeOpened
|
||||
computeOpened,
|
||||
};
|
||||
},
|
||||
data() {
|
||||
@@ -97,9 +90,9 @@ export default {
|
||||
{ icon: "arrow-left", title: "关闭左侧", value: "left" },
|
||||
{ icon: "arrow-right", title: "关闭右侧", value: "right" },
|
||||
{ icon: "times", title: "关闭其它", value: "other" },
|
||||
{ icon: "times-circle", title: "关闭全部", value: "all" }
|
||||
{ icon: "times-circle", title: "关闭全部", value: "all" },
|
||||
],
|
||||
tagName: "/index"
|
||||
tagName: "/index",
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
@@ -195,8 +188,8 @@ export default {
|
||||
if (action === "remove") {
|
||||
this.close({ tagName });
|
||||
}
|
||||
}
|
||||
} as any
|
||||
},
|
||||
} as any,
|
||||
};
|
||||
</script>
|
||||
<style lang="less">
|
||||
|
||||
@@ -19,44 +19,44 @@ import { defineComponent, ref } from "vue";
|
||||
const colorListDefine = [
|
||||
{
|
||||
key: "薄暮",
|
||||
color: "#f5222d"
|
||||
color: "#f5222d",
|
||||
},
|
||||
{
|
||||
key: "火山",
|
||||
color: "#fa541c"
|
||||
color: "#fa541c",
|
||||
},
|
||||
{
|
||||
key: "日暮",
|
||||
color: "#faad14"
|
||||
color: "#faad14",
|
||||
},
|
||||
{
|
||||
key: "明青",
|
||||
color: "#13c2c2"
|
||||
color: "#13c2c2",
|
||||
},
|
||||
{
|
||||
key: "极光绿",
|
||||
color: "#52c41a"
|
||||
color: "#52c41a",
|
||||
},
|
||||
{
|
||||
key: "拂晓蓝(默认)",
|
||||
color: "#1890ff"
|
||||
color: "#1890ff",
|
||||
},
|
||||
{
|
||||
key: "极客蓝",
|
||||
color: "#2f54eb"
|
||||
color: "#2f54eb",
|
||||
},
|
||||
{
|
||||
key: "酱紫",
|
||||
color: "#722ed1"
|
||||
}
|
||||
color: "#722ed1",
|
||||
},
|
||||
];
|
||||
export default defineComponent({
|
||||
name: "FsThemeColorPicker",
|
||||
props: {
|
||||
primaryColor: {
|
||||
type: String,
|
||||
default: "#1890ff"
|
||||
}
|
||||
default: "#1890ff",
|
||||
},
|
||||
},
|
||||
emits: ["change"],
|
||||
setup(props, ctx) {
|
||||
@@ -66,9 +66,9 @@ export default defineComponent({
|
||||
}
|
||||
return {
|
||||
colorList,
|
||||
changeColor
|
||||
changeColor,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="less">
|
||||
|
||||
@@ -27,9 +27,9 @@ export default defineComponent({
|
||||
visible,
|
||||
show,
|
||||
afterVisibleChange,
|
||||
setting
|
||||
setting,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -29,9 +29,9 @@ export default defineComponent({
|
||||
};
|
||||
return {
|
||||
setting,
|
||||
onChange
|
||||
onChange,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<a-dropdown>
|
||||
<div class="fs-user-info">您好,{{ userStore.getUserInfo?.nickName || userStore.getUserInfo?.username }}</div>
|
||||
<div class="fs-user-info">{{ t("user.greeting") }},{{ userStore.getUserInfo?.nickName || userStore.getUserInfo?.username }}</div>
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
<a-menu-item>
|
||||
<div @click="goUserProfile">账号信息</div>
|
||||
<div @click="goUserProfile">{{ t("user.profile") }}</div>
|
||||
</a-menu-item>
|
||||
<a-menu-item>
|
||||
<div @click="doLogout">注销登录</div>
|
||||
<div @click="doLogout">{{ t("user.logout") }}</div>
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
|
||||
@@ -9,6 +9,9 @@ import { useSettingStore } from "/@/store/settings";
|
||||
import PageFooter from "./components/footer/index.vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import MaxKBChat from "/@/components/ai/index.vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const userStore = useUserStore();
|
||||
|
||||
@@ -19,14 +22,14 @@ const menus = computed(() => [
|
||||
router.push("/certd/mine/user-profile");
|
||||
},
|
||||
icon: "fa-solid:book",
|
||||
text: "账号信息",
|
||||
text: t("certd.accountInfo"),
|
||||
},
|
||||
{
|
||||
handler: () => {
|
||||
router.push("/certd/mine/security");
|
||||
},
|
||||
icon: "fluent:shield-keyhole-16-regular",
|
||||
text: "认证安全设置",
|
||||
text: t("certd.securitySettings"),
|
||||
},
|
||||
]);
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
<!-- <fs-menu class="header-menu" mode="horizontal" :expand-selected="false" :selectable="false" :menus="frameworkMenus" />-->
|
||||
<div
|
||||
v-for="menu of resourceStore.authedTopMenus"
|
||||
:key="menu.name"
|
||||
class="top-menu flex-center header-btn"
|
||||
:class="{ current: resourceStore.currentTopMenu === menu }"
|
||||
:style="{ color: resourceStore.currentTopMenu === menu ? token.colorPrimary : '' }"
|
||||
|
||||
18
packages/ui/certd-client/src/locales/antdv.ts
Normal file
18
packages/ui/certd-client/src/locales/antdv.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { ref } from "vue";
|
||||
import "dayjs/locale/zh-cn";
|
||||
import "dayjs/locale/en";
|
||||
import zhCN from "ant-design-vue/es/locale/zh_CN";
|
||||
import enUS from "ant-design-vue/es/locale/en_US";
|
||||
import dayjs from "dayjs";
|
||||
export const antdvLocale = ref(zhCN);
|
||||
|
||||
export async function setAntdvLocale(value: string) {
|
||||
console.log("locale changed:", value);
|
||||
if (value.startsWith("zh")) {
|
||||
dayjs.locale("zh-cn");
|
||||
antdvLocale.value = zhCN;
|
||||
} else {
|
||||
dayjs.locale("en");
|
||||
antdvLocale.value = enUS;
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,24 @@
|
||||
import type { App } from "vue";
|
||||
import type { Locale } from "vue-i18n";
|
||||
|
||||
import { setAntdvLocale } from "./antdv";
|
||||
import type { ImportLocaleFn, LoadMessageFn, LocaleSetupOptions, SupportedLanguagesType } from "./typing";
|
||||
|
||||
import { unref } from "vue";
|
||||
import { createI18n } from "vue-i18n";
|
||||
import en_US from "./langs/en-US/index";
|
||||
import zh_CN from "./langs/zh-CN/index";
|
||||
|
||||
import { useSimpleLocale } from "/@/vben/composables";
|
||||
|
||||
const i18n = createI18n({
|
||||
globalInjection: true,
|
||||
legacy: false,
|
||||
locale: "",
|
||||
messages: {}
|
||||
fallbackLocale: "en-US",
|
||||
locale: "en-US",
|
||||
messages: {
|
||||
"zh-CN": zh_CN,
|
||||
"en-US": en_US,
|
||||
},
|
||||
});
|
||||
|
||||
const modules = import.meta.glob("./langs/**/*.json");
|
||||
@@ -83,13 +89,15 @@ function loadLocalesMapFromDir(regexp: RegExp, modules: Record<string, () => Pro
|
||||
* @param locale
|
||||
*/
|
||||
function setI18nLanguage(locale: Locale) {
|
||||
setAntdvLocale(locale);
|
||||
//@ts-ignore
|
||||
i18n.global.locale.value = locale;
|
||||
|
||||
document?.querySelector("html")?.setAttribute("lang", locale);
|
||||
}
|
||||
|
||||
async function setupI18n(app: App, options: LocaleSetupOptions = {}) {
|
||||
const { defaultLocale = "zh-CN" } = options;
|
||||
const { defaultLocale = "en-US" } = options;
|
||||
// app可以自行扩展一些第三方库和组件库的国际化
|
||||
loadMessages = options.loadMessages || (async () => ({}));
|
||||
app.use(i18n);
|
||||
@@ -116,6 +124,7 @@ async function loadLocaleMessages(lang: SupportedLanguagesType) {
|
||||
const message = await localesMap[lang]?.();
|
||||
|
||||
if (message?.default) {
|
||||
//@ts-ignore
|
||||
i18n.global.setLocaleMessage(lang, message.default);
|
||||
}
|
||||
|
||||
@@ -125,4 +134,11 @@ async function loadLocaleMessages(lang: SupportedLanguagesType) {
|
||||
return setI18nLanguage(lang);
|
||||
}
|
||||
|
||||
export { i18n, loadLocaleMessages, loadLocalesMap, loadLocalesMapFromDir, setupI18n };
|
||||
export function useI18n() {
|
||||
return {
|
||||
t: i18n.global.t,
|
||||
locale: i18n.global.locale,
|
||||
};
|
||||
}
|
||||
export { i18n, loadLocaleMessages, loadLocalesMap, loadLocalesMapFromDir, setupI18n, setI18nLanguage };
|
||||
export default i18n;
|
||||
@@ -1,12 +1,12 @@
|
||||
import { i18n, loadLocaleMessages, loadLocalesMap, loadLocalesMapFromDir, setupI18n } from "./i18n";
|
||||
import { i18n, loadLocaleMessages, loadLocalesMap, loadLocalesMapFromDir, setupI18n, setI18nLanguage, useI18n } from "./i18n";
|
||||
|
||||
const $t = i18n.global.t;
|
||||
const $te = i18n.global.te;
|
||||
|
||||
export { $t, $te, i18n, loadLocaleMessages, loadLocalesMap, loadLocalesMapFromDir, setupI18n };
|
||||
export { $t, $te, i18n, loadLocaleMessages, loadLocalesMap, loadLocalesMapFromDir, setupI18n, setI18nLanguage, useI18n };
|
||||
export { type ImportLocaleFn, type LocaleSetupOptions, type SupportedLanguagesType } from "./typing";
|
||||
// export type { CompileError } from "@intlify/core-base";
|
||||
|
||||
export { useI18n } from "vue-i18n";
|
||||
// export { useI18n } from "vue-i18n";
|
||||
|
||||
export type { Locale } from "vue-i18n";
|
||||
@@ -0,0 +1,85 @@
|
||||
export default {
|
||||
welcomeBack: "Welcome Back",
|
||||
pageTitle: "Plug-and-play Admin system",
|
||||
pageDesc: "Efficient, versatile frontend template",
|
||||
loginSuccess: "Login Successful",
|
||||
loginSuccessDesc: "Welcome Back",
|
||||
loginSubtitle: "Enter your account details to manage your projects",
|
||||
selectAccount: "Quick Select Account",
|
||||
username: "Username",
|
||||
password: "Password",
|
||||
usernameTip: "Please enter username",
|
||||
passwordErrorTip: "Password is incorrect",
|
||||
passwordTip: "Please enter password",
|
||||
verifyRequiredTip: "Please complete the verification first",
|
||||
rememberMe: "Remember Me",
|
||||
createAnAccount: "Create an Account",
|
||||
createAccount: "Create Account",
|
||||
alreadyHaveAccount: "Already have an account?",
|
||||
accountTip: "Don't have an account?",
|
||||
signUp: "Sign Up",
|
||||
signUpSubtitle: "Make managing your applications simple and fun",
|
||||
confirmPassword: "Confirm Password",
|
||||
confirmPasswordTip: "The passwords do not match",
|
||||
agree: "I agree to",
|
||||
privacyPolicy: "Privacy-policy",
|
||||
terms: "Terms",
|
||||
agreeTip: "Please agree to the Privacy Policy and Terms",
|
||||
goToLogin: "Login instead",
|
||||
passwordStrength: "Use 8 or more characters with a mix of letters, numbers & symbols",
|
||||
forgetPassword: "Forget Password?",
|
||||
forgetPasswordSubtitle: "Enter your email and we'll send you instructions to reset your password",
|
||||
emailTip: "Please enter email",
|
||||
emailValidErrorTip: "The email format you entered is incorrect",
|
||||
sendResetLink: "Send Reset Link",
|
||||
email: "Email",
|
||||
qrcodeSubtitle: "Scan the QR code with your phone to login",
|
||||
qrcodePrompt: "Click 'Confirm' after scanning to complete login",
|
||||
qrcodeLogin: "QR Code Login",
|
||||
codeSubtitle: "Enter your phone number to start managing your project",
|
||||
code: "Security code",
|
||||
codeTip: "Security code required {0} characters",
|
||||
mobile: "Mobile",
|
||||
mobileLogin: "Mobile Login",
|
||||
mobileTip: "Please enter mobile number",
|
||||
mobileErrortip: "The phone number format is incorrect",
|
||||
sendCode: "Get Security code",
|
||||
sendText: "Resend in {0}s",
|
||||
thirdPartyLogin: "Or continue with",
|
||||
loginAgainTitle: "Please Log In Again",
|
||||
loginAgainSubTitle: "Your login session has expired. Please log in again to continue.",
|
||||
layout: {
|
||||
center: "Align Center",
|
||||
alignLeft: "Align Left",
|
||||
alignRight: "Align Right",
|
||||
},
|
||||
usernamePlaceholder: "Please enter username/email/phone number",
|
||||
passwordPlaceholder: "Please enter your password",
|
||||
mobilePlaceholder: "Please enter your mobile number",
|
||||
loginButton: "Log In",
|
||||
forgotAdminPassword: "Forgot admin password?",
|
||||
registerLink: "Register",
|
||||
|
||||
smsTab: "Login via SMS code",
|
||||
passwordTab: "Password login",
|
||||
title: "Change Password",
|
||||
weakPasswordWarning: "For your account security, please change your password immediately",
|
||||
changeNow: "Change Now",
|
||||
successMessage: "Changed successfully",
|
||||
oldPassword: "Old Password",
|
||||
oldPasswordRequired: "Please enter the old password",
|
||||
newPassword: "New Password",
|
||||
newPasswordRequired: "Please enter the new password",
|
||||
confirmNewPassword: "Confirm New Password",
|
||||
confirmNewPasswordRequired: "Please confirm the new password",
|
||||
changePasswordButton: "Change Password",
|
||||
enterPassword: "Please enter the password",
|
||||
newPasswordNotSameOld: "The new password cannot be the same as the old password",
|
||||
enterPasswordAgain: "Please enter the password again",
|
||||
passwordsNotMatch: "The two passwords do not match!",
|
||||
avatar: "Avatar",
|
||||
nickName: "Nickname",
|
||||
phoneNumber: "Phone Number",
|
||||
changePassword: "Change Password",
|
||||
updateProfile: "Update Profile",
|
||||
};
|
||||
712
packages/ui/certd-client/src/locales/langs/en-US/certd.ts
Normal file
712
packages/ui/certd-client/src/locales/langs/en-US/certd.ts
Normal file
@@ -0,0 +1,712 @@
|
||||
export default {
|
||||
app: {
|
||||
crud: {
|
||||
i18n: {
|
||||
name: "name",
|
||||
city: "city",
|
||||
status: "status",
|
||||
},
|
||||
},
|
||||
},
|
||||
fs: {
|
||||
rowHandle: {
|
||||
title: "Operation",
|
||||
},
|
||||
},
|
||||
order: {
|
||||
confirmTitle: "Order Confirmation",
|
||||
package: "Package",
|
||||
description: "Description",
|
||||
specifications: "Specifications",
|
||||
pipeline: "Pipeline",
|
||||
domain: "Domain",
|
||||
deployTimes: "Deployments",
|
||||
duration: "Duration",
|
||||
price: "Price",
|
||||
paymentMethod: "Payment Method",
|
||||
free: "Free",
|
||||
unit: {
|
||||
pieces: "pieces",
|
||||
count: "count",
|
||||
times: "times",
|
||||
},
|
||||
},
|
||||
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",
|
||||
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",
|
||||
suite: "Suite",
|
||||
mySuite: "My Suite",
|
||||
suiteBuy: "Suite Purchase",
|
||||
myTrade: "My Orders",
|
||||
paymentReturn: "Payment Return",
|
||||
user: {
|
||||
greeting: "Hello",
|
||||
profile: "Account Info",
|
||||
logout: "Logout",
|
||||
},
|
||||
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",
|
||||
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",
|
||||
},
|
||||
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",
|
||||
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",
|
||||
},
|
||||
types: {
|
||||
certApply: "Certificate Application",
|
||||
certUpload: "Certificate Upload",
|
||||
custom: "Custom",
|
||||
},
|
||||
myPipelines: "My Pipelines",
|
||||
selectedCount: "Selected {count} items",
|
||||
batchDelete: "Batch Delete",
|
||||
batchForceRerun: "Force 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",
|
||||
},
|
||||
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",
|
||||
},
|
||||
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",
|
||||
notificationHelper: "Get real-time alerts when the task fails",
|
||||
groupIdTitle: "Pipeline Group",
|
||||
},
|
||||
notificationDefault: "Use Default Notification",
|
||||
monitor: {
|
||||
title: "Site Certificate Monitoring",
|
||||
description: "Check website certificates' expiration at 0:00 daily; reminders sent 10 days before expiration (using default notification channel);",
|
||||
settingLink: "Site Monitoring Settings",
|
||||
limitInfo: "Basic edition limited to 1, professional and above unlimited, current",
|
||||
checkAll: "Check All",
|
||||
confirmTitle: "Confirm",
|
||||
confirmContent: "Confirm to trigger check for all site certificates?",
|
||||
checkSubmitted: "Check task submitted",
|
||||
pleaseRefresh: "Please refresh the page later to see the results",
|
||||
siteName: "Site Name",
|
||||
enterSiteName: "Please enter the site name",
|
||||
domain: "Domain",
|
||||
enterDomain: "Please enter the domain",
|
||||
enterValidDomain: "Please enter a valid domain",
|
||||
httpsPort: "HTTPS Port",
|
||||
enterPort: "Please enter the port",
|
||||
certInfo: "Certificate Info",
|
||||
issuer: "Issuer",
|
||||
certDomains: "Certificate Domains",
|
||||
certProvider: "Issuer",
|
||||
certStatus: "Certificate Status",
|
||||
status: {
|
||||
ok: "Valid",
|
||||
expired: "Expired",
|
||||
},
|
||||
certExpiresTime: "Certificate Expiration",
|
||||
expired: "expired",
|
||||
days: "days",
|
||||
lastCheckTime: "Last Check Time",
|
||||
disabled: "Enable/Disable",
|
||||
ipCheck: "Enable IP Check",
|
||||
selectRequired: "Please select",
|
||||
ipCheckConfirm: "Are you sure to {status} IP check?",
|
||||
ipCount: "IP Count",
|
||||
checkStatus: "Check Status",
|
||||
pipelineId: "Linked Pipeline ID",
|
||||
certInfoId: "Certificate ID",
|
||||
checkSubmittedRefresh: "Check task submitted. Please refresh later to view the result.",
|
||||
ipManagement: "IP Management",
|
||||
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.",
|
||||
setting: {
|
||||
siteMonitorSettings: "Site Monitor Settings",
|
||||
notificationChannel: "Notification Channel",
|
||||
setNotificationChannel: "Set the notification channel",
|
||||
retryTimes: "Retry Times",
|
||||
monitorRetryTimes: "Number of retry attempts for monitoring requests",
|
||||
monitorCronSetting: "Monitoring Schedule",
|
||||
cronTrigger: "Scheduled trigger for monitoring",
|
||||
dnsServer: "DNS Server",
|
||||
// dnsServerHelper: "使用自定义的域名解析服务器,如:1.1.1.1,8.8.8.8",
|
||||
dnsServerHelper: "Use a custom domain name resolution server, such as: 1.1.1.1,8.8.8.8",
|
||||
},
|
||||
},
|
||||
checkStatus: {
|
||||
success: "Success",
|
||||
checking: "Checking",
|
||||
error: "Error",
|
||||
},
|
||||
domainList: {
|
||||
title: "Domain List",
|
||||
helper: "Format: domain:port:name, one per line. Port and name are optional.\nExamples:\nwww.baidu.com:443:Baidu\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",
|
||||
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, please refer to the documentation ",
|
||||
subdomainManagement: "Subdomain Management",
|
||||
isDisabled: "Is Disabled",
|
||||
enabled: "Enabled",
|
||||
uploadCustomCert: "Upload Custom Certificate",
|
||||
sourcee: "Source",
|
||||
sourcePipeline: "Pipeline",
|
||||
sourceManualUpload: "Manual Upload",
|
||||
domains: "Domains",
|
||||
enterDomain: "Please enter domain",
|
||||
validDays: "Valid Days",
|
||||
expires: " expires",
|
||||
days: " days",
|
||||
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",
|
||||
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 <router-link to='/sys/cname/provider'>custom CNAME service</router-link> is set, CNAME proxy certificate application will not work.",
|
||||
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",
|
||||
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 expose /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",
|
||||
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.",
|
||||
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",
|
||||
},
|
||||
|
||||
sys: {
|
||||
setting: {
|
||||
showRunStrategy: "Show RunStrategy",
|
||||
showRunStrategyHelper: "Allow modify the run strategy of the task",
|
||||
},
|
||||
},
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user