mirror of
https://github.com/certd/certd.git
synced 2026-04-14 12:30:54 +08:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e96a83a528 | ||
|
|
fbddd7ead8 | ||
|
|
762a2058d3 | ||
|
|
2bc0a4bd14 | ||
|
|
e052e304bd | ||
|
|
50c56d134e | ||
|
|
4caa2fad9d | ||
|
|
07043aff0c | ||
|
|
e8b617b80c | ||
|
|
417971d15d | ||
|
|
ccfe72a0d9 | ||
|
|
6f8fe62087 | ||
|
|
5601bc4ab2 | ||
|
|
67ba17286c | ||
|
|
a10b8aa042 | ||
|
|
273ab6139f | ||
|
|
9b68009eb3 | ||
|
|
aec2448406 |
@@ -3,6 +3,14 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.26.4](https://github.com/certd/certd/compare/v1.26.3...v1.26.4) (2024-10-14)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* [comm] 支持插件管理 ([e8b617b](https://github.com/certd/certd/commit/e8b617b80ce882dd63006f0cfc719a80a1cc6acc))
|
||||||
|
* 新增代理设置功能 ([273ab61](https://github.com/certd/certd/commit/273ab6139f5807f4d7fe865cc353b97f51b9a668))
|
||||||
|
* EAB授权支持绑定邮箱,支持公共EAB设置 ([07043af](https://github.com/certd/certd/commit/07043aff0ca7fd29c56dd3c363002cb15d78b464))
|
||||||
|
|
||||||
## [1.26.3](https://github.com/certd/certd/compare/v1.26.2...v1.26.3) (2024-10-12)
|
## [1.26.3](https://github.com/certd/certd/compare/v1.26.2...v1.26.3) (2024-10-12)
|
||||||
|
|
||||||
### Performance Improvements
|
### Performance Improvements
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ Certd 是一个免费全自动申请和自动部署更新SSL证书的工具。
|
|||||||
## 一、特性
|
## 一、特性
|
||||||
本项目不仅支持证书申请过程自动化,还可以自动化部署更新证书,让你的证书永不过期。
|
本项目不仅支持证书申请过程自动化,还可以自动化部署更新证书,让你的证书永不过期。
|
||||||
|
|
||||||
* 全自动申请证书(支持阿里云、腾讯云、华为云、Cloudflare等各种途径注册的域名)
|
* 全自动申请证书(支持所有注册商注册的域名)
|
||||||
* 全自动部署更新证书(目前支持部署到主机、部署到阿里云、腾讯云等)
|
* 全自动部署更新证书(目前支持部署到主机、部署到阿里云、腾讯云等,目前已支持30+部署插件)
|
||||||
* 支持通配符域名/泛域名,支持多个域名打到一个证书上
|
* 支持通配符域名/泛域名,支持多个域名打到一个证书上
|
||||||
* 邮件通知
|
* 邮件通知
|
||||||
* 私有化部署,保障安全
|
* 私有化部署,保障数据安全
|
||||||
* 免费、免费、免费([阿里云单个通配符域名证书最便宜也要1800/年](https://yundun.console.aliyun.com/?p=cas#/certExtend/buy/cn-hangzhou))
|
* 免费、免费、免费([阿里云单个通配符域名证书最便宜也要1800/年](https://yundun.console.aliyun.com/?p=cas#/certExtend/buy/cn-hangzhou))
|
||||||
|
|
||||||
|
|
||||||
@@ -124,6 +124,7 @@ git clone https://github.com/certd/certd
|
|||||||
cd certd
|
cd certd
|
||||||
# 启动服务
|
# 启动服务
|
||||||
./start.sh
|
./start.sh
|
||||||
|
# 数据默认保存在 ./packages/ui/certd-server/data 目录下,注意数据备份
|
||||||
```
|
```
|
||||||
如果是windows,请先安装`git for windows` ,然后右键,选择`open git bash here`打开终端,再执行`./start.sh`命令
|
如果是windows,请先安装`git for windows` ,然后右键,选择`open git bash here`打开终端,再执行`./start.sh`命令
|
||||||
|
|
||||||
@@ -169,6 +170,7 @@ docker compose up -d
|
|||||||
* [google证书](./doc/google/google.md)
|
* [google证书](./doc/google/google.md)
|
||||||
* [群晖部署certd及证书更新教程](./doc/synology/index.md)
|
* [群晖部署certd及证书更新教程](./doc/synology/index.md)
|
||||||
|
|
||||||
|
* [CNAME证书校验方式说明](./doc/cname/index.md)
|
||||||
|
|
||||||
## 八、问题处理
|
## 八、问题处理
|
||||||
### 7.1 忘记管理员密码
|
### 7.1 忘记管理员密码
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
13:39
|
15:06
|
||||||
|
|||||||
BIN
doc/cname/images/cname1.png
Normal file
BIN
doc/cname/images/cname1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 172 KiB |
BIN
doc/cname/images/cname2.png
Normal file
BIN
doc/cname/images/cname2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 71 KiB |
BIN
doc/cname/images/cname3.png
Normal file
BIN
doc/cname/images/cname3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 200 KiB |
BIN
doc/cname/images/cname4.png
Normal file
BIN
doc/cname/images/cname4.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
27
doc/cname/index.md
Normal file
27
doc/cname/index.md
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# CNAME代理校验方式说明
|
||||||
|
|
||||||
|
## 1. 前言
|
||||||
|
申请域名证书是需要校验域名所有权的。
|
||||||
|
目前有两种校验方式:
|
||||||
|
1. http-01: 在网站根目录下放置一份txt文件(Certd不支持)
|
||||||
|
2. dns-01: 需要给域名添加txt解析记录,通配符域名只能用这种方式(Certd采用这种方式)
|
||||||
|
|
||||||
|
DNS-01方式需要开发适配DNS服务商的接口,目前已实现主流域名注册商的接口(阿里云、腾讯云、华为云、Cloudflare、西数)
|
||||||
|
|
||||||
|
如果域名不在这几家,那么就只能通过CNAME代理校验方式来实现
|
||||||
|
|
||||||
|
|
||||||
|
## 2. 使用步骤
|
||||||
|
|
||||||
|
1. 假设你要申请证书的域名叫:need.cert.com ,它是在其他服务商注册的
|
||||||
|
2. 现在你需要另外一个域名:cname.foo.com,这个域名属于是在阿里云、腾讯云、华为云、Cloudflare、西数,或者你把这个域名的DNS服务器转到这几家。
|
||||||
|
3. 到Certd的 CNAME服务管理界面,用`cname.foo.com`创建一条默认的CNAME服务,需要提供DNS提供商授权。
|
||||||
|

|
||||||
|
4. 申请证书时,Certd会生成一个随机的CNAME记录,例如:`_acme-challenge.need`->`xxxxxx.cname.foo.com`
|
||||||
|

|
||||||
|
5. 您需要手动添加这条CNAME记录到你要申请证书的域名解析中,点击校验,校验成功后就可以开始申请证书了 (此操作每个域名只需要做一次,后续可以重复使用,注意不要删除添加的CNAME记录)
|
||||||
|

|
||||||
|
6. 
|
||||||
|
6. 申请过程中,Certd会在`xxxxxx.cname.foo.com`下自动添加验证TXT记录。
|
||||||
|
7. 由于您配置了`_acme-challenge.need`的CNAME,所以这个TXT记录会被解析到`_acme-challenge.need.cert.com`下,从而完成域名校验。
|
||||||
|
|
||||||
@@ -9,5 +9,5 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"npmClient": "pnpm",
|
"npmClient": "pnpm",
|
||||||
"version": "1.26.3"
|
"version": "1.26.4"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,11 +14,12 @@
|
|||||||
"i-all": "lerna link && lerna exec npm install ",
|
"i-all": "lerna link && lerna exec npm install ",
|
||||||
"publish": "npm run prepublishOnly2 && lerna publish --force-publish=pro/plus-core --conventional-commits --create-release github && npm run afterpublishOnly && npm run commitAll",
|
"publish": "npm run prepublishOnly2 && lerna publish --force-publish=pro/plus-core --conventional-commits --create-release github && npm run afterpublishOnly && npm run commitAll",
|
||||||
"afterpublishOnly": "time /t >build.trigger && git add ./build.trigger && git commit -m \"build: trigger build image\" && TIMEOUT /T 10 && git push",
|
"afterpublishOnly": "time /t >build.trigger && git add ./build.trigger && git commit -m \"build: trigger build image\" && TIMEOUT /T 10 && git push",
|
||||||
|
"transform-sql":"cd ./packages/ui/certd-server/db/ && node --experimental-json-modules transform.js",
|
||||||
"commitAll": "git add . && git commit -m \"build: publish\" && git push && npm run commitPro",
|
"commitAll": "git add . && git commit -m \"build: publish\" && git push && npm run commitPro",
|
||||||
"commitPro": "cd ./packages/core/ && git add . && git commit -m \"build: publish\" && git push",
|
"commitPro": "cd ./packages/core/ && git add . && git commit -m \"build: publish\" && git push",
|
||||||
"prepublishOnly1": "npm run check && lerna run build ",
|
"prepublishOnly1": "npm run check && lerna run build ",
|
||||||
"prepublishOnly2": "npm run check && npm run before-build && lerna run build ",
|
"prepublishOnly2": "npm run check && npm run before-build && lerna run build ",
|
||||||
"before-build": "cd ./packages/core/basic && time /t >build.md && git add ./build.md && git commit -m \"build: prepare to build\"",
|
"before-build": "npm run transform-sql && cd ./packages/core/basic && time /t >build.md && git add ./build.md && git commit -m \"build: prepare to build\"",
|
||||||
"deploy1": "node --experimental-json-modules deploy.js ",
|
"deploy1": "node --experimental-json-modules deploy.js ",
|
||||||
"check": "node --experimental-json-modules publish-check.js",
|
"check": "node --experimental-json-modules publish-check.js",
|
||||||
"init": "lerna run build"
|
"init": "lerna run build"
|
||||||
|
|||||||
@@ -3,6 +3,10 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.26.4](https://github.com/publishlab/node-acme-client/compare/v1.26.3...v1.26.4) (2024-10-14)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
## [1.26.3](https://github.com/publishlab/node-acme-client/compare/v1.26.2...v1.26.3) (2024-10-12)
|
## [1.26.3](https://github.com/publishlab/node-acme-client/compare/v1.26.2...v1.26.3) (2024-10-12)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/acme-client
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"description": "Simple and unopinionated ACME client",
|
"description": "Simple and unopinionated ACME client",
|
||||||
"private": false,
|
"private": false,
|
||||||
"author": "nmorsman",
|
"author": "nmorsman",
|
||||||
"version": "1.26.3",
|
"version": "1.26.4",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"types": "types/index.d.ts",
|
"types": "types/index.d.ts",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -59,5 +59,5 @@
|
|||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/publishlab/node-acme-client/issues"
|
"url": "https://github.com/publishlab/node-acme-client/issues"
|
||||||
},
|
},
|
||||||
"gitHead": "66f9b08fcf5035577eafc609fd634d6490bc9cae"
|
"gitHead": "4343fb1b3072b03e2444398cafdb405f230a3779"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,12 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.26.4](https://github.com/certd/certd/compare/v1.26.3...v1.26.4) (2024-10-14)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 新增代理设置功能 ([273ab61](https://github.com/certd/certd/commit/273ab6139f5807f4d7fe865cc353b97f51b9a668))
|
||||||
|
|
||||||
## [1.26.3](https://github.com/certd/certd/compare/v1.26.2...v1.26.3) (2024-10-12)
|
## [1.26.3](https://github.com/certd/certd/compare/v1.26.2...v1.26.3) (2024-10-12)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/basic
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
15:04
|
12:33
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/basic",
|
"name": "@certd/basic",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.26.3",
|
"version": "1.26.4",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"module": "./dist/index.js",
|
"module": "./dist/index.js",
|
||||||
@@ -64,5 +64,5 @@
|
|||||||
"vite": "^4.3.8",
|
"vite": "^4.3.8",
|
||||||
"vue-tsc": "^1.6.5"
|
"vue-tsc": "^1.6.5"
|
||||||
},
|
},
|
||||||
"gitHead": "66f9b08fcf5035577eafc609fd634d6490bc9cae"
|
"gitHead": "4343fb1b3072b03e2444398cafdb405f230a3779"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,21 @@ export class HttpError extends Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const HttpCommonError = HttpError;
|
export const HttpCommonError = HttpError;
|
||||||
|
|
||||||
|
let defaultAgents = createAgent();
|
||||||
|
|
||||||
|
export function setGlobalProxy(opts: { httpProxy?: string; httpsProxy?: string }) {
|
||||||
|
logger.info('setGlobalProxy:', opts);
|
||||||
|
if (opts.httpProxy) {
|
||||||
|
process.env.HTTP_PROXY = opts.httpProxy;
|
||||||
|
}
|
||||||
|
if (opts.httpsProxy) {
|
||||||
|
process.env.HTTPS_PROXY = opts.httpsProxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultAgents = createAgent();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 创建请求实例
|
* @description 创建请求实例
|
||||||
*/
|
*/
|
||||||
@@ -54,7 +69,6 @@ export function createAxiosService({ logger }: { logger: Logger }) {
|
|||||||
// 创建一个 axios 实例
|
// 创建一个 axios 实例
|
||||||
const service = axios.create();
|
const service = axios.create();
|
||||||
|
|
||||||
const defaultAgents = createAgent();
|
|
||||||
// 请求拦截
|
// 请求拦截
|
||||||
service.interceptors.request.use(
|
service.interceptors.request.use(
|
||||||
(config: any) => {
|
(config: any) => {
|
||||||
|
|||||||
@@ -3,6 +3,13 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.26.4](https://github.com/certd/certd/compare/v1.26.3...v1.26.4) (2024-10-14)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* [comm] 支持插件管理 ([e8b617b](https://github.com/certd/certd/commit/e8b617b80ce882dd63006f0cfc719a80a1cc6acc))
|
||||||
|
* EAB授权支持绑定邮箱,支持公共EAB设置 ([07043af](https://github.com/certd/certd/commit/07043aff0ca7fd29c56dd3c363002cb15d78b464))
|
||||||
|
|
||||||
## [1.26.3](https://github.com/certd/certd/compare/v1.26.2...v1.26.3) (2024-10-12)
|
## [1.26.3](https://github.com/certd/certd/compare/v1.26.2...v1.26.3) (2024-10-12)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/pipeline
|
**Note:** Version bump only for package @certd/pipeline
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/pipeline",
|
"name": "@certd/pipeline",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.26.3",
|
"version": "1.26.4",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"types": "./dist/index.d.ts",
|
"types": "./dist/index.d.ts",
|
||||||
@@ -15,8 +15,8 @@
|
|||||||
"test": "mocha --loader=ts-node/esm"
|
"test": "mocha --loader=ts-node/esm"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@certd/basic": "^1.26.3",
|
"@certd/basic": "^1.26.4",
|
||||||
"@certd/plus-core": "^1.26.3",
|
"@certd/plus-core": "^1.26.4",
|
||||||
"axios": "^1.7.2",
|
"axios": "^1.7.2",
|
||||||
"dayjs": "^1.11.7",
|
"dayjs": "^1.11.7",
|
||||||
"fix-path": "^4.0.0",
|
"fix-path": "^4.0.0",
|
||||||
@@ -66,5 +66,5 @@
|
|||||||
"vite": "^4.3.8",
|
"vite": "^4.3.8",
|
||||||
"vue-tsc": "^1.6.5"
|
"vue-tsc": "^1.6.5"
|
||||||
},
|
},
|
||||||
"gitHead": "66f9b08fcf5035577eafc609fd634d6490bc9cae"
|
"gitHead": "4343fb1b3072b03e2444398cafdb405f230a3779"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,16 @@
|
|||||||
import { ConcurrencyStrategy, NotificationWhen, Pipeline, ResultType, Runnable, RunStrategy, Stage, Step, Task } from "../dt/index.js";
|
import { ConcurrencyStrategy, NotificationWhen, Pipeline, ResultType, Runnable, RunStrategy, Stage, Step, Task } from "../dt/index.js";
|
||||||
import _ from "lodash-es";
|
|
||||||
import { RunHistory, RunnableCollection } from "./run-history.js";
|
import { RunHistory, RunnableCollection } from "./run-history.js";
|
||||||
import { AbstractTaskPlugin, PluginDefine, pluginRegistry, TaskInstanceContext, UserInfo } from "../plugin/index.js";
|
import { AbstractTaskPlugin, PluginDefine, pluginRegistry, TaskInstanceContext, UserInfo } from "../plugin/index.js";
|
||||||
import { ContextFactory, IContext } from "./context.js";
|
import { ContextFactory, IContext } from "./context.js";
|
||||||
import { IStorage } from "./storage.js";
|
import { IStorage } from "./storage.js";
|
||||||
import { logger } from "../utils/index.js";
|
import { createAxiosService, hashUtils, logger, utils } from "../utils/index.js";
|
||||||
import { Logger } from "log4js";
|
import { Logger } from "log4js";
|
||||||
import { createAxiosService } from "../utils/index.js";
|
|
||||||
import { IAccessService } from "../access/index.js";
|
import { IAccessService } from "../access/index.js";
|
||||||
import { RegistryItem } from "../registry/index.js";
|
import { RegistryItem } from "../registry/index.js";
|
||||||
import { Decorator } from "../decorator/index.js";
|
import { Decorator } from "../decorator/index.js";
|
||||||
import { ICnameProxyService, IEmailService } from "../service/index.js";
|
import { ICnameProxyService, IEmailService, IPluginConfigService } from "../service/index.js";
|
||||||
import { FileStore } from "./file-store.js";
|
import { FileStore } from "./file-store.js";
|
||||||
import { hashUtils, utils } from "../utils/index.js";
|
import { cloneDeep, forEach, merge } from "lodash-es";
|
||||||
|
|
||||||
export type ExecutorOptions = {
|
export type ExecutorOptions = {
|
||||||
pipeline: Pipeline;
|
pipeline: Pipeline;
|
||||||
@@ -21,6 +19,7 @@ export type ExecutorOptions = {
|
|||||||
accessService: IAccessService;
|
accessService: IAccessService;
|
||||||
emailService: IEmailService;
|
emailService: IEmailService;
|
||||||
cnameProxyService: ICnameProxyService;
|
cnameProxyService: ICnameProxyService;
|
||||||
|
pluginConfigService: IPluginConfigService;
|
||||||
fileRootDir?: string;
|
fileRootDir?: string;
|
||||||
user: UserInfo;
|
user: UserInfo;
|
||||||
};
|
};
|
||||||
@@ -42,7 +41,7 @@ export class Executor {
|
|||||||
onChanged: (history: RunHistory) => Promise<void>;
|
onChanged: (history: RunHistory) => Promise<void>;
|
||||||
constructor(options: ExecutorOptions) {
|
constructor(options: ExecutorOptions) {
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.pipeline = _.cloneDeep(options.pipeline);
|
this.pipeline = cloneDeep(options.pipeline);
|
||||||
this.onChanged = async (history: RunHistory) => {
|
this.onChanged = async (history: RunHistory) => {
|
||||||
await options.onChanged(history);
|
await options.onChanged(history);
|
||||||
};
|
};
|
||||||
@@ -218,8 +217,10 @@ export class Executor {
|
|||||||
const instance: ITaskPlugin = new plugin.target();
|
const instance: ITaskPlugin = new plugin.target();
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const define: PluginDefine = plugin.define;
|
const define: PluginDefine = plugin.define;
|
||||||
|
const pluginName = define.name;
|
||||||
|
const pluginConfig = await this.options.pluginConfigService.getPluginConfig(pluginName);
|
||||||
//从outputContext读取输入参数
|
//从outputContext读取输入参数
|
||||||
const input = _.cloneDeep(step.input);
|
const input = cloneDeep(step.input);
|
||||||
Decorator.inject(define.input, instance, input, (item, key) => {
|
Decorator.inject(define.input, instance, input, (item, key) => {
|
||||||
if (item.component?.name === "output-selector") {
|
if (item.component?.name === "output-selector") {
|
||||||
const contextKey = input[key];
|
const contextKey = input[key];
|
||||||
@@ -239,6 +240,12 @@ export class Executor {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const sysInput = pluginConfig.sysSetting?.input || {};
|
||||||
|
//注入系统设置参数
|
||||||
|
for (const sysInputKey in sysInput) {
|
||||||
|
input[sysInputKey] = sysInput[sysInputKey];
|
||||||
|
}
|
||||||
|
|
||||||
const newInputHash = hashUtils.md5(JSON.stringify(input));
|
const newInputHash = hashUtils.md5(JSON.stringify(input));
|
||||||
step.status!.inputHash = newInputHash;
|
step.status!.inputHash = newInputHash;
|
||||||
//判断是否需要跳过
|
//判断是否需要跳过
|
||||||
@@ -269,6 +276,7 @@ export class Executor {
|
|||||||
accessService: this.options.accessService,
|
accessService: this.options.accessService,
|
||||||
emailService: this.options.emailService,
|
emailService: this.options.emailService,
|
||||||
cnameProxyService: this.options.cnameProxyService,
|
cnameProxyService: this.options.cnameProxyService,
|
||||||
|
pluginConfigService: this.options.pluginConfigService,
|
||||||
pipelineContext: this.pipelineContext,
|
pipelineContext: this.pipelineContext,
|
||||||
userContext: this.contextFactory.getContext("user", this.options.user.id),
|
userContext: this.contextFactory.getContext("user", this.options.user.id),
|
||||||
fileStore: new FileStore({
|
fileStore: new FileStore({
|
||||||
@@ -290,7 +298,7 @@ export class Executor {
|
|||||||
this.lastStatusMap.clear();
|
this.lastStatusMap.clear();
|
||||||
}
|
}
|
||||||
//输出上下文变量到output context
|
//输出上下文变量到output context
|
||||||
_.forEach(define.output, (item: any, key: any) => {
|
forEach(define.output, (item: any, key: any) => {
|
||||||
step.status!.output[key] = instance[key];
|
step.status!.output[key] = instance[key];
|
||||||
// const stepOutputKey = `step.${step.id}.${key}`;
|
// const stepOutputKey = `step.${step.id}.${key}`;
|
||||||
// this.runtime.context[stepOutputKey] = instance[key];
|
// this.runtime.context[stepOutputKey] = instance[key];
|
||||||
@@ -300,7 +308,7 @@ export class Executor {
|
|||||||
if (Object.keys(instance._result.pipelineVars).length > 0) {
|
if (Object.keys(instance._result.pipelineVars).length > 0) {
|
||||||
// 判断 pipelineVars 有值时更新
|
// 判断 pipelineVars 有值时更新
|
||||||
const vars = this.pipelineContext.getObj("vars");
|
const vars = this.pipelineContext.getObj("vars");
|
||||||
_.merge(vars, instance._result.pipelineVars);
|
merge(vars, instance._result.pipelineVars);
|
||||||
await this.pipelineContext.setObj("vars", vars);
|
await this.pipelineContext.setObj("vars", vars);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ import { IContext, PluginRequestHandleReq, RunnableCollection } from "../core/in
|
|||||||
import { ILogger, logger, utils } from "../utils/index.js";
|
import { ILogger, logger, utils } from "../utils/index.js";
|
||||||
import { HttpClient } from "../utils/index.js";
|
import { HttpClient } from "../utils/index.js";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import _ from "lodash-es";
|
import { IPluginConfigService } from "../service/config";
|
||||||
|
import { upperFirst } from "lodash-es";
|
||||||
export type UserInfo = {
|
export type UserInfo = {
|
||||||
role: "admin" | "user";
|
role: "admin" | "user";
|
||||||
id: any;
|
id: any;
|
||||||
@@ -25,7 +26,10 @@ export type TaskOutputDefine = {
|
|||||||
type?: string;
|
type?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TaskInputDefine = FormItemProps;
|
export type TaskInputDefine = {
|
||||||
|
required?: boolean;
|
||||||
|
isSys?: boolean;
|
||||||
|
} & FormItemProps;
|
||||||
|
|
||||||
export type PluginDefine = Registrable & {
|
export type PluginDefine = Registrable & {
|
||||||
default?: any;
|
default?: any;
|
||||||
@@ -72,6 +76,8 @@ export type TaskInstanceContext = {
|
|||||||
emailService: IEmailService;
|
emailService: IEmailService;
|
||||||
//cname记录服务
|
//cname记录服务
|
||||||
cnameProxyService: ICnameProxyService;
|
cnameProxyService: ICnameProxyService;
|
||||||
|
//插件配置服务
|
||||||
|
pluginConfigService: IPluginConfigService;
|
||||||
//流水线上下文
|
//流水线上下文
|
||||||
pipelineContext: IContext;
|
pipelineContext: IContext;
|
||||||
//用户上下文
|
//用户上下文
|
||||||
@@ -169,7 +175,7 @@ export abstract class AbstractTaskPlugin implements ITaskPlugin {
|
|||||||
|
|
||||||
let methodName = req.action;
|
let methodName = req.action;
|
||||||
if (!req.action.startsWith("on")) {
|
if (!req.action.startsWith("on")) {
|
||||||
methodName = `on${_.upperFirst(req.action)}`;
|
methodName = `on${upperFirst(req.action)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import _ from "lodash-es";
|
|
||||||
import { pluginRegistry } from "./registry.js";
|
import { pluginRegistry } from "./registry.js";
|
||||||
import { PluginDefine, TaskInputDefine, TaskOutputDefine } from "./api.js";
|
import { PluginDefine, TaskInputDefine, TaskOutputDefine } from "./api.js";
|
||||||
import { Decorator } from "../decorator/index.js";
|
import { Decorator } from "../decorator/index.js";
|
||||||
import { AUTOWIRE_KEY } from "../decorator/index.js";
|
import { AUTOWIRE_KEY } from "../decorator/index.js";
|
||||||
import "reflect-metadata";
|
import "reflect-metadata";
|
||||||
|
import { merge, sortBy } from "lodash-es";
|
||||||
// 提供一个唯一 key
|
// 提供一个唯一 key
|
||||||
export const PLUGIN_CLASS_KEY = "pipeline:plugin";
|
export const PLUGIN_CLASS_KEY = "pipeline:plugin";
|
||||||
|
|
||||||
@@ -42,13 +42,13 @@ export function IsTaskPlugin(define: PluginDefine): ClassDecorator {
|
|||||||
}
|
}
|
||||||
inputArray.push([key, _input]);
|
inputArray.push([key, _input]);
|
||||||
}
|
}
|
||||||
inputArray = _.sortBy(inputArray, (item: any) => item[1].order);
|
inputArray = sortBy(inputArray, (item: any) => item[1].order);
|
||||||
const inputMap: any = {};
|
const inputMap: any = {};
|
||||||
inputArray.forEach((item: any) => {
|
inputArray.forEach((item: any) => {
|
||||||
inputMap[item[0]] = item[1];
|
inputMap[item[0]] = item[1];
|
||||||
});
|
});
|
||||||
|
|
||||||
_.merge(define, { input: inputMap, autowire: autowires, output: outputs });
|
merge(define, { input: inputMap, autowire: autowires, output: outputs });
|
||||||
|
|
||||||
Reflect.defineMetadata(PLUGIN_CLASS_KEY, define, target);
|
Reflect.defineMetadata(PLUGIN_CLASS_KEY, define, target);
|
||||||
|
|
||||||
|
|||||||
12
packages/core/pipeline/src/service/config.ts
Normal file
12
packages/core/pipeline/src/service/config.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
export type PluginConfig = {
|
||||||
|
name: string;
|
||||||
|
disabled: boolean;
|
||||||
|
sysSetting: {
|
||||||
|
input: Record<string, any>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
//插件配置服务
|
||||||
|
export type IPluginConfigService = {
|
||||||
|
getPluginConfig: (pluginName: string) => Promise<PluginConfig>;
|
||||||
|
};
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
export * from "./email.js";
|
export * from "./email.js";
|
||||||
export * from "./cname.js";
|
export * from "./cname.js";
|
||||||
|
export * from "./config.js";
|
||||||
|
|||||||
@@ -3,6 +3,10 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.26.4](https://github.com/certd/certd/compare/v1.26.3...v1.26.4) (2024-10-14)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-huawei
|
||||||
|
|
||||||
## [1.26.3](https://github.com/certd/certd/compare/v1.26.2...v1.26.3) (2024-10-12)
|
## [1.26.3](https://github.com/certd/certd/compare/v1.26.2...v1.26.3) (2024-10-12)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/lib-huawei
|
**Note:** Version bump only for package @certd/lib-huawei
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/lib-huawei",
|
"name": "@certd/lib-huawei",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.26.3",
|
"version": "1.26.4",
|
||||||
"main": "./dist/bundle.js",
|
"main": "./dist/bundle.js",
|
||||||
"module": "./dist/bundle.js",
|
"module": "./dist/bundle.js",
|
||||||
"types": "./dist/d/index.d.ts",
|
"types": "./dist/d/index.d.ts",
|
||||||
@@ -17,5 +17,5 @@
|
|||||||
"rimraf": "^5.0.5",
|
"rimraf": "^5.0.5",
|
||||||
"rollup": "^3.7.4"
|
"rollup": "^3.7.4"
|
||||||
},
|
},
|
||||||
"gitHead": "66f9b08fcf5035577eafc609fd634d6490bc9cae"
|
"gitHead": "4343fb1b3072b03e2444398cafdb405f230a3779"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,10 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.26.4](https://github.com/certd/certd/compare/v1.26.3...v1.26.4) (2024-10-14)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-iframe
|
||||||
|
|
||||||
## [1.26.3](https://github.com/certd/certd/compare/v1.26.2...v1.26.3) (2024-10-12)
|
## [1.26.3](https://github.com/certd/certd/compare/v1.26.2...v1.26.3) (2024-10-12)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/lib-iframe
|
**Note:** Version bump only for package @certd/lib-iframe
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/lib-iframe",
|
"name": "@certd/lib-iframe",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.26.3",
|
"version": "1.26.4",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"types": "./dist/index.d.ts",
|
"types": "./dist/index.d.ts",
|
||||||
@@ -39,5 +39,5 @@
|
|||||||
"tslib": "^2.5.2",
|
"tslib": "^2.5.2",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "66f9b08fcf5035577eafc609fd634d6490bc9cae"
|
"gitHead": "4343fb1b3072b03e2444398cafdb405f230a3779"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,10 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.26.4](https://github.com/certd/certd/compare/v1.26.3...v1.26.4) (2024-10-14)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-jdcloud
|
||||||
|
|
||||||
## [1.26.3](https://github.com/certd/certd/compare/v1.26.2...v1.26.3) (2024-10-12)
|
## [1.26.3](https://github.com/certd/certd/compare/v1.26.2...v1.26.3) (2024-10-12)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/lib-jdcloud
|
**Note:** Version bump only for package @certd/lib-jdcloud
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/lib-jdcloud",
|
"name": "@certd/lib-jdcloud",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.26.3",
|
"version": "1.26.4",
|
||||||
"main": "./dist/bundle.mjs",
|
"main": "./dist/bundle.mjs",
|
||||||
"module": "./dist/bundle.mjs",
|
"module": "./dist/bundle.mjs",
|
||||||
"types": "./dist/d/index.d.ts",
|
"types": "./dist/d/index.d.ts",
|
||||||
@@ -27,5 +27,5 @@
|
|||||||
"rimraf": "^5.0.5",
|
"rimraf": "^5.0.5",
|
||||||
"rollup": "^3.7.4"
|
"rollup": "^3.7.4"
|
||||||
},
|
},
|
||||||
"gitHead": "66f9b08fcf5035577eafc609fd634d6490bc9cae"
|
"gitHead": "4343fb1b3072b03e2444398cafdb405f230a3779"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,10 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.26.4](https://github.com/certd/certd/compare/v1.26.3...v1.26.4) (2024-10-14)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-k8s
|
||||||
|
|
||||||
## [1.26.3](https://github.com/certd/certd/compare/v1.26.2...v1.26.3) (2024-10-12)
|
## [1.26.3](https://github.com/certd/certd/compare/v1.26.2...v1.26.3) (2024-10-12)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/lib-k8s
|
**Note:** Version bump only for package @certd/lib-k8s
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/lib-k8s",
|
"name": "@certd/lib-k8s",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.26.3",
|
"version": "1.26.4",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"types": "./dist/index.d.ts",
|
"types": "./dist/index.d.ts",
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
"@kubernetes/client-node": "0.21.0"
|
"@kubernetes/client-node": "0.21.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@certd/pipeline": "^1.26.3",
|
"@certd/pipeline": "^1.26.4",
|
||||||
"@rollup/plugin-commonjs": "^23.0.4",
|
"@rollup/plugin-commonjs": "^23.0.4",
|
||||||
"@rollup/plugin-json": "^6.0.0",
|
"@rollup/plugin-json": "^6.0.0",
|
||||||
"@rollup/plugin-node-resolve": "^15.0.1",
|
"@rollup/plugin-node-resolve": "^15.0.1",
|
||||||
@@ -40,5 +40,5 @@
|
|||||||
"tslib": "^2.5.2",
|
"tslib": "^2.5.2",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "66f9b08fcf5035577eafc609fd634d6490bc9cae"
|
"gitHead": "4343fb1b3072b03e2444398cafdb405f230a3779"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,14 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.26.4](https://github.com/certd/certd/compare/v1.26.3...v1.26.4) (2024-10-14)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* [comm] 支持插件管理 ([e8b617b](https://github.com/certd/certd/commit/e8b617b80ce882dd63006f0cfc719a80a1cc6acc))
|
||||||
|
* 新增代理设置功能 ([273ab61](https://github.com/certd/certd/commit/273ab6139f5807f4d7fe865cc353b97f51b9a668))
|
||||||
|
* EAB授权支持绑定邮箱,支持公共EAB设置 ([07043af](https://github.com/certd/certd/commit/07043aff0ca7fd29c56dd3c363002cb15d78b464))
|
||||||
|
|
||||||
## [1.26.3](https://github.com/certd/certd/compare/v1.26.2...v1.26.3) (2024-10-12)
|
## [1.26.3](https://github.com/certd/certd/compare/v1.26.2...v1.26.3) (2024-10-12)
|
||||||
|
|
||||||
### Performance Improvements
|
### Performance Improvements
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/lib-server",
|
"name": "@certd/lib-server",
|
||||||
"version": "1.26.3",
|
"version": "1.26.4",
|
||||||
"description": "midway with flyway, sql upgrade way ",
|
"description": "midway with flyway, sql upgrade way ",
|
||||||
"private": false,
|
"private": false,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -26,8 +26,8 @@
|
|||||||
],
|
],
|
||||||
"license": "AGPL",
|
"license": "AGPL",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@certd/basic": "^1.26.3",
|
"@certd/basic": "^1.26.4",
|
||||||
"@certd/pipeline": "^1.26.3",
|
"@certd/pipeline": "^1.26.4",
|
||||||
"@midwayjs/cache": "~3.14.0",
|
"@midwayjs/cache": "~3.14.0",
|
||||||
"@midwayjs/core": "~3.17.1",
|
"@midwayjs/core": "~3.17.1",
|
||||||
"@midwayjs/i18n": "~3.17.3",
|
"@midwayjs/i18n": "~3.17.3",
|
||||||
@@ -68,5 +68,5 @@
|
|||||||
"typeorm": "^0.3.11",
|
"typeorm": "^0.3.11",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "66f9b08fcf5035577eafc609fd634d6490bc9cae"
|
"gitHead": "4343fb1b3072b03e2444398cafdb405f230a3779"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,24 @@
|
|||||||
import { ValidateException } from './exception/index.js';
|
import { ValidateException } from './exception/index.js';
|
||||||
import * as _ from 'lodash-es';
|
import * as _ from 'lodash-es';
|
||||||
import { PermissionException } from './exception/index.js';
|
import { PermissionException } from './exception/index.js';
|
||||||
import { In, Repository } from 'typeorm';
|
import { In, Repository, SelectQueryBuilder } from 'typeorm';
|
||||||
import { Inject } from '@midwayjs/core';
|
import { Inject } from '@midwayjs/core';
|
||||||
import { TypeORMDataSourceManager } from '@midwayjs/typeorm';
|
import { TypeORMDataSourceManager } from '@midwayjs/typeorm';
|
||||||
import { EntityManager } from 'typeorm/entity-manager/EntityManager.js';
|
import { EntityManager } from 'typeorm/entity-manager/EntityManager.js';
|
||||||
|
|
||||||
|
export type PageReq<T = any> = {
|
||||||
|
page?: { offset: number; limit: number };
|
||||||
|
} & ListReq<T>;
|
||||||
|
|
||||||
|
export type ListReq<T = any> = {
|
||||||
|
query?: Partial<T>;
|
||||||
|
order?: {
|
||||||
|
prop: string;
|
||||||
|
asc: boolean;
|
||||||
|
};
|
||||||
|
buildQuery?: (bq: SelectQueryBuilder<any>) => void;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 服务基类
|
* 服务基类
|
||||||
*/
|
*/
|
||||||
@@ -106,50 +119,22 @@ export abstract class BaseService<T> {
|
|||||||
* 新增|修改|删除 之后的操作
|
* 新增|修改|删除 之后的操作
|
||||||
* @param data 对应数据
|
* @param data 对应数据
|
||||||
*/
|
*/
|
||||||
async modifyAfter(data) {}
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
async modifyAfter(data: any) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分页查询
|
* 分页查询
|
||||||
* @param query 查询条件 bean
|
|
||||||
* @param page
|
|
||||||
* @param order
|
|
||||||
* @param buildQuery
|
|
||||||
*/
|
*/
|
||||||
async page(query, page = { offset: 0, limit: 20 }, order, buildQuery) {
|
async page(pageReq: PageReq<T>) {
|
||||||
|
const { page } = pageReq;
|
||||||
if (page.offset == null) {
|
if (page.offset == null) {
|
||||||
page.offset = 0;
|
page.offset = 0;
|
||||||
}
|
}
|
||||||
if (page.limit == null) {
|
if (page.limit == null) {
|
||||||
page.limit = 20;
|
page.limit = 20;
|
||||||
}
|
}
|
||||||
const qb = this.getRepository().createQueryBuilder('main');
|
const qb = this.buildListQuery(pageReq);
|
||||||
if (order && order.prop) {
|
|
||||||
qb.addOrderBy('main.' + order.prop, order.asc ? 'ASC' : 'DESC');
|
|
||||||
}
|
|
||||||
qb.addOrderBy('id', 'DESC');
|
|
||||||
qb.offset(page.offset).limit(page.limit);
|
qb.offset(page.offset).limit(page.limit);
|
||||||
//根据bean query
|
|
||||||
if (query) {
|
|
||||||
let whereSql = '';
|
|
||||||
let index = 0;
|
|
||||||
_.forEach(query, (value, key) => {
|
|
||||||
if (!value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (index !== 0) {
|
|
||||||
whereSql += ' and ';
|
|
||||||
}
|
|
||||||
whereSql += ` main.${key} = :${key} `;
|
|
||||||
index++;
|
|
||||||
});
|
|
||||||
if (index > 0) {
|
|
||||||
qb.where(whereSql, query);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//自定义query
|
|
||||||
if (buildQuery) {
|
|
||||||
buildQuery(qb);
|
|
||||||
}
|
|
||||||
const list = await qb.getMany();
|
const list = await qb.getMany();
|
||||||
const total = await qb.getCount();
|
const total = await qb.getCount();
|
||||||
return {
|
return {
|
||||||
@@ -160,19 +145,13 @@ export abstract class BaseService<T> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private buildListQuery(listReq: ListReq<T>) {
|
||||||
* 分页查询
|
const { query, order, buildQuery } = listReq;
|
||||||
* @param query 查询条件 bean
|
|
||||||
* @param order
|
|
||||||
* @param buildQuery
|
|
||||||
*/
|
|
||||||
async list(query, order, buildQuery) {
|
|
||||||
const qb = this.getRepository().createQueryBuilder('main');
|
const qb = this.getRepository().createQueryBuilder('main');
|
||||||
if (order && order.prop) {
|
if (order && order.prop) {
|
||||||
qb.orderBy('main.' + order.prop, order.asc ? 'ASC' : 'DESC');
|
qb.addOrderBy('main.' + order.prop, order.asc ? 'ASC' : 'DESC');
|
||||||
} else {
|
|
||||||
qb.orderBy('id', 'DESC');
|
|
||||||
}
|
}
|
||||||
|
qb.addOrderBy('id', 'DESC');
|
||||||
//根据bean query
|
//根据bean query
|
||||||
if (query) {
|
if (query) {
|
||||||
let whereSql = '';
|
let whereSql = '';
|
||||||
@@ -188,13 +167,21 @@ export abstract class BaseService<T> {
|
|||||||
index++;
|
index++;
|
||||||
});
|
});
|
||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
qb.where(whereSql, query);
|
qb.andWhere(whereSql, query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//自定义query
|
//自定义query
|
||||||
if (buildQuery) {
|
if (buildQuery) {
|
||||||
buildQuery(qb);
|
buildQuery(qb);
|
||||||
}
|
}
|
||||||
|
return qb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询
|
||||||
|
*/
|
||||||
|
async list(listReq: ListReq<T>) {
|
||||||
|
const qb = this.buildListQuery(listReq);
|
||||||
return await qb.getMany();
|
return await qb.getMany();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,59 +2,50 @@ import { ALL, Body, Post, Query } from '@midwayjs/core';
|
|||||||
import { BaseController } from './base-controller.js';
|
import { BaseController } from './base-controller.js';
|
||||||
|
|
||||||
export abstract class CrudController<T> extends BaseController {
|
export abstract class CrudController<T> extends BaseController {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
abstract getService<T>();
|
abstract getService<T>();
|
||||||
|
|
||||||
@Post('/page')
|
@Post('/page')
|
||||||
async page(
|
async page(@Body(ALL) body: any) {
|
||||||
@Body(ALL)
|
const pageRet = await this.getService().page({
|
||||||
body
|
query: body.query ?? {},
|
||||||
) {
|
page: body.page,
|
||||||
const pageRet = await this.getService().page(body?.query, body?.page, body?.sort, null);
|
sort: body.sort,
|
||||||
|
bq: body.bq,
|
||||||
|
});
|
||||||
return this.ok(pageRet);
|
return this.ok(pageRet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('/list')
|
@Post('/list')
|
||||||
async list(
|
async list(@Body(ALL) body: any) {
|
||||||
@Body(ALL)
|
const listRet = await this.getService().list({
|
||||||
body
|
query: body.query ?? {},
|
||||||
) {
|
order: body.order,
|
||||||
const listRet = await this.getService().list(body, null, null);
|
});
|
||||||
return this.ok(listRet);
|
return this.ok(listRet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('/add')
|
@Post('/add')
|
||||||
async add(
|
async add(@Body(ALL) bean: any) {
|
||||||
@Body(ALL)
|
|
||||||
bean
|
|
||||||
) {
|
|
||||||
delete bean.id;
|
delete bean.id;
|
||||||
const id = await this.getService().add(bean);
|
const id = await this.getService().add(bean);
|
||||||
return this.ok(id);
|
return this.ok(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('/info')
|
@Post('/info')
|
||||||
async info(
|
async info(@Query('id') id: number) {
|
||||||
@Query('id')
|
|
||||||
id
|
|
||||||
) {
|
|
||||||
const bean = await this.getService().info(id);
|
const bean = await this.getService().info(id);
|
||||||
return this.ok(bean);
|
return this.ok(bean);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('/update')
|
@Post('/update')
|
||||||
async update(
|
async update(@Body(ALL) bean: any) {
|
||||||
@Body(ALL)
|
|
||||||
bean
|
|
||||||
) {
|
|
||||||
await this.getService().update(bean);
|
await this.getService().update(bean);
|
||||||
return this.ok(null);
|
return this.ok(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('/delete')
|
@Post('/delete')
|
||||||
async delete(
|
async delete(@Query('id') id: number) {
|
||||||
@Query('id')
|
|
||||||
id
|
|
||||||
) {
|
|
||||||
await this.getService().delete([id]);
|
await this.getService().delete([id]);
|
||||||
return this.ok(null);
|
return this.ok(null);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,13 +24,21 @@ export class SysPrivateSettings extends BaseSettings {
|
|||||||
static __key__ = 'sys.private';
|
static __key__ = 'sys.private';
|
||||||
jwtKey?: string;
|
jwtKey?: string;
|
||||||
encryptSecret?: string;
|
encryptSecret?: string;
|
||||||
|
|
||||||
|
httpsProxy? = '';
|
||||||
|
httpProxy? = '';
|
||||||
|
|
||||||
|
removeSecret() {
|
||||||
|
delete this.jwtKey;
|
||||||
|
delete this.encryptSecret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SysInstallInfo extends BaseSettings {
|
export class SysInstallInfo extends BaseSettings {
|
||||||
static __title__ = '系统安装信息';
|
static __title__ = '系统安装信息';
|
||||||
static __key__ = 'sys.install';
|
static __key__ = 'sys.install';
|
||||||
static __access__ = 'private';
|
static __access__ = 'private';
|
||||||
installTime: number;
|
installTime?: number;
|
||||||
siteId?: string;
|
siteId?: string;
|
||||||
bindUserId?: number;
|
bindUserId?: number;
|
||||||
bindUrl?: string;
|
bindUrl?: string;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { BaseSettings, SysPrivateSettings, SysPublicSettings } from './models.js
|
|||||||
import * as _ from 'lodash-es';
|
import * as _ from 'lodash-es';
|
||||||
import { BaseService } from '../../../basic/index.js';
|
import { BaseService } from '../../../basic/index.js';
|
||||||
import { isComm } from '@certd/pipeline';
|
import { isComm } from '@certd/pipeline';
|
||||||
|
import { setGlobalProxy } from '@certd/basic';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置
|
* 设置
|
||||||
@@ -118,8 +119,25 @@ export class SysSettingsService extends BaseService<SysSettingsEntity> {
|
|||||||
await this.saveSetting(bean);
|
await this.saveSetting(bean);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getPrivateSettings(): Promise<SysPrivateSettings> {
|
||||||
|
return await this.getSetting(SysPrivateSettings);
|
||||||
|
}
|
||||||
|
|
||||||
async savePrivateSettings(bean: SysPrivateSettings) {
|
async savePrivateSettings(bean: SysPrivateSettings) {
|
||||||
this.saveSetting(bean);
|
await this.saveSetting(bean);
|
||||||
|
|
||||||
|
//让设置生效
|
||||||
|
await this.reloadPrivateSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
async reloadPrivateSettings() {
|
||||||
|
const bean = await this.getPrivateSettings();
|
||||||
|
if (bean.httpProxy || bean.httpsProxy) {
|
||||||
|
setGlobalProxy({
|
||||||
|
httpProxy: bean.httpProxy,
|
||||||
|
httpsProxy: bean.httpsProxy,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateByKey(key: string, setting: any) {
|
async updateByKey(key: string, setting: any) {
|
||||||
|
|||||||
@@ -3,6 +3,10 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.26.4](https://github.com/certd/certd/compare/v1.26.3...v1.26.4) (2024-10-14)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||||
|
|
||||||
## [1.26.3](https://github.com/certd/certd/compare/v1.26.2...v1.26.3) (2024-10-12)
|
## [1.26.3](https://github.com/certd/certd/compare/v1.26.2...v1.26.3) (2024-10-12)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/midway-flyway-js",
|
"name": "@certd/midway-flyway-js",
|
||||||
"version": "1.26.3",
|
"version": "1.26.4",
|
||||||
"description": "midway with flyway, sql upgrade way ",
|
"description": "midway with flyway, sql upgrade way ",
|
||||||
"private": false,
|
"private": false,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -56,5 +56,5 @@
|
|||||||
"typeorm": "^0.3.11",
|
"typeorm": "^0.3.11",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "66f9b08fcf5035577eafc609fd634d6490bc9cae"
|
"gitHead": "4343fb1b3072b03e2444398cafdb405f230a3779"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,14 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.26.4](https://github.com/certd/certd/compare/v1.26.3...v1.26.4) (2024-10-14)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* [comm] 支持插件管理 ([e8b617b](https://github.com/certd/certd/commit/e8b617b80ce882dd63006f0cfc719a80a1cc6acc))
|
||||||
|
* 新增代理设置功能 ([273ab61](https://github.com/certd/certd/commit/273ab6139f5807f4d7fe865cc353b97f51b9a668))
|
||||||
|
* EAB授权支持绑定邮箱,支持公共EAB设置 ([07043af](https://github.com/certd/certd/commit/07043aff0ca7fd29c56dd3c363002cb15d78b464))
|
||||||
|
|
||||||
## [1.26.3](https://github.com/certd/certd/compare/v1.26.2...v1.26.3) (2024-10-12)
|
## [1.26.3](https://github.com/certd/certd/compare/v1.26.2...v1.26.3) (2024-10-12)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/plugin-cert
|
**Note:** Version bump only for package @certd/plugin-cert
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/plugin-cert",
|
"name": "@certd/plugin-cert",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.26.3",
|
"version": "1.26.4",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"types": "./dist/index.d.ts",
|
"types": "./dist/index.d.ts",
|
||||||
@@ -15,9 +15,9 @@
|
|||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@certd/acme-client": "^1.26.3",
|
"@certd/acme-client": "^1.26.4",
|
||||||
"@certd/basic": "^1.26.3",
|
"@certd/basic": "^1.26.4",
|
||||||
"@certd/pipeline": "^1.26.3",
|
"@certd/pipeline": "^1.26.4",
|
||||||
"@google-cloud/publicca": "^1.3.0",
|
"@google-cloud/publicca": "^1.3.0",
|
||||||
"dayjs": "^1.11.7",
|
"dayjs": "^1.11.7",
|
||||||
"jszip": "^3.10.1",
|
"jszip": "^3.10.1",
|
||||||
@@ -57,5 +57,5 @@
|
|||||||
"vite": "^3.1.0",
|
"vite": "^3.1.0",
|
||||||
"vue-tsc": "^0.38.9"
|
"vue-tsc": "^0.38.9"
|
||||||
},
|
},
|
||||||
"gitHead": "66f9b08fcf5035577eafc609fd634d6490bc9cae"
|
"gitHead": "4343fb1b3072b03e2444398cafdb405f230a3779"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,16 @@ export class EabAccess extends BaseAccess {
|
|||||||
encrypt: true,
|
encrypt: true,
|
||||||
})
|
})
|
||||||
hmacKey = "";
|
hmacKey = "";
|
||||||
|
|
||||||
|
@AccessInput({
|
||||||
|
title: "email",
|
||||||
|
component: {
|
||||||
|
placeholder: "绑定一个邮箱",
|
||||||
|
},
|
||||||
|
helper: "Google EAB 申请证书绑定邮箱后,不能更换,否则会导致EAB失效",
|
||||||
|
required: false,
|
||||||
|
})
|
||||||
|
email = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
new EabAccess();
|
new EabAccess();
|
||||||
|
|||||||
@@ -195,6 +195,7 @@ export abstract class CertApplyBasePlugin extends AbstractTaskPlugin {
|
|||||||
async condition() {
|
async condition() {
|
||||||
if (this.forceUpdate) {
|
if (this.forceUpdate) {
|
||||||
this.logger.info("强制更新证书选项已勾选,准备申请新证书");
|
this.logger.info("强制更新证书选项已勾选,准备申请新证书");
|
||||||
|
this.logger.warn("申请完之后,切记取消强制更新,避免申请过多证书。");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { createDnsProvider, DnsProviderContext, IDnsProvider } from "../../dns-p
|
|||||||
import { CertReader } from "./cert-reader.js";
|
import { CertReader } from "./cert-reader.js";
|
||||||
import { CertApplyBasePlugin } from "./base.js";
|
import { CertApplyBasePlugin } from "./base.js";
|
||||||
import { GoogleClient } from "../../libs/google.js";
|
import { GoogleClient } from "../../libs/google.js";
|
||||||
|
import { EabAccess } from "../../access";
|
||||||
|
|
||||||
export type { CertInfo };
|
export type { CertInfo };
|
||||||
export * from "./cert-reader.js";
|
export * from "./cert-reader.js";
|
||||||
@@ -103,7 +104,7 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
|||||||
},
|
},
|
||||||
rules: [{ type: "checkCnameVerifyPlan" }],
|
rules: [{ type: "checkCnameVerifyPlan" }],
|
||||||
required: true,
|
required: true,
|
||||||
helper: "如果选择CNAME方式,请按照上面的显示,给域名添加CNAME记录,添加后,点击验证,验证成功后不要删除记录,申请和续期证书会一直用它",
|
helper: "如果选择CNAME方式,请按照上面的显示,给要申请证书的域名添加CNAME记录,添加后,点击验证,验证成功后不要删除记录,申请和续期证书会一直用它",
|
||||||
col: {
|
col: {
|
||||||
span: 24,
|
span: 24,
|
||||||
},
|
},
|
||||||
@@ -122,7 +123,7 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
|||||||
domainsVerifyPlan!: DomainsVerifyPlanInput;
|
domainsVerifyPlan!: DomainsVerifyPlanInput;
|
||||||
|
|
||||||
@TaskInput({
|
@TaskInput({
|
||||||
title: "证书提供商",
|
title: "证书颁发机构",
|
||||||
value: "letsencrypt",
|
value: "letsencrypt",
|
||||||
component: {
|
component: {
|
||||||
name: "a-select",
|
name: "a-select",
|
||||||
@@ -138,6 +139,13 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
|||||||
})
|
})
|
||||||
sslProvider!: SSLProvider;
|
sslProvider!: SSLProvider;
|
||||||
|
|
||||||
|
@TaskInput({
|
||||||
|
title: "Google公共EAB授权",
|
||||||
|
isSys: true,
|
||||||
|
show: false,
|
||||||
|
})
|
||||||
|
googleCommonEabAccessId!: number;
|
||||||
|
|
||||||
@TaskInput({
|
@TaskInput({
|
||||||
title: "EAB授权",
|
title: "EAB授权",
|
||||||
component: {
|
component: {
|
||||||
@@ -151,7 +159,7 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
|||||||
mergeScript: `
|
mergeScript: `
|
||||||
return {
|
return {
|
||||||
show: ctx.compute(({form})=>{
|
show: ctx.compute(({form})=>{
|
||||||
return form.sslProvider === 'zerossl' || form.sslProvider === 'google'
|
return form.sslProvider === 'zerossl' || (form.sslProvider === 'google' && !form.googleCommonEabAccessId)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
@@ -171,7 +179,7 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
|||||||
mergeScript: `
|
mergeScript: `
|
||||||
return {
|
return {
|
||||||
show: ctx.compute(({form})=>{
|
show: ctx.compute(({form})=>{
|
||||||
return form.sslProvider === 'google'
|
return form.sslProvider === 'google' && !form.googleCommonEabAccessId
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
@@ -233,12 +241,13 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
|||||||
|
|
||||||
acme!: AcmeService;
|
acme!: AcmeService;
|
||||||
|
|
||||||
|
eab!: EabAccess;
|
||||||
async onInit() {
|
async onInit() {
|
||||||
let eab: any = null;
|
let eab: EabAccess = null;
|
||||||
|
|
||||||
if (this.sslProvider === "google") {
|
if (this.sslProvider === "google") {
|
||||||
if (this.googleAccessId) {
|
if (this.googleAccessId) {
|
||||||
this.logger.info("您正在使用google服务账号授权");
|
this.logger.info("当前正在使用 google服务账号授权获取EAB");
|
||||||
const googleAccess = await this.ctx.accessService.getById(this.googleAccessId);
|
const googleAccess = await this.ctx.accessService.getById(this.googleAccessId);
|
||||||
const googleClient = new GoogleClient({
|
const googleClient = new GoogleClient({
|
||||||
access: googleAccess,
|
access: googleAccess,
|
||||||
@@ -246,8 +255,11 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
|||||||
});
|
});
|
||||||
eab = await googleClient.getEab();
|
eab = await googleClient.getEab();
|
||||||
} else if (this.eabAccessId) {
|
} else if (this.eabAccessId) {
|
||||||
this.logger.info("您正在使用google EAB授权");
|
this.logger.info("当前正在使用 google EAB授权");
|
||||||
eab = await this.ctx.accessService.getById(this.eabAccessId);
|
eab = await this.ctx.accessService.getById(this.eabAccessId);
|
||||||
|
} else if (this.googleCommonEabAccessId) {
|
||||||
|
this.logger.info("当前正在使用 google公共EAB授权");
|
||||||
|
eab = await this.ctx.accessService.getById(this.googleCommonEabAccessId);
|
||||||
} else {
|
} else {
|
||||||
this.logger.error("google需要配置EAB授权或服务账号授权");
|
this.logger.error("google需要配置EAB授权或服务账号授权");
|
||||||
return;
|
return;
|
||||||
@@ -260,7 +272,7 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.eab = eab;
|
||||||
this.acme = new AcmeService({
|
this.acme = new AcmeService({
|
||||||
userContext: this.userContext,
|
userContext: this.userContext,
|
||||||
logger: this.logger,
|
logger: this.logger,
|
||||||
@@ -276,7 +288,10 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async doCertApply() {
|
async doCertApply() {
|
||||||
const email = this["email"];
|
let email = this.email;
|
||||||
|
if (this.eab && this.eab.email) {
|
||||||
|
email = this.eab.email;
|
||||||
|
}
|
||||||
const domains = this["domains"];
|
const domains = this["domains"];
|
||||||
|
|
||||||
const csrInfo = _.merge(
|
const csrInfo = _.merge(
|
||||||
|
|||||||
@@ -3,6 +3,14 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.26.4](https://github.com/certd/certd/compare/v1.26.3...v1.26.4) (2024-10-14)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* [comm] 支持插件管理 ([e8b617b](https://github.com/certd/certd/commit/e8b617b80ce882dd63006f0cfc719a80a1cc6acc))
|
||||||
|
* 新增代理设置功能 ([273ab61](https://github.com/certd/certd/commit/273ab6139f5807f4d7fe865cc353b97f51b9a668))
|
||||||
|
* EAB授权支持绑定邮箱,支持公共EAB设置 ([07043af](https://github.com/certd/certd/commit/07043aff0ca7fd29c56dd3c363002cb15d78b464))
|
||||||
|
|
||||||
## [1.26.3](https://github.com/certd/certd/compare/v1.26.2...v1.26.3) (2024-10-12)
|
## [1.26.3](https://github.com/certd/certd/compare/v1.26.2...v1.26.3) (2024-10-12)
|
||||||
|
|
||||||
### Performance Improvements
|
### Performance Improvements
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/ui-client",
|
"name": "@certd/ui-client",
|
||||||
"version": "1.26.3",
|
"version": "1.26.4",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite --open",
|
"dev": "vite --open",
|
||||||
@@ -61,8 +61,8 @@
|
|||||||
"vuedraggable": "^4.1.0"
|
"vuedraggable": "^4.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@certd/lib-iframe": "^1.26.3",
|
"@certd/lib-iframe": "^1.26.4",
|
||||||
"@certd/pipeline": "^1.26.3",
|
"@certd/pipeline": "^1.26.4",
|
||||||
"@rollup/plugin-commonjs": "^25.0.7",
|
"@rollup/plugin-commonjs": "^25.0.7",
|
||||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||||
"@types/chai": "^4.3.12",
|
"@types/chai": "^4.3.12",
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ export type SiteEnv = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
export type SiteInfo = {
|
export type SiteInfo = {
|
||||||
title: string;
|
title?: string;
|
||||||
slogan: string;
|
slogan?: string;
|
||||||
logo: string;
|
logo?: string;
|
||||||
loginLogo: string;
|
loginLogo?: string;
|
||||||
icpNo: string;
|
icpNo?: string;
|
||||||
licenseTo?: string;
|
licenseTo?: string;
|
||||||
licenseToUrl?: string;
|
licenseToUrl?: string;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ async function doActive() {
|
|||||||
}
|
}
|
||||||
const res = await api.doActive(formState);
|
const res = await api.doActive(formState);
|
||||||
if (res) {
|
if (res) {
|
||||||
await userStore.reInit();
|
await settingStore.init();
|
||||||
const vipLabel = settingStore.vipLabel;
|
const vipLabel = settingStore.vipLabel;
|
||||||
Modal.success({
|
Modal.success({
|
||||||
title: "激活成功",
|
title: "激活成功",
|
||||||
|
|||||||
@@ -77,10 +77,10 @@
|
|||||||
<a :href="siteInfo.licenseToUrl || ''">{{ siteInfo.licenseTo }}</a>
|
<a :href="siteInfo.licenseToUrl || ''">{{ siteInfo.licenseTo }}</a>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-if="siteInfo.icpNo">
|
<template v-if="sysPublic.icpNo">
|
||||||
<a-divider type="vertical" />
|
<a-divider type="vertical" />
|
||||||
<span>
|
<span>
|
||||||
<a href="https://beian.miit.gov.cn/" target="_blank">{{ siteInfo.icpNo }}</a>
|
<a href="https://beian.miit.gov.cn/" target="_blank">{{ sysPublic.icpNo }}</a>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
@@ -93,7 +93,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, onErrorCaptured, ref } from "vue";
|
import { computed, onErrorCaptured, onMounted, ref } from "vue";
|
||||||
import FsMenu from "./components/menu/index.jsx";
|
import FsMenu from "./components/menu/index.jsx";
|
||||||
import FsLocale from "./components/locale/index.vue";
|
import FsLocale from "./components/locale/index.vue";
|
||||||
import FsUserInfo from "./components/user-info/index.vue";
|
import FsUserInfo from "./components/user-info/index.vue";
|
||||||
@@ -140,9 +140,16 @@ const userStore = useUserStore();
|
|||||||
|
|
||||||
const settingStore = useSettingStore();
|
const settingStore = useSettingStore();
|
||||||
|
|
||||||
|
const sysPublic = computed(() => {
|
||||||
|
return settingStore.sysPublic;
|
||||||
|
});
|
||||||
const siteInfo = computed(() => {
|
const siteInfo = computed(() => {
|
||||||
return settingStore.siteInfo;
|
return settingStore.siteInfo;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await settingStore.checkUrlBound();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
@import "../style/theme/index.less";
|
@import "../style/theme/index.less";
|
||||||
|
|||||||
@@ -27,9 +27,9 @@
|
|||||||
<a-divider type="vertical" />
|
<a-divider type="vertical" />
|
||||||
<a :href="siteInfo.licenseToUrl" target="_blank">{{ siteInfo.licenseTo }}</a>
|
<a :href="siteInfo.licenseToUrl" target="_blank">{{ siteInfo.licenseTo }}</a>
|
||||||
</span>
|
</span>
|
||||||
<span v-if="siteInfo.icpNo">
|
<span v-if="sysPublic.icpNo">
|
||||||
<a-divider type="vertical" />
|
<a-divider type="vertical" />
|
||||||
<a href="https://beian.miit.gov.cn/" target="_blank">{{ siteInfo.icpNo }}</a>
|
<a href="https://beian.miit.gov.cn/" target="_blank">{{ sysPublic.icpNo }}</a>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -40,13 +40,17 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { env } from "/@/utils/util.env";
|
import { env } from "/@/utils/util.env";
|
||||||
import { computed, ref, Ref } from "vue";
|
import { computed, ref, Ref } from "vue";
|
||||||
import { SiteInfo, useSettingStore } from "/@/store/modules/settings";
|
import { useSettingStore } from "/@/store/modules/settings";
|
||||||
|
import { SiteInfo, SysPublicSetting } from "/@/api/modules/api.basic";
|
||||||
|
|
||||||
const envRef = ref(env);
|
const envRef = ref(env);
|
||||||
const settingStore = useSettingStore();
|
const settingStore = useSettingStore();
|
||||||
const siteInfo: Ref<SiteInfo> = computed(() => {
|
const siteInfo: Ref<SiteInfo> = computed(() => {
|
||||||
return settingStore.siteInfo;
|
return settingStore.siteInfo;
|
||||||
});
|
});
|
||||||
|
const sysPublic: Ref<SysPublicSetting> = computed(() => {
|
||||||
|
return settingStore.sysPublic;
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ function install(app: App, options: any = {}) {
|
|||||||
//固定label宽度
|
//固定label宽度
|
||||||
span: null,
|
span: null,
|
||||||
style: {
|
style: {
|
||||||
width: "120px"
|
width: "145px"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async afterSubmit({ mode }) {
|
async afterSubmit({ mode }) {
|
||||||
@@ -182,86 +182,7 @@ function install(app: App, options: any = {}) {
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
app.use(FsExtendsUploader, {
|
app.use(FsExtendsUploader, {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
defaultType: "cos",
|
defaultType: "form",
|
||||||
cos: {
|
|
||||||
keepName: true,
|
|
||||||
domain: "https://d2p-demo-1251260344.cos.ap-guangzhou.myqcloud.com",
|
|
||||||
bucket: "d2p-plugins-1251260344",
|
|
||||||
region: "ap-guangzhou",
|
|
||||||
secretId: "", //
|
|
||||||
secretKey: "", // 传了secretKey 和secretId 代表使用本地签名模式(不安全,生产环境不推荐)
|
|
||||||
async getAuthorization(custom: any) {
|
|
||||||
// 不传secretKey代表使用临时签名模式,此时此参数必传(安全,生产环境推荐)
|
|
||||||
const ret = request({
|
|
||||||
url: "http://www.docmirror.cn:7070/api/upload/cos/getAuthorization",
|
|
||||||
method: "get"
|
|
||||||
});
|
|
||||||
// 返回结构要求如下
|
|
||||||
// ret.data:{
|
|
||||||
// TmpSecretId,
|
|
||||||
// TmpSecretKey,
|
|
||||||
// XCosSecurityToken,
|
|
||||||
// ExpiredTime, // SDK 在 ExpiredTime 时间前,不会再次调用 getAuthorization
|
|
||||||
// }
|
|
||||||
return ret;
|
|
||||||
},
|
|
||||||
successHandle(ret: any) {
|
|
||||||
// 上传完成后可以在此处处理结果,修改url什么的
|
|
||||||
console.log("success handle:", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
alioss: {
|
|
||||||
keepName: true,
|
|
||||||
domain: "https://d2p-demo.oss-cn-shenzhen.aliyuncs.com",
|
|
||||||
bucket: "d2p-plugins",
|
|
||||||
region: "oss-cn-shenzhen",
|
|
||||||
accessKeyId: "",
|
|
||||||
accessKeySecret: "",
|
|
||||||
async getAuthorization(context: FsUploaderGetAuthContext): Promise<FsUploaderAliossSTS> {
|
|
||||||
// 不传accessKeySecret代表使用临时签名模式,此时此参数必传(安全,生产环境推荐)
|
|
||||||
const ret = await request({
|
|
||||||
url: "http://www.docmirror.cn:7070/api/upload/alioss/getAuthorization",
|
|
||||||
method: "get"
|
|
||||||
});
|
|
||||||
console.log("ret", ret);
|
|
||||||
// 返回结构要求如下
|
|
||||||
// ret.data:{
|
|
||||||
// TmpSecretId,
|
|
||||||
// TmpSecretKey,
|
|
||||||
// XCosSecurityToken,
|
|
||||||
// ExpiredTime, // SDK 在 ExpiredTime 时间前,不会再次调用 getAuthorization
|
|
||||||
// key //【可选】后台生成的文件key,如果不传则用前端自己生成的key
|
|
||||||
// }
|
|
||||||
return ret;
|
|
||||||
},
|
|
||||||
sdkOpts: {
|
|
||||||
// sdk配置
|
|
||||||
secure: true // 默认为非https上传,为了安全,设置为true
|
|
||||||
},
|
|
||||||
successHandle(ret: any) {
|
|
||||||
// 上传完成后可以在此处处理结果,修改url什么的
|
|
||||||
console.log("success handle:", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
qiniu: {
|
|
||||||
keepName: true,
|
|
||||||
bucket: "d2p-plugins",
|
|
||||||
async getToken(options: any) {
|
|
||||||
const ret = await request({
|
|
||||||
url: "http://www.docmirror.cn:7070/api/upload/qiniu/getToken",
|
|
||||||
method: "get"
|
|
||||||
});
|
|
||||||
return ret; // {token:xxx,expires:xxx}
|
|
||||||
},
|
|
||||||
successHandle(ret: any) {
|
|
||||||
// 上传完成后可以在此处处理结果,修改url什么的
|
|
||||||
console.log("success handle:", ret);
|
|
||||||
return ret;
|
|
||||||
},
|
|
||||||
domain: "http://d2p.file.handsfree.work/"
|
|
||||||
},
|
|
||||||
form: {
|
form: {
|
||||||
keepName: true,
|
keepName: true,
|
||||||
action: "http://www.docmirror.cn:7070/api/upload/form/upload",
|
action: "http://www.docmirror.cn:7070/api/upload/form/upload",
|
||||||
@@ -313,6 +234,11 @@ function install(app: App, options: any = {}) {
|
|||||||
//此处演示修改官方字段类型
|
//此处演示修改官方字段类型
|
||||||
const textType = getType("text");
|
const textType = getType("text");
|
||||||
textType.search.autoSearchTrigger = "change"; //修改官方的字段类型,变化就触发 , "enter"=回车键触发
|
textType.search.autoSearchTrigger = "change"; //修改官方的字段类型,变化就触发 , "enter"=回车键触发
|
||||||
|
if (!textType.column) {
|
||||||
|
textType.column = {};
|
||||||
|
}
|
||||||
|
textType.column.ellipsis = true;
|
||||||
|
textType.column.showTitle = true;
|
||||||
|
|
||||||
// 此处演示自定义字段类型
|
// 此处演示自定义字段类型
|
||||||
addTypes({
|
addTypes({
|
||||||
|
|||||||
@@ -68,6 +68,48 @@ export const sysResources = [
|
|||||||
permission: "sys:settings:view"
|
permission: "sys:settings:view"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: "系统级授权",
|
||||||
|
name: "SysAccess",
|
||||||
|
path: "/sys/access",
|
||||||
|
component: "/sys/access/index.vue",
|
||||||
|
meta: {
|
||||||
|
show: () => {
|
||||||
|
const settingStore = useSettingStore();
|
||||||
|
return settingStore.isComm;
|
||||||
|
},
|
||||||
|
icon: "ion:disc-outline",
|
||||||
|
permission: "sys:settings:view"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "插件管理",
|
||||||
|
name: "SysPlugin",
|
||||||
|
path: "/sys/plugin",
|
||||||
|
component: "/sys/plugin/index.vue",
|
||||||
|
meta: {
|
||||||
|
show: () => {
|
||||||
|
const settingStore = useSettingStore();
|
||||||
|
return settingStore.isComm;
|
||||||
|
},
|
||||||
|
icon: "ion:extension-puzzle-outline",
|
||||||
|
permission: "sys:settings:view"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "证书插件配置",
|
||||||
|
name: "SysPluginConfig",
|
||||||
|
path: "/sys/plugin/config",
|
||||||
|
component: "/sys/plugin/config.vue",
|
||||||
|
meta: {
|
||||||
|
show: () => {
|
||||||
|
const settingStore = useSettingStore();
|
||||||
|
return settingStore.isComm;
|
||||||
|
},
|
||||||
|
icon: "ion:extension-puzzle",
|
||||||
|
permission: "sys:settings:view"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: "账号绑定",
|
title: "账号绑定",
|
||||||
name: "AccountBind",
|
name: "AccountBind",
|
||||||
|
|||||||
@@ -44,12 +44,11 @@ const defaultThemeConfig = {
|
|||||||
mode: "light"
|
mode: "light"
|
||||||
};
|
};
|
||||||
const SETTING_THEME_KEY = "SETTING_THEME";
|
const SETTING_THEME_KEY = "SETTING_THEME";
|
||||||
const defaultSiteInfo = {
|
const defaultSiteInfo: SiteInfo = {
|
||||||
title: env.TITLE || "Certd",
|
title: env.TITLE || "Certd",
|
||||||
slogan: env.SLOGAN || "让你的证书永不过期",
|
slogan: env.SLOGAN || "让你的证书永不过期",
|
||||||
logo: env.LOGO || "/static/images/logo/logo.svg",
|
logo: env.LOGO || "/static/images/logo/logo.svg",
|
||||||
loginLogo: env.LOGIN_LOGO || "/static/images/logo/rect-block.svg",
|
loginLogo: env.LOGIN_LOGO || "/static/images/logo/rect-block.svg",
|
||||||
icpNo: env.ICP_NO,
|
|
||||||
licenseTo: "",
|
licenseTo: "",
|
||||||
licenseToUrl: ""
|
licenseToUrl: ""
|
||||||
};
|
};
|
||||||
@@ -69,7 +68,7 @@ export const useSettingStore = defineStore({
|
|||||||
sysPublic: {
|
sysPublic: {
|
||||||
registerEnabled: false,
|
registerEnabled: false,
|
||||||
managerOtherUserPipeline: false,
|
managerOtherUserPipeline: false,
|
||||||
icpNo: ""
|
icpNo: env.ICP_NO || ""
|
||||||
},
|
},
|
||||||
installInfo: {
|
installInfo: {
|
||||||
siteId: "",
|
siteId: "",
|
||||||
@@ -136,7 +135,6 @@ export const useSettingStore = defineStore({
|
|||||||
_.merge(this.plusInfo, allSettings.plusInfo || {});
|
_.merge(this.plusInfo, allSettings.plusInfo || {});
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
this.initSiteInfo(allSettings.siteInfo || {});
|
this.initSiteInfo(allSettings.siteInfo || {});
|
||||||
await this.checkUrlBound();
|
|
||||||
},
|
},
|
||||||
initSiteInfo(siteInfo: SiteInfo) {
|
initSiteInfo(siteInfo: SiteInfo) {
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
@@ -148,11 +146,6 @@ export const useSettingStore = defineStore({
|
|||||||
siteInfo.loginLogo = `/api/basic/file/download?key=${siteInfo.loginLogo}`;
|
siteInfo.loginLogo = `/api/basic/file/download?key=${siteInfo.loginLogo}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const sysPublic = this.getSysPublic;
|
|
||||||
if (sysPublic.icpNo) {
|
|
||||||
siteInfo.icpNo = sysPublic.icpNo;
|
|
||||||
}
|
|
||||||
this.siteInfo = _.merge({}, defaultSiteInfo, siteInfo);
|
this.siteInfo = _.merge({}, defaultSiteInfo, siteInfo);
|
||||||
},
|
},
|
||||||
async checkUrlBound() {
|
async checkUrlBound() {
|
||||||
|
|||||||
@@ -222,3 +222,8 @@ h1, h2, h3, h4, h5, h6 {
|
|||||||
/* right: 0; */
|
/* right: 0; */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.settings-form {
|
||||||
|
width: 800px;
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,33 +1,32 @@
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import * as api from "/@/views/certd/access/api";
|
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import { getCommonColumnDefine } from "/@/views/certd/access/common";
|
import { getCommonColumnDefine } from "/@/views/certd/access/common";
|
||||||
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||||
|
|
||||||
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||||
const { crudBinding } = crudExpose;
|
const { crudBinding } = crudExpose;
|
||||||
const { props, ctx } = context;
|
const { props, ctx, api } = context;
|
||||||
const lastResRef = ref();
|
const lastResRef = ref();
|
||||||
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
||||||
return await api.GetList(query);
|
return await context.api.GetList(query);
|
||||||
};
|
};
|
||||||
const editRequest = async (req: EditReq) => {
|
const editRequest = async (req: EditReq) => {
|
||||||
const { form, row } = req;
|
const { form, row } = req;
|
||||||
form.id = row.id;
|
form.id = row.id;
|
||||||
form.type = props.type;
|
form.type = props.type;
|
||||||
const res = await api.UpdateObj(form);
|
const res = await context.api.UpdateObj(form);
|
||||||
lastResRef.value = res;
|
lastResRef.value = res;
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
const delRequest = async (req: DelReq) => {
|
const delRequest = async (req: DelReq) => {
|
||||||
const { row } = req;
|
const { row } = req;
|
||||||
return await api.DelObj(row.id);
|
return await context.api.DelObj(row.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
const addRequest = async (req: AddReq) => {
|
const addRequest = async (req: AddReq) => {
|
||||||
const { form } = req;
|
const { form } = req;
|
||||||
form.type = props.type;
|
form.type = props.type;
|
||||||
const res = await api.AddObj(form);
|
const res = await context.api.AddObj(form);
|
||||||
lastResRef.value = res;
|
lastResRef.value = res;
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
@@ -41,7 +40,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
|
|
||||||
const typeRef = ref("aliyun");
|
const typeRef = ref("aliyun");
|
||||||
context.typeRef = typeRef;
|
context.typeRef = typeRef;
|
||||||
const commonColumnsDefine = getCommonColumnDefine(crudExpose, typeRef);
|
const commonColumnsDefine = getCommonColumnDefine(crudExpose, typeRef, api);
|
||||||
commonColumnsDefine.type.form.component.disabled = true;
|
commonColumnsDefine.type.form.component.disabled = true;
|
||||||
return {
|
return {
|
||||||
typeRef,
|
typeRef,
|
||||||
@@ -109,6 +108,33 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
width: 200
|
width: 200
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
from: {
|
||||||
|
title: "级别",
|
||||||
|
type: "dict-select",
|
||||||
|
dict: dict({
|
||||||
|
data: [
|
||||||
|
{ label: "系统", value: "sys" },
|
||||||
|
{ label: "用户", value: "user" }
|
||||||
|
]
|
||||||
|
}),
|
||||||
|
search: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
column: {
|
||||||
|
width: 100,
|
||||||
|
align: "center",
|
||||||
|
component: {
|
||||||
|
color: "auto"
|
||||||
|
},
|
||||||
|
order: 10
|
||||||
|
},
|
||||||
|
valueBuilder: ({ row, key, value }) => {
|
||||||
|
row[key] = row.userId > 0 ? "user" : "sys";
|
||||||
|
}
|
||||||
|
},
|
||||||
...commonColumnsDefine
|
...commonColumnsDefine
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
import { defineComponent, onMounted, watch } from "vue";
|
import { defineComponent, onMounted, watch } from "vue";
|
||||||
import { useFs } from "@fast-crud/fast-crud";
|
import { useFs } from "@fast-crud/fast-crud";
|
||||||
import createCrudOptions from "./crud";
|
import createCrudOptions from "./crud";
|
||||||
|
import { createAccessApi } from "/@/views/certd/access/api";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "CertAccessModal",
|
name: "CertAccessModal",
|
||||||
@@ -16,11 +17,16 @@ export default defineComponent({
|
|||||||
type: String,
|
type: String,
|
||||||
default: "aliyun"
|
default: "aliyun"
|
||||||
},
|
},
|
||||||
|
from: {
|
||||||
|
type: String, //user | sys
|
||||||
|
default: "user"
|
||||||
|
},
|
||||||
modelValue: {}
|
modelValue: {}
|
||||||
},
|
},
|
||||||
emits: ["update:modelValue"],
|
emits: ["update:modelValue"],
|
||||||
setup(props, ctx) {
|
setup(props, ctx) {
|
||||||
const context: any = { props, ctx };
|
const api = createAccessApi(props.from);
|
||||||
|
const context: any = { props, ctx, api };
|
||||||
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context });
|
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context });
|
||||||
|
|
||||||
// 你可以调用此方法,重新初始化crud配置
|
// 你可以调用此方法,重新初始化crud配置
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="access-selector">
|
<div class="access-selector">
|
||||||
<span v-if="target.name" class="mr-5 cd-flex-inline">
|
<span v-if="target.name" class="mr-5 cd-flex-inline">
|
||||||
<span class="mr-5">{{ target.name }}</span>
|
<a-tag class="mr-5" color="green">{{ target.name }}</a-tag>
|
||||||
<fs-icon class="cd-icon-button" icon="ion:close-circle-outline" @click="clear"></fs-icon>
|
<fs-icon class="cd-icon-button" icon="ion:close-circle-outline" @click="clear"></fs-icon>
|
||||||
</span>
|
</span>
|
||||||
<span v-else class="mlr-5 text-gray">{{ placeholder }}</span>
|
<span v-else class="mlr-5 text-gray">{{ placeholder }}</span>
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
<a-form-item-rest v-if="chooseForm.show">
|
<a-form-item-rest v-if="chooseForm.show">
|
||||||
<a-modal v-model:open="chooseForm.show" title="选择授权提供者" width="900px" @ok="chooseForm.ok">
|
<a-modal v-model:open="chooseForm.show" title="选择授权提供者" width="900px" @ok="chooseForm.ok">
|
||||||
<div style="height: 400px; position: relative">
|
<div style="height: 400px; position: relative">
|
||||||
<cert-access-modal v-model="selectedId" :type="type"></cert-access-modal>
|
<cert-access-modal v-model="selectedId" :type="type" :from="from"></cert-access-modal>
|
||||||
</div>
|
</div>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</a-form-item-rest>
|
</a-form-item-rest>
|
||||||
@@ -18,9 +18,8 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { defineComponent, reactive, ref, watch } from "vue";
|
import { defineComponent, reactive, ref, watch } from "vue";
|
||||||
import * as api from "../api";
|
|
||||||
import CertAccessModal from "./access/index.vue";
|
import CertAccessModal from "./access/index.vue";
|
||||||
import { GetProviderDefineByAccessType } from "../api";
|
import { createAccessApi } from "../api";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "AccessSelector",
|
name: "AccessSelector",
|
||||||
@@ -41,10 +40,16 @@ export default defineComponent({
|
|||||||
size: {
|
size: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "middle"
|
default: "middle"
|
||||||
|
},
|
||||||
|
from: {
|
||||||
|
type: String, //user | sys
|
||||||
|
default: "user"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
emits: ["update:modelValue"],
|
emits: ["update:modelValue"],
|
||||||
setup(props, ctx) {
|
setup(props, ctx) {
|
||||||
|
const api = createAccessApi(props.from);
|
||||||
|
|
||||||
const target = ref({});
|
const target = ref({});
|
||||||
const selectedId = ref();
|
const selectedId = ref();
|
||||||
async function refreshTarget(value) {
|
async function refreshTarget(value) {
|
||||||
|
|||||||
@@ -1,57 +1,62 @@
|
|||||||
import { request } from "/src/api/service";
|
import { request } from "/src/api/service";
|
||||||
const apiPrefix = "/pi/access";
|
|
||||||
export async function GetList(query: any) {
|
|
||||||
return await request({
|
|
||||||
url: apiPrefix + "/page",
|
|
||||||
method: "post",
|
|
||||||
data: query
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function AddObj(obj: any) {
|
export function createAccessApi(from = "user") {
|
||||||
return await request({
|
const apiPrefix = from === "sys" ? "/sys/access" : "/pi/access";
|
||||||
url: apiPrefix + "/add",
|
return {
|
||||||
method: "post",
|
async GetList(query: any) {
|
||||||
data: obj
|
return await request({
|
||||||
});
|
url: apiPrefix + "/page",
|
||||||
}
|
method: "post",
|
||||||
|
data: query
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
export async function UpdateObj(obj: any) {
|
async AddObj(obj: any) {
|
||||||
return await request({
|
return await request({
|
||||||
url: apiPrefix + "/update",
|
url: apiPrefix + "/add",
|
||||||
method: "post",
|
method: "post",
|
||||||
data: obj
|
data: obj
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
|
|
||||||
export async function DelObj(id: number) {
|
async UpdateObj(obj: any) {
|
||||||
return await request({
|
return await request({
|
||||||
url: apiPrefix + "/delete",
|
url: apiPrefix + "/update",
|
||||||
method: "post",
|
method: "post",
|
||||||
params: { id }
|
data: obj
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
|
|
||||||
export async function GetObj(id: number) {
|
async DelObj(id: number) {
|
||||||
return await request({
|
return await request({
|
||||||
url: apiPrefix + "/info",
|
url: apiPrefix + "/delete",
|
||||||
method: "post",
|
method: "post",
|
||||||
params: { id }
|
params: { id }
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
|
|
||||||
export async function GetProviderDefine(type: string) {
|
async GetObj(id: number) {
|
||||||
return await request({
|
return await request({
|
||||||
url: apiPrefix + "/define",
|
url: apiPrefix + "/info",
|
||||||
method: "post",
|
method: "post",
|
||||||
params: { type }
|
params: { id }
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
|
|
||||||
export async function GetProviderDefineByAccessType(type: string) {
|
async GetProviderDefine(type: string) {
|
||||||
return await request({
|
return await request({
|
||||||
url: apiPrefix + "/defineByAccessType",
|
url: apiPrefix + "/define",
|
||||||
method: "post",
|
method: "post",
|
||||||
params: { type }
|
params: { type }
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
async GetProviderDefineByAccessType(type: string) {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/defineByAccessType",
|
||||||
|
method: "post",
|
||||||
|
params: { type }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
import { ColumnCompositionProps, dict, compute } from "@fast-crud/fast-crud";
|
import { ColumnCompositionProps, dict } from "@fast-crud/fast-crud";
|
||||||
// @ts-ignore
|
|
||||||
import * as api from "./api";
|
|
||||||
// @ts-ignore
|
|
||||||
import _ from "lodash-es";
|
|
||||||
import { computed, ref, toRef } from "vue";
|
import { computed, ref, toRef } from "vue";
|
||||||
import { useReference } from "/@/use/use-refrence";
|
import { useReference } from "/@/use/use-refrence";
|
||||||
|
import { forEach, get, merge, set } from "lodash-es";
|
||||||
|
|
||||||
export function getCommonColumnDefine(crudExpose: any, typeRef: any) {
|
export function getCommonColumnDefine(crudExpose: any, typeRef: any, api: any) {
|
||||||
const AccessTypeDictRef = dict({
|
const AccessTypeDictRef = dict({
|
||||||
url: "/pi/access/accessTypeDict"
|
url: "/pi/access/accessTypeDict"
|
||||||
});
|
});
|
||||||
@@ -27,20 +24,20 @@ export function getCommonColumnDefine(crudExpose: any, typeRef: any) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log('crudBinding.value[mode + "Form"].columns', columnsRef.value);
|
console.log('crudBinding.value[mode + "Form"].columns', columnsRef.value);
|
||||||
_.forEach(define.input, (value: any, mapKey: any) => {
|
forEach(define.input, (value: any, mapKey: any) => {
|
||||||
const key = "access." + mapKey;
|
const key = "access." + mapKey;
|
||||||
const field = {
|
const field = {
|
||||||
...value,
|
...value,
|
||||||
key
|
key
|
||||||
};
|
};
|
||||||
const column = _.merge({ title: key }, defaultPluginConfig, field);
|
const column = merge({ title: key }, defaultPluginConfig, field);
|
||||||
|
|
||||||
//eval
|
//eval
|
||||||
useReference(column);
|
useReference(column);
|
||||||
|
|
||||||
//设置默认值
|
//设置默认值
|
||||||
if (column.value != null && _.get(form, key) == null) {
|
if (column.value != null && get(form, key) == null) {
|
||||||
_.set(form, key, column.value);
|
set(form, key, column.value);
|
||||||
}
|
}
|
||||||
//字段配置赋值
|
//字段配置赋值
|
||||||
columnsRef.value[key] = column;
|
columnsRef.value[key] = column;
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import * as api from "./api";
|
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import { getCommonColumnDefine } from "/@/views/certd/access/common";
|
import { getCommonColumnDefine } from "/@/views/certd/access/common";
|
||||||
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||||
|
|
||||||
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
const api = context.api;
|
||||||
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
||||||
return await api.GetList(query);
|
return await api.GetList(query);
|
||||||
};
|
};
|
||||||
@@ -28,7 +28,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
|
|||||||
};
|
};
|
||||||
|
|
||||||
const typeRef = ref();
|
const typeRef = ref();
|
||||||
const commonColumnsDefine = getCommonColumnDefine(crudExpose, typeRef);
|
const commonColumnsDefine = getCommonColumnDefine(crudExpose, typeRef, api);
|
||||||
return {
|
return {
|
||||||
crudOptions: {
|
crudOptions: {
|
||||||
request: {
|
request: {
|
||||||
|
|||||||
@@ -14,11 +14,13 @@
|
|||||||
import { defineComponent, onMounted } from "vue";
|
import { defineComponent, onMounted } from "vue";
|
||||||
import { useFs } from "@fast-crud/fast-crud";
|
import { useFs } from "@fast-crud/fast-crud";
|
||||||
import createCrudOptions from "./crud";
|
import createCrudOptions from "./crud";
|
||||||
|
import { createAccessApi } from "/@/views/certd/access/api";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "AccessManager",
|
name: "AccessManager",
|
||||||
setup() {
|
setup() {
|
||||||
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: {} });
|
const api = createAccessApi("user");
|
||||||
|
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: { api } });
|
||||||
|
|
||||||
// 页面打开后获取列表数据
|
// 页面打开后获取列表数据
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { request } from "/src/api/service";
|
import { request } from "/src/api/service";
|
||||||
import _ from "lodash-es";
|
import _ from "lodash-es";
|
||||||
|
import { PluginConfigBean, PluginSysSetting } from "/@/views/sys/plugin/api";
|
||||||
const apiPrefix = "/pi/plugin";
|
const apiPrefix = "/pi/plugin";
|
||||||
|
|
||||||
const defaultInputDefine = {
|
const defaultInputDefine = {
|
||||||
@@ -54,3 +55,11 @@ export async function GetGroups(query: any) {
|
|||||||
initPlugins(plugins);
|
initPlugins(plugins);
|
||||||
return groups;
|
return groups;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function GetPluginConfig(req: { id?: number; name: string; type: string }): Promise<PluginConfigBean> {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/config",
|
||||||
|
method: "post",
|
||||||
|
data: req
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { compute, CreateCrudOptionsRet, dict } from "@fast-crud/fast-crud";
|
import { compute, CreateCrudOptionsRet, dict } from "@fast-crud/fast-crud";
|
||||||
import { PluginGroup } from "@certd/pipeline";
|
import { PluginGroup } from "@certd/pipeline";
|
||||||
import { useReference } from "/@/use/use-refrence";
|
import { useReference } from "/@/use/use-refrence";
|
||||||
import _ from "lodash-es";
|
import _, { merge } from "lodash-es";
|
||||||
import { useUserStore } from "/@/store/modules/user";
|
import { useUserStore } from "/@/store/modules/user";
|
||||||
import { useSettingStore } from "/@/store/modules/settings";
|
import { useSettingStore } from "/@/store/modules/settings";
|
||||||
|
import * as api from "../api.plugin";
|
||||||
export default function (certPluginGroup: PluginGroup, formWrapperRef: any): CreateCrudOptionsRet {
|
export default function (certPluginGroup: PluginGroup, formWrapperRef: any): CreateCrudOptionsRet {
|
||||||
const inputs: any = {};
|
const inputs: any = {};
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
@@ -46,7 +46,7 @@ export default function (certPluginGroup: PluginGroup, formWrapperRef: any): Cre
|
|||||||
crudOptions: {
|
crudOptions: {
|
||||||
form: {
|
form: {
|
||||||
wrapper: {
|
wrapper: {
|
||||||
width: "1150px",
|
width: 1350,
|
||||||
saveRemind: false,
|
saveRemind: false,
|
||||||
title: "创建证书申请流水线"
|
title: "创建证书申请流水线"
|
||||||
}
|
}
|
||||||
@@ -73,6 +73,19 @@ export default function (certPluginGroup: PluginGroup, formWrapperRef: any): Cre
|
|||||||
</ul>
|
</ul>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
valueChange: {
|
||||||
|
handle: async ({ form, value }) => {
|
||||||
|
debugger;
|
||||||
|
const config = await api.GetPluginConfig({
|
||||||
|
name: value,
|
||||||
|
type: "builtIn"
|
||||||
|
});
|
||||||
|
if (config.sysSetting?.input) {
|
||||||
|
merge(form, config.sysSetting.input);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ import { useUserStore } from "/@/store/modules/user";
|
|||||||
import { compute, useCompute } from "@fast-crud/fast-crud";
|
import { compute, useCompute } from "@fast-crud/fast-crud";
|
||||||
import { useReference } from "/@/use/use-refrence";
|
import { useReference } from "/@/use/use-refrence";
|
||||||
import { useSettingStore } from "/@/store/modules/settings";
|
import { useSettingStore } from "/@/store/modules/settings";
|
||||||
|
import * as pluginApi from "../../../api.plugin";
|
||||||
export default {
|
export default {
|
||||||
name: "PiStepForm",
|
name: "PiStepForm",
|
||||||
// eslint-disable-next-line vue/no-unused-components
|
// eslint-disable-next-line vue/no-unused-components
|
||||||
@@ -163,7 +163,7 @@ export default {
|
|||||||
console.log("currentStepTypeChanged:", currentStep.value);
|
console.log("currentStepTypeChanged:", currentStep.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const stepTypeSave = () => {
|
const stepTypeSave = async () => {
|
||||||
currentStep.value._isAdd = false;
|
currentStep.value._isAdd = false;
|
||||||
if (currentStep.value.type == null) {
|
if (currentStep.value.type == null) {
|
||||||
message.warn("请先选择类型");
|
message.warn("请先选择类型");
|
||||||
@@ -171,7 +171,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 给step的input设置默认值
|
// 给step的input设置默认值
|
||||||
changeCurrentPlugin(currentStep.value);
|
await changeCurrentPlugin(currentStep.value);
|
||||||
|
|
||||||
//合并默认值
|
//合并默认值
|
||||||
_.merge(currentStep.value, { input: {}, strategy: { runStrategy: 0 } }, currentPlugin.value.default, currentStep.value);
|
_.merge(currentStep.value, { input: {}, strategy: { runStrategy: 0 } }, currentPlugin.value.default, currentStep.value);
|
||||||
@@ -229,7 +229,7 @@ export default {
|
|||||||
const currentPlugin = doComputed(() => {
|
const currentPlugin = doComputed(() => {
|
||||||
return currentPluginDefine.value;
|
return currentPluginDefine.value;
|
||||||
}, getContext);
|
}, getContext);
|
||||||
const changeCurrentPlugin = (step: any) => {
|
const changeCurrentPlugin = async (step: any) => {
|
||||||
const stepType = step.type;
|
const stepType = step.type;
|
||||||
step.type = stepType;
|
step.type = stepType;
|
||||||
step._isAdd = false;
|
step._isAdd = false;
|
||||||
@@ -255,6 +255,14 @@ export default {
|
|||||||
currentStep.value.input[key] = column.default ?? column.value;
|
currentStep.value.input[key] = column.default ?? column.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//设置系统初始值
|
||||||
|
debugger;
|
||||||
|
const pluginSysConfig = await pluginApi.GetPluginConfig({ name: pluginDefine.name, type: "builtIn" });
|
||||||
|
if (pluginSysConfig.sysSetting?.input) {
|
||||||
|
for (const key in pluginSysConfig.sysSetting?.input) {
|
||||||
|
currentStep.value.input[key] = pluginSysConfig.sysSetting?.input[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
console.log("currentStepTypeChanged:", currentStep.value);
|
console.log("currentStepTypeChanged:", currentStep.value);
|
||||||
console.log("currentStepPlugin:", currentPlugin.value);
|
console.log("currentStepPlugin:", currentPlugin.value);
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export type PluginGroup = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type PluginDefine = {
|
export type PluginDefine = {
|
||||||
key: string;
|
name: string;
|
||||||
title: string;
|
title: string;
|
||||||
desc?: string;
|
desc?: string;
|
||||||
input: {
|
input: {
|
||||||
|
|||||||
36
packages/ui/certd-client/src/views/sys/access/index.vue
Normal file
36
packages/ui/certd-client/src/views/sys/access/index.vue
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
<template>
|
||||||
|
<fs-page>
|
||||||
|
<template #header>
|
||||||
|
<div class="title">
|
||||||
|
系统级授权管理
|
||||||
|
<span class="sub">管理第三方系统的授权信息(系统级)</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<fs-crud ref="crudRef" v-bind="crudBinding"> </fs-crud>
|
||||||
|
</fs-page>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent, onMounted } from "vue";
|
||||||
|
import { useFs } from "@fast-crud/fast-crud";
|
||||||
|
import createCrudOptions from "../../certd/access/crud";
|
||||||
|
import { createAccessApi } from "/@/views/certd/access/api";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: "SysAccessManager",
|
||||||
|
setup() {
|
||||||
|
const api = createAccessApi("/sys/access");
|
||||||
|
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: { api } });
|
||||||
|
|
||||||
|
// 页面打开后获取列表数据
|
||||||
|
onMounted(() => {
|
||||||
|
crudExpose.doRefresh();
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
crudBinding,
|
||||||
|
crudRef
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@@ -76,18 +76,21 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
domain: {
|
domain: {
|
||||||
title: "域名",
|
title: "CNAME域名",
|
||||||
type: "text",
|
type: "text",
|
||||||
editForm: {
|
editForm: {
|
||||||
component: {
|
component: {
|
||||||
disabled: true
|
disabled: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
search: {
|
||||||
|
show: true
|
||||||
|
},
|
||||||
form: {
|
form: {
|
||||||
component: {
|
component: {
|
||||||
placeholder: "cname.handsfree.work"
|
placeholder: "cname.handsfree.work"
|
||||||
},
|
},
|
||||||
helper: "CNAME域名一旦确定不可修改,建议使用一级子域名",
|
helper: "需要一个右边DNS提供商注册的域名(也可以将其他域名的dns服务器转移到这几家来)。\nCNAME域名一旦确定不可修改,建议使用一级子域名",
|
||||||
rules: [{ required: true, message: "此项必填" }]
|
rules: [{ required: true, message: "此项必填" }]
|
||||||
},
|
},
|
||||||
column: {
|
column: {
|
||||||
@@ -97,6 +100,9 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
dnsProviderType: {
|
dnsProviderType: {
|
||||||
title: "DNS提供商",
|
title: "DNS提供商",
|
||||||
type: "dict-select",
|
type: "dict-select",
|
||||||
|
search: {
|
||||||
|
show: true
|
||||||
|
},
|
||||||
dict: dict({
|
dict: dict({
|
||||||
url: "pi/dnsProvider/list",
|
url: "pi/dnsProvider/list",
|
||||||
value: "key",
|
value: "key",
|
||||||
|
|||||||
102
packages/ui/certd-client/src/views/sys/plugin/api.ts
Normal file
102
packages/ui/certd-client/src/views/sys/plugin/api.ts
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
import { request } from "/src/api/service";
|
||||||
|
|
||||||
|
const apiPrefix = "/sys/plugin";
|
||||||
|
|
||||||
|
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 }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function SetDisabled(data: { id?: number; name?: string; type?: string; disabled: boolean }) {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/setDisabled",
|
||||||
|
method: "post",
|
||||||
|
data: data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export type PluginConfigBean = {
|
||||||
|
name: string;
|
||||||
|
disabled: boolean;
|
||||||
|
sysSetting: {
|
||||||
|
input?: Record<string, any>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export type CertApplyPluginSysInput = {
|
||||||
|
googleCommonEabAccessId: number;
|
||||||
|
};
|
||||||
|
export type PluginSysSetting<T> = {
|
||||||
|
sysSetting: {
|
||||||
|
input?: T;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
export type CommPluginConfig = {
|
||||||
|
CertApply?: PluginSysSetting<CertApplyPluginSysInput>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export async function GetCommPluginConfigs(): Promise<CommPluginConfig> {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/getCommPluginConfigs",
|
||||||
|
method: "post"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function SaveCommPluginConfigs(data: CommPluginConfig): Promise<void> {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/saveCommPluginConfigs",
|
||||||
|
method: "post",
|
||||||
|
data
|
||||||
|
});
|
||||||
|
}
|
||||||
73
packages/ui/certd-client/src/views/sys/plugin/config.vue
Normal file
73
packages/ui/certd-client/src/views/sys/plugin/config.vue
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
<template>
|
||||||
|
<fs-page class="page-plugin-config">
|
||||||
|
<template #header>
|
||||||
|
<div class="title">证书插件配置</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div class="sys-plugin-config settings-form">
|
||||||
|
<a-form :model="formState" :label-col="{ span: 8 }" :wrapper-col="{ span: 16 }" autocomplete="off" @finish="onFinish" @finish-failed="onFinishFailed">
|
||||||
|
<a-form-item label="公共Google EAB授权" :name="['CertApply', 'sysSetting', 'input', 'googleCommonEabAccessId']">
|
||||||
|
<access-selector v-model:model-value="formState.CertApply.sysSetting.input.googleCommonEabAccessId" type="eab" from="sys"></access-selector>
|
||||||
|
<div class="helper">
|
||||||
|
<div>设置公共Google EAB授权给用户使用,避免用户自己去翻墙获取Google EAB授权</div>
|
||||||
|
<div>
|
||||||
|
<a href="https://gitee.com/certd/certd/blob/v2/doc/google/google.md#21-%E7%9B%B4%E6%8E%A5%E8%8E%B7%E5%8F%96eab-%E6%8E%A8%E8%8D%90">
|
||||||
|
获取Google EAB授权方法
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item :wrapper-col="{ offset: 8, span: 16 }">
|
||||||
|
<a-button :loading="saveLoading" type="primary" html-type="submit">保存</a-button>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</div>
|
||||||
|
</fs-page>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import AccessSelector from "/@/views/certd/access/access-selector/index.vue";
|
||||||
|
import { reactive, ref } from "vue";
|
||||||
|
import { CommPluginConfig, GetCommPluginConfigs, SaveCommPluginConfigs } from "/@/views/sys/plugin/api";
|
||||||
|
import { merge } from "lodash-es";
|
||||||
|
import { notification } from "ant-design-vue";
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: "SysPluginConfig"
|
||||||
|
});
|
||||||
|
const formState = reactive<Partial<CommPluginConfig>>({
|
||||||
|
CertApply: {
|
||||||
|
sysSetting: {
|
||||||
|
input: {
|
||||||
|
googleCommonEabAccessId: null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
async function loadForm() {
|
||||||
|
const res = await GetCommPluginConfigs();
|
||||||
|
merge(formState, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
loadForm();
|
||||||
|
|
||||||
|
const saveLoading = ref(false);
|
||||||
|
const onFinish = async (form: any) => {
|
||||||
|
try {
|
||||||
|
saveLoading.value = true;
|
||||||
|
await SaveCommPluginConfigs(form);
|
||||||
|
notification.success({
|
||||||
|
message: "保存成功"
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
saveLoading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onFinishFailed = (errorInfo: any) => {
|
||||||
|
console.log("Failed:", errorInfo);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="less"></style>
|
||||||
211
packages/ui/certd-client/src/views/sys/plugin/crud.tsx
Normal file
211
packages/ui/certd-client/src/views/sys/plugin/crud.tsx
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
import * as api from "./api";
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
|
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";
|
||||||
|
import { useUserStore } from "/src/store/modules/user";
|
||||||
|
import { useSettingStore } from "/src/store/modules/settings";
|
||||||
|
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) => {
|
||||||
|
form.content = JSON.stringify({
|
||||||
|
title: form.title
|
||||||
|
});
|
||||||
|
const res = await api.AddObj(form);
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
|
const userStore = useUserStore();
|
||||||
|
const settingStore = useSettingStore();
|
||||||
|
const selectedRowKeys: Ref<any[]> = ref([]);
|
||||||
|
context.selectedRowKeys = selectedRowKeys;
|
||||||
|
|
||||||
|
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
|
||||||
|
},
|
||||||
|
actionbar: {
|
||||||
|
buttons: {
|
||||||
|
add: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rowHandle: {
|
||||||
|
minWidth: 200,
|
||||||
|
fixed: "right",
|
||||||
|
buttons: {
|
||||||
|
edit: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
copy: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
remove: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
columns: {
|
||||||
|
id: {
|
||||||
|
title: "ID",
|
||||||
|
key: "id",
|
||||||
|
type: "number",
|
||||||
|
column: {
|
||||||
|
width: 100
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
title: "插件名称",
|
||||||
|
type: "text",
|
||||||
|
search: {
|
||||||
|
show: true
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
column: {
|
||||||
|
width: 200
|
||||||
|
}
|
||||||
|
},
|
||||||
|
icon: {
|
||||||
|
title: "图标",
|
||||||
|
type: "text",
|
||||||
|
form: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
column: {
|
||||||
|
width: 100,
|
||||||
|
align: "center",
|
||||||
|
component: {
|
||||||
|
name: "fs-icon",
|
||||||
|
vModel: "icon",
|
||||||
|
style: {
|
||||||
|
fontSize: "22px"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
title: "标题",
|
||||||
|
type: "text",
|
||||||
|
column: {
|
||||||
|
width: 300
|
||||||
|
}
|
||||||
|
},
|
||||||
|
desc: {
|
||||||
|
title: "描述",
|
||||||
|
type: "text",
|
||||||
|
column: {
|
||||||
|
width: 300
|
||||||
|
}
|
||||||
|
},
|
||||||
|
group: {
|
||||||
|
title: "分组",
|
||||||
|
type: "text",
|
||||||
|
column: {
|
||||||
|
width: 100,
|
||||||
|
align: "center"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
title: "禁用/启用",
|
||||||
|
type: "dict-switch",
|
||||||
|
dict: dict({
|
||||||
|
data: [
|
||||||
|
{ label: "启用", value: false, color: "success" },
|
||||||
|
{ label: "禁用", value: true, color: "error" }
|
||||||
|
]
|
||||||
|
}),
|
||||||
|
form: {
|
||||||
|
value: false
|
||||||
|
},
|
||||||
|
column: {
|
||||||
|
width: 100,
|
||||||
|
align: "center",
|
||||||
|
component: {
|
||||||
|
title: "点击可禁用/启用",
|
||||||
|
on: {
|
||||||
|
async click({ value, row }) {
|
||||||
|
Modal.confirm({
|
||||||
|
title: "提示",
|
||||||
|
content: `确定要${!value ? "禁用" : "启用"}吗?`,
|
||||||
|
onOk: async () => {
|
||||||
|
await api.SetDisabled({
|
||||||
|
id: row.id,
|
||||||
|
name: row.name,
|
||||||
|
type: row.type,
|
||||||
|
disabled: !value
|
||||||
|
});
|
||||||
|
await crudExpose.doRefresh();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
createTime: {
|
||||||
|
title: "创建时间",
|
||||||
|
type: "datetime",
|
||||||
|
form: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
column: {
|
||||||
|
sorter: true,
|
||||||
|
width: 160,
|
||||||
|
align: "center"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updateTime: {
|
||||||
|
title: "更新时间",
|
||||||
|
type: "datetime",
|
||||||
|
form: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
column: {
|
||||||
|
show: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
51
packages/ui/certd-client/src/views/sys/plugin/index.vue
Normal file
51
packages/ui/certd-client/src/views/sys/plugin/index.vue
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<template>
|
||||||
|
<fs-page class="page-cert">
|
||||||
|
<template #header>
|
||||||
|
<div class="title">插件管理</div>
|
||||||
|
</template>
|
||||||
|
<fs-crud ref="crudRef" v-bind="crudBinding">
|
||||||
|
<!-- <template #pagination-left>-->
|
||||||
|
<!-- <a-tooltip title="批量删除">-->
|
||||||
|
<!-- <fs-button icon="DeleteOutlined" @click="handleBatchDelete"></fs-button>-->
|
||||||
|
<!-- </a-tooltip>-->
|
||||||
|
<!-- </template>-->
|
||||||
|
</fs-crud>
|
||||||
|
</fs-page>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { 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";
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: "SysPlugin"
|
||||||
|
});
|
||||||
|
const { crudBinding, crudRef, crudExpose, context } = useFs({ createCrudOptions });
|
||||||
|
|
||||||
|
const selectedRowKeys = context.selectedRowKeys;
|
||||||
|
const handleBatchDelete = () => {
|
||||||
|
if (selectedRowKeys.value?.length > 0) {
|
||||||
|
Modal.confirm({
|
||||||
|
title: "确认",
|
||||||
|
content: `确定要批量删除这${selectedRowKeys.value.length}条记录吗`,
|
||||||
|
async onOk() {
|
||||||
|
await DeleteBatch(selectedRowKeys.value);
|
||||||
|
message.info("删除成功");
|
||||||
|
crudExpose.doRefresh();
|
||||||
|
selectedRowKeys.value = [];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
message.error("请先勾选记录");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 页面打开后获取列表数据
|
||||||
|
onMounted(() => {
|
||||||
|
crudExpose.doRefresh();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style lang="less"></style>
|
||||||
@@ -1,6 +1,18 @@
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { request } from "/@/api/service";
|
import { request } from "/@/api/service";
|
||||||
const apiPrefix = "/sys/settings";
|
const apiPrefix = "/sys/settings";
|
||||||
|
export type SysSettings = { public: SysPublicSetting; private: SysPrivateSetting };
|
||||||
|
|
||||||
|
export type SysPublicSetting = {
|
||||||
|
registerEnabled?: boolean;
|
||||||
|
managerOtherUserPipeline?: boolean;
|
||||||
|
icpNo?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type SysPrivateSetting = {
|
||||||
|
httpProxy?: string;
|
||||||
|
httpsProxy?: string;
|
||||||
|
};
|
||||||
|
|
||||||
export const SettingKeys = {
|
export const SettingKeys = {
|
||||||
SysPublic: "sys.public",
|
SysPublic: "sys.public",
|
||||||
@@ -8,13 +20,17 @@ export const SettingKeys = {
|
|||||||
SysEmail: "sys.email"
|
SysEmail: "sys.email"
|
||||||
};
|
};
|
||||||
export async function SettingsGet(key: string) {
|
export async function SettingsGet(key: string) {
|
||||||
return await request({
|
const res = await request({
|
||||||
url: apiPrefix + "/get",
|
url: apiPrefix + "/get",
|
||||||
method: "post",
|
method: "post",
|
||||||
params: {
|
params: {
|
||||||
key
|
key
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (!res) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return JSON.parse(res.setting);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function SettingsSave(key: string, setting: any) {
|
export async function SettingsSave(key: string, setting: any) {
|
||||||
@@ -35,17 +51,31 @@ export async function EmailSettingsGet() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function PublicSettingsSave(setting: any) {
|
|
||||||
return await request({
|
|
||||||
url: apiPrefix + "/savePublicSettings",
|
|
||||||
method: "post",
|
|
||||||
data: setting
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function stopOtherUserTimer() {
|
export async function stopOtherUserTimer() {
|
||||||
return await request({
|
return await request({
|
||||||
url: apiPrefix + "/stopOtherUserTimer",
|
url: apiPrefix + "/stopOtherUserTimer",
|
||||||
method: "post"
|
method: "post"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function SysSettingsGet(): Promise<SysSettings> {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/getSysSettings",
|
||||||
|
method: "post"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function SysSettingsSave(data: SysSettings) {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/saveSysSettings",
|
||||||
|
method: "post",
|
||||||
|
data: data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function TestProxy() {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/testProxy",
|
||||||
|
method: "post"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<template #header>
|
<template #header>
|
||||||
<div class="title">系统设置</div>
|
<div class="title">系统设置</div>
|
||||||
</template>
|
</template>
|
||||||
<div class="sys-settings-form">
|
<div class="sys-settings-form settings-form">
|
||||||
<a-form
|
<a-form
|
||||||
:model="formState"
|
:model="formState"
|
||||||
name="basic"
|
name="basic"
|
||||||
@@ -13,29 +13,31 @@
|
|||||||
@finish="onFinish"
|
@finish="onFinish"
|
||||||
@finish-failed="onFinishFailed"
|
@finish-failed="onFinishFailed"
|
||||||
>
|
>
|
||||||
<a-form-item label="开启自助注册" name="registerEnabled">
|
<a-form-item label="开启自助注册" :name="['public', 'registerEnabled']">
|
||||||
<a-switch v-model:checked="formState.registerEnabled" />
|
<a-switch v-model:checked="formState.public.registerEnabled" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="管理其他用户流水线" name="managerOtherUserPipeline">
|
<a-form-item label="管理其他用户流水线" :name="['public', 'managerOtherUserPipeline']">
|
||||||
<a-switch v-model:checked="formState.managerOtherUserPipeline" />
|
<a-switch v-model:checked="formState.public.managerOtherUserPipeline" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="ICP备案号" name="icpNo">
|
<a-form-item label="ICP备案号" :name="['public', 'icpNo']">
|
||||||
<a-input v-model:value="formState.icpNo" />
|
<a-input v-model:value="formState.public.icpNo" placeholder="粤ICP备xxxxxxx号" />
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="HTTP代理" :name="['private', 'httpProxy']" :rules="urlRules">
|
||||||
|
<a-input v-model:value="formState.private.httpProxy" placeholder="http://192.168.1.2:18010/" />
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="HTTPS代理" :name="['private', 'httpsProxy']" :rules="urlRules">
|
||||||
|
<div class="flex">
|
||||||
|
<a-input v-model:value="formState.private.httpsProxy" placeholder="http://192.168.1.2:18010/" />
|
||||||
|
<a-button class="ml-5" type="primary" title="保存后,再点击测试" @click="testProxy">测试</a-button>
|
||||||
|
</div>
|
||||||
|
<div class="helper">一般这两个代理填一样的</div>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<!-- <a-form-item label="启动后触发流水线" name="triggerOnStartup">-->
|
|
||||||
<!-- <a-switch v-model:checked="formState.triggerOnStartup" />-->
|
|
||||||
<!-- <div class="helper">启动后自动触发一次所有已启用的流水线</div>-->
|
|
||||||
<!-- </a-form-item>-->
|
|
||||||
<a-form-item :wrapper-col="{ offset: 8, span: 16 }">
|
<a-form-item :wrapper-col="{ offset: 8, span: 16 }">
|
||||||
<a-button :loading="saveLoading" type="primary" html-type="submit">保存</a-button>
|
<a-button :loading="saveLoading" type="primary" html-type="submit">保存</a-button>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-form>
|
</a-form>
|
||||||
|
|
||||||
<!-- <a-descriptions label="系统维护操作">-->
|
|
||||||
<!-- <a-descriptions-item label="自动化任务">-->
|
|
||||||
<!-- <a-button @click="stopOtherUserTimer">停止所有其他用户的定时任务</a-button>-->
|
|
||||||
<!-- </a-descriptions-item>-->
|
|
||||||
<!-- </a-descriptions>-->
|
|
||||||
</div>
|
</div>
|
||||||
</fs-page>
|
</fs-page>
|
||||||
</template>
|
</template>
|
||||||
@@ -43,42 +45,41 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, ref } from "vue";
|
import { reactive, ref } from "vue";
|
||||||
import * as api from "./api";
|
import * as api from "./api";
|
||||||
import { PublicSettingsSave, SettingKeys } from "./api";
|
import { SysSettings } from "./api";
|
||||||
import { notification } from "ant-design-vue";
|
import { notification } from "ant-design-vue";
|
||||||
import { useSettingStore } from "/@/store/modules/settings";
|
import { useSettingStore } from "/@/store/modules/settings";
|
||||||
|
import { merge } from "lodash-es";
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "SysSettings"
|
name: "SysSettings"
|
||||||
});
|
});
|
||||||
|
|
||||||
interface FormState {
|
const formState = reactive<Partial<SysSettings>>({
|
||||||
registerEnabled: boolean;
|
public: {
|
||||||
managerOtherUserPipeline: boolean;
|
registerEnabled: false,
|
||||||
icpNo: string;
|
managerOtherUserPipeline: false,
|
||||||
}
|
icpNo: ""
|
||||||
|
},
|
||||||
const formState = reactive<Partial<FormState>>({
|
private: {}
|
||||||
registerEnabled: false,
|
|
||||||
managerOtherUserPipeline: false,
|
|
||||||
icpNo: ""
|
|
||||||
});
|
});
|
||||||
|
|
||||||
async function loadSysPublicSettings() {
|
const urlRules = ref({
|
||||||
const data: any = await api.SettingsGet(SettingKeys.SysPublic);
|
type: "url",
|
||||||
if (data == null) {
|
message: "请输入正确的URL"
|
||||||
return;
|
});
|
||||||
}
|
|
||||||
const setting = JSON.parse(data.setting);
|
async function loadSysSettings() {
|
||||||
Object.assign(formState, setting);
|
const data: any = await api.SysSettingsGet();
|
||||||
|
merge(formState, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
const saveLoading = ref(false);
|
const saveLoading = ref(false);
|
||||||
loadSysPublicSettings();
|
loadSysSettings();
|
||||||
const settingsStore = useSettingStore();
|
const settingsStore = useSettingStore();
|
||||||
const onFinish = async (form: any) => {
|
const onFinish = async (form: any) => {
|
||||||
try {
|
try {
|
||||||
saveLoading.value = true;
|
saveLoading.value = true;
|
||||||
await api.PublicSettingsSave(form);
|
await api.SysSettingsSave(form);
|
||||||
await settingsStore.loadSysSettings();
|
await settingsStore.loadSysSettings();
|
||||||
notification.success({
|
notification.success({
|
||||||
message: "保存成功"
|
message: "保存成功"
|
||||||
@@ -98,6 +99,15 @@ async function stopOtherUserTimer() {
|
|||||||
message: "停止成功"
|
message: "停止成功"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function testProxy() {
|
||||||
|
const res = await api.TestProxy();
|
||||||
|
const content = `测试google:${res.google === true ? "成功" : "失败" + res.google},测试百度:${res.baidu === true ? "成功" : "失败:" + res.baidu}`;
|
||||||
|
notification.success({
|
||||||
|
message: "测试完成",
|
||||||
|
description: content
|
||||||
|
});
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
|
|||||||
@@ -4,23 +4,11 @@
|
|||||||
# server:
|
# server:
|
||||||
# baseUrl: 'http://127.0.0.1:11007'
|
# baseUrl: 'http://127.0.0.1:11007'
|
||||||
|
|
||||||
#flyway:
|
|
||||||
# scriptDir: './db/migration-pg'
|
|
||||||
|
|
||||||
#typeorm:
|
#typeorm:
|
||||||
# dataSource:
|
# dataSource:
|
||||||
# default:
|
# default:
|
||||||
# type: postgres
|
# database: './data/db.sqlite'
|
||||||
# host: localhost
|
|
||||||
# port: 5433
|
|
||||||
# username: postgres
|
|
||||||
# password: root
|
|
||||||
# database: postgres
|
|
||||||
|
|
||||||
typeorm:
|
|
||||||
dataSource:
|
|
||||||
default:
|
|
||||||
database: './data/db.sqlite'
|
|
||||||
plus:
|
plus:
|
||||||
server:
|
server:
|
||||||
baseUrls: ['https://api.ai.handsfree.work', 'https://api.ai.docmirror.cn']
|
baseUrls: ['https://api.ai.handsfree.work', 'https://api.ai.docmirror.cn']
|
||||||
|
|||||||
21
packages/ui/certd-server/.env.pgpl.yaml
Normal file
21
packages/ui/certd-server/.env.pgpl.yaml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
flyway:
|
||||||
|
scriptDir: './db/migration-pg'
|
||||||
|
|
||||||
|
|
||||||
|
typeorm:
|
||||||
|
dataSource:
|
||||||
|
default:
|
||||||
|
type: postgres
|
||||||
|
host: 192.168.42.245
|
||||||
|
port: 5432
|
||||||
|
username: root
|
||||||
|
password: Baode@1234567
|
||||||
|
database: certd
|
||||||
|
|
||||||
|
#plus:
|
||||||
|
# server:
|
||||||
|
# baseUrl: 'https://api.ai.handsfree.work'
|
||||||
|
|
||||||
|
plus:
|
||||||
|
server:
|
||||||
|
baseUrl: 'http://127.0.0.1:11007'
|
||||||
2
packages/ui/certd-server/.gitignore
vendored
2
packages/ui/certd-server/.gitignore
vendored
@@ -17,3 +17,5 @@ run/
|
|||||||
/test/setup.ts
|
/test/setup.ts
|
||||||
/data/
|
/data/
|
||||||
.clinic
|
.clinic
|
||||||
|
|
||||||
|
.env.pgpl.yaml
|
||||||
|
|||||||
@@ -3,6 +3,14 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.26.4](https://github.com/certd/certd/compare/v1.26.3...v1.26.4) (2024-10-14)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* [comm] 支持插件管理 ([e8b617b](https://github.com/certd/certd/commit/e8b617b80ce882dd63006f0cfc719a80a1cc6acc))
|
||||||
|
* 新增代理设置功能 ([273ab61](https://github.com/certd/certd/commit/273ab6139f5807f4d7fe865cc353b97f51b9a668))
|
||||||
|
* EAB授权支持绑定邮箱,支持公共EAB设置 ([07043af](https://github.com/certd/certd/commit/07043aff0ca7fd29c56dd3c363002cb15d78b464))
|
||||||
|
|
||||||
## [1.26.3](https://github.com/certd/certd/compare/v1.26.2...v1.26.3) (2024-10-12)
|
## [1.26.3](https://github.com/certd/certd/compare/v1.26.2...v1.26.3) (2024-10-12)
|
||||||
|
|
||||||
### Performance Improvements
|
### Performance Improvements
|
||||||
|
|||||||
18
packages/ui/certd-server/db/migration-pg/v10010__plugin.sql
Normal file
18
packages/ui/certd-server/db/migration-pg/v10010__plugin.sql
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
CREATE TABLE "pi_plugin"
|
||||||
|
(
|
||||||
|
"id" bigint NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
|
||||||
|
"name" varchar(100) NOT NULL,
|
||||||
|
"icon" varchar(100),
|
||||||
|
"title" varchar(200),
|
||||||
|
"desc" varchar(500),
|
||||||
|
"group" varchar(100),
|
||||||
|
"version" varchar(100),
|
||||||
|
"setting" text,
|
||||||
|
"sys_setting" text,
|
||||||
|
"content" text,
|
||||||
|
"type" varchar(100) NOT NULL,
|
||||||
|
"disabled" boolean NOT NULL,
|
||||||
|
"create_time" timestamp NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||||
|
"update_time" timestamp NOT NULL DEFAULT (CURRENT_TIMESTAMP)
|
||||||
|
);
|
||||||
|
|
||||||
18
packages/ui/certd-server/db/migration/v10010__plugin.sql
Normal file
18
packages/ui/certd-server/db/migration/v10010__plugin.sql
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
CREATE TABLE "pi_plugin"
|
||||||
|
(
|
||||||
|
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||||
|
"name" varchar(100) NOT NULL,
|
||||||
|
"icon" varchar(100),
|
||||||
|
"title" varchar(200),
|
||||||
|
"desc" varchar(500),
|
||||||
|
"group" varchar(100),
|
||||||
|
"version" varchar(100),
|
||||||
|
"setting" text,
|
||||||
|
"sys_setting" text,
|
||||||
|
"content" text,
|
||||||
|
"type" varchar(100) NOT NULL,
|
||||||
|
"disabled" boolean NOT NULL,
|
||||||
|
"create_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||||
|
"update_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP)
|
||||||
|
);
|
||||||
|
|
||||||
@@ -1,24 +1,24 @@
|
|||||||
## sqlite与postgres不同点
|
## sqlite与postgres不同点
|
||||||
1.
|
1.
|
||||||
sl: AUTOINCREAMENT
|
sqlite: AUTOINCREAMENT
|
||||||
pg: GENERATED BY DEFAULT AS IDENTITY
|
postgresql: GENERATED BY DEFAULT AS IDENTITY
|
||||||
|
|
||||||
2.
|
2.
|
||||||
datetime
|
sqlite: datetime
|
||||||
timestamp
|
postgresql: timestamp
|
||||||
|
|
||||||
3.
|
3.
|
||||||
update sqlite_sequence set seq = 1000 where name = 'sys_role' ;
|
sqlite: update sqlite_sequence set seq = 1000 where name = 'sys_role' ;
|
||||||
select setval('sys_role_id_seq', 1000);
|
postgresql: select setval('sys_role_id_seq', 1000);
|
||||||
|
|
||||||
4.
|
4.
|
||||||
"disabled" boolean DEFAULT (0)
|
sqlite: "disabled" boolean DEFAULT (0)
|
||||||
"disabled" boolean DEFAULT (false)
|
postgresql: "disabled" boolean DEFAULT (false)
|
||||||
|
|
||||||
5.
|
5.
|
||||||
last_insert_rowid()
|
sqlite: last_insert_rowid()
|
||||||
LASTVAL()
|
postgresql: LASTVAL()
|
||||||
|
|
||||||
6.
|
6.
|
||||||
sl: integer
|
sqlite: integer
|
||||||
pg: bigint
|
postgresql: bigint
|
||||||
|
|||||||
53
packages/ui/certd-server/db/transform.js
Normal file
53
packages/ui/certd-server/db/transform.js
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
import fs from 'fs';
|
||||||
|
/**
|
||||||
|
* ## sqlite与postgres不同点
|
||||||
|
* 1.
|
||||||
|
* sqlite: AUTOINCREAMENT
|
||||||
|
* postgresql: GENERATED BY DEFAULT AS IDENTITY
|
||||||
|
*
|
||||||
|
* 2.
|
||||||
|
* sqlite: datetime
|
||||||
|
* postgresql: timestamp
|
||||||
|
*
|
||||||
|
* 3.
|
||||||
|
* sqlite: update sqlite_sequence set seq = 1000 where name = 'sys_role' ;
|
||||||
|
* postgresql: select setval('sys_role_id_seq', 1000);
|
||||||
|
*
|
||||||
|
* 4.
|
||||||
|
* sqlite: "disabled" boolean DEFAULT (0)
|
||||||
|
* postgresql: "disabled" boolean DEFAULT (false)
|
||||||
|
*
|
||||||
|
* 5.
|
||||||
|
* sqlite: last_insert_rowid()
|
||||||
|
* postgresql: LASTVAL()
|
||||||
|
*
|
||||||
|
* 6.
|
||||||
|
* sqlite: integer
|
||||||
|
* postgresql: bigint
|
||||||
|
*/
|
||||||
|
function transform() {
|
||||||
|
// 读取文件列表
|
||||||
|
const sqliteFiles = fs.readdirSync('./migration/');
|
||||||
|
const pgFiles = fs.readdirSync('./migration-pg');
|
||||||
|
//找出pg里面没有的文件
|
||||||
|
const notFiles = sqliteFiles.filter(file => !pgFiles.includes(file));
|
||||||
|
for (const notFile of notFiles) {
|
||||||
|
//开始转换
|
||||||
|
const sqliteSql = fs.readFileSync(`./migration/${notFile}`, 'utf-8');
|
||||||
|
let pgSql = sqliteSql.replace(/AUTOINCREMENT/g, 'GENERATED BY DEFAULT AS IDENTITY');
|
||||||
|
pgSql = pgSql.replace(/datetime/g, 'timestamp');
|
||||||
|
pgSql = pgSql.replace(/boolean DEFAULT \(0\)/g, 'boolean DEFAULT (false)');
|
||||||
|
pgSql = pgSql.replace(/integer/g, 'bigint');
|
||||||
|
pgSql = pgSql.replace(/last_insert_rowid\(\)/g, 'LASTVAL()');
|
||||||
|
fs.writeFileSync(`./migration-pg/${notFile}`, pgSql);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (notFiles.length > 0) {
|
||||||
|
console.log('sqlite->pg 转换完成');
|
||||||
|
|
||||||
|
throw new Error('sqlite->pg 转换完成,有更新,需要测试pg');
|
||||||
|
} else {
|
||||||
|
console.log('sql无需更新');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
transform();
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/ui-server",
|
"name": "@certd/ui-server",
|
||||||
"version": "1.26.3",
|
"version": "1.26.4",
|
||||||
"description": "fast-server base midway",
|
"description": "fast-server base midway",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -10,6 +10,9 @@
|
|||||||
"commdev": "cross-env NODE_ENV=commdev mwtsc --watch --run @midwayjs/mock/app",
|
"commdev": "cross-env NODE_ENV=commdev mwtsc --watch --run @midwayjs/mock/app",
|
||||||
"commpro": "cross-env NODE_ENV=commpro mwtsc --watch --run @midwayjs/mock/app",
|
"commpro": "cross-env NODE_ENV=commpro mwtsc --watch --run @midwayjs/mock/app",
|
||||||
"pgdev": "cross-env NODE_ENV=pgdev mwtsc --watch --run @midwayjs/mock/app",
|
"pgdev": "cross-env NODE_ENV=pgdev mwtsc --watch --run @midwayjs/mock/app",
|
||||||
|
"pgpl": "cross-env NODE_ENV=pgpl mwtsc --watch --run @midwayjs/mock/app",
|
||||||
|
"dev-new": "npm run rm-db-new && cross-env NODE_ENV=local mwtsc --watch --run @midwayjs/mock/app",
|
||||||
|
"rm-db-new": "rimraf ./data/db-new.sqlite",
|
||||||
"test": "cross-env NODE_ENV=unittest mocha",
|
"test": "cross-env NODE_ENV=unittest mocha",
|
||||||
"cov": "cross-env c8 --all --reporter=text --reporter=lcovonly npm run test",
|
"cov": "cross-env c8 --all --reporter=text --reporter=lcovonly npm run test",
|
||||||
"lint": "mwts check",
|
"lint": "mwts check",
|
||||||
@@ -19,22 +22,22 @@
|
|||||||
"dev-build": "echo 1",
|
"dev-build": "echo 1",
|
||||||
"build-on-docker": "node ./before-build.js && npm run build",
|
"build-on-docker": "node ./before-build.js && npm run build",
|
||||||
"up-mw-deps": "npx midway-version -u -w",
|
"up-mw-deps": "npx midway-version -u -w",
|
||||||
"heap": "clinic heapprofiler -- node ./bootstrap.js",
|
"heap": "cross-env NODE_ENV=pgpl clinic heapprofiler -- node ./bootstrap.js",
|
||||||
"flame": "clinic flame -- node ./bootstrap.js"
|
"flame": "clinic flame -- node ./bootstrap.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@alicloud/pop-core": "^1.7.10",
|
"@alicloud/pop-core": "^1.7.10",
|
||||||
"@certd/acme-client": "^1.26.3",
|
"@certd/acme-client": "^1.26.4",
|
||||||
"@certd/commercial-core": "^1.26.3",
|
"@certd/commercial-core": "^1.26.4",
|
||||||
"@certd/lib-huawei": "^1.26.3",
|
"@certd/lib-huawei": "^1.26.4",
|
||||||
"@certd/lib-jdcloud": "^1.26.3",
|
"@certd/lib-jdcloud": "^1.26.4",
|
||||||
"@certd/lib-k8s": "^1.26.3",
|
"@certd/lib-k8s": "^1.26.4",
|
||||||
"@certd/lib-server": "^1.26.3",
|
"@certd/lib-server": "^1.26.4",
|
||||||
"@certd/midway-flyway-js": "^1.26.3",
|
"@certd/midway-flyway-js": "^1.26.4",
|
||||||
"@certd/pipeline": "^1.26.3",
|
"@certd/pipeline": "^1.26.4",
|
||||||
"@certd/plugin-cert": "^1.26.3",
|
"@certd/plugin-cert": "^1.26.4",
|
||||||
"@certd/plugin-plus": "^1.26.3",
|
"@certd/plugin-plus": "^1.26.4",
|
||||||
"@certd/plus-core": "^1.26.3",
|
"@certd/plus-core": "^1.26.4",
|
||||||
"@koa/cors": "^5.0.0",
|
"@koa/cors": "^5.0.0",
|
||||||
"@midwayjs/bootstrap": "~3.17.1",
|
"@midwayjs/bootstrap": "~3.17.1",
|
||||||
"@midwayjs/cache": "~3.14.0",
|
"@midwayjs/cache": "~3.14.0",
|
||||||
@@ -102,6 +105,7 @@
|
|||||||
"mocha": "^10.2.0",
|
"mocha": "^10.2.0",
|
||||||
"mwts": "^1.3.0",
|
"mwts": "^1.3.0",
|
||||||
"prettier": "^3.3.3",
|
"prettier": "^3.3.3",
|
||||||
|
"rimraf": "^5.0.5",
|
||||||
"ts-node": "^10.9.2",
|
"ts-node": "^10.9.2",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ const development = {
|
|||||||
type: 'better-sqlite3',
|
type: 'better-sqlite3',
|
||||||
database: './data/db.sqlite',
|
database: './data/db.sqlite',
|
||||||
synchronize: false, // 如果第一次使用,不存在表,有同步的需求可以写 true
|
synchronize: false, // 如果第一次使用,不存在表,有同步的需求可以写 true
|
||||||
logging: false,
|
logging: true,
|
||||||
|
|
||||||
// 配置实体模型 或者 entities: '/entity',
|
// 配置实体模型 或者 entities: '/entity',
|
||||||
entities: ['**/modules/**/entity/*.js', ...libServerEntities, ...commercialEntities, PipelineEntity, FlywayHistory, UserEntity],
|
entities: ['**/modules/**/entity/*.js', ...libServerEntities, ...commercialEntities, PipelineEntity, FlywayHistory, UserEntity],
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import * as cache from '@midwayjs/cache';
|
|||||||
import * as validate from '@midwayjs/validate';
|
import * as validate from '@midwayjs/validate';
|
||||||
import * as info from '@midwayjs/info';
|
import * as info from '@midwayjs/info';
|
||||||
import * as staticFile from '@midwayjs/static-file';
|
import * as staticFile from '@midwayjs/static-file';
|
||||||
import * as cron from './modules/plugin/cron/index.js';
|
import * as cron from './modules/cron/index.js';
|
||||||
import * as flyway from '@certd/midway-flyway-js';
|
import * as flyway from '@certd/midway-flyway-js';
|
||||||
import cors from '@koa/cors';
|
import cors from '@koa/cors';
|
||||||
import { GlobalExceptionMiddleware } from './middleware/global-exception.js';
|
import { GlobalExceptionMiddleware } from './middleware/global-exception.js';
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import { ALL, Inject } from '@midwayjs/core';
|
|||||||
import { Body } from '@midwayjs/core';
|
import { Body } from '@midwayjs/core';
|
||||||
import { Controller, Post, Provide } from '@midwayjs/core';
|
import { Controller, Post, Provide } from '@midwayjs/core';
|
||||||
import { BaseController } from '@certd/lib-server';
|
import { BaseController } from '@certd/lib-server';
|
||||||
import { CodeService } from '../service/code-service.js';
|
import { CodeService } from '../../modules/basic/service/code-service.js';
|
||||||
import { EmailService } from '../service/email-service.js';
|
import { EmailService } from '../../modules/basic/service/email-service.js';
|
||||||
import { Constants } from '@certd/lib-server';
|
import { Constants } from '@certd/lib-server';
|
||||||
export class SmsCodeReq {
|
export class SmsCodeReq {
|
||||||
@Rule(RuleType.number().required())
|
@Rule(RuleType.number().required())
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Body, Controller, Inject, Post, Provide } from '@midwayjs/core';
|
import { Body, Controller, Inject, Post, Provide } from '@midwayjs/core';
|
||||||
import { BaseController } from '@certd/lib-server';
|
import { BaseController } from '@certd/lib-server';
|
||||||
import { EmailService } from '../service/email-service.js';
|
import { EmailService } from '../../modules/basic/service/email-service.js';
|
||||||
import { Constants } from '@certd/lib-server';
|
import { Constants } from '@certd/lib-server';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { ALL, Body, Controller, Inject, Post, Provide } from '@midwayjs/core';
|
import { ALL, Body, Controller, Inject, Post, Provide } from '@midwayjs/core';
|
||||||
import { BaseController, Constants } from '@certd/lib-server';
|
import { BaseController, Constants } from '@certd/lib-server';
|
||||||
import { CnameRecordService } from '../service/cname-record-service.js';
|
import { CnameRecordService } from '../../modules/cname/service/cname-record-service.js';
|
||||||
import { CnameProviderService } from '../../sys/cname/service/cname-provider-service.js';
|
import { CnameProviderService } from '../../modules/cname/service/cname-provider-service.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 授权
|
* 授权
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
|
import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
|
||||||
import { Constants, CrudController } from '@certd/lib-server';
|
import { Constants, CrudController } from '@certd/lib-server';
|
||||||
import { CnameRecordService } from '../service/cname-record-service.js';
|
import { CnameRecordService } from '../../modules/cname/service/cname-record-service.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 授权
|
* 授权
|
||||||
@@ -24,11 +24,16 @@ export class CnameRecordController extends CrudController<CnameRecordService> {
|
|||||||
|
|
||||||
const bq = qb => {
|
const bq = qb => {
|
||||||
if (domain) {
|
if (domain) {
|
||||||
qb.where('domain like :domain', { domain: `%${domain}%` });
|
qb.andWhere('domain like :domain', { domain: `%${domain}%` });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const pageRet = await this.getService().page(body?.query, body?.page, body?.sort, bq);
|
const pageRet = await this.getService().page({
|
||||||
|
query: body.query,
|
||||||
|
page: body.page,
|
||||||
|
order: body.order,
|
||||||
|
buildQuery: bq,
|
||||||
|
});
|
||||||
return this.ok(pageRet);
|
return this.ok(pageRet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Body, Controller, Inject, Post, Provide, ALL } from '@midwayjs/core';
|
import { Body, Controller, Inject, Post, Provide, ALL } from '@midwayjs/core';
|
||||||
import { LoginService } from '../service/login-service.js';
|
import { LoginService } from '../../modules/login/service/login-service.js';
|
||||||
import { BaseController } from '@certd/lib-server';
|
import { BaseController } from '@certd/lib-server';
|
||||||
import { Constants } from '@certd/lib-server';
|
import { Constants } from '@certd/lib-server';
|
||||||
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
import { ALL, Body, Controller, Inject, Post, Provide } from '@midwayjs/core';
|
import { ALL, Body, Controller, Inject, Post, Provide } from '@midwayjs/core';
|
||||||
import { BaseController } from '@certd/lib-server';
|
import { BaseController } from '@certd/lib-server';
|
||||||
import { Constants } from '@certd/lib-server';
|
import { Constants } from '@certd/lib-server';
|
||||||
import { UserService } from '../../sys/authority/service/user-service.js';
|
import { UserService } from '../../modules/sys/authority/service/user-service.js';
|
||||||
import { UserEntity } from '../../sys/authority/entity/user.js';
|
import { UserEntity } from '../../modules/sys/authority/entity/user.js';
|
||||||
import { SysSettingsService } from '@certd/lib-server';
|
import { SysSettingsService } from '@certd/lib-server';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { ALL, Body, Controller, Inject, Post, Provide } from '@midwayjs/core';
|
import { ALL, Body, Controller, Inject, Post, Provide } from '@midwayjs/core';
|
||||||
import { BaseController, Constants } from '@certd/lib-server';
|
import { BaseController, Constants } from '@certd/lib-server';
|
||||||
import { UserService } from '../../sys/authority/service/user-service.js';
|
import { UserService } from '../../modules/sys/authority/service/user-service.js';
|
||||||
import { RoleService } from '../../sys/authority/service/role-service.js';
|
import { RoleService } from '../../modules/sys/authority/service/role-service.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
|
import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
|
||||||
import { CrudController } from '@certd/lib-server';
|
import { CrudController } from '@certd/lib-server';
|
||||||
import { Constants } from '@certd/lib-server';
|
import { Constants } from '@certd/lib-server';
|
||||||
import { UserSettingsService } from '../service/user-settings-service.js';
|
import { UserSettingsService } from '../../modules/mine/service/user-settings-service.js';
|
||||||
import { UserSettingsEntity } from '../entity/user-settings.js';
|
import { UserSettingsEntity } from '../../modules/mine/entity/user-settings.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
|
import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
|
||||||
import { CrudController } from '@certd/lib-server';
|
import { CrudController } from '@certd/lib-server';
|
||||||
import { AccessService } from '../service/access-service.js';
|
import { AccessService } from '../../modules/pipeline/service/access-service.js';
|
||||||
import { Constants } from '@certd/lib-server';
|
import { Constants } from '@certd/lib-server';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -19,8 +19,17 @@ export class AccessController extends CrudController<AccessService> {
|
|||||||
@Post('/page', { summary: Constants.per.authOnly })
|
@Post('/page', { summary: Constants.per.authOnly })
|
||||||
async page(@Body(ALL) body) {
|
async page(@Body(ALL) body) {
|
||||||
body.query = body.query ?? {};
|
body.query = body.query ?? {};
|
||||||
body.query.userId = this.getUserId();
|
delete body.query.userId;
|
||||||
return await super.page(body);
|
const buildQuery = qb => {
|
||||||
|
qb.andWhere('user_id = :userId', { userId: this.getUserId() });
|
||||||
|
};
|
||||||
|
const res = await this.service.page({
|
||||||
|
query: body.query,
|
||||||
|
page: body.page,
|
||||||
|
order: body.order,
|
||||||
|
buildQuery,
|
||||||
|
});
|
||||||
|
return this.ok(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('/list', { summary: Constants.per.authOnly })
|
@Post('/list', { summary: Constants.per.authOnly })
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { ALL, Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
|
import { ALL, Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
|
||||||
import { DnsProviderService } from '../service/dns-provider-service.js';
|
import { DnsProviderService } from '../../modules/pipeline/service/dns-provider-service.js';
|
||||||
import { BaseController } from '@certd/lib-server';
|
import { BaseController } from '@certd/lib-server';
|
||||||
import { Constants } from '@certd/lib-server';
|
import { Constants } from '@certd/lib-server';
|
||||||
|
|
||||||
@@ -13,9 +13,9 @@ import {
|
|||||||
utils,
|
utils,
|
||||||
} from '@certd/pipeline';
|
} from '@certd/pipeline';
|
||||||
import { BaseController } from '@certd/lib-server';
|
import { BaseController } from '@certd/lib-server';
|
||||||
import { AccessService } from '../service/access-service.js';
|
import { AccessService } from '../../modules/pipeline/service/access-service.js';
|
||||||
import { EmailService } from '../../basic/service/email-service.js';
|
import { EmailService } from '../../modules/basic/service/email-service.js';
|
||||||
import { AccessGetter } from '../service/access-getter.js';
|
import { AccessGetter } from '../../modules/pipeline/service/access-getter.js';
|
||||||
|
|
||||||
@Provide()
|
@Provide()
|
||||||
@Controller('/api/pi/handle')
|
@Controller('/api/pi/handle')
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
import { ALL, Body, Controller, Get, Inject, Post, Provide, Query } from '@midwayjs/core';
|
import { ALL, Body, Controller, Get, Inject, Post, Provide, Query } from '@midwayjs/core';
|
||||||
import { CommonException, Constants, CrudController, PermissionException } from '@certd/lib-server';
|
import { CommonException, Constants, CrudController, PermissionException } from '@certd/lib-server';
|
||||||
import { PipelineEntity } from '../entity/pipeline.js';
|
import { PipelineEntity } from '../../modules/pipeline/entity/pipeline.js';
|
||||||
import { HistoryService } from '../service/history-service.js';
|
import { HistoryService } from '../../modules/pipeline/service/history-service.js';
|
||||||
import { HistoryLogService } from '../service/history-log-service.js';
|
import { HistoryLogService } from '../../modules/pipeline/service/history-log-service.js';
|
||||||
import { HistoryEntity } from '../entity/history.js';
|
import { HistoryEntity } from '../../modules/pipeline/entity/history.js';
|
||||||
import { HistoryLogEntity } from '../entity/history-log.js';
|
import { HistoryLogEntity } from '../../modules/pipeline/entity/history-log.js';
|
||||||
import { PipelineService } from '../service/pipeline-service.js';
|
import { PipelineService } from '../../modules/pipeline/service/pipeline-service.js';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import { logger } from '@certd/pipeline';
|
import { logger } from '@certd/pipeline';
|
||||||
import { AuthService } from '../../sys/authority/service/auth-service.js';
|
import { AuthService } from '../../modules/sys/authority/service/auth-service.js';
|
||||||
import { SysSettingsService } from '@certd/lib-server';
|
import { SysSettingsService } from '@certd/lib-server';
|
||||||
import { In } from 'typeorm';
|
import { In } from 'typeorm';
|
||||||
|
|
||||||
@@ -48,21 +48,29 @@ export class HistoryController extends CrudController<HistoryService> {
|
|||||||
let pipelineIds: any = null;
|
let pipelineIds: any = null;
|
||||||
const pipelineTitle = body.query?.pipelineTitle;
|
const pipelineTitle = body.query?.pipelineTitle;
|
||||||
if (pipelineTitle) {
|
if (pipelineTitle) {
|
||||||
const pipelines = await this.pipelineService.list(pipelineQuery, null, qb => {
|
const pipelines = await this.pipelineService.list({
|
||||||
qb.where('title like :title', { title: `%${pipelineTitle}%` });
|
query: pipelineQuery,
|
||||||
|
buildQuery: qb => {
|
||||||
|
qb.andWhere('title like :title', { title: `%${pipelineTitle}%` });
|
||||||
|
},
|
||||||
});
|
});
|
||||||
pipelineIds = pipelines.map(p => p.id);
|
pipelineIds = pipelines.map(p => p.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
const buildQuery = qb => {
|
const buildQuery = qb => {
|
||||||
if (pipelineIds) {
|
if (pipelineIds) {
|
||||||
qb.where({
|
qb.andWhere({
|
||||||
pipelineId: In(pipelineIds),
|
pipelineId: In(pipelineIds),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const res = await this.service.page(body?.query, body?.page, body?.sort, buildQuery);
|
const res = await this.service.page({
|
||||||
|
query: body.query,
|
||||||
|
page: body.page,
|
||||||
|
order: body.order,
|
||||||
|
buildQuery,
|
||||||
|
});
|
||||||
return this.ok(res);
|
return this.ok(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,7 +86,11 @@ export class HistoryController extends CrudController<HistoryService> {
|
|||||||
const buildQuery = qb => {
|
const buildQuery = qb => {
|
||||||
qb.limit(10);
|
qb.limit(10);
|
||||||
};
|
};
|
||||||
const listRet = await this.getService().list(body, { prop: 'id', asc: false }, buildQuery);
|
const listRet = await this.getService().list({
|
||||||
|
query: body,
|
||||||
|
order: { prop: 'id', asc: false },
|
||||||
|
buildQuery,
|
||||||
|
});
|
||||||
return this.ok(listRet);
|
return this.ok(listRet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
|
import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
|
||||||
import { Constants, CrudController, SysSettingsService } from '@certd/lib-server';
|
import { Constants, CrudController, SysSettingsService } from '@certd/lib-server';
|
||||||
import { PipelineService } from '../service/pipeline-service.js';
|
import { PipelineService } from '../../modules/pipeline/service/pipeline-service.js';
|
||||||
import { PipelineEntity } from '../entity/pipeline.js';
|
import { PipelineEntity } from '../../modules/pipeline/entity/pipeline.js';
|
||||||
import { HistoryService } from '../service/history-service.js';
|
import { HistoryService } from '../../modules/pipeline/service/history-service.js';
|
||||||
import { AuthService } from '../../sys/authority/service/auth-service.js';
|
import { AuthService } from '../../modules/sys/authority/service/auth-service.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 证书
|
* 证书
|
||||||
@@ -37,14 +37,19 @@ export class PipelineController extends CrudController<PipelineService> {
|
|||||||
|
|
||||||
const buildQuery = qb => {
|
const buildQuery = qb => {
|
||||||
if (title) {
|
if (title) {
|
||||||
qb.where('title like :title', { title: `%${title}%` });
|
qb.andWhere('title like :title', { title: `%${title}%` });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (!body.sort || !body.sort?.prop) {
|
if (!body.sort || !body.sort?.prop) {
|
||||||
body.sort = { prop: 'order', asc: false };
|
body.sort = { prop: 'order', asc: false };
|
||||||
}
|
}
|
||||||
|
|
||||||
const pageRet = await this.getService().page(body?.query, body?.page, body?.sort, buildQuery);
|
const pageRet = await this.getService().page({
|
||||||
|
query: body.query,
|
||||||
|
page: body.page,
|
||||||
|
order: body.order,
|
||||||
|
buildQuery,
|
||||||
|
});
|
||||||
return this.ok(pageRet);
|
return this.ok(pageRet);
|
||||||
}
|
}
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user