mirror of https://github.com/certd/certd
Merge branch 'v2-dev' into v2
commit
1ff6daaa27
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.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复某些页面翻译不全显示错误的bug ([0b3158f](https://github.com/certd/certd/commit/0b3158fdd5fe5bb0a98c4e65715dbc3de2c38047))
|
||||
* 修复运行流水线后会闪烁一下的bug ([dfc9362](https://github.com/certd/certd/commit/dfc9362084082ee535b898f23b2609c1d946a6fd))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 部署plesk证书,支持删除未使用的证书 ([902d246](https://github.com/certd/certd/commit/902d246d1a7473ad90f604028c4eb09c8c67d99c))
|
||||
* 通知和定时器的删除按钮显示为红色更显眼 ([61ba83c](https://github.com/certd/certd/commit/61ba83c77546c3d505d081e19a3d68c127662bf1))
|
||||
* 优化流水线列表页面、详情页面性能,精简返回数据 ([609ac9c](https://github.com/certd/certd/commit/609ac9c9a2dde605eb09834ae59693c1cb238765))
|
||||
* 支持自动选择校验方式申请证书 ([3f99432](https://github.com/certd/certd/commit/3f9943270cfb12946e38e6272bc5e8d95ad6ab9e))
|
||||
* OpenAPI支持autoApply参数 ([42f4d14](https://github.com/certd/certd/commit/42f4d1477dc791520a874aed56035abcbc8c433b))
|
||||
|
||||
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 某些插件找不到的bug ([4b3f4a8](https://github.com/certd/certd/commit/4b3f4a868a8b0800c5c59de9d0f47bddc079e7b3))
|
||||
|
||||
## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10)
|
||||
|
||||
### Bug Fixes
|
||||
|
|
|
@ -1 +1 @@
|
|||
23:42
|
||||
23:53
|
||||
|
|
|
@ -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.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复某些页面翻译不全显示错误的bug ([0b3158f](https://github.com/certd/certd/commit/0b3158fdd5fe5bb0a98c4e65715dbc3de2c38047))
|
||||
* 修复运行流水线后会闪烁一下的bug ([dfc9362](https://github.com/certd/certd/commit/dfc9362084082ee535b898f23b2609c1d946a6fd))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 部署plesk证书,支持删除未使用的证书 ([902d246](https://github.com/certd/certd/commit/902d246d1a7473ad90f604028c4eb09c8c67d99c))
|
||||
* 通知和定时器的删除按钮显示为红色更显眼 ([61ba83c](https://github.com/certd/certd/commit/61ba83c77546c3d505d081e19a3d68c127662bf1))
|
||||
* 优化流水线列表页面、详情页面性能,精简返回数据 ([609ac9c](https://github.com/certd/certd/commit/609ac9c9a2dde605eb09834ae59693c1cb238765))
|
||||
* 支持自动选择校验方式申请证书 ([3f99432](https://github.com/certd/certd/commit/3f9943270cfb12946e38e6272bc5e8d95ad6ab9e))
|
||||
* OpenAPI支持autoApply参数 ([42f4d14](https://github.com/certd/certd/commit/42f4d1477dc791520a874aed56035abcbc8c433b))
|
||||
|
||||
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 某些插件找不到的bug ([4b3f4a8](https://github.com/certd/certd/commit/4b3f4a868a8b0800c5c59de9d0f47bddc079e7b3))
|
||||
|
||||
## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10)
|
||||
|
||||
### Bug Fixes
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
|
@ -13,4 +13,54 @@
|
|||
:::
|
||||
|
||||
## 升级日志
|
||||
可以查看最新版本号,以及所有版本的更新日志
|
||||
[CHANGELOG](../changelogs/CHANGELOG.md)
|
||||
|
||||
|
||||
## 自动升级配置
|
||||
|
||||
### 1. 方法一:使用watchtower监控
|
||||
|
||||
修改docker-compose.yaml文件增加如下配置, 使用watchtower监控自动升级
|
||||
```yaml
|
||||
services:
|
||||
certd:
|
||||
...
|
||||
labels:
|
||||
com.centurylinklabs.watchtower.enable: "true"
|
||||
|
||||
# ↓↓↓↓ --------------------------------------------------------- 自动升级,上面certd的版本号要保持为latest
|
||||
certd-updater: # 添加 Watchtower 服务
|
||||
image: containrrr/watchtower:latest
|
||||
container_name: certd-updater
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
# 配置 自动更新
|
||||
environment:
|
||||
- WATCHTOWER_CLEANUP=true # 自动清理旧版本容器
|
||||
- WATCHTOWER_INCLUDE_STOPPED=false # 不更新已停止的容器
|
||||
- WATCHTOWER_LABEL_ENABLE=true # 根据容器标签进行更新
|
||||
- WATCHTOWER_POLL_INTERVAL=600 # 每 10 分钟检查一次更新
|
||||
|
||||
```
|
||||
|
||||
|
||||
### 2. 方法二:使用Certd版本监控功能
|
||||
|
||||
选择Github-检查Release版本插件
|
||||

|
||||
按如下图填写配置
|
||||

|
||||
|
||||
|
||||
检测到新版本后执行宿主机升级命令:
|
||||
|
||||
```shell
|
||||
# 拉取最新镜像
|
||||
docker pull registry.cn-shenzhen.aliyuncs.com/handsfree/certd:latest
|
||||
# 升级容器命令, 替换成你自己的certd更新命令
|
||||
export RESTART_CERT='sleep 10; cd ~/deploy/certd/ ; docker compose down; docker compose up -d'
|
||||
# 构造一个脚本10s后在后台执行,避免容器销毁时执行太快,导致流水线任务无法结束
|
||||
nohup sh -c '$RESTART_CERT' >/dev/null 2>&1 & echo '10秒后重启' && exit
|
||||
```
|
|
@ -9,5 +9,5 @@
|
|||
}
|
||||
},
|
||||
"npmClient": "pnpm",
|
||||
"version": "1.36.4"
|
||||
"version": "1.36.6"
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
},
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"@certd/ui-server": "link:packages/ui/certd-server",
|
||||
"axios": "^1.7.7",
|
||||
"copyfiles": "^2.4.1",
|
||||
"lodash-es": "^4.17.21",
|
||||
|
|
|
@ -3,6 +3,14 @@
|
|||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.36.6](https://github.com/publishlab/node-acme-client/compare/v1.36.5...v1.36.6) (2025-07-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.36.5](https://github.com/publishlab/node-acme-client/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.36.4](https://github.com/publishlab/node-acme-client/compare/v1.36.3...v1.36.4) (2025-07-10)
|
||||
|
||||
**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.36.4",
|
||||
"version": "1.36.6",
|
||||
"type": "module",
|
||||
"module": "scr/index.js",
|
||||
"main": "src/index.js",
|
||||
|
@ -18,7 +18,7 @@
|
|||
"types"
|
||||
],
|
||||
"dependencies": {
|
||||
"@certd/basic": "^1.36.4",
|
||||
"@certd/basic": "^1.36.6",
|
||||
"@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": "0ff700849ff6427f79cce241f92257eca35af65d"
|
||||
"gitHead": "29d49d72f95aa101729965710375104240a2c038"
|
||||
}
|
||||
|
|
|
@ -3,6 +3,14 @@
|
|||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
|
|
@ -1 +1 @@
|
|||
23:36
|
||||
23:48
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@certd/basic",
|
||||
"private": false,
|
||||
"version": "1.36.4",
|
||||
"version": "1.36.6",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
|
@ -45,5 +45,5 @@
|
|||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "0ff700849ff6427f79cce241f92257eca35af65d"
|
||||
"gitHead": "29d49d72f95aa101729965710375104240a2c038"
|
||||
}
|
||||
|
|
|
@ -3,6 +3,14 @@
|
|||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@certd/pipeline",
|
||||
"private": false,
|
||||
"version": "1.36.4",
|
||||
"version": "1.36.6",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
|
@ -17,8 +17,8 @@
|
|||
"pub": "npm publish"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/basic": "^1.36.4",
|
||||
"@certd/plus-core": "^1.36.4",
|
||||
"@certd/basic": "^1.36.6",
|
||||
"@certd/plus-core": "^1.36.6",
|
||||
"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": "0ff700849ff6427f79cce241f92257eca35af65d"
|
||||
"gitHead": "29d49d72f95aa101729965710375104240a2c038"
|
||||
}
|
||||
|
|
|
@ -3,6 +3,14 @@
|
|||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@certd/lib-huawei",
|
||||
"private": false,
|
||||
"version": "1.36.4",
|
||||
"version": "1.36.6",
|
||||
"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": "0ff700849ff6427f79cce241f92257eca35af65d"
|
||||
"gitHead": "29d49d72f95aa101729965710375104240a2c038"
|
||||
}
|
||||
|
|
|
@ -3,6 +3,14 @@
|
|||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@certd/lib-iframe",
|
||||
"private": false,
|
||||
"version": "1.36.4",
|
||||
"version": "1.36.6",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
|
@ -31,5 +31,5 @@
|
|||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "0ff700849ff6427f79cce241f92257eca35af65d"
|
||||
"gitHead": "29d49d72f95aa101729965710375104240a2c038"
|
||||
}
|
||||
|
|
|
@ -3,6 +3,14 @@
|
|||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/jdcloud
|
||||
|
||||
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/jdcloud
|
||||
|
||||
## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10)
|
||||
|
||||
**Note:** Version bump only for package @certd/jdcloud
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@certd/jdcloud",
|
||||
"version": "1.36.4",
|
||||
"version": "1.36.6",
|
||||
"description": "jdcloud openApi sdk",
|
||||
"main": "./dist/bundle.js",
|
||||
"module": "./dist/bundle.js",
|
||||
|
@ -61,5 +61,5 @@
|
|||
"fetch"
|
||||
]
|
||||
},
|
||||
"gitHead": "0ff700849ff6427f79cce241f92257eca35af65d"
|
||||
"gitHead": "29d49d72f95aa101729965710375104240a2c038"
|
||||
}
|
||||
|
|
|
@ -3,6 +3,14 @@
|
|||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@certd/lib-k8s",
|
||||
"private": false,
|
||||
"version": "1.36.4",
|
||||
"version": "1.36.6",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
|
@ -17,7 +17,7 @@
|
|||
"pub": "npm publish"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/basic": "^1.36.4",
|
||||
"@certd/basic": "^1.36.6",
|
||||
"@kubernetes/client-node": "0.21.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -32,5 +32,5 @@
|
|||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "0ff700849ff6427f79cce241f92257eca35af65d"
|
||||
"gitHead": "29d49d72f95aa101729965710375104240a2c038"
|
||||
}
|
||||
|
|
|
@ -3,6 +3,17 @@
|
|||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 优化流水线列表页面、详情页面性能,精简返回数据 ([609ac9c](https://github.com/certd/certd/commit/609ac9c9a2dde605eb09834ae59693c1cb238765))
|
||||
* OpenAPI支持autoApply参数 ([42f4d14](https://github.com/certd/certd/commit/42f4d1477dc791520a874aed56035abcbc8c433b))
|
||||
|
||||
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-server
|
||||
|
||||
## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-server
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@certd/lib-server",
|
||||
"version": "1.36.4",
|
||||
"version": "1.36.6",
|
||||
"description": "midway with flyway, sql upgrade way ",
|
||||
"private": false,
|
||||
"type": "module",
|
||||
|
@ -27,10 +27,10 @@
|
|||
],
|
||||
"license": "AGPL",
|
||||
"dependencies": {
|
||||
"@certd/acme-client": "^1.36.4",
|
||||
"@certd/basic": "^1.36.4",
|
||||
"@certd/pipeline": "^1.36.4",
|
||||
"@certd/plus-core": "^1.36.4",
|
||||
"@certd/acme-client": "^1.36.6",
|
||||
"@certd/basic": "^1.36.6",
|
||||
"@certd/pipeline": "^1.36.6",
|
||||
"@certd/plus-core": "^1.36.6",
|
||||
"@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": "0ff700849ff6427f79cce241f92257eca35af65d"
|
||||
"gitHead": "29d49d72f95aa101729965710375104240a2c038"
|
||||
}
|
||||
|
|
|
@ -164,8 +164,11 @@ export abstract class BaseService<T> {
|
|||
}
|
||||
|
||||
private buildListQuery(listReq: ListReq<T>) {
|
||||
const { query, sort, buildQuery } = listReq;
|
||||
const { query, sort, buildQuery,select } = listReq;
|
||||
const qb = this.getRepository().createQueryBuilder('main');
|
||||
if (select) {
|
||||
qb.setFindOptions({select});
|
||||
}
|
||||
if (query) {
|
||||
const keys = Object.keys(query);
|
||||
for (const key of keys) {
|
||||
|
@ -191,6 +194,7 @@ export abstract class BaseService<T> {
|
|||
if (buildQuery) {
|
||||
buildQuery(qb);
|
||||
}
|
||||
|
||||
return qb;
|
||||
}
|
||||
|
||||
|
|
|
@ -107,5 +107,17 @@ export const Constants = {
|
|||
code: 20012,
|
||||
message: '证书还未生成',
|
||||
},
|
||||
openCertApplying: {
|
||||
code: 20013,
|
||||
message: '证书正在申请中,请稍后重新获取',
|
||||
},
|
||||
openDomainNoVerifier:{
|
||||
code: 20014,
|
||||
message: '域名校验方式未配置',
|
||||
},
|
||||
openEmailNotFound: {
|
||||
code: 20021,
|
||||
message: '用户邮箱还未配置',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -11,13 +11,13 @@ export class CommonException extends BaseException {
|
|||
}
|
||||
|
||||
export class CodeException extends BaseException {
|
||||
constructor(res: { code: number; message: string }) {
|
||||
super("CodeException", res.code, res.message);
|
||||
constructor(res: { code: number; message: string; data?: any }) {
|
||||
super("CodeException", res.code, res.message, res.data);
|
||||
}
|
||||
}
|
||||
|
||||
export class TextException extends BaseException {
|
||||
constructor(name, code,message, data?) {
|
||||
constructor(name, code, message, data?) {
|
||||
super(name, code, message, data);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import {Inject, Provide, Scope, ScopeEnum} from '@midwayjs/core';
|
||||
import {InjectEntityModel} from '@midwayjs/typeorm';
|
||||
import {Repository} from 'typeorm';
|
||||
import { In, Repository } from "typeorm";
|
||||
import {AccessGetter, BaseService, PageReq, PermissionException, ValidateException} from '../../../index.js';
|
||||
import {AccessEntity} from '../entity/access.js';
|
||||
import {AccessDefine, accessRegistry, newAccess} from '@certd/pipeline';
|
||||
|
@ -175,4 +175,27 @@ export class AccessService extends BaseService<AccessEntity> {
|
|||
getDefineByType(type: string) {
|
||||
return accessRegistry.getDefine(type);
|
||||
}
|
||||
|
||||
|
||||
async getSimpleByIds(ids: number[], userId: any) {
|
||||
if (ids.length === 0) {
|
||||
return [];
|
||||
}
|
||||
if (!userId) {
|
||||
return [];
|
||||
}
|
||||
return await this.repository.find({
|
||||
where: {
|
||||
id: In(ids),
|
||||
userId,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
type: true,
|
||||
userId:true
|
||||
},
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,14 @@
|
|||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||
|
||||
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||
|
||||
## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10)
|
||||
|
||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@certd/midway-flyway-js",
|
||||
"version": "1.36.4",
|
||||
"version": "1.36.6",
|
||||
"description": "midway with flyway, sql upgrade way ",
|
||||
"private": false,
|
||||
"type": "module",
|
||||
|
@ -46,5 +46,5 @@
|
|||
"typeorm": "^0.3.11",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "0ff700849ff6427f79cce241f92257eca35af65d"
|
||||
"gitHead": "29d49d72f95aa101729965710375104240a2c038"
|
||||
}
|
||||
|
|
|
@ -3,6 +3,17 @@
|
|||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 支持自动选择校验方式申请证书 ([3f99432](https://github.com/certd/certd/commit/3f9943270cfb12946e38e6272bc5e8d95ad6ab9e))
|
||||
* OpenAPI支持autoApply参数 ([42f4d14](https://github.com/certd/certd/commit/42f4d1477dc791520a874aed56035abcbc8c433b))
|
||||
|
||||
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-cert
|
||||
|
||||
## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10)
|
||||
|
||||
### Performance Improvements
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@certd/plugin-cert",
|
||||
"private": false,
|
||||
"version": "1.36.4",
|
||||
"version": "1.36.6",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
|
@ -16,10 +16,10 @@
|
|||
"pub": "npm publish"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/acme-client": "^1.36.4",
|
||||
"@certd/basic": "^1.36.4",
|
||||
"@certd/pipeline": "^1.36.4",
|
||||
"@certd/plugin-lib": "^1.36.4",
|
||||
"@certd/acme-client": "^1.36.6",
|
||||
"@certd/basic": "^1.36.6",
|
||||
"@certd/pipeline": "^1.36.6",
|
||||
"@certd/plugin-lib": "^1.36.6",
|
||||
"@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": "0ff700849ff6427f79cce241f92257eca35af65d"
|
||||
"gitHead": "29d49d72f95aa101729965710375104240a2c038"
|
||||
}
|
||||
|
|
|
@ -59,3 +59,38 @@ export interface ISubDomainsGetter {
|
|||
export interface IDomainParser {
|
||||
parse(fullDomain: string): Promise<string>;
|
||||
}
|
||||
|
||||
export type DnsVerifier = {
|
||||
// dns直接校验
|
||||
dnsProviderType?: string;
|
||||
dnsProviderAccessId?: number;
|
||||
};
|
||||
|
||||
export type CnameVerifier = {
|
||||
hostRecord: string;
|
||||
domain: string;
|
||||
recordValue: string;
|
||||
};
|
||||
|
||||
export type HttpVerifier = {
|
||||
// http校验
|
||||
httpUploaderType: string;
|
||||
httpUploaderAccess: number;
|
||||
httpUploadRootDir: string;
|
||||
};
|
||||
export type DomainVerifier = {
|
||||
domain: string;
|
||||
mainDomain: string;
|
||||
type: string;
|
||||
dns?: DnsVerifier;
|
||||
cname?: CnameVerifier;
|
||||
http?: HttpVerifier;
|
||||
};
|
||||
|
||||
export type DomainVerifiers = {
|
||||
[key: string]: DomainVerifier;
|
||||
};
|
||||
|
||||
export interface IDomainVerifierGetter {
|
||||
getVerifiers(domains: string[]): Promise<DomainVerifiers>;
|
||||
}
|
||||
|
|
|
@ -23,10 +23,11 @@ export type HttpVerifyPlan = {
|
|||
|
||||
export type DomainVerifyPlan = {
|
||||
domain: string;
|
||||
mainDomain: string;
|
||||
type: "cname" | "dns" | "http";
|
||||
dnsProvider?: IDnsProvider;
|
||||
cnameVerifyPlan?: Record<string, CnameVerifyPlan>;
|
||||
httpVerifyPlan?: Record<string, HttpVerifyPlan>;
|
||||
cnameVerifyPlan?: CnameVerifyPlan;
|
||||
httpVerifyPlan?: HttpVerifyPlan;
|
||||
};
|
||||
export type DomainsVerifyPlan = {
|
||||
[key: string]: DomainVerifyPlan;
|
||||
|
@ -233,23 +234,20 @@ export class AcmeService {
|
|||
let dnsProvider = providers.dnsProvider;
|
||||
let fullRecord = `_acme-challenge.${fullDomain}`;
|
||||
|
||||
const origDomain = punycode.toUnicode(domain);
|
||||
// const origDomain = punycode.toUnicode(domain);
|
||||
const origFullDomain = punycode.toUnicode(fullDomain);
|
||||
if (providers.domainsVerifyPlan) {
|
||||
//按照计划执行
|
||||
const domainVerifyPlan = providers.domainsVerifyPlan[origDomain];
|
||||
const domainVerifyPlan = providers.domainsVerifyPlan[origFullDomain];
|
||||
if (domainVerifyPlan) {
|
||||
if (domainVerifyPlan.type === "dns") {
|
||||
dnsProvider = domainVerifyPlan.dnsProvider;
|
||||
} else if (domainVerifyPlan.type === "cname") {
|
||||
const cnameVerifyPlan = domainVerifyPlan.cnameVerifyPlan;
|
||||
if (cnameVerifyPlan) {
|
||||
const cname = cnameVerifyPlan[origFullDomain];
|
||||
if (cname) {
|
||||
dnsProvider = cname.dnsProvider;
|
||||
domain = await this.options.domainParser.parse(cname.domain);
|
||||
fullRecord = cname.fullRecord;
|
||||
}
|
||||
const cname: CnameVerifyPlan = domainVerifyPlan.cnameVerifyPlan;
|
||||
if (cname) {
|
||||
dnsProvider = cname.dnsProvider;
|
||||
domain = await this.options.domainParser.parse(cname.domain);
|
||||
fullRecord = cname.fullRecord;
|
||||
} else {
|
||||
this.logger.error(`未找到域名${fullDomain}的CNAME校验计划,请修改证书申请配置`);
|
||||
}
|
||||
|
@ -257,13 +255,12 @@ export class AcmeService {
|
|||
throw new Error(`未找到域名${fullDomain}CNAME校验计划的DnsProvider,请修改证书申请配置`);
|
||||
}
|
||||
} else if (domainVerifyPlan.type === "http") {
|
||||
const httpVerifyPlan = domainVerifyPlan.httpVerifyPlan;
|
||||
if (httpVerifyPlan) {
|
||||
const plan: HttpVerifyPlan = domainVerifyPlan.httpVerifyPlan;
|
||||
if (plan) {
|
||||
const httpChallenge = getChallenge("http-01");
|
||||
if (httpChallenge == null) {
|
||||
throw new Error("该域名不支持http-01方式校验");
|
||||
}
|
||||
const plan = httpVerifyPlan[fullDomain];
|
||||
return await doHttpVerify(httpChallenge, plan.httpUploader);
|
||||
} else {
|
||||
throw new Error("未找到域名【" + fullDomain + "】的http校验配置");
|
||||
|
@ -272,9 +269,12 @@ export class AcmeService {
|
|||
throw new Error("不支持的校验类型", domainVerifyPlan.type);
|
||||
}
|
||||
} else {
|
||||
this.logger.info("未找到域名校验计划,使用默认的dnsProvider");
|
||||
this.logger.warn(`未找到域名${fullDomain}的校验计划,使用默认的dnsProvider`);
|
||||
}
|
||||
}
|
||||
if (!dnsProvider) {
|
||||
throw new Error(`域名${fullDomain}没有匹配到任何校验方式,证书申请失败`);
|
||||
}
|
||||
|
||||
const dnsChallenge = getChallenge("dns-01");
|
||||
return await doDnsVerify(dnsChallenge, fullRecord, dnsProvider);
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
import { CancelError, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
|
||||
import { utils } from "@certd/basic";
|
||||
|
||||
import type { CertInfo, CnameVerifyPlan, DomainsVerifyPlan, HttpVerifyPlan, PrivateKeyType, SSLProvider } from "./acme.js";
|
||||
import { AcmeService } from "./acme.js";
|
||||
import { AcmeService, CertInfo, DomainsVerifyPlan, DomainVerifyPlan, PrivateKeyType, SSLProvider } from "./acme.js";
|
||||
import * as _ from "lodash-es";
|
||||
import { createDnsProvider, DnsProviderContext, IDnsProvider, ISubDomainsGetter } from "../../dns-provider/index.js";
|
||||
import { createDnsProvider, DnsProviderContext, DnsVerifier, DomainVerifiers, HttpVerifier, IDnsProvider, IDomainVerifierGetter, ISubDomainsGetter } from "../../dns-provider/index.js";
|
||||
import { CertReader } from "./cert-reader.js";
|
||||
import { CertApplyBasePlugin } from "./base.js";
|
||||
import { GoogleClient } from "../../libs/google.js";
|
||||
import { EabAccess } from "../../access";
|
||||
import { DomainParser } from "../../dns-provider/domain-parser.js";
|
||||
import { ossClientFactory } from "@certd/plugin-lib";
|
||||
|
||||
export * from "./base.js";
|
||||
export type { CertInfo };
|
||||
export * from "./cert-reader.js";
|
||||
|
@ -66,13 +66,15 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
|||
{ value: "cname", label: "CNAME代理验证" },
|
||||
{ value: "http", label: "HTTP文件验证" },
|
||||
{ value: "dnses", label: "多DNS提供商" },
|
||||
{ value: "auto", label: "自动匹配" },
|
||||
],
|
||||
},
|
||||
required: true,
|
||||
helper: `1. <b>DNS直接验证</b>:域名dns解析是在阿里云/腾讯云/华为云/CF/NameSilo/西数/火山/dns.la/京东云/51dns的,选它
|
||||
2. <b>CNAME代理验证</b>:支持任何注册商的域名,第一次需要手动添加CNAME记录(建议将DNS服务器修改为阿里云/腾讯云的,然后使用DNS直接验证)
|
||||
2. <b>CNAME代理验证</b>:支持任何注册商的域名,第一次需要手动添加[CNAME记录](#/certd/cname/record)(建议将DNS服务器修改为阿里云/腾讯云的,然后使用DNS直接验证)
|
||||
3. <b>HTTP文件验证</b>:不支持泛域名,需要配置网站文件上传
|
||||
4. <b>多DNS提供商</b>:每个域名可以选择独立的DNS提供商
|
||||
5. <b>自动匹配</b>:需要在[域名管理](#/certd/cert/domain)中事先配置好校验方式
|
||||
`,
|
||||
})
|
||||
challengeType!: string;
|
||||
|
@ -333,6 +335,7 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
|||
acme!: AcmeService;
|
||||
|
||||
eab!: EabAccess;
|
||||
|
||||
async onInit() {
|
||||
let eab: EabAccess = null;
|
||||
|
||||
|
@ -408,7 +411,9 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
|||
let dnsProvider: IDnsProvider = null;
|
||||
let domainsVerifyPlan: DomainsVerifyPlan = null;
|
||||
if (this.challengeType === "cname" || this.challengeType === "http" || this.challengeType === "dnses") {
|
||||
domainsVerifyPlan = await this.createDomainsVerifyPlan();
|
||||
domainsVerifyPlan = await this.createDomainsVerifyPlan(domains, this.domainsVerifyPlan);
|
||||
} else if (this.challengeType === "auto") {
|
||||
domainsVerifyPlan = await this.createDomainsVerifyPlanByAuto(domains);
|
||||
} else {
|
||||
const dnsProviderType = this.dnsProviderType;
|
||||
const access = await this.getAccess(this.dnsProviderAccess);
|
||||
|
@ -444,73 +449,132 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
|||
|
||||
async createDnsProvider(dnsProviderType: string, dnsProviderAccess: any): Promise<IDnsProvider> {
|
||||
const domainParser = this.acme.options.domainParser;
|
||||
const context: DnsProviderContext = { access: dnsProviderAccess, logger: this.logger, http: this.ctx.http, utils, domainParser };
|
||||
const context: DnsProviderContext = {
|
||||
access: dnsProviderAccess,
|
||||
logger: this.logger,
|
||||
http: this.ctx.http,
|
||||
utils,
|
||||
domainParser,
|
||||
};
|
||||
return await createDnsProvider({
|
||||
dnsProviderType,
|
||||
context,
|
||||
});
|
||||
}
|
||||
|
||||
async createDomainsVerifyPlan(): Promise<DomainsVerifyPlan> {
|
||||
async createDomainsVerifyPlan(domains: string[], verifyPlanSetting: DomainsVerifyPlanInput): Promise<DomainsVerifyPlan> {
|
||||
const plan: DomainsVerifyPlan = {};
|
||||
for (const domain in this.domainsVerifyPlan) {
|
||||
const domainVerifyPlan = this.domainsVerifyPlan[domain];
|
||||
let dnsProvider = null;
|
||||
const cnameVerifyPlan: Record<string, CnameVerifyPlan> = {};
|
||||
const httpVerifyPlan: Record<string, HttpVerifyPlan> = {};
|
||||
if (domainVerifyPlan.type === "dns") {
|
||||
const access = await this.getAccess(domainVerifyPlan.dnsProviderAccessId);
|
||||
dnsProvider = await this.createDnsProvider(domainVerifyPlan.dnsProviderType, access);
|
||||
} else if (domainVerifyPlan.type === "cname") {
|
||||
for (const key in domainVerifyPlan.cnameVerifyPlan) {
|
||||
const cnameRecord = await this.ctx.cnameProxyService.getByDomain(key);
|
||||
let dnsProvider = cnameRecord.commonDnsProvider;
|
||||
if (cnameRecord.cnameProvider.id > 0) {
|
||||
dnsProvider = await this.createDnsProvider(cnameRecord.cnameProvider.dnsProviderType, cnameRecord.cnameProvider.access);
|
||||
}
|
||||
cnameVerifyPlan[key] = {
|
||||
type: "cname",
|
||||
domain: cnameRecord.cnameProvider.domain,
|
||||
fullRecord: cnameRecord.recordValue,
|
||||
dnsProvider,
|
||||
};
|
||||
}
|
||||
} else if (domainVerifyPlan.type === "http") {
|
||||
const httpUploaderContext = {
|
||||
accessService: this.ctx.accessService,
|
||||
logger: this.logger,
|
||||
utils,
|
||||
};
|
||||
for (const key in domainVerifyPlan.httpVerifyPlan) {
|
||||
const httpRecord = domainVerifyPlan.httpVerifyPlan[key];
|
||||
const access = await this.getAccess(httpRecord.httpUploaderAccess);
|
||||
let rootDir = httpRecord.httpUploadRootDir;
|
||||
if (!rootDir.endsWith("/") && !rootDir.endsWith("\\")) {
|
||||
rootDir = rootDir + "/";
|
||||
}
|
||||
this.logger.info("上传方式", httpRecord.httpUploaderType);
|
||||
const httpUploader = await ossClientFactory.createOssClientByType(httpRecord.httpUploaderType, {
|
||||
access,
|
||||
rootDir: rootDir,
|
||||
ctx: httpUploaderContext,
|
||||
});
|
||||
httpVerifyPlan[key] = {
|
||||
type: "http",
|
||||
domain: key,
|
||||
httpUploader,
|
||||
};
|
||||
}
|
||||
|
||||
const domainParser = this.acme.options.domainParser;
|
||||
for (const fullDomain of domains) {
|
||||
const domain = fullDomain.replaceAll("*.", "");
|
||||
const mainDomain = await domainParser.parse(domain);
|
||||
const planSetting: DomainVerifyPlanInput = verifyPlanSetting[mainDomain];
|
||||
if (planSetting == null) {
|
||||
throw new Error(`没有找到域名(${domain})的校验计划`);
|
||||
}
|
||||
if (planSetting.type === "dns") {
|
||||
plan[domain] = await this.createDnsDomainVerifyPlan(planSetting, domain, mainDomain);
|
||||
} else if (planSetting.type === "cname") {
|
||||
plan[domain] = await this.createCnameDomainVerifyPlan(domain, mainDomain);
|
||||
} else if (planSetting.type === "http") {
|
||||
plan[domain] = await this.createHttpDomainVerifyPlan(planSetting.httpVerifyPlan[domain], domain, mainDomain);
|
||||
}
|
||||
plan[domain] = {
|
||||
domain,
|
||||
type: domainVerifyPlan.type,
|
||||
dnsProvider,
|
||||
cnameVerifyPlan,
|
||||
httpVerifyPlan,
|
||||
};
|
||||
}
|
||||
return plan;
|
||||
}
|
||||
|
||||
private async createDomainsVerifyPlanByAuto(domains: string[]) {
|
||||
//从数据库里面自动选择校验方式
|
||||
// domain list
|
||||
const domainList = new Set<string>();
|
||||
//整理域名
|
||||
for (let domain of domains) {
|
||||
domain = domain.replaceAll("*.", "");
|
||||
domainList.add(domain);
|
||||
}
|
||||
const domainVerifierGetter: IDomainVerifierGetter = await this.ctx.serviceGetter.get("domainVerifierGetter");
|
||||
|
||||
const verifiers: DomainVerifiers = await domainVerifierGetter.getVerifiers([...domainList]);
|
||||
|
||||
const plan: DomainsVerifyPlan = {};
|
||||
|
||||
for (const domain in verifiers) {
|
||||
const verifier = verifiers[domain];
|
||||
if (verifier == null) {
|
||||
throw new Error(`没有找到与该域名(${domain})匹配的校验方式,请先到‘域名管理’页面添加校验方式`);
|
||||
}
|
||||
if (verifier.type === "dns") {
|
||||
plan[domain] = await this.createDnsDomainVerifyPlan(verifier.dns, domain, verifier.mainDomain);
|
||||
} else if (verifier.type === "cname") {
|
||||
plan[domain] = await this.createCnameDomainVerifyPlan(domain, verifier.mainDomain);
|
||||
} else if (verifier.type === "http") {
|
||||
plan[domain] = await this.createHttpDomainVerifyPlan(verifier.http, domain, verifier.mainDomain);
|
||||
}
|
||||
}
|
||||
return plan;
|
||||
}
|
||||
|
||||
private async createDnsDomainVerifyPlan(planSetting: DnsVerifier, domain: string, mainDomain: string): Promise<DomainVerifyPlan> {
|
||||
const access = await this.getAccess(planSetting.dnsProviderAccessId);
|
||||
return {
|
||||
type: "dns",
|
||||
mainDomain,
|
||||
domain,
|
||||
dnsProvider: await this.createDnsProvider(planSetting.dnsProviderType, access),
|
||||
};
|
||||
}
|
||||
|
||||
private async createHttpDomainVerifyPlan(httpSetting: HttpVerifier, domain: string, mainDomain: string): Promise<DomainVerifyPlan> {
|
||||
const httpUploaderContext = {
|
||||
accessService: this.ctx.accessService,
|
||||
logger: this.logger,
|
||||
utils,
|
||||
};
|
||||
|
||||
const access = await this.getAccess(httpSetting.httpUploaderAccess);
|
||||
let rootDir = httpSetting.httpUploadRootDir;
|
||||
if (!rootDir.endsWith("/") && !rootDir.endsWith("\\")) {
|
||||
rootDir = rootDir + "/";
|
||||
}
|
||||
this.logger.info("上传方式", httpSetting.httpUploaderType);
|
||||
const httpUploader = await ossClientFactory.createOssClientByType(httpSetting.httpUploaderType, {
|
||||
access,
|
||||
rootDir: rootDir,
|
||||
ctx: httpUploaderContext,
|
||||
});
|
||||
return {
|
||||
type: "http",
|
||||
domain,
|
||||
mainDomain,
|
||||
httpVerifyPlan: {
|
||||
type: "http",
|
||||
domain,
|
||||
httpUploader,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
private async createCnameDomainVerifyPlan(domain: string, mainDomain: string): Promise<DomainVerifyPlan> {
|
||||
const cnameRecord = await this.ctx.cnameProxyService.getByDomain(domain);
|
||||
if (cnameRecord == null) {
|
||||
throw new Error(`请先配置${domain}的CNAME记录,并通过校验`);
|
||||
}
|
||||
let dnsProvider = cnameRecord.commonDnsProvider;
|
||||
if (cnameRecord.cnameProvider.id > 0) {
|
||||
dnsProvider = await this.createDnsProvider(cnameRecord.cnameProvider.dnsProviderType, cnameRecord.cnameProvider.access);
|
||||
}
|
||||
return {
|
||||
type: "cname",
|
||||
domain,
|
||||
mainDomain,
|
||||
cnameVerifyPlan: {
|
||||
domain: cnameRecord.cnameProvider.domain,
|
||||
fullRecord: cnameRecord.recordValue,
|
||||
dnsProvider,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
new CertApplyPlugin();
|
||||
|
|
|
@ -3,6 +3,14 @@
|
|||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-lib
|
||||
|
||||
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-lib
|
||||
|
||||
## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10)
|
||||
|
||||
### Bug Fixes
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@certd/plugin-lib",
|
||||
"private": false,
|
||||
"version": "1.36.4",
|
||||
"version": "1.36.6",
|
||||
"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.36.4",
|
||||
"@certd/pipeline": "^1.36.4",
|
||||
"@certd/basic": "^1.36.6",
|
||||
"@certd/pipeline": "^1.36.6",
|
||||
"@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": "0ff700849ff6427f79cce241f92257eca35af65d"
|
||||
"gitHead": "29d49d72f95aa101729965710375104240a2c038"
|
||||
}
|
||||
|
|
|
@ -491,7 +491,7 @@ export class SshClient {
|
|||
* Set-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Windows\System32\cmd.exe"
|
||||
* @param options
|
||||
*/
|
||||
async exec(options: { connectConf: SshAccess; script: string | Array<string>; env?: any; throwOnStdErr?: boolean }): Promise<string> {
|
||||
async exec(options: { connectConf: SshAccess; script: string | Array<string>; env?: any; throwOnStdErr?: boolean; stopOnError?: boolean }): Promise<string> {
|
||||
let { script } = options;
|
||||
const { connectConf, throwOnStdErr } = options;
|
||||
|
||||
|
@ -506,6 +506,10 @@ export class SshClient {
|
|||
isWinCmd = await this.isCmd(conn);
|
||||
}
|
||||
|
||||
if (isLinux && options.stopOnError !== false) {
|
||||
script = "set -e\n" + script;
|
||||
}
|
||||
|
||||
if (options.env) {
|
||||
for (const key in options.env) {
|
||||
if (isLinux) {
|
||||
|
@ -538,6 +542,7 @@ export class SshClient {
|
|||
script = envScripts.join(newLine) + newLine + script;
|
||||
}
|
||||
}
|
||||
|
||||
return await conn.exec(script as string, { throwOnStdErr });
|
||||
},
|
||||
});
|
||||
|
|
|
@ -3,6 +3,23 @@
|
|||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复某些页面翻译不全显示错误的bug ([0b3158f](https://github.com/certd/certd/commit/0b3158fdd5fe5bb0a98c4e65715dbc3de2c38047))
|
||||
* 修复运行流水线后会闪烁一下的bug ([dfc9362](https://github.com/certd/certd/commit/dfc9362084082ee535b898f23b2609c1d946a6fd))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 通知和定时器的删除按钮显示为红色更显眼 ([61ba83c](https://github.com/certd/certd/commit/61ba83c77546c3d505d081e19a3d68c127662bf1))
|
||||
* 优化流水线列表页面、详情页面性能,精简返回数据 ([609ac9c](https://github.com/certd/certd/commit/609ac9c9a2dde605eb09834ae59693c1cb238765))
|
||||
* OpenAPI支持autoApply参数 ([42f4d14](https://github.com/certd/certd/commit/42f4d1477dc791520a874aed56035abcbc8c433b))
|
||||
|
||||
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||
|
||||
**Note:** Version bump only for package @certd/ui-client
|
||||
|
||||
## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10)
|
||||
|
||||
### Bug Fixes
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@certd/ui-client",
|
||||
"version": "1.36.4",
|
||||
"version": "1.36.6",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite --open",
|
||||
|
@ -103,8 +103,8 @@
|
|||
"zod-defaults": "^0.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@certd/lib-iframe": "^1.36.4",
|
||||
"@certd/pipeline": "^1.36.4",
|
||||
"@certd/lib-iframe": "^1.36.6",
|
||||
"@certd/pipeline": "^1.36.6",
|
||||
"@rollup/plugin-commonjs": "^25.0.7",
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@types/chai": "^4.3.12",
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
import { Ref, ref, watch, nextTick } from "vue";
|
||||
import { HttpRecord } from "/@/components/plugins/cert/domains-verify-plan-editor/type";
|
||||
import { dict } from "@fast-crud/fast-crud";
|
||||
import { Dicts } from "/@/components/plugins/lib/dicts";
|
||||
|
||||
defineOptions({
|
||||
name: "HttpVerifyPlan",
|
||||
|
@ -68,17 +69,7 @@ async function onRecordChange() {
|
|||
emit("change", records.value);
|
||||
}
|
||||
|
||||
const uploaderTypeDict = dict({
|
||||
data: [
|
||||
{ label: "SFTP", value: "sftp" },
|
||||
{ label: "FTP", value: "ftp" },
|
||||
{ label: "阿里云OSS", value: "alioss" },
|
||||
{ label: "腾讯云COS", value: "tencentcos" },
|
||||
{ label: "七牛OSS", value: "qiniuoss" },
|
||||
{ label: "S3/Minio", value: "s3" },
|
||||
{ label: "SSH(已废弃,请选择SFTP方式)", value: "ssh", disabled: true },
|
||||
],
|
||||
});
|
||||
const uploaderTypeDict = Dicts.uploaderTypeDict;
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
import { dict } from "@fast-crud/fast-crud";
|
||||
|
||||
export const Dicts = {
|
||||
sslProviderDict: dict({
|
||||
data: [
|
||||
{ value: "letsencrypt", label: "Let‘s Encrypt" },
|
||||
{ value: "zerossl", label: "ZeroSSL" },
|
||||
],
|
||||
}),
|
||||
challengeTypeDict: dict({
|
||||
data: [
|
||||
{ value: "dns", label: "DNS校验", color: "green" },
|
||||
{ value: "cname", label: "CNAME代理校验", color: "blue" },
|
||||
{ value: "http", label: "HTTP校验", color: "yellow" },
|
||||
],
|
||||
}),
|
||||
dnsProviderTypeDict: dict({
|
||||
url: "pi/dnsProvider/dnsProviderTypeDict",
|
||||
}),
|
||||
uploaderTypeDict: dict({
|
||||
data: [
|
||||
{ label: "SFTP", value: "sftp" },
|
||||
{ label: "FTP", value: "ftp" },
|
||||
{ label: "阿里云OSS", value: "alioss" },
|
||||
{ label: "腾讯云COS", value: "tencentcos" },
|
||||
{ label: "七牛OSS", value: "qiniuoss" },
|
||||
{ label: "S3/Minio", value: "s3" },
|
||||
{ label: "SSH(已废弃,请选择SFTP方式)", value: "ssh", disabled: true },
|
||||
],
|
||||
}),
|
||||
};
|
|
@ -471,7 +471,7 @@ export default {
|
|||
statusError: "Error",
|
||||
actionImportBatch: "Batch Import",
|
||||
actionSyncIp: "Sync IP",
|
||||
TitleSyncIp: "Sync IP",
|
||||
modalTitleSyncIp: "Sync IP",
|
||||
modalContentSyncIp: "Are you sure to sync IP?",
|
||||
notificationSyncComplete: "Sync Complete",
|
||||
actionCheckAll: "Check All",
|
||||
|
@ -712,4 +712,18 @@ export default {
|
|||
close: "Close",
|
||||
viewCertificateTitle: "View Certificate",
|
||||
},
|
||||
domain: {
|
||||
domainManager: "Domain Manager",
|
||||
domainDescription: "used to auto apply for certificate", //管理域名的校验方式,用于申请证书时自动选择验证方式
|
||||
domain: "Domain",
|
||||
challengeType: "Challenge Type",
|
||||
dnsProviderType: "DNS Provider Type",
|
||||
dnsProviderAccess: "DNS Provider Access",
|
||||
httpUploaderType: "HTTP Uploader Type",
|
||||
httpUploaderAccess: "HTTP Uploader Access",
|
||||
httpUploadRootDir: "HTTP Upload Root Dir",
|
||||
disabled: "Disabled",
|
||||
challengeSetting: "Challenge Setting",
|
||||
gotoCnameTip: "Please go to CNAME Record Page",
|
||||
},
|
||||
};
|
||||
|
|
|
@ -14,6 +14,8 @@ export default {
|
|||
search: "Search",
|
||||
enabled: "Enabled",
|
||||
disabled: "Disabled",
|
||||
enable: "Enable",
|
||||
disable: "Disable",
|
||||
edit: "Edit",
|
||||
delete: "Delete",
|
||||
create: "Create",
|
||||
|
|
|
@ -715,4 +715,18 @@ export default {
|
|||
close: "关闭",
|
||||
viewCertificateTitle: "查看证书",
|
||||
},
|
||||
domain: {
|
||||
domainManager: "域名管理",
|
||||
domainDescription: "管理域名的校验方式,用于申请证书时自动选择验证方式",
|
||||
domain: "域名",
|
||||
challengeType: "校验类型",
|
||||
dnsProviderType: "DNS提供商类型",
|
||||
dnsProviderAccess: "DNS提供商授权",
|
||||
httpUploaderType: "上传方式",
|
||||
httpUploaderAccess: "上传授权信息",
|
||||
httpUploadRootDir: "网站根路径",
|
||||
disabled: "禁用/启用",
|
||||
challengeSetting: "校验配置",
|
||||
gotoCnameTip: "CNAME域名配置请前往CNAME记录页面添加",
|
||||
},
|
||||
};
|
||||
|
|
|
@ -14,6 +14,8 @@ export default {
|
|||
search: "搜索",
|
||||
enabled: "已启用",
|
||||
disabled: "已禁用",
|
||||
enable: "启用",
|
||||
disable: "禁用",
|
||||
edit: "修改",
|
||||
delete: "删除",
|
||||
create: "新增",
|
||||
|
|
|
@ -116,6 +116,17 @@ export const certdResources = [
|
|||
keepAlive: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "certd.domain.domainManager",
|
||||
name: "DomainManager",
|
||||
path: "/certd/cert/domain",
|
||||
component: "/certd/cert/domain/index.vue",
|
||||
meta: {
|
||||
icon: "ion:globe-outline",
|
||||
auth: true,
|
||||
keepAlive: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "certd.cnameRecord",
|
||||
name: "CnameRecord",
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import { ref } from "vue";
|
||||
import { getCommonColumnDefine } from "/@/views/certd/access/common";
|
||||
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
|
||||
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||
const { t } = useI18n();
|
||||
|
|
|
@ -55,6 +55,14 @@ export function createAccessApi(from = "user") {
|
|||
});
|
||||
},
|
||||
|
||||
async GetDictByIds(ids: number[]) {
|
||||
return await request({
|
||||
url: apiPrefix + "/getDictByIds",
|
||||
method: "post",
|
||||
data: { ids },
|
||||
});
|
||||
},
|
||||
|
||||
async GetSecretPlain(id: number, key: string) {
|
||||
return await request({
|
||||
url: apiPrefix + "/getSecretPlain",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// @ts-ignore
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
import { ref } from "vue";
|
||||
import { getCommonColumnDefine } from "/@/views/certd/access/common";
|
||||
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||
|
|
|
@ -15,7 +15,7 @@ import { defineComponent, onActivated, onMounted } from "vue";
|
|||
import { useFs } from "@fast-crud/fast-crud";
|
||||
import createCrudOptions from "./crud";
|
||||
import { createAccessApi } from "/@/views/certd/access/api";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
|
||||
export default defineComponent({
|
||||
name: "AccessManager",
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
import { request } from "/src/api/service";
|
||||
|
||||
const apiPrefix = "/cert/domain";
|
||||
|
||||
export async function GetList(query: any) {
|
||||
return await request({
|
||||
url: apiPrefix + "/page",
|
||||
method: "post",
|
||||
data: query,
|
||||
});
|
||||
}
|
||||
|
||||
export async function AddObj(obj: any) {
|
||||
return await request({
|
||||
url: apiPrefix + "/add",
|
||||
method: "post",
|
||||
data: obj,
|
||||
});
|
||||
}
|
||||
|
||||
export async function UpdateObj(obj: any) {
|
||||
return await request({
|
||||
url: apiPrefix + "/update",
|
||||
method: "post",
|
||||
data: obj,
|
||||
});
|
||||
}
|
||||
|
||||
export async function DelObj(id: any) {
|
||||
return await request({
|
||||
url: apiPrefix + "/delete",
|
||||
method: "post",
|
||||
params: { id },
|
||||
});
|
||||
}
|
||||
|
||||
export async function GetObj(id: any) {
|
||||
return await request({
|
||||
url: apiPrefix + "/info",
|
||||
method: "post",
|
||||
params: { id },
|
||||
});
|
||||
}
|
||||
|
||||
export async function GetDetail(id: any) {
|
||||
return await request({
|
||||
url: apiPrefix + "/detail",
|
||||
method: "post",
|
||||
params: { id },
|
||||
});
|
||||
}
|
||||
|
||||
export async function DeleteBatch(ids: any[]) {
|
||||
return await request({
|
||||
url: apiPrefix + "/deleteByIds",
|
||||
method: "post",
|
||||
data: { ids },
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,330 @@
|
|||
import * as api from "./api";
|
||||
import { useI18n } from "/src/locales";
|
||||
import { Ref, ref } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||
import { useUserStore } from "/@/store/user";
|
||||
import { useSettingStore } from "/@/store/settings";
|
||||
import { Dicts } from "/@/components/plugins/lib/dicts";
|
||||
import { createAccessApi } from "/@/views/certd/access/api";
|
||||
import { Modal } from "ant-design-vue";
|
||||
|
||||
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||
const router = useRouter();
|
||||
const { t } = useI18n();
|
||||
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
||||
return await api.GetList(query);
|
||||
};
|
||||
const editRequest = async ({ form, row }: EditReq) => {
|
||||
form.id = row.id;
|
||||
const res = await api.UpdateObj(form);
|
||||
return res;
|
||||
};
|
||||
const delRequest = async ({ row }: DelReq) => {
|
||||
return await api.DelObj(row.id);
|
||||
};
|
||||
|
||||
const addRequest = async ({ form }: AddReq) => {
|
||||
const res = await api.AddObj(form);
|
||||
return res;
|
||||
};
|
||||
|
||||
const userStore = useUserStore();
|
||||
const settingStore = useSettingStore();
|
||||
const selectedRowKeys: Ref<any[]> = ref([]);
|
||||
context.selectedRowKeys = selectedRowKeys;
|
||||
|
||||
const accessApi = createAccessApi();
|
||||
const accessDict = dict({
|
||||
value: "id",
|
||||
label: "name",
|
||||
url: "accessDict",
|
||||
async getNodesByValues(ids: number[]) {
|
||||
return await accessApi.GetDictByIds(ids);
|
||||
},
|
||||
});
|
||||
|
||||
const httpUploaderTypeDict = Dicts.uploaderTypeDict;
|
||||
|
||||
const dnsProviderTypeDict = dict({
|
||||
url: "pi/dnsProvider/dnsProviderTypeDict",
|
||||
});
|
||||
return {
|
||||
crudOptions: {
|
||||
settings: {
|
||||
plugins: {
|
||||
//这里使用行选择插件,生成行选择crudOptions配置,最终会与crudOptions合并
|
||||
rowSelection: {
|
||||
enabled: true,
|
||||
order: -2,
|
||||
before: true,
|
||||
// handle: (pluginProps,useCrudProps)=>CrudOptions,
|
||||
props: {
|
||||
multiple: true,
|
||||
crossPage: true,
|
||||
selectedRowKeys,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
request: {
|
||||
pageRequest,
|
||||
addRequest,
|
||||
editRequest,
|
||||
delRequest,
|
||||
},
|
||||
tabs: {
|
||||
name: "challengeType",
|
||||
show: true,
|
||||
},
|
||||
rowHandle: {
|
||||
minWidth: 200,
|
||||
fixed: "right",
|
||||
},
|
||||
form: {
|
||||
beforeSubmit({ form }) {
|
||||
if (form.challengeType === "cname") {
|
||||
throw new Error("CNAME方式请前往CNAME记录页面进行管理");
|
||||
}
|
||||
},
|
||||
},
|
||||
columns: {
|
||||
id: {
|
||||
title: "ID",
|
||||
key: "id",
|
||||
type: "number",
|
||||
column: {
|
||||
width: 80,
|
||||
},
|
||||
form: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
domain: {
|
||||
title: t("certd.domain.domain"),
|
||||
type: "text",
|
||||
search: {
|
||||
show: true,
|
||||
},
|
||||
form: {
|
||||
required: true,
|
||||
},
|
||||
editForm: {
|
||||
component: {
|
||||
disabled: false,
|
||||
},
|
||||
},
|
||||
column: {
|
||||
sorter: true,
|
||||
},
|
||||
},
|
||||
challengeType: {
|
||||
title: t("certd.domain.challengeType"),
|
||||
type: "dict-select",
|
||||
dict: Dicts.challengeTypeDict,
|
||||
search: {
|
||||
show: true,
|
||||
},
|
||||
form: {
|
||||
required: true,
|
||||
valueChange({ value }) {
|
||||
if (value === "cname") {
|
||||
Modal.confirm({
|
||||
title: t("certd.domain.gotoCnameTip"),
|
||||
async onOk() {
|
||||
router.push({
|
||||
path: "/certd/cname/record",
|
||||
});
|
||||
crudExpose.getFormWrapperRef().close();
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
column: {
|
||||
sorter: true,
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
/**
|
||||
* challengeType varchar(50),
|
||||
* dnsProviderType varchar(50),
|
||||
* dnsProviderAccess bigint,
|
||||
* httpUploaderType varchar(50),
|
||||
* httpUploaderAccess bigint,
|
||||
* httpUploadRootDir varchar(512),
|
||||
*/
|
||||
dnsProviderType: {
|
||||
title: t("certd.domain.dnsProviderType"),
|
||||
type: "dict-select",
|
||||
dict: dnsProviderTypeDict,
|
||||
form: {
|
||||
component: {
|
||||
name: "DnsProviderSelector",
|
||||
},
|
||||
show: compute(({ form }) => {
|
||||
return form.challengeType === "dns";
|
||||
}),
|
||||
required: true,
|
||||
},
|
||||
column: {
|
||||
show: false,
|
||||
component: {
|
||||
color: "auto",
|
||||
},
|
||||
},
|
||||
},
|
||||
dnsProviderAccess: {
|
||||
title: t("certd.domain.dnsProviderAccess"),
|
||||
type: "dict-select",
|
||||
dict: accessDict,
|
||||
form: {
|
||||
component: {
|
||||
name: "AccessSelector",
|
||||
vModel: "modelValue",
|
||||
type: compute(({ form }) => {
|
||||
return form.dnsProviderType;
|
||||
}),
|
||||
},
|
||||
show: compute(({ form }) => {
|
||||
return form.challengeType === "dns";
|
||||
}),
|
||||
required: true,
|
||||
},
|
||||
column: {
|
||||
show: false,
|
||||
component: {
|
||||
color: "auto",
|
||||
},
|
||||
},
|
||||
},
|
||||
httpUploaderType: {
|
||||
title: t("certd.domain.httpUploaderType"),
|
||||
type: "dict-select",
|
||||
dict: Dicts.uploaderTypeDict,
|
||||
form: {
|
||||
show: compute(({ form }) => {
|
||||
return form.challengeType === "http";
|
||||
}),
|
||||
required: true,
|
||||
},
|
||||
column: {
|
||||
show: false,
|
||||
component: {
|
||||
color: "auto",
|
||||
},
|
||||
},
|
||||
},
|
||||
httpUploaderAccess: {
|
||||
title: t("certd.domain.httpUploaderAccess"),
|
||||
type: "text",
|
||||
form: {
|
||||
component: {
|
||||
name: "AccessSelector",
|
||||
vModel: "modelValue",
|
||||
type: compute(({ form }) => {
|
||||
return form.httpUploaderType;
|
||||
}),
|
||||
},
|
||||
show: compute(({ form }) => {
|
||||
return form.challengeType === "http";
|
||||
}),
|
||||
required: true,
|
||||
},
|
||||
column: {
|
||||
show: false,
|
||||
component: {
|
||||
color: "auto",
|
||||
},
|
||||
},
|
||||
},
|
||||
httpUploadRootDir: {
|
||||
title: t("certd.domain.httpUploadRootDir"),
|
||||
type: "text",
|
||||
form: {
|
||||
show: compute(({ form }) => {
|
||||
return form.challengeType === "http";
|
||||
}),
|
||||
required: true,
|
||||
},
|
||||
column: {
|
||||
show: false,
|
||||
component: {
|
||||
color: "auto",
|
||||
},
|
||||
},
|
||||
},
|
||||
challengeSetting: {
|
||||
title: t("certd.domain.challengeSetting"),
|
||||
type: "text",
|
||||
form: { show: false },
|
||||
column: {
|
||||
width: 600,
|
||||
conditionalRender: false,
|
||||
cellRender({ row }) {
|
||||
if (row.challengeType === "dns") {
|
||||
return (
|
||||
<div class={"flex"}>
|
||||
<fs-values-format modelValue={row.challengeType} dict={Dicts.challengeTypeDict} color={"auto"}></fs-values-format>
|
||||
<fs-values-format modelValue={row.dnsProviderType} dict={dnsProviderTypeDict} color={"auto"}></fs-values-format>
|
||||
<fs-values-format class={"ml-5"} modelValue={row.dnsProviderAccess} dict={accessDict} color={"auto"}></fs-values-format>
|
||||
</div>
|
||||
);
|
||||
} else if (row.challengeType === "http") {
|
||||
return (
|
||||
<div class={"flex"}>
|
||||
<fs-values-format modelValue={row.challengeType} dict={Dicts.challengeTypeDict} color={"auto"}></fs-values-format>
|
||||
<fs-values-format modelValue={row.httpUploaderType} dict={httpUploaderTypeDict} color={"auto"}></fs-values-format>
|
||||
<fs-values-format class={"ml-5"} modelValue={row.httpUploaderAccess} dict={accessDict} color={"auto"}></fs-values-format>
|
||||
<a-tag class={"ml-5 flex items-center"}>路径:{row.httpUploadRootDir}</a-tag>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
disabled: {
|
||||
title: t("certd.domain.disabled"),
|
||||
type: "dict-switch",
|
||||
search: { show: true },
|
||||
dict: dict({
|
||||
data: [
|
||||
{ label: t("common.enabled"), value: false, color: "green" },
|
||||
{ label: t("common.disabled"), value: true, color: "red" },
|
||||
],
|
||||
}),
|
||||
form: {
|
||||
value: false,
|
||||
required: true,
|
||||
},
|
||||
column: {
|
||||
width: 100,
|
||||
sorter: true,
|
||||
},
|
||||
},
|
||||
createTime: {
|
||||
title: t("certd.createTime"),
|
||||
type: "datetime",
|
||||
form: {
|
||||
show: false,
|
||||
},
|
||||
column: {
|
||||
sorter: true,
|
||||
width: 160,
|
||||
align: "center",
|
||||
},
|
||||
},
|
||||
updateTime: {
|
||||
title: t("certd.updateTime"),
|
||||
type: "datetime",
|
||||
form: {
|
||||
show: false,
|
||||
},
|
||||
column: {
|
||||
show: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
<template>
|
||||
<fs-page class="page-cert">
|
||||
<template #header>
|
||||
<div class="title">
|
||||
{{ t("certd.domain.domainManager") }}
|
||||
<span class="sub">
|
||||
{{ t("certd.domain.domainDescription") }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<fs-crud ref="crudRef" v-bind="crudBinding">
|
||||
<template #pagination-left>
|
||||
<a-tooltip :title="t('certd.batch_delete')">
|
||||
<fs-button icon="DeleteOutlined" @click="handleBatchDelete"></fs-button>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
</fs-crud>
|
||||
</fs-page>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onActivated, onMounted } from "vue";
|
||||
import { useFs } from "@fast-crud/fast-crud";
|
||||
import createCrudOptions from "./crud";
|
||||
import { message, Modal } from "ant-design-vue";
|
||||
import { DeleteBatch } from "./api";
|
||||
import { useI18n } from "/src/locales";
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
defineOptions({
|
||||
name: "DomainManager",
|
||||
});
|
||||
const { crudBinding, crudRef, crudExpose, context } = useFs({ createCrudOptions });
|
||||
|
||||
const selectedRowKeys = context.selectedRowKeys;
|
||||
const handleBatchDelete = () => {
|
||||
if (selectedRowKeys.value?.length > 0) {
|
||||
Modal.confirm({
|
||||
title: t("certd.confirm"),
|
||||
content: t("certd.confirm_delete_count", { count: selectedRowKeys.value.length }),
|
||||
async onOk() {
|
||||
await DeleteBatch(selectedRowKeys.value);
|
||||
message.info(t("certd.delete_successful"));
|
||||
crudExpose.doRefresh();
|
||||
selectedRowKeys.value = [];
|
||||
},
|
||||
});
|
||||
} else {
|
||||
message.error(t("certd.please_select_records"));
|
||||
}
|
||||
};
|
||||
|
||||
// 页面打开后获取列表数据
|
||||
onMounted(() => {
|
||||
crudExpose.doRefresh();
|
||||
});
|
||||
onActivated(async () => {
|
||||
await crudExpose.doRefresh();
|
||||
});
|
||||
</script>
|
||||
<style lang="less"></style>
|
|
@ -1,5 +1,5 @@
|
|||
import * as api from "./api";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
import { Ref, ref } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||
|
|
|
@ -26,7 +26,7 @@ import { useFs } from "@fast-crud/fast-crud";
|
|||
import createCrudOptions from "./crud";
|
||||
import { message, Modal } from "ant-design-vue";
|
||||
import { DeleteBatch } from "./api";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as api from "./api";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
import { computed, Ref, ref } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes, utils } from "@fast-crud/fast-crud";
|
||||
|
|
|
@ -19,7 +19,7 @@ import { useFs } from "@fast-crud/fast-crud";
|
|||
import createCrudOptions from "./crud";
|
||||
import { message, Modal } from "ant-design-vue";
|
||||
import { DeleteBatch } from "./api";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
|
||||
const { t } = useI18n();
|
||||
import { CrudOptions, useColumns, useFormWrapper } from "@fast-crud/fast-crud";
|
||||
|
|
|
@ -79,7 +79,7 @@ import { UserTwoFactorSetting } from "./api";
|
|||
import { Modal, notification } from "ant-design-vue";
|
||||
import { merge } from "lodash-es";
|
||||
import { useSettingStore } from "/@/store/settings";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
|
||||
const { t } = useI18n();
|
||||
const settingsStore = useSettingStore();
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
import * as api from "./api";
|
||||
import { Ref, ref } from "vue";
|
||||
import ChangePasswordButton from "/@/views/certd/mine/change-password-button.vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
import { useUserProfile } from "./use";
|
||||
|
||||
const { t } = useI18n();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// @ts-ignore
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
//
|
||||
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, useFormWrapper, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||
import { certInfoApi } from "./api";
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
import { onActivated, onMounted } from "vue";
|
||||
import { useFs } from "@fast-crud/fast-crud";
|
||||
import createCrudOptions from "./crud";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// @ts-ignore
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
import { AddReq, ColumnCompositionProps, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||
import { siteInfoApi } from "./api";
|
||||
import dayjs from "dayjs";
|
||||
|
@ -46,6 +46,20 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||
|
||||
const { openSiteIpMonitorDialog } = useSiteIpMonitor();
|
||||
const { openSiteImportDialog } = useSiteImport();
|
||||
|
||||
function checkAll() {
|
||||
Modal.confirm({
|
||||
title: t("certd.monitor.confirmTitle"), // "确认"
|
||||
content: t("certd.monitor.confirmContent"), // "确认触发检查全部站点证书吗?"
|
||||
onOk: async () => {
|
||||
await siteInfoApi.CheckAll();
|
||||
notification.success({
|
||||
message: t("certd.monitor.checkSubmitted"), // "检查任务已提交"
|
||||
description: t("certd.monitor.pleaseRefresh"), // "请稍后刷新页面查看结果"
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
return {
|
||||
id: "siteMonitorCrud",
|
||||
crudOptions: {
|
||||
|
@ -114,6 +128,14 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||
});
|
||||
},
|
||||
},
|
||||
checkAll: {
|
||||
show: true,
|
||||
text: t("certd.monitor.checkAll"),
|
||||
type: "primary",
|
||||
click() {
|
||||
checkAll();
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
rowHandle: {
|
||||
|
|
|
@ -14,9 +14,6 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="more">
|
||||
<a-button type="primary" @click="checkAll">{{ t("certd.monitor.checkAll") }}</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<fs-crud ref="crudRef" v-bind="crudBinding"> </fs-crud>
|
||||
</fs-page>
|
||||
|
@ -28,26 +25,13 @@ import { useFs } from "@fast-crud/fast-crud";
|
|||
import createCrudOptions from "./crud";
|
||||
import { siteInfoApi } from "./api";
|
||||
import { Modal, notification } from "ant-design-vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
|
||||
const { t } = useI18n();
|
||||
defineOptions({
|
||||
name: "SiteCertMonitor",
|
||||
});
|
||||
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: {} });
|
||||
function checkAll() {
|
||||
Modal.confirm({
|
||||
title: t("certd.monitor.confirmTitle"), // "确认"
|
||||
content: t("certd.monitor.confirmContent"), // "确认触发检查全部站点证书吗?"
|
||||
onOk: async () => {
|
||||
await siteInfoApi.CheckAll();
|
||||
notification.success({
|
||||
message: t("certd.monitor.checkSubmitted"), // "检查任务已提交"
|
||||
description: t("certd.monitor.pleaseRefresh"), // "请稍后刷新页面查看结果"
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// 页面打开后获取列表数据
|
||||
onMounted(() => {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// @ts-ignore
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||
import { siteIpApi } from "./api";
|
||||
import dayjs from "dayjs";
|
||||
|
|
|
@ -47,7 +47,7 @@ import { merge } from "lodash-es";
|
|||
import { useSettingStore } from "/src/store/settings";
|
||||
import NotificationSelector from "/@/views/certd/notification/notification-selector/index.vue";
|
||||
import { useUserStore } from "/@/store/user";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { useFormWrapper } from "@fast-crud/fast-crud";
|
||||
import { siteInfoApi } from "./api";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
|
||||
export function useSiteImport() {
|
||||
const { t } = useI18n();
|
||||
|
|
|
@ -41,7 +41,7 @@ import { dict } from "@fast-crud/fast-crud";
|
|||
import createCrudOptions from "../crud";
|
||||
import { notificationProvide } from "/@/views/certd/notification/common";
|
||||
import { useUserStore } from "/@/store/user";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// @ts-ignore
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||
import { OPEN_API_DOC, openkeyApi } from "./api";
|
||||
import { useModal } from "/@/use/use-modal";
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
import { dict } from "@fast-crud/fast-crud";
|
||||
|
||||
export const Dicts = {
|
||||
sslProviderDict: dict({
|
||||
data: [
|
||||
{ value: "letsencrypt", label: "Let‘s Encrypt" },
|
||||
{ value: "zerossl", label: "ZeroSSL" },
|
||||
],
|
||||
}),
|
||||
challengeTypeDict: dict({ data: [{ value: "dns", label: "DNS校验" }] }),
|
||||
dnsProviderTypeDict: dict({
|
||||
url: "pi/dnsProvider/dnsProviderTypeDict",
|
||||
}),
|
||||
};
|
|
@ -125,6 +125,7 @@ export function useCertPipelineCreator() {
|
|||
const pluginStore = usePluginStore();
|
||||
const randomHour = Math.floor(Math.random() * 6);
|
||||
const randomMin = Math.floor(Math.random() * 60);
|
||||
const randomCron = `0 ${randomMin} ${randomHour} * * *`;
|
||||
|
||||
const groupDictRef = dict({
|
||||
url: "/pi/pipeline/group/all",
|
||||
|
@ -193,7 +194,7 @@ export function useCertPipelineCreator() {
|
|||
title: t("certd.pipelineForm.triggerCronTitle"),
|
||||
type: "text",
|
||||
form: {
|
||||
value: `0 ${randomMin} ${randomHour} * * *`,
|
||||
value: randomCron,
|
||||
component: {
|
||||
name: "cron-editor",
|
||||
vModel: "modelValue",
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<script setup lang="ts">
|
||||
import * as api from "../api";
|
||||
import { useFormWrapper } from "@fast-crud/fast-crud";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
|
|
@ -335,7 +335,7 @@ export default function ({ crudExpose, context: { groupDictRef, selectedRowKeys
|
|||
}
|
||||
},
|
||||
},
|
||||
_triggerCount: {
|
||||
triggerCount: {
|
||||
title: t("certd.fields.scheduledTaskCount"),
|
||||
type: "number",
|
||||
column: {
|
||||
|
@ -346,7 +346,7 @@ export default function ({ crudExpose, context: { groupDictRef, selectedRowKeys
|
|||
show: false,
|
||||
},
|
||||
},
|
||||
_stepCount: {
|
||||
stepCount: {
|
||||
title: t("certd.fields.deployTaskCount"),
|
||||
type: "number",
|
||||
form: { show: false },
|
||||
|
|
|
@ -31,7 +31,7 @@ import ChangeGroup from "./components/change-group.vue";
|
|||
import ChangeTrigger from "./components/change-trigger.vue";
|
||||
import { Modal, notification } from "ant-design-vue";
|
||||
import * as api from "./api";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
|
||||
const { t } = useI18n();
|
||||
import ChangeNotification from "/@/views/certd/pipeline/components/change-notification.vue";
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<fs-icon v-bind="status" :color="status.iconColor || status.color" />
|
||||
</template>
|
||||
<p>
|
||||
<fs-date-format :model-value="runnable.status?.startTime"></fs-date-format>
|
||||
<fs-date-format :model-value="runnable.createTime"></fs-date-format>
|
||||
<a-tag class="ml-5" :color="status.color" :closable="status.value === 'start'" @close="cancelTask">
|
||||
{{ status.label }}
|
||||
</a-tag>
|
||||
|
@ -46,7 +46,7 @@ export default defineComponent({
|
|||
emits: ["view", "cancel"],
|
||||
setup(props: any, ctx: any) {
|
||||
const status = computed(() => {
|
||||
return statusUtil.get(props.runnable?.status?.result);
|
||||
return statusUtil.get(props.runnable?.status);
|
||||
});
|
||||
|
||||
function view() {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<template #title>
|
||||
<div>
|
||||
{{ t("certd.edit_notification") }}
|
||||
<a-button v-if="mode === 'edit'" @click="notificationDelete()">
|
||||
<a-button v-if="mode === 'edit'" danger @click="notificationDelete()">
|
||||
<template #icon>
|
||||
<DeleteOutlined />
|
||||
</template>
|
||||
|
@ -90,7 +90,7 @@ import * as _ from "lodash-es";
|
|||
import { nanoid } from "nanoid";
|
||||
import PiNotificationFormEmail from "./pi-notification-form-email.vue";
|
||||
import NotificationSelector from "/@/views/certd/notification/notification-selector/index.vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
import { cloneDeep } from "lodash-es";
|
||||
|
||||
const { t } = useI18n();
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
import { Ref, ref, watch } from "vue";
|
||||
import { useUserStore } from "/@/store/user";
|
||||
import { useSettingStore } from "/@/store/settings";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<template #title>
|
||||
<div>
|
||||
编辑任务
|
||||
<a-button v-if="editMode" @click="taskDelete()">
|
||||
<a-button v-if="editMode" danger @click="taskDelete()">
|
||||
<template #icon><DeleteOutlined /></template>
|
||||
</a-button>
|
||||
</div>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<template #title>
|
||||
<div>
|
||||
{{ t("certd.editTrigger") }}
|
||||
<a-button v-if="mode === 'edit'" @click="triggerDelete()">
|
||||
<a-button v-if="mode === 'edit'" danger @click="triggerDelete()">
|
||||
<template #icon>
|
||||
<DeleteOutlined />
|
||||
</template>
|
||||
|
|
|
@ -258,7 +258,7 @@
|
|||
<a-timeline class="mt-10">
|
||||
<template v-for="item of histories" :key="item.id">
|
||||
<pi-history-timeline-item
|
||||
:runnable="item.pipeline"
|
||||
:runnable="item"
|
||||
:history-id="item.id"
|
||||
:is-current="currentHistory?.id === item.id"
|
||||
:edit-mode="editMode"
|
||||
|
@ -280,7 +280,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, onMounted, onUnmounted, provide, Ref, ref, watch, computed } from "vue";
|
||||
import { computed, defineComponent, onMounted, onUnmounted, provide, ref, Ref, watch } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import PiTaskForm from "./component/task-form/index.vue";
|
||||
import PiTriggerForm from "./component/trigger-form/index.vue";
|
||||
|
@ -288,7 +288,7 @@ import PiNotificationForm from "./component/notification-form/index.vue";
|
|||
import PiTaskView from "./component/task-view/index.vue";
|
||||
import PiStatusShow from "./component/status-show.vue";
|
||||
import VDraggable from "vuedraggable";
|
||||
import * as _ from "lodash-es";
|
||||
import { cloneDeep, merge, remove } from "lodash-es";
|
||||
import { message, Modal, notification } from "ant-design-vue";
|
||||
import { nanoid } from "nanoid";
|
||||
import { PipelineDetail, PipelineOptions, RunHistory } from "./type";
|
||||
|
@ -299,9 +299,10 @@ import { useSettingStore } from "/@/store/settings";
|
|||
import { useUserStore } from "/@/store/user";
|
||||
import TaskShortcuts from "./component/shortcut/task-shortcuts.vue";
|
||||
import { eachSteps, findStep } from "../utils";
|
||||
import { PluginGroups, usePluginStore } from "/@/store/plugin";
|
||||
import { usePluginStore } from "/@/store/plugin";
|
||||
import { getCronNextTimes } from "/@/components/cron-editor/utils";
|
||||
import { useCertViewer } from "/@/views/certd/pipeline/use";
|
||||
import { useI18n } from "/@/locales";
|
||||
|
||||
export default defineComponent({
|
||||
name: "PipelineEdit",
|
||||
|
@ -339,6 +340,7 @@ export default defineComponent({
|
|||
},
|
||||
emits: ["update:modelValue", "update:editMode"],
|
||||
setup(props, ctx) {
|
||||
const { t } = useI18n();
|
||||
const currentPipeline: Ref<any> = ref({});
|
||||
const pipeline: Ref<any> = ref({});
|
||||
|
||||
|
@ -371,18 +373,19 @@ export default defineComponent({
|
|||
const loadCurrentHistoryDetail = async () => {
|
||||
const detail: RunHistory = await props.options?.getHistoryDetail({ historyId: currentHistory.value.id });
|
||||
currentHistory.value.logs = detail.logs;
|
||||
_.merge(currentHistory.value.pipeline, detail.pipeline);
|
||||
currentHistory.value.pipeline = detail.pipeline;
|
||||
};
|
||||
const changeCurrentHistory = async (history?: RunHistory) => {
|
||||
if (!history) {
|
||||
//取消历史记录查看模式
|
||||
currentHistory.value = null;
|
||||
pipeline.value = currentPipeline.value;
|
||||
pipeline.value = cloneDeep(currentPipeline.value);
|
||||
return;
|
||||
}
|
||||
currentHistory.value = history;
|
||||
pipeline.value = history.pipeline;
|
||||
await loadCurrentHistoryDetail();
|
||||
pipeline.value = currentHistory.value.pipeline;
|
||||
currentPipeline.value = cloneDeep(pipeline.value);
|
||||
};
|
||||
|
||||
async function loadHistoryList(reload = false) {
|
||||
|
@ -413,7 +416,8 @@ export default defineComponent({
|
|||
return true;
|
||||
}
|
||||
}
|
||||
if (historyList[0].pipeline?.version === pipeline.value.version) {
|
||||
//@ts-ignore
|
||||
if (historyList[0]?.version === pipeline.value.version) {
|
||||
await changeCurrentHistory(historyList[0]);
|
||||
}
|
||||
}
|
||||
|
@ -477,7 +481,7 @@ export default defineComponent({
|
|||
return;
|
||||
}
|
||||
const detail: PipelineDetail = await props.options.getPipelineDetail({ pipelineId: value });
|
||||
currentPipeline.value = _.merge(
|
||||
currentPipeline.value = merge(
|
||||
{
|
||||
title: "新管道流程",
|
||||
stages: [],
|
||||
|
@ -540,7 +544,7 @@ export default defineComponent({
|
|||
};
|
||||
|
||||
const taskCopy = (stage: any, stageIndex: number, task: any) => {
|
||||
task = _.cloneDeep(task);
|
||||
task = cloneDeep(task);
|
||||
task.id = nanoid();
|
||||
task.title = task.title + "_copy";
|
||||
for (const step of task.steps) {
|
||||
|
@ -560,7 +564,7 @@ export default defineComponent({
|
|||
if (type === "delete") {
|
||||
stage.tasks.splice(taskIndex, 1);
|
||||
if (stage.tasks.length === 0) {
|
||||
_.remove(pipeline.value.stages, (item: Runnable) => {
|
||||
remove(pipeline.value.stages, (item: Runnable) => {
|
||||
return item.id === stage.id;
|
||||
});
|
||||
}
|
||||
|
@ -666,9 +670,19 @@ export default defineComponent({
|
|||
notificationFormRef.value.notificationView(notification, (type: string, value: any) => {});
|
||||
}
|
||||
};
|
||||
const notificationDelete = (notification: any, index: any) => {
|
||||
Modal.confirm({
|
||||
title: t("certd.confirm"),
|
||||
content: t("certd.confirm_delete_trigger"),
|
||||
async onOk() {
|
||||
pipeline.value.notifications.splice(index, 1);
|
||||
},
|
||||
});
|
||||
};
|
||||
return {
|
||||
notificationAdd,
|
||||
notificationEdit,
|
||||
notificationDelete,
|
||||
notificationFormRef,
|
||||
};
|
||||
}
|
||||
|
@ -788,7 +802,7 @@ export default defineComponent({
|
|||
currentPipeline.value = pipeline.value;
|
||||
|
||||
//移除空阶段
|
||||
_.remove(pipeline.value.stages, (item: Stage) => {
|
||||
remove(pipeline.value.stages, (item: Stage) => {
|
||||
return item.tasks.length === 0;
|
||||
});
|
||||
|
||||
|
@ -802,12 +816,12 @@ export default defineComponent({
|
|||
}
|
||||
};
|
||||
const edit = () => {
|
||||
pipeline.value = _.cloneDeep(currentPipeline.value);
|
||||
pipeline.value = cloneDeep(currentPipeline.value);
|
||||
currentHistory.value = null;
|
||||
toggleEditMode(true);
|
||||
};
|
||||
const cancel = () => {
|
||||
pipeline.value = currentPipeline.value;
|
||||
pipeline.value = cloneDeep(currentPipeline.value);
|
||||
toggleEditMode(false);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import * as api from "./api";
|
||||
import { Ref, ref } from "vue";
|
||||
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
|
||||
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||
const { t } = useI18n();
|
||||
|
|
|
@ -22,7 +22,7 @@ import { useFs } from "@fast-crud/fast-crud";
|
|||
import createCrudOptions from "./crud";
|
||||
import { message, Modal } from "ant-design-vue";
|
||||
import { DeleteBatch } from "./api";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
import { onActivated, onMounted } from "vue";
|
||||
import { useFs } from "@fast-crud/fast-crud";
|
||||
import createCrudOptions from "./crud";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
defineOptions({
|
||||
name: "PipelineTemplate",
|
||||
});
|
||||
|
|
|
@ -1,33 +1,33 @@
|
|||
<template>
|
||||
<a-modal v-model:open="openRef" class="order-modal" :title="$t('order.confirmTitle')" @ok="orderCreate">
|
||||
<a-modal v-model:open="openRef" class="order-modal" :title="$t('certd.order.confirmTitle')" @ok="orderCreate">
|
||||
<div v-if="product" class="order-box">
|
||||
<div class="flex-o mt-5">
|
||||
<span class="label">{{ $t("order.package") }}:</span>{{ product.title }}
|
||||
<span class="label">{{ $t("certd.order.package") }}:</span>{{ product.title }}
|
||||
</div>
|
||||
<div class="flex-o mt-5">
|
||||
<span class="label">{{ $t("order.description") }}:</span>{{ product.intro }}
|
||||
<span class="label">{{ $t("certd.order.description") }}:</span>{{ product.intro }}
|
||||
</div>
|
||||
<div class="flex-o mt-5">
|
||||
<span class="label">{{ $t("order.specifications") }}:</span>
|
||||
<span class="label">{{ $t("certd.order.specifications") }}:</span>
|
||||
<span class="flex-o flex-wrap">
|
||||
<span class="flex-o"> {{ $t("order.pipeline") }}<suite-value class="ml-5" :model-value="product.content.maxPipelineCount" unit="{{$t('order.unit.pieces')}}" />; </span>
|
||||
<span class="flex-o"> {{ $t("order.domain") }}<suite-value class="ml-5" :model-value="product.content.maxDomainCount" unit="{{$t('order.unit.count')}}" />; </span>
|
||||
<span class="flex-o"> {{ $t("order.deployTimes") }}<suite-value class="ml-5" :model-value="product.content.maxDeployCount" unit="{{$t('order.unit.times')}}" />; </span>
|
||||
<span class="flex-o"> {{ $t("certd.order.pipeline") }}<suite-value class="ml-5" :model-value="product.content.maxPipelineCount" :unit="$t('certd.order.unit.pieces')" />; </span>
|
||||
<span class="flex-o"> {{ $t("certd.order.domain") }}<suite-value class="ml-5" :model-value="product.content.maxDomainCount" :unit="$t('certd.order.unit.count')" />; </span>
|
||||
<span class="flex-o"> {{ $t("certd.order.deployTimes") }}<suite-value class="ml-5" :model-value="product.content.maxDeployCount" :unit="$t('certd.order.unit.times')" />; </span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="flex-o mt-5">
|
||||
<span class="label">{{ $t("order.duration") }}:</span>
|
||||
<span class="label">{{ $t("certd.order.duration") }}:</span>
|
||||
<duration-value v-model="formRef.duration"></duration-value>
|
||||
</div>
|
||||
<div class="flex-o mt-5">
|
||||
<span class="label">{{ $t("order.price") }}:</span>
|
||||
<span class="label">{{ $t("certd.order.price") }}:</span>
|
||||
<price-input :edit="false" :model-value="durationSelected.price"></price-input>
|
||||
</div>
|
||||
|
||||
<div class="flex-o mt-5">
|
||||
<span class="label">{{ $t("order.paymentMethod") }}:</span>
|
||||
<div v-if="durationSelected.price === 0">{{ $t("order.free") }}</div>
|
||||
<span class="label">{{ $t("certd.order.paymentMethod") }}:</span>
|
||||
<div v-if="durationSelected.price === 0">{{ $t("certd.order.free") }}</div>
|
||||
<fs-dict-select v-else v-model:value="formRef.payType" :dict="paymentsDictRef" style="width: 200px"> </fs-dict-select>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as api from "./api";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
import { computed, Ref, ref } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes, utils } from "@fast-crud/fast-crud";
|
||||
|
|
|
@ -149,7 +149,7 @@ import { UserInfoRes } from "/@/store/user/api.user";
|
|||
import { GetStatisticCount } from "/@/views/framework/home/dashboard/api";
|
||||
import { useRouter } from "vue-router";
|
||||
import * as api from "./api";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
const { t } = useI18n();
|
||||
import { usePluginStore } from "/@/store/plugin";
|
||||
defineOptions({
|
||||
|
@ -214,6 +214,7 @@ function transformStatusCount() {
|
|||
{ name: "error", label: "失败" },
|
||||
{ name: "canceled", label: "已取消" },
|
||||
{ name: null, label: "未执行" },
|
||||
{ name: "skip", label: "跳过" },
|
||||
];
|
||||
const result = [];
|
||||
for (const item of sorted) {
|
||||
|
|
|
@ -43,7 +43,7 @@ const slots = defineSlots();
|
|||
.data-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 180px;
|
||||
height: 188px;
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
|
|
@ -12,7 +12,7 @@ import { useUserStore } from "/@/store/user";
|
|||
import ChangePasswordButton from "/@/views/certd/mine/change-password-button.vue";
|
||||
import { onMounted, ref } from "vue";
|
||||
import { Modal } from "ant-design-vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import * as api from "./api.js";
|
||||
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
|
||||
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||
const { t } = useI18n();
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
import { utils } from "@fast-crud/fast-crud";
|
||||
import { cloneDeep } from "lodash-es";
|
||||
import { computed, defineComponent, ref } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
|
||||
export default defineComponent({
|
||||
name: "FsPermissionTree",
|
||||
|
|
|
@ -19,7 +19,7 @@ import createCrudOptions from "./crud.js";
|
|||
import FsPermissionTree from "./fs-permission-tree.vue";
|
||||
import { usePermission } from "/src/plugin/permission";
|
||||
import { useFs, useUi } from "@fast-crud/fast-crud";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
|
||||
export default defineComponent({
|
||||
name: "AuthorityManager",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import * as api from "./api";
|
||||
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
|
||||
export default function ({ crudExpose, context: { authz } }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||
const { t } = useI18n();
|
||||
|
|
|
@ -19,7 +19,7 @@ import * as api from "./api";
|
|||
import { message } from "ant-design-vue";
|
||||
import FsPermissionTree from "../permission/fs-permission-tree.vue";
|
||||
import { UseCrudPermissionCompProps, UseCrudPermissionExtraProps } from "/@/plugin/permission";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
|
||||
function useAuthz() {
|
||||
const checkedKeys = ref();
|
||||
|
|
|
@ -4,7 +4,7 @@ import { useUserStore } from "/@/store/user";
|
|||
import { Modal, notification } from "ant-design-vue";
|
||||
import dayjs from "dayjs";
|
||||
import { useSettingStore } from "/@/store/settings";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
|
||||
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||
const { t } = useI18n();
|
||||
|
@ -207,8 +207,8 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
|
|||
type: "dict-switch",
|
||||
dict: dict({
|
||||
data: [
|
||||
{ label: t("certd.enabled"), value: 1, color: "green" },
|
||||
{ label: t("certd.disabled"), value: 0, color: "red" },
|
||||
{ label: t("common.enabled"), value: 1, color: "green" },
|
||||
{ label: t("common.disabled"), value: 0, color: "red" },
|
||||
],
|
||||
}),
|
||||
column: {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as api from "./api";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
import { computed, Ref, ref } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes, utils } from "@fast-crud/fast-crud";
|
||||
|
|
|
@ -27,7 +27,7 @@ import { useFs } from "@fast-crud/fast-crud";
|
|||
import createCrudOptions from "./crud";
|
||||
import { message, Modal } from "ant-design-vue";
|
||||
import { DeleteBatch } from "./api";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as api from "./api";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
import { Ref, ref } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, useFormWrapper, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||
|
|
|
@ -22,7 +22,7 @@ import { useFs } from "@fast-crud/fast-crud";
|
|||
import createCrudOptions from "./crud";
|
||||
import { message, Modal } from "ant-design-vue";
|
||||
import { DeleteBatch } from "./api";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useI18n } from "/src/locales";
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue