mirror of
https://github.com/certd/certd.git
synced 2026-07-15 01:58:56 +08:00
Compare commits
23 Commits
v1.40.0
...
85c633fddf
| Author | SHA1 | Date | |
|---|---|---|---|
| 85c633fddf | |||
| cb08e061d2 | |||
| 9bf7ca400f | |||
| 9f75e30af3 | |||
| 3f0243ba9a | |||
| 1a9b367c9d | |||
| 73996f055b | |||
| 57ea2f317a | |||
| c66c05b442 | |||
| 6450d2bd56 | |||
| b5368d120d | |||
| f9a310b6c3 | |||
| 1bdcfe646f | |||
| a88d14a3bd | |||
| bdb3d09c09 | |||
| 667e7b185b | |||
| 8483ee0d41 | |||
| c3baaf3ac7 | |||
| c63745d1ba | |||
| 59b9ffadd0 | |||
| d131ea3790 | |||
| b849d34be5 | |||
| 58fc9a551c |
@@ -0,0 +1,55 @@
|
||||
---
|
||||
name: fast-crud-page-dev
|
||||
description: 用于开发或重构 Certd 前端列表管理、后台管理、记录查询、CRUD 表格页面,优先使用 Fast Crud(@fast-crud/fast-crud、fs-crud、useFs、createCrudOptions)实现。当用户要求列表页、管理页、审核页、记录页或表格 CRUD 页面时触发。
|
||||
version: 1.0.0
|
||||
---
|
||||
|
||||
# Fast Crud 页面开发技能
|
||||
|
||||
## 角色定义
|
||||
|
||||
你是一名 Certd 前端列表管理页面开发专家,熟悉 Vue 3、Ant Design Vue、Fast Crud 和本仓库现有页面拆分方式。你的目标是让管理页面保持统一的表格、搜索、分页、操作列和弹窗体验。
|
||||
|
||||
## 核心规则
|
||||
|
||||
- 列表管理、后台管理、记录查询、审核记录、CRUD 表格类页面,默认优先使用 Fast Crud 实现。
|
||||
- 只有轻量只读展示、强交互自定义界面、复杂可视化或已有页面模式明确不适合 Fast Crud 时,才手写 `a-table` / 自定义列表,并在回复中说明原因。
|
||||
- 设置表单、概览卡片、向导流程等非列表主体可以保留自定义 Vue;如果同一功能同时包含设置和列表,优先拆成独立页面,或把设置放入对话框。
|
||||
|
||||
## 推荐文件拆分
|
||||
|
||||
- `api.ts`:封装接口请求,保持页面和 CRUD 配置里不直接散落 URL。
|
||||
- `crud.tsx` / `crud-*.tsx`:导出 `createCrudOptions`,集中定义请求映射、搜索项、列、表单、操作列、工具栏和字典。
|
||||
- `index.vue`:承载 `fs-page`、`fs-crud`、页面头部、弹窗和生命周期,使用 `useFs({ createCrudOptions, context })` 创建绑定。
|
||||
|
||||
## 实现流程
|
||||
|
||||
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()`。
|
||||
3. 在 `crud.tsx` 中配置 `request.pageRequest`、`columns`、`search`、`form`、`rowHandle`、`actionbar`、`toolbar` 等,接口分页参数和返回值按现有页面适配。
|
||||
4. 操作按钮优先放在 Fast Crud 的 `rowHandle.buttons` 或 `actionbar.buttons` 中;审核、保存设置、批量操作等复杂交互可通过 `context` 调用 `index.vue` 中的方法。
|
||||
5. 金额、状态、时间、枚举等字段优先复用项目已有组件、字典和格式化工具;避免在模板里重复堆格式化逻辑。
|
||||
6. 表格查询条件使用 Fast Crud 的 `search` 配置;新增/编辑表单使用 Fast Crud 的 `form` 配置,复杂设置项可以用 Ant Design Vue 对话框承载。
|
||||
7. 删除、审核通过、拒绝等危险操作必须保留确认弹窗和错误提示,成功后刷新当前 CRUD 列表。
|
||||
8. 对话框里只做纯确认时可以使用 `Modal.confirm`;只要需要字段输入、表单校验或提交字段,统一使用 `useFormDialog` / `openFormDialog`,不要在 `Modal.confirm` 的 `content` 里手写输入框。
|
||||
|
||||
## 布局高度
|
||||
|
||||
- Fast Crud 表格依赖外部容器高度计算。虽然表格本身有默认约 200px 高度,但页面内嵌 `fs-crud` 时,为了获得稳定可用的列表区域,必须让外层容器提供明确高度或剩余高度。
|
||||
- 独立列表页通常可直接让 `fs-page` / 页面内容区撑满;如果表格嵌在 tabs、详情页、上下分区或弹窗里,要从页面根容器到 `fs-crud` 建立完整的 flex 高度链路:父容器 `display: flex; flex-direction: column; min-height: 0`,中间内容区和 tab pane 使用 `flex: 1; min-height: 0`,`fs-crud` 本身也使用 `flex: 1; min-height: 0`。
|
||||
- 有固定操作栏、统计区、说明区时,这些区域应 `flex: none`,把剩余空间交给表格区域。
|
||||
- 修改嵌入式 Fast Crud 页面后,要检查空数据、少量数据和多页数据时表格高度、分页器和空状态是否仍在预期区域内。
|
||||
|
||||
## 代码习惯
|
||||
|
||||
- 页面命名、API 命名、权限标识和路由结构要贴近同目录已有页面。
|
||||
- CRUD 配置中不要写大段业务流程;复杂逻辑放回 `index.vue` 方法或 `api.ts`。
|
||||
- 能用 `dict`、`compute`、`valueBuilder`、`valueResolve`、`component` 配置表达的表格/表单行为,不要改成手写模板。
|
||||
- 保持列表页密度和操作入口克制,不要做营销式布局、嵌套卡片或大块说明文字。
|
||||
- 如果页面有“设置 + 列表”,管理端优先拆成两个路由页面;用户端提现设置这类低频配置优先使用对话框保存。
|
||||
|
||||
## 验证方式
|
||||
|
||||
- 前端改动后,只对本次改动的 Vue / TS / TSX / locale 文件运行项目现有 Prettier / ESLint。
|
||||
- 不运行 `vue-tsc` / `pnpm tsc`,因为当前依赖组合下 `vue-tsc` 已知会抛内部错误。
|
||||
- 若只是新增或修改本 skill / 文档,不需要运行前端格式化和测试。
|
||||
@@ -35,6 +35,8 @@ Certd 是一个支持私有化部署的 SSL/TLS 证书自动化管理平台。
|
||||
- `packages/ui/certd-server/`:后端服务
|
||||
- `packages/ui/certd-client/`:前端 Web 管理台
|
||||
|
||||
`packages/pro/` 是独立 Git 工作区,使用 `packages/pro/.git` 管理。根仓库的 `git status` / `git diff` 默认看不到这里的实际改动;修改商业版代码后,要在 `packages/pro` 目录内单独执行 `git status` / `git diff` 检查。
|
||||
|
||||
## 后端
|
||||
|
||||
主要后端包:`packages/ui/certd-server`。
|
||||
@@ -108,6 +110,14 @@ Certd 是一个支持私有化部署的 SSL/TLS 证书自动化管理平台。
|
||||
- 不要运行前端 `pnpm tsc` / `vue-tsc`:当前依赖组合中 `vue-tsc@1.8.27` 会直接抛内部错误 `Search string not found: "/supportedTSExtensions = .*(?=;)/"`,不是有效的项目类型检查结果。
|
||||
- 前端暂不跑单元测试;当前 `test:unit` 只是占位脚本
|
||||
|
||||
前端列表管理页面约定:
|
||||
|
||||
- 列表管理、后台管理、记录查询、CRUD 表格类页面,默认优先使用 Fast Crud(`@fast-crud/fast-crud`、`fs-crud`、`useFs`、`createCrudOptions`)实现。
|
||||
- 只有轻量只读展示、强交互自定义界面或已有页面模式明确不适合 Fast Crud 时,才手写 `a-table` / 自定义列表,并在回复中说明原因。
|
||||
- 开发或重构这类页面前,先读取 `.trae/skills/fast-crud-page-dev/SKILL.md`,按仓库内 Fast Crud 页面拆分与验证方式实现。
|
||||
- 前端对话框里只做纯确认时可以使用 `Modal.confirm`;只要对话框里有字段输入、表单校验或提交字段,统一使用 `useFormDialog` / `openFormDialog`,不要在 `Modal.confirm` 的 `content` 里手写输入框。
|
||||
- 页面内嵌 Fast Crud 表格时,要显式给外层容器稳定高度或 `flex: 1; min-height: 0` 的撑满链路;Fast Crud 依赖外部元素高度,不能只依赖表格默认高度。
|
||||
|
||||
## 流水线与插件模型
|
||||
|
||||
项目最关键的架构概念是证书流水线。
|
||||
@@ -168,6 +178,7 @@ Certd 是一个支持私有化部署的 SSL/TLS 证书自动化管理平台。
|
||||
- `packages/ui/certd-server/data/`、`logs/`、生成的 metadata/dist 等通常视为运行时或构建产物,除非任务明确要求处理它们。
|
||||
- 注意本地数据和配置里可能包含凭据、证书材料等敏感信息。
|
||||
- 本仓库代码注释优先使用中文,尤其是解释业务规则、兼容逻辑、协议细节和隐藏风险时;除非文件已有明确英文注释风格或引用外部英文术语,否则不要新增英文说明性注释。
|
||||
- 代码可读性优先于短写法。遇到包含业务分支的复杂三元表达式、内联对象、链式调用或条件组合时,优先拆成命名清晰的中间变量、独立分支或小函数,让读代码的人能一眼看出业务意图;不要为了少写几行把逻辑压成难读的一坨。
|
||||
|
||||
## 插件开发技能
|
||||
|
||||
@@ -182,6 +193,7 @@ Certd 是一个支持私有化部署的 SSL/TLS 证书自动化管理平台。
|
||||
|
||||
- `access-plugin-dev`:开发 Access 授权插件
|
||||
- `dns-provider-dev`:开发 DNS Provider 插件
|
||||
- `fast-crud-page-dev`:开发或重构前端 Fast Crud 列表管理页面
|
||||
- `task-plugin-dev`:开发 Task 部署任务插件
|
||||
- `plugin-converter`:将插件转换为 YAML 配置
|
||||
|
||||
|
||||
@@ -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.40.1](https://github.com/certd/certd/compare/v1.40.0...v1.40.1) (2026-05-18)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 固化华为云sdk版本,避免华为云调用报错 ([59b9ffa](https://github.com/certd/certd/commit/59b9ffadd05faf3982151c48f8d83cbd97419865))
|
||||
* **email-service:** 优化商业版测试邮件内容中带的url链接 ([667e7b1](https://github.com/certd/certd/commit/667e7b185bf26558972be01720872f48352b5876))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 商业版支持限制泛域名数量 ([c63745d](https://github.com/certd/certd/commit/c63745d1ba30904428ba6b13ab0785298baa5cae))
|
||||
* **suite:** 商业版用户已购套餐支持修改 ([bdb3d09](https://github.com/certd/certd/commit/bdb3d09c09fc73e7e5e3401f6ef5588bf8ad5088))
|
||||
|
||||
# [1.40.0](https://github.com/certd/certd/compare/v1.39.16...v1.40.0) (2026-05-14)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -34,7 +34,7 @@ Certd® 是一个免费的全自动证书管理系统,让你的网站证书永
|
||||
* **多种通知方式**: 邮件通知、webhook通知、企微、钉钉、飞书、anpush等多种通知方式
|
||||
* **私有化部署**: 数据保存本地,安装简单快捷,镜像由Github Actions构建,过程公开透明
|
||||
* **多重安全保障**: 授权加密,站点隐藏,2FA,密码防爆破等多重安全保障
|
||||
* **多数据库支持**:支持SQLite、PostgreSQL、MySQL
|
||||
* **多数据库支持**:支持SQLite、PostgreSQL、MySQL、MariaDB
|
||||
* **开放接口支持**: 提供RESTful API接口,方便集成到其他系统
|
||||
* **站点证书监控**: 定时监控网站证书的过期时间
|
||||
* **多用户管理**: 用户可以管理自己的证书流水线
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ This project not only supports automated certificate application but also automa
|
||||
* Multiple notification methods, including email, webhook, WeChat Work, DingTalk, Lark, and anpush.
|
||||
* On-premises deployment, local data storage, simple and quick installation. Images are built by Github Actions, with a transparent process.
|
||||
* Multiple security measures, including authorization encryption, site hiding, 2FA, and password brute-force protection.
|
||||
* Supports multiple databases such as SQLite, PostgreSQL, and MySQL.
|
||||
* Supports multiple databases such as SQLite, PostgreSQL, MySQL, and MariaDB.
|
||||
* Open API support.
|
||||
* Site certificate monitoring.
|
||||
* Multi-user management.
|
||||
|
||||
@@ -3,6 +3,37 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.40.1](https://github.com/certd/certd/compare/v1.40.0...v1.40.1) (2026-05-18)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 固化华为云sdk版本,避免华为云调用报错 ([59b9ffa](https://github.com/certd/certd/commit/59b9ffadd05faf3982151c48f8d83cbd97419865))
|
||||
* **email-service:** 优化商业版测试邮件内容中带的url链接 ([667e7b1](https://github.com/certd/certd/commit/667e7b185bf26558972be01720872f48352b5876))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 商业版支持限制泛域名数量 ([c63745d](https://github.com/certd/certd/commit/c63745d1ba30904428ba6b13ab0785298baa5cae))
|
||||
* **suite:** 商业版用户已购套餐支持修改 ([bdb3d09](https://github.com/certd/certd/commit/bdb3d09c09fc73e7e5e3401f6ef5588bf8ad5088))
|
||||
|
||||
# [1.40.0](https://github.com/certd/certd/compare/v1.39.16...v1.40.0) (2026-05-14)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复第三方登录丢失state时无法在用户信息页面绑定第三方账号的bug ([45dedf5](https://github.com/certd/certd/commit/45dedf5bc779fea852e1f33dda4f31db2765633c))
|
||||
* 修复群晖授权没有显示设备id输入框的bug ([2f172b5](https://github.com/certd/certd/commit/2f172b56e9411303ca15138d827bdb9bafdae4d1))
|
||||
* 修复自动注册后没有跳转到控制台的bug ([4681ec9](https://github.com/certd/certd/commit/4681ec90088a3eb665427b2ac4047ec5ccefd7b3))
|
||||
* 修复clogin登录丢失state问题 ([22f5cfc](https://github.com/certd/certd/commit/22f5cfcfd8462ca74128329eefb3f48b3ee0b7ea))
|
||||
* 修复clogin多选类型登录失败的bug ([9f878a3](https://github.com/certd/certd/commit/9f878a353cd49b7b10bb0a95610ad236bc920dd2))
|
||||
|
||||
### Features
|
||||
|
||||
* 彩虹登录支持选择多种登录方式 ([7aa0c7e](https://github.com/certd/certd/commit/7aa0c7e491fe660abb62e68792ff5474f19bd5b8))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 第三方登录自动注册的用户支持设置初始化密码 ([a815d02](https://github.com/certd/certd/commit/a815d0245b97efbb948b33d6fc9d49862ce06889))
|
||||
* 头像增加缓存时间 ([7015b1b](https://github.com/certd/certd/commit/7015b1b232602e5168a3eb8bee6d7f1776ae1e74))
|
||||
|
||||
## [1.39.16](https://github.com/certd/certd/compare/v1.39.15...v1.39.16) (2026-05-13)
|
||||
|
||||
**Note:** Version bump only for package root
|
||||
|
||||
+1
-1
@@ -9,5 +9,5 @@
|
||||
}
|
||||
},
|
||||
"npmClient": "pnpm",
|
||||
"version": "1.40.0"
|
||||
"version": "1.40.1"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.40.1](https://github.com/publishlab/node-acme-client/compare/v1.40.0...v1.40.1) (2026-05-18)
|
||||
|
||||
**Note:** Version bump only for package @certd/acme-client
|
||||
|
||||
# [1.40.0](https://github.com/publishlab/node-acme-client/compare/v1.39.16...v1.40.0) (2026-05-14)
|
||||
|
||||
**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.40.0",
|
||||
"version": "1.40.1",
|
||||
"type": "module",
|
||||
"module": "./dist/index.js",
|
||||
"main": "./dist/index.js",
|
||||
@@ -18,7 +18,7 @@
|
||||
"types"
|
||||
],
|
||||
"dependencies": {
|
||||
"@certd/basic": "^1.40.0",
|
||||
"@certd/basic": "^1.40.1",
|
||||
"@peculiar/x509": "^1.11.0",
|
||||
"asn1js": "^3.0.5",
|
||||
"axios": "^1.9.0",
|
||||
@@ -50,7 +50,7 @@
|
||||
},
|
||||
"scripts": {
|
||||
"before-build": "node -e \"const fs=require('fs');fs.rmSync('dist',{recursive:true,force:true});fs.rmSync('tsconfig.tsbuildinfo',{force:true});\"",
|
||||
"build": "npm run before-build && tsc --skipLibCheck",
|
||||
"build": "npm run before-build && tsc -p tsconfig.build.json --skipLibCheck",
|
||||
"build-docs": "jsdoc2md dist/client.js > docs/client.md && jsdoc2md dist/crypto/index.js > docs/crypto.md && jsdoc2md dist/crypto/forge.js > docs/forge.md",
|
||||
"lint": "eslint \"src/**/*.ts\" \"types/**/*.ts\"",
|
||||
"lint-types": "tsd --files \"types/index.test-d.ts\"",
|
||||
@@ -76,5 +76,5 @@
|
||||
"bugs": {
|
||||
"url": "https://github.com/publishlab/node-acme-client/issues"
|
||||
},
|
||||
"gitHead": "1c6dc169ac04fd09ef94404a912a15cbb17e1452"
|
||||
"gitHead": "73996f055bbff996ee776e7788e5a5cb500fc197"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"sourceMap": false,
|
||||
"inlineSourceMap": false
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
"moduleResolution": "node",
|
||||
"esModuleInterop": true,
|
||||
"inlineSourceMap": false,
|
||||
"sourceMap": false,
|
||||
"sourceMap": true,
|
||||
"noImplicitThis": false,
|
||||
"noUnusedLocals": false,
|
||||
"stripInternal": true,
|
||||
|
||||
@@ -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.40.1](https://github.com/certd/certd/compare/v1.40.0...v1.40.1) (2026-05-18)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
# [1.40.0](https://github.com/certd/certd/compare/v1.39.16...v1.40.0) (2026-05-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/basic
|
||||
|
||||
@@ -1 +1 @@
|
||||
00:44
|
||||
00:34
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/basic",
|
||||
"private": false,
|
||||
"version": "1.40.0",
|
||||
"version": "1.40.1",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -9,7 +9,7 @@
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"before-build": "rimraf dist && rimraf tsconfig.tsbuildinfo && rimraf .rollup.cache",
|
||||
"build": "npm run before-build && tsc --skipLibCheck",
|
||||
"build": "npm run before-build && tsc -p tsconfig.build.json --skipLibCheck",
|
||||
"dev-build": "npm run build",
|
||||
"preview": "vite preview",
|
||||
"test": "mocha --loader=ts-node/esm",
|
||||
@@ -52,5 +52,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "1c6dc169ac04fd09ef94404a912a15cbb17e1452"
|
||||
"gitHead": "73996f055bbff996ee776e7788e5a5cb500fc197"
|
||||
}
|
||||
|
||||
@@ -11,9 +11,10 @@ export class LocalCache<V = any> {
|
||||
cache: Map<string, { value: V; expiresAt: number }>;
|
||||
constructor(opts: { clearInterval?: number } = {}) {
|
||||
this.cache = new Map();
|
||||
setInterval(() => {
|
||||
const intervalId = setInterval(() => {
|
||||
this.clearExpires();
|
||||
}, opts.clearInterval ?? 5 * 60 * 1000);
|
||||
intervalId.unref?.();
|
||||
}
|
||||
|
||||
get(key: string): V | undefined {
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"sourceMap": false,
|
||||
"inlineSourceMap": false
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"inlineSourceMap": false,
|
||||
"sourceMap": false,
|
||||
"sourceMap": true,
|
||||
"noImplicitThis": true,
|
||||
"noUnusedLocals": true,
|
||||
"stripInternal": true,
|
||||
|
||||
@@ -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.40.1](https://github.com/certd/certd/compare/v1.40.0...v1.40.1) (2026-05-18)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
# [1.40.0](https://github.com/certd/certd/compare/v1.39.16...v1.40.0) (2026-05-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/pipeline
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/pipeline",
|
||||
"private": false,
|
||||
"version": "1.40.0",
|
||||
"version": "1.40.1",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -9,7 +9,7 @@
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"before-build": "rimraf dist && rimraf tsconfig.tsbuildinfo && rimraf .rollup.cache",
|
||||
"build": "npm run before-build && tsc --skipLibCheck",
|
||||
"build": "npm run before-build && tsc -p tsconfig.build.json --skipLibCheck",
|
||||
"dev-build": "npm run build",
|
||||
"build3": "rollup -c",
|
||||
"preview": "vite preview",
|
||||
@@ -19,8 +19,8 @@
|
||||
"compile": "tsc --skipLibCheck --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/basic": "^1.40.0",
|
||||
"@certd/plus-core": "^1.40.0",
|
||||
"@certd/basic": "^1.40.1",
|
||||
"@certd/plus-core": "^1.40.1",
|
||||
"dayjs": "^1.11.7",
|
||||
"lodash-es": "^4.17.21",
|
||||
"reflect-metadata": "^0.1.13"
|
||||
@@ -49,5 +49,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "1c6dc169ac04fd09ef94404a912a15cbb17e1452"
|
||||
"gitHead": "73996f055bbff996ee776e7788e5a5cb500fc197"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"sourceMap": false,
|
||||
"inlineSourceMap": false
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"inlineSourceMap": false,
|
||||
"sourceMap": false,
|
||||
"sourceMap": true,
|
||||
"noImplicitThis": true,
|
||||
"noUnusedLocals": true,
|
||||
"importHelpers": true,
|
||||
|
||||
@@ -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.40.1](https://github.com/certd/certd/compare/v1.40.0...v1.40.1) (2026-05-18)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
# [1.40.0](https://github.com/certd/certd/compare/v1.39.16...v1.40.0) (2026-05-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-huawei
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-huawei",
|
||||
"private": false,
|
||||
"version": "1.40.0",
|
||||
"version": "1.40.1",
|
||||
"main": "./dist/bundle.js",
|
||||
"module": "./dist/bundle.js",
|
||||
"types": "./dist/d/index.d.ts",
|
||||
@@ -27,5 +27,5 @@
|
||||
"prettier": "^2.8.8",
|
||||
"tslib": "^2.8.1"
|
||||
},
|
||||
"gitHead": "bae5a04dcc0a679c290a9805c3ac4a6020eb6ec0"
|
||||
"gitHead": "73996f055bbff996ee776e7788e5a5cb500fc197"
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ module.exports = {
|
||||
output: {
|
||||
file: "dist/bundle.js",
|
||||
format: "cjs",
|
||||
sourcemap: false,
|
||||
},
|
||||
plugins: [
|
||||
// 解析第三方依赖
|
||||
@@ -22,10 +23,13 @@ module.exports = {
|
||||
// ],
|
||||
}),
|
||||
Typescript({
|
||||
tsconfig: "./tsconfig.build.json",
|
||||
target: "esnext",
|
||||
rootDir: "src",
|
||||
declaration: true,
|
||||
declarationDir: "dist/d",
|
||||
sourceMap: false,
|
||||
inlineSourceMap: false,
|
||||
exclude: ["./node_modules/**", "./src/**/*.vue", "./src/**/*.spec.ts"],
|
||||
allowSyntheticDefaultImports: true,
|
||||
}),
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"sourceMap": false,
|
||||
"inlineSourceMap": false
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@
|
||||
"composite": false,
|
||||
"useDefineForClassFields": true,
|
||||
"strict": false,
|
||||
"sourceMap": false,
|
||||
"sourceMap": true,
|
||||
"inlineSourceMap": false,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": false,
|
||||
|
||||
@@ -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.40.1](https://github.com/certd/certd/compare/v1.40.0...v1.40.1) (2026-05-18)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
# [1.40.0](https://github.com/certd/certd/compare/v1.39.16...v1.40.0) (2026-05-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-iframe
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-iframe",
|
||||
"private": false,
|
||||
"version": "1.40.0",
|
||||
"version": "1.40.1",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -9,7 +9,7 @@
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"before-build": "rimraf dist && rimraf tsconfig.tsbuildinfo && rimraf .rollup.cache",
|
||||
"build": "npm run before-build && tsc --skipLibCheck",
|
||||
"build": "npm run before-build && tsc -p tsconfig.build.json --skipLibCheck",
|
||||
"dev-build": "npm run build",
|
||||
"build3": "rollup -c",
|
||||
"build2": "vue-tsc --noEmit && vite build",
|
||||
@@ -34,5 +34,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "bae5a04dcc0a679c290a9805c3ac4a6020eb6ec0"
|
||||
"gitHead": "73996f055bbff996ee776e7788e5a5cb500fc197"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"sourceMap": false,
|
||||
"inlineSourceMap": false
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"inlineSourceMap":false,
|
||||
"sourceMap": true,
|
||||
"noImplicitThis": true,
|
||||
"noUnusedLocals": true,
|
||||
"stripInternal": true,
|
||||
@@ -22,7 +23,6 @@
|
||||
"composite": false,
|
||||
"useDefineForClassFields": true,
|
||||
"strict": false,
|
||||
// "sourceMap": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"lib": ["ESNext", "DOM"],
|
||||
|
||||
@@ -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.40.1](https://github.com/certd/certd/compare/v1.40.0...v1.40.1) (2026-05-18)
|
||||
|
||||
**Note:** Version bump only for package @certd/jdcloud
|
||||
|
||||
# [1.40.0](https://github.com/certd/certd/compare/v1.39.16...v1.40.0) (2026-05-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/jdcloud
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
{
|
||||
"name": "@certd/jdcloud",
|
||||
"version": "1.40.0",
|
||||
"version": "1.40.1",
|
||||
"description": "jdcloud openApi sdk",
|
||||
"main": "./dist/bundle.js",
|
||||
"module": "./dist/bundle.js",
|
||||
"types": "./dist/d/index.d.ts",
|
||||
"scripts": {
|
||||
"build": "rollup -c ",
|
||||
"before-build": "node -e \"const fs=require('fs');fs.rmSync('dist',{recursive:true,force:true});fs.rmSync('tsconfig.tsbuildinfo',{force:true});fs.rmSync('.rollup.cache',{recursive:true,force:true});\"",
|
||||
"build": "npm run before-build && rollup -c ",
|
||||
"dev-build": "npm run build",
|
||||
"test:unit": "cross-env NODE_ENV=unittest echo no unit tests",
|
||||
"pub": "npm publish"
|
||||
@@ -58,5 +59,5 @@
|
||||
"fetch"
|
||||
]
|
||||
},
|
||||
"gitHead": "bae5a04dcc0a679c290a9805c3ac4a6020eb6ec0"
|
||||
"gitHead": "73996f055bbff996ee776e7788e5a5cb500fc197"
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ module.exports = {
|
||||
output: {
|
||||
file: "dist/bundle.js",
|
||||
format: "cjs",
|
||||
sourcemap: false,
|
||||
},
|
||||
plugins: [
|
||||
// 解析第三方依赖
|
||||
@@ -22,10 +23,13 @@ module.exports = {
|
||||
// ],
|
||||
}),
|
||||
Typescript({
|
||||
tsconfig: "./tsconfig.build.json",
|
||||
target: "esnext",
|
||||
rootDir: "src",
|
||||
declaration: true,
|
||||
declarationDir: "dist/d",
|
||||
sourceMap: false,
|
||||
inlineSourceMap: false,
|
||||
exclude: ["./node_modules/**", "./src/**/*.vue", "./src/**/*.spec.ts"],
|
||||
allowSyntheticDefaultImports: true,
|
||||
}),
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"sourceMap": false,
|
||||
"inlineSourceMap": false
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@
|
||||
"composite": false,
|
||||
"useDefineForClassFields": true,
|
||||
"strict": false,
|
||||
"sourceMap": false,
|
||||
"sourceMap": true,
|
||||
"inlineSourceMap": false,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": false,
|
||||
|
||||
@@ -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.40.1](https://github.com/certd/certd/compare/v1.40.0...v1.40.1) (2026-05-18)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
# [1.40.0](https://github.com/certd/certd/compare/v1.39.16...v1.40.0) (2026-05-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-k8s
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@certd/lib-k8s",
|
||||
"private": false,
|
||||
"version": "1.40.0",
|
||||
"version": "1.40.1",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
@@ -9,7 +9,7 @@
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"before-build": "rimraf dist && rimraf tsconfig.tsbuildinfo && rimraf .rollup.cache",
|
||||
"build": "npm run before-build && tsc --skipLibCheck",
|
||||
"build": "npm run before-build && tsc -p tsconfig.build.json --skipLibCheck",
|
||||
"dev-build": "npm run build",
|
||||
"build3": "rollup -c",
|
||||
"build2": "vue-tsc --noEmit && vite build",
|
||||
@@ -19,7 +19,7 @@
|
||||
"compile": "tsc --skipLibCheck --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/basic": "^1.40.0",
|
||||
"@certd/basic": "^1.40.1",
|
||||
"@kubernetes/client-node": "0.21.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -36,5 +36,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "1c6dc169ac04fd09ef94404a912a15cbb17e1452"
|
||||
"gitHead": "73996f055bbff996ee776e7788e5a5cb500fc197"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"sourceMap": false,
|
||||
"inlineSourceMap": false
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"inlineSourceMap":false,
|
||||
"sourceMap": true,
|
||||
"noImplicitThis": true,
|
||||
"noUnusedLocals": true,
|
||||
"stripInternal": true,
|
||||
@@ -22,7 +23,6 @@
|
||||
"composite": false,
|
||||
"useDefineForClassFields": true,
|
||||
"strict": false,
|
||||
// "sourceMap": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"lib": ["ESNext", "DOM"],
|
||||
|
||||
@@ -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.40.1](https://github.com/certd/certd/compare/v1.40.0...v1.40.1) (2026-05-18)
|
||||
|
||||
**Note:** Version bump only for package @certd/lib-server
|
||||
|
||||
# [1.40.0](https://github.com/certd/certd/compare/v1.39.16...v1.40.0) (2026-05-14)
|
||||
|
||||
### Features
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/lib-server",
|
||||
"version": "1.40.0",
|
||||
"version": "1.40.1",
|
||||
"description": "midway with flyway, sql upgrade way ",
|
||||
"private": false,
|
||||
"type": "module",
|
||||
@@ -9,7 +9,7 @@
|
||||
"types": "./dist/index.d.ts",
|
||||
"scripts": {
|
||||
"before-build": "rimraf dist && rimraf tsconfig.tsbuildinfo && rimraf .rollup.cache",
|
||||
"build": "npm run before-build && tsc --skipLibCheck",
|
||||
"build": "npm run before-build && tsc -p tsconfig.build.json --skipLibCheck",
|
||||
"dev-build": "npm run build",
|
||||
"test": "midway-bin test --ts -V",
|
||||
"test:unit": "cross-env NODE_ENV=unittest mocha --no-config --node-option no-warnings --node-option loader=ts-node/esm \"src/**/*.test.ts\"",
|
||||
@@ -29,11 +29,11 @@
|
||||
],
|
||||
"license": "AGPL",
|
||||
"dependencies": {
|
||||
"@certd/acme-client": "^1.40.0",
|
||||
"@certd/basic": "^1.40.0",
|
||||
"@certd/pipeline": "^1.40.0",
|
||||
"@certd/plugin-lib": "^1.40.0",
|
||||
"@certd/plus-core": "^1.40.0",
|
||||
"@certd/acme-client": "^1.40.1",
|
||||
"@certd/basic": "^1.40.1",
|
||||
"@certd/pipeline": "^1.40.1",
|
||||
"@certd/plugin-lib": "^1.40.1",
|
||||
"@certd/plus-core": "^1.40.1",
|
||||
"@midwayjs/cache": "3.14.0",
|
||||
"@midwayjs/core": "3.20.11",
|
||||
"@midwayjs/i18n": "3.20.13",
|
||||
@@ -69,5 +69,5 @@
|
||||
"typeorm": "^0.3.11",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "1c6dc169ac04fd09ef94404a912a15cbb17e1452"
|
||||
"gitHead": "73996f055bbff996ee776e7788e5a5cb500fc197"
|
||||
}
|
||||
|
||||
@@ -253,6 +253,14 @@ export class SysSuiteSetting extends BaseSettings {
|
||||
intro?: string;
|
||||
}
|
||||
|
||||
export class SysAutoFixSetting extends BaseSettings {
|
||||
static __title__ = '自动修复记录';
|
||||
static __key__ = 'sys.auto.fix';
|
||||
static __access__ = 'private';
|
||||
|
||||
fixed: Record<string, boolean> = {};
|
||||
}
|
||||
|
||||
|
||||
export type SiteHidden = {
|
||||
enabled: boolean;
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"sourceMap": false,
|
||||
"inlineSourceMap": false
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"inlineSourceMap": false,
|
||||
"sourceMap": false,
|
||||
"sourceMap": true,
|
||||
"noImplicitThis": true,
|
||||
"noUnusedLocals": true,
|
||||
"stripInternal": true,
|
||||
|
||||
@@ -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.40.1](https://github.com/certd/certd/compare/v1.40.0...v1.40.1) (2026-05-18)
|
||||
|
||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||
|
||||
# [1.40.0](https://github.com/certd/certd/compare/v1.39.16...v1.40.0) (2026-05-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/midway-flyway-js
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/midway-flyway-js",
|
||||
"version": "1.40.0",
|
||||
"version": "1.40.1",
|
||||
"description": "midway with flyway, sql upgrade way ",
|
||||
"private": false,
|
||||
"type": "module",
|
||||
@@ -9,7 +9,7 @@
|
||||
"types": "./dist/index.d.ts",
|
||||
"scripts": {
|
||||
"before-build": "rimraf dist && rimraf tsconfig.tsbuildinfo && rimraf .rollup.cache",
|
||||
"build": "npm run before-build && tsc --skipLibCheck",
|
||||
"build": "npm run before-build && tsc -p tsconfig.build.json --skipLibCheck",
|
||||
"dev-build": "npm run build",
|
||||
"test": "midway-bin test --ts -V",
|
||||
"test1": "midway-bin test --ts -V -f test/blank.test.ts -t 'hash-check'",
|
||||
@@ -49,5 +49,5 @@
|
||||
"typeorm": "^0.3.11",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "bae5a04dcc0a679c290a9805c3ac4a6020eb6ec0"
|
||||
"gitHead": "73996f055bbff996ee776e7788e5a5cb500fc197"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"sourceMap": false,
|
||||
"inlineSourceMap": false
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"inlineSourceMap":false,
|
||||
"sourceMap": true,
|
||||
"noImplicitThis": true,
|
||||
"noUnusedLocals": true,
|
||||
"stripInternal": true,
|
||||
@@ -21,7 +22,6 @@
|
||||
"composite": false,
|
||||
"useDefineForClassFields": true,
|
||||
"strict": false,
|
||||
// "sourceMap": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"lib": ["ESNext", "DOM"],
|
||||
|
||||
@@ -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.40.1](https://github.com/certd/certd/compare/v1.40.0...v1.40.1) (2026-05-18)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-cert
|
||||
|
||||
# [1.40.0](https://github.com/certd/certd/compare/v1.39.16...v1.40.0) (2026-05-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-cert
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
{
|
||||
"name": "@certd/plugin-cert",
|
||||
"private": false,
|
||||
"version": "1.40.0",
|
||||
"version": "1.40.1",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"before-build": "rimraf dist && rimraf tsconfig.tsbuildinfo && rimraf .rollup.cache",
|
||||
"build": "tsc --skipLibCheck",
|
||||
"build": "tsc -p tsconfig.build.json --skipLibCheck",
|
||||
"dev-build": "npm run build",
|
||||
"build3": "rollup -c",
|
||||
"build2": "vue-tsc --noEmit && vite build",
|
||||
@@ -18,10 +18,10 @@
|
||||
"compile": "tsc --skipLibCheck --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/acme-client": "^1.40.0",
|
||||
"@certd/basic": "^1.40.0",
|
||||
"@certd/pipeline": "^1.40.0",
|
||||
"@certd/plugin-lib": "^1.40.0",
|
||||
"@certd/acme-client": "^1.40.1",
|
||||
"@certd/basic": "^1.40.1",
|
||||
"@certd/pipeline": "^1.40.1",
|
||||
"@certd/plugin-lib": "^1.40.1",
|
||||
"psl": "^1.9.0",
|
||||
"punycode.js": "^2.3.1"
|
||||
},
|
||||
@@ -41,5 +41,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "1c6dc169ac04fd09ef94404a912a15cbb17e1452"
|
||||
"gitHead": "73996f055bbff996ee776e7788e5a5cb500fc197"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"sourceMap": false,
|
||||
"inlineSourceMap": false
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"inlineSourceMap":false,
|
||||
"sourceMap": false,
|
||||
"sourceMap": true,
|
||||
"noImplicitThis": true,
|
||||
"noUnusedLocals": true,
|
||||
"stripInternal": true,
|
||||
|
||||
@@ -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.40.1](https://github.com/certd/certd/compare/v1.40.0...v1.40.1) (2026-05-18)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-lib
|
||||
|
||||
# [1.40.0](https://github.com/certd/certd/compare/v1.39.16...v1.40.0) (2026-05-14)
|
||||
|
||||
**Note:** Version bump only for package @certd/plugin-lib
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
{
|
||||
"name": "@certd/plugin-lib",
|
||||
"private": false,
|
||||
"version": "1.40.0",
|
||||
"version": "1.40.1",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"before-build": "rimraf dist && rimraf tsconfig.tsbuildinfo && rimraf .rollup.cache",
|
||||
"build": "npm run before-build &&tsc --skipLibCheck",
|
||||
"build": "npm run before-build && tsc -p tsconfig.build.json --skipLibCheck",
|
||||
"dev-build": "npm run build",
|
||||
"build3": "rollup -c",
|
||||
"build2": "vue-tsc --noEmit && vite build",
|
||||
@@ -23,10 +23,10 @@
|
||||
"@alicloud/pop-core": "^1.7.10",
|
||||
"@alicloud/tea-util": "^1.4.11",
|
||||
"@aws-sdk/client-s3": "^3.964.0",
|
||||
"@certd/acme-client": "^1.40.0",
|
||||
"@certd/basic": "^1.40.0",
|
||||
"@certd/pipeline": "^1.40.0",
|
||||
"@certd/plus-core": "^1.40.0",
|
||||
"@certd/acme-client": "^1.40.1",
|
||||
"@certd/basic": "^1.40.1",
|
||||
"@certd/pipeline": "^1.40.1",
|
||||
"@certd/plus-core": "^1.40.1",
|
||||
"@kubernetes/client-node": "0.21.0",
|
||||
"ali-oss": "^6.22.0",
|
||||
"basic-ftp": "^5.0.5",
|
||||
@@ -61,5 +61,5 @@
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"gitHead": "1c6dc169ac04fd09ef94404a912a15cbb17e1452"
|
||||
"gitHead": "73996f055bbff996ee776e7788e5a5cb500fc197"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"sourceMap": false,
|
||||
"inlineSourceMap": false
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"inlineSourceMap": false,
|
||||
"sourceMap": false,
|
||||
"sourceMap": true,
|
||||
"noImplicitThis": true,
|
||||
"noUnusedLocals": true,
|
||||
"stripInternal": true,
|
||||
|
||||
@@ -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.40.1](https://github.com/certd/certd/compare/v1.40.0...v1.40.1) (2026-05-18)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 商业版支持限制泛域名数量 ([c63745d](https://github.com/certd/certd/commit/c63745d1ba30904428ba6b13ab0785298baa5cae))
|
||||
* **suite:** 商业版用户已购套餐支持修改 ([bdb3d09](https://github.com/certd/certd/commit/bdb3d09c09fc73e7e5e3401f6ef5588bf8ad5088))
|
||||
|
||||
# [1.40.0](https://github.com/certd/certd/compare/v1.39.16...v1.40.0) (2026-05-14)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/ui-client",
|
||||
"version": "1.40.0",
|
||||
"version": "1.40.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite --open",
|
||||
@@ -106,8 +106,8 @@
|
||||
"zod-defaults": "^0.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@certd/lib-iframe": "^1.40.0",
|
||||
"@certd/pipeline": "^1.40.0",
|
||||
"@certd/lib-iframe": "^1.40.1",
|
||||
"@certd/pipeline": "^1.40.1",
|
||||
"@rollup/plugin-commonjs": "^25.0.7",
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@types/chai": "^4.3.12",
|
||||
|
||||
@@ -40,6 +40,9 @@ export default {
|
||||
basicInfo: "Basic Information",
|
||||
disabled: "Disabled",
|
||||
enabled: "Enabled",
|
||||
enabledLabel: "Enabled",
|
||||
normal: "Normal",
|
||||
used_up: "Used up",
|
||||
default: "Default",
|
||||
success: "Success",
|
||||
test: "Test",
|
||||
|
||||
@@ -6,6 +6,9 @@ export default {
|
||||
specifications: "Specifications",
|
||||
pipeline: "Pipeline",
|
||||
domain: "Domain",
|
||||
totalDomain: "Total Domain Count",
|
||||
wildcardDomain: "Wildcard Domain",
|
||||
includedWildcardDomain: "Included Wildcard Domain Count",
|
||||
deployTimes: "Deployments",
|
||||
monitorCount: "DomainMonitors",
|
||||
duration: "Duration",
|
||||
@@ -24,11 +27,13 @@ export default {
|
||||
please_select_package: "Please select a package",
|
||||
package: "Package",
|
||||
addon_package: "Addon Package",
|
||||
domain_count: "Domain Count",
|
||||
domain_count: "Total Domain Count",
|
||||
wildcard_domain_count: "Wildcard Domain Count",
|
||||
unit_count: "pcs",
|
||||
pipeline_count: "Pipeline Count",
|
||||
unit_item: "items",
|
||||
deploy_count: "Deploy Count",
|
||||
deploy_count_used: "Used Deploy Count",
|
||||
unit_times: "times",
|
||||
monitor_count: "Certificate Monitor Count",
|
||||
duration: "Duration",
|
||||
@@ -42,6 +47,7 @@ export default {
|
||||
intro: "Introduction",
|
||||
packageContent: "Package Content",
|
||||
maxDomainCount: "Max Domain Count",
|
||||
maxWildcardDomainCount: "Max Wildcard Domain Count",
|
||||
maxPipelineCount: "Max Pipeline Count",
|
||||
maxDeployCount: "Max Deploy Count",
|
||||
maxMonitorCount: "Max Monitor Count",
|
||||
@@ -51,6 +57,10 @@ export default {
|
||||
addon: "Addon",
|
||||
typeHelper: "Suite: Only the most recently purchased one is active at a time\nAddon: Multiple can be purchased, effective immediately without affecting the suite\nThe quantities of suite and addon can be accumulated",
|
||||
pipelineCount: "Pipeline Count",
|
||||
wildcardDomainCount: "Wildcard Domain Count",
|
||||
wildcardDomainCountPart: "Included Wildcard Domain Count",
|
||||
wildcardDomainCountSub: "- Wildcard Domain Count",
|
||||
wildcardDomainCountHelper: "Wildcard domains are also limited by the total domain count: each wildcard domain consumes both domain count and wildcard domain count quota.",
|
||||
unitPipeline: "pipelines",
|
||||
deployCount: "Deployment Count",
|
||||
unitDeploy: "times",
|
||||
|
||||
@@ -44,6 +44,9 @@ export default {
|
||||
basicInfo: "基础信息",
|
||||
disabled: "禁用",
|
||||
enabled: "启用",
|
||||
enabledLabel: "启用",
|
||||
normal: "正常",
|
||||
used_up: "已用完",
|
||||
default: "默认",
|
||||
success: "成功",
|
||||
test: "测试",
|
||||
|
||||
@@ -22,6 +22,8 @@ export default {
|
||||
mySuite: "我的套餐",
|
||||
suiteBuy: "套餐购买",
|
||||
myTrade: "我的订单",
|
||||
myWallet: "我的钱包",
|
||||
inviteCommission: "邀请返佣",
|
||||
paymentReturn: "支付返回",
|
||||
source: "源码",
|
||||
github: "github",
|
||||
@@ -46,6 +48,8 @@ export default {
|
||||
suiteSetting: "套餐设置",
|
||||
orderManager: "订单管理",
|
||||
userSuites: "用户套餐",
|
||||
inviteCommissionSetting: "邀请返佣设置",
|
||||
inviteWithdraw: "提现申请记录",
|
||||
netTest: "网络测试",
|
||||
enterpriseManager: "企业管理设置",
|
||||
projectManager: "项目管理",
|
||||
|
||||
@@ -6,6 +6,9 @@ export default {
|
||||
specifications: "规格",
|
||||
pipeline: "流水线",
|
||||
domain: "域名",
|
||||
totalDomain: "域名总数量",
|
||||
wildcardDomain: "泛域名",
|
||||
includedWildcardDomain: "其中泛域名数量",
|
||||
deployTimes: "部署次数",
|
||||
monitorCount: "域名监控数",
|
||||
duration: "时长",
|
||||
@@ -24,11 +27,13 @@ export default {
|
||||
please_select_package: "请选择套餐",
|
||||
package: "套餐",
|
||||
addon_package: "加量包",
|
||||
domain_count: "域名数量",
|
||||
domain_count: "域名总数量",
|
||||
wildcard_domain_count: "泛域名数量",
|
||||
unit_count: "个",
|
||||
pipeline_count: "流水线数量",
|
||||
unit_item: "条",
|
||||
deploy_count: "部署次数",
|
||||
deploy_count_used: "已用部署次数",
|
||||
unit_times: "次",
|
||||
monitor_count: "证书监控数量",
|
||||
duration: "时长",
|
||||
@@ -42,6 +47,7 @@ export default {
|
||||
intro: "介绍",
|
||||
packageContent: "套餐内容",
|
||||
maxDomainCount: "最大域名数",
|
||||
maxWildcardDomainCount: "最大泛域名数",
|
||||
maxPipelineCount: "最大流水线数",
|
||||
maxDeployCount: "最大部署数",
|
||||
maxMonitorCount: "最大监控数",
|
||||
@@ -51,6 +57,10 @@ export default {
|
||||
addon: "加量包",
|
||||
typeHelper: "套餐:同一时间只有最新购买的一个生效\n加量包:可购买多个,购买后立即生效,不影响套餐\n套餐和加量包数量可叠加",
|
||||
pipelineCount: "流水线数量",
|
||||
wildcardDomainCount: "泛域名数量",
|
||||
wildcardDomainCountPart: "其中泛域名数量",
|
||||
wildcardDomainCountSub: "- 泛域名数量",
|
||||
wildcardDomainCountHelper: "泛域名数量受域名总数量限制:泛域名会同时占用域名总数量和泛域名数量额度;注意:如果域名总数有限制,泛域名数量不要设置为无限制。",
|
||||
unitPipeline: "条",
|
||||
deployCount: "部署次数",
|
||||
unitDeploy: "次",
|
||||
|
||||
@@ -12,9 +12,11 @@ import plugin from "./plugin/";
|
||||
import { setupVben } from "./vben";
|
||||
import { util } from "/@/utils";
|
||||
import { initPreferences } from "/@/vben/preferences";
|
||||
import { inviteUtils } from "/@/utils/util.invite";
|
||||
// import "./components/code-editor/import-works";
|
||||
// @ts-ignore
|
||||
async function bootstrap() {
|
||||
inviteUtils.captureFromLocation();
|
||||
const app = createApp(App);
|
||||
// app.use(Antd);
|
||||
app.use(Antd);
|
||||
|
||||
@@ -324,7 +324,7 @@ export const certdResources = [
|
||||
meta: {
|
||||
show: () => {
|
||||
const settingStore = useSettingStore();
|
||||
return settingStore.isComm;
|
||||
return settingStore.isInviteCommissionEnabled;
|
||||
},
|
||||
icon: "ion:gift-outline",
|
||||
auth: true,
|
||||
@@ -359,6 +359,36 @@ export const certdResources = [
|
||||
keepAlive: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "certd.myWallet",
|
||||
name: "MyWallet",
|
||||
path: "/certd/wallet",
|
||||
component: "/certd/wallet/index.vue",
|
||||
meta: {
|
||||
show: () => {
|
||||
const settingStore = useSettingStore();
|
||||
return settingStore.isComm;
|
||||
},
|
||||
icon: "ion:wallet-outline",
|
||||
auth: true,
|
||||
keepAlive: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "certd.inviteCommission",
|
||||
name: "InviteCommission",
|
||||
path: "/certd/invite",
|
||||
component: "/certd/invite/index.vue",
|
||||
meta: {
|
||||
show: () => {
|
||||
const settingStore = useSettingStore();
|
||||
return settingStore.isComm;
|
||||
},
|
||||
icon: "ion:gift-outline",
|
||||
auth: true,
|
||||
keepAlive: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "certd.paymentReturn",
|
||||
name: "PaymentReturn",
|
||||
|
||||
@@ -286,6 +286,38 @@ export const sysResources = [
|
||||
keepAlive: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "certd.sysResources.inviteCommissionSetting",
|
||||
name: "SysInviteCommissionSetting",
|
||||
path: "/sys/suite/invite/setting",
|
||||
component: "/sys/suite/invite/setting.vue",
|
||||
meta: {
|
||||
show: () => {
|
||||
const settingStore = useSettingStore();
|
||||
return settingStore.isComm;
|
||||
},
|
||||
icon: "ion:gift-outline",
|
||||
permission: "sys:settings:edit",
|
||||
auth: true,
|
||||
keepAlive: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "certd.sysResources.inviteWithdraw",
|
||||
name: "SysInviteWithdraw",
|
||||
path: "/sys/suite/invite/withdraw",
|
||||
component: "/sys/suite/invite/withdraw.vue",
|
||||
meta: {
|
||||
show: () => {
|
||||
const settingStore = useSettingStore();
|
||||
return settingStore.isComm;
|
||||
},
|
||||
icon: "ion:cash-outline",
|
||||
permission: "sys:settings:edit",
|
||||
auth: true,
|
||||
keepAlive: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -97,6 +97,9 @@ export type SysPublicSetting = {
|
||||
export type SuiteSetting = {
|
||||
enabled?: boolean;
|
||||
};
|
||||
export type InviteSetting = {
|
||||
enabled?: boolean;
|
||||
};
|
||||
export type SysPrivateSetting = {
|
||||
httpProxy?: string;
|
||||
httpsProxy?: string;
|
||||
@@ -142,6 +145,7 @@ export type AllSettings = {
|
||||
siteEnv: SiteEnv;
|
||||
headerMenus: HeaderMenus;
|
||||
suiteSetting: SuiteSetting;
|
||||
inviteSetting: InviteSetting;
|
||||
app: AppInfo;
|
||||
};
|
||||
|
||||
|
||||
@@ -30,6 +30,9 @@ export interface SettingState {
|
||||
headerMenus?: HeaderMenus;
|
||||
inited?: boolean;
|
||||
suiteSetting?: SuiteSetting;
|
||||
inviteSetting?: {
|
||||
enabled?: boolean;
|
||||
};
|
||||
app: {
|
||||
version?: string;
|
||||
time?: number;
|
||||
@@ -102,6 +105,7 @@ export const useSettingStore = defineStore({
|
||||
menus: [],
|
||||
},
|
||||
suiteSetting: { enabled: false },
|
||||
inviteSetting: { enabled: false },
|
||||
inited: false,
|
||||
app: {
|
||||
version: "",
|
||||
@@ -196,6 +200,9 @@ export const useSettingStore = defineStore({
|
||||
// @ts-ignore
|
||||
return this.suiteSetting?.enabled === true;
|
||||
},
|
||||
isInviteCommissionEnabled(): boolean {
|
||||
return this.isComm && this.inviteSetting?.enabled === true;
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
checkPlus() {
|
||||
@@ -215,6 +222,7 @@ export const useSettingStore = defineStore({
|
||||
merge(this.plusInfo, allSettings.plusInfo || {});
|
||||
merge(this.headerMenus, allSettings.headerMenus || {});
|
||||
merge(this.suiteSetting, allSettings.suiteSetting || {});
|
||||
merge(this.inviteSetting, allSettings.inviteSetting || {});
|
||||
//@ts-ignore
|
||||
this.initSiteInfo(allSettings.siteInfo || {});
|
||||
this.initAppInfo(allSettings.app || {});
|
||||
|
||||
@@ -4,6 +4,7 @@ export interface RegisterReq {
|
||||
username: string;
|
||||
password: string;
|
||||
confirmPassword: string;
|
||||
inviteCode?: string;
|
||||
}
|
||||
/**
|
||||
* @description: Login interface parameters
|
||||
@@ -18,6 +19,7 @@ export interface SmsLoginReq {
|
||||
phoneCode: string;
|
||||
smsCode: string;
|
||||
randomStr: string;
|
||||
inviteCode?: string;
|
||||
}
|
||||
|
||||
export interface ForgotPasswordReq {
|
||||
|
||||
@@ -13,7 +13,6 @@ export function useReference(formItem: any) {
|
||||
const ctx = {
|
||||
compute: (opts: any) => {
|
||||
const func = (context: any) => {
|
||||
debugger;
|
||||
let form = context.form || {};
|
||||
form = form.input || form.body || form; // form.access去掉,历史原因,access的mergeScript会处理form.access
|
||||
return opts({
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
const INVITE_STORAGE_KEY = "certd_invite_code";
|
||||
const INVITE_TTL = 3 * 24 * 60 * 60 * 1000;
|
||||
|
||||
export type InviteCache = {
|
||||
code: string;
|
||||
expiresAt: number;
|
||||
};
|
||||
|
||||
function normalizeInviteCode(code?: string | null) {
|
||||
return code?.trim().toUpperCase();
|
||||
}
|
||||
|
||||
export const inviteUtils = {
|
||||
save(code?: string | null) {
|
||||
const normalized = normalizeInviteCode(code);
|
||||
if (!normalized) {
|
||||
return;
|
||||
}
|
||||
const cache: InviteCache = {
|
||||
code: normalized,
|
||||
expiresAt: Date.now() + INVITE_TTL,
|
||||
};
|
||||
localStorage.setItem(INVITE_STORAGE_KEY, JSON.stringify(cache));
|
||||
},
|
||||
|
||||
get() {
|
||||
const text = localStorage.getItem(INVITE_STORAGE_KEY);
|
||||
if (!text) {
|
||||
return "";
|
||||
}
|
||||
try {
|
||||
const cache = JSON.parse(text) as InviteCache;
|
||||
if (!cache.code || !cache.expiresAt || cache.expiresAt < Date.now()) {
|
||||
localStorage.removeItem(INVITE_STORAGE_KEY);
|
||||
return "";
|
||||
}
|
||||
return cache.code;
|
||||
} catch (e) {
|
||||
localStorage.removeItem(INVITE_STORAGE_KEY);
|
||||
return "";
|
||||
}
|
||||
},
|
||||
|
||||
captureFromLocation() {
|
||||
const hashQuery = window.location.hash?.split("?")[1] || "";
|
||||
const search = window.location.search?.replace(/^\?/, "") || "";
|
||||
const hashParams = new URLSearchParams(hashQuery);
|
||||
const searchParams = new URLSearchParams(search);
|
||||
const code = hashParams.get("inviteCode") || searchParams.get("inviteCode");
|
||||
if (code) {
|
||||
this.save(code);
|
||||
}
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
import { request } from "/@/api/service";
|
||||
|
||||
export async function GetMyInvite() {
|
||||
return await request({ url: "/invite/my", method: "post" });
|
||||
}
|
||||
|
||||
export async function GetInvitees(query: any) {
|
||||
return await request({ url: "/invite/invitees/page", method: "post", data: query });
|
||||
}
|
||||
|
||||
export async function GetCommissionLogs(query: any) {
|
||||
return await request({ url: "/invite/commission/page", method: "post", data: query });
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import { CreateCrudOptionsProps, CreateCrudOptionsRet, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||
import * as api from "./api";
|
||||
|
||||
export default function (): CreateCrudOptionsRet {
|
||||
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
||||
return await api.GetInvitees(query);
|
||||
};
|
||||
|
||||
return {
|
||||
crudOptions: {
|
||||
request: { pageRequest },
|
||||
actionbar: { show: false },
|
||||
toolbar: { show: false },
|
||||
rowHandle: { show: false },
|
||||
columns: {
|
||||
inviteeUserId: {
|
||||
title: "被邀请人ID",
|
||||
type: "number",
|
||||
column: { width: 140 },
|
||||
},
|
||||
inviteCode: {
|
||||
title: "邀请码",
|
||||
type: "text",
|
||||
column: { width: 160 },
|
||||
},
|
||||
createTime: {
|
||||
title: "邀请时间",
|
||||
type: "datetime",
|
||||
column: { width: 180 },
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import { CreateCrudOptionsRet, dict, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||
import * as api from "./api";
|
||||
import PriceInput from "/@/views/sys/suite/product/price-input.vue";
|
||||
|
||||
export default function (): CreateCrudOptionsRet {
|
||||
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
||||
return await api.GetCommissionLogs(query);
|
||||
};
|
||||
|
||||
return {
|
||||
crudOptions: {
|
||||
request: { pageRequest },
|
||||
actionbar: { show: false },
|
||||
toolbar: { show: false },
|
||||
rowHandle: { show: false },
|
||||
columns: {
|
||||
type: {
|
||||
title: "类型",
|
||||
type: "dict-select",
|
||||
dict: dict({
|
||||
data: [{ label: "佣金入账", value: "commission", color: "success" }],
|
||||
}),
|
||||
column: { width: 130 },
|
||||
},
|
||||
amount: {
|
||||
title: "金额",
|
||||
type: "number",
|
||||
column: {
|
||||
width: 120,
|
||||
component: { name: PriceInput, vModel: "modelValue", edit: false },
|
||||
},
|
||||
},
|
||||
inviteeUserDisplay: {
|
||||
title: "被邀请用户",
|
||||
type: "text",
|
||||
column: { width: 150 },
|
||||
},
|
||||
consumeAmount: {
|
||||
title: "消费金额",
|
||||
type: "number",
|
||||
column: {
|
||||
width: 120,
|
||||
component: { name: PriceInput, vModel: "modelValue", edit: false },
|
||||
},
|
||||
},
|
||||
remark: {
|
||||
title: "备注",
|
||||
type: "text",
|
||||
column: { minWidth: 220 },
|
||||
},
|
||||
createTime: {
|
||||
title: "时间",
|
||||
type: "datetime",
|
||||
column: { width: 180 },
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
<template>
|
||||
<fs-page class="page-invite">
|
||||
<template #header>
|
||||
<div class="title">邀请返佣</div>
|
||||
</template>
|
||||
<div v-if="loaded && enabled" class="invite-body">
|
||||
<div class="invite-link-row flex-o">
|
||||
<span class="label">邀请码:</span>
|
||||
<fs-copyable v-model="inviteInfo.inviteCode" />
|
||||
</div>
|
||||
<div class="invite-link-row flex-o mt-10">
|
||||
<span class="label">邀请链接:</span>
|
||||
<fs-copyable v-model="inviteInfo.inviteLink" />
|
||||
</div>
|
||||
|
||||
<a-tabs v-model:active-key="activeTab" class="invite-tabs mt-6">
|
||||
<a-tab-pane key="invitees" tab="邀请成功">
|
||||
<fs-crud v-if="activeTab === 'invitees'" ref="inviteesCrudRef" class="invite-crud" v-bind="inviteesCrudBinding" />
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="logs" tab="佣金记录">
|
||||
<fs-crud v-if="activeTab === 'logs'" ref="logsCrudRef" class="invite-crud" v-bind="logsCrudBinding" />
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</div>
|
||||
<a-empty v-else-if="loaded" description="邀请返佣未开启" />
|
||||
</fs-page>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, nextTick, onActivated, onMounted, reactive, ref } from "vue";
|
||||
import { useFs } from "@fast-crud/fast-crud";
|
||||
import * as api from "./api";
|
||||
import createInviteesCrudOptions from "./crud-invitees";
|
||||
import createLogsCrudOptions from "./crud-logs";
|
||||
import { useSettingStore } from "/@/store/settings";
|
||||
|
||||
defineOptions({ name: "InviteCommission" });
|
||||
|
||||
const settingStore = useSettingStore();
|
||||
const enabled = computed(() => settingStore.isInviteCommissionEnabled);
|
||||
const activeTab = ref("invitees");
|
||||
const inviteInfo = reactive<any>({ inviteCode: "", inviteLink: "" });
|
||||
const loaded = ref(false);
|
||||
|
||||
const { crudBinding: inviteesCrudBinding, crudExpose: inviteesCrudExpose, crudRef: inviteesCrudRef } = useFs({ createCrudOptions: createInviteesCrudOptions });
|
||||
const { crudBinding: logsCrudBinding, crudExpose: logsCrudExpose, crudRef: logsCrudRef } = useFs({ createCrudOptions: createLogsCrudOptions });
|
||||
|
||||
async function loadMyInvite() {
|
||||
const res: any = await api.GetMyInvite();
|
||||
inviteInfo.inviteCode = res.inviteCode;
|
||||
inviteInfo.inviteLink = res.inviteLink;
|
||||
}
|
||||
|
||||
async function refreshActiveList() {
|
||||
if (activeTab.value === "invitees") {
|
||||
await inviteesCrudExpose.doRefresh();
|
||||
} else if (activeTab.value === "logs") {
|
||||
await logsCrudExpose.doRefresh();
|
||||
}
|
||||
}
|
||||
|
||||
async function refreshInvitePage(refreshAll = false) {
|
||||
await settingStore.initOnce();
|
||||
loaded.value = true;
|
||||
if (!enabled.value) {
|
||||
return;
|
||||
}
|
||||
await loadMyInvite();
|
||||
await nextTick();
|
||||
if (refreshAll) {
|
||||
await Promise.all([inviteesCrudExpose.doRefresh(), logsCrudExpose.doRefresh()]);
|
||||
return;
|
||||
}
|
||||
await refreshActiveList();
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await refreshInvitePage(true);
|
||||
});
|
||||
|
||||
onActivated(async () => {
|
||||
if (!loaded.value) {
|
||||
return;
|
||||
}
|
||||
await refreshInvitePage();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.page-invite {
|
||||
display: flex;
|
||||
min-height: 0;
|
||||
|
||||
.fs-page-content {
|
||||
display: flex;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.invite-body {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.invite-tabs {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.ant-tabs-content-holder,
|
||||
.ant-tabs-content,
|
||||
.ant-tabs-tabpane {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.ant-tabs-tabpane {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.invite-crud {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
.label {
|
||||
width: 80px;
|
||||
flex: none;
|
||||
text-align: right;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -56,6 +56,10 @@ export function findStep(pipeline: any, id: string) {
|
||||
|
||||
export async function checkPipelineLimit() {
|
||||
const settingsStore = useSettingStore();
|
||||
if (settingsStore.isEnterprise) {
|
||||
//企业模式不限制
|
||||
return;
|
||||
}
|
||||
if (settingsStore.isComm && settingsStore.suiteSetting.enabled) {
|
||||
//检查数量是否超限
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ export type TradeCreateReq = {
|
||||
duration: number;
|
||||
num: number;
|
||||
payType: string;
|
||||
useRebateBalance?: boolean;
|
||||
};
|
||||
|
||||
export async function TradeCreate(form: TradeCreateReq) {
|
||||
|
||||
@@ -14,6 +14,7 @@ export type SuiteDetail = {
|
||||
expiresTime?: number;
|
||||
pipelineCount?: SuiteValue;
|
||||
domainCount?: SuiteValue;
|
||||
wildcardDomainCount?: SuiteValue;
|
||||
deployCount?: SuiteValue;
|
||||
monitorCount?: SuiteValue;
|
||||
};
|
||||
|
||||
@@ -147,7 +147,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
},
|
||||
},
|
||||
"content.maxDomainCount": {
|
||||
title: "域名数量",
|
||||
title: "域名总数量",
|
||||
type: "text",
|
||||
form: {
|
||||
key: ["content", "maxDomainCount"],
|
||||
@@ -168,6 +168,28 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
align: "center",
|
||||
},
|
||||
},
|
||||
"content.maxWildcardDomainCount": {
|
||||
title: "其中泛域名数量",
|
||||
type: "text",
|
||||
form: {
|
||||
key: ["content", "maxWildcardDomainCount"],
|
||||
component: {
|
||||
name: SuiteValueEdit,
|
||||
vModel: "modelValue",
|
||||
unit: "个",
|
||||
},
|
||||
rules: [{ required: true, message: "此项必填" }],
|
||||
},
|
||||
column: {
|
||||
width: 120,
|
||||
component: {
|
||||
name: SuiteValue,
|
||||
vModel: "modelValue",
|
||||
unit: "个",
|
||||
},
|
||||
align: "center",
|
||||
},
|
||||
},
|
||||
"content.maxPipelineCount": {
|
||||
title: "流水线数量",
|
||||
type: "text",
|
||||
|
||||
@@ -11,7 +11,10 @@
|
||||
<span class="label">{{ $t("certd.order.specifications") }}:</span>
|
||||
<span class="flex-o flex-wrap">
|
||||
<span class="flex-o"> {{ $t("certd.order.pipeline") }}<suite-value class="ml-5" :model-value="product.content.maxPipelineCount" :unit="$t('certd.order.unit.pieces')" />; </span>
|
||||
<span class="flex-o"> {{ $t("certd.order.domain") }}<suite-value class="ml-5" :model-value="product.content.maxDomainCount" :unit="$t('certd.order.unit.count')" />; </span>
|
||||
<span class="flex-o"> {{ $t("certd.order.totalDomain") }}<suite-value class="ml-5" :model-value="product.content.maxDomainCount" :unit="$t('certd.order.unit.count')" />; </span>
|
||||
<span class="flex-o" style="padding-left: 2em">
|
||||
- {{ $t("certd.order.includedWildcardDomain") }}<suite-value class="ml-5" :model-value="product.content.maxWildcardDomainCount" :unit="$t('certd.order.unit.count')" />;
|
||||
</span>
|
||||
<span class="flex-o"> {{ $t("certd.order.deployTimes") }}<suite-value class="ml-5" :model-value="product.content.maxDeployCount" :unit="$t('certd.order.unit.times')" />; </span>
|
||||
<span class="flex-o"> {{ $t("certd.order.monitorCount") }}<suite-value class="ml-5" :model-value="product.content.maxMonitorCount" :unit="$t('certd.order.unit.times')" />; </span>
|
||||
</span>
|
||||
@@ -25,10 +28,19 @@
|
||||
<span class="label">{{ $t("certd.order.price") }}:</span>
|
||||
<price-input :edit="false" :model-value="durationSelected.price"></price-input>
|
||||
</div>
|
||||
<div v-if="durationSelected.price > 0 && wallet.availableAmount > 0" class="flex-o mt-5">
|
||||
<span class="label">返利抵扣:</span>
|
||||
<a-switch v-model:checked="formRef.useRebateBalance" />
|
||||
<span class="ml-10">可用 {{ amountToYuan(wallet.availableAmount) }} 元,预计抵扣 {{ amountToYuan(expectedRebateAmount) }} 元</span>
|
||||
</div>
|
||||
<div v-if="durationSelected.price > 0 && formRef.useRebateBalance" class="flex-o mt-5">
|
||||
<span class="label">还需支付:</span>
|
||||
<span class="color-red">{{ amountToYuan(expectedThirdPartyAmount) }} 元</span>
|
||||
</div>
|
||||
|
||||
<div class="flex-o mt-5">
|
||||
<span class="label">{{ $t("certd.order.paymentMethod") }}:</span>
|
||||
<div v-if="durationSelected.price === 0">{{ $t("certd.order.free") }}</div>
|
||||
<div v-if="durationSelected.price === 0 || expectedThirdPartyAmount === 0">{{ $t("certd.order.free") }}</div>
|
||||
<fs-dict-select v-else v-model:value="formRef.payType" :dict="paymentsDictRef" style="width: 200px"> </fs-dict-select>
|
||||
</div>
|
||||
</div>
|
||||
@@ -36,7 +48,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="tsx">
|
||||
import { ref } from "vue";
|
||||
import { computed, ref } from "vue";
|
||||
import { GetPaymentTypes, OrderModalOpenReq, TradeCreate } from "/@/views/certd/suite/api";
|
||||
import SuiteValue from "/@/views/sys/suite/product/suite-value.vue";
|
||||
import PriceInput from "/@/views/sys/suite/product/price-input.vue";
|
||||
@@ -46,11 +58,14 @@ import DurationValue from "/@/views/sys/suite/product/duration-value.vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import qrcode from "qrcode";
|
||||
import * as api from "/@/views/certd/suite/api";
|
||||
import { GetMyInvite } from "/@/views/certd/invite/api";
|
||||
import { util } from "/@/utils";
|
||||
const openRef = ref(false);
|
||||
|
||||
const product = ref<any>(null);
|
||||
const formRef = ref<any>({});
|
||||
const durationSelected = ref<any>(null);
|
||||
const wallet = ref<any>({ availableAmount: 0 });
|
||||
async function open(opts: OrderModalOpenReq) {
|
||||
openRef.value = true;
|
||||
|
||||
@@ -60,6 +75,13 @@ 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;
|
||||
try {
|
||||
const inviteInfo: any = await GetMyInvite();
|
||||
wallet.value = inviteInfo.wallet || { availableAmount: 0 };
|
||||
} catch (e) {
|
||||
wallet.value = { availableAmount: 0 };
|
||||
}
|
||||
}
|
||||
const paymentsDictRef = dict({
|
||||
async getData() {
|
||||
@@ -74,6 +96,21 @@ const paymentsDictRef = dict({
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const expectedRebateAmount = computed(() => {
|
||||
if (!formRef.value.useRebateBalance) {
|
||||
return 0;
|
||||
}
|
||||
return Math.min(wallet.value.availableAmount || 0, durationSelected.value?.price || 0);
|
||||
});
|
||||
|
||||
const expectedThirdPartyAmount = computed(() => {
|
||||
return Math.max(0, (durationSelected.value?.price || 0) - expectedRebateAmount.value);
|
||||
});
|
||||
|
||||
function amountToYuan(amount: number) {
|
||||
return util.amount.toYuan(amount || 0);
|
||||
}
|
||||
|
||||
async function orderCreate() {
|
||||
if (durationSelected.value.price === 0) {
|
||||
//如果是0,直接请求创建订单
|
||||
@@ -90,7 +127,7 @@ async function orderCreate() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!formRef.value.payType) {
|
||||
if (expectedThirdPartyAmount.value > 0 && !formRef.value.payType) {
|
||||
notification.error({
|
||||
message: "请选择支付方式",
|
||||
});
|
||||
@@ -101,8 +138,17 @@ async function orderCreate() {
|
||||
duration: formRef.value.duration,
|
||||
num: formRef.value.num ?? 1,
|
||||
payType: formRef.value.payType,
|
||||
useRebateBalance: formRef.value.useRebateBalance,
|
||||
});
|
||||
|
||||
if (paymentReq.paid) {
|
||||
notification.success({
|
||||
message: "套餐购买成功",
|
||||
});
|
||||
openRef.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
async function onPaid() {
|
||||
openRef.value = false;
|
||||
router.push({
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<a-card :title="product.title" class="product-card">
|
||||
<template #extra>
|
||||
<fs-values-format v-model="product.type" :dict="productTypeDictRef"></fs-values-format>
|
||||
<fs-values-format :model-value="product.type" :dict="productTypeDictRef"></fs-values-format>
|
||||
</template>
|
||||
|
||||
<div class="product-intro">{{ product.intro || "暂无介绍" }}</div>
|
||||
@@ -12,9 +12,13 @@
|
||||
<suite-value :model-value="product.content.maxPipelineCount" unit="条" />
|
||||
</div>
|
||||
<div class="flex-between mt-5">
|
||||
<div class="flex-o"><fs-icon icon="ant-design:check-outlined" class="color-green mr-5" />域名数量:</div>
|
||||
<div class="flex-o"><fs-icon icon="ant-design:check-outlined" class="color-green mr-5" />域名总数量:</div>
|
||||
<suite-value :model-value="product.content.maxDomainCount" unit="个" />
|
||||
</div>
|
||||
<div class="flex-between mt-5">
|
||||
<div class="flex-o" style="padding-left: 2em">- 其中泛域名数量:</div>
|
||||
<suite-value :model-value="product.content.maxWildcardDomainCount" unit="个" />
|
||||
</div>
|
||||
<div class="flex-between mt-5">
|
||||
<div class="flex-o">
|
||||
<fs-icon icon="ant-design:check-outlined" class="color-green mr-5" />
|
||||
|
||||
@@ -151,6 +151,30 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
},
|
||||
},
|
||||
},
|
||||
rebateAmount: {
|
||||
title: "返利抵扣",
|
||||
type: "number",
|
||||
column: {
|
||||
width: 110,
|
||||
component: {
|
||||
name: PriceInput,
|
||||
vModel: "modelValue",
|
||||
edit: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
thirdPartyPayAmount: {
|
||||
title: "实付金额",
|
||||
type: "number",
|
||||
column: {
|
||||
width: 110,
|
||||
component: {
|
||||
name: PriceInput,
|
||||
vModel: "modelValue",
|
||||
edit: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
status: {
|
||||
title: "状态",
|
||||
search: { show: true },
|
||||
@@ -177,6 +201,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
{ label: "支付宝", value: "alipay" },
|
||||
{ label: "微信", value: "wxpay" },
|
||||
{ label: "免费", value: "free" },
|
||||
{ label: "返利余额", value: "rebate" },
|
||||
],
|
||||
}),
|
||||
column: {
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { request } from "/@/api/service";
|
||||
|
||||
export async function GetWalletSummary() {
|
||||
return await request({ url: "/wallet/summary", method: "post" });
|
||||
}
|
||||
|
||||
export async function GetWithdrawSetting() {
|
||||
return await request({ url: "/wallet/withdraw/setting/get", method: "post" });
|
||||
}
|
||||
|
||||
export async function SaveWithdrawSetting(data: any) {
|
||||
return await request({ url: "/wallet/withdraw/setting/save", method: "post", data });
|
||||
}
|
||||
|
||||
export async function ApplyWithdraw(amount: number) {
|
||||
return await request({ url: "/wallet/withdraw/apply", method: "post", data: { amount } });
|
||||
}
|
||||
|
||||
export async function GetWithdraws(query: any) {
|
||||
return await request({ url: "/wallet/withdraw/page", method: "post", data: query });
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
import { CreateCrudOptionsRet, dict, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||
import * as api from "./api";
|
||||
import PriceInput from "/@/views/sys/suite/product/price-input.vue";
|
||||
|
||||
export default function (): CreateCrudOptionsRet {
|
||||
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
||||
return await api.GetWithdraws(query);
|
||||
};
|
||||
|
||||
return {
|
||||
crudOptions: {
|
||||
request: { pageRequest },
|
||||
actionbar: { show: false },
|
||||
toolbar: { show: false },
|
||||
rowHandle: { show: false },
|
||||
columns: {
|
||||
amount: {
|
||||
title: "金额",
|
||||
type: "number",
|
||||
column: {
|
||||
width: 120,
|
||||
component: { name: PriceInput, vModel: "modelValue", edit: false },
|
||||
},
|
||||
},
|
||||
status: {
|
||||
title: "状态",
|
||||
type: "dict-select",
|
||||
dict: dict({
|
||||
data: [
|
||||
{ label: "待审核", value: "pending", color: "warning" },
|
||||
{ label: "已通过", value: "approved", color: "success" },
|
||||
{ label: "已拒绝", value: "rejected", color: "error" },
|
||||
],
|
||||
}),
|
||||
column: { width: 110 },
|
||||
},
|
||||
channel: {
|
||||
title: "提现渠道",
|
||||
type: "dict-select",
|
||||
dict: dict({
|
||||
data: [
|
||||
{ label: "支付宝", value: "alipay" },
|
||||
{ label: "银行卡", value: "bank" },
|
||||
],
|
||||
}),
|
||||
column: { width: 110 },
|
||||
},
|
||||
realName: { title: "真实姓名", type: "text", column: { width: 120 } },
|
||||
account: { title: "收款账号", type: "text", column: { width: 180 } },
|
||||
bankName: { title: "开户银行", type: "text", column: { width: 160 } },
|
||||
auditRemark: { title: "审核备注", type: "text", column: { minWidth: 180 } },
|
||||
createTime: { title: "申请时间", type: "datetime", column: { width: 180 } },
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
<template>
|
||||
<fs-page class="page-wallet">
|
||||
<template #header>
|
||||
<div class="title">我的钱包</div>
|
||||
</template>
|
||||
<div class="wallet-body">
|
||||
<a-row :gutter="16" class="wallet-summary">
|
||||
<a-col :span="6">
|
||||
<a-statistic title="可用余额" :value="amountToYuan(summary.availableAmount)" suffix="元" />
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-statistic title="冻结余额" :value="amountToYuan(summary.frozenAmount)" suffix="元" />
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-statistic title="累计收入" :value="amountToYuan(summary.totalIncomeAmount)" suffix="元" />
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-statistic title="累计提现" :value="amountToYuan(summary.totalWithdrawAmount)" suffix="元" />
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<div class="wallet-actions">
|
||||
<a-space>
|
||||
<a-button type="primary" @click="openWithdrawSetting">提现设置</a-button>
|
||||
<a-input-number v-model:value="withdrawAmountYuan" :min="0" addon-before="提现金额" addon-after="元" />
|
||||
<a-button @click="applyWithdraw">申请提现</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
|
||||
<fs-crud ref="withdrawCrudRef" class="wallet-crud" v-bind="withdrawCrudBinding" />
|
||||
</div>
|
||||
</fs-page>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onActivated, onMounted, reactive, ref } from "vue";
|
||||
import { compute, dict, useFs } from "@fast-crud/fast-crud";
|
||||
import { notification } from "ant-design-vue";
|
||||
import * as api from "./api";
|
||||
import createWithdrawCrudOptions from "./crud-withdraw";
|
||||
import { util } from "/@/utils";
|
||||
import { useFormDialog } from "/@/use/use-dialog";
|
||||
|
||||
defineOptions({ name: "MyWallet" });
|
||||
|
||||
const summary = reactive<any>({ availableAmount: 0, frozenAmount: 0, totalIncomeAmount: 0, totalWithdrawAmount: 0 });
|
||||
const withdrawAmountYuan = ref(0);
|
||||
const loaded = ref(false);
|
||||
const { openFormDialog } = useFormDialog();
|
||||
const { crudBinding: withdrawCrudBinding, crudExpose: withdrawCrudExpose, crudRef: withdrawCrudRef } = useFs({ createCrudOptions: createWithdrawCrudOptions });
|
||||
|
||||
function amountToYuan(amount: number) {
|
||||
return util.amount.toYuan(amount || 0);
|
||||
}
|
||||
|
||||
async function loadWalletSummary() {
|
||||
const res: any = await api.GetWalletSummary();
|
||||
Object.assign(summary, res || {});
|
||||
}
|
||||
|
||||
async function openWithdrawSetting() {
|
||||
const setting: any = await api.GetWithdrawSetting();
|
||||
const initialForm = Object.assign({ channel: "alipay", realName: "", account: "", bankName: "" }, setting || {});
|
||||
await openFormDialog({
|
||||
title: "提现设置",
|
||||
wrapper: {
|
||||
width: 560,
|
||||
},
|
||||
initialForm,
|
||||
columns: {
|
||||
channel: {
|
||||
title: "提现渠道",
|
||||
type: "dict-radio",
|
||||
dict: dict({
|
||||
data: [
|
||||
{ label: "支付宝", value: "alipay" },
|
||||
{ label: "银行卡", value: "bank" },
|
||||
],
|
||||
}),
|
||||
form: {
|
||||
col: { span: 24 },
|
||||
rules: [{ required: true, message: "请选择提现渠道" }],
|
||||
},
|
||||
},
|
||||
realName: {
|
||||
title: "真实姓名",
|
||||
type: "text",
|
||||
form: {
|
||||
col: { span: 24 },
|
||||
rules: [{ required: true, message: "请输入真实姓名" }],
|
||||
},
|
||||
},
|
||||
account: {
|
||||
title: "收款账号",
|
||||
type: "text",
|
||||
form: {
|
||||
col: { span: 24 },
|
||||
rules: [{ required: true, message: "请输入收款账号" }],
|
||||
},
|
||||
},
|
||||
bankName: {
|
||||
title: "开户银行",
|
||||
type: "text",
|
||||
form: {
|
||||
col: { span: 24 },
|
||||
show: compute(({ form }) => form.channel === "bank"),
|
||||
rules: [{ required: compute(({ form }) => form.channel === "bank"), message: "请输入开户银行" }],
|
||||
},
|
||||
},
|
||||
},
|
||||
async onSubmit(form: any) {
|
||||
await api.SaveWithdrawSetting(form);
|
||||
notification.success({ message: "保存成功" });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async function applyWithdraw() {
|
||||
await api.ApplyWithdraw(util.amount.toCent(withdrawAmountYuan.value || 0));
|
||||
withdrawAmountYuan.value = 0;
|
||||
await loadWalletSummary();
|
||||
await withdrawCrudExpose.doRefresh();
|
||||
notification.success({ message: "提现申请已提交" });
|
||||
}
|
||||
|
||||
async function refreshWalletPage() {
|
||||
await loadWalletSummary();
|
||||
await withdrawCrudExpose.doRefresh();
|
||||
loaded.value = true;
|
||||
}
|
||||
|
||||
onMounted(refreshWalletPage);
|
||||
|
||||
onActivated(async () => {
|
||||
if (!loaded.value) {
|
||||
return;
|
||||
}
|
||||
await refreshWalletPage();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.page-wallet {
|
||||
display: flex;
|
||||
min-height: 0;
|
||||
|
||||
.fs-page-content {
|
||||
display: flex;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.wallet-body {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.wallet-summary,
|
||||
.wallet-actions {
|
||||
flex: none;
|
||||
}
|
||||
|
||||
.wallet-actions {
|
||||
margin: 16px 0 10px;
|
||||
}
|
||||
|
||||
.wallet-crud {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -20,10 +20,14 @@
|
||||
<div class="flex-between mt-5">
|
||||
<div class="flex-o">
|
||||
<fs-icon icon="ant-design:check-outlined" class="color-green mr-5" />
|
||||
域名数量:
|
||||
域名总数量:
|
||||
</div>
|
||||
<suite-value :model-value="detail.domainCount.max" :used="detail.domainCount.used" unit="个" />
|
||||
</div>
|
||||
<div class="flex-between mt-5">
|
||||
<div class="flex-o ml-20">- 其中泛域名数量:</div>
|
||||
<suite-value :model-value="detail.wildcardDomainCount.max" :used="detail.wildcardDomainCount.used" unit="个" />
|
||||
</div>
|
||||
<div class="flex-between mt-5">
|
||||
<div class="flex-o">
|
||||
<fs-icon icon="ant-design:check-outlined" class="color-green mr-5" />
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
<!-- eslint-disable vue/multi-word-component-names -->
|
||||
<template>
|
||||
<div class="main login-page">
|
||||
<a-form v-if="!twoFactor.loginId" ref="formRef" class="user-layout-login" name="custom-validation" :model="formState" v-bind="layout" @finish="handleFinish" @finish-failed="handleFinishFailed">
|
||||
@@ -108,6 +109,7 @@ import * as oauthApi from "../oauth/api";
|
||||
import { notification } from "ant-design-vue";
|
||||
import { request } from "/src/api/service";
|
||||
import * as UserApi from "/src/store/user/api.user";
|
||||
import { inviteUtils } from "/@/utils/util.invite";
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
@@ -136,6 +138,7 @@ const formState = reactive({
|
||||
smsCode: "",
|
||||
captcha: null,
|
||||
smsCaptcha: null,
|
||||
inviteCode: inviteUtils.get(),
|
||||
});
|
||||
|
||||
const rules = {
|
||||
|
||||
@@ -78,6 +78,14 @@
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
|
||||
<a-form-item v-if="registerType !== 'mobile'" has-feedback name="inviteCode" label="邀请码">
|
||||
<a-input v-model:value="formState.inviteCode" placeholder="邀请码(选填)" size="large" autocomplete="off">
|
||||
<template #prefix>
|
||||
<fs-icon icon="ion:gift-outline"></fs-icon>
|
||||
</template>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-if="registerType !== 'mobile'">
|
||||
<a-button type="primary" size="large" html-type="submit" class="login-button">注册</a-button>
|
||||
</a-form-item>
|
||||
@@ -97,6 +105,7 @@ import { useSettingStore } from "/@/store/settings";
|
||||
import { notification } from "ant-design-vue";
|
||||
import CaptchaInput from "/@/components/captcha/captcha-input.vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { inviteUtils } from "/@/utils/util.invite";
|
||||
export default defineComponent({
|
||||
name: "RegisterPage",
|
||||
components: { CaptchaInput, EmailCode },
|
||||
@@ -125,6 +134,7 @@ export default defineComponent({
|
||||
confirmPassword: "",
|
||||
captcha: null,
|
||||
captchaForEmail: null,
|
||||
inviteCode: inviteUtils.get(),
|
||||
});
|
||||
|
||||
const rules = {
|
||||
@@ -213,6 +223,7 @@ export default defineComponent({
|
||||
email: formState.email,
|
||||
captcha: registerType.value === "email" ? formState.captchaForEmail : formState.captcha,
|
||||
validateCode: formState.validateCode,
|
||||
inviteCode: formState.inviteCode,
|
||||
}) as any
|
||||
);
|
||||
} finally {
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { request } from "/@/api/service";
|
||||
|
||||
export async function GetSettings() {
|
||||
return await request({ url: "/sys/invite/settings/get", method: "post" });
|
||||
}
|
||||
|
||||
export async function SaveSettings(data: any) {
|
||||
return await request({ url: "/sys/invite/settings/save", method: "post", data });
|
||||
}
|
||||
|
||||
export async function GetWithdraws(query: any) {
|
||||
return await request({ url: "/sys/wallet/withdraw/page", method: "post", data: query });
|
||||
}
|
||||
|
||||
export async function ApproveWithdraw(id: number, remark?: string) {
|
||||
return await request({ url: "/sys/wallet/withdraw/approve", method: "post", data: { id, remark } });
|
||||
}
|
||||
|
||||
export async function RejectWithdraw(id: number, remark: string) {
|
||||
return await request({ url: "/sys/wallet/withdraw/reject", method: "post", data: { id, remark } });
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
import { compute, CreateCrudOptionsProps, CreateCrudOptionsRet, dict, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||
import { Modal, notification } from "ant-design-vue";
|
||||
import * as api from "./api";
|
||||
import PriceInput from "/@/views/sys/suite/product/price-input.vue";
|
||||
import { useFormDialog } from "/@/use/use-dialog";
|
||||
|
||||
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||
const { openFormDialog } = useFormDialog();
|
||||
|
||||
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
||||
return await api.GetWithdraws(query);
|
||||
};
|
||||
|
||||
async function approve(row: any) {
|
||||
Modal.confirm({
|
||||
title: "确认提现已线下打款?",
|
||||
async onOk() {
|
||||
await api.ApproveWithdraw(row.id);
|
||||
await crudExpose.doRefresh();
|
||||
notification.success({ message: "已审核通过" });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async function reject(row: any) {
|
||||
await openFormDialog({
|
||||
title: "拒绝提现申请",
|
||||
wrapper: {
|
||||
width: 520,
|
||||
},
|
||||
initialForm: {
|
||||
remark: "",
|
||||
},
|
||||
columns: {
|
||||
remark: {
|
||||
title: "拒绝理由",
|
||||
type: "textarea",
|
||||
form: {
|
||||
col: {
|
||||
span: 24,
|
||||
},
|
||||
component: {
|
||||
name: "a-textarea",
|
||||
vModel: "value",
|
||||
rows: 4,
|
||||
placeholder: "请填写拒绝理由",
|
||||
},
|
||||
rules: [{ required: true, message: "请填写拒绝理由" }],
|
||||
},
|
||||
},
|
||||
},
|
||||
async onSubmit(form: any) {
|
||||
const remark = form.remark.trim();
|
||||
if (!remark) {
|
||||
notification.error({ message: "请填写拒绝理由" });
|
||||
throw new Error("请填写拒绝理由");
|
||||
}
|
||||
await api.RejectWithdraw(row.id, remark);
|
||||
await crudExpose.doRefresh();
|
||||
notification.success({ message: "已拒绝并退回余额" });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
crudOptions: {
|
||||
request: { pageRequest },
|
||||
actionbar: { show: false },
|
||||
toolbar: { show: false },
|
||||
rowHandle: {
|
||||
width: 150,
|
||||
fixed: "right",
|
||||
buttons: {
|
||||
view: { show: false },
|
||||
edit: { show: false },
|
||||
copy: { show: false },
|
||||
remove: { show: false },
|
||||
approve: {
|
||||
text: "通过",
|
||||
type: "link",
|
||||
show: compute(({ row }) => row.status === "pending"),
|
||||
click: ({ row }) => approve(row),
|
||||
},
|
||||
reject: {
|
||||
text: "拒绝",
|
||||
type: "link",
|
||||
show: compute(({ row }) => row.status === "pending"),
|
||||
click: ({ row }) => reject(row),
|
||||
},
|
||||
},
|
||||
},
|
||||
columns: {
|
||||
userId: { title: "用户ID", type: "number", search: { show: true }, column: { width: 100 } },
|
||||
amount: {
|
||||
title: "金额",
|
||||
type: "number",
|
||||
column: {
|
||||
width: 120,
|
||||
component: { name: PriceInput, vModel: "modelValue", edit: false },
|
||||
},
|
||||
},
|
||||
status: {
|
||||
title: "状态",
|
||||
type: "dict-select",
|
||||
search: { show: true },
|
||||
dict: dict({
|
||||
data: [
|
||||
{ label: "待审核", value: "pending", color: "warning" },
|
||||
{ label: "已通过", value: "approved", color: "success" },
|
||||
{ label: "已拒绝", value: "rejected", color: "error" },
|
||||
],
|
||||
}),
|
||||
column: { width: 110 },
|
||||
},
|
||||
channel: {
|
||||
title: "提现渠道",
|
||||
type: "dict-select",
|
||||
search: { show: true },
|
||||
dict: dict({
|
||||
data: [
|
||||
{ label: "支付宝", value: "alipay" },
|
||||
{ label: "银行卡", value: "bank" },
|
||||
],
|
||||
}),
|
||||
column: { width: 110 },
|
||||
},
|
||||
realName: { title: "真实姓名", type: "text", search: { show: true }, column: { width: 120 } },
|
||||
account: { title: "收款账号", type: "text", column: { width: 180 } },
|
||||
bankName: { title: "开户银行", type: "text", column: { width: 160 } },
|
||||
auditRemark: { title: "审核备注", type: "text", column: { minWidth: 180 } },
|
||||
createTime: { title: "申请时间", type: "datetime", column: { width: 180 } },
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<template>
|
||||
<fs-page class="page-sys-invite-setting">
|
||||
<template #header>
|
||||
<div class="title">邀请返佣设置</div>
|
||||
</template>
|
||||
<div class="page-body">
|
||||
<a-form ref="formRef" :model="settings" :label-col="{ style: { width: '140px' } }" class="settings-form">
|
||||
<a-form-item label="开启返佣" name="enabled">
|
||||
<a-switch v-model:checked="settings.enabled" />
|
||||
</a-form-item>
|
||||
<a-form-item label="返佣比例" name="commissionRate">
|
||||
<a-input-number v-model:value="settings.commissionRate" :min="0" :max="100" addon-after="%" />
|
||||
</a-form-item>
|
||||
<a-form-item label="最低提现金额" name="minWithdrawAmountYuan">
|
||||
<a-input-number v-model:value="settings.minWithdrawAmountYuan" :min="0" addon-after="元" />
|
||||
</a-form-item>
|
||||
<a-form-item label="提现渠道" name="withdrawChannels">
|
||||
<a-checkbox-group v-model:value="settings.withdrawChannels" :options="withdrawChannelOptions" />
|
||||
</a-form-item>
|
||||
<a-form-item label=" ">
|
||||
<a-button type="primary" @click="saveSettings">保存设置</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
</fs-page>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, reactive } from "vue";
|
||||
import { notification } from "ant-design-vue";
|
||||
import * as api from "./api";
|
||||
import { util } from "/@/utils";
|
||||
import { useSettingStore } from "/@/store/settings";
|
||||
|
||||
defineOptions({ name: "SysInviteCommissionSetting" });
|
||||
|
||||
const settings = reactive<any>({ enabled: false, commissionRate: 0, minWithdrawAmountYuan: 0, withdrawChannels: ["alipay", "bank"] });
|
||||
const withdrawChannelOptions = [
|
||||
{ label: "支付宝", value: "alipay" },
|
||||
{ label: "银行卡", value: "bank" },
|
||||
];
|
||||
|
||||
async function loadSettings() {
|
||||
const data: any = await api.GetSettings();
|
||||
settings.enabled = !!data?.enabled;
|
||||
settings.commissionRate = data?.commissionRate || 0;
|
||||
settings.minWithdrawAmountYuan = util.amount.toYuan(data?.minWithdrawAmount || 0);
|
||||
settings.withdrawChannels = data?.withdrawChannels?.length ? data.withdrawChannels : ["alipay", "bank"];
|
||||
}
|
||||
|
||||
async function saveSettings() {
|
||||
await api.SaveSettings({
|
||||
enabled: settings.enabled,
|
||||
commissionRate: settings.commissionRate || 0,
|
||||
minWithdrawAmount: util.amount.toCent(settings.minWithdrawAmountYuan || 0),
|
||||
withdrawChannels: settings.withdrawChannels || [],
|
||||
});
|
||||
await useSettingStore().loadSysSettings();
|
||||
notification.success({ message: "保存成功" });
|
||||
}
|
||||
|
||||
onMounted(loadSettings);
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.page-sys-invite-setting {
|
||||
.page-body {
|
||||
padding: 20px;
|
||||
}
|
||||
.settings-form {
|
||||
max-width: 720px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,25 @@
|
||||
<template>
|
||||
<fs-page class="page-sys-invite-withdraw">
|
||||
<template #header>
|
||||
<div class="title">提现申请记录</div>
|
||||
</template>
|
||||
<fs-crud ref="crudRef" v-bind="crudBinding" />
|
||||
</fs-page>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onActivated, onMounted } from "vue";
|
||||
import { useFs } from "@fast-crud/fast-crud";
|
||||
import createCrudOptions from "./crud-withdraw";
|
||||
|
||||
defineOptions({ name: "SysInviteWithdraw" });
|
||||
|
||||
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions });
|
||||
|
||||
onMounted(() => {
|
||||
crudExpose.doRefresh();
|
||||
});
|
||||
onActivated(() => {
|
||||
crudExpose.doRefresh();
|
||||
});
|
||||
</script>
|
||||
@@ -59,7 +59,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
},
|
||||
content: {
|
||||
header: t("certd.packageContent"),
|
||||
columns: ["content.maxDomainCount", "content.maxPipelineCount", "content.maxDeployCount", "content.maxMonitorCount"],
|
||||
columns: ["content.maxDomainCount", "content.maxWildcardDomainCount", "content.maxPipelineCount", "content.maxDeployCount", "content.maxMonitorCount"],
|
||||
},
|
||||
price: {
|
||||
header: t("certd.price"),
|
||||
@@ -154,6 +154,28 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
},
|
||||
},
|
||||
},
|
||||
"content.maxWildcardDomainCount": {
|
||||
title: t("certd.wildcardDomainCountPart"),
|
||||
type: "text",
|
||||
form: {
|
||||
key: ["content", "maxWildcardDomainCount"],
|
||||
helper: t("certd.wildcardDomainCountHelper"),
|
||||
component: {
|
||||
name: SuiteValueEdit,
|
||||
vModel: "modelValue",
|
||||
unit: t("certd.unitCount"),
|
||||
},
|
||||
rules: [{ required: true, message: t("certd.requiredField") }],
|
||||
},
|
||||
column: {
|
||||
width: 120,
|
||||
component: {
|
||||
name: SuiteValue,
|
||||
vModel: "modelValue",
|
||||
unit: t("certd.unitCount"),
|
||||
},
|
||||
},
|
||||
},
|
||||
"content.maxPipelineCount": {
|
||||
title: t("certd.pipelineCount"),
|
||||
type: "text",
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
<div style="height: 400px">
|
||||
<ProductManager @refreshed="onTableRefresh"></ProductManager>
|
||||
</div>
|
||||
<div class="helper">泛域名数量受域名总数量限制:泛域名会同时占用域名总数量和泛域名数量额度。</div>
|
||||
<div class="helper">不建议设置免费套餐,可以在下方配置注册赠送套餐,或者在用户套餐管理中手动赠送套餐</div>
|
||||
</a-form-item>
|
||||
|
||||
|
||||
@@ -174,6 +174,30 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
},
|
||||
},
|
||||
},
|
||||
rebateAmount: {
|
||||
title: "返利抵扣",
|
||||
type: "number",
|
||||
column: {
|
||||
width: 110,
|
||||
component: {
|
||||
name: PriceInput,
|
||||
vModel: "modelValue",
|
||||
edit: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
thirdPartyPayAmount: {
|
||||
title: "实付金额",
|
||||
type: "number",
|
||||
column: {
|
||||
width: 110,
|
||||
component: {
|
||||
name: PriceInput,
|
||||
vModel: "modelValue",
|
||||
edit: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
status: {
|
||||
title: "状态",
|
||||
search: { show: true },
|
||||
@@ -200,6 +224,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
{ label: "支付宝", value: "alipay" },
|
||||
{ label: "微信", value: "wxpay" },
|
||||
{ label: "免费", value: "free" },
|
||||
{ label: "返利余额", value: "rebate" },
|
||||
],
|
||||
}),
|
||||
column: {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||
import { sysUserSuiteApi } from "./api";
|
||||
import { useRouter } from "vue-router";
|
||||
import SuiteValueEdit from "/@/views/sys/suite/product/suite-value-edit.vue";
|
||||
import SuiteValue from "/@/views/sys/suite/product/suite-value.vue";
|
||||
import DurationValue from "/@/views/sys/suite/product/duration-value.vue";
|
||||
@@ -33,8 +32,6 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
return res;
|
||||
};
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
return {
|
||||
crudOptions: {
|
||||
request: {
|
||||
@@ -71,7 +68,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
buttons: {
|
||||
view: { show: true },
|
||||
copy: { show: false },
|
||||
edit: { show: false },
|
||||
edit: { show: true },
|
||||
remove: { show: true },
|
||||
// continue:{
|
||||
// text:"续期",
|
||||
@@ -107,7 +104,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
show: true,
|
||||
},
|
||||
form: {
|
||||
show: false,
|
||||
rules: [{ required: true, message: t("certd.field_required") }],
|
||||
},
|
||||
column: {
|
||||
width: 200,
|
||||
@@ -127,7 +124,9 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
label: "nickName",
|
||||
}),
|
||||
form: {
|
||||
show: true,
|
||||
component: {
|
||||
disabled: true,
|
||||
crossPage: true,
|
||||
multiple: false,
|
||||
select: {
|
||||
@@ -183,7 +182,10 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
],
|
||||
}),
|
||||
form: {
|
||||
show: false,
|
||||
show: true,
|
||||
component: {
|
||||
disabled: true,
|
||||
},
|
||||
},
|
||||
column: {
|
||||
width: 80,
|
||||
@@ -204,7 +206,6 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
title: t("certd.domain_count"),
|
||||
type: "text",
|
||||
form: {
|
||||
show: false,
|
||||
key: ["content", "maxDomainCount"],
|
||||
component: {
|
||||
name: SuiteValueEdit,
|
||||
@@ -223,11 +224,32 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
align: "center",
|
||||
},
|
||||
},
|
||||
"content.maxWildcardDomainCount": {
|
||||
title: t("certd.wildcardDomainCountPart"),
|
||||
type: "text",
|
||||
form: {
|
||||
key: ["content", "maxWildcardDomainCount"],
|
||||
component: {
|
||||
name: SuiteValueEdit,
|
||||
vModel: "modelValue",
|
||||
unit: t("certd.unit_count"),
|
||||
},
|
||||
rules: [{ required: true, message: t("certd.field_required") }],
|
||||
},
|
||||
column: {
|
||||
width: 120,
|
||||
component: {
|
||||
name: SuiteValue,
|
||||
vModel: "modelValue",
|
||||
unit: t("certd.unit_count"),
|
||||
},
|
||||
align: "center",
|
||||
},
|
||||
},
|
||||
"content.maxPipelineCount": {
|
||||
title: t("certd.pipeline_count"),
|
||||
type: "text",
|
||||
form: {
|
||||
show: false,
|
||||
key: ["content", "maxPipelineCount"],
|
||||
component: {
|
||||
name: SuiteValueEdit,
|
||||
@@ -250,7 +272,6 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
title: t("certd.deploy_count"),
|
||||
type: "text",
|
||||
form: {
|
||||
show: false,
|
||||
key: ["content", "maxDeployCount"],
|
||||
component: {
|
||||
name: SuiteValueEdit,
|
||||
@@ -276,7 +297,6 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
title: t("certd.monitor_count"),
|
||||
type: "text",
|
||||
form: {
|
||||
show: false,
|
||||
key: ["content", "maxMonitorCount"],
|
||||
component: {
|
||||
name: SuiteValueEdit,
|
||||
@@ -298,7 +318,9 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
duration: {
|
||||
title: t("certd.duration"),
|
||||
type: "text",
|
||||
form: { show: false },
|
||||
form: {
|
||||
rules: [{ required: true, message: t("certd.field_required") }],
|
||||
},
|
||||
column: {
|
||||
component: {
|
||||
name: DurationValue,
|
||||
@@ -342,7 +364,13 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
title: t("certd.expires_time"),
|
||||
type: "date",
|
||||
form: {
|
||||
show: false,
|
||||
valueBuilder: ({ value }) => {
|
||||
return dayjs(value);
|
||||
},
|
||||
valueResolve: ({ value }) => {
|
||||
//今天的最后一秒
|
||||
return dayjs(value).endOf("day").valueOf();
|
||||
},
|
||||
},
|
||||
column: {
|
||||
width: 150,
|
||||
@@ -367,13 +395,56 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
}),
|
||||
form: {
|
||||
value: true,
|
||||
show: false,
|
||||
},
|
||||
column: {
|
||||
width: 100,
|
||||
align: "center",
|
||||
},
|
||||
},
|
||||
deployCountUsed: {
|
||||
title: t("certd.deploy_count_used"),
|
||||
type: "number",
|
||||
form: {
|
||||
value: 0,
|
||||
rules: [{ required: true, message: t("certd.field_required") }],
|
||||
},
|
||||
column: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
disabled: {
|
||||
title: t("certd.disabled"),
|
||||
type: "dict-switch",
|
||||
dict: dict({
|
||||
data: [
|
||||
{ label: t("certd.enabledLabel"), value: false, color: "success" },
|
||||
{ label: t("certd.disabledLabel"), value: true, color: "error" },
|
||||
],
|
||||
}),
|
||||
form: {
|
||||
value: false,
|
||||
},
|
||||
column: {
|
||||
width: 100,
|
||||
align: "center",
|
||||
},
|
||||
},
|
||||
isEmpty: {
|
||||
title: t("certd.status"),
|
||||
type: "dict-switch",
|
||||
dict: dict({
|
||||
data: [
|
||||
{ label: t("certd.normal"), value: false, color: "success" },
|
||||
{ label: t("certd.used_up"), value: true, color: "gray" },
|
||||
],
|
||||
}),
|
||||
form: {
|
||||
value: false,
|
||||
},
|
||||
column: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
createTime: {
|
||||
title: t("certd.createTime"),
|
||||
type: "datetime",
|
||||
|
||||
@@ -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.40.1](https://github.com/certd/certd/compare/v1.40.0...v1.40.1) (2026-05-18)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 固化华为云sdk版本,避免华为云调用报错 ([59b9ffa](https://github.com/certd/certd/commit/59b9ffadd05faf3982151c48f8d83cbd97419865))
|
||||
* **email-service:** 优化商业版测试邮件内容中带的url链接 ([667e7b1](https://github.com/certd/certd/commit/667e7b185bf26558972be01720872f48352b5876))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 商业版支持限制泛域名数量 ([c63745d](https://github.com/certd/certd/commit/c63745d1ba30904428ba6b13ab0785298baa5cae))
|
||||
|
||||
# [1.40.0](https://github.com/certd/certd/compare/v1.39.16...v1.40.0) (2026-05-14)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE cd_cert_info ADD COLUMN wildcard_domain_count bigint NOT NULL DEFAULT 0;
|
||||
@@ -0,0 +1,88 @@
|
||||
ALTER TABLE cd_trade ADD COLUMN rebate_amount bigint NOT NULL DEFAULT 0;
|
||||
ALTER TABLE cd_trade ADD COLUMN third_party_pay_amount bigint NOT NULL DEFAULT 0;
|
||||
|
||||
CREATE TABLE `cd_invite_code`
|
||||
(
|
||||
`id` bigint PRIMARY KEY AUTO_INCREMENT NOT NULL,
|
||||
`user_id` bigint,
|
||||
`code` varchar(50),
|
||||
`disabled` boolean NOT NULL DEFAULT false,
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE UNIQUE INDEX `index_invite_code_user_id` ON `cd_invite_code` (`user_id`);
|
||||
CREATE UNIQUE INDEX `index_invite_code_code` ON `cd_invite_code` (`code`);
|
||||
|
||||
CREATE TABLE `cd_invite_relation`
|
||||
(
|
||||
`id` bigint PRIMARY KEY AUTO_INCREMENT NOT NULL,
|
||||
`inviter_user_id` bigint,
|
||||
`invitee_user_id` bigint,
|
||||
`invite_code` varchar(50),
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX `index_invite_relation_inviter` ON `cd_invite_relation` (`inviter_user_id`);
|
||||
CREATE UNIQUE INDEX `index_invite_relation_invitee` ON `cd_invite_relation` (`invitee_user_id`);
|
||||
|
||||
CREATE TABLE `cd_user_wallet`
|
||||
(
|
||||
`id` bigint PRIMARY KEY AUTO_INCREMENT NOT NULL,
|
||||
`user_id` bigint,
|
||||
`available_amount` bigint NOT NULL DEFAULT 0,
|
||||
`frozen_amount` bigint NOT NULL DEFAULT 0,
|
||||
`total_income_amount` bigint NOT NULL DEFAULT 0,
|
||||
`total_consumed_amount` bigint NOT NULL DEFAULT 0,
|
||||
`total_withdraw_amount` bigint NOT NULL DEFAULT 0,
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE UNIQUE INDEX `index_user_wallet_user_id` ON `cd_user_wallet` (`user_id`);
|
||||
|
||||
CREATE TABLE `cd_invite_commission_log`
|
||||
(
|
||||
`id` bigint PRIMARY KEY AUTO_INCREMENT NOT NULL,
|
||||
`user_id` bigint,
|
||||
`amount` bigint,
|
||||
`trade_id` bigint,
|
||||
`invitee_user_id` bigint,
|
||||
`consume_amount` bigint NOT NULL DEFAULT 0,
|
||||
`remark` varchar(2048),
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX `index_invite_log_user_id` ON `cd_invite_commission_log` (`user_id`);
|
||||
|
||||
CREATE TABLE `cd_user_wallet_log`
|
||||
(
|
||||
`id` bigint PRIMARY KEY AUTO_INCREMENT NOT NULL,
|
||||
`user_id` bigint,
|
||||
`type` varchar(50),
|
||||
`amount` bigint,
|
||||
`balance_after` bigint,
|
||||
`trade_id` bigint,
|
||||
`withdraw_id` bigint,
|
||||
`remark` varchar(2048),
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX `index_user_wallet_log_user_id` ON `cd_user_wallet_log` (`user_id`);
|
||||
|
||||
CREATE TABLE `cd_user_wallet_withdraw`
|
||||
(
|
||||
`id` bigint PRIMARY KEY AUTO_INCREMENT NOT NULL,
|
||||
`user_id` bigint,
|
||||
`amount` bigint,
|
||||
`status` varchar(50),
|
||||
`channel` varchar(50),
|
||||
`real_name` varchar(100),
|
||||
`account` varchar(200),
|
||||
`bank_name` varchar(200),
|
||||
`audit_user_id` bigint,
|
||||
`audit_remark` varchar(2048),
|
||||
`audit_time` bigint,
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX `index_user_wallet_withdraw_user_id` ON `cd_user_wallet_withdraw` (`user_id`);
|
||||
CREATE INDEX `index_user_wallet_withdraw_status` ON `cd_user_wallet_withdraw` (`status`);
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE cd_cert_info ADD COLUMN wildcard_domain_count bigint NOT NULL DEFAULT 0;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user