mirror of
https://github.com/certd/certd.git
synced 2026-10-15 03:01:02 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
14809127d6 | ||
|
|
bd8b251d6e | ||
|
|
5563abb13a | ||
|
|
51e83e4c38 | ||
|
|
2b1a5296fe | ||
|
|
bded368cbb | ||
|
|
6a649aaca0 | ||
|
|
e971145686 | ||
|
|
bbca449f94 | ||
|
|
e6852c2715 | ||
|
|
47cb523307 | ||
|
|
cbf46b5c48 | ||
|
|
7ed3105d97 | ||
|
|
61b945c08f |
@@ -75,7 +75,7 @@ Certd 是可私有化部署的 SSL/TLS 证书自动化管理平台,提供 Web
|
||||
- 只有真正机械化的大批量替换、格式化或生成任务才考虑脚本/工具。若必须使用临时脚本,应放在临时目录并在同一个受控步骤内完成创建、执行、删除;不要把临时脚本落在仓库里跨多步工具调用执行。
|
||||
- 不要主动运行 `pnpm install`;缺依赖、TTY、网络导致安装或测试失败时,停止尝试并说明环境问题。
|
||||
- 优先沿用现有模块、插件、service、页面模式;不要为形式上的复用制造过度抽象。
|
||||
- 代码可读性优先于短写法。尽量少用三元表达式,优先使用完整的 `if/else`;复杂条件、链式调用、内联对象和多层 helper 调用要拆成命名清晰的中间变量或小方法。
|
||||
- 【重要重要重要】代码可读性优先于短写法。尽量少用三元表达式,优先使用完整的 `if/else`【其他技能与此条要求冲突的,以此条要求为准】;复杂条件、链式调用、内联对象和多层 helper 调用要拆成命名清晰的中间变量或小方法。
|
||||
- 方法调用链不要直接塞进另一个方法参数;先用有意义的局部变量承接返回值,再传入下一步。
|
||||
- 不要在单一表达式内嵌套分支、对象构造与方法调用。优先使用清晰的 `if/else` 分支;仅在确实能降低复杂度时才提取有意义的中间变量,避免为拆分而增加阅读跳转。
|
||||
- 注释优先使用中文,尤其是业务规则、兼容逻辑、协议细节和隐藏风险;文件已有英文风格或引用外部术语时可保持一致。
|
||||
|
||||
@@ -3,6 +3,19 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.44.4](https://github.com/certd/certd/compare/v1.44.3...v1.44.4) (2026-09-12)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复添加步骤会修改所有步骤标题的bug ([51e83e4](https://github.com/certd/certd/commit/51e83e4c38f7f319314fdc38ef33cf5720b2dde0))
|
||||
* 修复证书插件配置无法打开的bug ([5563abb](https://github.com/certd/certd/commit/5563abb13a62140f4dee668ab768cf4ff9371ddb))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 新增余额管理,管理员充值功能 ([bded368](https://github.com/certd/certd/commit/bded368cbb8974b6937ae260e448c25fae5c33ad))
|
||||
* **acme-account-access:** AcmeAccount授权允许修改eab,重新生成account ([6a649aa](https://github.com/certd/certd/commit/6a649aaca083ccd3b517f7d676a58220aa33b37d))
|
||||
* **ui:** 商业版套餐购买不要求设置支付方式 ([e971145](https://github.com/certd/certd/commit/e9711456860d7db40914a0c295534f7bca56f83c))
|
||||
|
||||
## [1.44.3](https://github.com/certd/certd/compare/v1.44.2...v1.44.3) (2026-09-06)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -3,6 +3,17 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.44.3](https://github.com/certd/certd/compare/v1.44.2...v1.44.3) (2026-09-06)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **plugin-service:** 修复同步自己开发的云端插件不显示已安装状态问题 ([dac94b6](https://github.com/certd/certd/commit/dac94b64f0ceb7176e2cf07ce220be0aa5ed98d2))
|
||||
* **plugin:** 修复插件配置保存与加载的相关问题 ([bd94334](https://github.com/certd/certd/commit/bd9433478a43d5d64ce6370386d0fe0aaff07d2e))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **plugin:** add Fastly custom TLS certificates integration ([#797](https://github.com/certd/certd/issues/797)) [@szhu25](https://github.com/szhu25) ([2a2e963](https://github.com/certd/certd/commit/2a2e963914c4dfc192cbe0a4bbb9c115e626da01))
|
||||
|
||||
## [1.44.2](https://github.com/certd/certd/compare/v1.44.1...v1.44.2) (2026-09-03)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
+1
-1
@@ -9,5 +9,5 @@
|
||||
}
|
||||
},
|
||||
"npmClient": "pnpm",
|
||||
"version": "1.44.3"
|
||||
"version": "1.44.4"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.44.4](https://github.com/publishlab/node-acme-client/compare/v1.44.3...v1.44.4) (2026-09-12)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
## [1.44.3](https://github.com/publishlab/node-acme-client/compare/v1.44.2...v1.44.3) (2026-09-06)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"description": "Simple and unopinionated ACME client",
|
||||
"private": false,
|
||||
"author": "nmorsman",
|
||||
"version": "1.44.3",
|
||||
"version": "1.44.4",
|
||||
"type": "module",
|
||||
"module": "./dist/index.js",
|
||||
"main": "./dist/index.js",
|
||||
@@ -18,7 +18,7 @@
|
||||
"types"
|
||||
],
|
||||
"dependencies": {
|
||||
"@certd/basic": "^1.44.3",
|
||||
"@certd/basic": "^1.44.4",
|
||||
"@peculiar/x509": "^1.11.0",
|
||||
"asn1js": "^3.0.5",
|
||||
"axios": "^1.9.0",
|
||||
@@ -76,5 +76,5 @@
|
||||
"bugs": {
|
||||
"url": "https://github.com/publishlab/node-acme-client/issues"
|
||||
},
|
||||
"gitHead": "67f3daae625ba734e7e390dd84acc9e3bc1930bc"
|
||||
"gitHead": "cc60cd4cd1d914110be65284bcf16cd3c5a63b8d"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.44.4](https://github.com/certd/certd/compare/v1.44.3...v1.44.4) (2026-09-12)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
## [1.44.3](https://github.com/certd/certd/compare/v1.44.2...v1.44.3) (2026-09-06)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
@@ -1 +1 @@
|
||||
23:46
|
||||
19:17
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/basic",
|
||||
"private": false,
|
||||
"version": "1.44.3",
|
||||
"version": "1.44.4",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -54,5 +54,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "67f3daae625ba734e7e390dd84acc9e3bc1930bc"
|
||||
"gitHead": "cc60cd4cd1d914110be65284bcf16cd3c5a63b8d"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.44.4](https://github.com/certd/certd/compare/v1.44.3...v1.44.4) (2026-09-12)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
## [1.44.3](https://github.com/certd/certd/compare/v1.44.2...v1.44.3) (2026-09-06)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/pipeline",
|
||||
"private": false,
|
||||
"version": "1.44.3",
|
||||
"version": "1.44.4",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -21,8 +21,8 @@
|
||||
"lint": "eslint --fix --ext .ts src"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/basic": "^1.44.3",
|
||||
"@certd/plus-core": "^1.44.3",
|
||||
"@certd/basic": "^1.44.4",
|
||||
"@certd/plus-core": "^1.44.4",
|
||||
"dayjs": "^1.11.7",
|
||||
"lodash-es": "^4.17.21",
|
||||
"reflect-metadata": "^0.2.2"
|
||||
@@ -51,5 +51,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "67f3daae625ba734e7e390dd84acc9e3bc1930bc"
|
||||
"gitHead": "cc60cd4cd1d914110be65284bcf16cd3c5a63b8d"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.44.4](https://github.com/certd/certd/compare/v1.44.3...v1.44.4) (2026-09-12)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
## [1.44.3](https://github.com/certd/certd/compare/v1.44.2...v1.44.3) (2026-09-06)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-huawei",
|
||||
"private": false,
|
||||
"version": "1.44.3",
|
||||
"version": "1.44.4",
|
||||
"main": "./dist/bundle.js",
|
||||
"module": "./dist/bundle.js",
|
||||
"types": "./dist/d/index.d.ts",
|
||||
@@ -31,5 +31,5 @@
|
||||
"prettier": "3.3.3",
|
||||
"tslib": "^2.8.1"
|
||||
},
|
||||
"gitHead": "67f3daae625ba734e7e390dd84acc9e3bc1930bc"
|
||||
"gitHead": "cc60cd4cd1d914110be65284bcf16cd3c5a63b8d"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.44.4](https://github.com/certd/certd/compare/v1.44.3...v1.44.4) (2026-09-12)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
## [1.44.3](https://github.com/certd/certd/compare/v1.44.2...v1.44.3) (2026-09-06)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-iframe",
|
||||
"private": false,
|
||||
"version": "1.44.3",
|
||||
"version": "1.44.4",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -37,5 +37,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "67f3daae625ba734e7e390dd84acc9e3bc1930bc"
|
||||
"gitHead": "cc60cd4cd1d914110be65284bcf16cd3c5a63b8d"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.44.4](https://github.com/certd/certd/compare/v1.44.3...v1.44.4) (2026-09-12)
|
||||
|
||||
**Note:** Version bump only for package @certd/jdcloud
|
||||
|
||||
## [1.44.3](https://github.com/certd/certd/compare/v1.44.2...v1.44.3) (2026-09-06)
|
||||
|
||||
**Note:** Version bump only for package @certd/jdcloud
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/jdcloud",
|
||||
"version": "1.44.3",
|
||||
"version": "1.44.4",
|
||||
"description": "jdcloud openApi sdk",
|
||||
"main": "./dist/bundle.js",
|
||||
"module": "./dist/bundle.js",
|
||||
@@ -63,5 +63,5 @@
|
||||
"fetch"
|
||||
]
|
||||
},
|
||||
"gitHead": "67f3daae625ba734e7e390dd84acc9e3bc1930bc"
|
||||
"gitHead": "cc60cd4cd1d914110be65284bcf16cd3c5a63b8d"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.44.4](https://github.com/certd/certd/compare/v1.44.3...v1.44.4) (2026-09-12)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
## [1.44.3](https://github.com/certd/certd/compare/v1.44.2...v1.44.3) (2026-09-06)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-k8s",
|
||||
"private": false,
|
||||
"version": "1.44.3",
|
||||
"version": "1.44.4",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -21,7 +21,7 @@
|
||||
"lint": "eslint --fix --ext .ts src"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/basic": "^1.44.3",
|
||||
"@certd/basic": "^1.44.4",
|
||||
"@kubernetes/client-node": "0.21.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -38,5 +38,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "67f3daae625ba734e7e390dd84acc9e3bc1930bc"
|
||||
"gitHead": "cc60cd4cd1d914110be65284bcf16cd3c5a63b8d"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.44.4](https://github.com/certd/certd/compare/v1.44.3...v1.44.4) (2026-09-12)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复证书插件配置无法打开的bug ([5563abb](https://github.com/certd/certd/commit/5563abb13a62140f4dee668ab768cf4ff9371ddb))
|
||||
|
||||
## [1.44.3](https://github.com/certd/certd/compare/v1.44.2...v1.44.3) (2026-09-06)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/lib-server",
|
||||
"version": "1.44.3",
|
||||
"version": "1.44.4",
|
||||
"description": "midway with flyway, sql upgrade way ",
|
||||
"private": false,
|
||||
"type": "module",
|
||||
@@ -29,11 +29,11 @@
|
||||
],
|
||||
"license": "AGPL",
|
||||
"dependencies": {
|
||||
"@certd/acme-client": "^1.44.3",
|
||||
"@certd/basic": "^1.44.3",
|
||||
"@certd/pipeline": "^1.44.3",
|
||||
"@certd/plugin-lib": "^1.44.3",
|
||||
"@certd/plus-core": "^1.44.3",
|
||||
"@certd/acme-client": "^1.44.4",
|
||||
"@certd/basic": "^1.44.4",
|
||||
"@certd/pipeline": "^1.44.4",
|
||||
"@certd/plugin-lib": "^1.44.4",
|
||||
"@certd/plus-core": "^1.44.4",
|
||||
"@midwayjs/cache": "3.14.0",
|
||||
"@midwayjs/core": "3.20.11",
|
||||
"@midwayjs/i18n": "3.20.13",
|
||||
@@ -69,5 +69,5 @@
|
||||
"typeorm": "^0.3.20",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "67f3daae625ba734e7e390dd84acc9e3bc1930bc"
|
||||
"gitHead": "cc60cd4cd1d914110be65284bcf16cd3c5a63b8d"
|
||||
}
|
||||
|
||||
@@ -133,12 +133,12 @@ export class SysPrivateSettings extends BaseSettings {
|
||||
// 内置项不在此配置 Directory URL:其端点由运行时按加密算法(pkType)通过 acme.getDirectoryUrl 获取,
|
||||
// 例如 ZeroSSL、SSL.com 的 RSA 与 EC 证书使用不同的端点,写死单一 URL 会导致 EC 申请走错端点。
|
||||
customAcmeProviders?: CustomAcmeProvider[] = [
|
||||
{ sslProvider: "letsencrypt", title: "Let's Encrypt", directoryUrl: "", needEAB: false, builtIn: true },
|
||||
{ sslProvider: "letsencrypt_staging", title: "Let's Encrypt测试环境", directoryUrl: "", needEAB: false, builtIn: true },
|
||||
{ sslProvider: "letsencrypt", title: "Let's Encrypt(支持7天IP证书)", directoryUrl: "", needEAB: false, builtIn: true },
|
||||
{ sslProvider: "google", title: "Google", directoryUrl: "", needEAB: true, builtIn: true },
|
||||
{ sslProvider: "zerossl", title: "ZeroSSL", directoryUrl: "", needEAB: true, builtIn: true },
|
||||
{ sslProvider: "litessl", title: "litessl", directoryUrl: "", needEAB: true, builtIn: true },
|
||||
{ sslProvider: "litessl", title: "Litessl", directoryUrl: "", needEAB: true, builtIn: true },
|
||||
{ sslProvider: "sslcom", title: "SSL.com", directoryUrl: "", needEAB: true, builtIn: true },
|
||||
{ sslProvider: "letsencrypt_staging", title: "Let's Encrypt测试环境(只能生成测试证书)", directoryUrl: "", needEAB: false, builtIn: true },
|
||||
];
|
||||
|
||||
removeSecret() {
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.44.4](https://github.com/certd/certd/compare/v1.44.3...v1.44.4) (2026-09-12)
|
||||
|
||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||
|
||||
## [1.44.3](https://github.com/certd/certd/compare/v1.44.2...v1.44.3) (2026-09-06)
|
||||
|
||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/midway-flyway-js",
|
||||
"version": "1.44.3",
|
||||
"version": "1.44.4",
|
||||
"description": "midway with flyway, sql upgrade way ",
|
||||
"private": false,
|
||||
"type": "module",
|
||||
@@ -52,5 +52,5 @@
|
||||
"typeorm": "^0.3.20",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "67f3daae625ba734e7e390dd84acc9e3bc1930bc"
|
||||
"gitHead": "cc60cd4cd1d914110be65284bcf16cd3c5a63b8d"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.44.4](https://github.com/certd/certd/compare/v1.44.3...v1.44.4) (2026-09-12)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-cert
|
||||
|
||||
## [1.44.3](https://github.com/certd/certd/compare/v1.44.2...v1.44.3) (2026-09-06)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-cert
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/plugin-cert",
|
||||
"private": false,
|
||||
"version": "1.44.3",
|
||||
"version": "1.44.4",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -20,7 +20,7 @@
|
||||
"lint": "eslint --fix --ext .ts src"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/plugin-lib": "^1.44.3"
|
||||
"@certd/plugin-lib": "^1.44.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/chai": "^4.3.12",
|
||||
@@ -38,5 +38,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "67f3daae625ba734e7e390dd84acc9e3bc1930bc"
|
||||
"gitHead": "cc60cd4cd1d914110be65284bcf16cd3c5a63b8d"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.44.4](https://github.com/certd/certd/compare/v1.44.3...v1.44.4) (2026-09-12)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-lib
|
||||
|
||||
## [1.44.3](https://github.com/certd/certd/compare/v1.44.2...v1.44.3) (2026-09-06)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-lib
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/plugin-lib",
|
||||
"private": false,
|
||||
"version": "1.44.3",
|
||||
"version": "1.44.4",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -17,9 +17,9 @@
|
||||
"lint": "eslint --fix --ext .ts src"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/acme-client": "^1.44.3",
|
||||
"@certd/basic": "^1.44.3",
|
||||
"@certd/pipeline": "^1.44.3",
|
||||
"@certd/acme-client": "^1.44.4",
|
||||
"@certd/basic": "^1.44.4",
|
||||
"@certd/pipeline": "^1.44.4",
|
||||
"dayjs": "^1.11.7",
|
||||
"jszip": "^3.10.1",
|
||||
"lodash-es": "^4.17.21",
|
||||
@@ -45,5 +45,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "67f3daae625ba734e7e390dd84acc9e3bc1930bc"
|
||||
"gitHead": "cc60cd4cd1d914110be65284bcf16cd3c5a63b8d"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,18 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.44.4](https://github.com/certd/certd/compare/v1.44.3...v1.44.4) (2026-09-12)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复添加步骤会修改所有步骤标题的bug ([51e83e4](https://github.com/certd/certd/commit/51e83e4c38f7f319314fdc38ef33cf5720b2dde0))
|
||||
* 修复证书插件配置无法打开的bug ([5563abb](https://github.com/certd/certd/commit/5563abb13a62140f4dee668ab768cf4ff9371ddb))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 新增余额管理,管理员充值功能 ([bded368](https://github.com/certd/certd/commit/bded368cbb8974b6937ae260e448c25fae5c33ad))
|
||||
* **ui:** 商业版套餐购买不要求设置支付方式 ([e971145](https://github.com/certd/certd/commit/e9711456860d7db40914a0c295534f7bca56f83c))
|
||||
|
||||
## [1.44.3](https://github.com/certd/certd/compare/v1.44.2...v1.44.3) (2026-09-06)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/ui-client",
|
||||
"version": "1.44.3",
|
||||
"version": "1.44.4",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite --open",
|
||||
@@ -104,8 +104,8 @@
|
||||
"zod-defaults": "^0.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@certd/lib-iframe": "^1.44.3",
|
||||
"@certd/pipeline": "^1.44.3",
|
||||
"@certd/lib-iframe": "^1.44.4",
|
||||
"@certd/pipeline": "^1.44.4",
|
||||
"@rollup/plugin-commonjs": "^25.0.7",
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@types/chai": "^4.3.12",
|
||||
|
||||
@@ -53,6 +53,8 @@ export default {
|
||||
suiteSetting: "Suite Settings",
|
||||
orderManager: "Order Management",
|
||||
userSuites: "User Suites",
|
||||
balanceManager: "Balance Management",
|
||||
balanceLog: "Balance Change Records",
|
||||
inviteCommissionSetting: "Incentive Plan Settings",
|
||||
inviteLevel: "Promotion Levels",
|
||||
inviteUserLevel: "User Promotion Levels",
|
||||
|
||||
@@ -54,6 +54,8 @@ export default {
|
||||
suiteSetting: "套餐设置",
|
||||
orderManager: "订单管理",
|
||||
userSuites: "用户套餐",
|
||||
balanceManager: "余额管理",
|
||||
balanceLog: "余额变更记录",
|
||||
inviteCommissionSetting: "激励计划设置",
|
||||
inviteLevel: "推广等级",
|
||||
inviteUserLevel: "用户推广等级",
|
||||
|
||||
@@ -317,6 +317,34 @@ export const sysResources = [
|
||||
keepAlive: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "certd.sysResources.balanceManager",
|
||||
name: "SysWallet",
|
||||
path: "/sys/suite/wallet",
|
||||
component: "/sys/suite/wallet/index.vue",
|
||||
meta: {
|
||||
show: () => {
|
||||
const settingStore = useSettingStore();
|
||||
return settingStore.isComm;
|
||||
},
|
||||
icon: "ion:wallet-outline",
|
||||
permission: "sys:settings:edit",
|
||||
auth: true,
|
||||
keepAlive: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "certd.sysResources.balanceLog",
|
||||
name: "SysWalletLog",
|
||||
path: "/sys/suite/wallet-log",
|
||||
component: "/sys/suite/wallet/log/index.vue",
|
||||
meta: {
|
||||
isMenu: false,
|
||||
permission: "sys:settings:view",
|
||||
auth: true,
|
||||
keepAlive: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "certd.sysResources.inviteCommissionSetting",
|
||||
name: "SysInviteCommissionSetting",
|
||||
|
||||
@@ -26,6 +26,14 @@ export function fillPluginDefine(plugin: any) {
|
||||
|
||||
if (plugin.sysSetting?.metadata) {
|
||||
merge(plugin.input, plugin.sysSetting.metadata?.input || {});
|
||||
const keys = Object.keys(plugin.input);
|
||||
for (const key of keys) {
|
||||
//修复旧版本错误引入的key导致报错的问题 【多引入进了一个type=CertApply】
|
||||
const column = plugin.input[key];
|
||||
if (typeof column != "object") {
|
||||
delete plugin.input[key];
|
||||
}
|
||||
}
|
||||
// 应用选项映射
|
||||
for (const key of Object.keys(plugin.input)) {
|
||||
const inputDef = plugin.input[key];
|
||||
|
||||
@@ -51,10 +51,11 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
rowHandle: {
|
||||
width: 120,
|
||||
fixed: "right",
|
||||
show: false,
|
||||
buttons: {
|
||||
view: { show: false },
|
||||
edit: { show: false },
|
||||
remove: { show: true },
|
||||
remove: { show: false },
|
||||
copy: { show: false },
|
||||
},
|
||||
},
|
||||
|
||||
+4
-1
@@ -280,7 +280,10 @@ function useStepForm() {
|
||||
return;
|
||||
}
|
||||
|
||||
callback.value("save", currentStep);
|
||||
// currentStep 是复用同一份 reactive 对象,直接传给回调会被 task.steps 保存同一引用,
|
||||
// 后续再次 stepOpen 会 delete 掉其属性,导致已保存的步骤(如第一个步骤)被覆盖。
|
||||
// 这里深拷贝一份再传出,保证每个步骤是独立对象。
|
||||
callback.value("save", cloneDeep(currentStep));
|
||||
stepDrawerClose();
|
||||
};
|
||||
|
||||
|
||||
@@ -53,9 +53,14 @@
|
||||
|
||||
<div class="flex-o mt-5">
|
||||
<span class="label">{{ $t("certd.order.paymentMethod") }}:</span>
|
||||
<div v-if="durationSelected.price === 0 || expectedThirdPartyAmount === 0">{{ $t("certd.order.free") }}</div>
|
||||
<div v-if="durationSelected.price === 0 || expectedThirdPartyAmount === 0">0元</div>
|
||||
<div v-else-if="noPaymentMethod">当前仅支持余额支付</div>
|
||||
<fs-dict-select v-else v-model:value="formRef.payType" :dict="paymentsDictRef" style="width: 200px"> </fs-dict-select>
|
||||
</div>
|
||||
|
||||
<div v-if="showBalanceInsufficientTip" class="flex-o mt-5">
|
||||
<span class="color-red">余额不足,请联系管理员,充值或设置套餐</span>
|
||||
</div>
|
||||
</div>
|
||||
</a-modal>
|
||||
</template>
|
||||
@@ -88,12 +93,17 @@ async function open(opts: OrderModalOpenReq) {
|
||||
formRef.value.productId = opts.product.id;
|
||||
formRef.value.duration = opts.duration;
|
||||
formRef.value.num = opts.num ?? 1;
|
||||
formRef.value.useRebateBalance = false;
|
||||
formRef.value.useRebateBalance = true;
|
||||
try {
|
||||
wallet.value = await GetWalletSummary();
|
||||
} catch (e) {
|
||||
wallet.value = { availableAmount: 0 };
|
||||
}
|
||||
try {
|
||||
await paymentsDictRef.loadDict();
|
||||
} catch (e) {
|
||||
// 支付方式加载失败时按无可用支付方式处理
|
||||
}
|
||||
}
|
||||
const paymentsDictRef = dict({
|
||||
async getData() {
|
||||
@@ -119,6 +129,23 @@ const expectedThirdPartyAmount = computed(() => {
|
||||
return Math.max(0, (durationSelected.value?.price || 0) - expectedRebateAmount.value);
|
||||
});
|
||||
|
||||
const noPaymentMethod = computed(() => {
|
||||
return paymentsDictRef.data.length === 0;
|
||||
});
|
||||
|
||||
const balanceInsufficient = computed(() => {
|
||||
const price = durationSelected.value?.price || 0;
|
||||
if (price <= 0) {
|
||||
return false;
|
||||
}
|
||||
const availableAmount = wallet.value?.availableAmount || 0;
|
||||
return availableAmount < price;
|
||||
});
|
||||
|
||||
const showBalanceInsufficientTip = computed(() => {
|
||||
return noPaymentMethod.value && balanceInsufficient.value;
|
||||
});
|
||||
|
||||
function amountToYuan(amount: number) {
|
||||
return util.amount.toYuan(amount || 0);
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ const labelCol = ref({
|
||||
},
|
||||
});
|
||||
const wrapperCol = ref({ span: 16 });
|
||||
const configForm: any = reactive({ type: props.plugin.fullName || props.plugin.name });
|
||||
const configForm: any = reactive({});
|
||||
|
||||
const showDict = dict({
|
||||
data: [
|
||||
@@ -306,7 +306,6 @@ provide("get:scope", () => {
|
||||
return getScope();
|
||||
});
|
||||
provide("get:plugin:type", () => {
|
||||
debugger;
|
||||
return props.plugin.pluginType;
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<template #header>
|
||||
<div class="title">
|
||||
套餐设置
|
||||
<span class="sub"> 需要<router-link :to="{ path: '/sys/settings', query: { tab: 'payment' } }">开启至少一种支付方式</router-link></span>
|
||||
<span class="sub"> 建议<router-link :to="{ path: '/sys/settings', query: { tab: 'payment' } }">开启至少一种支付方式</router-link></span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
<a-form-item label=" " :colon="false">
|
||||
<loading-button type="primary" html-type="button" :click="onClick">保存</loading-button>
|
||||
<div class="helper">需要 <router-link :to="{ path: '/sys/settings', query: { tab: 'payment' } }">开启至少一种支付方式</router-link></div>
|
||||
<div class="helper">建议 <router-link :to="{ path: '/sys/settings', query: { tab: 'payment' } }">开启至少一种支付方式</router-link></div>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import { request } from "/src/api/service";
|
||||
|
||||
const apiPrefix = "/sys/wallet";
|
||||
|
||||
export async function GetList(query: any) {
|
||||
return await request({
|
||||
url: apiPrefix + "/page",
|
||||
method: "post",
|
||||
data: query,
|
||||
});
|
||||
}
|
||||
|
||||
export async function Recharge(data: { userId: number; amount: number; remark?: string }) {
|
||||
return await request({
|
||||
url: apiPrefix + "/recharge",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
export async function GetWalletLogs(query: any) {
|
||||
return await request({
|
||||
url: apiPrefix + "/log/page",
|
||||
method: "post",
|
||||
data: query,
|
||||
});
|
||||
}
|
||||
|
||||
export async function GetSimpleUserByIds(ids: number[]) {
|
||||
return await request({
|
||||
url: "/sys/authority/user/getSimpleUserByIds",
|
||||
method: "post",
|
||||
data: { ids },
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
import { CreateCrudOptionsProps, CreateCrudOptionsRet, dict, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||
import { notification } from "ant-design-vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { util } from "/@/utils";
|
||||
import { useFormDialog } from "/@/use/use-dialog";
|
||||
import createCrudOptionsUser from "/@/views/sys/authority/user/crud";
|
||||
import PriceInput from "/@/views/sys/suite/product/price-input.vue";
|
||||
import * as api from "./api";
|
||||
|
||||
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||
const { openFormDialog } = useFormDialog();
|
||||
const router = useRouter();
|
||||
|
||||
const userDict = dict({
|
||||
async getNodesByValues(ids: number[]) {
|
||||
return await api.GetSimpleUserByIds(ids);
|
||||
},
|
||||
value: "id",
|
||||
label: "nickName",
|
||||
});
|
||||
|
||||
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
||||
return await api.GetList(query);
|
||||
};
|
||||
|
||||
function moneyColumn(title: string) {
|
||||
return {
|
||||
title,
|
||||
type: "number",
|
||||
column: {
|
||||
width: 120,
|
||||
component: {
|
||||
name: PriceInput,
|
||||
vModel: "modelValue",
|
||||
edit: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async function openRecharge(userId?: number) {
|
||||
await openFormDialog({
|
||||
title: "用户余额充值",
|
||||
wrapper: { width: 520 },
|
||||
initialForm: {
|
||||
userId: userId ?? null,
|
||||
amountYuan: null,
|
||||
remark: "",
|
||||
},
|
||||
columns: {
|
||||
userId: {
|
||||
title: "用户",
|
||||
type: "table-select",
|
||||
dict: userDict,
|
||||
form: {
|
||||
col: { span: 24 },
|
||||
rules: [{ required: true, message: "请选择用户" }],
|
||||
component: {
|
||||
disabled: userId != null,
|
||||
crossPage: true,
|
||||
multiple: false,
|
||||
select: {
|
||||
placeholder: "请选择用户",
|
||||
},
|
||||
createCrudOptions: createCrudOptionsUser,
|
||||
},
|
||||
},
|
||||
},
|
||||
amountYuan: {
|
||||
title: "充值金额",
|
||||
type: "number",
|
||||
form: {
|
||||
col: { span: 24 },
|
||||
rules: [{ required: true, message: "请输入充值金额" }],
|
||||
component: {
|
||||
name: "a-input-number",
|
||||
vModel: "value",
|
||||
min: 0,
|
||||
precision: 2,
|
||||
addonAfter: "元",
|
||||
style: { width: "100%" },
|
||||
},
|
||||
},
|
||||
},
|
||||
remark: {
|
||||
title: "备注",
|
||||
type: "text",
|
||||
form: {
|
||||
col: { span: 24 },
|
||||
helper: "选填",
|
||||
},
|
||||
},
|
||||
},
|
||||
async onSubmit(form: any) {
|
||||
await api.Recharge({
|
||||
userId: form.userId,
|
||||
amount: util.amount.toCent(form.amountYuan || 0),
|
||||
remark: form.remark,
|
||||
});
|
||||
await crudExpose.doRefresh();
|
||||
notification.success({ message: "充值成功" });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
crudOptions: {
|
||||
request: {
|
||||
pageRequest,
|
||||
},
|
||||
toolbar: { show: false },
|
||||
actionbar: {
|
||||
buttons: {
|
||||
add: { show: false },
|
||||
recharge: {
|
||||
text: "余额充值",
|
||||
type: "primary",
|
||||
click: () => openRecharge(),
|
||||
},
|
||||
log: {
|
||||
text: "余额变更记录",
|
||||
type: "primary",
|
||||
click: () => router.push("/sys/suite/wallet-log"),
|
||||
},
|
||||
},
|
||||
},
|
||||
rowHandle: {
|
||||
width: 220,
|
||||
fixed: "right",
|
||||
buttons: {
|
||||
view: { show: false },
|
||||
edit: { show: false },
|
||||
copy: { show: false },
|
||||
remove: { show: false },
|
||||
walletLog: {
|
||||
text: "余额变更记录",
|
||||
type: "link",
|
||||
click: ({ row }) => router.push({ path: "/sys/suite/wallet-log", query: { userId: row.userId } }),
|
||||
},
|
||||
recharge: {
|
||||
text: "充值",
|
||||
type: "link",
|
||||
click: ({ row }) => openRecharge(row.userId),
|
||||
},
|
||||
},
|
||||
},
|
||||
columns: {
|
||||
id: {
|
||||
title: "ID",
|
||||
type: "number",
|
||||
column: { width: 80 },
|
||||
form: { show: false },
|
||||
},
|
||||
userId: {
|
||||
title: "用户",
|
||||
type: "table-select",
|
||||
dict: userDict,
|
||||
search: { show: true, col: { span: 3 } },
|
||||
column: { width: 160 },
|
||||
form: {
|
||||
show: false,
|
||||
component: {
|
||||
crossPage: true,
|
||||
multiple: false,
|
||||
select: {
|
||||
placeholder: "点击选择用户",
|
||||
},
|
||||
createCrudOptions: createCrudOptionsUser,
|
||||
},
|
||||
},
|
||||
},
|
||||
availableAmount: moneyColumn("可用余额"),
|
||||
totalAmount: moneyColumn("总余额"),
|
||||
frozenAmount: moneyColumn("冻结余额"),
|
||||
totalIncomeAmount: moneyColumn("累计收入"),
|
||||
totalConsumedAmount: moneyColumn("累计消费"),
|
||||
totalWithdrawAmount: moneyColumn("累计提现"),
|
||||
createTime: {
|
||||
title: "创建时间",
|
||||
type: "datetime",
|
||||
form: { show: false },
|
||||
column: { sorter: true, width: 160 },
|
||||
},
|
||||
updateTime: {
|
||||
title: "更新时间",
|
||||
type: "datetime",
|
||||
form: { show: false },
|
||||
column: { width: 160 },
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<fs-page>
|
||||
<template #header>
|
||||
<div class="title">
|
||||
余额管理
|
||||
<span class="sub">管理用户余额,可给用户充值</span>
|
||||
</div>
|
||||
</template>
|
||||
<fs-crud ref="crudRef" v-bind="crudBinding"> </fs-crud>
|
||||
</fs-page>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { useFs } from "@fast-crud/fast-crud";
|
||||
import createCrudOptions from "./crud";
|
||||
import { useMounted } from "/@/use/use-mounted";
|
||||
|
||||
defineOptions({
|
||||
name: "SysWallet",
|
||||
});
|
||||
|
||||
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions });
|
||||
|
||||
// 页面打开后获取列表数据
|
||||
useMounted(async () => {
|
||||
await crudExpose.doRefresh();
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,100 @@
|
||||
import { CreateCrudOptionsRet, dict, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||
import { useRoute } from "vue-router";
|
||||
import { util } from "/@/utils";
|
||||
import createCrudOptionsUser from "/@/views/sys/authority/user/crud";
|
||||
import * as api from "../api";
|
||||
|
||||
function moneyText(amount: number) {
|
||||
const yuan = util.amount.toYuan(Math.abs(amount || 0));
|
||||
if (amount < 0) {
|
||||
return `-¥${yuan}`;
|
||||
}
|
||||
return `¥${yuan}`;
|
||||
}
|
||||
|
||||
export default function (): CreateCrudOptionsRet {
|
||||
const route = useRoute();
|
||||
const userIdFromQuery = route.query.userId ? Number(route.query.userId) : undefined;
|
||||
|
||||
const userDict = dict({
|
||||
async getNodesByValues(ids: number[]) {
|
||||
return await api.GetSimpleUserByIds(ids);
|
||||
},
|
||||
value: "id",
|
||||
label: "nickName",
|
||||
});
|
||||
|
||||
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
||||
return await api.GetWalletLogs(query);
|
||||
};
|
||||
|
||||
return {
|
||||
crudOptions: {
|
||||
request: { pageRequest },
|
||||
search: {
|
||||
initialForm: { userId: userIdFromQuery },
|
||||
},
|
||||
actionbar: { show: false },
|
||||
toolbar: { show: false },
|
||||
rowHandle: { show: false },
|
||||
columns: {
|
||||
createTime: { title: "时间", type: "datetime", column: { width: 180 } },
|
||||
userId: {
|
||||
title: "用户",
|
||||
type: "table-select",
|
||||
dict: userDict,
|
||||
search: { show: true, col: { span: 3 } },
|
||||
column: { width: 160 },
|
||||
form: {
|
||||
show: false,
|
||||
component: {
|
||||
crossPage: true,
|
||||
multiple: false,
|
||||
select: { placeholder: "点击选择用户" },
|
||||
createCrudOptions: createCrudOptionsUser,
|
||||
},
|
||||
},
|
||||
},
|
||||
type: {
|
||||
title: "类型",
|
||||
type: "dict-select",
|
||||
dict: dict({
|
||||
data: [
|
||||
{ label: "收益入账", value: "income", color: "success" },
|
||||
{ label: "余额抵扣", value: "consume", color: "default" },
|
||||
{ label: "提现扣减", value: "withdraw", color: "warning" },
|
||||
],
|
||||
}),
|
||||
search: { show: true, col: { span: 3 } },
|
||||
column: { width: 120 },
|
||||
},
|
||||
amount: {
|
||||
title: "变动金额",
|
||||
type: "number",
|
||||
column: {
|
||||
width: 120,
|
||||
cellRender({ value }) {
|
||||
const amount = Number(value || 0);
|
||||
return <span class={amount < 0 ? "text-green-500" : "text-red-500"}>{moneyText(amount)}</span>;
|
||||
},
|
||||
},
|
||||
},
|
||||
balanceAfter: {
|
||||
title: "变动后余额",
|
||||
type: "number",
|
||||
column: {
|
||||
width: 130,
|
||||
cellRender({ value }) {
|
||||
return <span class="text-red-500">{moneyText(Number(value || 0))}</span>;
|
||||
},
|
||||
},
|
||||
},
|
||||
remark: {
|
||||
title: "备注",
|
||||
type: "text",
|
||||
column: { minWidth: 220 },
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<fs-page>
|
||||
<template #header>
|
||||
<div class="title">
|
||||
{{ pageTitle }}
|
||||
<span class="sub">{{ pageSub }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<fs-crud ref="crudRef" v-bind="crudBinding"> </fs-crud>
|
||||
</fs-page>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import { useFs } from "@fast-crud/fast-crud";
|
||||
import createCrudOptions from "./crud";
|
||||
import { useMounted } from "/@/use/use-mounted";
|
||||
|
||||
defineOptions({
|
||||
name: "SysWalletLog",
|
||||
});
|
||||
|
||||
const route = useRoute();
|
||||
const isUserLog = computed(() => route.query.userId != null);
|
||||
const pageTitle = computed(() => {
|
||||
if (isUserLog.value) {
|
||||
return "用户余额变更记录";
|
||||
}
|
||||
return "余额变更记录";
|
||||
});
|
||||
const pageSub = computed(() => {
|
||||
if (isUserLog.value) {
|
||||
return "查看该用户的余额变更明细";
|
||||
}
|
||||
return "查看所有用户的余额变更明细";
|
||||
});
|
||||
|
||||
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions });
|
||||
|
||||
// 页面打开后获取列表数据
|
||||
useMounted(async () => {
|
||||
await crudExpose.doRefresh();
|
||||
});
|
||||
</script>
|
||||
@@ -3,6 +3,13 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.44.4](https://github.com/certd/certd/compare/v1.44.3...v1.44.4) (2026-09-12)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 新增余额管理,管理员充值功能 ([bded368](https://github.com/certd/certd/commit/bded368cbb8974b6937ae260e448c25fae5c33ad))
|
||||
* **acme-account-access:** AcmeAccount授权允许修改eab,重新生成account ([6a649aa](https://github.com/certd/certd/commit/6a649aaca083ccd3b517f7d676a58220aa33b37d))
|
||||
|
||||
## [1.44.3](https://github.com/certd/certd/compare/v1.44.2...v1.44.3) (2026-09-06)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -43,7 +43,7 @@ input:
|
||||
|
||||
return {
|
||||
component: {
|
||||
disabled: ctx.compute(({form})=> !!form.access?.account)
|
||||
disabled: ctx.compute(({form})=> !!form.access?.account && !form.access?.editAccount)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ input:
|
||||
return form.access?._needEAB === true;
|
||||
}),
|
||||
component: {
|
||||
disabled: ctx.compute(({form})=> !!form.access?.account)
|
||||
disabled: ctx.compute(({form})=> !!form.access?.account && !form.access?.editAccount)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ input:
|
||||
return form.access?._needEAB === true;
|
||||
}),
|
||||
component: {
|
||||
disabled: ctx.compute(({form})=> !!form.access?.account)
|
||||
disabled: ctx.compute(({form})=> !!form.access?.account && !form.access?.editAccount)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,9 @@ input:
|
||||
placeholder: api token,用户 API 令牌
|
||||
helper: |-
|
||||
前往 [获取API令牌](https://dash.cloudflare.com/profile/api-tokens),注意是令牌,不是密钥。
|
||||
token权限必须包含:[Zone区域-Zone区域-Edit编辑], [Zone区域-DNS-Edit编辑]
|
||||
token权限必须包含两条:
|
||||
[Zone区域-Zone区域-Edit编辑]
|
||||
[Zone区域-DNS-Edit编辑]
|
||||
required: true
|
||||
encrypt: true
|
||||
proxy:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/ui-server",
|
||||
"version": "1.44.3",
|
||||
"version": "1.44.4",
|
||||
"description": "fast-server base midway",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
@@ -43,20 +43,20 @@
|
||||
"lint1": "eslint --fix --ext .ts src"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/acme-client": "^1.44.3",
|
||||
"@certd/basic": "^1.44.3",
|
||||
"@certd/commercial-core": "^1.44.3",
|
||||
"@certd/acme-client": "^1.44.4",
|
||||
"@certd/basic": "^1.44.4",
|
||||
"@certd/commercial-core": "^1.44.4",
|
||||
"@certd/cv4pve-api-javascript": "^8.4.2",
|
||||
"@certd/jdcloud": "^1.44.3",
|
||||
"@certd/lib-huawei": "^1.44.3",
|
||||
"@certd/lib-k8s": "^1.44.3",
|
||||
"@certd/lib-server": "^1.44.3",
|
||||
"@certd/midway-flyway-js": "^1.44.3",
|
||||
"@certd/pipeline": "^1.44.3",
|
||||
"@certd/plugin-cert": "^1.44.3",
|
||||
"@certd/plugin-lib": "^1.44.3",
|
||||
"@certd/plugin-plus": "^1.44.3",
|
||||
"@certd/plus-core": "^1.44.3",
|
||||
"@certd/jdcloud": "^1.44.4",
|
||||
"@certd/lib-huawei": "^1.44.4",
|
||||
"@certd/lib-k8s": "^1.44.4",
|
||||
"@certd/lib-server": "^1.44.4",
|
||||
"@certd/midway-flyway-js": "^1.44.4",
|
||||
"@certd/pipeline": "^1.44.4",
|
||||
"@certd/plugin-cert": "^1.44.4",
|
||||
"@certd/plugin-lib": "^1.44.4",
|
||||
"@certd/plugin-plus": "^1.44.4",
|
||||
"@certd/plus-core": "^1.44.4",
|
||||
"@koa/cors": "^5.0.0",
|
||||
"@midwayjs/bootstrap": "3.20.11",
|
||||
"@midwayjs/cache": "3.14.0",
|
||||
|
||||
@@ -45,6 +45,7 @@ process.on("uncaughtException", error => {
|
||||
// setInterval(log, 200);
|
||||
// log()
|
||||
// }
|
||||
|
||||
// startHeapLog();
|
||||
|
||||
@Configuration({
|
||||
|
||||
@@ -659,26 +659,6 @@ export class PluginService extends BaseService<PluginEntity> {
|
||||
return this.builtInPluginService.getByType(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 表单可能直接提交对象形式的 dependPlugins(KvInput),落库前统一序列化为 YAML 字符串。
|
||||
*/
|
||||
// private normalizeDependPluginsParam(param: any) {
|
||||
// if (param.dependPlugins && typeof param.dependPlugins === "object" && !Array.isArray(param.dependPlugins)) {
|
||||
// param.dependPlugins = toDependPluginsYaml(param.dependPlugins);
|
||||
// }
|
||||
// }
|
||||
|
||||
// private normalizePluginYamlParam(param: any, field: "extra" | "dependPlugins") {
|
||||
// const value = param[field];
|
||||
// if (value && typeof value === "object" && !Array.isArray(value)) {
|
||||
// param[field] = yaml.dump(value, {
|
||||
// lineWidth: -1,
|
||||
// noRefs: true,
|
||||
// sortKeys: false,
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
private normalizeStorePluginAuthor(plugin: Record<string, any>) {
|
||||
const author = `${plugin.author || ""}`.trim();
|
||||
plugin.author = author;
|
||||
@@ -693,7 +673,6 @@ export class PluginService extends BaseService<PluginEntity> {
|
||||
* @param param 数据
|
||||
*/
|
||||
async add(param: any) {
|
||||
// this.normalizeDependPluginsParam(param);
|
||||
param.type = normalizePluginSourceType(param.type);
|
||||
if (param.type === "store") {
|
||||
this.normalizeStorePluginAuthor(param);
|
||||
@@ -849,7 +828,6 @@ export class PluginService extends BaseService<PluginEntity> {
|
||||
private attachOnlineInstallState(list: PluginEntity[], bindUserId?: number) {
|
||||
return list.map(item => {
|
||||
const record = this.toOnlinePluginBean(item);
|
||||
record.fullName = this.getOnlinePluginFullName(record);
|
||||
record.upgradeAvailable = record.installed ? isOnlinePluginUpgradeAvailable(record.version, record.latest) : false;
|
||||
record.editable = isAuthor(record, bindUserId);
|
||||
return record;
|
||||
@@ -903,6 +881,7 @@ export class PluginService extends BaseService<PluginEntity> {
|
||||
} else {
|
||||
storePlugin = await this.findOne({ where: { ...query, name: dependencyRef } });
|
||||
}
|
||||
|
||||
if (storePlugin) {
|
||||
return {
|
||||
plugin: storePlugin,
|
||||
@@ -1084,7 +1063,6 @@ export class PluginService extends BaseService<PluginEntity> {
|
||||
override: true,
|
||||
type: "store",
|
||||
});
|
||||
// await this.refreshOnlinePluginDownloadCount(res.fullName || fullName, res.plugin?.downloadCount);
|
||||
return {
|
||||
...importRes,
|
||||
fullName: res.fullName || fullName,
|
||||
@@ -1295,21 +1273,6 @@ export class PluginService extends BaseService<PluginEntity> {
|
||||
await this.sysSettingsService.saveSetting(setting);
|
||||
}
|
||||
|
||||
// private async refreshOnlinePluginDownloadCount(fullName: string, downloadCount?: number) {
|
||||
// if (!fullName || downloadCount == null) {
|
||||
// return;
|
||||
// }
|
||||
// await this.updateWhere(
|
||||
// {
|
||||
// type: "store",
|
||||
// fullName,
|
||||
// },
|
||||
// {
|
||||
// downloadCount,
|
||||
// }
|
||||
// );
|
||||
// }
|
||||
|
||||
async unRegisterById(id: any) {
|
||||
const item = await this.info(id);
|
||||
if (!item) {
|
||||
@@ -1354,19 +1317,11 @@ export class PluginService extends BaseService<PluginEntity> {
|
||||
if (!param?.id) {
|
||||
throw new Error("id 不能为空");
|
||||
}
|
||||
// this.normalizePluginYamlParam(param, "extra");
|
||||
// this.normalizeDependPluginsParam(param);
|
||||
await this.unRegisterById(param.id);
|
||||
const res = await super.update(param);
|
||||
await this.registerById(param.id);
|
||||
return res;
|
||||
}
|
||||
async compile(code: string) {
|
||||
const ts = await import("typescript");
|
||||
return ts.transpileModule(code, {
|
||||
compilerOptions: { module: ts.ModuleKind.ESNext },
|
||||
}).outputText;
|
||||
}
|
||||
|
||||
async importer(modulePath: string) {
|
||||
if (!modulePath) {
|
||||
@@ -1406,7 +1361,6 @@ export class PluginService extends BaseService<PluginEntity> {
|
||||
const plugin = info[0];
|
||||
try {
|
||||
const AsyncFunction = Object.getPrototypeOf(async () => {}).constructor;
|
||||
// const script = await this.compile(plugin.content);
|
||||
const script = plugin.content;
|
||||
const getPluginClass = new AsyncFunction("_ctx", script);
|
||||
const importer = this.importer.bind(this);
|
||||
@@ -1651,26 +1605,6 @@ export class PluginService extends BaseService<PluginEntity> {
|
||||
);
|
||||
}
|
||||
|
||||
isNewVersion(version: string, latestVersion: string) {
|
||||
if (!latestVersion) {
|
||||
return false;
|
||||
}
|
||||
if (latestVersion === version) {
|
||||
return false;
|
||||
}
|
||||
//分段比较
|
||||
const current = version.split(".");
|
||||
const latest = latestVersion.split(".");
|
||||
for (let i = 0; i < current.length; i++) {
|
||||
if (parseInt(latest[i]) > parseInt(current[i])) {
|
||||
return true;
|
||||
} else if (parseInt(latest[i]) < parseInt(current[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
async getPluginDefine(name: string) {
|
||||
return pluginRegistry.getDefine(name);
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ export class AcmeAccountAccess extends BaseAccess {
|
||||
mergeScript: `
|
||||
return {
|
||||
component: {
|
||||
disabled: ctx.compute(({form})=> !!form.access?.account)
|
||||
disabled: ctx.compute(({form})=> !!form.access?.account && !form.access?.editAccount)
|
||||
}
|
||||
}
|
||||
`,
|
||||
@@ -116,7 +116,7 @@ export class AcmeAccountAccess extends BaseAccess {
|
||||
return form.access?._needEAB === true;
|
||||
}),
|
||||
component: {
|
||||
disabled: ctx.compute(({form})=> !!form.access?.account)
|
||||
disabled: ctx.compute(({form})=> !!form.access?.account && !form.access?.editAccount)
|
||||
}
|
||||
}
|
||||
`,
|
||||
@@ -137,7 +137,7 @@ export class AcmeAccountAccess extends BaseAccess {
|
||||
return form.access?._needEAB === true;
|
||||
}),
|
||||
component: {
|
||||
disabled: ctx.compute(({form})=> !!form.access?.account)
|
||||
disabled: ctx.compute(({form})=> !!form.access?.account && !form.access?.editAccount)
|
||||
}
|
||||
}
|
||||
`,
|
||||
|
||||
@@ -19,7 +19,7 @@ export class CloudflareAccess extends BaseAccess {
|
||||
component: {
|
||||
placeholder: "api token,用户 API 令牌",
|
||||
},
|
||||
helper: "前往 [获取API令牌](https://dash.cloudflare.com/profile/api-tokens),注意是令牌,不是密钥。\n token权限必须包含:[Zone区域-Zone区域-Edit编辑], [Zone区域-DNS-Edit编辑]",
|
||||
helper: "前往 [获取API令牌](https://dash.cloudflare.com/profile/api-tokens),注意是令牌,不是密钥。\n token权限必须包含两条:\n[Zone区域-Zone区域-Edit编辑]\n[Zone区域-DNS-Edit编辑]",
|
||||
required: true,
|
||||
encrypt: true,
|
||||
})
|
||||
|
||||
@@ -212,10 +212,7 @@ export class FastlyAccess extends BaseAccess {
|
||||
this.ctx.logger.info(`Fastly 已存在相同证书,复用 certId: ${existingId}`);
|
||||
return existingId;
|
||||
}
|
||||
throw new Error(
|
||||
`Fastly 证书已存在:${message}。` +
|
||||
"该证书可能此前已上传。请在【Fastly-上传证书到Fastly】任务中填写该证书ID以走更新(PATCH)流程。"
|
||||
);
|
||||
throw new Error(`Fastly 证书已存在:${message}。` + "该证书可能此前已上传。请在【Fastly-上传证书到Fastly】任务中填写该证书ID以走更新(PATCH)流程。");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,11 +283,7 @@ export class FastlyAccess extends BaseAccess {
|
||||
private async findActivation(configurationId: string, domainId: string): Promise<any | undefined> {
|
||||
// encodeURIComponent 按规范保留 `*`,但 Fastly 过滤条件要求通配符编码为 `%2A`。
|
||||
const encodedDomainId = encodeURIComponent(domainId).replace(/\*/g, "%2A");
|
||||
const body = await this.doRequestApi(
|
||||
`/tls/activations?filter[tls_domain.id]=${encodedDomainId}&page[size]=100`,
|
||||
null,
|
||||
"get"
|
||||
);
|
||||
const body = await this.doRequestApi(`/tls/activations?filter[tls_domain.id]=${encodedDomainId}&page[size]=100`, null, "get");
|
||||
const items: any[] = Array.isArray(body?.data) ? body.data : [];
|
||||
if (items.length === 0) {
|
||||
return undefined;
|
||||
@@ -308,11 +301,7 @@ export class FastlyAccess extends BaseAccess {
|
||||
private async ensurePrivateKey(keyPem: string, name?: string): Promise<string> {
|
||||
this.ctx.logger.info("开始上传私钥到 Fastly...");
|
||||
try {
|
||||
const keyRes = await this.doRequestApi(
|
||||
"/tls/private_keys",
|
||||
{ data: { type: "tls_private_key", attributes: { key: keyPem, ...(name && { name }) } } },
|
||||
"post"
|
||||
);
|
||||
const keyRes = await this.doRequestApi("/tls/private_keys", { data: { type: "tls_private_key", attributes: { key: keyPem, ...(name && { name }) } } }, "post");
|
||||
const id = keyRes?.data?.id;
|
||||
if (!id) {
|
||||
throw new Error("Fastly 私钥上传失败,未获取到 private key ID");
|
||||
@@ -337,11 +326,7 @@ export class FastlyAccess extends BaseAccess {
|
||||
return matched[0].id;
|
||||
}
|
||||
}
|
||||
throw new Error(
|
||||
`Fastly 私钥已存在但无法确定其ID:${message}。` +
|
||||
"请在【Fastly-上传证书到Fastly】任务中填写已有证书ID以走更新(PATCH)流程," +
|
||||
"或在 Fastly 控制台删除该孤立私钥后重试。"
|
||||
);
|
||||
throw new Error(`Fastly 私钥已存在但无法确定其ID:${message}。` + "请在【Fastly-上传证书到Fastly】任务中填写已有证书ID以走更新(PATCH)流程," + "或在 Fastly 控制台删除该孤立私钥后重试。");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
22:05
|
||||
23:51
|
||||
|
||||
@@ -1 +1 @@
|
||||
22:16
|
||||
00:07
|
||||
|
||||
Reference in New Issue
Block a user