diff --git a/packages/ui/certd-client/src/locales/i18n.ts b/packages/ui/certd-client/src/locales/i18n.ts
index 63210113..ec966bcb 100644
--- a/packages/ui/certd-client/src/locales/i18n.ts
+++ b/packages/ui/certd-client/src/locales/i18n.ts
@@ -133,5 +133,12 @@ async function loadLocaleMessages(lang: SupportedLanguagesType) {
return setI18nLanguage(lang);
}
+
+export function useI18n() {
+ return {
+ t: i18n.global.t,
+ locale: i18n.global.locale,
+ };
+}
export { i18n, loadLocaleMessages, loadLocalesMap, loadLocalesMapFromDir, setupI18n, setI18nLanguage };
export default i18n;
diff --git a/packages/ui/certd-client/src/locales/index.ts b/packages/ui/certd-client/src/locales/index.ts
index 3ae503d0..2cfd2164 100644
--- a/packages/ui/certd-client/src/locales/index.ts
+++ b/packages/ui/certd-client/src/locales/index.ts
@@ -1,12 +1,12 @@
-import { i18n, loadLocaleMessages, loadLocalesMap, loadLocalesMapFromDir, setupI18n, setI18nLanguage } from "./i18n";
+import { i18n, loadLocaleMessages, loadLocalesMap, loadLocalesMapFromDir, setupI18n, setI18nLanguage, useI18n } from "./i18n";
const $t = i18n.global.t;
const $te = i18n.global.te;
-export { $t, $te, i18n, loadLocaleMessages, loadLocalesMap, loadLocalesMapFromDir, setupI18n, setI18nLanguage };
+export { $t, $te, i18n, loadLocaleMessages, loadLocalesMap, loadLocalesMapFromDir, setupI18n, setI18nLanguage, useI18n };
export { type ImportLocaleFn, type LocaleSetupOptions, type SupportedLanguagesType } from "./typing";
// export type { CompileError } from "@intlify/core-base";
-export { useI18n } from "vue-i18n";
+// export { useI18n } from "vue-i18n";
export type { Locale } from "vue-i18n";
diff --git a/packages/ui/certd-client/src/views/certd/pipeline/certd-form/use.tsx b/packages/ui/certd-client/src/views/certd/pipeline/certd-form/use.tsx
index a02dbfc8..f1edd6c4 100644
--- a/packages/ui/certd-client/src/views/certd/pipeline/certd-form/use.tsx
+++ b/packages/ui/certd-client/src/views/certd/pipeline/certd-form/use.tsx
@@ -11,8 +11,7 @@ import * as api from "../api";
import { PluginGroup, usePluginStore } from "/@/store/plugin";
import { createNotificationApi } from "/@/views/certd/notification/api";
import GroupSelector from "../group/group-selector.vue";
-import { useI18n } from "vue-i18n";
-
+import { useI18n } from "/src/locales";
export function fillPipelineByDefaultForm(pipeline: any, form: any) {
const triggers = [];
@@ -34,241 +33,240 @@ export function fillPipelineByDefaultForm(pipeline: any, form: any) {
}
export function setRunnableIds(pipeline: any) {
- const { t } = useI18n();
- const idMap: any = {};
- function createId(oldId: any) {
- if (oldId == null) {
- return nanoid();
- }
- const newId = nanoid();
- idMap[oldId] = newId;
- return newId;
- }
- if (pipeline.stages) {
- for (const stage of pipeline.stages) {
- stage.id = createId(stage.id);
- if (stage.tasks) {
- for (const task of stage.tasks) {
- task.id = createId(task.id);
- if (task.steps) {
- for (const step of task.steps) {
- step.id = createId(step.id);
- }
- }
- }
- }
- }
- }
+ const { t } = useI18n();
+ const idMap: any = {};
+ function createId(oldId: any) {
+ if (oldId == null) {
+ return nanoid();
+ }
+ const newId = nanoid();
+ idMap[oldId] = newId;
+ return newId;
+ }
+ if (pipeline.stages) {
+ for (const stage of pipeline.stages) {
+ stage.id = createId(stage.id);
+ if (stage.tasks) {
+ for (const task of stage.tasks) {
+ task.id = createId(task.id);
+ if (task.steps) {
+ for (const step of task.steps) {
+ step.id = createId(step.id);
+ }
+ }
+ }
+ }
+ }
+ }
- for (const trigger of pipeline.triggers) {
- trigger.id = nanoid();
- }
- for (const notification of pipeline.notifications) {
- notification.id = nanoid();
- }
+ for (const trigger of pipeline.triggers) {
+ trigger.id = nanoid();
+ }
+ for (const notification of pipeline.notifications) {
+ notification.id = nanoid();
+ }
- let content = JSON.stringify(pipeline);
- for (const key in idMap) {
- content = content.replaceAll(key, idMap[key]);
- }
- return JSON.parse(content);
+ let content = JSON.stringify(pipeline);
+ for (const key in idMap) {
+ content = content.replaceAll(key, idMap[key]);
+ }
+ return JSON.parse(content);
}
export function useCertPipelineCreator() {
- const { t } = useI18n();
- const { openCrudFormDialog } = useFormWrapper();
+ const { t } = useI18n();
+ const { openCrudFormDialog } = useFormWrapper();
- const pluginStore = usePluginStore();
- const router = useRouter();
+ const pluginStore = usePluginStore();
+ const router = useRouter();
- function createCrudOptions(certPlugins: any[], getFormData: any, doSubmit: any): CreateCrudOptionsRet {
- const inputs: any = {};
- const moreParams = [];
- for (const plugin of certPlugins) {
- for (const inputKey in plugin.input) {
- if (inputs[inputKey]) {
- //如果两个插件有的字段,直接显示
- inputs[inputKey].form.show = true;
- continue;
- }
- const inputDefine = cloneDeep(plugin.input[inputKey]);
- if (!inputDefine.required && !inputDefine.maybeNeed) {
- moreParams.push(inputKey);
- // continue;
- }
- useReference(inputDefine);
- inputs[inputKey] = {
- title: inputDefine.title,
- form: {
- ...inputDefine,
- show: compute(ctx => {
- const form = getFormData();
- if (!form) {
- return false;
- }
+ function createCrudOptions(certPlugins: any[], getFormData: any, doSubmit: any): CreateCrudOptionsRet {
+ const inputs: any = {};
+ const moreParams = [];
+ for (const plugin of certPlugins) {
+ for (const inputKey in plugin.input) {
+ if (inputs[inputKey]) {
+ //如果两个插件有的字段,直接显示
+ inputs[inputKey].form.show = true;
+ continue;
+ }
+ const inputDefine = cloneDeep(plugin.input[inputKey]);
+ if (!inputDefine.required && !inputDefine.maybeNeed) {
+ moreParams.push(inputKey);
+ // continue;
+ }
+ useReference(inputDefine);
+ inputs[inputKey] = {
+ title: inputDefine.title,
+ form: {
+ ...inputDefine,
+ show: compute(ctx => {
+ const form = getFormData();
+ if (!form) {
+ return false;
+ }
- let inputDefineShow = true;
- if (inputDefine.show != null) {
- const computeShow = inputDefine.show as any;
- if (computeShow === false) {
- inputDefineShow = false;
- } else if (computeShow && computeShow.computeFn) {
- inputDefineShow = computeShow.computeFn({ form });
- }
- }
- return form?.certApplyPlugin === plugin.name && inputDefineShow;
- }),
- },
- };
- }
- }
+ let inputDefineShow = true;
+ if (inputDefine.show != null) {
+ const computeShow = inputDefine.show as any;
+ if (computeShow === false) {
+ inputDefineShow = false;
+ } else if (computeShow && computeShow.computeFn) {
+ inputDefineShow = computeShow.computeFn({ form });
+ }
+ }
+ return form?.certApplyPlugin === plugin.name && inputDefineShow;
+ }),
+ },
+ };
+ }
+ }
- const pluginStore = usePluginStore();
- const randomHour = Math.floor(Math.random() * 6);
- const randomMin = Math.floor(Math.random() * 60);
+ const pluginStore = usePluginStore();
+ const randomHour = Math.floor(Math.random() * 6);
+ const randomMin = Math.floor(Math.random() * 60);
- const groupDictRef = dict({
- url: "/pi/pipeline/group/all",
- value: "id",
- label: "name",
- });
+ const groupDictRef = dict({
+ url: "/pi/pipeline/group/all",
+ value: "id",
+ label: "name",
+ });
- return {
- crudOptions: {
- form: {
- doSubmit,
- wrapper: {
- width: 1350,
- saveRemind: false,
- title: t("certd.pipelineForm.createTitle"),
- },
- group: {
- groups: {
- more: {
- header: t("certd.pipelineForm.moreParams"),
- columns: moreParams,
- collapsed: true,
- },
- },
- },
- },
- columns: {
- certApplyPlugin: {
- title: t("certd.plugin.selectTitle"),
- type: "dict-select",
- dict: dict({
- data: [
- { value: "CertApply", label: "JS-ACME" },
- { value: "CertApplyLego", label: "Lego-ACME" },
- ],
- }),
- form: {
- order: 0,
- value: "CertApply",
- helper: {
- render: () => {
- return (
-
- - {t("certd.plugin.jsAcme")}
- - {t("certd.plugin.legoAcme")}
-
- );
- },
- },
- valueChange: {
- handle: async ({ form, value }) => {
- const config = await pluginStore.getPluginConfig({
- name: value,
- type: "builtIn",
- });
- if (config.sysSetting?.input) {
- merge(form, config.sysSetting.input);
- }
- },
- immediate: true,
- },
- },
- },
- ...inputs,
- triggerCron: {
- title: t("certd.pipelineForm.triggerCronTitle"),
- type: "text",
- form: {
- value: `0 ${randomMin} ${randomHour} * * *`,
- component: {
- name: "cron-editor",
- vModel: "modelValue",
- placeholder: "0 0 4 * * *",
- },
- helper: t("certd.pipelineForm.triggerCronHelper"),
- order: 100,
- },
- },
- notification: {
- title: t("certd.pipelineForm.notificationTitle"),
- type: "text",
- form: {
- value: 0,
- component: {
- name: NotificationSelector,
- vModel: "modelValue",
- on: {
- selectedChange({ $event, form }) {
- form.notificationTarget = $event;
- },
- },
- },
- order: 101,
- helper: t("certd.pipelineForm.notificationHelper"),
- },
- },
- groupId: {
- title: t("certd.pipelineForm.groupIdTitle"),
- type: "dict-select",
- dict: groupDictRef,
- form: {
- component: {
- name: GroupSelector,
- vModel: "modelValue",
- },
- order: 9999,
- },
- }
+ return {
+ crudOptions: {
+ form: {
+ doSubmit,
+ wrapper: {
+ width: 1350,
+ saveRemind: false,
+ title: t("certd.pipelineForm.createTitle"),
+ },
+ group: {
+ groups: {
+ more: {
+ header: t("certd.pipelineForm.moreParams"),
+ columns: moreParams,
+ collapsed: true,
+ },
+ },
+ },
+ },
+ columns: {
+ certApplyPlugin: {
+ title: t("certd.plugin.selectTitle"),
+ type: "dict-select",
+ dict: dict({
+ data: [
+ { value: "CertApply", label: "JS-ACME" },
+ { value: "CertApplyLego", label: "Lego-ACME" },
+ ],
+ }),
+ form: {
+ order: 0,
+ value: "CertApply",
+ helper: {
+ render: () => {
+ return (
+
+ - {t("certd.plugin.jsAcme")}
+ - {t("certd.plugin.legoAcme")}
+
+ );
+ },
+ },
+ valueChange: {
+ handle: async ({ form, value }) => {
+ const config = await pluginStore.getPluginConfig({
+ name: value,
+ type: "builtIn",
+ });
+ if (config.sysSetting?.input) {
+ merge(form, config.sysSetting.input);
+ }
+ },
+ immediate: true,
+ },
+ },
+ },
+ ...inputs,
+ triggerCron: {
+ title: t("certd.pipelineForm.triggerCronTitle"),
+ type: "text",
+ form: {
+ value: `0 ${randomMin} ${randomHour} * * *`,
+ component: {
+ name: "cron-editor",
+ vModel: "modelValue",
+ placeholder: "0 0 4 * * *",
+ },
+ helper: t("certd.pipelineForm.triggerCronHelper"),
+ order: 100,
+ },
+ },
+ notification: {
+ title: t("certd.pipelineForm.notificationTitle"),
+ type: "text",
+ form: {
+ value: 0,
+ component: {
+ name: NotificationSelector,
+ vModel: "modelValue",
+ on: {
+ selectedChange({ $event, form }) {
+ form.notificationTarget = $event;
+ },
+ },
+ },
+ order: 101,
+ helper: t("certd.pipelineForm.notificationHelper"),
+ },
+ },
+ groupId: {
+ title: t("certd.pipelineForm.groupIdTitle"),
+ type: "dict-select",
+ dict: groupDictRef,
+ form: {
+ component: {
+ name: GroupSelector,
+ vModel: "modelValue",
+ },
+ order: 9999,
+ },
+ },
+ },
+ },
+ };
+ }
- },
- },
- };
- }
+ async function getCertPlugins() {
+ const pluginGroup = await pluginStore.getGroups();
+ const pluginGroups: { [key: string]: PluginGroup } = pluginGroup.groups;
+ const certPluginGroup = pluginGroups.cert;
- async function getCertPlugins() {
- const pluginGroup = await pluginStore.getGroups();
- const pluginGroups: { [key: string]: PluginGroup } = pluginGroup.groups;
- const certPluginGroup = pluginGroups.cert;
+ const certPlugins = [];
+ for (const plugin of certPluginGroup.plugins) {
+ const detail: any = await pluginStore.getPluginDefine(plugin.name);
+ certPlugins.push(detail);
+ }
+ return certPlugins;
+ }
- const certPlugins = [];
- for (const plugin of certPluginGroup.plugins) {
- const detail: any = await pluginStore.getPluginDefine(plugin.name);
- certPlugins.push(detail);
- }
- return certPlugins;
- }
+ async function openAddCertdPipelineDialog(req: { defaultGroupId?: number }) {
+ //检查是否流水线数量超出限制
+ await checkPipelineLimit();
- async function openAddCertdPipelineDialog(req: { defaultGroupId?: number }) {
- //检查是否流水线数量超出限制
- await checkPipelineLimit();
+ const wrapperRef = ref();
+ function getFormData() {
+ if (!wrapperRef.value) {
+ return null;
+ }
+ return wrapperRef.value.getFormData();
+ }
- const wrapperRef = ref();
- function getFormData() {
- if (!wrapperRef.value) {
- return null;
- }
- return wrapperRef.value.getFormData();
- }
-
- async function doSubmit({ form }: any) {
- // const certDetail = readCertDetail(form.cert.crt);
- // 添加certd pipeline
- const pluginInput = omit(form, ["triggerCron", "notification", "notificationTarget", "certApplyPlugin", "groupId"]);
+ async function doSubmit({ form }: any) {
+ // const certDetail = readCertDetail(form.cert.crt);
+ // 添加certd pipeline
+ const pluginInput = omit(form, ["triggerCron", "notification", "notificationTarget", "certApplyPlugin", "groupId"]);
let pipeline: any = {
title: form.domains[0] + "证书自动化",
runnableType: "pipeline",
@@ -301,38 +299,38 @@ export function useCertPipelineCreator() {
],
};
- pipeline = fillPipelineByDefaultForm(pipeline, form);
+ pipeline = fillPipelineByDefaultForm(pipeline, form);
pipeline = setRunnableIds(pipeline);
- const groupId = form.groupId;
- const id = await api.Save({
- title: pipeline.title,
- content: JSON.stringify(pipeline),
- keepHistoryCount: 30,
- type: "cert",
- groupId,
- });
- if (form.email) {
- try {
- //创建一个默认的邮件通知
- const notificationApi = createNotificationApi();
- await notificationApi.GetOrCreateDefault({ email: form.email });
- } catch (e) {
- console.error(e);
- }
- }
- message.success("创建成功,请添加证书部署任务");
- router.push({ path: "/certd/pipeline/detail", query: { id, editMode: "true" } });
- }
- const certPlugins = await getCertPlugins();
- const { crudOptions } = createCrudOptions(certPlugins, getFormData, doSubmit);
- //@ts-ignore
- crudOptions.columns.groupId.form.value = req.defaultGroupId || undefined;
- const wrapper = await openCrudFormDialog({ crudOptions });
- wrapperRef.value = wrapper;
- }
+ const groupId = form.groupId;
+ const id = await api.Save({
+ title: pipeline.title,
+ content: JSON.stringify(pipeline),
+ keepHistoryCount: 30,
+ type: "cert",
+ groupId,
+ });
+ if (form.email) {
+ try {
+ //创建一个默认的邮件通知
+ const notificationApi = createNotificationApi();
+ await notificationApi.GetOrCreateDefault({ email: form.email });
+ } catch (e) {
+ console.error(e);
+ }
+ }
+ message.success("创建成功,请添加证书部署任务");
+ router.push({ path: "/certd/pipeline/detail", query: { id, editMode: "true" } });
+ }
+ const certPlugins = await getCertPlugins();
+ const { crudOptions } = createCrudOptions(certPlugins, getFormData, doSubmit);
+ //@ts-ignore
+ crudOptions.columns.groupId.form.value = req.defaultGroupId || undefined;
+ const wrapper = await openCrudFormDialog({ crudOptions });
+ wrapperRef.value = wrapper;
+ }
- return {
- openAddCertdPipelineDialog,
- };
+ return {
+ openAddCertdPipelineDialog,
+ };
}
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 3a82cd4d..d0a900c5 100644
--- a/packages/ui/certd-client/src/views/certd/pipeline/crud.tsx
+++ b/packages/ui/certd-client/src/views/certd/pipeline/crud.tsx
@@ -1,5 +1,4 @@
import * as api from "./api";
-import { useI18n } from "vue-i18n";
import { computed, ref } from "vue";
import { useRouter } from "vue-router";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes, useUi } from "@fast-crud/fast-crud";
@@ -14,471 +13,474 @@ import { setRunnableIds, useCertPipelineCreator } from "/@/views/certd/pipeline/
import { useCertUpload } from "/@/views/certd/pipeline/cert-upload/use";
import GroupSelector from "/@/views/certd/pipeline/group/group-selector.vue";
import { useCertViewer } from "/@/views/certd/pipeline/use";
+import { useI18n } from "/src/locales";
export default function ({ crudExpose, context: { groupDictRef, selectedRowKeys } }: CreateCrudOptionsProps): CreateCrudOptionsRet {
- const router = useRouter();
- const lastResRef = ref();
+ const router = useRouter();
+ const lastResRef = ref();
- const { openAddCertdPipelineDialog } = useCertPipelineCreator();
- const { openUploadCreateDialog } = useCertUpload();
+ const { t } = useI18n();
- const pageRequest = async (query: UserPageQuery): Promise => {
- return await api.GetList(query);
- };
- const editRequest = async ({ form, row }: EditReq) => {
- form.id = row.id;
- const res = await api.UpdateObj(form);
- lastResRef.value = res;
- return res;
- };
- const delRequest = async ({ row }: DelReq) => {
- return await api.DelObj(row.id);
- };
+ const { openAddCertdPipelineDialog } = useCertPipelineCreator();
+ const { openUploadCreateDialog } = useCertUpload();
- const addRequest = async ({ form }: AddReq) => {
- if (form.content == null) {
- form.content = JSON.stringify({
- title: form.title,
- });
- } else {
- //复制的流水线
- delete form.status;
- delete form.lastHistoryTime;
- delete form.lastVars;
- delete form.createTime;
- delete form.id;
- let pipeline = JSON.parse(form.content);
- pipeline.title = form.title;
- pipeline = setRunnableIds(pipeline);
- form.content = JSON.stringify(pipeline);
- }
+ const pageRequest = async (query: UserPageQuery): Promise => {
+ return await api.GetList(query);
+ };
+ const editRequest = async ({ form, row }: EditReq) => {
+ form.id = row.id;
+ const res = await api.UpdateObj(form);
+ lastResRef.value = res;
+ return res;
+ };
+ const delRequest = async ({ row }: DelReq) => {
+ return await api.DelObj(row.id);
+ };
- const res = await api.AddObj(form);
- lastResRef.value = res;
- return res;
- };
+ const addRequest = async ({ form }: AddReq) => {
+ if (form.content == null) {
+ form.content = JSON.stringify({
+ title: form.title,
+ });
+ } else {
+ //复制的流水线
+ delete form.status;
+ delete form.lastHistoryTime;
+ delete form.lastVars;
+ delete form.createTime;
+ delete form.id;
+ let pipeline = JSON.parse(form.content);
+ pipeline.title = form.title;
+ pipeline = setRunnableIds(pipeline);
+ form.content = JSON.stringify(pipeline);
+ }
- const { viewCert, downloadCert } = useCertViewer();
- const userStore = useUserStore();
- const settingStore = useSettingStore();
+ const res = await api.AddObj(form);
+ lastResRef.value = res;
+ return res;
+ };
- function onDialogOpen(opt: any) {
- const searchForm = crudExpose.getSearchValidatedFormData();
- opt.initialForm = {
- ...opt.initialForm,
- groupId: searchForm.groupId,
- };
- }
+ const { viewCert, downloadCert } = useCertViewer();
+ const userStore = useUserStore();
+ const settingStore = useSettingStore();
- return {
- crudOptions: {
- request: {
- pageRequest,
- addRequest,
- editRequest,
- delRequest,
- },
- settings: {
- plugins: {
- //行选择插件,内置插件
- rowSelection: {
- //是否启用本插件
- enabled: true,
- order: -2,
- //合并在用户配置crudOptions之前还是之后
- before: true,
- props: {
- multiple: true,
- crossPage: false,
- selectedRowKeys,
- onSelectedChanged(selected) {
- console.log("已选择变化:", selected);
- },
- },
- },
- },
- },
- actionbar: {
- buttons: {
- add: {
- order: 5,
- icon: "ion:ios-add-circle-outline",
- text: t("certd.customPipeline"),
- },
- addCertd: {
- order: 1,
- text: t("certd.createCertdPipeline"),
- type: "primary",
- icon: "ion:ios-add-circle-outline",
- click() {
- const searchForm = crudExpose.getSearchValidatedFormData();
- const defaultGroupId = searchForm.groupId;
- openAddCertdPipelineDialog({ defaultGroupId });
- },
- },
- uploadCert: {
- order: 2,
- text: t("certd.commercialCertHosting"),
- type: "primary",
- tooltip: {
- slots: {
- title() {
- return (
-
- - {t("certd.tooltip.manualUploadOwnCert")}
- - {t("certd.tooltip.noAutoApplyCommercialCert")}
- - {t("certd.tooltip.manualUploadOnUpdate")}
-
- );
- },
- },
- },
- icon: "ion:cloud-upload-outline",
- click() {
- const searchForm = crudExpose.getSearchValidatedFormData();
- openUploadCreateDialog({ defaultGroupId: searchForm.groupId });
- },
- },
- },
- },
- form: {
- afterSubmit({ form, res, mode }) {
- if (mode === "add") {
- router.push({ path: "/certd/pipeline/detail", query: { id: res.id, editMode: "true" } });
- }
- },
- wrapper: {
- onOpen: onDialogOpen,
- },
- },
- table: {
- scroll: { x: 1500 },
- remove: {
- confirmTitle: t("certd.table.confirmDeleteTitle"),
- confirmMessage: t("certd.table.confirmDeleteMessage"),
- },
- },
- tabs: {
- name: "groupId",
- show: true,
- },
- rowHandle: {
- width: 200,
- fixed: "right",
- dropdown: {
- show: true,
- },
- buttons: {
- play: {
- order: -999,
- title: t("certd.play.runPipeline"),
- tooltip: { title: t("certd.play.runPipeline") },
- type: "link",
- icon: "ant-design:play-circle-outlined",
- click({ row }) {
- Modal.confirm({
- title: t("certd.play.confirm"),
- content: t("certd.play.confirmTrigger"),
- async onOk() {
- await api.Trigger(row.id);
- notification.success({ message: t("certd.play.pipelineStarted") });
- },
- });
- },
- },
- view: {
- show: false,
- click({ row }) {
- router.push({ path: "/certd/pipeline/detail", query: { id: row.id, editMode: "false" } });
- },
- },
- copy: {
- click: async context => {
- settingStore.checkPlus();
- const { ui } = useUi();
- // @ts-ignore
- let row = context[ui.tableColumn.row];
- row = cloneDeep(row);
- row.title = row.title + "_copy";
- await crudExpose.openCopy({
- row: row,
- index: context.index,
- });
- },
- class: "need-plus",
- },
- config: {
- order: 1,
- title: t("certd.actions.editPipeline"),
- type: "link",
- dropdown: true,
- icon: "ant-design:edit-outlined",
- click({ row }) {
- router.push({ path: "/certd/pipeline/detail", query: { id: row.id, editMode: "true" } });
- },
- },
- edit: {
- order: 2,
- title: t("certd.actions.editConfigGroup"),
- icon: "ant-design:setting-outlined",
- dropdown: true,
- },
- viewCert: {
- order: 3,
- title: t("certd.actions.viewCertificate"),
- tooltip: { title: t("certd.actions.viewCertificate") },
- type: "link",
- icon: "ph:certificate",
- async click({ row }) {
- await viewCert(row.id);
- },
- },
- download: {
- order: 4,
- type: "link",
- title: t("certd.actions.downloadCertificate"),
- tooltip: { title: t("certd.actions.downloadCertificate") },
- icon: "ant-design:download-outlined",
- async click({ row }) {
- await downloadCert(row.id);
- },
- },
- remove: {
- order: 5,
- dropdown: true,
- },
- },
- },
- columns: {
- id: {
- title: "ID",
- key: "id",
- type: "number",
- search: {
- show: true,
- },
- column: {
- width: 100,
- },
- form: {
- show: false,
- },
- },
- userId: {
- title: t("certd.fields.userId"),
- type: "number",
- search: {
- show: computed(() => {
- return userStore.isAdmin && settingStore.sysPublic.managerOtherUserPipeline;
- }),
- },
- form: {
- show: false,
- },
- column: {
- show: computed(() => {
- return userStore.isAdmin && settingStore.sysPublic.managerOtherUserPipeline;
- }),
- width: 100,
- },
- },
- title: {
- title: t("certd.fields.pipelineName"),
- type: "link",
- search: {
- show: true,
- title: t("certd.fields.keyword"),
- component: {
- name: "a-input",
- },
- },
- form: {
- rules: [{ required: true, message: t("certd.fields.required") }],
- },
- column: {
- width: 350,
- ellipsis: true,
- sorter: true,
- showTitle: true,
- cellRender: ({ row, value }) => {
- return {value};
- },
- },
- },
- content: {
- title: t("certd.fields.pipelineContent"),
- form: { show: false },
- column: {
- show: false,
- },
- valueBuilder({ row }) {
- if (row.content) {
- row.content = JSON.parse(row.content);
- const pipeline = row.content;
- let stepCount = 0;
- eachStages(pipeline.stages, (item, runnableType) => {
- if (runnableType === "step") {
- stepCount++;
- }
- });
- row._stepCount = stepCount;
- if (pipeline.triggers) {
- row._triggerCount = pipeline.triggers?.length > 0 ? pipeline.triggers.length : "-";
- }
- }
- },
- valueResolve({ row }) {
- if (row.content) {
- row.content = JSON.stringify(row.content);
- }
- },
- },
- _triggerCount: {
- title: t("certd.fields.scheduledTaskCount"),
- type: "number",
- column: {
- align: "center",
- width: 100,
- },
- form: {
- show: false,
- },
- },
- _stepCount: {
- title: t("certd.fields.deployTaskCount"),
- type: "number",
- form: { show: false },
- column: {
- align: "center",
- width: 100,
- },
- },
- lastVars: {
- title: t("certd.fields.remainingValidity"),
- type: "number",
- form: {
- show: false,
- },
- column: {
- cellRender({ row }) {
- if (!row.lastVars?.certExpiresTime) {
- return "-";
- }
- const leftDays = dayjs(row.lastVars.certExpiresTime).diff(dayjs(), "day");
- const color = leftDays < 20 ? "red" : "#389e0d";
- const percent = (leftDays / 90) * 100;
- return `${leftDays} 天`} />;
- },
- width: 150,
- },
- },
- "lastVars.certExpiresTime": {
- title: t("certd.fields.expiryTime"),
- search: {
- show: false,
- },
- type: "datetime",
- form: {
- show: false,
- },
- column: {
- sorter: false,
- width: 150,
- align: "center",
- },
- },
- status: {
- title: t("certd.fields.status"),
- type: "dict-select",
- search: {
- show: true,
- },
- dict: dict({
- data: statusUtil.getOptions(),
- }),
- form: {
- show: false,
- },
- column: {
- sorter: true,
- width: 120,
- align: "center",
- },
- },
- lastHistoryTime: {
- title: t("certd.fields.lastRun"),
- type: "datetime",
- form: {
- show: false,
- },
- column: {
- sorter: true,
- width: 150,
- align: "center",
- },
- },
- disabled: {
- title: t("certd.fields.enabled"),
- type: "dict-switch",
- dict: dict({
- data: [
- { value: false, label: t("certd.fields.enabledLabel") },
- { value: true, label: t("certd.fields.disabledLabel") },
- ],
- }),
- form: {
- value: false,
- show: false,
- },
- column: {
- sorter: true,
- width: 80,
- align: "center",
- component: {
- name: "fs-dict-switch",
- vModel: "checked",
- },
- async valueChange({ row, key, value }) {
- return await api.UpdateObj({
- id: row.id,
- disabled: row[key],
- });
- },
- },
- },
- groupId: {
- title: t("certd.fields.group"),
- type: "dict-select",
- search: {
- show: true,
- },
- dict: groupDictRef,
- form: {
- component: {
- name: GroupSelector,
- vModel: "modelValue",
- },
- },
- column: {
- width: 130,
- align: "center",
- component: {
- color: "auto",
- },
- sorter: true,
- },
- },
- type: {
- title: t("certd.fields.type"),
- type: "dict-select",
- search: {
- show: true,
- },
- dict: dict({
- data: [
- { value: "cert", label: t("certd.types.certApply") },
- { value: "cert_upload", label: t("certd.types.certUpload") },
- { value: "custom", label: t("certd.types.custom") },
+ function onDialogOpen(opt: any) {
+ const searchForm = crudExpose.getSearchValidatedFormData();
+ opt.initialForm = {
+ ...opt.initialForm,
+ groupId: searchForm.groupId,
+ };
+ }
+
+ return {
+ crudOptions: {
+ request: {
+ pageRequest,
+ addRequest,
+ editRequest,
+ delRequest,
+ },
+ settings: {
+ plugins: {
+ //行选择插件,内置插件
+ rowSelection: {
+ //是否启用本插件
+ enabled: true,
+ order: -2,
+ //合并在用户配置crudOptions之前还是之后
+ before: true,
+ props: {
+ multiple: true,
+ crossPage: false,
+ selectedRowKeys,
+ onSelectedChanged(selected) {
+ console.log("已选择变化:", selected);
+ },
+ },
+ },
+ },
+ },
+ actionbar: {
+ buttons: {
+ add: {
+ order: 5,
+ icon: "ion:ios-add-circle-outline",
+ text: t("certd.customPipeline"),
+ },
+ addCertd: {
+ order: 1,
+ text: t("certd.createCertdPipeline"),
+ type: "primary",
+ icon: "ion:ios-add-circle-outline",
+ click() {
+ const searchForm = crudExpose.getSearchValidatedFormData();
+ const defaultGroupId = searchForm.groupId;
+ openAddCertdPipelineDialog({ defaultGroupId });
+ },
+ },
+ uploadCert: {
+ order: 2,
+ text: t("certd.commercialCertHosting"),
+ type: "primary",
+ tooltip: {
+ slots: {
+ title() {
+ return (
+
+ - {t("certd.tooltip.manualUploadOwnCert")}
+ - {t("certd.tooltip.noAutoApplyCommercialCert")}
+ - {t("certd.tooltip.manualUploadOnUpdate")}
+
+ );
+ },
+ },
+ },
+ icon: "ion:cloud-upload-outline",
+ click() {
+ const searchForm = crudExpose.getSearchValidatedFormData();
+ openUploadCreateDialog({ defaultGroupId: searchForm.groupId });
+ },
+ },
+ },
+ },
+ form: {
+ afterSubmit({ form, res, mode }) {
+ if (mode === "add") {
+ router.push({ path: "/certd/pipeline/detail", query: { id: res.id, editMode: "true" } });
+ }
+ },
+ wrapper: {
+ onOpen: onDialogOpen,
+ },
+ },
+ table: {
+ scroll: { x: 1500 },
+ remove: {
+ confirmTitle: t("certd.table.confirmDeleteTitle"),
+ confirmMessage: t("certd.table.confirmDeleteMessage"),
+ },
+ },
+ tabs: {
+ name: "groupId",
+ show: true,
+ },
+ rowHandle: {
+ width: 200,
+ fixed: "right",
+ dropdown: {
+ show: true,
+ },
+ buttons: {
+ play: {
+ order: -999,
+ title: t("certd.play.runPipeline"),
+ tooltip: { title: t("certd.play.runPipeline") },
+ type: "link",
+ icon: "ant-design:play-circle-outlined",
+ click({ row }) {
+ Modal.confirm({
+ title: t("certd.play.confirm"),
+ content: t("certd.play.confirmTrigger"),
+ async onOk() {
+ await api.Trigger(row.id);
+ notification.success({ message: t("certd.play.pipelineStarted") });
+ },
+ });
+ },
+ },
+ view: {
+ show: false,
+ click({ row }) {
+ router.push({ path: "/certd/pipeline/detail", query: { id: row.id, editMode: "false" } });
+ },
+ },
+ copy: {
+ click: async context => {
+ settingStore.checkPlus();
+ const { ui } = useUi();
+ // @ts-ignore
+ let row = context[ui.tableColumn.row];
+ row = cloneDeep(row);
+ row.title = row.title + "_copy";
+ await crudExpose.openCopy({
+ row: row,
+ index: context.index,
+ });
+ },
+ class: "need-plus",
+ },
+ config: {
+ order: 1,
+ title: t("certd.actions.editPipeline"),
+ type: "link",
+ dropdown: true,
+ icon: "ant-design:edit-outlined",
+ click({ row }) {
+ router.push({ path: "/certd/pipeline/detail", query: { id: row.id, editMode: "true" } });
+ },
+ },
+ edit: {
+ order: 2,
+ title: t("certd.actions.editConfigGroup"),
+ icon: "ant-design:setting-outlined",
+ dropdown: true,
+ },
+ viewCert: {
+ order: 3,
+ title: t("certd.actions.viewCertificate"),
+ tooltip: { title: t("certd.actions.viewCertificate") },
+ type: "link",
+ icon: "ph:certificate",
+ async click({ row }) {
+ await viewCert(row.id);
+ },
+ },
+ download: {
+ order: 4,
+ type: "link",
+ title: t("certd.actions.downloadCertificate"),
+ tooltip: { title: t("certd.actions.downloadCertificate") },
+ icon: "ant-design:download-outlined",
+ async click({ row }) {
+ await downloadCert(row.id);
+ },
+ },
+ remove: {
+ order: 5,
+ dropdown: true,
+ },
+ },
+ },
+ columns: {
+ id: {
+ title: "ID",
+ key: "id",
+ type: "number",
+ search: {
+ show: true,
+ },
+ column: {
+ width: 100,
+ },
+ form: {
+ show: false,
+ },
+ },
+ userId: {
+ title: t("certd.fields.userId"),
+ type: "number",
+ search: {
+ show: computed(() => {
+ return userStore.isAdmin && settingStore.sysPublic.managerOtherUserPipeline;
+ }),
+ },
+ form: {
+ show: false,
+ },
+ column: {
+ show: computed(() => {
+ return userStore.isAdmin && settingStore.sysPublic.managerOtherUserPipeline;
+ }),
+ width: 100,
+ },
+ },
+ title: {
+ title: t("certd.fields.pipelineName"),
+ type: "link",
+ search: {
+ show: true,
+ title: t("certd.fields.keyword"),
+ component: {
+ name: "a-input",
+ },
+ },
+ form: {
+ rules: [{ required: true, message: t("certd.fields.required") }],
+ },
+ column: {
+ width: 350,
+ ellipsis: true,
+ sorter: true,
+ showTitle: true,
+ cellRender: ({ row, value }) => {
+ return {value};
+ },
+ },
+ },
+ content: {
+ title: t("certd.fields.pipelineContent"),
+ form: { show: false },
+ column: {
+ show: false,
+ },
+ valueBuilder({ row }) {
+ if (row.content) {
+ row.content = JSON.parse(row.content);
+ const pipeline = row.content;
+ let stepCount = 0;
+ eachStages(pipeline.stages, (item, runnableType) => {
+ if (runnableType === "step") {
+ stepCount++;
+ }
+ });
+ row._stepCount = stepCount;
+ if (pipeline.triggers) {
+ row._triggerCount = pipeline.triggers?.length > 0 ? pipeline.triggers.length : "-";
+ }
+ }
+ },
+ valueResolve({ row }) {
+ if (row.content) {
+ row.content = JSON.stringify(row.content);
+ }
+ },
+ },
+ _triggerCount: {
+ title: t("certd.fields.scheduledTaskCount"),
+ type: "number",
+ column: {
+ align: "center",
+ width: 100,
+ },
+ form: {
+ show: false,
+ },
+ },
+ _stepCount: {
+ title: t("certd.fields.deployTaskCount"),
+ type: "number",
+ form: { show: false },
+ column: {
+ align: "center",
+ width: 100,
+ },
+ },
+ lastVars: {
+ title: t("certd.fields.remainingValidity"),
+ type: "number",
+ form: {
+ show: false,
+ },
+ column: {
+ cellRender({ row }) {
+ if (!row.lastVars?.certExpiresTime) {
+ return "-";
+ }
+ const leftDays = dayjs(row.lastVars.certExpiresTime).diff(dayjs(), "day");
+ const color = leftDays < 20 ? "red" : "#389e0d";
+ const percent = (leftDays / 90) * 100;
+ return `${leftDays} 天`} />;
+ },
+ width: 150,
+ },
+ },
+ "lastVars.certExpiresTime": {
+ title: t("certd.fields.expiryTime"),
+ search: {
+ show: false,
+ },
+ type: "datetime",
+ form: {
+ show: false,
+ },
+ column: {
+ sorter: false,
+ width: 150,
+ align: "center",
+ },
+ },
+ status: {
+ title: t("certd.fields.status"),
+ type: "dict-select",
+ search: {
+ show: true,
+ },
+ dict: dict({
+ data: statusUtil.getOptions(),
+ }),
+ form: {
+ show: false,
+ },
+ column: {
+ sorter: true,
+ width: 120,
+ align: "center",
+ },
+ },
+ lastHistoryTime: {
+ title: t("certd.fields.lastRun"),
+ type: "datetime",
+ form: {
+ show: false,
+ },
+ column: {
+ sorter: true,
+ width: 150,
+ align: "center",
+ },
+ },
+ disabled: {
+ title: t("certd.fields.enabled"),
+ type: "dict-switch",
+ dict: dict({
+ data: [
+ { value: false, label: t("certd.fields.enabledLabel") },
+ { value: true, label: t("certd.fields.disabledLabel") },
+ ],
+ }),
+ form: {
+ value: false,
+ show: false,
+ },
+ column: {
+ sorter: true,
+ width: 80,
+ align: "center",
+ component: {
+ name: "fs-dict-switch",
+ vModel: "checked",
+ },
+ async valueChange({ row, key, value }) {
+ return await api.UpdateObj({
+ id: row.id,
+ disabled: row[key],
+ });
+ },
+ },
+ },
+ groupId: {
+ title: t("certd.fields.group"),
+ type: "dict-select",
+ search: {
+ show: true,
+ },
+ dict: groupDictRef,
+ form: {
+ component: {
+ name: GroupSelector,
+ vModel: "modelValue",
+ },
+ },
+ column: {
+ width: 130,
+ align: "center",
+ component: {
+ color: "auto",
+ },
+ sorter: true,
+ },
+ },
+ type: {
+ title: t("certd.fields.type"),
+ type: "dict-select",
+ search: {
+ show: true,
+ },
+ dict: dict({
+ data: [
+ { value: "cert", label: t("certd.types.certApply") },
+ { value: "cert_upload", label: t("certd.types.certUpload") },
+ { value: "custom", label: t("certd.types.custom") },
{ value: "template", label: "模版" },
],
}),
@@ -498,55 +500,54 @@ export default function ({ crudExpose, context: { groupDictRef, selectedRowKeys
},
order: {
title: t("certd.fields.order"),
- type: "number",
- column: {
- sorter: true,
- align: "center",
- width: 80,
- },
- form: {
- value: 0,
- },
- },
- keepHistoryCount: {
- title: t("certd.fields.keepHistoryCount"),
- type: "number",
- form: {
- value: 20,
- helper: t("certd.fields.keepHistoryHelper"),
- },
- column: {
- width: 130,
- show: false,
- sorter: true,
- },
- },
- createTime: {
- title: t("certd.fields.createTime"),
- type: "datetime",
- form: {
- show: false,
- },
- column: {
- sorter: true,
- width: 155,
- align: "center",
- },
- },
- updateTime: {
- title: t("certd.fields.updateTime"),
- type: "datetime",
- form: {
- show: false,
- },
- column: {
- width: 125,
- show: false,
- sorter: true,
- },
- },
-
- },
- },
- };
+ type: "number",
+ column: {
+ sorter: true,
+ align: "center",
+ width: 80,
+ },
+ form: {
+ value: 0,
+ },
+ },
+ keepHistoryCount: {
+ title: t("certd.fields.keepHistoryCount"),
+ type: "number",
+ form: {
+ value: 20,
+ helper: t("certd.fields.keepHistoryHelper"),
+ },
+ column: {
+ width: 130,
+ show: false,
+ sorter: true,
+ },
+ },
+ createTime: {
+ title: t("certd.fields.createTime"),
+ type: "datetime",
+ form: {
+ show: false,
+ },
+ column: {
+ sorter: true,
+ width: 155,
+ align: "center",
+ },
+ },
+ updateTime: {
+ title: t("certd.fields.updateTime"),
+ type: "datetime",
+ form: {
+ show: false,
+ },
+ column: {
+ width: 125,
+ show: false,
+ sorter: true,
+ },
+ },
+ },
+ },
+ };
}
diff --git a/packages/ui/certd-client/src/views/certd/pipeline/index.vue b/packages/ui/certd-client/src/views/certd/pipeline/index.vue
index 01a77c1c..4e7e131d 100644
--- a/packages/ui/certd-client/src/views/certd/pipeline/index.vue
+++ b/packages/ui/certd-client/src/views/certd/pipeline/index.vue
@@ -22,7 +22,6 @@
-
diff --git a/packages/ui/certd-client/src/views/certd/pipeline/template/import/table.vue b/packages/ui/certd-client/src/views/certd/pipeline/template/import/table.vue
index 32bfc4f6..dd2a2943 100644
--- a/packages/ui/certd-client/src/views/certd/pipeline/template/import/table.vue
+++ b/packages/ui/certd-client/src/views/certd/pipeline/template/import/table.vue
@@ -91,7 +91,10 @@ onMounted(async () => {
await pluginStore.init();
await nextTick();
const steps = getStepsMap(props.detail.pipeline);
- templateProps.value = JSON.parse(props.detail.template?.content ?? "{input:{}}");
+ if (props.detail.template?.content) {
+ templateProps.value = JSON.parse(props.detail.template?.content);
+ }
+
appendCrudOptions({ ...buildColumns(steps) });
crudBinding.value.data = [];
await crudExpose.editable.enable({ mode: "row" });
@@ -101,6 +104,9 @@ defineExpose({
getData() {
return crudBinding.value.data;
},
+ clear() {
+ crudBinding.value.data = [];
+ },
});
diff --git a/packages/ui/certd-client/src/views/certd/pipeline/template/use.tsx b/packages/ui/certd-client/src/views/certd/pipeline/template/use.tsx
index ab8fe4a9..a781bbb3 100644
--- a/packages/ui/certd-client/src/views/certd/pipeline/template/use.tsx
+++ b/packages/ui/certd-client/src/views/certd/pipeline/template/use.tsx
@@ -67,6 +67,34 @@ export function createExtraColumns() {
};
}
+export async function createPipelineByTemplate(opts: { templateId: number; title: string; groupId?: string; pipeline: any; templateForm: any; keepHistoryCount?: number }) {
+ const { title, groupId, pipeline, templateForm, keepHistoryCount, templateId } = opts;
+ //填充模版参数
+ const steps: any = {};
+ eachSteps(pipeline, (step: any) => {
+ steps[step.id] = step;
+ });
+
+ for (const stepId in templateForm) {
+ const step = steps[stepId];
+ const tempStep = templateForm[stepId];
+ if (step) {
+ for (const key in tempStep) {
+ step.input[key] = tempStep[key];
+ }
+ }
+ }
+
+ pipeline.title = title;
+ return await templateApi.CreatePipelineByTemplate({
+ title,
+ content: JSON.stringify(pipeline),
+ keepHistoryCount: keepHistoryCount ?? 30,
+ groupId,
+ templateId,
+ });
+}
+
export function useTemplate() {
const { openCrudFormDialog } = useFormWrapper();
@@ -102,28 +130,12 @@ export function useTemplate() {
let newPipeline = cloneDeep(pipeline);
newPipeline = fillPipelineByDefaultForm(newPipeline, form);
//填充模版参数
- const steps: any = {};
- eachSteps(newPipeline, (step: any) => {
- steps[step.id] = step;
- });
-
- for (const inputKey in tempInputs) {
- const [stepId, key] = inputKey.split(".");
- const step = steps[stepId];
- if (step) {
- step.input[key] = tempInputs[inputKey];
- }
- }
-
- const title = form.title;
- newPipeline.title = title;
- const groupId = form.groupId;
- const { id } = await templateApi.CreatePipelineByTemplate({
- title,
- content: JSON.stringify(newPipeline),
- keepHistoryCount: 30,
- groupId,
+ const { id } = await createPipelineByTemplate({
templateId: detail.template.id,
+ templateForm: tempInputs,
+ pipeline: newPipeline,
+ title: form.title,
+ groupId: form.groupId,
});
if (req.onCreated) {
req.onCreated({ id });