From 021155278e7375f8487b0531ed1b5ad52512f007 Mon Sep 17 00:00:00 2001 From: xiaojunnuo Date: Wed, 3 Jun 2026 01:01:19 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=91=98=E9=92=88=E5=AF=B9=E7=94=A8=E6=88=B7=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E5=92=8C=E8=AF=81=E4=B9=A6=E7=9B=91=E6=8E=A7=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 新增后台管理页面:用户流水线管理、用户证书监控管理 2. 新增对应前后端接口与控制器 3. 添加多语言国际化配置 4. 修复导入顺序与多余空行问题 5. 补充证书申请类型选项 --- .../locales/langs/en-US/certd/navigation.ts | 3 + .../locales/langs/zh-CN/certd/navigation.ts | 3 + .../src/router/source/modules/sys.ts | 38 ++ .../src/views/certd/pipeline/crud.tsx | 1 + .../src/views/sys/monitor/site/api.ts | 37 ++ .../src/views/sys/monitor/site/crud.tsx | 379 ++++++++++++++++++ .../src/views/sys/monitor/site/index.vue | 35 ++ .../src/views/sys/pipeline/api.ts | 37 ++ .../src/views/sys/pipeline/crud.tsx | 363 +++++++++++++++++ .../src/views/sys/pipeline/index.vue | 35 ++ packages/ui/certd-server/src/configuration.ts | 1 - .../sys/monitor/site-info-controller.ts | 55 +++ .../sys/pipeline/pipeline-controller.ts | 53 +++ .../service/cert-apply-template-service.ts | 4 +- 14 files changed, 1041 insertions(+), 3 deletions(-) create mode 100644 packages/ui/certd-client/src/views/sys/monitor/site/api.ts create mode 100644 packages/ui/certd-client/src/views/sys/monitor/site/crud.tsx create mode 100644 packages/ui/certd-client/src/views/sys/monitor/site/index.vue create mode 100644 packages/ui/certd-client/src/views/sys/pipeline/api.ts create mode 100644 packages/ui/certd-client/src/views/sys/pipeline/crud.tsx create mode 100644 packages/ui/certd-client/src/views/sys/pipeline/index.vue create mode 100644 packages/ui/certd-server/src/controller/sys/monitor/site-info-controller.ts create mode 100644 packages/ui/certd-server/src/controller/sys/pipeline/pipeline-controller.ts 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 49f05df9d..d7b0ae5e1 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 @@ -45,6 +45,9 @@ export default { permissionManager: "Permission Management", roleManager: "Role Management", userManager: "User Management", + userDataManager: "User Data Management", + pipelineManager: "User Pipeline Management", + siteMonitorManager: "User Certificate Monitor", suiteManager: "Suite Management", suiteSetting: "Suite Settings", orderManager: "Order Management", 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 54da7d2d1..2c740e8ff 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 @@ -46,6 +46,9 @@ export default { permissionManager: "权限管理", roleManager: "角色管理", userManager: "用户管理", + userDataManager: "用户数据管理", + pipelineManager: "用户流水线管理", + siteMonitorManager: "用户证书监控管理", suiteManager: "套餐管理", suiteSetting: "套餐设置", orderManager: "订单管理", diff --git a/packages/ui/certd-client/src/router/source/modules/sys.ts b/packages/ui/certd-client/src/router/source/modules/sys.ts index 0f3912db6..766135d24 100644 --- a/packages/ui/certd-client/src/router/source/modules/sys.ts +++ b/packages/ui/certd-client/src/router/source/modules/sys.ts @@ -230,6 +230,44 @@ export const sysResources = [ auth: true, }, }, + { + title: "certd.sysResources.userDataManager", + name: "UserDataManager", + path: "/sys/user-data", + redirect: "/sys/pipeline", + meta: { + icon: "ion:folder-open-outline", + permission: "sys:settings:view", + keepAlive: true, + auth: true, + }, + children: [ + { + title: "certd.sysResources.pipelineManager", + name: "SysPipelineManager", + path: "/sys/pipeline", + component: "/sys/pipeline/index.vue", + meta: { + icon: "ion:analytics-sharp", + permission: "sys:settings:view", + keepAlive: true, + auth: true, + }, + }, + { + title: "certd.sysResources.siteMonitorManager", + name: "SysSiteMonitorManager", + path: "/sys/monitor/site", + component: "/sys/monitor/site/index.vue", + meta: { + icon: "ion:videocam-outline", + permission: "sys:settings:view", + keepAlive: true, + auth: true, + }, + }, + ], + }, { title: "certd.sysResources.suiteManager", name: "SuiteManager", diff --git a/packages/ui/certd-client/src/views/certd/pipeline/crud.tsx b/packages/ui/certd-client/src/views/certd/pipeline/crud.tsx index ca8144cfa..70fb8dc5a 100644 --- a/packages/ui/certd-client/src/views/certd/pipeline/crud.tsx +++ b/packages/ui/certd-client/src/views/certd/pipeline/crud.tsx @@ -568,6 +568,7 @@ export default function ({ crudExpose, context: { selectedRowKeys, openCertApply { value: "cert_upload", label: t("certd.types.certUpload") }, { value: "custom", label: t("certd.types.custom") }, { value: "template", label: t("certd.types.template") }, + { value: "cert_auto", label: t("certd.types.certApply") }, ], }), form: { diff --git a/packages/ui/certd-client/src/views/sys/monitor/site/api.ts b/packages/ui/certd-client/src/views/sys/monitor/site/api.ts new file mode 100644 index 000000000..7bed79182 --- /dev/null +++ b/packages/ui/certd-client/src/views/sys/monitor/site/api.ts @@ -0,0 +1,37 @@ +import { request } from "/src/api/service"; + +const apiPrefix = "/sys/monitor/site"; + +export const sysSiteMonitorApi = { + async GetList(query: any) { + return await request({ + url: apiPrefix + "/page", + method: "post", + data: query, + }); + }, + + async DelObj(id: number) { + return await request({ + url: apiPrefix + "/delete", + method: "post", + params: { id }, + }); + }, + + async BatchDelObj(ids: number[]) { + return await request({ + url: apiPrefix + "/batchDelete", + method: "post", + data: { ids }, + }); + }, + + async GetSimpleUserByIds(ids: number[]) { + return await request({ + url: "/sys/authority/user/getSimpleUserByIds", + method: "post", + data: { ids }, + }); + }, +}; diff --git a/packages/ui/certd-client/src/views/sys/monitor/site/crud.tsx b/packages/ui/certd-client/src/views/sys/monitor/site/crud.tsx new file mode 100644 index 000000000..0ff40e001 --- /dev/null +++ b/packages/ui/certd-client/src/views/sys/monitor/site/crud.tsx @@ -0,0 +1,379 @@ +import createCrudOptionsUser from "/@/views/sys/authority/user/crud"; +import { CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud"; +import { message, Modal } from "ant-design-vue"; +import dayjs from "dayjs"; +import { ref } from "vue"; +import { sysSiteMonitorApi } from "./api"; + +export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet { + const api = sysSiteMonitorApi; + const pageRequest = async (query: UserPageQuery): Promise => { + return await api.GetList(query); + }; + const delRequest = async ({ row }: DelReq) => { + return await api.DelObj(row.id); + }; + + const selectedRowKeys = ref([]); + const handleBatchDelete = () => { + if (!selectedRowKeys.value?.length) { + message.error("请先选择要删除的记录"); + return; + } + Modal.confirm({ + title: "确认", + content: `确认删除选中的 ${selectedRowKeys.value.length} 条站点监控记录?`, + async onOk() { + await api.BatchDelObj(selectedRowKeys.value); + message.success("删除成功"); + selectedRowKeys.value = []; + await crudExpose.doRefresh(); + }, + }); + }; + context.handleBatchDelete = handleBatchDelete; + + const checkStatusDict = dict({ + data: [ + { label: "正常", value: "ok", color: "green" }, + { label: "检查中", value: "checking", color: "blue" }, + { label: "异常", value: "error", color: "red" }, + ], + }); + + return { + crudOptions: { + request: { + pageRequest, + delRequest, + }, + actionbar: { + show: false, + }, + toolbar: { + buttons: { + export: { + show: true, + }, + }, + export: { + dataFrom: "search", + }, + }, + pagination: { + pageSizeOptions: ["10", "20", "50", "100", "200"], + }, + settings: { + plugins: { + rowSelection: { + enabled: true, + props: { + multiple: true, + crossPage: false, + selectedRowKeys: () => { + return selectedRowKeys; + }, + }, + }, + }, + }, + rowHandle: { + fixed: "right", + width: 100, + buttons: { + view: { show: false }, + copy: { show: false }, + edit: { show: false }, + remove: { + show: true, + }, + }, + }, + columns: { + id: { + title: "ID", + key: "id", + type: "number", + column: { + width: 80, + align: "center", + }, + form: { + show: false, + }, + }, + userId: { + title: "用户", + type: "table-select", + search: { + show: true, + col: { + span: 4, + }, + }, + dict: dict({ + async getNodesByValues(ids: number[]) { + return await api.GetSimpleUserByIds(ids); + }, + value: "id", + label: "nickName", + }), + form: { + show: false, + component: { + crossPage: true, + multiple: false, + select: { + placeholder: "点击选择用户", + }, + createCrudOptions: createCrudOptionsUser, + }, + }, + column: { + width: 150, + }, + }, + projectId: { + title: "项目ID", + type: "number", + search: { + show: true, + col: { + span: 3, + }, + }, + column: { + width: 100, + align: "center", + }, + form: { + show: false, + }, + }, + name: { + title: "站点名称", + type: "text", + search: { + show: true, + col: { + span: 4, + }, + }, + column: { + width: 160, + }, + form: { + show: false, + }, + }, + domain: { + title: "域名", + type: "text", + search: { + show: true, + col: { + span: 4, + }, + }, + column: { + width: 230, + sorter: true, + cellRender({ value, row }) { + const domainPort = `${value}:${row.httpsPort || 443}`; + return ( + + + + {domainPort} + + + + ); + }, + }, + form: { + show: false, + }, + }, + certDomains: { + title: "证书域名", + type: "text", + search: { + show: true, + col: { + span: 4, + }, + }, + column: { + width: 260, + sorter: true, + ellipsis: true, + cellRender({ value }) { + return {value}; + }, + }, + form: { + show: false, + }, + }, + certProvider: { + title: "颁发机构", + type: "text", + column: { + width: 200, + sorter: true, + ellipsis: true, + cellRender({ value }) { + return {value}; + }, + }, + form: { + show: false, + }, + }, + certStatus: { + title: "证书状态", + type: "dict-select", + search: { + show: true, + col: { + span: 3, + }, + }, + dict: dict({ + data: [ + { label: "正常", value: "ok", color: "green" }, + { label: "已过期", value: "expired", color: "red" }, + ], + }), + column: { + width: 100, + sorter: true, + align: "center", + }, + form: { + show: false, + }, + }, + checkStatus: { + title: "检查状态", + type: "dict-select", + search: { + show: true, + col: { + span: 3, + }, + }, + dict: checkStatusDict, + column: { + width: 100, + sorter: true, + align: "center", + cellRender({ value, row }) { + return ( + + + + ); + }, + }, + form: { + show: false, + }, + }, + certExpiresTime: { + title: "证书到期时间", + type: "datetime", + column: { + sorter: true, + width: 155, + }, + form: { + show: false, + }, + }, + remainingValidity: { + title: "剩余有效期", + type: "date", + column: { + width: 120, + conditionalRender: false, + cellRender({ row }) { + if (!row.certExpiresTime) { + return "-"; + } + const leftDays = dayjs(row.certExpiresTime).diff(dayjs(), "day"); + const color = leftDays < 15 ? "red" : "#389e0d"; + return {leftDays}天; + }, + }, + form: { + show: false, + }, + }, + lastCheckTime: { + title: "上次检查时间", + type: "datetime", + column: { + sorter: true, + width: 155, + }, + form: { + show: false, + }, + }, + disabled: { + title: "状态", + type: "dict-select", + search: { + show: true, + col: { + span: 3, + }, + }, + dict: dict({ + data: [ + { label: "启用", value: false, color: "green" }, + { label: "禁用", value: true, color: "red" }, + ], + }), + column: { + width: 90, + sorter: true, + align: "center", + }, + form: { + show: false, + }, + }, + remark: { + title: "备注", + type: "textarea", + column: { + width: 200, + sorter: true, + ellipsis: true, + cellRender({ value }) { + return {value}; + }, + }, + form: { + show: false, + }, + }, + createTime: { + title: "创建时间", + type: "datetime", + column: { + width: 155, + sorter: true, + show: false, + }, + form: { + show: false, + }, + }, + }, + }, + }; +} diff --git a/packages/ui/certd-client/src/views/sys/monitor/site/index.vue b/packages/ui/certd-client/src/views/sys/monitor/site/index.vue new file mode 100644 index 000000000..55fa612e9 --- /dev/null +++ b/packages/ui/certd-client/src/views/sys/monitor/site/index.vue @@ -0,0 +1,35 @@ + + + diff --git a/packages/ui/certd-client/src/views/sys/pipeline/api.ts b/packages/ui/certd-client/src/views/sys/pipeline/api.ts new file mode 100644 index 000000000..8eaca1878 --- /dev/null +++ b/packages/ui/certd-client/src/views/sys/pipeline/api.ts @@ -0,0 +1,37 @@ +import { request } from "/src/api/service"; + +const apiPrefix = "/sys/pipeline"; + +export const sysPipelineApi = { + async GetList(query: any) { + return await request({ + url: apiPrefix + "/page", + method: "post", + data: query, + }); + }, + + async DelObj(id: number) { + return await request({ + url: apiPrefix + "/delete", + method: "post", + params: { id }, + }); + }, + + async BatchDelObj(ids: number[]) { + return await request({ + url: apiPrefix + "/batchDelete", + method: "post", + data: { ids }, + }); + }, + + async GetSimpleUserByIds(ids: number[]) { + return await request({ + url: "/sys/authority/user/getSimpleUserByIds", + method: "post", + data: { ids }, + }); + }, +}; diff --git a/packages/ui/certd-client/src/views/sys/pipeline/crud.tsx b/packages/ui/certd-client/src/views/sys/pipeline/crud.tsx new file mode 100644 index 000000000..956f2bdc5 --- /dev/null +++ b/packages/ui/certd-client/src/views/sys/pipeline/crud.tsx @@ -0,0 +1,363 @@ +import createCrudOptionsUser from "/@/views/sys/authority/user/crud"; +import { CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud"; +import { message, Modal } from "ant-design-vue"; +import dayjs from "dayjs"; +import { ref } from "vue"; +import { statusUtil } from "/@/views/certd/pipeline/pipeline/utils/util.status"; +import { sysPipelineApi } from "./api"; +import { useSettingStore } from "/@/store/settings"; + +export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet { + const api = sysPipelineApi; + const settingStore = useSettingStore(); + const pageRequest = async (query: UserPageQuery): Promise => { + return await api.GetList(query); + }; + const delRequest = async ({ row }: DelReq) => { + return await api.DelObj(row.id); + }; + + const selectedRowKeys = ref([]); + const handleBatchDelete = () => { + if (!selectedRowKeys.value?.length) { + message.error("请先选择要删除的记录"); + return; + } + settingStore.checkPlus(); + Modal.confirm({ + title: "确认", + content: `确认删除选中的 ${selectedRowKeys.value.length} 条用户流水线?删除后会清理对应执行历史、日志和证书仓库记录。`, + async onOk() { + await api.BatchDelObj(selectedRowKeys.value); + message.success("删除成功"); + selectedRowKeys.value = []; + await crudExpose.doRefresh(); + }, + }); + }; + context.handleBatchDelete = handleBatchDelete; + + return { + crudOptions: { + request: { + pageRequest, + delRequest, + }, + actionbar: { + show: false, + }, + toolbar: { + buttons: { + export: { + show: true, + }, + }, + export: { + dataFrom: "search", + }, + }, + pagination: { + pageSizeOptions: ["10", "20", "50", "100", "200"], + }, + settings: { + plugins: { + rowSelection: { + enabled: true, + props: { + multiple: true, + crossPage: false, + selectedRowKeys: () => { + return selectedRowKeys; + }, + }, + }, + }, + }, + rowHandle: { + fixed: "right", + width: 100, + buttons: { + view: { show: false }, + copy: { show: false }, + edit: { show: false }, + remove: { + show: true, + }, + }, + }, + columns: { + id: { + title: "ID", + key: "id", + type: "number", + search: { + show: true, + col: { + span: 2, + }, + }, + column: { + width: 90, + align: "center", + }, + form: { + show: false, + }, + }, + userId: { + title: "用户", + type: "table-select", + search: { + show: true, + col: { + span: 4, + }, + }, + dict: dict({ + async getNodesByValues(ids: number[]) { + return await api.GetSimpleUserByIds(ids); + }, + value: "id", + label: "nickName", + }), + form: { + show: false, + component: { + crossPage: true, + multiple: false, + select: { + placeholder: "点击选择用户", + }, + createCrudOptions: createCrudOptionsUser, + }, + }, + column: { + width: 150, + }, + }, + projectId: { + title: "项目ID", + type: "number", + search: { + show: true, + col: { + span: 3, + }, + }, + column: { + width: 100, + align: "center", + }, + form: { + show: false, + }, + }, + title: { + title: "流水线名称", + type: "text", + search: { + show: true, + title: "关键词", + component: { + name: "a-input", + }, + col: { + span: 4, + }, + }, + column: { + width: 320, + sorter: true, + ellipsis: true, + showTitle: true, + }, + form: { + show: false, + }, + }, + type: { + title: "类型", + type: "dict-select", + search: { + show: true, + col: { + span: 3, + }, + }, + dict: dict({ + data: [ + { value: "cert", label: "证书申请" }, + { value: "cert_upload", label: "证书上传" }, + { value: "custom", label: "自定义" }, + { value: "template", label: "模板" }, + { value: "cert_auto", label: "证书申请" }, + ], + }), + column: { + width: 110, + align: "center", + sorter: true, + component: { + color: "auto", + }, + }, + form: { + show: false, + }, + }, + status: { + title: "运行状态", + type: "dict-select", + search: { + show: true, + col: { + span: 3, + }, + }, + dict: dict({ + data: statusUtil.getOptions(), + }), + column: { + sorter: true, + width: 120, + align: "center", + }, + form: { + show: false, + }, + }, + disabled: { + title: "状态", + type: "dict-select", + search: { + show: true, + col: { + span: 3, + }, + }, + dict: dict({ + data: [ + { label: "启用", value: false, color: "green" }, + { label: "禁用", value: true, color: "red" }, + ], + }), + column: { + width: 90, + sorter: true, + align: "center", + }, + form: { + show: false, + }, + }, + stepCount: { + title: "部署任务数", + type: "number", + column: { + align: "center", + width: 110, + }, + form: { + show: false, + }, + }, + triggerCount: { + title: "定时任务数", + type: "number", + column: { + align: "center", + width: 110, + sorter: true, + }, + form: { + show: false, + }, + }, + lastHistoryTime: { + title: "最后执行时间", + type: "datetime", + column: { + sorter: true, + width: 155, + align: "center", + }, + form: { + show: false, + }, + }, + nextRunTime: { + title: "下次执行时间", + type: "datetime", + column: { + sorter: true, + width: 155, + align: "center", + }, + form: { + show: false, + }, + }, + validTime: { + title: "有效期", + type: "date", + column: { + sorter: true, + width: 130, + align: "center", + cellRender({ value }) { + if (!value || value <= 0) { + return "-"; + } + if (value < Date.now()) { + return 已过期; + } + return dayjs(value).format("YYYY-MM-DD"); + }, + }, + form: { + show: false, + }, + }, + remark: { + title: "备注", + type: "textarea", + column: { + width: 200, + sorter: true, + ellipsis: true, + cellRender({ value }) { + return {value}; + }, + }, + form: { + show: false, + }, + }, + createTime: { + title: "创建时间", + type: "datetime", + column: { + width: 155, + sorter: true, + show: false, + }, + form: { + show: false, + }, + }, + updateTime: { + title: "更新时间", + type: "datetime", + column: { + width: 155, + sorter: true, + show: false, + }, + form: { + show: false, + }, + }, + }, + }, + }; +} diff --git a/packages/ui/certd-client/src/views/sys/pipeline/index.vue b/packages/ui/certd-client/src/views/sys/pipeline/index.vue new file mode 100644 index 000000000..58bdb647b --- /dev/null +++ b/packages/ui/certd-client/src/views/sys/pipeline/index.vue @@ -0,0 +1,35 @@ + + + diff --git a/packages/ui/certd-server/src/configuration.ts b/packages/ui/certd-server/src/configuration.ts index 5ce3fba47..8eaaef70c 100644 --- a/packages/ui/certd-server/src/configuration.ts +++ b/packages/ui/certd-server/src/configuration.ts @@ -134,6 +134,5 @@ export class MainConfiguration { }); logger.info("当前环境:", this.app.getEnv()); // prod - } } diff --git a/packages/ui/certd-server/src/controller/sys/monitor/site-info-controller.ts b/packages/ui/certd-server/src/controller/sys/monitor/site-info-controller.ts new file mode 100644 index 000000000..c3b5c75b7 --- /dev/null +++ b/packages/ui/certd-server/src/controller/sys/monitor/site-info-controller.ts @@ -0,0 +1,55 @@ +import { ALL, Body, Controller, Inject, Post, Provide, Query } from "@midwayjs/core"; +import { CrudController } from "@certd/lib-server"; +import { SiteInfoService } from "../../../modules/monitor/service/site-info-service.js"; +import { ApiTags } from "@midwayjs/swagger"; + +@Provide() +@Controller("/api/sys/monitor/site") +@ApiTags(["sys-monitor"]) +export class SysSiteInfoController extends CrudController { + @Inject() + service: SiteInfoService; + + getService(): SiteInfoService { + return this.service; + } + + @Post("/page", { description: "sys:settings:view", summary: "管理员查询站点监控分页列表" }) + async page(@Body(ALL) body: any) { + body.query = body.query ?? {}; + const certDomains = body.query.certDomains; + const domain = body.query.domain; + const name = body.query.name; + delete body.query.certDomains; + delete body.query.domain; + delete body.query.name; + const res = await this.service.page({ + query: body.query, + page: body.page, + sort: body.sort, + buildQuery: bq => { + if (domain) { + bq.andWhere("domain like :domain", { domain: `%${domain}%` }); + } + if (certDomains) { + bq.andWhere("cert_domains like :cert_domains", { cert_domains: `%${certDomains}%` }); + } + if (name) { + bq.andWhere("name like :name", { name: `%${name}%` }); + } + }, + }); + return this.ok(res); + } + + @Post("/delete", { description: "sys:settings:edit", summary: "管理员删除站点监控" }) + async delete(@Query("id") id: number) { + return await super.delete(id); + } + + @Post("/batchDelete", { description: "sys:settings:edit", summary: "管理员批量删除站点监控" }) + async batchDelete(@Body("ids") ids: number[]) { + await this.service.delete(ids); + return this.ok(); + } +} diff --git a/packages/ui/certd-server/src/controller/sys/pipeline/pipeline-controller.ts b/packages/ui/certd-server/src/controller/sys/pipeline/pipeline-controller.ts new file mode 100644 index 000000000..03719d541 --- /dev/null +++ b/packages/ui/certd-server/src/controller/sys/pipeline/pipeline-controller.ts @@ -0,0 +1,53 @@ +import { ALL, Body, Controller, Inject, Post, Provide, Query } from "@midwayjs/core"; +import { CrudController } from "@certd/lib-server"; +import { ApiTags } from "@midwayjs/swagger"; +import { PipelineService } from "../../../modules/pipeline/service/pipeline-service.js"; +import { checkPlus } from "@certd/plus-core"; + +@Provide() +@Controller("/api/sys/pipeline") +@ApiTags(["sys-pipeline"]) +export class SysPipelineController extends CrudController { + @Inject() + service: PipelineService; + + getService(): PipelineService { + return this.service; + } + + @Post("/page", { description: "sys:settings:view", summary: "管理员查询用户流水线分页列表" }) + async page(@Body(ALL) body: any) { + body.query = body.query ?? {}; + const title = body.query.title; + delete body.query.title; + + if (!body.sort || !body.sort?.prop) { + body.sort = { prop: "order", asc: false }; + } + + const res = await this.service.page({ + query: body.query, + page: body.page, + sort: body.sort, + buildQuery: bq => { + if (title) { + bq.andWhere("(title like :title or content like :content)", { title: `%${title}%`, content: `%${title}%` }); + } + }, + }); + return this.ok(res); + } + + @Post("/delete", { description: "sys:settings:edit", summary: "管理员删除用户流水线" }) + async delete(@Query("id") id: number) { + await this.service.delete(id); + return this.ok(); + } + + @Post("/batchDelete", { description: "sys:settings:edit", summary: "管理员批量删除用户流水线" }) + async batchDelete(@Body("ids") ids: number[]) { + checkPlus(); + await this.service.batchDelete(ids); + return this.ok(); + } +} diff --git a/packages/ui/certd-server/src/modules/cert/service/cert-apply-template-service.ts b/packages/ui/certd-server/src/modules/cert/service/cert-apply-template-service.ts index b533ff2dd..1de6f935a 100644 --- a/packages/ui/certd-server/src/modules/cert/service/cert-apply-template-service.ts +++ b/packages/ui/certd-server/src/modules/cert/service/cert-apply-template-service.ts @@ -1,7 +1,7 @@ +import { BaseService, ValidateException } from "@certd/lib-server"; import { Provide, Scope, ScopeEnum } from "@midwayjs/core"; import { InjectEntityModel } from "@midwayjs/typeorm"; -import { BaseService, ValidateException } from "@certd/lib-server"; -import { IsNull, Repository } from "typeorm"; +import { Repository } from "typeorm"; import { CertApplyTemplateEntity } from "../entity/cert-apply-template.js"; import { CertApplyTemplateParams, pickCertApplyCustomParams, pickCertApplyTemplateParams } from "./cert-apply-template-fields.js";