diff --git a/README.md b/README.md
index f253c3add..9a09765bd 100644
--- a/README.md
+++ b/README.md
@@ -141,7 +141,14 @@ https://certd.handfree.work/
## 五、生态
-### 1. 客户端工具 SSL-Assistant
+### 1. 官方客户端 Certd Client
+
+`Certd Client` 是 Certd 官方证书部署客户端,运行于应用服务器上。自动发现本机 Nginx、Apache 和 IIS 站点,从 Certd 获取新证书并部署到本机。适用于不希望服务器开放 SSH、无法由 Certd 直接访问目标服务器的场景。
+
+项目主页:[AtomGit](https://atomgit.com/certd/certd-client/) | [GitHub](https://github.com/certd/certd-client/)
+下载地址:[AtomGit Releases](https://atomgit.com/certd/certd-client/releases) | [GitHub Releases](https://github.com/certd/certd-client/releases)
+
+### 2. 第三方客户端 SSL-Assistant
`SSL Assistant` 是一个运行于主机上的证书部署管理助手客户端。
支持自动扫描主机`Nginx`配置,然后从`Certd`拉取证书并部署。
diff --git a/README_en.md b/README_en.md
index 230a13b4b..d0a6ea1b2 100644
--- a/README_en.md
+++ b/README_en.md
@@ -123,7 +123,14 @@ You can choose one of the following deployment methods based on your needs:
## 5. Ecosystem
-### 1. Client Tool: SSL-Assistant
+### 1. Official Client: Certd Client
+
+`Certd Client` is the official Certd certificate deployment client that runs on application servers. It automatically discovers local Nginx, Apache, and IIS sites, retrieves new certificates from Certd, and deploys them locally. It is designed for servers that should not expose SSH or cannot be accessed directly by Certd.
+
+Project Home: [AtomGit](https://atomgit.com/certd/certd-client/) | [GitHub](https://github.com/certd/certd-client/)
+Downloads: [AtomGit Releases](https://atomgit.com/certd/certd-client/releases) | [GitHub Releases](https://github.com/certd/certd-client/releases)
+
+### 2. Third-Party Client: SSL-Assistant
`SSL Assistant` is a certificate deployment and management assistant client that runs on hosts. It supports automatic scanning of the host's `Nginx` configuration and pulling certificates from `Certd` for deployment. This tool is very useful when you don't want to expose your SSH host password.
diff --git a/docs/guide/open/index.md b/docs/guide/open/index.md
index 1aeb92a37..36559ca48 100644
--- a/docs/guide/open/index.md
+++ b/docs/guide/open/index.md
@@ -47,7 +47,13 @@ header中传入x-certd-token即可调用开放接口
## 客户端工具
-### SSL-Assistant
+### 官方客户端:Certd Client
+`Certd Client` 是 Certd 的官方证书部署客户端。运行在应用服务器上,自动发现本机 Nginx、Apache 和 IIS 站点,然后从 Certd 获取新证书并部署到本机。适用于不希望服务器开放 SSH、无法由 Certd 直接访问目标服务器的场景。
+
+项目主页:[AtomGit](https://atomgit.com/certd/certd-client/) | [GitHub](https://github.com/certd/certd-client/)
+下载地址:[AtomGit Releases](https://atomgit.com/certd/certd-client/releases) | [GitHub Releases](https://github.com/certd/certd-client/releases)
+
+### 第三方客户端:SSL-Assistant
`SSL Assistant` 是一个基于 Go 语言开发的跨平台证书部署管理助手。
支持自动扫描主机`Nginx`配置,然后从Certd拉取证书并部署。
在不想暴露ssh主机密码情况下,该工具非常好用。
diff --git a/packages/ui/certd-client/src/layout/components/menu/index.less b/packages/ui/certd-client/src/layout/components/menu/index.less
deleted file mode 100644
index 80d2be846..000000000
--- a/packages/ui/certd-client/src/layout/components/menu/index.less
+++ /dev/null
@@ -1,15 +0,0 @@
-.fs-menu-wrapper {
- height: 100%;
- overflow-y: auto;
- &.fs-menu-better-scroll {
- overflow-y: hidden;
- }
- .menu-item-title {
- display: flex;
- align-items: center;
- .fs-icon {
- font-size: 16px !important;
- min-width: 16px !important;
- }
- }
-}
diff --git a/packages/ui/certd-client/src/layout/components/menu/index.vue b/packages/ui/certd-client/src/layout/components/menu/index.vue
deleted file mode 100644
index 4605f5704..000000000
--- a/packages/ui/certd-client/src/layout/components/menu/index.vue
+++ /dev/null
@@ -1,124 +0,0 @@
-
-
-
-
-
-
diff --git a/packages/ui/certd-client/src/layout/components/menu/index1.tsx b/packages/ui/certd-client/src/layout/components/menu/index1.tsx
deleted file mode 100644
index e21c7d1ca..000000000
--- a/packages/ui/certd-client/src/layout/components/menu/index1.tsx
+++ /dev/null
@@ -1,183 +0,0 @@
-import { useRoute, useRouter } from "vue-router";
-import { ref, watch, onMounted, onUnmounted, resolveComponent, nextTick, defineComponent } from "vue";
-import * as _ from "lodash-es";
-import BScroll from "better-scroll";
-import "./index.less";
-import { utils } from "@fast-crud/fast-crud";
-import { routerUtils } from "/@/utils/util.router";
-
-defineOptions();
-
-export default defineComponent({
- name: "FsMenu",
- inheritAttrs: true,
- props: {
- menus: {},
- expandSelected: {
- default: false,
- },
- scroll: {},
- },
- setup(props, ctx) {
- async function onSelect(item: any) {
- await routerUtils.open(item.key);
- }
-
- const items = ref([]);
-
- function buildItemMenus(menus: any) {
- if (menus == null) {
- return;
- }
- const list: any = [];
- for (const sub of menus) {
- const item: any = {
- key: sub.path,
- label: sub.title,
- title: sub.title,
- icon: () => {
- return ;
- },
- };
- list.push(item);
- if (sub.children && sub.children.length > 0) {
- item.children = buildItemMenus(sub.children);
- }
- }
- return list;
- }
- items.value = buildItemMenus(props.menus);
- console.log("items", items.value);
- const fsIcon = resolveComponent("FsIcon");
-
- const buildMenus = (children: any) => {
- const slots: any = [];
- if (children == null) {
- return slots;
- }
- for (const sub of children) {
- if (sub.meta?.show != null) {
- if (sub.meta.show === false || (typeof sub.meta.show === "function" && !sub.meta.show())) {
- continue;
- }
- }
- const title: any = () => {
- const icon = sub.icon || sub?.meta?.icon;
- if (icon) {
- // @ts-ignore , anticon必须要有,不然不能折叠
- return (
-
- );
- }
- return sub.title;
- };
- if (sub.children && sub.children.length > 0) {
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- const subSlots = {
- default: () => {
- return buildMenus(sub.children);
- },
- title,
- };
- function onTitleClick() {
- if (sub.path && ctx.attrs.mode === "horizontal") {
- open(sub.path);
- }
- }
- slots.push();
- } else {
- slots.push(
-
- {title}
-
- );
- }
- }
- return slots;
- };
- const slots = {
- default() {
- return buildMenus(props.menus);
- },
- };
- const selectedKeys = ref([]);
- const openKeys = ref([]);
-
- const route = useRoute();
- const router = useRouter();
-
- function openSelectedParents(fullPath: any) {
- if (!props.expandSelected) {
- return;
- }
- if (props.menus == null) {
- return;
- }
- const keys: any = [];
- let changed = false;
- utils.deepdash.forEachDeep(props.menus, (value: any, key: any, parent: any, context: any) => {
- if (value == null) {
- return;
- }
- if (value.path === fullPath) {
- _.forEach(context.parents, item => {
- if (item.value instanceof Array) {
- return;
- }
- keys.push(item.value.path);
- });
- }
- });
- if (keys.length > 0) {
- for (const key of keys) {
- if (openKeys.value.indexOf(key) === -1) {
- openKeys.value.push(key);
- changed = true;
- }
- }
- }
- return changed;
- }
-
- // const { asideMenuRef, onOpenChange } = useBetterScroll(props.scroll as any);
-
- watch(
- () => {
- return route.fullPath;
- },
- path => {
- // path = route.fullPath;
- selectedKeys.value = [path];
- const changed = openSelectedParents(path);
- if (changed) {
- // onOpenChange();
- }
- },
- {
- immediate: true,
- }
- );
- return () => {
- const menu = (
-
- );
- const classNames = { "fs-menu-wrapper": true, "fs-menu-better-scroll": props.scroll };
- return {menu}
;
- };
- },
-});
diff --git a/packages/ui/certd-client/src/layout/layout-basic.vue b/packages/ui/certd-client/src/layout/layout-basic.vue
index 39a2f3f78..944802f79 100644
--- a/packages/ui/certd-client/src/layout/layout-basic.vue
+++ b/packages/ui/certd-client/src/layout/layout-basic.vue
@@ -75,6 +75,9 @@ onMounted(async () => {
function goGithub() {
window.open("https://github.com/certd/certd");
}
+function goCertdClient() {
+ window.open("https://github.com/certd/certd-client");
+}
const settingsStore = useSettingStore();
const chatBox = ref();
const openChat = (q: string) => {
@@ -105,6 +108,9 @@ const projectStore = useProjectStore();
+
+
+
diff --git a/packages/ui/certd-client/src/layout/layout-framework.vue b/packages/ui/certd-client/src/layout/layout-framework.vue
deleted file mode 100644
index 2776975e6..000000000
--- a/packages/ui/certd-client/src/layout/layout-framework.vue
+++ /dev/null
@@ -1,303 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/packages/ui/certd-client/src/locales/langs/en-US/certd/navigation.ts b/packages/ui/certd-client/src/locales/langs/en-US/certd/navigation.ts
index 52bbdbcbd..3b0c6beab 100644
--- a/packages/ui/certd-client/src/locales/langs/en-US/certd/navigation.ts
+++ b/packages/ui/certd-client/src/locales/langs/en-US/certd/navigation.ts
@@ -26,6 +26,7 @@ export default {
myTrade: "My Orders",
inviteCommission: "Incentive Plan",
paymentReturn: "Payment Return",
+ client: "Certd Client",
source: "Source Code",
github: "GitHub",
gitee: "Gitee",
diff --git a/packages/ui/certd-client/src/locales/langs/zh-CN/certd/navigation.ts b/packages/ui/certd-client/src/locales/langs/zh-CN/certd/navigation.ts
index ef5583df6..470934352 100644
--- a/packages/ui/certd-client/src/locales/langs/zh-CN/certd/navigation.ts
+++ b/packages/ui/certd-client/src/locales/langs/zh-CN/certd/navigation.ts
@@ -27,6 +27,7 @@ export default {
myWallet: "我的钱包",
inviteCommission: "激励计划",
paymentReturn: "支付返回",
+ client: "主机自动拉取证书客户端",
source: "源码",
github: "github",
gitee: "gitee",
diff --git a/packages/ui/certd-client/src/router/resolve.ts b/packages/ui/certd-client/src/router/resolve.ts
index 0169e2cef..c611edd88 100644
--- a/packages/ui/certd-client/src/router/resolve.ts
+++ b/packages/ui/certd-client/src/router/resolve.ts
@@ -1,7 +1,6 @@
import LayoutPass from "/src/layout/layout-pass.vue";
import { cloneDeep } from "lodash-es";
import { outsideResource } from "./source/outside";
-import { headerResource } from "./source/header";
import { frameworkResource } from "./source/framework";
const modules = import.meta.glob("/src/views/**/*.vue");
@@ -144,11 +143,9 @@ function flatSubRouters(routers: any) {
const frameworkRet = buildMenusAndRouters(frameworkResource);
const outsideRet = buildMenusAndRouters(outsideResource);
-const headerRet = buildMenusAndRouters(headerResource);
const outsideRoutes = outsideRet.routes;
const frameworkRoutes = frameworkRet.routes;
const routes = [...outsideRoutes, ...frameworkRoutes];
const frameworkMenus = frameworkRet.menus;
-const headerMenus = headerRet.menus;
-export { routes, outsideRoutes, frameworkRoutes, frameworkMenus, headerMenus, findMenus, filterMenus };
+export { routes, outsideRoutes, frameworkRoutes, frameworkMenus, findMenus, filterMenus };
diff --git a/packages/ui/certd-client/src/router/source/header.ts b/packages/ui/certd-client/src/router/source/header.ts
deleted file mode 100644
index 0debcd8c6..000000000
--- a/packages/ui/certd-client/src/router/source/header.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import i18n from "/@/locales/i18n";
-
-export const headerResource = [
- {
- title: "certd.helpDoc",
- path: "https://certd.docmirror.cn",
- meta: {
- icon: "ion:document-text-outline",
- },
- },
- {
- title: "certd.source",
- name: "source",
- key: "source",
- meta: {
- icon: "ion:git-branch-outline",
- },
- children: [
- {
- title: "certd.github",
- path: "https://github.com/certd/certd",
- meta: {
- icon: "ion:logo-github",
- },
- },
- {
- title: "certd.gitee",
- path: "https://gitee.com/certd/certd",
- meta: {
- icon: "ion:logo-octocat",
- },
- },
- ],
- },
-];
diff --git a/packages/ui/certd-client/src/views/certd/pipeline/pipeline/component/task-form/index.vue b/packages/ui/certd-client/src/views/certd/pipeline/pipeline/component/task-form/index.vue
index d3e35db90..b62cdc116 100644
--- a/packages/ui/certd-client/src/views/certd/pipeline/pipeline/component/task-form/index.vue
+++ b/packages/ui/certd-client/src/views/certd/pipeline/pipeline/component/task-form/index.vue
@@ -8,6 +8,9 @@
+
+
+
@@ -145,6 +148,10 @@ export default {
const selectedStepIds = ref([]);
const stepBatchEditing = ref(false);
+ function goCertdClient() {
+ window.open("https://github.com/certd/certd-client");
+ }
+
function useStep() {
const stepFormRef: Ref = ref(null);
const currentStepIndex = ref(0);
@@ -433,6 +440,7 @@ export default {
return {
userStore,
settingStore,
+ goCertdClient,
labelCol: { span: 4 },
wrapperCol: { span: 20 },
...useTaskForm(),
diff --git a/packages/ui/certd-server/src/controller/user/dashboard/statistic-controller.ts b/packages/ui/certd-server/src/controller/user/dashboard/statistic-controller.ts
index f0775e9a5..631ee278b 100644
--- a/packages/ui/certd-server/src/controller/user/dashboard/statistic-controller.ts
+++ b/packages/ui/certd-server/src/controller/user/dashboard/statistic-controller.ts
@@ -4,7 +4,7 @@ import { UserService } from "../../../modules/sys/authority/service/user-service
import { RoleService } from "../../../modules/sys/authority/service/role-service.js";
import { PipelineService } from "../../../modules/pipeline/service/pipeline-service.js";
import { HistoryService } from "../../../modules/pipeline/service/history-service.js";
-import { CertInfoService } from "../../../modules/monitor/index.js";
+import { CertInfoService, CertStatus } from "../../../modules/monitor/index.js";
import { ApiTags } from "@midwayjs/swagger";
export type ChartItem = {
@@ -56,7 +56,7 @@ export class StatisticController extends BaseController {
const historyCount = await this.historyService.countPerDay({ userId, projectId, days: 7 });
const expiringList = await this.pipelineService.latestExpiringList({ userId, projectId, count: 5 });
- const certCount = await this.certInfoService.count({ userId, projectId });
+ const certCount = await this.certInfoService.count({ userId, projectId, status: CertStatus.active });
const count: UserStatisticCount = {
pipelineCount,
diff --git a/packages/ui/certd-server/src/modules/monitor/service/cert-info-service.ts b/packages/ui/certd-server/src/modules/monitor/service/cert-info-service.ts
index 70a468a93..a392c2a22 100644
--- a/packages/ui/certd-server/src/modules/monitor/service/cert-info-service.ts
+++ b/packages/ui/certd-server/src/modules/monitor/service/cert-info-service.ts
@@ -356,11 +356,12 @@ export class CertInfoService extends BaseService {
});
}
- async count({ userId, projectId }: { userId: number; projectId?: number }) {
+ async count({ userId, projectId,status }: { userId: number; projectId?: number,status?:string }) {
const userProjectQuery = this.buildUserProjectQuery(userId, projectId);
const total = await this.repository.count({
where: {
...userProjectQuery,
+ status,
expiresTime: Not(IsNull()),
},
});
@@ -368,6 +369,7 @@ export class CertInfoService extends BaseService {
const expired = await this.repository.count({
where: {
...userProjectQuery,
+ status,
expiresTime: LessThan(new Date().getTime()),
},
});
@@ -375,6 +377,7 @@ export class CertInfoService extends BaseService {
const expiring = await this.repository.count({
where: {
...userProjectQuery,
+ status,
expiresTime: Between(new Date().getTime(), new Date().getTime() + 15 * 24 * 60 * 60 * 1000),
},
});