pref: 优化插件store

pull/373/head
xiaojunnuo 2025-04-12 23:59:03 +08:00
parent 965dc2cb47
commit cc0657aaa8
71 changed files with 764 additions and 767 deletions

View File

@ -38,6 +38,9 @@ export function buildLogger(write: (text: string) => void) {
logger.addContext("outputHandler", {
write: (text: string) => {
for (const item of _secrets) {
if (item == null) {
continue;
}
//换成同长度的*号, item可能有多行
const reg = new RegExp(item, "g");
text = text.replaceAll(reg, "*".repeat(item.length));

View File

@ -1,31 +0,0 @@
export default [
{
path: "/login",
method: "post",
handle() {
return {
code: 0,
msg: "success",
data: {
token: "faker token",
expire: 10000
}
};
}
},
{
path: "/sys/authority/user/mine",
method: "get",
handle() {
return {
code: 0,
msg: "success",
data: {
id: 1,
username: "username",
nickName: "admin"
}
};
}
}
];

View File

@ -1,9 +1,8 @@
import axios from "axios";
import { get } from "lodash-es";
import Adapter from "axios-mock-adapter";
import { errorLog, errorCreate, response } from "./tools";
import { errorLog, errorCreate } from "./tools";
import { env } from "/src/utils/util.env";
import { useUserStore } from "../store/modules/user";
import { useUserStore } from "/@/store/user";
/**
* @description
*/
@ -12,8 +11,8 @@ function createService() {
const service = axios.create();
// 请求拦截
service.interceptors.request.use(
(config) => config,
(error) => {
config => config,
error => {
// 发送失败
console.log(error);
return Promise.reject(error);
@ -21,7 +20,7 @@ function createService() {
);
// 响应拦截
service.interceptors.response.use(
(response) => {
response => {
if (response.config.responseType === "blob") {
return response;
}
@ -67,7 +66,7 @@ function createService() {
}
}
},
(error) => {
error => {
const status = get(error, "response.status");
switch (status) {
case 400:
@ -130,11 +129,11 @@ function createRequestFunction(service: any) {
return function (config: any) {
const configDefault = {
headers: {
"Content-Type": get(config, "headers.Content-Type", "application/json")
"Content-Type": get(config, "headers.Content-Type", "application/json"),
},
timeout: 20000,
baseURL: env.API,
data: {}
data: {},
};
const userStore = useUserStore();
const token = userStore.getToken;
@ -149,10 +148,3 @@ function createRequestFunction(service: any) {
// 用于真实网络请求的实例和请求方法
export const service = createService();
export const request = createRequestFunction(service);
// 用于模拟网络请求的实例和请求方法
export const serviceForMock = createService();
export const requestForMock = createRequestFunction(serviceForMock);
// 网络请求数据模拟工具
export const mock = new Adapter(serviceForMock, { delayResponse: 200 });

View File

@ -8,7 +8,7 @@
</a-input>
</div>
<div v-else class="view" @click="edit">
<span> {{ modelValue }}</span>
<span class="ellipsis"> {{ modelValue }}</span>
<fs-icon class="edit-icon" icon="ant-design:edit-outlined"></fs-icon>
</div>
</div>
@ -22,19 +22,19 @@ export default {
props: {
modelValue: {
type: String,
default: ""
default: "",
},
input: {
type: Object
type: Object,
},
disabled: {
type: Boolean,
default: false
default: false,
},
hoverShow: {
type: Boolean,
default: false
}
default: false,
},
},
emits: ["update:modelValue"],
setup(props, ctx) {
@ -44,7 +44,7 @@ export default {
() => {
return props.modelValue;
},
(value) => {
value => {
valueRef.value = value;
}
);
@ -66,9 +66,9 @@ export default {
isEdit,
save,
edit,
inputRef
inputRef,
};
}
},
};
</script>

View File

@ -1,5 +1,5 @@
import { notification } from "ant-design-vue";
import { useSettingStore } from "/@/store/modules/settings";
import { useSettingStore } from "/@/store/settings";
export default {
mounted(el: any, binding: any, vnode: any) {

View File

@ -16,9 +16,9 @@ import { computed, onMounted, reactive } from "vue";
import dayjs from "dayjs";
import { message, Modal } from "ant-design-vue";
import * as api from "./api";
import { useSettingStore } from "/@/store/modules/settings";
import { useSettingStore } from "/@/store/settings";
import { useRouter } from "vue-router";
import { useUserStore } from "/@/store/modules/user";
import { useUserStore } from "/@/store/user";
import { mitter } from "/@/utils/util.mitt";
const settingStore = useSettingStore();

View File

@ -23,7 +23,7 @@
</template>
<script setup lang="ts">
import { computed, onMounted, ref } from "vue";
import { useSettingStore } from "/@/store/modules/settings";
import { useSettingStore } from "/@/store/settings";
defineOptions({
name: "PageFooter"

View File

@ -10,7 +10,7 @@
<script lang="ts">
import { ref, defineComponent } from "vue";
import FsThemeColorPicker from "./color-picker.vue";
import { useSettingStore } from "/@/store/modules/settings";
import { useSettingStore } from "/@/store/settings";
export default defineComponent({
name: "FsTheme",

View File

@ -13,7 +13,7 @@
<script lang="ts">
import { ref, defineComponent } from "vue";
import { useSettingStore } from "/@/store/modules/settings";
import { useSettingStore } from "/@/store/settings";
export default defineComponent({
name: "FsThemeModeSet",

View File

@ -14,7 +14,7 @@
</a-dropdown>
</template>
<script lang="ts" setup>
import { useUserStore } from "/src/store/modules/user";
import { useUserStore } from "/src/store/user";
import { Modal } from "ant-design-vue";
import { useI18n } from "vue-i18n";
import { useRouter } from "vue-router";

View File

@ -4,10 +4,10 @@ import { BasicLayout, LockScreen, UserDropdown } from "/@/vben/layouts";
import { computed, onErrorCaptured, onMounted } from "vue";
import { preferences } from "/@/vben/preferences";
import { useAccessStore } from "/@/vben/stores";
import { useUserStore } from "/@/store/modules/user";
import { useUserStore } from "/@/store/user";
import VipButton from "/@/components/vip-button/index.vue";
import TutorialButton from "/@/components/tutorial/index.vue";
import { useSettingStore } from "/@/store/modules/settings";
import { useSettingStore } from "/@/store/settings";
import PageFooter from "./components/footer/index.vue";
import { useRouter } from "vue-router";
const userStore = useUserStore();

View File

@ -110,8 +110,8 @@ import FsThemeSet from "/@/layout/components/theme/index.vue";
import { env } from "../utils/util.env";
import VipButton from "/@/components/vip-button/index.vue";
import TutorialButton from "/@/components/tutorial/index.vue";
import { useUserStore } from "/@/store/modules/user";
import { useSettingStore } from "/@/store/modules/settings";
import { useUserStore } from "/@/store/user";
import { useSettingStore } from "/@/store/settings";
import { routerUtils } from "/@/utils/util.router";
import { theme } from "ant-design-vue";

View File

@ -40,7 +40,7 @@
<script lang="ts" setup>
import { env } from "/@/utils/util.env";
import { computed, ref, Ref } from "vue";
import { useSettingStore } from "/@/store/modules/settings";
import { useSettingStore } from "/@/store/settings";
import { SiteInfo, SysPublicSetting } from "/@/api/modules/api.basic";
const envRef = ref(env);

View File

@ -1,4 +1,4 @@
import { request, requestForMock } from "/src/api/service";
import { request } from "/src/api/service";
// import "/src/mock";
import { ColumnCompositionProps, CrudOptions, FastCrud, PageQuery, PageRes, setLogger, TransformResProps, useColumns, UseCrudProps, UserPageQuery, useTypes, utils } from "@fast-crud/fast-crud";
import "@fast-crud/fast-crud/dist/style.css";
@ -51,10 +51,6 @@ function install(app: App, options: any = {}) {
app.use(FastCrud, {
i18n: options.i18n,
async dictRequest({ url }: any) {
if (url && url.startsWith("/mock")) {
//如果是crud开头的dict请求视为mock
return await requestForMock({ url, method: "post" });
}
return await request({ url, method: "post" });
},
/**

View File

@ -1,5 +1,5 @@
import router from "/src/router";
import { useUserStore } from "/@/store/modules/user";
import { useUserStore } from "/@/store/user";
import { usePermissionStore } from "./store.permission";
import util from "./util.permission";
import { message } from "ant-design-vue";

View File

@ -5,10 +5,10 @@ import { preferences } from "/@/vben/preferences";
import { useAccessStore } from "/@/vben/stores";
import { generateMenus, startProgress, stopProgress } from "/@/vben/utils";
import { frameworkRoutes } from "/@/router/resolve";
import { useSettingStore } from "/@/store/modules/settings";
import { useSettingStore } from "/@/store/settings";
import { usePermissionStore } from "/@/plugin/permission/store.permission";
import util from "/@/plugin/permission/util.permission";
import { useUserStore } from "/@/store/modules/user";
import { useUserStore } from "/@/store/user";
function buildAccessedMenus(menus: any) {
if (menus == null) {

View File

@ -1,5 +1,5 @@
import { IFrameView } from "/@/vben/layouts";
import { useSettingStore } from "/@/store/modules/settings";
import { useSettingStore } from "/@/store/settings";
import { computed } from "vue";
import TutorialButton from "/@/components/tutorial/index.vue";
export const aboutResource = [

View File

@ -1,4 +1,4 @@
import { useSettingStore } from "/@/store/modules/settings";
import { useSettingStore } from "/@/store/settings";
import aboutResource from "/@/router/source/modules/about";
export const certdResources = [

View File

@ -1,5 +1,5 @@
import LayoutPass from "/@/layout/layout-pass.vue";
import { useSettingStore } from "/@/store/modules/settings";
import { useSettingStore } from "/@/store/settings";
import aboutResource from "/@/router/source/modules/about";
export const sysResources = [

View File

@ -1,9 +0,0 @@
import { createPinia } from "pinia";
const store = createPinia();
export default {
install(app: any) {
app.use(store);
}
};
export { store };

View File

@ -11,11 +11,17 @@ const defaultInputDefine = {
};
function initPlugins(plugins: any) {
const checkedComponents = ["a-checkbox", "a-radio", "a-switch"];
for (const plugin of plugins) {
for (const key in plugin.input) {
const field = _.merge({}, defaultInputDefine, plugin.input[key]);
if (field.component.name === "a-input" || field.component.name === "a-select") {
field.component.vModel = "value";
const componentName = field.component.name;
if (componentName.startsWith("a-")) {
if (checkedComponents.includes(componentName)) {
field.component.vModel = "checked";
} else {
field.component.vModel = "value";
}
}
//嵌套对象
field.key = ["input", key];

View File

@ -0,0 +1,161 @@
import { defineStore } from "pinia";
import * as api from "./api.plugin";
import { DynamicType, FormItemProps } from "@fast-crud/fast-crud";
interface PluginState {
group?: PluginGroups;
}
export type PluginGroup = {
key: string;
title: string;
desc?: string;
order: number;
icon: string;
plugins: any[];
};
export type PluginDefine = {
name: string;
title: string;
desc?: string;
shortcut: any;
input: {
[key: string]: DynamicType<FormItemProps>;
};
output: {
[key: string]: any;
};
};
export class PluginGroups {
groups!: { [key: string]: PluginGroup };
map!: { [key: string]: PluginDefine };
constructor(groups: { [key: string]: PluginGroup }) {
this.groups = groups;
this.initGroup(groups);
this.initMap();
}
private initGroup(groups: { [p: string]: PluginGroup }) {
const all: PluginGroup = {
key: "all",
title: "全部",
order: 0,
plugins: [],
icon: "material-symbols:border-all-rounded",
};
for (const key in groups) {
all.plugins.push(...groups[key].plugins);
}
this.groups = {
all,
...groups,
};
}
initMap() {
const map: { [key: string]: PluginDefine } = {};
for (const key in this.groups) {
const group = this.groups[key];
for (const plugin of group.plugins) {
map[plugin.name] = plugin;
}
}
this.map = map;
}
getGroups() {
return this.groups;
}
get(name: string) {
return this.map[name];
}
getPreStepOutputOptions({ pipeline, currentStageIndex, currentTaskIndex, currentStepIndex, currentTask }: any) {
const steps = this.collectionPreStepOutputs({
pipeline,
currentStageIndex,
currentTaskIndex,
currentStepIndex,
currentTask,
});
const options: any[] = [];
for (const step of steps) {
const stepDefine = this.get(step.type);
for (const key in stepDefine?.output) {
options.push({
value: `step.${step.id}.${key}`,
label: `${stepDefine.output[key].title}【from${step.title}`,
type: step.type,
});
}
}
return options;
}
collectionPreStepOutputs({ pipeline, currentStageIndex, currentTaskIndex, currentStepIndex, currentTask }: any) {
const steps: any[] = [];
// 开始放step
for (let i = 0; i < currentStageIndex; i++) {
const stage = pipeline.stages[i];
for (const task of stage.tasks) {
for (const step of task.steps) {
steps.push(step);
}
}
}
//当前阶段之前的task
const currentStage = pipeline.stages[currentStageIndex];
for (let i = 0; i < currentTaskIndex; i++) {
const task = currentStage.tasks[i];
for (const step of task.steps) {
steps.push(step);
}
}
//放当前任务下的step
for (let i = 0; i < currentStepIndex; i++) {
const step = currentTask.steps[i];
steps.push(step);
}
return steps;
}
}
export const usePluginStore = defineStore({
id: "app.plugin",
state: (): PluginState => ({
group: null,
}),
actions: {
async reload() {
const groups = await api.GetGroups({});
this.group = new PluginGroups(groups);
},
async init() {
if (!this.group) {
await this.reload();
}
return this.group;
},
async getGroups(): Promise<PluginGroups> {
await this.init();
return this.group as PluginGroups;
},
async clear() {
this.group = null;
},
async getList(): Promise<PluginDefine[]> {
await this.init();
return this.group.groups.all.plugins;
},
async getPluginDefine(name: string): Promise<PluginDefine> {
await this.init();
return this.group.get(name);
},
async getPluginConfig(query: any) {
return await api.GetPluginConfig(query);
},
},
});

View File

@ -1,4 +1,4 @@
import { request } from "../service";
import { request } from "/src/api/service";
export type SiteEnv = {
agent?: {

View File

@ -1,9 +1,9 @@
import { defineStore } from "pinia";
import { Modal, notification } from "ant-design-vue";
import * as _ from "lodash-es";
import * as basicApi from "/@/api/modules/api.basic";
import { AppInfo, HeaderMenus, PlusInfo, SiteEnv, SiteInfo, SuiteSetting, SysInstallInfo, SysPublicSetting } from "/@/api/modules/api.basic";
import { useUserStore } from "/@/store/modules/user";
import * as basicApi from "./api.basic";
import { AppInfo, HeaderMenus, PlusInfo, SiteEnv, SiteInfo, SuiteSetting, SysInstallInfo, SysPublicSetting } from "./api.basic";
import { useUserStore } from "../user";
import { mitter } from "/@/utils/util.mitt";
import { env } from "/@/utils/util.env";
import { updatePreferences } from "/@/vben/preferences";

View File

@ -1,5 +1,4 @@
import { request, requestForMock } from "../service";
import { env } from "/@/utils/util.env";
import { request } from "/src/api/service";
export interface RegisterReq {
username: string;
@ -39,24 +38,16 @@ export async function register(user: RegisterReq): Promise<UserInfoRes> {
return await request({
url: "/register",
method: "post",
data: user
data: user,
});
}
export async function login(data: LoginReq): Promise<LoginRes> {
if (env.PM_ENABLED === "false") {
//没有开启权限模块,模拟登录
return await requestForMock({
url: "/login",
method: "post",
data
});
}
//如果开启了登录与权限模块,则真实登录
return await request({
url: "/login",
method: "post",
data
data,
});
}
@ -65,20 +56,13 @@ export async function loginBySms(data: SmsLoginReq): Promise<LoginRes> {
return await request({
url: "/loginBySms",
method: "post",
data
data,
});
}
export async function mine(): Promise<UserInfoRes> {
if (env.PM_ENABLED === "false") {
//没有开启权限模块,模拟登录
return await requestForMock({
url: "/sys/authority/user/mine",
method: "post"
});
}
return await request({
url: "/mine/info",
method: "post"
method: "post",
});
}

View File

@ -3,8 +3,8 @@ import router from "../../router";
// @ts-ignore
import { LocalStorage } from "/src/utils/util.storage";
// @ts-ignore
import * as UserApi from "/src/api/modules/api.user";
import { RegisterReq, SmsLoginReq } from "/src/api/modules/api.user";
import * as UserApi from "./api.user";
import { RegisterReq, SmsLoginReq } from "./api.user";
// @ts-ignore
import { LoginReq, UserInfoRes } from "/@/api/modules/api.user";
import { message, Modal, notification } from "ant-design-vue";
@ -28,7 +28,7 @@ export const useUserStore = defineStore({
// user info
userInfo: null,
// token
token: undefined
token: undefined,
}),
getters: {
getUserInfo(): UserInfoRes {
@ -39,7 +39,7 @@ export const useUserStore = defineStore({
},
isAdmin(): boolean {
return this.getUserInfo.roleIds?.includes(1) || this.getUserInfo.id === 1;
}
},
},
actions: {
setToken(token: string, expire: number) {
@ -63,7 +63,7 @@ export const useUserStore = defineStore({
async register(user: RegisterReq) {
await UserApi.register(user);
notification.success({
message: "注册成功,请登录"
message: "注册成功,请登录",
});
await router.replace("/login");
},
@ -127,8 +127,8 @@ export const useUserStore = defineStore({
content: t("app.login.logoutMessage"),
onOk: async () => {
await this.logout(true);
}
},
});
}
}
},
},
});

View File

@ -10,7 +10,7 @@ import "./styles/antd/index.css";
import { useTitle } from "@vueuse/core";
import { setupI18n } from "/@/vben/locales";
import { useSettingStore } from "/@/store/modules/settings";
import { useSettingStore } from "/@/store/settings";
export async function setupVben(app: any, { loadMessages, router }: any) {
await setupI18n(app, { loadMessages });

View File

@ -78,11 +78,11 @@ export const useAccessStore = defineStore("core-access", {
},
setRefreshToken(token: AccessToken) {
this.refreshToken = token;
}
},
},
persist: {
// 持久化
pick: ["accessToken", "refreshToken", "accessCodes"]
pick: ["accessToken", "refreshToken", "accessCodes"],
},
state: (): AccessState => ({
accessCodes: [],
@ -91,8 +91,8 @@ export const useAccessStore = defineStore("core-access", {
accessToken: null,
isAccessChecked: false,
loginExpired: false,
refreshToken: null
})
refreshToken: null,
}),
});
// 解决热更新问题

View File

@ -21,13 +21,13 @@ export const useLockStore = defineStore("core-lock", {
unlockScreen() {
this.isLockScreen = false;
this.lockScreenPassword = undefined;
}
},
},
persist: {
pick: ["isLockScreen", "lockScreenPassword"]
pick: ["isLockScreen", "lockScreenPassword"],
},
state: (): AppState => ({
isLockScreen: false,
lockScreenPassword: undefined
})
lockScreenPassword: undefined,
}),
});

View File

@ -49,12 +49,12 @@ export const useUserStore = defineStore("core-user", {
},
setUserRoles(roles: string[]) {
this.userRoles = roles;
}
},
},
state: (): AccessState => ({
userInfo: null,
userRoles: []
})
userRoles: [],
}),
});
// 解决热更新问题

View File

@ -3,8 +3,8 @@ import { useI18n } from "vue-i18n";
import { Ref, ref } from "vue";
import { useRouter } from "vue-router";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { useUserStore } from "/@/store/modules/user";
import { useSettingStore } from "/@/store/modules/settings";
import { useUserStore } from "/@/store/user";
import { useSettingStore } from "/@/store/settings";
import { message } from "ant-design-vue";
import CnameTip from "/@/components/plugins/cert/domains-verify-plan-editor/cname-tip.vue";
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {

View File

@ -3,8 +3,8 @@ import { useI18n } from "vue-i18n";
import { computed, Ref, ref } from "vue";
import { useRouter } from "vue-router";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes, utils } from "@fast-crud/fast-crud";
import { useUserStore } from "/@/store/modules/user";
import { useSettingStore } from "/@/store/modules/settings";
import { useUserStore } from "/@/store/user";
import { useSettingStore } from "/@/store/settings";
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const router = useRouter();

View File

@ -7,7 +7,7 @@ import { ref } from "vue";
import { CrudOptions, useColumns, useFormWrapper } from "@fast-crud/fast-crud";
import * as api from "/@/views/certd/mine/api";
import { notification } from "ant-design-vue";
import { useUserStore } from "/@/store/modules/user";
import { useUserStore } from "/@/store/user";
defineProps<{
showButton: boolean;

View File

@ -4,7 +4,7 @@ import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, Edi
import { siteInfoApi } from "./api";
import dayjs from "dayjs";
import { notification } from "ant-design-vue";
import { useSettingStore } from "/@/store/modules/settings";
import { useSettingStore } from "/@/store/settings";
import { mySuiteApi } from "/@/views/certd/suite/mine/api";
import { mitter } from "/@/utils/util.mitt";

View File

@ -22,12 +22,10 @@ import { useFs } from "@fast-crud/fast-crud";
import createCrudOptions from "./crud";
import { siteInfoApi } from "./api";
import { Modal, notification } from "ant-design-vue";
import { useSettingStore } from "/@/store/modules/settings";
defineOptions({
name: "SiteCertMonitor",
});
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: {} });
const settingStore = useSettingStore();
function checkAll() {
Modal.confirm({
title: "确认",

View File

@ -3,11 +3,11 @@ import NotificationSelector from "/@/views/certd/notification/notification-selec
import { cloneDeep, omit } from "lodash-es";
import { useReference } from "/@/use/use-refrence";
import { ref } from "vue";
import * as pluginApi from "../api.plugin";
import * as api from "../api";
import { checkPipelineLimit, getAllDomainsFromCrt } from "/@/views/certd/pipeline/utils";
import { useRouter } from "vue-router";
import { nanoid } from "nanoid";
import { usePluginStore } from "/@/store/plugin";
export function useCertUpload() {
const { openCrudFormDialog } = useFormWrapper();
@ -52,8 +52,10 @@ export function useCertUpload() {
},
};
const pluginStore = usePluginStore();
async function buildUploadCertPluginInputs(getFormData: any) {
const plugin: any = await pluginApi.GetPluginDefine("CertApplyUpload");
const plugin: any = await pluginStore.getPluginDefine("CertApplyUpload");
const inputs: any = {};
for (const inputKey in plugin.input) {
if (inputKey === "uploadCert" || inputKey === "domains") {

View File

@ -1,8 +1,8 @@
import { compute, CreateCrudOptionsRet, dict } from "@fast-crud/fast-crud";
import { useReference } from "/@/use/use-refrence";
import { merge, cloneDeep } from "lodash-es";
import * as api from "../api.plugin";
import NotificationSelector from "/@/views/certd/notification/notification-selector/index.vue";
import { usePluginStore } from "/@/store/plugin";
export default function (certPlugins: any[], formWrapperRef: any): CreateCrudOptionsRet {
const inputs: any = {};
@ -46,6 +46,7 @@ export default function (certPlugins: any[], formWrapperRef: any): CreateCrudOpt
}
}
const pluginStore = usePluginStore();
const randomHour = Math.floor(Math.random() * 6);
const randomMin = Math.floor(Math.random() * 60);
return {
@ -91,7 +92,7 @@ export default function (certPlugins: any[], formWrapperRef: any): CreateCrudOpt
},
valueChange: {
handle: async ({ form, value }) => {
const config = await api.GetPluginConfig({
const config = await pluginStore.getPluginConfig({
name: value,
type: "builtIn",
});

View File

@ -2,68 +2,66 @@
<fs-form-wrapper v-if="formWrapperOptions" ref="formWrapperRef" />
</template>
<script lang="ts">
import { useColumns, useExpose } from "@fast-crud/fast-crud";
<script lang="ts" setup>
import { useColumns } from "@fast-crud/fast-crud";
import createCrudOptions from "./crud.jsx";
import { ref } from "vue";
import * as _ from "lodash-es";
import * as api from "../api.plugin";
import { PluginGroup, PluginGroups } from "/@/views/certd/pipeline/pipeline/type";
import { GetPluginDefine } from "../api.plugin";
import { merge } from "lodash-es";
import { PluginGroup, usePluginStore } from "/@/store/plugin";
import { createNotificationApi } from "/@/views/certd/notification/api";
export default {
defineOptions({
name: "PiCertdForm",
setup(props: any, ctx: any) {
const formWrapperRef = ref();
const formWrapperOptions = ref();
const doSubmitRef = ref();
async function buildFormOptions() {
const pluginGroups: { [key: string]: PluginGroup } = await api.GetGroups({});
const certPluginGroup = pluginGroups.cert;
});
const certPlugins = [];
for (const plugin of certPluginGroup.plugins) {
const detail: any = await api.GetPluginDefine(plugin.name);
certPlugins.push(detail);
}
const formWrapperRef = ref();
const formWrapperOptions = ref();
const doSubmitRef = ref();
const pluginStore = usePluginStore();
async function buildFormOptions() {
const pluginGroup = await pluginStore.getGroups();
const pluginGroups: { [key: string]: PluginGroup } = pluginGroup.groups;
const certPluginGroup = pluginGroups.cert;
//
const { buildFormOptions } = useColumns();
//使crudOptions
let { crudOptions } = createCrudOptions(certPlugins, formWrapperRef);
const certPlugins = [];
for (const plugin of certPluginGroup.plugins) {
const detail: any = await pluginStore.getPluginDefine(plugin.name);
certPlugins.push(detail);
}
const formOptions = buildFormOptions(
_.merge(crudOptions, {
form: {
async doSubmit({ form }: any) {
// certd pipeline
await doSubmitRef.value({ form });
//
const { buildFormOptions } = useColumns();
//使crudOptions
let { crudOptions } = createCrudOptions(certPlugins, formWrapperRef);
if (form.email) {
//
const notificationApi = createNotificationApi();
await notificationApi.GetOrCreateDefault({ email: form.email });
}
},
},
}) as any
);
const formOptions = buildFormOptions(
merge(crudOptions, {
form: {
async doSubmit({ form }: any) {
// certd pipeline
await doSubmitRef.value({ form });
formWrapperOptions.value = formOptions;
}
buildFormOptions();
function open(doSubmit: any) {
doSubmitRef.value = doSubmit;
formWrapperRef.value.open(formWrapperOptions.value);
}
if (form.email) {
//
const notificationApi = createNotificationApi();
await notificationApi.GetOrCreateDefault({ email: form.email });
}
},
},
}) as any
);
return {
formWrapperRef,
open,
formWrapperOptions,
};
},
};
formWrapperOptions.value = formOptions;
}
buildFormOptions();
function open(doSubmit: any) {
doSubmitRef.value = doSubmit;
formWrapperRef.value.open(formWrapperOptions.value);
}
defineExpose({
open,
});
</script>
<style scoped></style>

View File

@ -6,9 +6,9 @@ import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, Edi
import { statusUtil } from "/@/views/certd/pipeline/pipeline/utils/util.status";
import { Modal, notification } from "ant-design-vue";
import { env } from "/@/utils/util.env";
import { useUserStore } from "/@/store/modules/user";
import { useUserStore } from "/@/store/user";
import dayjs from "dayjs";
import { useSettingStore } from "/@/store/modules/settings";
import { useSettingStore } from "/@/store/settings";
import { cloneDeep } from "lodash-es";
import { useModal } from "/@/use/use-modal";
import CertView from "./cert-view.vue";

View File

@ -6,23 +6,23 @@
</template>
<script lang="ts" setup>
import { nextTick, onMounted, Ref, ref } from "vue";
import { nextTick, Ref, ref } from "vue";
import PipelineEdit from "./pipeline/index.vue";
import * as pluginApi from "./api.plugin";
import * as historyApi from "./api.history";
import * as api from "./api";
import { useRoute } from "vue-router";
import { PipelineDetail, PipelineOptions, PluginGroups, RunHistory } from "./pipeline/type";
import { TourProps } from "ant-design-vue";
import { PipelineDetail, PipelineOptions, RunHistory } from "./pipeline/type";
import { LocalStorage } from "/@/utils/util.storage";
import { useUserStore } from "/@/store/modules/user";
import { useUserStore } from "/@/store/user";
import { usePluginStore, PluginGroups } from "/@/store/plugin";
defineOptions({
name: "PipelineDetail",
});
const route = useRoute();
const pipelineId: Ref = ref(route.query.id);
const historyId = ref(route.query.historyId);
const historyId = ref(route.query.historyId as string);
const pluginStore = usePluginStore();
const pipelineOptions: PipelineOptions = {
async getPipelineDetail({ pipelineId }) {
const detail = await api.GetDetail(pipelineId);
@ -48,9 +48,8 @@ const pipelineOptions: PipelineOptions = {
return detail;
},
async getPluginGroups() {
const groups = await pluginApi.GetGroups({});
return new PluginGroups(groups);
async getPluginGroups(): Promise<PluginGroups> {
return await pluginStore.getGroups();
},
async doSave(pipelineConfig: any) {

View File

@ -23,8 +23,8 @@
</template>
<script lang="ts" setup>
import { Ref, ref, watch } from "vue";
import { useUserStore } from "/@/store/modules/user";
import { useSettingStore } from "/@/store/modules/settings";
import { useUserStore } from "/@/store/user";
import { useSettingStore } from "/@/store/settings";
const props = defineProps({
options: {

View File

@ -5,8 +5,8 @@
</template>
<script setup lang="ts">
import { ref, watch } from "vue";
import * as pluginApi from "/@/views/certd/pipeline/api.plugin";
import TaskShortcut from "./task-shortcut.vue";
import { usePluginStore } from "/@/store/plugin";
defineOptions({
name: "TaskShortcuts",
@ -15,7 +15,8 @@ defineOptions({
const props = defineProps<{
task: any;
}>();
const shortcuts = ref([]);
const pluginStore = usePluginStore();
watch(
() => props.task,
value => {
@ -24,7 +25,6 @@ watch(
{ immediate: true }
);
const shortcuts = ref([]);
async function init() {
const steps = props.task?.steps || [];
if (steps.length === 0) {
@ -33,7 +33,7 @@ async function init() {
const list = [];
for (const step of steps) {
const stepType = step.type;
const pluginDefine = await pluginApi.GetPluginDefine(stepType);
const pluginDefine = await pluginStore.getPluginDefine(stepType);
if (pluginDefine.shortcut) {
for (const key in pluginDefine.shortcut) {
const shortcut = pluginDefine.shortcut[key];

View File

@ -5,7 +5,9 @@
编辑步骤
<template v-if="editMode">
<a-button @click="stepDelete()">
<template #icon><DeleteOutlined /></template>
<template #icon>
<DeleteOutlined />
</template>
</a-button>
</template>
</div>
@ -65,7 +67,7 @@
</div>
<template #footer>
<div style="padding: 20px; margin-left: 100px">
<a-button v-if="editMode" type="primary" @click="stepTypeSave"> </a-button>
<a-button v-if="editMode" type="primary" @click="stepTypeSave"> </a-button>
</div>
</template>
</pi-container>
@ -103,7 +105,7 @@
</div>
<template #footer>
<div v-if="editMode" class="bottom-button">
<a-button type="primary" @click="stepSave"> </a-button>
<a-button type="primary" @click="stepSave"> </a-button>
</div>
</template>
</pi-container>
@ -111,310 +113,327 @@
</a-drawer>
</template>
<script lang="tsx">
<script lang="tsx" setup>
import { message, Modal } from "ant-design-vue";
import { computed, inject, Ref, ref, watch, provide } from "vue";
import * as _ from "lodash-es";
import { computed, provide, ref, Ref, watch } from "vue";
import { merge, cloneDeep } from "lodash-es";
import { nanoid } from "nanoid";
import { CopyOutlined } from "@ant-design/icons-vue";
import { PluginGroups } from "/@/views/certd/pipeline/pipeline/type";
import { useUserStore } from "/@/store/modules/user";
import { compute, useCompute } from "@fast-crud/fast-crud";
import { usePluginStore, PluginGroups } from "/@/store/plugin";
import { useCompute } from "@fast-crud/fast-crud";
import { useReference } from "/@/use/use-refrence";
import { useSettingStore } from "/@/store/modules/settings";
import * as pluginApi from "../../../api.plugin";
import { useSettingStore } from "/@/store/settings";
import { mitter } from "/@/utils/util.mitt";
import { utils } from "/@/utils";
export default {
defineOptions({
name: "PiStepForm",
// eslint-disable-next-line vue/no-unused-components
components: { CopyOutlined },
props: {
editMode: {
type: Boolean,
default: true,
});
const props = defineProps({
editMode: {
type: Boolean,
default: true,
},
});
const emit = defineEmits(["update"]);
const pluginStore = usePluginStore();
function transformDesc(desc: string = "") {
return utils.transformLink(desc);
}
/**
* step drawer
* @returns
*/
function useStepForm() {
const settingStore = useSettingStore();
const mode: Ref = ref("add");
const callback: Ref = ref();
const currentStep: Ref = ref({ title: undefined, input: {} });
const stepFormRef: Ref = ref(null);
const stepDrawerVisible: Ref = ref(false);
const fullscreen: Ref<boolean> = ref(false);
const rules: Ref = ref({
name: [
{
type: "string",
required: true,
message: "请输入名称",
},
],
});
const stepTypeSelected = (item: any) => {
if (item.needPlus && !settingStore.isPlus) {
message.warn("此插件需要开通专业版才能使用");
mitter.emit("openVipModal");
throw new Error("此插件需要开通专业版才能使用");
}
currentStep.value.type = item.name;
currentStep.value.title = item.title;
console.log("currentStepTypeChanged:", currentStep.value);
};
const stepTypeSave = async () => {
currentStep.value._isAdd = false;
if (currentStep.value.type == null) {
message.warn("请先选择类型");
return;
}
// stepinput
await changeCurrentPlugin(currentStep.value);
//
merge(
currentStep.value,
{
input: {},
strategy: { runStrategy: 0 },
},
currentPlugin.value.default,
currentStep.value
);
};
const stepDrawerShow = () => {
stepDrawerVisible.value = true;
};
const stepDrawerClose = () => {
stepDrawerVisible.value = false;
};
const stepOpen = (step: any, emit: any) => {
callback.value = emit;
currentStep.value = merge({ input: {}, strategy: {} }, step);
if (step.type) {
changeCurrentPlugin(currentStep.value);
}
stepDrawerShow();
};
const stepAdd = (emit: any, stepDef: any) => {
mode.value = "add";
const step: any = {
id: nanoid(),
title: "新任务",
type: undefined,
_isAdd: true,
input: {},
status: null,
};
merge(step, stepDef);
stepOpen(step, emit);
};
const stepEdit = (step: any, emit: any) => {
mode.value = "edit";
stepOpen(step, emit);
};
const stepView = (step: any, emit: any) => {
mode.value = "view";
stepOpen(step, emit);
};
const currentPluginDefine = ref();
provide("getCurrentPluginDefine", () => {
return currentPluginDefine;
});
provide("get:plugin:type", () => {
return "plugin";
});
function getContext() {
return {
form: currentStep.value.input,
};
}
const { doComputed } = useCompute();
const currentPlugin = doComputed(() => {
return currentPluginDefine.value || {};
}, getContext);
const changeCurrentPlugin = async (step: any) => {
const stepType = step.type;
step.type = stepType;
step._isAdd = false;
const pluginDefine = await pluginStore.getPluginDefine(stepType);
// let pluginDefine = pluginGroups.get(stepType);
if (pluginDefine == null) {
console.log("插件未找到", stepType);
return;
}
// pluginDefine = _.cloneDeep(pluginDefine);
const columns = pluginDefine.input;
for (let key in columns) {
const column = columns[key];
useReference(column);
}
currentPluginDefine.value = pluginDefine;
for (let key in pluginDefine.input) {
const column = pluginDefine.input[key];
//
if ((column.default != null || column.value != null) && currentStep.value.input[key] == null) {
currentStep.value.input[key] = column.default ?? column.value;
}
}
//
const pluginSysConfig = await pluginStore.getPluginConfig({ name: pluginDefine.name, type: "builtIn" });
if (pluginSysConfig.sysSetting?.input) {
for (const key in pluginSysConfig.sysSetting?.input) {
currentStep.value.input[key] = pluginSysConfig.sysSetting?.input[key];
}
}
console.log("currentStepTypeChanged:", currentStep.value);
console.log("currentStepPlugin:", currentPlugin.value);
};
const stepSave = async (e: any) => {
console.log("currentStepSave", currentStep.value);
try {
await stepFormRef.value.validate();
} catch (e) {
console.error("表单验证失败:", e);
return;
}
callback.value("save", currentStep.value);
stepDrawerClose();
};
const stepDelete = () => {
Modal.confirm({
title: "确认",
content: `确定要删除此步骤吗?`,
async onOk() {
callback.value("delete");
stepDrawerClose();
},
});
};
const stepCopy = () => {
const step = cloneDeep(currentStep.value);
step.id = nanoid();
step.title = `${step.title}-copy`;
callback.value("copy", step);
stepDrawerClose();
};
const getScopeFunc = () => {
return {
form: currentStep.value,
};
};
const pluginSearch = ref({
keyword: "",
result: [],
});
const pluginGroupActive = ref("all");
const pluginGroup: Ref = ref();
const pluginStore = usePluginStore();
async function loadPluginGroups() {
pluginGroup.value = await pluginStore.getGroups();
}
loadPluginGroups();
const computedPluginGroups: any = computed(() => {
if (!pluginGroup.value) {
return {};
}
const group = pluginGroup.value as PluginGroups;
const groups = group.groups;
if (pluginSearch.value.keyword) {
const keyword = pluginSearch.value.keyword.toLowerCase();
const list = groups.all.plugins.filter((plugin: any) => {
return plugin.title?.toLowerCase().includes(keyword) || plugin.desc?.toLowerCase().includes(keyword) || plugin.name?.toLowerCase().includes(keyword);
});
return {
search: { key: "search", title: "搜索结果", plugins: list },
};
} else {
return groups;
}
});
watch(
() => {
return pluginSearch.value.keyword;
},
(val: any) => {
if (val) {
pluginGroupActive.value = "search";
} else {
pluginGroupActive.value = "all";
}
}
);
return {
pluginGroupActive,
computedPluginGroups,
pluginSearch,
stepTypeSelected,
stepTypeSave,
stepFormRef,
mode,
stepAdd,
stepEdit,
stepView,
stepDrawerShow,
stepDrawerVisible,
currentStep,
currentPlugin,
stepSave,
stepDelete,
rules,
getScopeFunc,
stepCopy,
fullscreen,
};
}
const runStrategyProps = ref({
title: "运行策略",
key: "strategy.runStrategy",
component: {
name: "a-select",
vModel: "value",
options: [
{ value: 0, label: "正常运行(只有证书申请任务需要选择它)" },
{ value: 1, label: "成功后跳过(其他任务请选择它)" },
],
},
helper: {
render: () => {
return (
<div>
<div class="color-green">一般保持默认即可</div>
<div>正常运行每次都运行证书任务需要每次都运行</div>
<div>成功后跳过该任务成功一次之后跳过不重复执行证书变化之后才会再次运行</div>
</div>
);
},
},
emits: ["update"],
setup(props: any, context: any) {
function transformDesc(desc: string = "") {
return utils.transformLink(desc);
}
rules: [{ required: true, message: "此项必填" }],
});
/**
* step drawer
* @returns
*/
function useStepForm() {
const settingStore = useSettingStore();
const getPluginGroups: any = inject("getPluginGroups");
const pluginGroups: PluginGroups = getPluginGroups();
const mode: Ref = ref("add");
const callback: Ref = ref();
const currentStep: Ref = ref({ title: undefined, input: {} });
const stepFormRef: Ref = ref(null);
const stepDrawerVisible: Ref = ref(false);
const fullscreen: Ref<boolean> = ref(false);
const rules: Ref = ref({
name: [
{
type: "string",
required: true,
message: "请输入名称",
},
],
});
const labelCol = ref({ span: 6 });
const wrapperCol = ref({ span: 16 });
const stepTypeSelected = (item: any) => {
if (item.needPlus && !settingStore.isPlus) {
message.warn("此插件需要开通专业版才能使用");
mitter.emit("openVipModal");
throw new Error("此插件需要开通专业版才能使用");
}
currentStep.value.type = item.name;
currentStep.value.title = item.title;
console.log("currentStepTypeChanged:", currentStep.value);
};
const stepTypeSave = async () => {
currentStep.value._isAdd = false;
if (currentStep.value.type == null) {
message.warn("请先选择类型");
return;
}
// stepinput
await changeCurrentPlugin(currentStep.value);
//
_.merge(currentStep.value, { input: {}, strategy: { runStrategy: 0 } }, currentPlugin.value.default, currentStep.value);
};
const stepDrawerShow = () => {
stepDrawerVisible.value = true;
};
const stepDrawerClose = () => {
stepDrawerVisible.value = false;
};
const stepOpen = (step: any, emit: any) => {
callback.value = emit;
currentStep.value = _.merge({ input: {}, strategy: {} }, step);
if (step.type) {
changeCurrentPlugin(currentStep.value);
}
stepDrawerShow();
};
const stepAdd = (emit: any, stepDef: any) => {
mode.value = "add";
const step: any = {
id: nanoid(),
title: "新任务",
type: undefined,
_isAdd: true,
input: {},
status: null,
};
_.merge(step, stepDef);
stepOpen(step, emit);
};
const stepEdit = (step: any, emit: any) => {
mode.value = "edit";
stepOpen(step, emit);
};
const stepView = (step: any, emit: any) => {
mode.value = "view";
stepOpen(step, emit);
};
const currentPluginDefine = ref();
provide("getCurrentPluginDefine", () => {
return currentPluginDefine;
});
provide("get:plugin:type", () => {
return "plugin";
});
function getContext() {
return {
form: currentStep.value.input,
};
}
const { doComputed } = useCompute();
const currentPlugin = doComputed(() => {
return currentPluginDefine.value || {};
}, getContext);
const changeCurrentPlugin = async (step: any) => {
const stepType = step.type;
step.type = stepType;
step._isAdd = false;
const pluginDefine = await pluginApi.GetPluginDefine(stepType);
// let pluginDefine = pluginGroups.get(stepType);
if (pluginDefine == null) {
console.log("插件未找到", stepType);
return;
}
// pluginDefine = _.cloneDeep(pluginDefine);
const columns = pluginDefine.input;
for (let key in columns) {
const column = columns[key];
useReference(column);
}
currentPluginDefine.value = pluginDefine;
for (let key in pluginDefine.input) {
const column = pluginDefine.input[key];
//
if ((column.default != null || column.value != null) && currentStep.value.input[key] == null) {
currentStep.value.input[key] = column.default ?? column.value;
}
}
//
const pluginSysConfig = await pluginApi.GetPluginConfig({ name: pluginDefine.name, type: "builtIn" });
if (pluginSysConfig.sysSetting?.input) {
for (const key in pluginSysConfig.sysSetting?.input) {
currentStep.value.input[key] = pluginSysConfig.sysSetting?.input[key];
}
}
console.log("currentStepTypeChanged:", currentStep.value);
console.log("currentStepPlugin:", currentPlugin.value);
};
const stepSave = async (e: any) => {
console.log("currentStepSave", currentStep.value);
try {
await stepFormRef.value.validate();
} catch (e) {
console.error("表单验证失败:", e);
return;
}
callback.value("save", currentStep.value);
stepDrawerClose();
};
const stepDelete = () => {
Modal.confirm({
title: "确认",
content: `确定要删除此步骤吗?`,
async onOk() {
callback.value("delete");
stepDrawerClose();
},
});
};
const stepCopy = () => {
const step = _.cloneDeep(currentStep.value);
step.id = nanoid();
step.title = `${step.title}-copy`;
callback.value("copy", step);
stepDrawerClose();
};
const getScopeFunc = () => {
return {
form: currentStep.value,
};
};
const pluginSearch = ref({
keyword: "",
result: [],
});
const pluginGroupActive = ref("all");
const computedPluginGroups: any = computed(() => {
const groups = pluginGroups.groups;
if (pluginSearch.value.keyword) {
const keyword = pluginSearch.value.keyword.toLowerCase();
const list = groups.all.plugins.filter(plugin => {
return plugin.title?.toLowerCase().includes(keyword) || plugin.desc?.toLowerCase().includes(keyword) || plugin.name?.toLowerCase().includes(keyword);
});
return {
search: { key: "search", title: "搜索结果", plugins: list },
};
} else {
return groups;
}
});
watch(
() => {
return pluginSearch.value.keyword;
},
(val: any) => {
if (val) {
pluginGroupActive.value = "search";
} else {
pluginGroupActive.value = "all";
}
}
);
return {
pluginGroupActive,
computedPluginGroups,
pluginSearch,
stepTypeSelected,
stepTypeSave,
pluginGroups,
stepFormRef,
mode,
stepAdd,
stepEdit,
stepView,
stepDrawerShow,
stepDrawerVisible,
currentStep,
currentPlugin,
stepSave,
stepDelete,
rules,
getScopeFunc,
stepCopy,
fullscreen,
};
}
const runStrategyProps = ref({
title: "运行策略",
key: "strategy.runStrategy",
component: {
name: "a-select",
vModel: "value",
options: [
{ value: 0, label: "正常运行(只有证书申请任务需要选择它)" },
{ value: 1, label: "成功后跳过(其他任务请选择它)" },
],
},
helper: {
render: () => {
return (
<div>
<div class="color-green">一般保持默认即可</div>
<div>正常运行每次都运行证书任务需要每次都运行</div>
<div>成功后跳过该任务成功一次之后跳过不重复执行证书变化之后才会再次运行</div>
</div>
);
},
},
rules: [{ required: true, message: "此项必填" }],
});
return {
...useStepForm(),
labelCol: { span: 6 },
wrapperCol: { span: 16 },
runStrategyProps,
transformDesc,
};
},
};
const stepFormRes = useStepForm();
const { pluginGroupActive, computedPluginGroups, pluginSearch, stepTypeSelected, stepTypeSave, stepFormRef, stepDrawerVisible, currentStep, currentPlugin, stepSave, stepDelete, getScopeFunc, fullscreen } = stepFormRes;
defineExpose({
...stepFormRes,
});
</script>
<style lang="less">
@ -427,6 +446,7 @@ export default {
display: flex;
align-items: center;
color: #00b7ff;
svg {
vertical-align: middle !important;
display: flex;
@ -437,28 +457,35 @@ export default {
.step-form-drawer {
max-width: 100%;
.ant-tabs-right > div > .ant-tabs-nav .ant-tabs-tab {
padding: 8px 10px;
}
.ant-tabs-nav .ant-tabs-tab {
margin-top: 10px !important;
}
&.fullscreen {
.pi-step-form {
.body {
margin: auto;
.step-plugin {
width: 16.666666%;
}
.step-form {
display: flex;
flex-wrap: wrap;
width: 1500px;
.fs-form-item {
width: 100%;
}
}
}
.footer {
.bottom-button {
text-align: center;
@ -491,14 +518,17 @@ export default {
.step-plugin {
}
.ant-tabs-content {
height: 100%;
}
.ant-tabs-tabpane {
padding-right: 10px;
overflow-y: auto;
overflow-x: hidden;
}
.ant-card {
margin-bottom: 10px;

View File

@ -1,12 +1,5 @@
<template>
<a-drawer
v-model:open="taskDrawerVisible"
placement="right"
:closable="true"
width="700px"
class="pi-task-form"
@after-open-change="taskDrawerOnAfterVisibleChange"
>
<a-drawer v-model:open="taskDrawerVisible" placement="right" :closable="true" width="700px" class="pi-task-form" @after-open-change="taskDrawerOnAfterVisibleChange">
<template #title>
<div>
编辑任务
@ -25,21 +18,15 @@
key: 'title',
component: {
name: 'a-input',
vModel: 'value'
vModel: 'value',
},
rules: [{ required: true, message: '此项必填' }]
rules: [{ required: true, message: '此项必填' }],
}"
:get-context-fn="blankFn"
/>
<div class="steps">
<a-form-item
:value="currentTask.steps"
name="steps"
label=""
:wrapper-col="{ span: 24 }"
:rules="[{ required: true, message: '至少需要一个步骤,或者你可以点击标题右边删除按钮删除此任务' }]"
>
<a-form-item :value="currentTask.steps" name="steps" label="" :wrapper-col="{ span: 24 }" :rules="[{ required: true, message: '至少需要一个步骤,或者你可以点击标题右边删除按钮删除此任务' }]">
<a-descriptions title="任务步骤" size="small">
<template #extra>
<a-button type="primary" @click="stepAdd(currentTask)"></a-button>
@ -86,8 +73,8 @@ import PiStepForm from "../step-form/index.vue";
import { Modal } from "ant-design-vue";
import { CopyOutlined } from "@ant-design/icons-vue";
import VDraggable from "vuedraggable";
import { useUserStore } from "/@/store/modules/user";
import { useSettingStore } from "/@/store/modules/settings";
import { useUserStore } from "/@/store/user";
import { useSettingStore } from "/@/store/settings";
import { filter } from "lodash-es";
export default {
name: "PiTaskForm",
@ -95,8 +82,8 @@ export default {
props: {
editMode: {
type: Boolean,
default: true
}
default: true,
},
},
emits: ["update"],
setup(props: any, ctx: any) {
@ -149,7 +136,7 @@ export default {
content: `确定要删除此步骤吗?`,
async onOk() {
task.steps.splice(stepIndex, 1);
}
},
});
};
@ -176,9 +163,9 @@ export default {
{
type: "string",
required: true,
message: "请输入名称"
}
]
message: "请输入名称",
},
],
});
const taskDrawerShow = () => {
@ -245,7 +232,7 @@ export default {
async onOk() {
callback.value("delete");
taskDrawerClose();
}
},
});
};
@ -265,7 +252,7 @@ export default {
taskSave,
taskDelete,
rules,
blankFn
blankFn,
};
}
return {
@ -274,9 +261,9 @@ export default {
labelCol: { span: 6 },
wrapperCol: { span: 16 },
...useTaskForm(),
...useStep()
...useStep(),
};
}
},
};
</script>

View File

@ -255,7 +255,7 @@
</template>
<script lang="ts">
import { defineComponent, ref, provide, Ref, watch, onMounted } from "vue";
import { defineComponent, onMounted, provide, Ref, ref, watch } from "vue";
import { useRouter } from "vue-router";
import PiTaskForm from "./component/task-form/index.vue";
import PiTriggerForm from "./component/trigger-form/index.vue";
@ -264,16 +264,17 @@ import PiTaskView from "./component/task-view/index.vue";
import PiStatusShow from "./component/status-show.vue";
import VDraggable from "vuedraggable";
import * as _ from "lodash-es";
import { message, Modal, notification, TourProps } from "ant-design-vue";
import { message, Modal, notification } from "ant-design-vue";
import { nanoid } from "nanoid";
import { PipelineDetail, PipelineOptions, PluginGroups, RunHistory } from "./type";
import { PipelineDetail, PipelineOptions, RunHistory } from "./type";
import type { Runnable, Stage } from "@certd/pipeline";
import PiHistoryTimelineItem from "/@/views/certd/pipeline/pipeline/component/history-timeline-item.vue";
import { FsIcon } from "@fast-crud/fast-crud";
import { useSettingStore } from "/@/store/modules/settings";
import { useUserStore } from "/@/store/modules/user";
import { useSettingStore } from "/@/store/settings";
import { useUserStore } from "/@/store/user";
import TaskShortcuts from "./component/shortcut/task-shortcuts.vue";
import { eachSteps, findStep } from "../utils";
export default defineComponent({
name: "PipelineEdit",
// eslint-disable-next-line vue/no-unused-components

View File

@ -1,5 +1,6 @@
import type { Pipeline } from "@certd/pipeline";
import { DynamicType, FormItemProps } from "@fast-crud/fast-crud";
import { PluginGroups } from "/@/store/plugin";
export type PipelineDetail = {
pipeline: Pipeline;
};
@ -11,120 +12,6 @@ export type RunHistory = {
[id: string]: string[];
};
};
export type PluginGroup = {
key: string;
title: string;
desc?: string;
order: number;
plugins: any[];
};
export type PluginDefine = {
name: string;
title: string;
desc?: string;
input: {
[key: string]: DynamicType<FormItemProps>;
};
output: {
[key: string]: any;
};
};
export class PluginGroups {
groups: { [key: string]: PluginGroup };
map: { [key: string]: PluginDefine };
constructor(groups: { [key: string]: PluginGroup }) {
this.groups = groups;
this.initGroup(groups);
this.initMap();
}
private initGroup(groups: { [p: string]: PluginGroup }) {
const all: PluginGroup = {
key: "all",
title: "全部",
order: 0,
plugins: [],
icon: "material-symbols:border-all-rounded",
};
for (const key in groups) {
all.plugins.push(...groups[key].plugins);
}
this.groups = {
all,
...groups,
};
}
initMap() {
const map: { [key: string]: PluginDefine } = {};
for (const key in this.groups) {
const group = this.groups[key];
for (const plugin of group.plugins) {
map[plugin.name] = plugin;
}
}
this.map = map;
}
getGroups() {
return this.groups;
}
get(name: string) {
return this.map[name];
}
getPreStepOutputOptions({ pipeline, currentStageIndex, currentTaskIndex, currentStepIndex, currentTask }: any) {
const steps = this.collectionPreStepOutputs({
pipeline,
currentStageIndex,
currentTaskIndex,
currentStepIndex,
currentTask,
});
const options: any[] = [];
for (const step of steps) {
const stepDefine = this.get(step.type);
for (const key in stepDefine?.output) {
options.push({
value: `step.${step.id}.${key}`,
label: `${stepDefine.output[key].title}【from${step.title}`,
type: step.type,
});
}
}
return options;
}
collectionPreStepOutputs({ pipeline, currentStageIndex, currentTaskIndex, currentStepIndex, currentTask }: any) {
const steps: any[] = [];
// 开始放step
for (let i = 0; i < currentStageIndex; i++) {
const stage = pipeline.stages[i];
for (const task of stage.tasks) {
for (const step of task.steps) {
steps.push(step);
}
}
}
//当前阶段之前的task
const currentStage = pipeline.stages[currentStageIndex];
for (let i = 0; i < currentTaskIndex; i++) {
const task = currentStage.tasks[i];
for (const step of task.steps) {
steps.push(step);
}
}
//放当前任务下的step
for (let i = 0; i < currentStepIndex; i++) {
const step = currentTask.steps[i];
steps.push(step);
}
return steps;
}
}
export type PipelineOptions = {
doTrigger(options: { pipelineId: number; stepId?: string }): Promise<void>;

View File

@ -1,7 +1,7 @@
import { forEach } from "lodash-es";
import { mySuiteApi } from "/@/views/certd/suite/mine/api";
import { notification } from "ant-design-vue";
import { useSettingStore } from "/@/store/modules/settings";
import { useSettingStore } from "/@/store/settings";
//@ts-ignore
import forge from "node-forge";
export function eachStages(list: any[], exec: (item: any, runnableType: string) => void, runnableType: string = "stage") {

View File

@ -3,8 +3,8 @@ import { useI18n } from "vue-i18n";
import { computed, Ref, ref } from "vue";
import { useRouter } from "vue-router";
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes, utils } from "@fast-crud/fast-crud";
import { useUserStore } from "/@/store/modules/user";
import { useSettingStore } from "/@/store/modules/settings";
import { useUserStore } from "/@/store/user";
import { useSettingStore } from "/@/store/settings";
import { Modal } from "ant-design-vue";
import PriceInput from "/@/views/sys/suite/product/price-input.vue";
import SuiteValue from "/@/views/sys/suite/product/suite-value.vue";

View File

@ -29,7 +29,7 @@
</template>
<script lang="ts" setup>
import { computed, ref, Ref } from "vue";
import { useSettingStore } from "/@/store/modules/settings";
import { useSettingStore } from "/@/store/settings";
import { SiteInfo } from "/@/api/modules/api.basic";
const version = ref(import.meta.env.VITE_APP_VERSION);

View File

@ -4,7 +4,7 @@ import { LocalStorage } from "/@/utils/util.storage";
export async function GetStatisticCount() {
return await request({
url: "/statistic/count",
method: "POST"
method: "POST",
});
}
@ -16,7 +16,7 @@ export async function GetLatestVersion() {
const res = await request({
url: "/app/latest",
method: "GET",
unpack: true
unpack: true,
});
try {
const latest = res;

View File

@ -125,23 +125,22 @@
<script lang="ts" setup>
import { FsIcon } from "@fast-crud/fast-crud";
import SimpleSteps from "/@/components/tutorial/simple-steps.vue";
import { useUserStore } from "/@/store/modules/user";
import { useUserStore } from "/@/store/user";
import { computed, ComputedRef, onMounted, Ref, ref } from "vue";
import dayjs from "dayjs";
import StatisticCard from "/@/views/framework/home/dashboard/statistic-card.vue";
import * as pluginApi from "/@/views/certd/pipeline/api.plugin";
import { PluginGroups } from "/@/views/certd/pipeline/pipeline/type";
import TutorialButton from "/@/components/tutorial/index.vue";
import DayCount from "./charts/day-count.vue";
import PieCount from "./charts/pie-count.vue";
import ExpiringList from "./charts/expiring-list.vue";
import SuiteCard from "./suite-card.vue";
import { useSettingStore } from "/@/store/modules/settings";
import { SiteInfo } from "/@/api/modules/api.basic";
import { UserInfoRes } from "/@/api/modules/api.user";
import { useSettingStore } from "/@/store/settings";
import { SiteInfo } from "/@/store/settings/api.basic";
import { UserInfoRes } from "/@/store/user/api.user";
import { GetStatisticCount } from "/@/views/framework/home/dashboard/api";
import { useRouter } from "vue-router";
import * as api from "./api";
import { usePluginStore } from "/@/store/plugin";
defineOptions({
name: "DashboardUser",
});
@ -227,9 +226,10 @@ async function loadCount() {
});
}
const pluginStore = usePluginStore();
async function loadPluginGroups() {
const groups = await pluginApi.GetGroups({});
pluginGroups.value = new PluginGroups(groups);
const groups = await pluginStore.getGroups();
pluginGroups.value = groups;
}
const pluginGroups = ref();

View File

@ -8,7 +8,7 @@
<script lang="ts" setup>
import DashboardUser from "./dashboard/index.vue";
import { useUserStore } from "/@/store/modules/user";
import { useUserStore } from "/@/store/user";
import ChangePasswordButton from "/@/views/certd/mine/change-password-button.vue";
import { onMounted, ref } from "vue";
import { Modal } from "ant-design-vue";

View File

@ -67,8 +67,8 @@
</template>
<script lang="ts">
import { defineComponent, reactive, ref, toRaw } from "vue";
import { useUserStore } from "/src/store/modules/user";
import { useSettingStore } from "/@/store/modules/settings";
import { useUserStore } from "/src/store/user";
import { useSettingStore } from "/@/store/settings";
import { utils } from "@fast-crud/fast-crud";
import ImageCode from "/@/views/framework/login/image-code.vue";
import SmsCode from "/@/views/framework/login/sms-code.vue";

View File

@ -87,11 +87,11 @@
</template>
<script lang="ts">
import { defineComponent, reactive, ref, toRaw } from "vue";
import { useUserStore } from "/src/store/modules/user";
import { useUserStore } from "/src/store/user";
import { utils } from "@fast-crud/fast-crud";
import ImageCode from "/@/views/framework/login/image-code.vue";
import EmailCode from "./email-code.vue";
import { useSettingStore } from "/@/store/modules/settings";
import { useSettingStore } from "/@/store/settings";
import { notification } from "ant-design-vue";
export default defineComponent({
name: "RegisterPage",

View File

@ -14,8 +14,8 @@
<script setup lang="tsx">
import { IframeClient } from "@certd/lib-iframe";
import { computed, onMounted, ref } from "vue";
import { useUserStore } from "/@/store/modules/user";
import { useSettingStore } from "/@/store/modules/settings";
import { useUserStore } from "/@/store/user";
import { useSettingStore } from "/@/store/settings";
import * as api from "./api";
import { notification } from "ant-design-vue";

View File

@ -1,6 +1,6 @@
import * as api from "./api";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { useUserStore } from "/@/store/modules/user";
import { useUserStore } from "/@/store/user";
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {

View File

@ -3,8 +3,8 @@ import { useI18n } from "vue-i18n";
import { computed, Ref, ref } from "vue";
import { useRouter } from "vue-router";
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes, utils } from "@fast-crud/fast-crud";
import { useUserStore } from "/@/store/modules/user";
import { useSettingStore } from "/@/store/modules/settings";
import { useUserStore } from "/@/store/user";
import { useSettingStore } from "/@/store/settings";
import { Modal } from "ant-design-vue";
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {

View File

@ -3,8 +3,6 @@ import { useI18n } from "vue-i18n";
import { Ref, ref } from "vue";
import { useRouter } from "vue-router";
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { useUserStore } from "/src/store/modules/user";
import { useSettingStore } from "/src/store/modules/settings";
import { Modal } from "ant-design-vue";
//@ts-ignore
import yaml from "js-yaml";
@ -29,8 +27,6 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
return res;
};
const userStore = useUserStore();
const settingStore = useSettingStore();
const selectedRowKeys: Ref<any[]> = ref([]);
context.selectedRowKeys = selectedRowKeys;

View File

@ -54,6 +54,7 @@ defineOptions({
});
const route = useRoute();
const pluginStore = usePluginStore();
const plugin = ref<any>({});
const formOptionsRef: Ref = ref();
const baseFormRef: Ref = ref({});
@ -145,6 +146,7 @@ async function doSave() {
notification.success({
message: "保存成功",
});
pluginStore.clear();
} finally {
saveLoading.value = false;
}

View File

@ -8,16 +8,7 @@
</template>
<div class="flex-o">
<a-form
:model="formState"
name="basic"
:label-col="{ span: 8 }"
:wrapper-col="{ span: 16 }"
autocomplete="off"
class="email-form-box"
@finish="onFinish"
@finish-failed="onFinishFailed"
>
<a-form :model="formState" name="basic" :label-col="{ span: 8 }" :wrapper-col="{ span: 16 }" autocomplete="off" class="email-form-box" @finish="onFinish" @finish-failed="onFinishFailed">
<div v-if="!formState.usePlus" class="email-form">
<a-form-item label="使用自定义邮件服务器"> </a-form-item>
<a-form-item label="SMTP域名" name="host" :rules="[{ required: true, message: '请输入smtp域名或ip' }]">
@ -80,13 +71,12 @@
<script setup lang="ts">
import { reactive } from "vue";
import * as api from "../api";
import { EmailSettingsSave, SettingKeys } from "../api";
import * as emailApi from "./api.email";
import { notification } from "ant-design-vue";
import { useSettingStore } from "/src/store/modules/settings";
import { useSettingStore } from "/src/store/settings";
import * as _ from "lodash-es";
defineOptions({
name: "EmailSetting"
name: "EmailSetting",
});
interface FormState {
@ -108,10 +98,10 @@ interface FormState {
const formState = reactive<Partial<FormState>>({
auth: {
user: "",
pass: ""
pass: "",
},
tls: {},
usePlus: false
usePlus: false,
});
async function load() {
@ -125,7 +115,7 @@ const onFinish = async (form: any) => {
console.log("Success:", form);
await api.EmailSettingsSave(form);
notification.success({
message: "保存成功"
message: "保存成功",
});
};
@ -143,14 +133,14 @@ interface TestFormState {
}
const testFormState = reactive<TestFormState>({
receiver: "",
loading: false
loading: false,
});
async function onTestSend() {
testFormState.loading = true;
try {
await emailApi.TestSend(testFormState.receiver);
notification.success({
message: "发送成功"
message: "发送成功",
});
} finally {
testFormState.loading = false;

View File

@ -2,7 +2,7 @@ import { useI18n } from "vue-i18n";
import { Ref, ref } from "vue";
import { useRouter } from "vue-router";
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { useSettingStore } from "/@/store/modules/settings";
import { useSettingStore } from "/@/store/settings";
import { cloneDeep, find, merge, remove } from "lodash-es";
import { nanoid } from "nanoid";
import { HeaderMenusSettingsSave, SettingsSave } from "../api";

View File

@ -11,7 +11,7 @@
import { onActivated, onMounted } from "vue";
import { useFs } from "@fast-crud/fast-crud";
import createCrudOptions from "./crud";
import { useSettingStore } from "/@/store/modules/settings";
import { useSettingStore } from "/@/store/settings";
defineOptions({
name: "SettingsHeaderMenus",

View File

@ -25,7 +25,7 @@ import SettingRegister from "/@/views/sys/settings/tabs/register.vue";
import SettingPayment from "/@/views/sys/settings/tabs/payment.vue";
import { useRoute, useRouter } from "vue-router";
import { ref } from "vue";
import { useSettingStore } from "/@/store/modules/settings";
import { useSettingStore } from "/@/store/settings";
defineOptions({
name: "SysSettings",
});

View File

@ -48,7 +48,7 @@ import { reactive, ref } from "vue";
import { SysSettings } from "/@/views/sys/settings/api";
import * as api from "/@/views/sys/settings/api";
import { merge } from "lodash-es";
import { useSettingStore } from "/@/store/modules/settings";
import { useSettingStore } from "/@/store/settings";
import { notification } from "ant-design-vue";
import { util } from "/@/utils";

View File

@ -62,7 +62,7 @@ import { reactive, ref, Ref } from "vue";
import { GetSmsTypeDefine, SysSettings } from "/@/views/sys/settings/api";
import * as api from "/@/views/sys/settings/api";
import { merge } from "lodash-es";
import { useSettingStore } from "/@/store/modules/settings";
import { useSettingStore } from "/@/store/settings";
import { notification } from "ant-design-vue";
defineOptions({

View File

@ -42,8 +42,8 @@
import { reactive, ref } from "vue";
import * as api from "./api";
import { notification } from "ant-design-vue";
import { useSettingStore } from "/src/store/modules/settings";
import { useUserStore } from "/@/store/modules/user";
import { useSettingStore } from "/src/store/settings";
import { useUserStore } from "/@/store/user";
import { merge } from "lodash-es";
defineOptions({

View File

@ -46,7 +46,7 @@ import { notification } from "ant-design-vue";
import { request } from "/@/api/service";
import SuiteDurationSelector from "/@/views/sys/suite/setting/suite-duration-selector.vue";
import ProductManager from "/@/views/sys/suite/product/index.vue";
import { useSettingStore } from "/@/store/modules/settings";
import { useSettingStore } from "/@/store/settings";
defineOptions({
name: "SettingsSuite"

View File

@ -3,8 +3,8 @@ import { useI18n } from "vue-i18n";
import { computed, Ref, ref } from "vue";
import { useRouter } from "vue-router";
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes, utils } from "@fast-crud/fast-crud";
import { useUserStore } from "/@/store/modules/user";
import { useSettingStore } from "/@/store/modules/settings";
import { useUserStore } from "/@/store/user";
import { useSettingStore } from "/@/store/settings";
import { Modal } from "ant-design-vue";
import DurationValue from "/@/views/sys/suite/product/duration-value.vue";
import PriceInput from "/@/views/sys/suite/product/price-input.vue";

View File

@ -43,15 +43,18 @@ export class PluginService extends BaseService<PluginEntity> {
};
}
async getEnabledBuildInGroup() {
async getEnabledBuildInGroup(isSimple = false) {
const groups = this.builtInPluginService.getGroups();
for (const key in groups) {
const group = groups[key];
group.plugins.forEach(item => {
delete item.input;
});
if(isSimple){
for (const key in groups) {
const group = groups[key];
group.plugins.forEach(item => {
delete item.input;
});
}
}
if (!isComm()) {
return groups;
}

View File

@ -46,7 +46,7 @@ importers:
packages/core/acme-client:
dependencies:
'@certd/basic':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../basic
'@peculiar/x509':
specifier: ^1.11.0
@ -204,10 +204,10 @@ importers:
packages/core/pipeline:
dependencies:
'@certd/basic':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../basic
'@certd/plus-core':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../pro/plus-core
dayjs:
specifier: ^1.11.7
@ -412,7 +412,7 @@ importers:
packages/libs/lib-k8s:
dependencies:
'@certd/basic':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../core/basic
'@kubernetes/client-node':
specifier: 0.21.0
@ -452,16 +452,16 @@ importers:
packages/libs/lib-server:
dependencies:
'@certd/acme-client':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../core/acme-client
'@certd/basic':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../core/basic
'@certd/pipeline':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../core/pipeline
'@certd/plus-core':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../pro/plus-core
'@midwayjs/cache':
specifier: ~3.14.0
@ -604,16 +604,16 @@ importers:
packages/plugins/plugin-cert:
dependencies:
'@certd/acme-client':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../core/acme-client
'@certd/basic':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../core/basic
'@certd/pipeline':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../core/pipeline
'@certd/plugin-lib':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../plugin-lib
'@google-cloud/publicca':
specifier: ^1.3.0
@ -680,10 +680,10 @@ importers:
specifier: ^1.7.10
version: 1.8.0
'@certd/basic':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../core/basic
'@certd/pipeline':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../core/pipeline
'@kubernetes/client-node':
specifier: 0.21.0
@ -771,19 +771,19 @@ importers:
packages/pro/commercial-core:
dependencies:
'@certd/basic':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../core/basic
'@certd/lib-server':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../libs/lib-server
'@certd/pipeline':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../core/pipeline
'@certd/plugin-plus':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../plugin-plus
'@certd/plus-core':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../plus-core
'@midwayjs/core':
specifier: ~3.20.3
@ -868,22 +868,22 @@ importers:
specifier: ^1.0.2
version: 1.0.2
'@certd/basic':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../core/basic
'@certd/lib-k8s':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../libs/lib-k8s
'@certd/pipeline':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../core/pipeline
'@certd/plugin-cert':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../plugins/plugin-cert
'@certd/plugin-lib':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../plugins/plugin-lib
'@certd/plus-core':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../plus-core
ali-oss:
specifier: ^6.21.0
@ -980,7 +980,7 @@ importers:
packages/pro/plus-core:
dependencies:
'@certd/basic':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../core/basic
dayjs:
specifier: ^1.11.7
@ -1264,10 +1264,10 @@ importers:
version: 0.1.3(zod@3.24.2)
devDependencies:
'@certd/lib-iframe':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../libs/lib-iframe
'@certd/pipeline':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../core/pipeline
'@rollup/plugin-commonjs':
specifier: ^25.0.7
@ -1447,43 +1447,43 @@ importers:
specifier: ^3.705.0
version: 3.758.0(aws-crt@1.25.3)
'@certd/acme-client':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../core/acme-client
'@certd/basic':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../core/basic
'@certd/commercial-core':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../pro/commercial-core
'@certd/jdcloud':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../libs/lib-jdcloud
'@certd/lib-huawei':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../libs/lib-huawei
'@certd/lib-k8s':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../libs/lib-k8s
'@certd/lib-server':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../libs/lib-server
'@certd/midway-flyway-js':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../libs/midway-flyway-js
'@certd/pipeline':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../core/pipeline
'@certd/plugin-cert':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../plugins/plugin-cert
'@certd/plugin-lib':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../plugins/plugin-lib
'@certd/plugin-plus':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../pro/plugin-plus
'@certd/plus-core':
specifier: ^1.32.0
specifier: ^1.33.0
version: link:../../pro/plus-core
'@corsinvest/cv4pve-api-javascript':
specifier: ^8.3.0

View File

@ -10,13 +10,14 @@ find ./packages -mindepth 1 -maxdepth 1 -type d ! -name 'ui' -exec rm -rf {} +
echo "删除成功"
echo "安装pnpm 8.15.7, 前提是已经安装了nodejs"
npm install -g pnpm@8.15.7 --registry https://registry.npmmirror.com
echo "安装pnpm, 前提是已经安装了nodejs"
npm install -g pnpm@ --registry https://registry.npmmirror.com
echo "安装依赖"
pnpm install --registry https://registry.npmmirror.com
echo "开始构建"
echo "构建certd-client"
export NODE_OPTIONS=--max-old-space-size=32768
cd packages/ui/certd-client
npm run build
cp -r dist/* ../certd-server/public