mirror of
https://github.com/certd/certd.git
synced 2026-06-15 21:57:33 +08:00
Compare commits
61 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ed58ae3c53 | |||
| 194463bea9 | |||
| 260f5ae777 | |||
| e85d824337 | |||
| e17fc39709 | |||
| da9b297b12 | |||
| 807dfcd57a | |||
| 0a410db52a | |||
| 4501095106 | |||
| bc731e4fb1 | |||
| 53561d2755 | |||
| e913fe509c | |||
| a3a215b7ae | |||
| 56f2949ac5 | |||
| c1b5a35f90 | |||
| 48ab1fbffe | |||
| 5f078273b3 | |||
| 636338f9ed | |||
| 6cbd629777 | |||
| 5a07dce759 | |||
| 15484bc119 | |||
| d6cd9d136d | |||
| c76815756b | |||
| eef93250ac | |||
| a1c6cf0477 | |||
| 14a0ccac93 | |||
| 9439743b7e | |||
| acbac6a9c3 | |||
| cc38ccd0e9 | |||
| 7d0cf846ac | |||
| f9541fab70 | |||
| 8d9870e9c6 | |||
| 0f3f8519e0 | |||
| 016ae865b1 | |||
| 3e9953a74a | |||
| 1fc80d2b93 | |||
| b55fe2ef19 | |||
| 71030b7e27 | |||
| 5e8bdac008 | |||
| 56b8c689ec | |||
| 454912d314 | |||
| 61e3f5761c | |||
| 2908569841 | |||
| 775226b49f | |||
| e3dacb5b3f | |||
| cdea411136 | |||
| fdb000ee7c | |||
| 4a0be1c29d | |||
| 892d22e225 | |||
| 4958a48b92 | |||
| 28bbea85f0 | |||
| 73b3a29cfc | |||
| 77b8024453 | |||
| 1175e1164b | |||
| 5546af518e | |||
| 99fd3083f2 | |||
| c0df8be832 | |||
| 73cab6a6ee | |||
| 7a71e45799 | |||
| fdb1d1e6dd | |||
| 6dd4d6adeb |
+7
-2
@@ -1,4 +1,4 @@
|
|||||||
./packages/core/lego
|
./packages/core/lego
|
||||||
# IntelliJ project files
|
# IntelliJ project files
|
||||||
node_modules/
|
node_modules/
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
@@ -34,4 +34,9 @@ test.js
|
|||||||
/logs
|
/logs
|
||||||
.pnpm-lock.yaml
|
.pnpm-lock.yaml
|
||||||
pnpm-lock.yaml
|
pnpm-lock.yaml
|
||||||
.studio/
|
.studio/
|
||||||
|
|
||||||
|
# Certd 推广报告,仅本地使用
|
||||||
|
/popularize/reports/
|
||||||
|
output/
|
||||||
|
.uploads/
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
你是一名资深nodejs工程师,擅长开发Certd开源系统的任务插件。
|
|
||||||
certd是一款全自动证书申请部署管理工具,基于流水线的方式,通过里面申请证书插件申请证书,然后将证书传递给下一个部署任务插件,不同的部署任务插件将证书部署到用户的各个应用系统当中。
|
|
||||||
|
|
||||||
certd插件分成以下几种类型:
|
|
||||||
Access:存储用户的第三放应用的授权数据,比如用户名密码,accessSecret 或 accessToken等。同时它里面的方法还负责对接第三方的api接口
|
|
||||||
Task: 部署任务插件,它继承AbstractTaskPlugin类,被流水线调用execute方法,将证书部署到对应的应用上
|
|
||||||
DnsProvider: DNS提供商插件,它用于在ACME申请证书时给域名添加txt解析记录。
|
|
||||||
|
|
||||||
注意事项:
|
|
||||||
1、使用技能:在开始工作前,请阅读并加载.trae/skills下面的技能,根据skills进行相应的插件开发
|
|
||||||
2、迭代技能:当开发过程用户提醒你更好的做法时,你需要总结经验,更新相应的skills,让skills越来越完善,能够在以后得新插件开发中具备指导意义。
|
|
||||||
3、一般调用的api接口文档会比较复杂,你不知道接口是什么时,请务必询问用户,让用户提供API接口文档
|
|
||||||
4、完成开发后无需测试,通知用户自己去测试
|
|
||||||
@@ -25,7 +25,7 @@ version: 1.0.0
|
|||||||
## 实现流程
|
## 实现流程
|
||||||
|
|
||||||
1. 先在 `packages/ui/certd-client/src/views` 下找 1-2 个相近 Fast Crud 页面,沿用它们的导入、布局、命名和权限写法。
|
1. 先在 `packages/ui/certd-client/src/views` 下找 1-2 个相近 Fast Crud 页面,沿用它们的导入、布局、命名和权限写法。
|
||||||
2. 在 `index.vue` 中使用 `fs-crud ref="crudRef" v-bind="crudBinding"`,并在 `onMounted` / `onActivated` 时调用 `crudExpose.doRefresh()`。
|
2. 在 `index.vue` 中使用 `fs-crud ref="crudRef" v-bind="crudBinding"`,并在 `onMounted` 或 `onActivated` 时调用 `crudExpose.doRefresh()`;两个生命周期同时存在时只保留一个刷新入口,避免首次进入页面请求两次。
|
||||||
3. 在 `crud.tsx` 中配置 `request.pageRequest`、`columns`、`search`、`form`、`rowHandle`、`actionbar`、`toolbar` 等,接口分页参数和返回值按现有页面适配。
|
3. 在 `crud.tsx` 中配置 `request.pageRequest`、`columns`、`search`、`form`、`rowHandle`、`actionbar`、`toolbar` 等,接口分页参数和返回值按现有页面适配。
|
||||||
4. 操作按钮优先放在 Fast Crud 的 `rowHandle.buttons` 或 `actionbar.buttons` 中;审核、保存设置、批量操作等复杂交互可通过 `context` 调用 `index.vue` 中的方法。
|
4. 操作按钮优先放在 Fast Crud 的 `rowHandle.buttons` 或 `actionbar.buttons` 中;审核、保存设置、批量操作等复杂交互可通过 `context` 调用 `index.vue` 中的方法。
|
||||||
5. 金额、状态、时间、枚举等字段优先复用项目已有组件、字典和格式化工具;避免在模板里重复堆格式化逻辑。
|
5. 金额、状态、时间、枚举等字段优先复用项目已有组件、字典和格式化工具;避免在模板里重复堆格式化逻辑。
|
||||||
@@ -77,6 +77,84 @@ container:{}, //容器配置 ,对应fs-container
|
|||||||
- 有固定操作栏、统计区、说明区时,这些区域应 `flex: none`,把剩余空间交给表格区域。
|
- 有固定操作栏、统计区、说明区时,这些区域应 `flex: none`,把剩余空间交给表格区域。
|
||||||
- 修改嵌入式 Fast Crud 页面后,要检查空数据、少量数据和多页数据时表格高度、分页器和空状态是否仍在预期区域内。
|
- 修改嵌入式 Fast Crud 页面后,要检查空数据、少量数据和多页数据时表格高度、分页器和空状态是否仍在预期区域内。
|
||||||
|
|
||||||
|
## 列表导出
|
||||||
|
|
||||||
|
- 列表需要导出时,优先使用 Fast Crud 工具栏导出能力,不要另写一套导出按钮或后端接口,除非数据必须跨权限、跨分页或异步生成文件。
|
||||||
|
- 导出当前搜索条件下的数据时,在 `toolbar.export` 中设置 `dataFrom: "search"`,并显式打开导出按钮。
|
||||||
|
- 导出列必须输出 Excel 可读的纯文本或数字;不要直接导出对象、数组、VNode、进度条组件、开关组件、时间戳毫秒值等。
|
||||||
|
- 有隐藏但业务上需要导出的字段时,把字段定义为普通列并设置 `column.show: false`,再在 `columnFilter` 中对该字段返回 `true`。例如证书域名这类只用于导出的辅助列。
|
||||||
|
- 嵌套字段可以使用 `lastVars.certDomains` 这类 key;导出格式化时用安全取值函数读取嵌套值。
|
||||||
|
- `dataFormatter` 中统一格式化特殊字段:时间字段转 `YYYY-MM-DD HH:mm:ss`,日期类有效期转业务文案或 `YYYY-MM-DD`,枚举/开关转字典 label,数组转逗号分隔字符串,对象转明确的业务摘要。
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { ColumnProps, DataFormatterContext } from "@fast-crud/fast-crud";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
|
function getRecordValue(row: any, key: string) {
|
||||||
|
return key.split(".").reduce((target, item) => target?.[item], row);
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatListValue(value: any) {
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
return value.join(",");
|
||||||
|
}
|
||||||
|
return value ?? "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function exportColumnFilter(col: ColumnProps) {
|
||||||
|
if (!col.key || ["_index", "_selection", "rowHandle"].includes(col.key)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (col.key === "lastVars.certDomains") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return col.show !== false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function exportDataFormatter(opts: DataFormatterContext) {
|
||||||
|
const { row, originalRow, col, exportCol } = opts;
|
||||||
|
const key = col.key;
|
||||||
|
const value = getRecordValue(originalRow, key);
|
||||||
|
|
||||||
|
if (key === "lastVars.certDomains") {
|
||||||
|
row[key] = formatListValue(value);
|
||||||
|
} else if (key.includes("Time") && value) {
|
||||||
|
row[key] = dayjs(value).format("YYYY-MM-DD HH:mm:ss");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (col.width) {
|
||||||
|
exportCol.width = col.width / 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
crudOptions: {
|
||||||
|
toolbar: {
|
||||||
|
buttons: {
|
||||||
|
export: { show: true },
|
||||||
|
},
|
||||||
|
export: {
|
||||||
|
dataFrom: "search",
|
||||||
|
columnFilter: exportColumnFilter,
|
||||||
|
dataFormatter: exportDataFormatter,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
columns: {
|
||||||
|
"lastVars.certDomains": {
|
||||||
|
title: "证书域名",
|
||||||
|
type: "text",
|
||||||
|
column: {
|
||||||
|
show: false,
|
||||||
|
width: 260,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
form: { show: false },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
## 内置 CRUD 按钮
|
## 内置 CRUD 按钮
|
||||||
|
|
||||||
只要在 `request` 中配置了 `addRequest`、`editRequest`、`delRequest`,Fast Crud 会自动在 `rowHandle` 渲染新增、编辑、删除按钮并完成对应操作,**不需要手写 `openDeleteConfirm`、`openEditDialog` 等方法**。
|
只要在 `request` 中配置了 `addRequest`、`editRequest`、`delRequest`,Fast Crud 会自动在 `rowHandle` 渲染新增、编辑、删除按钮并完成对应操作,**不需要手写 `openDeleteConfirm`、`openEditDialog` 等方法**。
|
||||||
|
|||||||
@@ -3,6 +3,53 @@
|
|||||||
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.41.4](https://github.com/certd/certd/compare/v1.41.3...v1.41.4) (2026-06-14)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复设置里面不显示tab页签,导致某些页面需要点击查询按钮才有数据出来的bug ([c1b5a35](https://github.com/certd/certd/commit/c1b5a35f90a7d4b41397717b5c27905bc68e1bfb))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* **plugin:** 增加 Dynadot DNS and access 插件 ([a3a215b](https://github.com/certd/certd/commit/a3a215b7ae2b90efcde91270ce4165bbfe77dc64))
|
||||||
|
|
||||||
|
## [1.41.3](https://github.com/certd/certd/compare/v1.41.2...v1.41.3) (2026-06-11)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复litessl无法申请证书,报authorization must be pending 错误的问题 ([d6cd9d1](https://github.com/certd/certd/commit/d6cd9d136d2812b2335917305f36d6d9414507ad))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 首页夜间模式主图切换为黑色背景 ([15484bc](https://github.com/certd/certd/commit/15484bc119fef7a0ca7f3fdab01d665fde47e688))
|
||||||
|
|
||||||
|
## [1.41.2](https://github.com/certd/certd/compare/v1.41.1...v1.41.2) (2026-06-10)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **cert-plugin:** 修复DNS提供商授权无法回显的bug ([016ae86](https://github.com/certd/certd/commit/016ae865b1d914fe5792e77a08e3ab5358df5f89))
|
||||||
|
* Parse PEM chain and import certificate chain ([#747](https://github.com/certd/certd/issues/747)) ([454912d](https://github.com/certd/certd/commit/454912d31407d350cbd170953ccbd0564e74fd6c))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 添加AWS Rate Limit应对措施 ([#748](https://github.com/certd/certd/issues/748)) ([56b8c68](https://github.com/certd/certd/commit/56b8c689ec2b5cff49010a8c765483dd36803e9d))
|
||||||
|
* 新增站点证书监控从DNS解析记录批量导入功能 ([f9541fa](https://github.com/certd/certd/commit/f9541fab701e01ba57af061da322204c894adfb8))
|
||||||
|
* 优化 HiPM DNSMgr 插件,添加域名查询双层策略 ([#744](https://github.com/certd/certd/issues/744)) @WUHINS ([0f3f851](https://github.com/certd/certd/commit/0f3f8519e04d95cb848e28b98a3d4fcbed481fce))
|
||||||
|
|
||||||
|
### Reverts
|
||||||
|
|
||||||
|
* Revert "perf: 添加AWS Rate Limit应对措施 (#748)" (#749) ([5e8bdac](https://github.com/certd/certd/commit/5e8bdac00850bed4f5f2a272bee42c490730ec21)), closes [#748](https://github.com/certd/certd/issues/748) [#749](https://github.com/certd/certd/issues/749)
|
||||||
|
|
||||||
|
## [1.41.1](https://github.com/certd/certd/compare/v1.41.0...v1.41.1) (2026-06-05)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 流水线、监控站点支持导出 ([99fd308](https://github.com/certd/certd/commit/99fd3083f259cdb96fd656f04858dd708d1251c7))
|
||||||
|
* 优化列表页面请求两次的问题 ([5546af5](https://github.com/certd/certd/commit/5546af518e92c765513787ccaf8e856be789bcf9))
|
||||||
|
* 优化邀请注册流程 ([7a71e45](https://github.com/certd/certd/commit/7a71e45799d782d0691606fb42b4236f1d3009b0))
|
||||||
|
* **settings:** 新增NO_PROXY代理排除配置 ([c0df8be](https://github.com/certd/certd/commit/c0df8be83237e323c2c9a5bd02507430a86a00cc))
|
||||||
|
* **volcengine-vke:** 火山VKE集群证书支持两种类型的证书保密字典 ([77b8024](https://github.com/certd/certd/commit/77b802445322d576d54d194f7c505da49e0e824c))
|
||||||
|
|
||||||
# [1.41.0](https://github.com/certd/certd/compare/v1.40.5...v1.41.0) (2026-06-04)
|
# [1.41.0](https://github.com/certd/certd/compare/v1.40.5...v1.41.0) (2026-06-04)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
@@ -179,7 +179,10 @@ https://certd.handfree.work/
|
|||||||
2. 您的需求我们将优先实现,并且可能将作为专业版功能提供
|
2. 您的需求我们将优先实现,并且可能将作为专业版功能提供
|
||||||
3. 获得专业版功能
|
3. 获得专业版功能
|
||||||
|
|
||||||
[50元专业版优惠券限时领取](https://app.handfree.work/subject/#/app/certd/product)
|
|
||||||
|
> [50元专业版优惠券限时领取](https://app.handfree.work/subject/#/app/certd/product) https://app.handfree.work/subject/#/app/certd/product
|
||||||
|
> app.handfree.work是Certd官方激活码购买平台
|
||||||
|
|
||||||
|
|
||||||
专业版、商业版特权对比
|
专业版、商业版特权对比
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,78 @@
|
|||||||
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.41.4](https://github.com/certd/certd/compare/v1.41.3...v1.41.4) (2026-06-14)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复设置里面不显示tab页签,导致某些页面需要点击查询按钮才有数据出来的bug ([c1b5a35](https://github.com/certd/certd/commit/c1b5a35f90a7d4b41397717b5c27905bc68e1bfb))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* **plugin:** 增加 Dynadot DNS and access 插件 ([a3a215b](https://github.com/certd/certd/commit/a3a215b7ae2b90efcde91270ce4165bbfe77dc64))
|
||||||
|
|
||||||
|
## [1.41.3](https://github.com/certd/certd/compare/v1.41.2...v1.41.3) (2026-06-11)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复litessl无法申请证书,报authorization must be pending 错误的问题 ([d6cd9d1](https://github.com/certd/certd/commit/d6cd9d136d2812b2335917305f36d6d9414507ad))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 首页夜间模式主图切换为黑色背景 ([15484bc](https://github.com/certd/certd/commit/15484bc119fef7a0ca7f3fdab01d665fde47e688))
|
||||||
|
|
||||||
|
## [1.41.2](https://github.com/certd/certd/compare/v1.41.1...v1.41.2) (2026-06-10)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **cert-plugin:** 修复DNS提供商授权无法回显的bug ([016ae86](https://github.com/certd/certd/commit/016ae865b1d914fe5792e77a08e3ab5358df5f89))
|
||||||
|
* Parse PEM chain and import certificate chain ([#747](https://github.com/certd/certd/issues/747)) ([454912d](https://github.com/certd/certd/commit/454912d31407d350cbd170953ccbd0564e74fd6c))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 添加AWS Rate Limit应对措施 ([#748](https://github.com/certd/certd/issues/748)) ([56b8c68](https://github.com/certd/certd/commit/56b8c689ec2b5cff49010a8c765483dd36803e9d))
|
||||||
|
* 新增站点证书监控从DNS解析记录批量导入功能 ([f9541fa](https://github.com/certd/certd/commit/f9541fab701e01ba57af061da322204c894adfb8))
|
||||||
|
* 优化 HiPM DNSMgr 插件,添加域名查询双层策略 ([#744](https://github.com/certd/certd/issues/744)) @WUHINS ([0f3f851](https://github.com/certd/certd/commit/0f3f8519e04d95cb848e28b98a3d4fcbed481fce))
|
||||||
|
|
||||||
|
### Reverts
|
||||||
|
|
||||||
|
* Revert "perf: 添加AWS Rate Limit应对措施 (#748)" (#749) ([5e8bdac](https://github.com/certd/certd/commit/5e8bdac00850bed4f5f2a272bee42c490730ec21)), closes [#748](https://github.com/certd/certd/issues/748) [#749](https://github.com/certd/certd/issues/749)
|
||||||
|
|
||||||
|
## [1.41.1](https://github.com/certd/certd/compare/v1.41.0...v1.41.1) (2026-06-05)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 流水线、监控站点支持导出 ([99fd308](https://github.com/certd/certd/commit/99fd3083f259cdb96fd656f04858dd708d1251c7))
|
||||||
|
* 优化列表页面请求两次的问题 ([5546af5](https://github.com/certd/certd/commit/5546af518e92c765513787ccaf8e856be789bcf9))
|
||||||
|
* 优化邀请注册流程 ([7a71e45](https://github.com/certd/certd/commit/7a71e45799d782d0691606fb42b4236f1d3009b0))
|
||||||
|
* **settings:** 新增NO_PROXY代理排除配置 ([c0df8be](https://github.com/certd/certd/commit/c0df8be83237e323c2c9a5bd02507430a86a00cc))
|
||||||
|
* **volcengine-vke:** 火山VKE集群证书支持两种类型的证书保密字典 ([77b8024](https://github.com/certd/certd/commit/77b802445322d576d54d194f7c505da49e0e824c))
|
||||||
|
|
||||||
|
# [1.41.0](https://github.com/certd/certd/compare/v1.40.5...v1.41.0) (2026-06-04)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复阿里云证书订单orderid 选择出错的问题 ([41254d1](https://github.com/certd/certd/commit/41254d10b748a2d3e6ba43c7e11411650c748d1b))
|
||||||
|
* **monitor:** 修复开放接口自动创建证书流水线重复触发和等待时间不足的问题 ([91d5c90](https://github.com/certd/certd/commit/91d5c90eb0eaf65c81dddbd2d4d4b404cb8b4d07))
|
||||||
|
* **pipeline:** 修复批量随机修改定时没有生效的bug ([2e19dda](https://github.com/certd/certd/commit/2e19dda72e70b525a7c269e18e963a5ee602f59f))
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* 商业版支持邀请返佣功能 ([f9a310b](https://github.com/certd/certd/commit/f9a310b6c3bbf30f221482a0c59e9c30080bdfc8))
|
||||||
|
* 商业版支持邀请推广功能 ([f1d2a10](https://github.com/certd/certd/commit/f1d2a1033a0f8d3dbd91fc9793e07bd0b858b539))
|
||||||
|
* 新增管理员针对用户流水线和证书监控管理功能 ([0211552](https://github.com/certd/certd/commit/021155278e7375f8487b0531ed1b5ad52512f007))
|
||||||
|
* 新增套餐激活码功能,通过CDK兑换套餐 ([81d6289](https://github.com/certd/certd/commit/81d6289a8631b073b49f24dee4b14bb1c8f31071))
|
||||||
|
* 新增推广等级激励功能 ([5096df5](https://github.com/certd/certd/commit/5096df5cc0d8f0ad8aa327b8e2a900ba23714bd8))
|
||||||
|
* 新增证书申请参数模版管理,开放接口支持使用证书参数模版和指定证书申请参数 ([f8b71a0](https://github.com/certd/certd/commit/f8b71a0e612fad527cf49136335e0b46f0f379cd))
|
||||||
|
* 支持dns-persist-01持久化验证方式申请证书,优化Acme账号的存储方式 ([67b05e2](https://github.com/certd/certd/commit/67b05e2d75e96b9f855e1ca0b3d0d8d03b92d8e6))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 插件全局配置支持下拉选项自定义映射功能 ([c637985](https://github.com/certd/certd/commit/c637985575b09196b04cce37ac14fbe68c029bde))
|
||||||
|
* 商业版提现增加收款二维码上传 ([83a5a21](https://github.com/certd/certd/commit/83a5a21f956e50942541f1532f3a8dcaa5821d34))
|
||||||
|
* **aliyun-apig:** 优化阿里云API网关部署插件的查询及翻页 ([3e4b7f3](https://github.com/certd/certd/commit/3e4b7f30ac6f3c976c8274bdf256c69b8a2c46db))
|
||||||
|
* **trade:** 优化商品购买页面的规格展示和折扣计算,支持订单取消 ([6624769](https://github.com/certd/certd/commit/66247690326ce2789900fc9110c08b3502cea655))
|
||||||
|
|
||||||
## [1.40.5](https://github.com/certd/certd/compare/v1.40.4...v1.40.5) (2026-05-26)
|
## [1.40.5](https://github.com/certd/certd/compare/v1.40.4...v1.40.5) (2026-05-26)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@ Certd 是一款开源、免费、全自动申请和部署更新SSL证书的工
|
|||||||
关键字:证书自动申请、证书自动更新、证书自动续期、证书自动续签、证书管理工具
|
关键字:证书自动申请、证书自动更新、证书自动续期、证书自动续签、证书管理工具
|
||||||
|
|
||||||
|
|
||||||
| 官方开源地址: | |
|
| |官方开源地址: |
|
||||||
| ---- | ---- |
|
| ---- | ---- |
|
||||||
| [Github](https://github.com/certd/certd)|  |
|
| [Github](https://github.com/certd/certd)|  |
|
||||||
| [Gitee](https://gitee.com/certd/certd) |  |
|
| [Gitee](https://gitee.com/certd/certd) |  |
|
||||||
|
|||||||
@@ -33,53 +33,54 @@
|
|||||||
| 29.| **彩虹DNS** | 彩虹DNS管理系统授权 |
|
| 29.| **彩虹DNS** | 彩虹DNS管理系统授权 |
|
||||||
| 30.| **多吉云** | |
|
| 30.| **多吉云** | |
|
||||||
| 31.| **Dokploy授权** | |
|
| 31.| **Dokploy授权** | |
|
||||||
| 32.| **farcdn授权** | |
|
| 32.| **Dynadot授权** | |
|
||||||
| 33.| **FlexCDN授权** | |
|
| 33.| **farcdn授权** | |
|
||||||
| 34.| **Gcore** | Gcore |
|
| 34.| **FlexCDN授权** | |
|
||||||
| 35.| **Github授权** | |
|
| 35.| **Gcore** | Gcore |
|
||||||
| 36.| **godaddy授权** | |
|
| 36.| **Github授权** | |
|
||||||
| 37.| **HiPM DNSMgr** | HiPM DNSMgr API Token 授权 |
|
| 37.| **godaddy授权** | |
|
||||||
| 38.| **金山云授权** | |
|
| 38.| **HiPM DNSMgr** | HiPM DNSMgr API Token 授权 |
|
||||||
| 39.| **FTP授权** | |
|
| 39.| **金山云授权** | |
|
||||||
| 40.| **七牛OSS授权** | |
|
| 40.| **FTP授权** | |
|
||||||
| 41.| **腾讯云COS授权** | 腾讯云对象存储授权,包含地域和存储桶 |
|
| 41.| **七牛OSS授权** | |
|
||||||
| 42.| **s3/minio授权** | S3/minio oss授权 |
|
| 42.| **腾讯云COS授权** | 腾讯云对象存储授权,包含地域和存储桶 |
|
||||||
| 43.| **namesilo授权** | |
|
| 43.| **s3/minio授权** | S3/minio oss授权 |
|
||||||
| 44.| **Next Terminal 授权** | 用于访问 Next Terminal API 的授权配置 |
|
| 44.| **namesilo授权** | |
|
||||||
| 45.| **Nginx Proxy Manager 授权** | 用于登录 Nginx Proxy Manager,并为代理主机证书部署提供授权。 |
|
| 45.| **Next Terminal 授权** | 用于访问 Next Terminal API 的授权配置 |
|
||||||
| 46.| **1panel授权** | 账号和密码 |
|
| 46.| **Nginx Proxy Manager 授权** | 用于登录 Nginx Proxy Manager,并为代理主机证书部署提供授权。 |
|
||||||
| 47.| **支付宝** | |
|
| 47.| **1panel授权** | 账号和密码 |
|
||||||
| 48.| **白山云授权** | |
|
| 48.| **支付宝** | |
|
||||||
| 49.| **宝塔云WAF授权** | 用于连接和管理宝塔云WAF服务的授权配置 |
|
| 49.| **白山云授权** | |
|
||||||
| 50.| **cdnfly授权** | |
|
| 50.| **宝塔云WAF授权** | 用于连接和管理宝塔云WAF服务的授权配置 |
|
||||||
| 51.| **k8s授权** | |
|
| 51.| **cdnfly授权** | |
|
||||||
| 52.| **括彩云cdn授权** | 括彩云CDN,每月免费30G,[注册即领](https://kuocaicdn.com/register?code=8mn536rrzfbf8) |
|
| 52.| **k8s授权** | |
|
||||||
| 53.| **LeCDN授权** | |
|
| 53.| **括彩云cdn授权** | 括彩云CDN,每月免费30G,[注册即领](https://kuocaicdn.com/register?code=8mn536rrzfbf8) |
|
||||||
| 54.| **lucky** | |
|
| 54.| **LeCDN授权** | |
|
||||||
| 55.| **猫云授权** | |
|
| 55.| **lucky** | |
|
||||||
| 56.| **plesk授权** | |
|
| 56.| **猫云授权** | |
|
||||||
| 57.| **长亭雷池授权** | |
|
| 57.| **plesk授权** | |
|
||||||
| 58.| **群晖登录授权** | |
|
| 58.| **长亭雷池授权** | |
|
||||||
| 59.| **uniCloud** | unicloud授权 |
|
| 59.| **群晖登录授权** | |
|
||||||
| 60.| **微信支付** | |
|
| 60.| **uniCloud** | unicloud授权 |
|
||||||
| 61.| **易盾rcdn授权** | 易盾CDN,每月免费30G,[注册即领](https://rhcdn.yiduncdn.com/register?code=8mn536rrzfbf8) |
|
| 61.| **微信支付** | |
|
||||||
| 62.| **易发云短信** | sms.yfyidc.cn/ |
|
| 62.| **易盾rcdn授权** | 易盾CDN,每月免费30G,[注册即领](https://rhcdn.yiduncdn.com/register?code=8mn536rrzfbf8) |
|
||||||
| 63.| **易盾DCDN授权** | https://user.yiduncdn.com |
|
| 63.| **易发云短信** | sms.yfyidc.cn/ |
|
||||||
| 64.| **易支付** | |
|
| 64.| **易盾DCDN授权** | https://user.yiduncdn.com |
|
||||||
| 65.| **proxmox** | |
|
| 65.| **易支付** | |
|
||||||
| 66.| **Spaceship.com 授权** | Spaceship.com API 授权插件 |
|
| 66.| **proxmox** | |
|
||||||
| 67.| **Technitium DNS Server** | Technitium DNS Server 自建DNS服务器授权 |
|
| 67.| **Spaceship.com 授权** | Spaceship.com API 授权插件 |
|
||||||
| 68.| **UCloud授权** | 优刻得授权 |
|
| 68.| **Technitium DNS Server** | Technitium DNS Server 自建DNS服务器授权 |
|
||||||
| 69.| **又拍云** | |
|
| 69.| **UCloud授权** | 优刻得授权 |
|
||||||
| 70.| **网宿授权** | |
|
| 70.| **又拍云** | |
|
||||||
| 71.| **西部数码授权** | |
|
| 71.| **网宿授权** | |
|
||||||
| 72.| **我爱云授权** | 我爱云CDN |
|
| 72.| **西部数码授权** | |
|
||||||
| 73.| **新网授权(代理方式)** | |
|
| 73.| **我爱云授权** | 我爱云CDN |
|
||||||
| 74.| **新网授权** | |
|
| 74.| **新网授权(代理方式)** | |
|
||||||
| 75.| **新网互联授权** | 仅支持代理账号,ip需要加入白名单 |
|
| 75.| **新网授权** | |
|
||||||
| 76.| **Zenlayer授权** | Zenlayer授权 |
|
| 76.| **新网互联授权** | 仅支持代理账号,ip需要加入白名单 |
|
||||||
| 77.| **GoEdge授权** | |
|
| 77.| **Zenlayer授权** | Zenlayer授权 |
|
||||||
| 78.| **雨云授权** | https://app.rainyun.com/ |
|
| 78.| **GoEdge授权** | |
|
||||||
|
| 79.| **雨云授权** | https://app.rainyun.com/ |
|
||||||
|
|
||||||
<style module>
|
<style module>
|
||||||
table th:first-of-type {
|
table th:first-of-type {
|
||||||
|
|||||||
@@ -13,21 +13,22 @@
|
|||||||
| 9.| **BIND9 DNS** | 通过 SSH 连接到 BIND9 服务器,使用 nsupdate 命令管理 DNS 记录 |
|
| 9.| **BIND9 DNS** | 通过 SSH 连接到 BIND9 服务器,使用 nsupdate 命令管理 DNS 记录 |
|
||||||
| 10.| **cloudflare** | cloudflare dns provider |
|
| 10.| **cloudflare** | cloudflare dns provider |
|
||||||
| 11.| **dns.la** | dns.la |
|
| 11.| **dns.la** | dns.la |
|
||||||
| 12.| **godaddy** | GoDaddy |
|
| 12.| **Dynadot** | Dynadot DNS提供商 |
|
||||||
| 13.| **HiPM DNSMgr** | HiPM DNSMgr DNS 解析提供商 |
|
| 13.| **godaddy** | GoDaddy |
|
||||||
| 14.| **华为云** | 华为云DNS解析提供商 |
|
| 14.| **HiPM DNSMgr** | HiPM DNSMgr DNS 解析提供商 |
|
||||||
| 15.| **namesilo** | namesilo dns provider |
|
| 15.| **华为云** | 华为云DNS解析提供商 |
|
||||||
| 16.| **雨云** | 雨云DNS解析提供商 |
|
| 16.| **namesilo** | namesilo dns provider |
|
||||||
| 17.| **Technitium DNS Server** | Technitium DNS Server 自建DNS服务器 |
|
| 17.| **雨云** | 雨云DNS解析提供商 |
|
||||||
| 18.| **腾讯云** | 腾讯云域名DNS解析提供者 |
|
| 18.| **Technitium DNS Server** | Technitium DNS Server 自建DNS服务器 |
|
||||||
| 19.| **腾讯云EO DNS** | 腾讯云EO DNS解析提供者 |
|
| 19.| **腾讯云** | 腾讯云域名DNS解析提供者 |
|
||||||
| 20.| **西部数码** | west dns provider |
|
| 20.| **腾讯云EO DNS** | 腾讯云EO DNS解析提供者 |
|
||||||
| 21.| **Google Cloud DNS** | Google Cloud DNS提供商 |
|
| 21.| **西部数码** | west dns provider |
|
||||||
| 22.| **Dns提供商Demo** | dns provider示例 |
|
| 22.| **Google Cloud DNS** | Google Cloud DNS提供商 |
|
||||||
| 23.| **彩虹DNS** | 彩虹DNS管理系统 |
|
| 23.| **Dns提供商Demo** | dns provider示例 |
|
||||||
| 24.| **Spaceship** | Spaceship 域名解析 |
|
| 24.| **彩虹DNS** | 彩虹DNS管理系统 |
|
||||||
| 25.| **51dns** | 51DNS |
|
| 25.| **Spaceship** | Spaceship 域名解析 |
|
||||||
| 26.| **新网互联** | 新网互联 |
|
| 26.| **51dns** | 51DNS |
|
||||||
|
| 27.| **新网互联** | 新网互联 |
|
||||||
|
|
||||||
<style module>
|
<style module>
|
||||||
table th:first-of-type {
|
table th:first-of-type {
|
||||||
|
|||||||
+1
-1
@@ -9,5 +9,5 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"npmClient": "pnpm",
|
"npmClient": "pnpm",
|
||||||
"version": "1.41.0"
|
"version": "1.41.4"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,24 @@
|
|||||||
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.41.4](https://github.com/publishlab/node-acme-client/compare/v1.41.3...v1.41.4) (2026-06-14)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.41.3](https://github.com/publishlab/node-acme-client/compare/v1.41.2...v1.41.3) (2026-06-11)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复litessl无法申请证书,报authorization must be pending 错误的问题 ([d6cd9d1](https://github.com/publishlab/node-acme-client/commit/d6cd9d136d2812b2335917305f36d6d9414507ad))
|
||||||
|
|
||||||
|
## [1.41.2](https://github.com/publishlab/node-acme-client/compare/v1.41.1...v1.41.2) (2026-06-10)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.41.1](https://github.com/publishlab/node-acme-client/compare/v1.41.0...v1.41.1) (2026-06-05)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
# [1.41.0](https://github.com/publishlab/node-acme-client/compare/v1.40.5...v1.41.0) (2026-06-04)
|
# [1.41.0](https://github.com/publishlab/node-acme-client/compare/v1.40.5...v1.41.0) (2026-06-04)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
@@ -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.41.0",
|
"version": "1.41.4",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"module": "./dist/index.js",
|
"module": "./dist/index.js",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
"types"
|
"types"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@certd/basic": "^1.41.0",
|
"@certd/basic": "^1.41.4",
|
||||||
"@peculiar/x509": "^1.11.0",
|
"@peculiar/x509": "^1.11.0",
|
||||||
"asn1js": "^3.0.5",
|
"asn1js": "^3.0.5",
|
||||||
"axios": "^1.9.0",
|
"axios": "^1.9.0",
|
||||||
@@ -76,5 +76,5 @@
|
|||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/publishlab/node-acme-client/issues"
|
"url": "https://github.com/publishlab/node-acme-client/issues"
|
||||||
},
|
},
|
||||||
"gitHead": "7ceb0f6306b8b5e9ab875b9f7c41cc7d56209ea4"
|
"gitHead": "bc731e4fb119787930e816a7d57c808b1b5cd66a"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
import assert from "node:assert/strict";
|
||||||
|
import auto from "./auto.js";
|
||||||
|
import { createCsr, createPrivateRsaKey } from "./crypto/index.js";
|
||||||
|
|
||||||
|
declare const describe: any;
|
||||||
|
declare const it: any;
|
||||||
|
|
||||||
|
describe("auto challenge status polling", () => {
|
||||||
|
it("polls the authorization URL after completing a challenge", async () => {
|
||||||
|
const [, csr] = await createCsr({ commonName: "example.com" }, await createPrivateRsaKey());
|
||||||
|
const challenge = {
|
||||||
|
type: "dns-01",
|
||||||
|
url: "https://ca.example/chall/1",
|
||||||
|
token: "token",
|
||||||
|
};
|
||||||
|
const authz = {
|
||||||
|
status: "pending",
|
||||||
|
identifier: { type: "dns", value: "example.com" },
|
||||||
|
url: "https://ca.example/authz/1",
|
||||||
|
challenges: [challenge],
|
||||||
|
};
|
||||||
|
const order = {
|
||||||
|
status: "pending",
|
||||||
|
url: "https://ca.example/order/1",
|
||||||
|
finalize: "https://ca.example/order/1/finalize",
|
||||||
|
authorizations: [authz.url],
|
||||||
|
};
|
||||||
|
const polledUrls: string[] = [];
|
||||||
|
const originalSetTimeout = globalThis.setTimeout;
|
||||||
|
|
||||||
|
(globalThis as any).setTimeout = (fn: (...args: any[]) => void) => originalSetTimeout(fn, 0);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const certificate = await auto(
|
||||||
|
{
|
||||||
|
logger: { info: () => {} },
|
||||||
|
sslProvider: "litessl",
|
||||||
|
getAccountUrl: () => "https://ca.example/acct/1",
|
||||||
|
createOrder: async () => order,
|
||||||
|
getAuthorizations: async () => [authz],
|
||||||
|
getChallengeKeyAuthorization: async () => "key-authorization",
|
||||||
|
verifyChallenge: async () => {},
|
||||||
|
completeChallenge: async () => ({ ...challenge, status: "processing" }),
|
||||||
|
waitForValidStatus: async (item: { url: string }) => {
|
||||||
|
polledUrls.push(item.url);
|
||||||
|
return { ...item, status: "valid" };
|
||||||
|
},
|
||||||
|
finalizeOrder: async () => ({ ...order, status: "valid", certificate: "https://ca.example/cert/1" }),
|
||||||
|
getCertificate: async () => "CERTIFICATE",
|
||||||
|
} as any,
|
||||||
|
{
|
||||||
|
csr,
|
||||||
|
termsOfServiceAgreed: true,
|
||||||
|
waitDnsDiffuseTime: 0,
|
||||||
|
challengeCreateFn: async (_authz: any, keyAuthorizationGetter: (challenge: any) => Promise<string>) => ({
|
||||||
|
challenge,
|
||||||
|
keyAuthorization: await keyAuthorizationGetter(challenge),
|
||||||
|
}),
|
||||||
|
challengeRemoveFn: async () => {},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.equal(certificate, "CERTIFICATE");
|
||||||
|
assert.deepEqual(polledUrls, [authz.url]);
|
||||||
|
} finally {
|
||||||
|
(globalThis as any).setTimeout = originalSetTimeout;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -172,7 +172,7 @@ export default async (client, userOpts) => {
|
|||||||
}
|
}
|
||||||
challengeCompleted = true;
|
challengeCompleted = true;
|
||||||
log(`[auto] [${d}] 等待返回valid状态`);
|
log(`[auto] [${d}] 等待返回valid状态`);
|
||||||
await client.waitForValidStatus(challenge,d);
|
await client.waitForValidStatus(authz,d);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -263,4 +263,4 @@ export function createChallengeFn(opts = {}) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// createChallengeFn({logger:{info:console.log}}).walkDnsChallengeRecord("handsfree.work")
|
// createChallengeFn({logger:{info:console.log}}).walkDnsChallengeRecord("handfree.work")
|
||||||
|
|||||||
@@ -3,6 +3,28 @@
|
|||||||
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.41.4](https://github.com/certd/certd/compare/v1.41.3...v1.41.4) (2026-06-14)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复设置里面不显示tab页签,导致某些页面需要点击查询按钮才有数据出来的bug ([c1b5a35](https://github.com/certd/certd/commit/c1b5a35f90a7d4b41397717b5c27905bc68e1bfb))
|
||||||
|
|
||||||
|
## [1.41.3](https://github.com/certd/certd/compare/v1.41.2...v1.41.3) (2026-06-11)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.41.2](https://github.com/certd/certd/compare/v1.41.1...v1.41.2) (2026-06-10)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 新增站点证书监控从DNS解析记录批量导入功能 ([f9541fa](https://github.com/certd/certd/commit/f9541fab701e01ba57af061da322204c894adfb8))
|
||||||
|
|
||||||
|
## [1.41.1](https://github.com/certd/certd/compare/v1.41.0...v1.41.1) (2026-06-05)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* **settings:** 新增NO_PROXY代理排除配置 ([c0df8be](https://github.com/certd/certd/commit/c0df8be83237e323c2c9a5bd02507430a86a00cc))
|
||||||
|
|
||||||
# [1.41.0](https://github.com/certd/certd/compare/v1.40.5...v1.41.0) (2026-06-04)
|
# [1.41.0](https://github.com/certd/certd/compare/v1.40.5...v1.41.0) (2026-06-04)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/basic
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
12:22
|
21:25
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/basic",
|
"name": "@certd/basic",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.41.0",
|
"version": "1.41.4",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"module": "./dist/index.js",
|
"module": "./dist/index.js",
|
||||||
@@ -52,5 +52,5 @@
|
|||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "7ceb0f6306b8b5e9ab875b9f7c41cc7d56209ea4"
|
"gitHead": "bc731e4fb119787930e816a7d57c808b1b5cd66a"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { expect } from "chai";
|
import { expect } from "chai";
|
||||||
import { createAxiosService, HttpClient, setGlobalHeaders } from "./util.request.js";
|
import { createAgent, createAxiosService, getGlobalAgents, HttpClient, isNoProxyMatched, setGlobalHeaders, setGlobalProxy } from "./util.request.js";
|
||||||
import { ILogger } from "./util.log.js";
|
import { ILogger } from "./util.log.js";
|
||||||
|
|
||||||
const testLogger = {
|
const testLogger = {
|
||||||
|
debug() {},
|
||||||
info() {},
|
info() {},
|
||||||
error() {},
|
error() {},
|
||||||
} as unknown as ILogger;
|
} as unknown as ILogger;
|
||||||
@@ -10,6 +11,9 @@ const testLogger = {
|
|||||||
describe("util.request", () => {
|
describe("util.request", () => {
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
setGlobalHeaders({});
|
setGlobalHeaders({});
|
||||||
|
setGlobalProxy({});
|
||||||
|
delete process.env.NO_PROXY;
|
||||||
|
delete process.env.no_proxy;
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should merge global headers without overriding request headers", async () => {
|
it("should merge global headers without overriding request headers", async () => {
|
||||||
@@ -50,4 +54,122 @@ describe("util.request", () => {
|
|||||||
request: "request",
|
request: "request",
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should set no_proxy environment variables", () => {
|
||||||
|
setGlobalProxy({
|
||||||
|
httpProxy: "http://127.0.0.1:1080",
|
||||||
|
httpsProxy: "http://127.0.0.1:1080",
|
||||||
|
noProxy: "localhost,*.internal.example.com",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(process.env.NO_PROXY).to.equal("localhost,*.internal.example.com");
|
||||||
|
expect(process.env.no_proxy).to.equal("localhost,*.internal.example.com");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should normalize multiline no_proxy environment variables", () => {
|
||||||
|
setGlobalProxy({
|
||||||
|
noProxy: "localhost\n127.0.0.1, 192.168.*\n*.internal.example.com",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(process.env.NO_PROXY).to.equal("localhost,127.0.0.1,192.168.*,*.internal.example.com");
|
||||||
|
expect(process.env.no_proxy).to.equal("localhost,127.0.0.1,192.168.*,*.internal.example.com");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not change environment variables when creating agents", () => {
|
||||||
|
process.env.HTTP_PROXY = "http://old-http-proxy";
|
||||||
|
process.env.HTTPS_PROXY = "http://old-https-proxy";
|
||||||
|
process.env.NO_PROXY = "old.local";
|
||||||
|
|
||||||
|
createAgent({
|
||||||
|
httpProxy: "http://127.0.0.1:1080",
|
||||||
|
httpsProxy: "http://127.0.0.1:1081",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(process.env.HTTP_PROXY).to.equal("http://old-http-proxy");
|
||||||
|
expect(process.env.HTTPS_PROXY).to.equal("http://old-https-proxy");
|
||||||
|
expect(process.env.NO_PROXY).to.equal("old.local");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should bypass global proxy when request host matches no_proxy", async () => {
|
||||||
|
setGlobalProxy({
|
||||||
|
httpProxy: "http://127.0.0.1:1080",
|
||||||
|
httpsProxy: "http://127.0.0.1:1080",
|
||||||
|
noProxy: "localhost,.internal.example.com",
|
||||||
|
});
|
||||||
|
|
||||||
|
const globalAgents = getGlobalAgents();
|
||||||
|
const http = createAxiosService({ logger: testLogger }) as HttpClient;
|
||||||
|
const res = await http.request({
|
||||||
|
url: "https://api.internal.example.com",
|
||||||
|
method: "get",
|
||||||
|
logReq: false,
|
||||||
|
logRes: false,
|
||||||
|
adapter: async config => {
|
||||||
|
return {
|
||||||
|
config,
|
||||||
|
data: {
|
||||||
|
usesGlobalHttpAgent: config.httpAgent === globalAgents.httpAgent,
|
||||||
|
usesGlobalHttpsAgent: config.httpsAgent === globalAgents.httpsAgent,
|
||||||
|
},
|
||||||
|
headers: {},
|
||||||
|
status: 200,
|
||||||
|
statusText: "OK",
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(res).to.deep.equal({
|
||||||
|
usesGlobalHttpAgent: false,
|
||||||
|
usesGlobalHttpsAgent: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should bypass custom request proxy when request host matches no_proxy", async () => {
|
||||||
|
setGlobalProxy({
|
||||||
|
noProxy: ".internal.example.com",
|
||||||
|
});
|
||||||
|
|
||||||
|
const http = createAxiosService({ logger: testLogger }) as HttpClient;
|
||||||
|
const res = await http.request({
|
||||||
|
url: "https://api.internal.example.com",
|
||||||
|
method: "get",
|
||||||
|
httpProxy: "http://127.0.0.1:1080",
|
||||||
|
logReq: false,
|
||||||
|
logRes: false,
|
||||||
|
adapter: async config => {
|
||||||
|
return {
|
||||||
|
config,
|
||||||
|
data: {
|
||||||
|
httpAgent: config.httpAgent?.constructor?.name,
|
||||||
|
httpsAgent: config.httpsAgent?.constructor?.name,
|
||||||
|
},
|
||||||
|
headers: {},
|
||||||
|
status: 200,
|
||||||
|
statusText: "OK",
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(res).to.deep.equal({
|
||||||
|
httpAgent: "Agent",
|
||||||
|
httpsAgent: "Agent",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should match no_proxy rules", () => {
|
||||||
|
expect(isNoProxyMatched("*", { hostname: "api.example.com", port: "" })).to.equal(true);
|
||||||
|
expect(isNoProxyMatched("api.example.com", { hostname: "api.example.com", port: "" })).to.equal(true);
|
||||||
|
expect(isNoProxyMatched("example.com", { hostname: "api.example.com", port: "" })).to.equal(true);
|
||||||
|
expect(isNoProxyMatched(".example.com", { hostname: "api.example.com", port: "" })).to.equal(true);
|
||||||
|
expect(isNoProxyMatched("*.example.com", { hostname: "api.example.com", port: "" })).to.equal(true);
|
||||||
|
expect(isNoProxyMatched("127.0.0.1", { hostname: "127.0.0.1", port: "" })).to.equal(true);
|
||||||
|
expect(isNoProxyMatched("192.168.*", { hostname: "192.168.1.10", port: "" })).to.equal(true);
|
||||||
|
expect(isNoProxyMatched("192.168.*", { hostname: "192.169.1.10", port: "" })).to.equal(false);
|
||||||
|
expect(isNoProxyMatched("[::1]", { hostname: "::1", port: "" })).to.equal(true);
|
||||||
|
expect(isNoProxyMatched("[::1]:8443", { hostname: "::1", port: "8443" })).to.equal(true);
|
||||||
|
expect(isNoProxyMatched("api.example.com:8443", { hostname: "api.example.com", port: "8443" })).to.equal(true);
|
||||||
|
expect(isNoProxyMatched("api.example.com:8443", { hostname: "api.example.com", port: "443" })).to.equal(false);
|
||||||
|
expect(isNoProxyMatched("127.0.0.1", { hostname: "127.0.0.2", port: "" })).to.equal(false);
|
||||||
|
expect(isNoProxyMatched(".example.com", { hostname: "example.org", port: "" })).to.equal(false);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -82,11 +82,24 @@ export class HttpError extends Error {
|
|||||||
export const HttpCommonError = HttpError;
|
export const HttpCommonError = HttpError;
|
||||||
|
|
||||||
let defaultAgents = createAgent();
|
let defaultAgents = createAgent();
|
||||||
|
const directAgents = createAgent();
|
||||||
|
let defaultProxyOptions: GlobalProxyOptions = {};
|
||||||
let defaultHeaders: Record<string, string> = {};
|
let defaultHeaders: Record<string, string> = {};
|
||||||
|
|
||||||
export function setGlobalProxy(opts: { httpProxy?: string; httpsProxy?: string }) {
|
export type GlobalProxyOptions = {
|
||||||
|
httpProxy?: string;
|
||||||
|
httpsProxy?: string;
|
||||||
|
noProxy?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function setGlobalProxy(opts: GlobalProxyOptions) {
|
||||||
logger.info("setGlobalProxy:", opts);
|
logger.info("setGlobalProxy:", opts);
|
||||||
defaultAgents = createAgent(opts);
|
defaultProxyOptions = { ...opts };
|
||||||
|
defaultAgents = createAgent({
|
||||||
|
httpProxy: opts.httpProxy,
|
||||||
|
httpsProxy: opts.httpsProxy,
|
||||||
|
});
|
||||||
|
setProxyEnvironment(opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getGlobalAgents() {
|
export function getGlobalAgents() {
|
||||||
@@ -137,21 +150,25 @@ export function createAxiosService({ logger }: { logger: ILogger }) {
|
|||||||
if (config.timeout == null) {
|
if (config.timeout == null) {
|
||||||
config.timeout = 15000;
|
config.timeout = 15000;
|
||||||
}
|
}
|
||||||
let agents = defaultAgents;
|
const bypassProxy = shouldBypassProxy(config, defaultProxyOptions.noProxy);
|
||||||
if (config.skipSslVerify || config.httpProxy) {
|
const useCustomProxy = !!config.httpProxy && !bypassProxy;
|
||||||
let rejectUnauthorized = true;
|
let agents = bypassProxy ? directAgents : defaultAgents;
|
||||||
|
if (bypassProxy) {
|
||||||
|
logger.info("命中no_proxy配置,跳过代理:", config.url);
|
||||||
|
}
|
||||||
|
if (config.skipSslVerify || useCustomProxy) {
|
||||||
|
const agentOptions: any = {};
|
||||||
if (config.skipSslVerify) {
|
if (config.skipSslVerify) {
|
||||||
logger.info("忽略接口请求的SSL校验");
|
logger.info("忽略接口请求的SSL校验");
|
||||||
rejectUnauthorized = false;
|
agentOptions.rejectUnauthorized = false;
|
||||||
}
|
}
|
||||||
const proxy: any = {};
|
if (useCustomProxy) {
|
||||||
if (config.httpProxy) {
|
|
||||||
logger.info("使用自定义http代理:", config.httpProxy);
|
logger.info("使用自定义http代理:", config.httpProxy);
|
||||||
proxy.httpProxy = config.httpProxy;
|
agentOptions.httpProxy = config.httpProxy;
|
||||||
proxy.httpsProxy = config.httpProxy;
|
agentOptions.httpsProxy = config.httpProxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
agents = createAgent({ rejectUnauthorized, ...proxy } as any);
|
agents = createAgent(agentOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete config.skipSslVerify;
|
delete config.skipSslVerify;
|
||||||
@@ -354,7 +371,7 @@ export type CreateAgentOptions = {
|
|||||||
httpsProxy?: string;
|
httpsProxy?: string;
|
||||||
} & nodeHttp.AgentOptions;
|
} & nodeHttp.AgentOptions;
|
||||||
export function createAgent(opts: CreateAgentOptions = {}) {
|
export function createAgent(opts: CreateAgentOptions = {}) {
|
||||||
opts = merge(
|
const { httpProxy, httpsProxy, ...agentOptions } = merge(
|
||||||
{
|
{
|
||||||
autoSelectFamily: true,
|
autoSelectFamily: true,
|
||||||
autoSelectFamilyAttemptTimeout: 1000,
|
autoSelectFamilyAttemptTimeout: 1000,
|
||||||
@@ -364,29 +381,19 @@ export function createAgent(opts: CreateAgentOptions = {}) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let httpAgent, httpsAgent;
|
let httpAgent, httpsAgent;
|
||||||
const httpProxy = opts.httpProxy;
|
|
||||||
if (httpProxy) {
|
if (httpProxy) {
|
||||||
process.env.HTTP_PROXY = httpProxy;
|
|
||||||
process.env.http_proxy = httpProxy;
|
|
||||||
logger.info("use httpProxy:", httpProxy);
|
logger.info("use httpProxy:", httpProxy);
|
||||||
httpAgent = new HttpProxyAgent(httpProxy, opts as any);
|
httpAgent = new HttpProxyAgent(httpProxy, agentOptions as any);
|
||||||
merge(httpAgent.options, opts);
|
merge(httpAgent.options, agentOptions);
|
||||||
} else {
|
} else {
|
||||||
process.env.HTTP_PROXY = "";
|
httpAgent = new nodeHttp.Agent(agentOptions);
|
||||||
process.env.http_proxy = "";
|
|
||||||
httpAgent = new nodeHttp.Agent(opts);
|
|
||||||
}
|
}
|
||||||
const httpsProxy = opts.httpsProxy;
|
|
||||||
if (httpsProxy) {
|
if (httpsProxy) {
|
||||||
process.env.HTTPS_PROXY = httpsProxy;
|
|
||||||
process.env.https_proxy = httpsProxy;
|
|
||||||
logger.info("use httpsProxy:", httpsProxy);
|
logger.info("use httpsProxy:", httpsProxy);
|
||||||
httpsAgent = new HttpsProxyAgent(httpsProxy, opts as any);
|
httpsAgent = new HttpsProxyAgent(httpsProxy, agentOptions as any);
|
||||||
merge(httpsAgent.options, opts);
|
merge(httpsAgent.options, agentOptions);
|
||||||
} else {
|
} else {
|
||||||
process.env.HTTPS_PROXY = "";
|
httpsAgent = new https.Agent(agentOptions);
|
||||||
process.env.https_proxy = "";
|
|
||||||
httpsAgent = new https.Agent(opts);
|
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
httpAgent,
|
httpAgent,
|
||||||
@@ -394,6 +401,145 @@ export function createAgent(opts: CreateAgentOptions = {}) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setProxyEnvironment(opts: GlobalProxyOptions = {}) {
|
||||||
|
setEnvValue("HTTP_PROXY", opts.httpProxy);
|
||||||
|
setEnvValue("http_proxy", opts.httpProxy);
|
||||||
|
setEnvValue("HTTPS_PROXY", opts.httpsProxy);
|
||||||
|
setEnvValue("https_proxy", opts.httpsProxy);
|
||||||
|
const noProxy = normalizeNoProxyText(opts.noProxy);
|
||||||
|
setEnvValue("NO_PROXY", noProxy);
|
||||||
|
setEnvValue("no_proxy", noProxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setEnvValue(key: string, value?: string) {
|
||||||
|
process.env[key] = value || "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function shouldBypassProxy(config: AxiosRequestConfig, noProxy?: string) {
|
||||||
|
if (!noProxy) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const target = getRequestTarget(config);
|
||||||
|
if (!target) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return splitNoProxyRules(noProxy).some(item => isNoProxyMatched(item, target));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRequestTarget(config: AxiosRequestConfig) {
|
||||||
|
try {
|
||||||
|
const baseURL = config.baseURL || undefined;
|
||||||
|
const url = new URL(config.url || "", baseURL);
|
||||||
|
return {
|
||||||
|
hostname: normalizeHost(url.hostname),
|
||||||
|
port: url.port,
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isNoProxyMatched(rule: string, target: { hostname: string; port: string }) {
|
||||||
|
if (rule === "*") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const normalizedRule = normalizeNoProxyRule(rule);
|
||||||
|
if (!normalizedRule.host) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (normalizedRule.port && normalizedRule.port !== target.port) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const host = normalizeHost(target.hostname);
|
||||||
|
if (normalizedRule.host.includes("*")) {
|
||||||
|
return wildcardHostMatched(normalizedRule.host, host);
|
||||||
|
}
|
||||||
|
if (normalizedRule.host.startsWith("*.")) {
|
||||||
|
const suffix = normalizedRule.host.substring(1);
|
||||||
|
return host.endsWith(suffix);
|
||||||
|
}
|
||||||
|
if (normalizedRule.host.startsWith(".")) {
|
||||||
|
return host === normalizedRule.host.substring(1) || host.endsWith(normalizedRule.host);
|
||||||
|
}
|
||||||
|
return host === normalizedRule.host || host.endsWith(`.${normalizedRule.host}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeNoProxyRule(rule: string) {
|
||||||
|
let value = rule.trim().toLowerCase();
|
||||||
|
if (value.includes("://")) {
|
||||||
|
try {
|
||||||
|
const url = new URL(value);
|
||||||
|
return {
|
||||||
|
host: normalizeHost(url.hostname),
|
||||||
|
port: url.port,
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
return {
|
||||||
|
host: "",
|
||||||
|
port: "",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let port = "";
|
||||||
|
if (value.startsWith("[")) {
|
||||||
|
const closeIndex = value.indexOf("]");
|
||||||
|
const host = value.substring(1, closeIndex);
|
||||||
|
const rest = value.substring(closeIndex + 1);
|
||||||
|
if (rest.startsWith(":")) {
|
||||||
|
port = rest.substring(1);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
host: normalizeHost(host),
|
||||||
|
port,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const colonCount = (value.match(/:/g) || []).length;
|
||||||
|
const portIndex = value.lastIndexOf(":");
|
||||||
|
if (colonCount === 1 && portIndex > -1) {
|
||||||
|
port = value.substring(portIndex + 1);
|
||||||
|
value = value.substring(0, portIndex);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
host: normalizeHost(value),
|
||||||
|
port,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeHost(host: string) {
|
||||||
|
let value = host.trim().toLowerCase();
|
||||||
|
if (value.startsWith("[") && value.endsWith("]")) {
|
||||||
|
value = value.substring(1, value.length - 1);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function wildcardHostMatched(rule: string, host: string) {
|
||||||
|
const pattern = rule.split("*").map(escapeRegExp).join(".*");
|
||||||
|
return new RegExp(`^${pattern}$`).test(host);
|
||||||
|
}
|
||||||
|
|
||||||
|
function escapeRegExp(value: string) {
|
||||||
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeNoProxyText(noProxy?: string) {
|
||||||
|
return splitNoProxyRules(noProxy).join(",");
|
||||||
|
}
|
||||||
|
|
||||||
|
function splitNoProxyRules(noProxy?: string) {
|
||||||
|
if (!noProxy) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return noProxy
|
||||||
|
.split(/[,\s]+/)
|
||||||
|
.map(item => item.trim())
|
||||||
|
.filter(Boolean);
|
||||||
|
}
|
||||||
|
|
||||||
export async function download(req: { http: HttpClient; config: HttpRequestConfig; savePath: string; logger: ILogger }) {
|
export async function download(req: { http: HttpClient; config: HttpRequestConfig; savePath: string; logger: ILogger }) {
|
||||||
const { http, config, savePath, logger } = req;
|
const { http, config, savePath, logger } = req;
|
||||||
return safePromise((resolve, reject) => {
|
return safePromise((resolve, reject) => {
|
||||||
|
|||||||
@@ -3,6 +3,24 @@
|
|||||||
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.41.4](https://github.com/certd/certd/compare/v1.41.3...v1.41.4) (2026-06-14)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/pipeline
|
||||||
|
|
||||||
|
## [1.41.3](https://github.com/certd/certd/compare/v1.41.2...v1.41.3) (2026-06-11)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/pipeline
|
||||||
|
|
||||||
|
## [1.41.2](https://github.com/certd/certd/compare/v1.41.1...v1.41.2) (2026-06-10)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 新增站点证书监控从DNS解析记录批量导入功能 ([f9541fa](https://github.com/certd/certd/commit/f9541fab701e01ba57af061da322204c894adfb8))
|
||||||
|
|
||||||
|
## [1.41.1](https://github.com/certd/certd/compare/v1.41.0...v1.41.1) (2026-06-05)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/pipeline
|
||||||
|
|
||||||
# [1.41.0](https://github.com/certd/certd/compare/v1.40.5...v1.41.0) (2026-06-04)
|
# [1.41.0](https://github.com/certd/certd/compare/v1.40.5...v1.41.0) (2026-06-04)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/pipeline",
|
"name": "@certd/pipeline",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.41.0",
|
"version": "1.41.4",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"module": "./dist/index.js",
|
"module": "./dist/index.js",
|
||||||
@@ -19,8 +19,8 @@
|
|||||||
"compile": "tsc --skipLibCheck --watch"
|
"compile": "tsc --skipLibCheck --watch"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@certd/basic": "^1.41.0",
|
"@certd/basic": "^1.41.4",
|
||||||
"@certd/plus-core": "^1.41.0",
|
"@certd/plus-core": "^1.41.4",
|
||||||
"dayjs": "^1.11.7",
|
"dayjs": "^1.11.7",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"reflect-metadata": "^0.1.13"
|
"reflect-metadata": "^0.1.13"
|
||||||
@@ -49,5 +49,5 @@
|
|||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "7ceb0f6306b8b5e9ab875b9f7c41cc7d56209ea4"
|
"gitHead": "bc731e4fb119787930e816a7d57c808b1b5cd66a"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ export type Registrable = {
|
|||||||
group?: string;
|
group?: string;
|
||||||
deprecated?: string;
|
deprecated?: string;
|
||||||
order?: number;
|
order?: number;
|
||||||
|
icon?: string;
|
||||||
};
|
};
|
||||||
export type TargetGetter<T> = () => Promise<T>;
|
export type TargetGetter<T> = () => Promise<T>;
|
||||||
export type RegistryItem<T> = {
|
export type RegistryItem<T> = {
|
||||||
|
|||||||
@@ -3,6 +3,24 @@
|
|||||||
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.41.4](https://github.com/certd/certd/compare/v1.41.3...v1.41.4) (2026-06-14)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复设置里面不显示tab页签,导致某些页面需要点击查询按钮才有数据出来的bug ([c1b5a35](https://github.com/certd/certd/commit/c1b5a35f90a7d4b41397717b5c27905bc68e1bfb))
|
||||||
|
|
||||||
|
## [1.41.3](https://github.com/certd/certd/compare/v1.41.2...v1.41.3) (2026-06-11)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-huawei
|
||||||
|
|
||||||
|
## [1.41.2](https://github.com/certd/certd/compare/v1.41.1...v1.41.2) (2026-06-10)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-huawei
|
||||||
|
|
||||||
|
## [1.41.1](https://github.com/certd/certd/compare/v1.41.0...v1.41.1) (2026-06-05)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-huawei
|
||||||
|
|
||||||
# [1.41.0](https://github.com/certd/certd/compare/v1.40.5...v1.41.0) (2026-06-04)
|
# [1.41.0](https://github.com/certd/certd/compare/v1.40.5...v1.41.0) (2026-06-04)
|
||||||
|
|
||||||
**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.41.0",
|
"version": "1.41.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",
|
||||||
@@ -12,7 +12,8 @@
|
|||||||
"dev-build": "npm run build",
|
"dev-build": "npm run build",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"test:unit": "cross-env NODE_ENV=unittest echo no unit tests",
|
"test:unit": "cross-env NODE_ENV=unittest echo no unit tests",
|
||||||
"pub": "npm publish"
|
"pub": "npm publish",
|
||||||
|
"compile": "npm run build"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.9.0",
|
"axios": "^1.9.0",
|
||||||
@@ -27,5 +28,5 @@
|
|||||||
"prettier": "^2.8.8",
|
"prettier": "^2.8.8",
|
||||||
"tslib": "^2.8.1"
|
"tslib": "^2.8.1"
|
||||||
},
|
},
|
||||||
"gitHead": "7ceb0f6306b8b5e9ab875b9f7c41cc7d56209ea4"
|
"gitHead": "bc731e4fb119787930e816a7d57c808b1b5cd66a"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,24 @@
|
|||||||
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.41.4](https://github.com/certd/certd/compare/v1.41.3...v1.41.4) (2026-06-14)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复设置里面不显示tab页签,导致某些页面需要点击查询按钮才有数据出来的bug ([c1b5a35](https://github.com/certd/certd/commit/c1b5a35f90a7d4b41397717b5c27905bc68e1bfb))
|
||||||
|
|
||||||
|
## [1.41.3](https://github.com/certd/certd/compare/v1.41.2...v1.41.3) (2026-06-11)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-iframe
|
||||||
|
|
||||||
|
## [1.41.2](https://github.com/certd/certd/compare/v1.41.1...v1.41.2) (2026-06-10)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-iframe
|
||||||
|
|
||||||
|
## [1.41.1](https://github.com/certd/certd/compare/v1.41.0...v1.41.1) (2026-06-05)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-iframe
|
||||||
|
|
||||||
# [1.41.0](https://github.com/certd/certd/compare/v1.40.5...v1.41.0) (2026-06-04)
|
# [1.41.0](https://github.com/certd/certd/compare/v1.40.5...v1.41.0) (2026-06-04)
|
||||||
|
|
||||||
**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.41.0",
|
"version": "1.41.4",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"module": "./dist/index.js",
|
"module": "./dist/index.js",
|
||||||
@@ -15,7 +15,8 @@
|
|||||||
"build2": "vue-tsc --noEmit && vite build",
|
"build2": "vue-tsc --noEmit && vite build",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"test:unit": "cross-env NODE_ENV=unittest echo no unit tests",
|
"test:unit": "cross-env NODE_ENV=unittest echo no unit tests",
|
||||||
"pub": "npm publish"
|
"pub": "npm publish",
|
||||||
|
"compile": "npm run build"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"nanoid": "^4.0.0"
|
"nanoid": "^4.0.0"
|
||||||
@@ -34,5 +35,5 @@
|
|||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "7ceb0f6306b8b5e9ab875b9f7c41cc7d56209ea4"
|
"gitHead": "bc731e4fb119787930e816a7d57c808b1b5cd66a"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,24 @@
|
|||||||
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.41.4](https://github.com/certd/certd/compare/v1.41.3...v1.41.4) (2026-06-14)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复设置里面不显示tab页签,导致某些页面需要点击查询按钮才有数据出来的bug ([c1b5a35](https://github.com/certd/certd/commit/c1b5a35f90a7d4b41397717b5c27905bc68e1bfb))
|
||||||
|
|
||||||
|
## [1.41.3](https://github.com/certd/certd/compare/v1.41.2...v1.41.3) (2026-06-11)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/jdcloud
|
||||||
|
|
||||||
|
## [1.41.2](https://github.com/certd/certd/compare/v1.41.1...v1.41.2) (2026-06-10)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/jdcloud
|
||||||
|
|
||||||
|
## [1.41.1](https://github.com/certd/certd/compare/v1.41.0...v1.41.1) (2026-06-05)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/jdcloud
|
||||||
|
|
||||||
# [1.41.0](https://github.com/certd/certd/compare/v1.40.5...v1.41.0) (2026-06-04)
|
# [1.41.0](https://github.com/certd/certd/compare/v1.40.5...v1.41.0) (2026-06-04)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/jdcloud
|
**Note:** Version bump only for package @certd/jdcloud
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/jdcloud",
|
"name": "@certd/jdcloud",
|
||||||
"version": "1.41.0",
|
"version": "1.41.4",
|
||||||
"description": "jdcloud openApi sdk",
|
"description": "jdcloud openApi sdk",
|
||||||
"main": "./dist/bundle.js",
|
"main": "./dist/bundle.js",
|
||||||
"module": "./dist/bundle.js",
|
"module": "./dist/bundle.js",
|
||||||
@@ -10,7 +10,8 @@
|
|||||||
"build": "npm run before-build && rollup -c ",
|
"build": "npm run before-build && rollup -c ",
|
||||||
"dev-build": "npm run build",
|
"dev-build": "npm run build",
|
||||||
"test:unit": "cross-env NODE_ENV=unittest echo no unit tests",
|
"test:unit": "cross-env NODE_ENV=unittest echo no unit tests",
|
||||||
"pub": "npm publish"
|
"pub": "npm publish",
|
||||||
|
"compile": "npm run build"
|
||||||
},
|
},
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "Apache",
|
"license": "Apache",
|
||||||
@@ -59,5 +60,5 @@
|
|||||||
"fetch"
|
"fetch"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"gitHead": "7ceb0f6306b8b5e9ab875b9f7c41cc7d56209ea4"
|
"gitHead": "bc731e4fb119787930e816a7d57c808b1b5cd66a"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,22 @@
|
|||||||
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.41.4](https://github.com/certd/certd/compare/v1.41.3...v1.41.4) (2026-06-14)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-k8s
|
||||||
|
|
||||||
|
## [1.41.3](https://github.com/certd/certd/compare/v1.41.2...v1.41.3) (2026-06-11)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-k8s
|
||||||
|
|
||||||
|
## [1.41.2](https://github.com/certd/certd/compare/v1.41.1...v1.41.2) (2026-06-10)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-k8s
|
||||||
|
|
||||||
|
## [1.41.1](https://github.com/certd/certd/compare/v1.41.0...v1.41.1) (2026-06-05)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-k8s
|
||||||
|
|
||||||
# [1.41.0](https://github.com/certd/certd/compare/v1.40.5...v1.41.0) (2026-06-04)
|
# [1.41.0](https://github.com/certd/certd/compare/v1.40.5...v1.41.0) (2026-06-04)
|
||||||
|
|
||||||
**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.41.0",
|
"version": "1.41.4",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"module": "./dist/index.js",
|
"module": "./dist/index.js",
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
"compile": "tsc --skipLibCheck --watch"
|
"compile": "tsc --skipLibCheck --watch"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@certd/basic": "^1.41.0",
|
"@certd/basic": "^1.41.4",
|
||||||
"@kubernetes/client-node": "0.21.0"
|
"@kubernetes/client-node": "0.21.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -36,5 +36,5 @@
|
|||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "7ceb0f6306b8b5e9ab875b9f7c41cc7d56209ea4"
|
"gitHead": "bc731e4fb119787930e816a7d57c808b1b5cd66a"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,24 @@
|
|||||||
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.41.4](https://github.com/certd/certd/compare/v1.41.3...v1.41.4) (2026-06-14)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-server
|
||||||
|
|
||||||
|
## [1.41.3](https://github.com/certd/certd/compare/v1.41.2...v1.41.3) (2026-06-11)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-server
|
||||||
|
|
||||||
|
## [1.41.2](https://github.com/certd/certd/compare/v1.41.1...v1.41.2) (2026-06-10)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/lib-server
|
||||||
|
|
||||||
|
## [1.41.1](https://github.com/certd/certd/compare/v1.41.0...v1.41.1) (2026-06-05)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* **settings:** 新增NO_PROXY代理排除配置 ([c0df8be](https://github.com/certd/certd/commit/c0df8be83237e323c2c9a5bd02507430a86a00cc))
|
||||||
|
|
||||||
# [1.41.0](https://github.com/certd/certd/compare/v1.40.5...v1.41.0) (2026-06-04)
|
# [1.41.0](https://github.com/certd/certd/compare/v1.40.5...v1.41.0) (2026-06-04)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/lib-server",
|
"name": "@certd/lib-server",
|
||||||
"version": "1.41.0",
|
"version": "1.41.4",
|
||||||
"description": "midway with flyway, sql upgrade way ",
|
"description": "midway with flyway, sql upgrade way ",
|
||||||
"private": false,
|
"private": false,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -29,11 +29,11 @@
|
|||||||
],
|
],
|
||||||
"license": "AGPL",
|
"license": "AGPL",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@certd/acme-client": "^1.41.0",
|
"@certd/acme-client": "^1.41.4",
|
||||||
"@certd/basic": "^1.41.0",
|
"@certd/basic": "^1.41.4",
|
||||||
"@certd/pipeline": "^1.41.0",
|
"@certd/pipeline": "^1.41.4",
|
||||||
"@certd/plugin-lib": "^1.41.0",
|
"@certd/plugin-lib": "^1.41.4",
|
||||||
"@certd/plus-core": "^1.41.0",
|
"@certd/plus-core": "^1.41.4",
|
||||||
"@midwayjs/cache": "3.14.0",
|
"@midwayjs/cache": "3.14.0",
|
||||||
"@midwayjs/core": "3.20.11",
|
"@midwayjs/core": "3.20.11",
|
||||||
"@midwayjs/i18n": "3.20.13",
|
"@midwayjs/i18n": "3.20.13",
|
||||||
@@ -69,5 +69,5 @@
|
|||||||
"typeorm": "^0.3.11",
|
"typeorm": "^0.3.11",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "7ceb0f6306b8b5e9ab875b9f7c41cc7d56209ea4"
|
"gitHead": "bc731e4fb119787930e816a7d57c808b1b5cd66a"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ export class SysPrivateSettings extends BaseSettings {
|
|||||||
|
|
||||||
httpsProxy? = '';
|
httpsProxy? = '';
|
||||||
httpProxy? = '';
|
httpProxy? = '';
|
||||||
|
noProxy? = '';
|
||||||
commonHeaders?: string = '';
|
commonHeaders?: string = '';
|
||||||
|
|
||||||
reverseProxies?: Record<string, string> = {};
|
reverseProxies?: Record<string, string> = {};
|
||||||
|
|||||||
@@ -165,13 +165,12 @@ export class SysSettingsService extends BaseService<SysSettingsEntity> {
|
|||||||
const opts = {
|
const opts = {
|
||||||
httpProxy: privateSetting.httpProxy,
|
httpProxy: privateSetting.httpProxy,
|
||||||
httpsProxy: privateSetting.httpsProxy,
|
httpsProxy: privateSetting.httpsProxy,
|
||||||
|
noProxy: privateSetting.noProxy,
|
||||||
};
|
};
|
||||||
setGlobalProxy(opts);
|
setGlobalProxy(opts);
|
||||||
setGlobalHeaders(this.parseKeyValueText(privateSetting.commonHeaders));
|
setGlobalHeaders(this.parseKeyValueText(privateSetting.commonHeaders));
|
||||||
|
|
||||||
if (privateSetting.dnsResultOrder) {
|
dns.setDefaultResultOrder(privateSetting.dnsResultOrder as any || 'ipv4first');
|
||||||
dns.setDefaultResultOrder(privateSetting.dnsResultOrder as any);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (privateSetting.pipelineMaxRunningCount) {
|
if (privateSetting.pipelineMaxRunningCount) {
|
||||||
executorQueue.setMaxRunningCount(privateSetting.pipelineMaxRunningCount);
|
executorQueue.setMaxRunningCount(privateSetting.pipelineMaxRunningCount);
|
||||||
|
|||||||
@@ -3,6 +3,24 @@
|
|||||||
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.41.4](https://github.com/certd/certd/compare/v1.41.3...v1.41.4) (2026-06-14)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复设置里面不显示tab页签,导致某些页面需要点击查询按钮才有数据出来的bug ([c1b5a35](https://github.com/certd/certd/commit/c1b5a35f90a7d4b41397717b5c27905bc68e1bfb))
|
||||||
|
|
||||||
|
## [1.41.3](https://github.com/certd/certd/compare/v1.41.2...v1.41.3) (2026-06-11)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||||
|
|
||||||
|
## [1.41.2](https://github.com/certd/certd/compare/v1.41.1...v1.41.2) (2026-06-10)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||||
|
|
||||||
|
## [1.41.1](https://github.com/certd/certd/compare/v1.41.0...v1.41.1) (2026-06-05)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||||
|
|
||||||
# [1.41.0](https://github.com/certd/certd/compare/v1.40.5...v1.41.0) (2026-06-04)
|
# [1.41.0](https://github.com/certd/certd/compare/v1.40.5...v1.41.0) (2026-06-04)
|
||||||
|
|
||||||
**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.41.0",
|
"version": "1.41.4",
|
||||||
"description": "midway with flyway, sql upgrade way ",
|
"description": "midway with flyway, sql upgrade way ",
|
||||||
"private": false,
|
"private": false,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -16,7 +16,8 @@
|
|||||||
"test:unit": "cross-env NODE_ENV=unittest echo no unit tests",
|
"test:unit": "cross-env NODE_ENV=unittest echo no unit tests",
|
||||||
"cov": "midway-bin cov --ts",
|
"cov": "midway-bin cov --ts",
|
||||||
"prepublish": "npm run build",
|
"prepublish": "npm run build",
|
||||||
"pub": "npm publish"
|
"pub": "npm publish",
|
||||||
|
"compile": "npm run build"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "greper",
|
"author": "greper",
|
||||||
@@ -49,5 +50,5 @@
|
|||||||
"typeorm": "^0.3.11",
|
"typeorm": "^0.3.11",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "7ceb0f6306b8b5e9ab875b9f7c41cc7d56209ea4"
|
"gitHead": "bc731e4fb119787930e816a7d57c808b1b5cd66a"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,22 @@
|
|||||||
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.41.4](https://github.com/certd/certd/compare/v1.41.3...v1.41.4) (2026-06-14)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/plugin-cert
|
||||||
|
|
||||||
|
## [1.41.3](https://github.com/certd/certd/compare/v1.41.2...v1.41.3) (2026-06-11)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/plugin-cert
|
||||||
|
|
||||||
|
## [1.41.2](https://github.com/certd/certd/compare/v1.41.1...v1.41.2) (2026-06-10)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/plugin-cert
|
||||||
|
|
||||||
|
## [1.41.1](https://github.com/certd/certd/compare/v1.41.0...v1.41.1) (2026-06-05)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/plugin-cert
|
||||||
|
|
||||||
# [1.41.0](https://github.com/certd/certd/compare/v1.40.5...v1.41.0) (2026-06-04)
|
# [1.41.0](https://github.com/certd/certd/compare/v1.40.5...v1.41.0) (2026-06-04)
|
||||||
|
|
||||||
**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.41.0",
|
"version": "1.41.4",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"types": "./dist/index.d.ts",
|
"types": "./dist/index.d.ts",
|
||||||
@@ -18,10 +18,10 @@
|
|||||||
"compile": "tsc --skipLibCheck --watch"
|
"compile": "tsc --skipLibCheck --watch"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@certd/acme-client": "^1.41.0",
|
"@certd/acme-client": "^1.41.4",
|
||||||
"@certd/basic": "^1.41.0",
|
"@certd/basic": "^1.41.4",
|
||||||
"@certd/pipeline": "^1.41.0",
|
"@certd/pipeline": "^1.41.4",
|
||||||
"@certd/plugin-lib": "^1.41.0",
|
"@certd/plugin-lib": "^1.41.4",
|
||||||
"psl": "^1.9.0",
|
"psl": "^1.9.0",
|
||||||
"punycode.js": "^2.3.1"
|
"punycode.js": "^2.3.1"
|
||||||
},
|
},
|
||||||
@@ -41,5 +41,5 @@
|
|||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "7ceb0f6306b8b5e9ab875b9f7c41cc7d56209ea4"
|
"gitHead": "bc731e4fb119787930e816a7d57c808b1b5cd66a"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,24 @@
|
|||||||
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.41.4](https://github.com/certd/certd/compare/v1.41.3...v1.41.4) (2026-06-14)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/plugin-lib
|
||||||
|
|
||||||
|
## [1.41.3](https://github.com/certd/certd/compare/v1.41.2...v1.41.3) (2026-06-11)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/plugin-lib
|
||||||
|
|
||||||
|
## [1.41.2](https://github.com/certd/certd/compare/v1.41.1...v1.41.2) (2026-06-10)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 新增站点证书监控从DNS解析记录批量导入功能 ([f9541fa](https://github.com/certd/certd/commit/f9541fab701e01ba57af061da322204c894adfb8))
|
||||||
|
|
||||||
|
## [1.41.1](https://github.com/certd/certd/compare/v1.41.0...v1.41.1) (2026-06-05)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/plugin-lib
|
||||||
|
|
||||||
# [1.41.0](https://github.com/certd/certd/compare/v1.40.5...v1.41.0) (2026-06-04)
|
# [1.41.0](https://github.com/certd/certd/compare/v1.40.5...v1.41.0) (2026-06-04)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/plugin-lib
|
**Note:** Version bump only for package @certd/plugin-lib
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/plugin-lib",
|
"name": "@certd/plugin-lib",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.41.0",
|
"version": "1.41.4",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"types": "./dist/index.d.ts",
|
"types": "./dist/index.d.ts",
|
||||||
@@ -23,10 +23,10 @@
|
|||||||
"@alicloud/pop-core": "^1.7.10",
|
"@alicloud/pop-core": "^1.7.10",
|
||||||
"@alicloud/tea-util": "^1.4.11",
|
"@alicloud/tea-util": "^1.4.11",
|
||||||
"@aws-sdk/client-s3": "^3.964.0",
|
"@aws-sdk/client-s3": "^3.964.0",
|
||||||
"@certd/acme-client": "^1.41.0",
|
"@certd/acme-client": "^1.41.4",
|
||||||
"@certd/basic": "^1.41.0",
|
"@certd/basic": "^1.41.4",
|
||||||
"@certd/pipeline": "^1.41.0",
|
"@certd/pipeline": "^1.41.4",
|
||||||
"@certd/plus-core": "^1.41.0",
|
"@certd/plus-core": "^1.41.4",
|
||||||
"@kubernetes/client-node": "0.21.0",
|
"@kubernetes/client-node": "0.21.0",
|
||||||
"ali-oss": "^6.22.0",
|
"ali-oss": "^6.22.0",
|
||||||
"basic-ftp": "^5.0.5",
|
"basic-ftp": "^5.0.5",
|
||||||
@@ -61,5 +61,5 @@
|
|||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "7ceb0f6306b8b5e9ab875b9f7c41cc7d56209ea4"
|
"gitHead": "bc731e4fb119787930e816a7d57c808b1b5cd66a"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ export class CertConverter {
|
|||||||
if (!fs.existsSync(dir)) {
|
if (!fs.existsSync(dir)) {
|
||||||
fs.mkdirSync(dir, { recursive: true });
|
fs.mkdirSync(dir, { recursive: true });
|
||||||
}
|
}
|
||||||
await this.exec(`keytool -importkeystore -srckeystore ${p12Path} -srcstoretype PKCS12 -srcstorepass "${jksPassword}" -destkeystore ${jksPath} -deststoretype PKCS12 -deststorepass "${jksPassword}" `);
|
await this.exec(`keytool -importkeystore -srckeystore ${p12Path} -srcstoretype PKCS12 -srcstorepass "${jksPassword}" -destkeystore ${jksPath} -deststoretype JKS -deststorepass "${jksPassword}" `);
|
||||||
fs.unlinkSync(p12Path);
|
fs.unlinkSync(p12Path);
|
||||||
|
|
||||||
const fileBuffer = fs.readFileSync(jksPath);
|
const fileBuffer = fs.readFileSync(jksPath);
|
||||||
|
|||||||
@@ -34,6 +34,14 @@ export type DomainRecord = {
|
|||||||
domain: string;
|
domain: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type DnsResolveRecord = {
|
||||||
|
id: string;
|
||||||
|
hostRecord: string;
|
||||||
|
fullRecord: string;
|
||||||
|
type: string;
|
||||||
|
value: string;
|
||||||
|
};
|
||||||
|
|
||||||
export interface IDnsProvider<T = any> {
|
export interface IDnsProvider<T = any> {
|
||||||
onInstance(): Promise<void>;
|
onInstance(): Promise<void>;
|
||||||
|
|
||||||
@@ -59,6 +67,8 @@ export interface IDnsProvider<T = any> {
|
|||||||
usePunyCode(): boolean;
|
usePunyCode(): boolean;
|
||||||
|
|
||||||
getDomainListPage(pager: PageSearch): Promise<PageRes<DomainRecord>>;
|
getDomainListPage(pager: PageSearch): Promise<PageRes<DomainRecord>>;
|
||||||
|
|
||||||
|
getRecordListPage?(domain: string, pager: PageSearch): Promise<PageRes<DnsResolveRecord>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ISubDomainsGetter {
|
export interface ISubDomainsGetter {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { HttpClient, ILogger } from "@certd/basic";
|
import { HttpClient, ILogger } from "@certd/basic";
|
||||||
import { IAccessService, PageRes, PageSearch } from "@certd/pipeline";
|
import { IAccessService, PageRes, PageSearch } from "@certd/pipeline";
|
||||||
import punycode from "punycode.js";
|
import punycode from "punycode.js";
|
||||||
import { CreateRecordOptions, DnsProviderContext, DnsProviderDefine, DomainRecord, IDnsProvider, RemoveRecordOptions } from "./api.js";
|
import { CreateRecordOptions, DnsProviderContext, DnsProviderDefine, DnsResolveRecord, DomainRecord, IDnsProvider, RemoveRecordOptions } from "./api.js";
|
||||||
import { dnsProviderRegistry } from "./registry.js";
|
import { dnsProviderRegistry } from "./registry.js";
|
||||||
export abstract class AbstractDnsProvider<T = any> implements IDnsProvider<T> {
|
export abstract class AbstractDnsProvider<T = any> implements IDnsProvider<T> {
|
||||||
ctx!: DnsProviderContext;
|
ctx!: DnsProviderContext;
|
||||||
@@ -49,6 +49,10 @@ export abstract class AbstractDnsProvider<T = any> implements IDnsProvider<T> {
|
|||||||
async getDomainListPage(req: PageSearch): Promise<PageRes<DomainRecord>> {
|
async getDomainListPage(req: PageSearch): Promise<PageRes<DomainRecord>> {
|
||||||
throw new Error("Method not implemented.");
|
throw new Error("Method not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getRecordListPage(domain: string, req: PageSearch): Promise<PageRes<DnsResolveRecord>> {
|
||||||
|
throw new Error("Method not implemented.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createDnsProvider(opts: { dnsProviderType: string; context: DnsProviderContext }): Promise<IDnsProvider> {
|
export async function createDnsProvider(opts: { dnsProviderType: string; context: DnsProviderContext }): Promise<IDnsProvider> {
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ EXPOSE 7002
|
|||||||
|
|
||||||
RUN apk add --no-cache openssl
|
RUN apk add --no-cache openssl
|
||||||
RUN apk add --no-cache openjdk8
|
RUN apk add --no-cache openjdk8
|
||||||
RUN apk add --no-cache gcompat
|
# RUN apk add --no-cache gcompat
|
||||||
WORKDIR /app/
|
WORKDIR /app/
|
||||||
COPY --from=builder /workspace/certd-server/ /app/
|
COPY --from=builder /workspace/certd-server/ /app/
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ VITE_APP_PM_ENABLED=true
|
|||||||
VITE_APP_TITLE=Certd
|
VITE_APP_TITLE=Certd
|
||||||
VITE_APP_SLOGAN=让你的证书永不过期
|
VITE_APP_SLOGAN=让你的证书永不过期
|
||||||
VITE_APP_COPYRIGHT_YEAR=2021-2026
|
VITE_APP_COPYRIGHT_YEAR=2021-2026
|
||||||
VITE_APP_COPYRIGHT_NAME=handsfree.work
|
VITE_APP_COPYRIGHT_NAME=handfree.work
|
||||||
VITE_APP_COPYRIGHT_URL=https://certd.handsfree.work
|
VITE_APP_COPYRIGHT_URL=https://certd.handfree.work
|
||||||
VITE_APP_LOGO=static/images/logo/logo.svg
|
VITE_APP_LOGO=static/images/logo/logo.svg
|
||||||
VITE_APP_LOGIN_LOGO=static/images/logo/rect-black.svg
|
VITE_APP_LOGIN_LOGO=static/images/logo/rect-black.svg
|
||||||
VITE_APP_PROJECT_PATH=https://github.com/certd/certd
|
VITE_APP_PROJECT_PATH=https://github.com/certd/certd
|
||||||
|
|||||||
@@ -3,6 +3,37 @@
|
|||||||
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.41.4](https://github.com/certd/certd/compare/v1.41.3...v1.41.4) (2026-06-14)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复设置里面不显示tab页签,导致某些页面需要点击查询按钮才有数据出来的bug ([c1b5a35](https://github.com/certd/certd/commit/c1b5a35f90a7d4b41397717b5c27905bc68e1bfb))
|
||||||
|
|
||||||
|
## [1.41.3](https://github.com/certd/certd/compare/v1.41.2...v1.41.3) (2026-06-11)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 首页夜间模式主图切换为黑色背景 ([15484bc](https://github.com/certd/certd/commit/15484bc119fef7a0ca7f3fdab01d665fde47e688))
|
||||||
|
|
||||||
|
## [1.41.2](https://github.com/certd/certd/compare/v1.41.1...v1.41.2) (2026-06-10)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **cert-plugin:** 修复DNS提供商授权无法回显的bug ([016ae86](https://github.com/certd/certd/commit/016ae865b1d914fe5792e77a08e3ab5358df5f89))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 新增站点证书监控从DNS解析记录批量导入功能 ([f9541fa](https://github.com/certd/certd/commit/f9541fab701e01ba57af061da322204c894adfb8))
|
||||||
|
|
||||||
|
## [1.41.1](https://github.com/certd/certd/compare/v1.41.0...v1.41.1) (2026-06-05)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 流水线、监控站点支持导出 ([99fd308](https://github.com/certd/certd/commit/99fd3083f259cdb96fd656f04858dd708d1251c7))
|
||||||
|
* 优化列表页面请求两次的问题 ([5546af5](https://github.com/certd/certd/commit/5546af518e92c765513787ccaf8e856be789bcf9))
|
||||||
|
* 优化邀请注册流程 ([7a71e45](https://github.com/certd/certd/commit/7a71e45799d782d0691606fb42b4236f1d3009b0))
|
||||||
|
* **settings:** 新增NO_PROXY代理排除配置 ([c0df8be](https://github.com/certd/certd/commit/c0df8be83237e323c2c9a5bd02507430a86a00cc))
|
||||||
|
|
||||||
# [1.41.0](https://github.com/certd/certd/compare/v1.40.5...v1.41.0) (2026-06-04)
|
# [1.41.0](https://github.com/certd/certd/compare/v1.40.5...v1.41.0) (2026-06-04)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/ui-client",
|
"name": "@certd/ui-client",
|
||||||
"version": "1.41.0",
|
"version": "1.41.4",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite --open",
|
"dev": "vite --open",
|
||||||
@@ -106,8 +106,8 @@
|
|||||||
"zod-defaults": "^0.1.3"
|
"zod-defaults": "^0.1.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@certd/lib-iframe": "^1.41.0",
|
"@certd/lib-iframe": "^1.41.4",
|
||||||
"@certd/pipeline": "^1.41.0",
|
"@certd/pipeline": "^1.41.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",
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 MiB |
+7
-3
@@ -14,7 +14,7 @@ export default {
|
|||||||
default: undefined,
|
default: undefined,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
emits: ["update:modelValue", "selected-change"],
|
emits: ["update:modelValue", "selected-change", "change"],
|
||||||
setup(props: any, ctx: any) {
|
setup(props: any, ctx: any) {
|
||||||
const options = ref<any[]>([]);
|
const options = ref<any[]>([]);
|
||||||
|
|
||||||
@@ -33,7 +33,8 @@ export default {
|
|||||||
// if (props.modelValue == null && options.value.length > 0) {
|
// if (props.modelValue == null && options.value.length > 0) {
|
||||||
// ctx.emit("update:modelValue", options.value[0].value);
|
// ctx.emit("update:modelValue", options.value[0].value);
|
||||||
// }
|
// }
|
||||||
onSelectedChange(props.modelValue);
|
//这里需要一个第一次的selected-change事件,外部表单字段有情况会用到选中的option
|
||||||
|
onSelectedChange(props.modelValue, true);
|
||||||
}
|
}
|
||||||
onCreate();
|
onCreate();
|
||||||
|
|
||||||
@@ -41,9 +42,12 @@ export default {
|
|||||||
ctx.emit("update:modelValue", value);
|
ctx.emit("update:modelValue", value);
|
||||||
onSelectedChange(value);
|
onSelectedChange(value);
|
||||||
}
|
}
|
||||||
function onSelectedChange(value: any) {
|
function onSelectedChange(value: any, isFirst: boolean = false) {
|
||||||
if (value) {
|
if (value) {
|
||||||
const option = options.value.find(item => item.value == value);
|
const option = options.value.find(item => item.value == value);
|
||||||
|
if (!isFirst) {
|
||||||
|
ctx.emit("change", value);
|
||||||
|
}
|
||||||
if (option) {
|
if (option) {
|
||||||
ctx.emit("selected-change", option);
|
ctx.emit("selected-change", option);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ export default {
|
|||||||
subdomainConfirmTitle: "Subdomain Confirmation",
|
subdomainConfirmTitle: "Subdomain Confirmation",
|
||||||
subdomainConfirmContent: "{domain} appears to be a subdomain. Only delegated subdomains and free second-level subdomains need to be maintained here. Otherwise certificate application may fail. Continue?",
|
subdomainConfirmContent: "{domain} appears to be a subdomain. Only delegated subdomains and free second-level subdomains need to be maintained here. Otherwise certificate application may fail. Continue?",
|
||||||
importFromProvider: "Import from Domain Provider",
|
importFromProvider: "Import from Domain Provider",
|
||||||
|
importFromResolveRecords: "Import from DNS Records",
|
||||||
syncExpirationDate: "Sync Domain Expiration Time",
|
syncExpirationDate: "Sync Domain Expiration Time",
|
||||||
syncTaskSubmitted: "Sync task submitted",
|
syncTaskSubmitted: "Sync task submitted",
|
||||||
syncExpirationProgress: "Sync Domain Expiration Progress",
|
syncExpirationProgress: "Sync Domain Expiration Progress",
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ export default {
|
|||||||
pipelineContent: "Pipeline Content",
|
pipelineContent: "Pipeline Content",
|
||||||
scheduledTaskCount: "Scheduled Task Count",
|
scheduledTaskCount: "Scheduled Task Count",
|
||||||
deployTaskCount: "Deployment Task Count",
|
deployTaskCount: "Deployment Task Count",
|
||||||
|
certDomains: "Certificate Domains",
|
||||||
remainingValidity: "Remaining Validity",
|
remainingValidity: "Remaining Validity",
|
||||||
effectiveTime: "Effective time",
|
effectiveTime: "Effective time",
|
||||||
expiryTime: "Expiry Time",
|
expiryTime: "Expiry Time",
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ export default {
|
|||||||
pi: {
|
pi: {
|
||||||
validTime: "Piepline Valid Time",
|
validTime: "Piepline Valid Time",
|
||||||
validTimeHelper: "Not filled in means permanent validity",
|
validTimeHelper: "Not filled in means permanent validity",
|
||||||
|
permanentValid: "Permanent",
|
||||||
},
|
},
|
||||||
types: {
|
types: {
|
||||||
certApply: "Cert Apply",
|
certApply: "Cert Apply",
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ export default {
|
|||||||
"The domain name configured here serves as a proxy for verifying other domains. When other domains apply for certificates, they map to this domain via CNAME for ownership verification. The advantage is that any domain can apply for a certificate this way without providing an AccessSecret.",
|
"The domain name configured here serves as a proxy for verifying other domains. When other domains apply for certificates, they map to this domain via CNAME for ownership verification. The advantage is that any domain can apply for a certificate this way without providing an AccessSecret.",
|
||||||
cnameLinkText: "CNAME principle and usage instructions",
|
cnameLinkText: "CNAME principle and usage instructions",
|
||||||
cnameDomain: "CNAME Domain",
|
cnameDomain: "CNAME Domain",
|
||||||
cnameDomainPlaceholder: "cname.handsfree.work",
|
cnameDomainPlaceholder: "cname.handfree.work",
|
||||||
cnameDomainHelper:
|
cnameDomainHelper:
|
||||||
"Requires a domain registered with a DNS provider on the right (or you can transfer other domain DNS servers here).\nOnce the CNAME domain is set, it cannot be changed. It is recommended to use a first-level subdomain.",
|
"Requires a domain registered with a DNS provider on the right (or you can transfer other domain DNS servers here).\nOnce the CNAME domain is set, it cannot be changed. It is recommended to use a first-level subdomain.",
|
||||||
cnameDomainPattern: "Domain name cannot contain *",
|
cnameDomainPattern: "Domain name cannot contain *",
|
||||||
|
|||||||
@@ -111,6 +111,9 @@ export default {
|
|||||||
httpsProxyPlaceholder: "http://192.168.1.2:18010/",
|
httpsProxyPlaceholder: "http://192.168.1.2:18010/",
|
||||||
saveThenTestTitle: "Save first, then click test",
|
saveThenTestTitle: "Save first, then click test",
|
||||||
httpsProxyHelper: "Usually both proxies are the same, save first then test",
|
httpsProxyHelper: "Usually both proxies are the same, save first then test",
|
||||||
|
noProxy: "Proxy Bypass",
|
||||||
|
noProxyPlaceholder: "localhost,127.0.0.1,.example.com,192.168.*",
|
||||||
|
noProxyHelper: "Configure NO_PROXY. Separate entries with commas, spaces, or line breaks; matched requests bypass the proxy. \nExample: localhost,127.0.0.1,.example.com,192.168.*",
|
||||||
dualStackNetwork: "Dual Stack Network",
|
dualStackNetwork: "Dual Stack Network",
|
||||||
ipv4Priority: "IPv4 Priority",
|
ipv4Priority: "IPv4 Priority",
|
||||||
ipv6Priority: "IPv6 Priority",
|
ipv6Priority: "IPv6 Priority",
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ export default {
|
|||||||
subdomainConfirmTitle: "子域名确认",
|
subdomainConfirmTitle: "子域名确认",
|
||||||
subdomainConfirmContent: "检测到{domain}为子域名,只有托管子域名和免费二级子域名才需要在此处维护,否则会导致申请证书失败,请确认是否继续?",
|
subdomainConfirmContent: "检测到{domain}为子域名,只有托管子域名和免费二级子域名才需要在此处维护,否则会导致申请证书失败,请确认是否继续?",
|
||||||
importFromProvider: "从域名提供商导入",
|
importFromProvider: "从域名提供商导入",
|
||||||
|
importFromResolveRecords: "从解析记录导入",
|
||||||
syncExpirationDate: "同步域名过期时间",
|
syncExpirationDate: "同步域名过期时间",
|
||||||
syncTaskSubmitted: "同步任务已提交",
|
syncTaskSubmitted: "同步任务已提交",
|
||||||
syncExpirationProgress: "同步域名过期时间进度",
|
syncExpirationProgress: "同步域名过期时间进度",
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ export default {
|
|||||||
pipelineContent: "流水线内容",
|
pipelineContent: "流水线内容",
|
||||||
scheduledTaskCount: "定时任务数",
|
scheduledTaskCount: "定时任务数",
|
||||||
deployTaskCount: "部署任务数",
|
deployTaskCount: "部署任务数",
|
||||||
|
certDomains: "证书域名",
|
||||||
remainingValidity: "到期剩余",
|
remainingValidity: "到期剩余",
|
||||||
effectiveTime: "生效时间",
|
effectiveTime: "生效时间",
|
||||||
expiryTime: "过期时间",
|
expiryTime: "过期时间",
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ export default {
|
|||||||
pi: {
|
pi: {
|
||||||
validTime: "流水线有效期",
|
validTime: "流水线有效期",
|
||||||
validTimeHelper: "不填则为永久有效",
|
validTimeHelper: "不填则为永久有效",
|
||||||
|
permanentValid: "永久有效",
|
||||||
},
|
},
|
||||||
types: {
|
types: {
|
||||||
certApply: "证书申请",
|
certApply: "证书申请",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ export default {
|
|||||||
cnameDescription: "此处配置的域名作为其他域名校验的代理,当别的域名需要申请证书时,通过CNAME映射到此域名上来验证所有权。好处是任何域名都可以通过此方式申请证书,也无需填写AccessSecret。",
|
cnameDescription: "此处配置的域名作为其他域名校验的代理,当别的域名需要申请证书时,通过CNAME映射到此域名上来验证所有权。好处是任何域名都可以通过此方式申请证书,也无需填写AccessSecret。",
|
||||||
cnameLinkText: "CNAME功能原理及使用说明",
|
cnameLinkText: "CNAME功能原理及使用说明",
|
||||||
cnameDomain: "CNAME域名",
|
cnameDomain: "CNAME域名",
|
||||||
cnameDomainPlaceholder: "cname.handsfree.work",
|
cnameDomainPlaceholder: "cname.handfree.work",
|
||||||
cnameDomainHelper: "需要一个右边DNS提供商注册的域名(也可以将其他域名的dns服务器转移到这几家来)。\nCNAME域名一旦确定不可修改,建议使用一级子域名",
|
cnameDomainHelper: "需要一个右边DNS提供商注册的域名(也可以将其他域名的dns服务器转移到这几家来)。\nCNAME域名一旦确定不可修改,建议使用一级子域名",
|
||||||
cnameDomainPattern: "域名不能使用星号",
|
cnameDomainPattern: "域名不能使用星号",
|
||||||
cnameProviderSubdomain: "托管子域名",
|
cnameProviderSubdomain: "托管子域名",
|
||||||
|
|||||||
@@ -108,6 +108,9 @@ export default {
|
|||||||
httpsProxyPlaceholder: "http://192.168.1.2:18010/",
|
httpsProxyPlaceholder: "http://192.168.1.2:18010/",
|
||||||
saveThenTestTitle: "保存后,再点击测试",
|
saveThenTestTitle: "保存后,再点击测试",
|
||||||
httpsProxyHelper: "一般这两个代理填一样的,保存后再测试",
|
httpsProxyHelper: "一般这两个代理填一样的,保存后再测试",
|
||||||
|
noProxy: "代理排除",
|
||||||
|
noProxyPlaceholder: "localhost,127.0.0.1,.example.com,192.168.*",
|
||||||
|
noProxyHelper: "配置NO_PROXY,多个地址可用英文逗号、空格或换行分隔,命中的请求将不走代理\n例如:localhost,127.0.0.1,.example.com,192.168.*",
|
||||||
dualStackNetwork: "双栈网络",
|
dualStackNetwork: "双栈网络",
|
||||||
ipv4Priority: "IPV4优先",
|
ipv4Priority: "IPV4优先",
|
||||||
ipv6Priority: "IPV6优先",
|
ipv6Priority: "IPV6优先",
|
||||||
|
|||||||
@@ -107,6 +107,9 @@ function install(app: App, options: any = {}) {
|
|||||||
scroll: {
|
scroll: {
|
||||||
x: 960,
|
x: 960,
|
||||||
},
|
},
|
||||||
|
rowSelection: {
|
||||||
|
fixed: "left",
|
||||||
|
},
|
||||||
size: "small",
|
size: "small",
|
||||||
pagination: false,
|
pagination: false,
|
||||||
onResizeColumn: (w: number, col: any) => {
|
onResizeColumn: (w: number, col: any) => {
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ export const certdResources = [
|
|||||||
isMenu: true,
|
isMenu: true,
|
||||||
icon: "ion:duplicate-outline",
|
icon: "ion:duplicate-outline",
|
||||||
auth: true,
|
auth: true,
|
||||||
|
keepAlive: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -282,6 +283,7 @@ export const certdResources = [
|
|||||||
meta: {
|
meta: {
|
||||||
icon: "ion:barcode-outline",
|
icon: "ion:barcode-outline",
|
||||||
auth: true,
|
auth: true,
|
||||||
|
keepAlive: true,
|
||||||
isMenu: true,
|
isMenu: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -350,6 +352,7 @@ export const certdResources = [
|
|||||||
},
|
},
|
||||||
icon: "ion:gift-outline",
|
icon: "ion:gift-outline",
|
||||||
auth: true,
|
auth: true,
|
||||||
|
keepAlive: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -389,7 +392,7 @@ export const certdResources = [
|
|||||||
meta: {
|
meta: {
|
||||||
show: () => {
|
show: () => {
|
||||||
const settingStore = useSettingStore();
|
const settingStore = useSettingStore();
|
||||||
return settingStore.isComm;
|
return settingStore.isInviteCommissionEnabled;
|
||||||
},
|
},
|
||||||
icon: "ion:gift-outline",
|
icon: "ion:gift-outline",
|
||||||
auth: true,
|
auth: true,
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ export const sysResources = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "certd.sysResources.headerMenus",
|
title: "certd.sysResources.headerMenus",
|
||||||
name: "HeaderMenus",
|
name: "SettingsHeaderMenus",
|
||||||
path: "/sys/settings/header-menus",
|
path: "/sys/settings/header-menus",
|
||||||
component: "/sys/settings/header-menus/index.vue",
|
component: "/sys/settings/header-menus/index.vue",
|
||||||
meta: {
|
meta: {
|
||||||
@@ -128,7 +128,7 @@ export const sysResources = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "certd.sysResources.sysAccess",
|
title: "certd.sysResources.sysAccess",
|
||||||
name: "SysAccess",
|
name: "SysAccessManager",
|
||||||
path: "/sys/access",
|
path: "/sys/access",
|
||||||
component: "/sys/access/index.vue",
|
component: "/sys/access/index.vue",
|
||||||
meta: {
|
meta: {
|
||||||
@@ -311,7 +311,7 @@ export const sysResources = [
|
|||||||
},
|
},
|
||||||
icon: "ion:bag-check",
|
icon: "ion:bag-check",
|
||||||
permission: "sys:settings:edit",
|
permission: "sys:settings:edit",
|
||||||
keepAlive: true,
|
keepAlive: false,
|
||||||
auth: true,
|
auth: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -105,6 +105,7 @@ export type InviteSetting = {
|
|||||||
export type SysPrivateSetting = {
|
export type SysPrivateSetting = {
|
||||||
httpProxy?: string;
|
httpProxy?: string;
|
||||||
httpsProxy?: string;
|
httpsProxy?: string;
|
||||||
|
noProxy?: string;
|
||||||
commonHeaders?: string;
|
commonHeaders?: string;
|
||||||
reverseProxies?: any;
|
reverseProxies?: any;
|
||||||
dnsResultOrder?: string;
|
dnsResultOrder?: string;
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import { resetAllStores, useAccessStore } from "/@/vben/stores";
|
|||||||
|
|
||||||
import { useUserStore as vbenUserStore } from "/@/vben/stores/modules/user";
|
import { useUserStore as vbenUserStore } from "/@/vben/stores/modules/user";
|
||||||
import { request } from "/@/api/service";
|
import { request } from "/@/api/service";
|
||||||
|
import { inviteUtils } from "/@/utils/util.invite";
|
||||||
|
|
||||||
interface UserState {
|
interface UserState {
|
||||||
userInfo: Nullable<UserInfoRes>;
|
userInfo: Nullable<UserInfoRes>;
|
||||||
@@ -66,6 +67,9 @@ export const useUserStore = defineStore({
|
|||||||
},
|
},
|
||||||
async register(user: RegisterReq) {
|
async register(user: RegisterReq) {
|
||||||
await UserApi.register(user);
|
await UserApi.register(user);
|
||||||
|
if (user.inviteCode) {
|
||||||
|
inviteUtils.clear();
|
||||||
|
}
|
||||||
notification.success({
|
notification.success({
|
||||||
message: "注册成功,请登录",
|
message: "注册成功,请登录",
|
||||||
});
|
});
|
||||||
@@ -85,6 +89,9 @@ export const useUserStore = defineStore({
|
|||||||
let loginRes: any = null;
|
let loginRes: any = null;
|
||||||
if (loginType === "sms") {
|
if (loginType === "sms") {
|
||||||
loginRes = await UserApi.loginBySms(params as SmsLoginReq);
|
loginRes = await UserApi.loginBySms(params as SmsLoginReq);
|
||||||
|
if ((params as SmsLoginReq).inviteCode) {
|
||||||
|
inviteUtils.clear();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
loginRes = await UserApi.login(params as LoginReq);
|
loginRes = await UserApi.login(params as LoginReq);
|
||||||
}
|
}
|
||||||
@@ -136,12 +143,12 @@ export const useUserStore = defineStore({
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("注销登录请求失败:", e);
|
console.error("注销登录请求失败:", e);
|
||||||
}
|
}
|
||||||
|
// 第三方登录注销
|
||||||
|
this.oauthLogout();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.resetState();
|
this.resetState();
|
||||||
resetAllStores();
|
resetAllStores();
|
||||||
// 第三方登录注销
|
|
||||||
await this.oauthLogout();
|
|
||||||
goLogin && router.push("/login");
|
goLogin && router.push("/login");
|
||||||
mitter.emit("app.logout");
|
mitter.emit("app.logout");
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -8,4 +8,45 @@
|
|||||||
.vben-normal-menu__item.is-active {
|
.vben-normal-menu__item.is-active {
|
||||||
background-color: #3b3b3b !important;
|
background-color: #3b3b3b !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cd-table {
|
||||||
|
th,
|
||||||
|
td {
|
||||||
|
border-bottom: 1px solid #303030;
|
||||||
|
border-left: 1px solid #303030;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
background: #1f1f1f;
|
||||||
|
color: rgba(255, 255, 255, 0.85);
|
||||||
|
border-top: 1px solid #303030;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-right: 1px solid #303030;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
&:last-child {
|
||||||
|
border-right: 1px solid #303030;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
td.position-sticky-right {
|
||||||
|
background-color: #141414;
|
||||||
|
}
|
||||||
|
|
||||||
|
.position-sticky-right::before {
|
||||||
|
background: #303030;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr.hover-color:hover td {
|
||||||
|
background: #262626;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-active {
|
||||||
|
background: #1f3a23;
|
||||||
|
color: #81c784;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import { onActivated, onMounted } from "vue";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 可靠的页面刷新钩子:
|
||||||
|
* - 如果组件实际被 KeepAlive 缓存命中,由 onActivated 触发 init;
|
||||||
|
* - 如果没有被缓存,由 onMounted 兜底触发,避免不刷新也不触发 onActivated。
|
||||||
|
*/
|
||||||
|
export function useMounted(init: () => void | Promise<void>) {
|
||||||
|
let activated = false;
|
||||||
|
|
||||||
|
onActivated(() => {
|
||||||
|
activated = true;
|
||||||
|
init();
|
||||||
|
});
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 让 onActivated 有机会先执行;组件未被 KeepAlive 缓存时 onActivated 不会触发,由这里兜底。
|
||||||
|
setTimeout(() => {
|
||||||
|
if (!activated) {
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -41,6 +41,10 @@ export const inviteUtils = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
localStorage.removeItem(INVITE_STORAGE_KEY);
|
||||||
|
},
|
||||||
|
|
||||||
captureFromLocation() {
|
captureFromLocation() {
|
||||||
const hashQuery = window.location.hash?.split("?")[1] || "";
|
const hashQuery = window.location.hash?.split("?")[1] || "";
|
||||||
const search = window.location.search?.replace(/^\?/, "") || "";
|
const search = window.location.search?.replace(/^\?/, "") || "";
|
||||||
|
|||||||
@@ -11,7 +11,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, onActivated, onMounted } from "vue";
|
import { defineComponent } from "vue";
|
||||||
|
import { useMounted } from "/@/use/use-mounted";
|
||||||
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";
|
import { createAccessApi } from "/@/views/certd/access/api";
|
||||||
@@ -23,14 +24,7 @@ export default defineComponent({
|
|||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const api = createAccessApi("user");
|
const api = createAccessApi("user");
|
||||||
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: { api, permission: { isProjectPermission: true } } });
|
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: { api, permission: { isProjectPermission: true } } });
|
||||||
|
useMounted(() => crudExpose.doRefresh());
|
||||||
// 页面打开后获取列表数据
|
|
||||||
onMounted(() => {
|
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
onActivated(() => {
|
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
crudBinding,
|
crudBinding,
|
||||||
|
|||||||
@@ -11,7 +11,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, onActivated, onMounted } from "vue";
|
import { defineComponent } from "vue";
|
||||||
|
import { useMounted } from "/@/use/use-mounted";
|
||||||
import { useFs } from "@fast-crud/fast-crud";
|
import { useFs } from "@fast-crud/fast-crud";
|
||||||
import createCrudOptions from "./crud";
|
import createCrudOptions from "./crud";
|
||||||
import { createAddonApi } from "./api";
|
import { createAddonApi } from "./api";
|
||||||
@@ -26,14 +27,7 @@ export default defineComponent({
|
|||||||
createCrudOptions,
|
createCrudOptions,
|
||||||
context: { api, permission: { isProjectPermission: true } },
|
context: { api, permission: { isProjectPermission: true } },
|
||||||
});
|
});
|
||||||
|
useMounted(() => crudExpose.doRefresh());
|
||||||
// 页面打开后获取列表数据
|
|
||||||
onMounted(() => {
|
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
onActivated(() => {
|
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
crudBinding,
|
crudBinding,
|
||||||
|
|||||||
@@ -11,7 +11,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, onActivated, onMounted } from "vue";
|
import { defineComponent } from "vue";
|
||||||
|
import { useMounted } from "/@/use/use-mounted";
|
||||||
import { useFs } from "@fast-crud/fast-crud";
|
import { useFs } from "@fast-crud/fast-crud";
|
||||||
import createCrudOptions from "./crud";
|
import createCrudOptions from "./crud";
|
||||||
|
|
||||||
@@ -24,14 +25,7 @@ export default defineComponent({
|
|||||||
permission: { isProjectPermission: true },
|
permission: { isProjectPermission: true },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
useMounted(() => crudExpose.doRefresh());
|
||||||
// 页面打开后获取列表数据
|
|
||||||
onMounted(() => {
|
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
onActivated(() => {
|
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
crudBinding,
|
crudBinding,
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
|
|||||||
},
|
},
|
||||||
rowHandle: {
|
rowHandle: {
|
||||||
fixed: "right",
|
fixed: "right",
|
||||||
width: 120,
|
width: 200,
|
||||||
buttons: {
|
buttons: {
|
||||||
edit: {
|
edit: {
|
||||||
click: ({ row }) => openForm(row),
|
click: ({ row }) => openForm(row),
|
||||||
|
|||||||
@@ -11,9 +11,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onActivated, 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 { useMounted } from "/@/use/use-mounted";
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "CertApplyTemplate",
|
name: "CertApplyTemplate",
|
||||||
@@ -25,12 +25,5 @@ const { crudBinding, crudRef, crudExpose } = useFs({
|
|||||||
permission: { isProjectPermission: true },
|
permission: { isProjectPermission: true },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
useMounted(() => crudExpose.doRefresh());
|
||||||
onMounted(() => {
|
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
|
|
||||||
onActivated(() => {
|
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -11,9 +11,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onActivated, 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 { useMounted } from "/@/use/use-mounted";
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "DnsPersistRecord",
|
name: "DnsPersistRecord",
|
||||||
@@ -24,10 +24,8 @@ const context: any = {
|
|||||||
};
|
};
|
||||||
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context });
|
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context });
|
||||||
|
|
||||||
onMounted(() => {
|
// 页面打开后获取列表数据
|
||||||
crudExpose.doRefresh();
|
useMounted(async () => {
|
||||||
});
|
|
||||||
onActivated(async () => {
|
|
||||||
await crudExpose.doRefresh();
|
await crudExpose.doRefresh();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -19,13 +19,14 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onActivated, 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 { message, Modal } from "ant-design-vue";
|
import { message, Modal } from "ant-design-vue";
|
||||||
import { DeleteBatch } from "./api";
|
import { DeleteBatch } from "./api";
|
||||||
import { useI18n } from "/src/locales";
|
import { useI18n } from "/src/locales";
|
||||||
import { useCrudPermission } from "/@/plugin/permission";
|
import { useCrudPermission } from "/@/plugin/permission";
|
||||||
|
import { useMounted } from "/@/use/use-mounted";
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
@@ -61,10 +62,7 @@ const handleBatchDelete = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 页面打开后获取列表数据
|
// 页面打开后获取列表数据
|
||||||
onMounted(() => {
|
useMounted(async () => {
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
onActivated(async () => {
|
|
||||||
await crudExpose.doRefresh();
|
await crudExpose.doRefresh();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -21,13 +21,14 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onActivated, 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 { message, Modal } from "ant-design-vue";
|
import { message, Modal } from "ant-design-vue";
|
||||||
import { DeleteBatch } from "./api";
|
import { DeleteBatch } from "./api";
|
||||||
import { useI18n } from "/src/locales";
|
import { useI18n } from "/src/locales";
|
||||||
import { useCrudPermission } from "/@/plugin/permission";
|
import { useCrudPermission } from "/@/plugin/permission";
|
||||||
|
import { useMounted } from "/@/use/use-mounted";
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
@@ -61,10 +62,7 @@ const handleBatchDelete = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 页面打开后获取列表数据
|
// 页面打开后获取列表数据
|
||||||
onMounted(() => {
|
useMounted(async () => {
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
onActivated(async () => {
|
|
||||||
await crudExpose.doRefresh();
|
await crudExpose.doRefresh();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -14,13 +14,13 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onActivated, onMounted } from "vue";
|
|
||||||
import { useFs } from "@fast-crud/fast-crud";
|
import { useFs } from "@fast-crud/fast-crud";
|
||||||
import createCrudOptions from "./crud";
|
|
||||||
import { message, Modal } from "ant-design-vue";
|
import { message, Modal } from "ant-design-vue";
|
||||||
import { DeleteBatch } from "./api";
|
import { DeleteBatch } from "./api";
|
||||||
import { useI18n } from "/src/locales";
|
import createCrudOptions from "./crud";
|
||||||
import { useCrudPermission } from "/@/plugin/permission";
|
import { useCrudPermission } from "/@/plugin/permission";
|
||||||
|
import { useMounted } from "/@/use/use-mounted";
|
||||||
|
import { useI18n } from "/src/locales";
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
@@ -52,13 +52,6 @@ const handleBatchDelete = () => {
|
|||||||
message.error(t("certd.pleaseSelectRecords"));
|
message.error(t("certd.pleaseSelectRecords"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
useMounted(() => crudExpose.doRefresh());
|
||||||
// 页面打开后获取列表数据
|
|
||||||
onMounted(() => {
|
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
onActivated(() => {
|
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="less"></style>
|
<style lang="less"></style>
|
||||||
|
|||||||
@@ -149,7 +149,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, nextTick, onActivated, onMounted, reactive, ref } from "vue";
|
import { computed, nextTick, reactive, ref } from "vue";
|
||||||
import { FsIcon, useFs } from "@fast-crud/fast-crud";
|
import { FsIcon, useFs } from "@fast-crud/fast-crud";
|
||||||
import { notification } from "ant-design-vue";
|
import { notification } from "ant-design-vue";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
@@ -158,6 +158,7 @@ import createInviteesCrudOptions from "./crud-invitees";
|
|||||||
import createLogsCrudOptions from "./crud-logs";
|
import createLogsCrudOptions from "./crud-logs";
|
||||||
import { useSettingStore } from "/@/store/settings";
|
import { useSettingStore } from "/@/store/settings";
|
||||||
import { util } from "/@/utils";
|
import { util } from "/@/utils";
|
||||||
|
import { useMounted } from "/@/use/use-mounted";
|
||||||
|
|
||||||
defineOptions({ name: "InviteCommission" });
|
defineOptions({ name: "InviteCommission" });
|
||||||
|
|
||||||
@@ -300,7 +301,7 @@ async function handleTabChange() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function refreshInvitePage(autoOpenAgreement = true) {
|
async function refreshInvitePage(autoOpenAgreement = true) {
|
||||||
await settingStore.initOnce();
|
await settingStore.init();
|
||||||
enabled.value = settingStore.isInviteCommissionEnabled;
|
enabled.value = settingStore.isInviteCommissionEnabled;
|
||||||
loaded.value = true;
|
loaded.value = true;
|
||||||
if (!enabled.value) {
|
if (!enabled.value) {
|
||||||
@@ -314,16 +315,10 @@ async function refreshInvitePage(autoOpenAgreement = true) {
|
|||||||
await refreshActiveList();
|
await refreshActiveList();
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
// 页面打开后获取列表数据
|
||||||
|
useMounted(async () => {
|
||||||
await refreshInvitePage(true);
|
await refreshInvitePage(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
onActivated(async () => {
|
|
||||||
if (!loaded.value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await refreshInvitePage();
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
|
|||||||
@@ -11,9 +11,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onActivated, 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 { useMounted } from "/@/use/use-mounted";
|
||||||
import { useI18n } from "/src/locales";
|
import { useI18n } from "/src/locales";
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
@@ -22,12 +22,5 @@ defineOptions({
|
|||||||
name: "CertStore",
|
name: "CertStore",
|
||||||
});
|
});
|
||||||
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: { permission: { isProjectPermission: true } } });
|
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: { permission: { isProjectPermission: true } } });
|
||||||
|
useMounted(() => crudExpose.doRefresh());
|
||||||
// 页面打开后获取列表数据
|
|
||||||
onMounted(() => {
|
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
onActivated(() => {
|
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -22,8 +22,8 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useFs } from "@fast-crud/fast-crud";
|
import { useFs } from "@fast-crud/fast-crud";
|
||||||
import { onActivated, onMounted } from "vue";
|
|
||||||
import createCrudOptions from "./crud";
|
import createCrudOptions from "./crud";
|
||||||
|
import { useMounted } from "/@/use/use-mounted";
|
||||||
import { useI18n } from "/src/locales";
|
import { useI18n } from "/src/locales";
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
defineOptions({
|
defineOptions({
|
||||||
@@ -37,12 +37,5 @@ const context: any = {
|
|||||||
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context });
|
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context });
|
||||||
|
|
||||||
const handleBatchDelete = context.handleBatchDelete;
|
const handleBatchDelete = context.handleBatchDelete;
|
||||||
|
useMounted(() => crudExpose.doRefresh());
|
||||||
// 页面打开后获取列表数据
|
|
||||||
onMounted(() => {
|
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
onActivated(() => {
|
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -72,6 +72,36 @@ export const siteInfoApi = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async ImportTaskSave(body: any) {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/import/save",
|
||||||
|
method: "post",
|
||||||
|
data: body,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
async ImportTaskStatus() {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/import/status",
|
||||||
|
method: "post",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
async ImportTaskDelete(key: string) {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/import/delete",
|
||||||
|
method: "post",
|
||||||
|
data: { key },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
async ImportTaskStart(key: string) {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/import/start",
|
||||||
|
method: "post",
|
||||||
|
data: { key },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async DisabledChange(id: number, disabled: boolean) {
|
async DisabledChange(id: number, disabled: boolean) {
|
||||||
return await request({
|
return await request({
|
||||||
url: apiPrefix + "/disabledChange",
|
url: apiPrefix + "/disabledChange",
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { useSettingStore } from "/@/store/settings";
|
|||||||
import { mySuiteApi } from "/@/views/certd/suite/mine/api";
|
import { mySuiteApi } from "/@/views/certd/suite/mine/api";
|
||||||
import { mitter } from "/@/utils/util.mitt";
|
import { mitter } from "/@/utils/util.mitt";
|
||||||
import { useSiteIpMonitor } from "./ip/use";
|
import { useSiteIpMonitor } from "./ip/use";
|
||||||
import { useSiteImport } from "/@/views/certd/monitor/site/use";
|
import { useSiteImport, useSiteImportTaskManage } from "/@/views/certd/monitor/site/use";
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import GroupSelector from "../../basic/group/group-selector.vue";
|
import GroupSelector from "../../basic/group/group-selector.vue";
|
||||||
import { createGroupDictRef } from "../../basic/group/api";
|
import { createGroupDictRef } from "../../basic/group/api";
|
||||||
@@ -53,6 +53,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
|
|
||||||
const { openSiteIpMonitorDialog } = useSiteIpMonitor();
|
const { openSiteIpMonitorDialog } = useSiteIpMonitor();
|
||||||
const { openSiteImportDialog } = useSiteImport();
|
const { openSiteImportDialog } = useSiteImport();
|
||||||
|
const openSiteImportTaskManageDialog = useSiteImportTaskManage();
|
||||||
|
|
||||||
const certValidDaysRef = ref(10);
|
const certValidDaysRef = ref(10);
|
||||||
|
|
||||||
@@ -200,6 +201,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
actionbar: {
|
actionbar: {
|
||||||
buttons: {
|
buttons: {
|
||||||
add: {
|
add: {
|
||||||
|
icon: "ion:add-circle-outline",
|
||||||
async click() {
|
async click() {
|
||||||
if (!settingsStore.isPlus) {
|
if (!settingsStore.isPlus) {
|
||||||
// 非plus
|
// 非plus
|
||||||
@@ -236,6 +238,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
show: hasActionPermission("write"),
|
show: hasActionPermission("write"),
|
||||||
text: t("monitor.bulkImport"),
|
text: t("monitor.bulkImport"),
|
||||||
type: "primary",
|
type: "primary",
|
||||||
|
icon: "ion:cloud-upload-outline",
|
||||||
async click() {
|
async click() {
|
||||||
const defaultGroupId = getDefaultGroupId();
|
const defaultGroupId = getDefaultGroupId();
|
||||||
openSiteImportDialog({
|
openSiteImportDialog({
|
||||||
@@ -246,10 +249,27 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
importFromProvider: {
|
||||||
|
show: hasActionPermission("write"),
|
||||||
|
title: t("certd.domain.importFromResolveRecords"),
|
||||||
|
text: t("certd.domain.importFromResolveRecords"),
|
||||||
|
type: "primary",
|
||||||
|
needPlus: true,
|
||||||
|
color: "gold",
|
||||||
|
icon: "mingcute:vip-1-line",
|
||||||
|
click: async () => {
|
||||||
|
await openSiteImportTaskManageDialog({
|
||||||
|
afterSubmit: () => {
|
||||||
|
crudExpose.doRefresh();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
checkAll: {
|
checkAll: {
|
||||||
show: true,
|
show: true,
|
||||||
text: t("monitor.checkAll"),
|
text: t("monitor.checkAll"),
|
||||||
type: "primary",
|
type: "primary",
|
||||||
|
icon: "ion:play-circle-outline",
|
||||||
click() {
|
click() {
|
||||||
checkAll();
|
checkAll();
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,139 @@
|
|||||||
|
<template>
|
||||||
|
<div class="site-info-import-task-status min-h-[300px]">
|
||||||
|
<div class="action mb-5">
|
||||||
|
<fs-button type="primary" icon="mingcute:vip-1-line" @click="addTask">{{ t("certd.domain.addImportTask") }}</fs-button>
|
||||||
|
<fs-button type="primary" icon="ion:refresh-outline" class="ml-2" @click="loadImportTaskStatus">{{ t("certd.domain.refresh") }}</fs-button>
|
||||||
|
</div>
|
||||||
|
<div class="table-container overflow-auto mb-10">
|
||||||
|
<table class="cd-table border-gray-300 w-full">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="w-[220px]">{{ t("certd.sourcee") }}</th>
|
||||||
|
<th class="">{{ t("certd.domain.progress") }}</th>
|
||||||
|
<th class="w-[220px]">{{ t("certd.domain.operation") }}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr v-for="item in list" :key="item.key">
|
||||||
|
<td class="ellipsis">
|
||||||
|
<span class="flex items-center pointer" @click="editTask(item)">
|
||||||
|
<span class="flex-1 ellipsis flex items-center">
|
||||||
|
<fs-icon :icon="item.icon" class="mr-2"></fs-icon>
|
||||||
|
{{ item.title }}
|
||||||
|
</span>
|
||||||
|
<fs-icon icon="ant-design:edit-outlined" class="ml-2" />
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div v-if="item.task">
|
||||||
|
<div>
|
||||||
|
<a-tag color="blue">{{ t("certd.domain.total") }}:{{ item.task?.total }}</a-tag>
|
||||||
|
<a-tag color="success" class="ml-2">{{ t("certd.success") }}:{{ item.task?.successCount }}</a-tag>
|
||||||
|
<a-tag type="info" class="ml-2">{{ t("certd.domain.skipped") }}:{{ item.task?.skipCount }}</a-tag>
|
||||||
|
<a-tooltip v-if="item.task?.errors.length > 0">
|
||||||
|
<template #title>
|
||||||
|
<div v-for="error in item.task?.errors" :key="error">{{ error }}</div>
|
||||||
|
</template>
|
||||||
|
<a-tag color="red" class="ml-2">{{ t("certd.domain.failed") }}:{{ item.task?.errors.length }}</a-tag>
|
||||||
|
</a-tooltip>
|
||||||
|
</div>
|
||||||
|
<a-progress :percent="item.task?.progress" size="small" status="active" />
|
||||||
|
</div>
|
||||||
|
<div v-else>{{ t("certd.domain.notExecuted") }}</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<fs-button type="primary" icon="ion:play-outline" :disabled="item.task?.status === 'running'" @click="startTask(item)">{{ t("certd.domain.execute") }}</fs-button>
|
||||||
|
<fs-button type="primary" class="ml-2" danger icon="ion:trash-outline" @click="deleteTask(item)">{{ t("certd.domain.delete") }}</fs-button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { Modal } from "ant-design-vue";
|
||||||
|
import { onMounted, onUnmounted, ref } from "vue";
|
||||||
|
import * as api from "./api";
|
||||||
|
import { useSiteImportTask } from "./use";
|
||||||
|
import { useSettingStore } from "/@/store/settings";
|
||||||
|
import { useI18n } from "/@/locales";
|
||||||
|
defineOptions({
|
||||||
|
name: "SiteInfoImportTaskStatus",
|
||||||
|
});
|
||||||
|
|
||||||
|
const list = ref([]);
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
async function loadImportTaskStatus() {
|
||||||
|
const res = await api.siteInfoApi.ImportTaskStatus();
|
||||||
|
list.value = res || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
async function startTask(item: any) {
|
||||||
|
settingStore.checkPlus();
|
||||||
|
await api.siteInfoApi.ImportTaskStart(item.key);
|
||||||
|
await loadImportTaskStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deleteTask(item: any) {
|
||||||
|
Modal.confirm({
|
||||||
|
title: t("certd.domain.confirmDelete"),
|
||||||
|
okText: t("common.confirm"),
|
||||||
|
okType: "danger",
|
||||||
|
onOk: async () => {
|
||||||
|
await api.siteInfoApi.ImportTaskDelete(item.key);
|
||||||
|
await loadImportTaskStatus();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const openSiteImportTaskDialog = useSiteImportTask();
|
||||||
|
const settingStore = useSettingStore();
|
||||||
|
async function addTask() {
|
||||||
|
settingStore.checkPlus();
|
||||||
|
await openSiteImportTaskDialog({
|
||||||
|
afterSubmit: async (res?: any) => {
|
||||||
|
if (res) {
|
||||||
|
await api.siteInfoApi.ImportTaskStart(res.key);
|
||||||
|
}
|
||||||
|
await loadImportTaskStatus();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function editTask(item: any) {
|
||||||
|
settingStore.checkPlus();
|
||||||
|
await openSiteImportTaskDialog({
|
||||||
|
afterSubmit: async () => {
|
||||||
|
await loadImportTaskStatus();
|
||||||
|
},
|
||||||
|
form: item,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const checkIntervalRef = ref();
|
||||||
|
onMounted(async () => {
|
||||||
|
await loadImportTaskStatus();
|
||||||
|
checkIntervalRef.value = setInterval(async () => {
|
||||||
|
await loadImportTaskStatus();
|
||||||
|
}, 3000);
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
clearInterval(checkIntervalRef.value);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less">
|
||||||
|
.site-info-import-task-status {
|
||||||
|
.table-container {
|
||||||
|
height: 50vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-progress {
|
||||||
|
margin-bottom: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -27,8 +27,8 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useFs } from "@fast-crud/fast-crud";
|
import { useFs } from "@fast-crud/fast-crud";
|
||||||
import { onActivated, onMounted } from "vue";
|
|
||||||
import createCrudOptions from "./crud";
|
import createCrudOptions from "./crud";
|
||||||
|
import { useMounted } from "/@/use/use-mounted";
|
||||||
import { useI18n } from "/src/locales";
|
import { useI18n } from "/src/locales";
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
defineOptions({
|
defineOptions({
|
||||||
@@ -42,12 +42,5 @@ const context: any = {
|
|||||||
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context });
|
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context });
|
||||||
|
|
||||||
const handleBatchDelete = context.handleBatchDelete;
|
const handleBatchDelete = context.handleBatchDelete;
|
||||||
|
useMounted(() => crudExpose.doRefresh());
|
||||||
// 页面打开后获取列表数据
|
|
||||||
onMounted(() => {
|
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
onActivated(() => {
|
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -5,9 +5,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onActivated, onMounted, ref, Ref } 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 { useMounted } from "/@/use/use-mounted";
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "SiteIpCertMonitor",
|
name: "SiteIpCertMonitor",
|
||||||
@@ -21,12 +21,5 @@ const { crudBinding, crudRef, crudExpose } = useFs({
|
|||||||
props,
|
props,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
useMounted(() => crudExpose.doRefresh());
|
||||||
// 页面打开后获取列表数据
|
|
||||||
onMounted(() => {
|
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
onActivated(() => {
|
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
import { useFormWrapper } from "@fast-crud/fast-crud";
|
import { useFormWrapper, compute } from "@fast-crud/fast-crud";
|
||||||
import { siteInfoApi } from "./api";
|
import { siteInfoApi } from "./api";
|
||||||
import { useI18n } from "/src/locales";
|
import { useI18n } from "/@/locales";
|
||||||
|
import { useSettingStore } from "/@/store/settings";
|
||||||
|
import { useFormDialog } from "/@/use/use-dialog";
|
||||||
import GroupSelector from "../../basic/group/group-selector.vue";
|
import GroupSelector from "../../basic/group/group-selector.vue";
|
||||||
|
import SiteInfoImportTaskStatus from "./import.vue";
|
||||||
|
|
||||||
export function useSiteImport() {
|
export function useSiteImport() {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { openCrudFormDialog } = useFormWrapper();
|
const { openCrudFormDialog } = useFormWrapper();
|
||||||
@@ -13,7 +17,7 @@ export function useSiteImport() {
|
|||||||
columns: {
|
columns: {
|
||||||
text: {
|
text: {
|
||||||
type: "textarea",
|
type: "textarea",
|
||||||
title: t("certd.domainList.title"), // 域名列表
|
title: t("certd.domainList.title"),
|
||||||
form: {
|
form: {
|
||||||
helper: t("certd.domainList.helper"),
|
helper: t("certd.domainList.helper"),
|
||||||
rules: [{ required: true, message: t("certd.domainList.required") }],
|
rules: [{ required: true, message: t("certd.domainList.required") }],
|
||||||
@@ -21,9 +25,7 @@ export function useSiteImport() {
|
|||||||
placeholder: t("certd.domainList.placeholder"),
|
placeholder: t("certd.domainList.placeholder"),
|
||||||
rows: 8,
|
rows: 8,
|
||||||
},
|
},
|
||||||
col: {
|
col: { span: 24 },
|
||||||
span: 24,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
groupId: {
|
groupId: {
|
||||||
@@ -36,13 +38,10 @@ export function useSiteImport() {
|
|||||||
vModel: "modelValue",
|
vModel: "modelValue",
|
||||||
type: "site",
|
type: "site",
|
||||||
},
|
},
|
||||||
col: {
|
col: { span: 24 },
|
||||||
span: 24,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
form: {
|
form: {
|
||||||
async doSubmit({ form }) {
|
async doSubmit({ form }) {
|
||||||
return siteInfoApi.Import(form);
|
return siteInfoApi.Import(form);
|
||||||
@@ -53,7 +52,99 @@ export function useSiteImport() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return { openSiteImportDialog };
|
||||||
openSiteImportDialog,
|
}
|
||||||
|
|
||||||
|
export function useSiteImportTask() {
|
||||||
|
const { openFormDialog } = useFormDialog();
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
const columns = {
|
||||||
|
dnsProviderType: {
|
||||||
|
title: t("certd.domain.domainProvider"),
|
||||||
|
type: "text",
|
||||||
|
form: {
|
||||||
|
component: {
|
||||||
|
name: "dns-provider-selector",
|
||||||
|
on: {
|
||||||
|
selectedChange: ({ form, $event }: any) => {
|
||||||
|
form.dnsProviderAccessType = $event.accessType;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
valueChange({ form }: any) {
|
||||||
|
form.dnsProviderAccessId = null;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
dnsProviderAccessType: {
|
||||||
|
title: t("certd.domain.domainProviderAccessType"),
|
||||||
|
type: "text",
|
||||||
|
form: { show: false },
|
||||||
|
},
|
||||||
|
dnsProviderAccessId: {
|
||||||
|
title: t("certd.domain.domainProviderAccess"),
|
||||||
|
type: "text",
|
||||||
|
form: {
|
||||||
|
component: {
|
||||||
|
name: "access-selector",
|
||||||
|
vModel: "modelValue",
|
||||||
|
type: compute(({ form }: any) => form.dnsProviderAccessType || form.dnsProviderType),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
groupId: {
|
||||||
|
title: t("certd.fields.group"),
|
||||||
|
type: "text",
|
||||||
|
form: {
|
||||||
|
component: {
|
||||||
|
name: GroupSelector,
|
||||||
|
vModel: "modelValue",
|
||||||
|
type: "site",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return function openSiteImportTaskDialog(req: { afterSubmit?: (res?: any) => void; form?: any }) {
|
||||||
|
openFormDialog({
|
||||||
|
title: t("certd.domain.importFromProvider"),
|
||||||
|
columns,
|
||||||
|
initialForm: { ...req.form },
|
||||||
|
onSubmit: async (form: any) => {
|
||||||
|
const res = await siteInfoApi.ImportTaskSave({
|
||||||
|
key: form.key,
|
||||||
|
dnsProviderType: form.dnsProviderType,
|
||||||
|
dnsProviderAccessId: form.dnsProviderAccessId,
|
||||||
|
groupId: form.groupId,
|
||||||
|
});
|
||||||
|
if (req.afterSubmit) {
|
||||||
|
req.afterSubmit(res);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useSiteImportTaskManage() {
|
||||||
|
const { openFormDialog } = useFormDialog();
|
||||||
|
const { t } = useI18n();
|
||||||
|
const settingStore = useSettingStore();
|
||||||
|
return async function openSiteImportTaskManageDialog(req: {
|
||||||
|
afterSubmit?: (res?: any) => void;
|
||||||
|
form?: any;
|
||||||
|
zIndex?: number;
|
||||||
|
}) {
|
||||||
|
settingStore.checkPlus();
|
||||||
|
await openFormDialog({
|
||||||
|
title: t("certd.domain.importFromProvider"),
|
||||||
|
body: () => <SiteInfoImportTaskStatus />,
|
||||||
|
zIndex: req.zIndex,
|
||||||
|
onSubmit: async (form: any) => {
|
||||||
|
if (req.afterSubmit) {
|
||||||
|
req.afterSubmit(form);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, onActivated, onMounted } from "vue";
|
import { defineComponent } from "vue";
|
||||||
|
import { useMounted } from "/@/use/use-mounted";
|
||||||
import { useFs } from "@fast-crud/fast-crud";
|
import { useFs } from "@fast-crud/fast-crud";
|
||||||
import createCrudOptions from "./crud";
|
import createCrudOptions from "./crud";
|
||||||
import { createNotificationApi } from "./api";
|
import { createNotificationApi } from "./api";
|
||||||
@@ -23,14 +24,7 @@ export default defineComponent({
|
|||||||
const api = createNotificationApi();
|
const api = createNotificationApi();
|
||||||
notificationProvide(api);
|
notificationProvide(api);
|
||||||
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: { api, permission: { isProjectPermission: true } } });
|
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: { api, permission: { isProjectPermission: true } } });
|
||||||
|
useMounted(() => crudExpose.doRefresh());
|
||||||
// 页面打开后获取列表数据
|
|
||||||
onMounted(() => {
|
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
onActivated(() => {
|
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
crudBinding,
|
crudBinding,
|
||||||
|
|||||||
@@ -11,21 +11,14 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onActivated, 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 { useMounted } from "/@/use/use-mounted";
|
||||||
import { OPEN_API_DOC } from "/@/views/certd/open/openkey/api";
|
import { OPEN_API_DOC } from "/@/views/certd/open/openkey/api";
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "OpenKey",
|
name: "OpenKey",
|
||||||
});
|
});
|
||||||
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: { permission: { isProjectPermission: true } } });
|
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: { permission: { isProjectPermission: true } } });
|
||||||
|
useMounted(() => crudExpose.doRefresh());
|
||||||
// 页面打开后获取列表数据
|
|
||||||
onMounted(() => {
|
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
onActivated(() => {
|
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes, useUi } from "@fast-crud/fast-crud";
|
import { AddReq, ColumnProps, CreateCrudOptionsProps, CreateCrudOptionsRet, DataFormatterContext, DelReq, dict, EditReq, UserPageQuery, UserPageRes, useUi } from "@fast-crud/fast-crud";
|
||||||
import { Modal, notification } from "ant-design-vue";
|
import { Modal, notification } from "ant-design-vue";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import { computed, ref } from "vue";
|
import { computed, ref } from "vue";
|
||||||
@@ -75,6 +75,17 @@ export default function ({ crudExpose, context: { selectedRowKeys, openCertApply
|
|||||||
const projectStore = useProjectStore();
|
const projectStore = useProjectStore();
|
||||||
const { myProjectDict } = useDicts();
|
const { myProjectDict } = useDicts();
|
||||||
const DEFAULT_WILL_EXPIRE_DAYS = settingStore.sysPublic.defaultWillExpireDays || settingStore.sysPublic.defaultCertRenewDays || 15;
|
const DEFAULT_WILL_EXPIRE_DAYS = settingStore.sysPublic.defaultWillExpireDays || settingStore.sysPublic.defaultCertRenewDays || 15;
|
||||||
|
const pipelineTypeDictData = [
|
||||||
|
{ value: "cert", label: t("certd.types.certApply") },
|
||||||
|
{ value: "cert_upload", label: t("certd.types.certUpload") },
|
||||||
|
{ value: "custom", label: t("certd.types.custom") },
|
||||||
|
{ value: "template", label: t("certd.types.template") },
|
||||||
|
{ value: "cert_auto", label: t("certd.types.certApply") },
|
||||||
|
];
|
||||||
|
const disabledDictData = [
|
||||||
|
{ value: false, label: t("certd.fields.enabledLabel") },
|
||||||
|
{ value: true, label: t("certd.fields.disabledLabel") },
|
||||||
|
];
|
||||||
|
|
||||||
function onDialogOpen(opt: any) {
|
function onDialogOpen(opt: any) {
|
||||||
const searchForm = crudExpose.getSearchValidatedFormData();
|
const searchForm = crudExpose.getSearchValidatedFormData();
|
||||||
@@ -84,6 +95,79 @@ export default function ({ crudExpose, context: { selectedRowKeys, openCertApply
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getRecordValue(row: any, key: string) {
|
||||||
|
return key.split(".").reduce((target, item) => target?.[item], row);
|
||||||
|
}
|
||||||
|
|
||||||
|
function findDictLabel(data: any[], value: any) {
|
||||||
|
return data.find(item => item.value === value)?.label ?? value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatValidTime(value: any) {
|
||||||
|
if (!value || value <= 0) {
|
||||||
|
return t("certd.pi.permanentValid");
|
||||||
|
}
|
||||||
|
if (value < Date.now()) {
|
||||||
|
return t("certd.hasExpired");
|
||||||
|
}
|
||||||
|
return dayjs(value).format("YYYY-MM-DD");
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatRemainingValidity(lastVars: any) {
|
||||||
|
const expiresTime = lastVars?.certExpiresTime;
|
||||||
|
if (!expiresTime) {
|
||||||
|
return "-";
|
||||||
|
}
|
||||||
|
const leftDays = dayjs(expiresTime).diff(dayjs(), "day");
|
||||||
|
if (leftDays < 0) {
|
||||||
|
return t("certd.hasExpired");
|
||||||
|
}
|
||||||
|
return `${leftDays}${t("certd.days")}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatListValue(value: any) {
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
return value.join(",");
|
||||||
|
}
|
||||||
|
return value ?? "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function exportColumnFilter(col: ColumnProps) {
|
||||||
|
if (!col.key || ["_index", "_selection", "rowHandle"].includes(col.key)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (col.key === "lastVars.certDomains") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return col.show !== false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function exportDataFormatter(opts: DataFormatterContext) {
|
||||||
|
const { row, originalRow, col, exportCol } = opts;
|
||||||
|
const key = col.key;
|
||||||
|
const value = getRecordValue(originalRow, key);
|
||||||
|
|
||||||
|
if (key === "validTime") {
|
||||||
|
row[key] = formatValidTime(value);
|
||||||
|
} else if (key === "lastVars") {
|
||||||
|
row[key] = formatRemainingValidity(value);
|
||||||
|
} else if (key === "lastVars.certDomains") {
|
||||||
|
row[key] = formatListValue(value);
|
||||||
|
} else if (key === "status") {
|
||||||
|
row[key] = statusUtil.get(value)?.label ?? value;
|
||||||
|
} else if (key === "disabled") {
|
||||||
|
row[key] = findDictLabel(disabledDictData, value);
|
||||||
|
} else if (key === "type") {
|
||||||
|
row[key] = findDictLabel(pipelineTypeDictData, value);
|
||||||
|
} else if (key.includes("Time") && value) {
|
||||||
|
row[key] = dayjs(value).format("YYYY-MM-DD HH:mm:ss");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (col.width) {
|
||||||
|
exportCol.width = col.width / 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
crudOptions: {
|
crudOptions: {
|
||||||
request: {
|
request: {
|
||||||
@@ -178,6 +262,18 @@ export default function ({ crudExpose, context: { selectedRowKeys, openCertApply
|
|||||||
confirmMessage: t("certd.table.confirmDeleteMessage"),
|
confirmMessage: t("certd.table.confirmDeleteMessage"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
toolbar: {
|
||||||
|
buttons: {
|
||||||
|
export: {
|
||||||
|
show: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
export: {
|
||||||
|
dataFrom: "search",
|
||||||
|
columnFilter: exportColumnFilter,
|
||||||
|
dataFormatter: exportDataFormatter,
|
||||||
|
},
|
||||||
|
},
|
||||||
tabs: {
|
tabs: {
|
||||||
name: "groupId",
|
name: "groupId",
|
||||||
show: true,
|
show: true,
|
||||||
@@ -419,6 +515,19 @@ export default function ({ crudExpose, context: { selectedRowKeys, openCertApply
|
|||||||
width: 150,
|
width: 150,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"lastVars.certDomains": {
|
||||||
|
title: t("certd.fields.certDomains"),
|
||||||
|
type: "text",
|
||||||
|
form: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
column: {
|
||||||
|
width: 260,
|
||||||
|
show: false,
|
||||||
|
ellipsis: true,
|
||||||
|
showTitle: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
"lastVars.certEffectiveTime": {
|
"lastVars.certEffectiveTime": {
|
||||||
title: t("certd.fields.effectiveTime"),
|
title: t("certd.fields.effectiveTime"),
|
||||||
search: {
|
search: {
|
||||||
@@ -503,10 +612,7 @@ export default function ({ crudExpose, context: { selectedRowKeys, openCertApply
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
dict: dict({
|
dict: dict({
|
||||||
data: [
|
data: disabledDictData,
|
||||||
{ value: false, label: t("certd.fields.enabledLabel") },
|
|
||||||
{ value: true, label: t("certd.fields.disabledLabel") },
|
|
||||||
],
|
|
||||||
}),
|
}),
|
||||||
form: {
|
form: {
|
||||||
value: false,
|
value: false,
|
||||||
@@ -563,13 +669,7 @@ export default function ({ crudExpose, context: { selectedRowKeys, openCertApply
|
|||||||
col: { span: 2 },
|
col: { span: 2 },
|
||||||
},
|
},
|
||||||
dict: dict({
|
dict: dict({
|
||||||
data: [
|
data: pipelineTypeDictData,
|
||||||
{ value: "cert", label: t("certd.types.certApply") },
|
|
||||||
{ value: "cert_upload", label: t("certd.types.certUpload") },
|
|
||||||
{ value: "custom", label: t("certd.types.custom") },
|
|
||||||
{ value: "template", label: t("certd.types.template") },
|
|
||||||
{ value: "cert_auto", label: t("certd.types.certApply") },
|
|
||||||
],
|
|
||||||
}),
|
}),
|
||||||
form: {
|
form: {
|
||||||
show: false,
|
show: false,
|
||||||
@@ -650,7 +750,7 @@ export default function ({ crudExpose, context: { selectedRowKeys, openCertApply
|
|||||||
align: "center",
|
align: "center",
|
||||||
cellRender({ value }) {
|
cellRender({ value }) {
|
||||||
if (!value || value <= 0) {
|
if (!value || value <= 0) {
|
||||||
return "-";
|
return t("certd.pi.permanentValid");
|
||||||
}
|
}
|
||||||
if (value < Date.now()) {
|
if (value < Date.now()) {
|
||||||
return t("certd.hasExpired");
|
return t("certd.hasExpired");
|
||||||
|
|||||||
@@ -11,7 +11,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, onActivated, onMounted } from "vue";
|
import { defineComponent } from "vue";
|
||||||
|
import { useMounted } from "/@/use/use-mounted";
|
||||||
import { useFs } from "@fast-crud/fast-crud";
|
import { useFs } from "@fast-crud/fast-crud";
|
||||||
import createCrudOptions from "./crud";
|
import createCrudOptions from "./crud";
|
||||||
|
|
||||||
@@ -24,14 +25,7 @@ export default defineComponent({
|
|||||||
permission: { isProjectPermission: true },
|
permission: { isProjectPermission: true },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
useMounted(() => crudExpose.doRefresh());
|
||||||
// 页面打开后获取列表数据
|
|
||||||
onMounted(() => {
|
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
onActivated(() => {
|
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
crudBinding,
|
crudBinding,
|
||||||
|
|||||||
@@ -55,7 +55,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, onActivated, onMounted, provide, ref } from "vue";
|
import { computed, provide, ref } from "vue";
|
||||||
import { dict, useFs } from "@fast-crud/fast-crud";
|
import { dict, useFs } from "@fast-crud/fast-crud";
|
||||||
import createCrudOptions from "./crud";
|
import createCrudOptions from "./crud";
|
||||||
import ChangeGroup from "./components/change-group.vue";
|
import ChangeGroup from "./components/change-group.vue";
|
||||||
@@ -67,7 +67,7 @@ import BatchRerun from "./components/batch-rerun.vue";
|
|||||||
import { Modal, notification } from "ant-design-vue";
|
import { Modal, notification } from "ant-design-vue";
|
||||||
import * as api from "./api";
|
import * as api from "./api";
|
||||||
import { useI18n } from "/src/locales";
|
import { useI18n } from "/src/locales";
|
||||||
|
import { useMounted } from "/@/use/use-mounted";
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
import ChangeNotification from "/@/views/certd/pipeline/components/change-notification.vue";
|
import ChangeNotification from "/@/views/certd/pipeline/components/change-notification.vue";
|
||||||
import { useSettingStore } from "/@/store/settings";
|
import { useSettingStore } from "/@/store/settings";
|
||||||
@@ -128,11 +128,7 @@ context.hasActionPermission = hasActionPermission;
|
|||||||
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context });
|
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context });
|
||||||
|
|
||||||
// 页面打开后获取列表数据
|
// 页面打开后获取列表数据
|
||||||
onMounted(() => {
|
useMounted(async () => {
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
|
|
||||||
onActivated(async () => {
|
|
||||||
await groupDictRef.reloadDict();
|
await groupDictRef.reloadDict();
|
||||||
await crudExpose.doRefresh();
|
await crudExpose.doRefresh();
|
||||||
});
|
});
|
||||||
|
|||||||
+2
-2
@@ -172,9 +172,9 @@ function useStepForm() {
|
|||||||
|
|
||||||
const stepTypeSelected = (item: any) => {
|
const stepTypeSelected = (item: any) => {
|
||||||
if (item.needPlus && !settingStore.isPlus) {
|
if (item.needPlus && !settingStore.isPlus) {
|
||||||
message.warn("此插件需要开通专业版才能使用");
|
message.warn("此插件需要开通Certd专业版才能使用");
|
||||||
mitter.emit("openVipModal");
|
mitter.emit("openVipModal");
|
||||||
throw new Error("此插件需要开通专业版才能使用");
|
throw new Error("此插件需要开通Certd专业版才能使用");
|
||||||
}
|
}
|
||||||
currentStep.value.type = item.name;
|
currentStep.value.type = item.name;
|
||||||
currentStep.value.title = item.title;
|
currentStep.value.title = item.title;
|
||||||
|
|||||||
@@ -26,18 +26,18 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onActivated, 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 { message, Modal } from "ant-design-vue";
|
import { message, Modal } from "ant-design-vue";
|
||||||
import { DeleteBatch } from "./api";
|
import { DeleteBatch } from "./api";
|
||||||
import { useI18n } from "/src/locales";
|
import { useI18n } from "/src/locales";
|
||||||
import { useCrudPermission } from "/@/plugin/permission";
|
import { useCrudPermission } from "/@/plugin/permission";
|
||||||
|
import { useMounted } from "/@/use/use-mounted";
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "CnameRecord",
|
name: "SubDomain",
|
||||||
});
|
});
|
||||||
const context: any = {
|
const context: any = {
|
||||||
permission: {
|
permission: {
|
||||||
@@ -67,10 +67,7 @@ const handleBatchDelete = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 页面打开后获取列表数据
|
// 页面打开后获取列表数据
|
||||||
onMounted(() => {
|
useMounted(async () => {
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
onActivated(async () => {
|
|
||||||
await crudExpose.doRefresh();
|
await crudExpose.doRefresh();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -14,9 +14,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onActivated, 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 { useMounted } from "/@/use/use-mounted";
|
||||||
import { useI18n } from "/src/locales";
|
import { useI18n } from "/src/locales";
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "PipelineTemplate",
|
name: "PipelineTemplate",
|
||||||
@@ -28,11 +28,5 @@ const { crudBinding, crudRef, crudExpose } = useFs({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
// 页面打开后获取列表数据
|
useMounted(() => crudExpose.doRefresh());
|
||||||
onMounted(() => {
|
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
onActivated(() => {
|
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -27,7 +27,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onActivated, onMounted, Ref, ref } from "vue";
|
import { onMounted, ref } from "vue";
|
||||||
|
import { useMounted } from "/@/use/use-mounted";
|
||||||
import { useFs } from "@fast-crud/fast-crud";
|
import { useFs } from "@fast-crud/fast-crud";
|
||||||
import createCrudOptions from "./crud";
|
import createCrudOptions from "./crud";
|
||||||
import { message, Modal } from "ant-design-vue";
|
import { message, Modal } from "ant-design-vue";
|
||||||
@@ -117,13 +118,12 @@ onMounted(async () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await loadProjectDetail();
|
await loadProjectDetail();
|
||||||
await crudExpose.doRefresh();
|
|
||||||
|
|
||||||
if (migrate === "true") {
|
if (migrate === "true") {
|
||||||
openTransferDialog();
|
openTransferDialog();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
onActivated(async () => {
|
useMounted(async () => {
|
||||||
await crudExpose.doRefresh();
|
await crudExpose.doRefresh();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -18,12 +18,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onActivated, 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 { message, Modal } from "ant-design-vue";
|
import { message, Modal } from "ant-design-vue";
|
||||||
import { DeleteBatch } from "./api";
|
import { DeleteBatch } from "./api";
|
||||||
import { useI18n } from "/src/locales";
|
import { useI18n } from "/src/locales";
|
||||||
|
import { useMounted } from "/@/use/use-mounted";
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
@@ -52,10 +52,7 @@ const handleBatchDelete = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 页面打开后获取列表数据
|
// 页面打开后获取列表数据
|
||||||
onMounted(() => {
|
useMounted(async () => {
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
onActivated(async () => {
|
|
||||||
await crudExpose.doRefresh();
|
await crudExpose.doRefresh();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -15,14 +15,14 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, onActivated, onMounted, ref } from "vue";
|
|
||||||
import { useFs } from "@fast-crud/fast-crud";
|
import { useFs } from "@fast-crud/fast-crud";
|
||||||
|
import { computed, ref } from "vue";
|
||||||
import createCrudOptions from "./crud";
|
import createCrudOptions from "./crud";
|
||||||
import { mySuiteApi, SuiteDetail } from "/@/views/certd/suite/mine/api";
|
import { mySuiteApi, SuiteDetail } from "/@/views/certd/suite/mine/api";
|
||||||
import SuiteCard from "/@/views/framework/home/dashboard/suite-card.vue";
|
import SuiteCard from "/@/views/framework/home/dashboard/suite-card.vue";
|
||||||
|
import { useMounted } from "/@/use/use-mounted";
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "MySuites",
|
name: "MySuite",
|
||||||
});
|
});
|
||||||
const detail = ref<SuiteDetail>({});
|
const detail = ref<SuiteDetail>({});
|
||||||
const currentSuite = computed(() => {
|
const currentSuite = computed(() => {
|
||||||
@@ -39,11 +39,8 @@ async function loadSuiteDetail() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 页面打开后获取列表数据
|
// 页面打开后获取列表数据
|
||||||
onMounted(async () => {
|
useMounted(async () => {
|
||||||
await loadSuiteDetail();
|
await loadSuiteDetail();
|
||||||
await crudExpose.doRefresh();
|
await crudExpose.doRefresh();
|
||||||
});
|
});
|
||||||
onActivated(() => {
|
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -8,9 +8,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onActivated, 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 { useMounted } from "/@/use/use-mounted";
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "MyTrade",
|
name: "MyTrade",
|
||||||
@@ -18,10 +18,7 @@ defineOptions({
|
|||||||
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions });
|
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions });
|
||||||
|
|
||||||
// 页面打开后获取列表数据
|
// 页面打开后获取列表数据
|
||||||
onMounted(() => {
|
useMounted(async () => {
|
||||||
crudExpose.doRefresh();
|
|
||||||
});
|
|
||||||
onActivated(async () => {
|
|
||||||
await crudExpose.doRefresh();
|
await crudExpose.doRefresh();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user