feat: ui模式

BREAKING CHANGE: 接口配置变更
This commit is contained in:
xiaojunnuo
2023-05-23 18:01:20 +08:00
parent 8c152371a1
commit 6f6606d76d
40 changed files with 303 additions and 262 deletions
+6 -3
View File
@@ -20,11 +20,14 @@
"author": "Greper",
"license": "MIT",
"dependencies": {
"@certd/acme-client": "workspace:^0.3.0",
"@certd/pipeline": "workspace:^0.3.0",
"@ant-design/colors": "^6.0.0",
"@ant-design/icons-vue": "^6.0.1",
"@fast-crud/fast-crud": "^1.9.2",
"@fast-crud/fast-extends": "^1.9.2",
"@fast-crud/ui-antdv": "^1.9.2",
"@fast-crud/fast-crud": "^1.13.8",
"@fast-crud/fast-extends": "^1.13.8",
"@fast-crud/ui-antdv": "^1.13.8",
"@fast-crud/ui-interface": "^1.13.8",
"@iconify/iconify": "^3.0.1",
"@iconify/json": "^2.1.151",
"@purge-icons/generated": "^0.9.0",
@@ -1,25 +1,31 @@
// @ts-ignore
import * as api from "/@/views/certd/access/api";
import { ref } from "vue";
import { getCommonColumnDefine } from "/@/views/certd/access/common";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
export default function ({ expose, props, ctx }) {
const { crudBinding } = expose;
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const { crudBinding } = crudExpose;
const { props, ctx } = context;
const lastResRef = ref();
const pageRequest = async (query) => {
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
return await api.GetList(query);
};
const editRequest = async ({ form, row }) => {
const editRequest = async (req: EditReq) => {
const { form, row } = req;
form.id = row.id;
form.type = props.type;
const res = await api.UpdateObj(form);
lastResRef.value = res;
return res;
};
const delRequest = async ({ row }) => {
const delRequest = async (req: DelReq) => {
const { row } = req;
return await api.DelObj(row.id);
};
const addRequest = async ({ form }) => {
const addRequest = async (req: AddReq) => {
const { form } = req;
form.type = props.type;
const res = await api.AddObj(form);
lastResRef.value = res;
@@ -27,24 +33,15 @@ export default function ({ expose, props, ctx }) {
};
const selectedRowKey = ref([props.modelValue]);
// watch(
// () => {
// return props.modelValue;
// },
// (value) => {
// selectedRowKey.value = [value];
// },
// {
// immediate: true
// }
// );
const onSelectChange = (changed) => {
const onSelectChange = (changed: any) => {
selectedRowKey.value = changed;
ctx.emit("update:modelValue", changed[0]);
};
const typeRef = ref("aliyun");
const commonColumnsDefine = getCommonColumnDefine(crudBinding, typeRef);
context.typeRef = typeRef;
const commonColumnsDefine = getCommonColumnDefine(crudExpose, typeRef);
commonColumnsDefine.type.form.component.disabled = true;
return {
typeRef,
@@ -75,7 +72,7 @@ export default function ({ expose, props, ctx }) {
selectedRowKeys: selectedRowKey,
onChange: onSelectChange
},
customRow: (record) => {
customRow: (record: any) => {
return {
onClick: () => {
onSelectChange([record.id]);
@@ -4,9 +4,9 @@
</fs-page>
</template>
<script>
import { defineComponent, onMounted, ref, watch } from "vue";
import { useCrud, useExpose } from "@fast-crud/fast-crud";
<script lang="ts">
import { defineComponent, onMounted, watch } from "vue";
import { useFs } from "@fast-crud/fast-crud";
import createCrudOptions from "./crud";
export default defineComponent({
@@ -20,22 +20,14 @@ export default defineComponent({
},
emits: ["update:modelValue"],
setup(props, ctx) {
// crud组件的ref
const crudRef = ref();
// crud 配置的ref
const crudBinding = ref();
// 暴露的方法
const { expose } = useExpose({ crudRef, crudBinding });
// 你的crud配置
const { crudOptions, typeRef } = createCrudOptions({ expose, props, ctx });
// 初始化crud配置
// eslint-disable-next-line @typescript-eslint/no-unused-vars,no-unused-vars
const { resetCrudOptions } = useCrud({ expose, crudOptions });
const context: any = { props, ctx };
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context });
// 你可以调用此方法,重新初始化crud配置
function onTypeChanged(value) {
typeRef.value = value;
expose.setSearchFormData({ form: { type: value }, mergeForm: true });
expose.doRefresh();
function onTypeChanged(value: any) {
context.typeRef.value = value;
crudExpose.setSearchFormData({ form: { type: value }, mergeForm: true });
crudExpose.doRefresh();
}
watch(
() => {
@@ -1,6 +1,6 @@
import { request } from "/src/api/service";
const apiPrefix = "/pi/access";
export function GetList(query) {
export function GetList(query: any) {
return request({
url: apiPrefix + "/page",
method: "post",
@@ -8,7 +8,7 @@ export function GetList(query) {
});
}
export function AddObj(obj) {
export function AddObj(obj: any) {
return request({
url: apiPrefix + "/add",
method: "post",
@@ -16,7 +16,7 @@ export function AddObj(obj) {
});
}
export function UpdateObj(obj) {
export function UpdateObj(obj: any) {
return request({
url: apiPrefix + "/update",
method: "post",
@@ -24,7 +24,7 @@ export function UpdateObj(obj) {
});
}
export function DelObj(id) {
export function DelObj(id: number) {
return request({
url: apiPrefix + "/delete",
method: "post",
@@ -32,7 +32,7 @@ export function DelObj(id) {
});
}
export function GetObj(id) {
export function GetObj(id: number) {
return request({
url: apiPrefix + "/info",
method: "post",
@@ -40,7 +40,7 @@ export function GetObj(id) {
});
}
export function GetProviderDefine(type) {
export function GetProviderDefine(type: string) {
return request({
url: apiPrefix + "/define",
method: "post",
@@ -1,8 +1,11 @@
import { dict } from "@fast-crud/fast-crud";
import { ColumnCompositionProps, dict } from "@fast-crud/fast-crud";
// @ts-ignore
import * as api from "./api";
// @ts-ignore
import _ from "lodash";
import { toRef } from "vue";
export function getCommonColumnDefine(crudBinding, typeRef) {
export function getCommonColumnDefine(crudExpose: any, typeRef: any) {
const AccessTypeDictRef = dict({
url: "/pi/access/accessTypeDict"
});
@@ -13,22 +16,24 @@ export function getCommonColumnDefine(crudBinding, typeRef) {
}
};
function buildDefineFields(define, mode) {
const columns = crudBinding.value[mode + "Form"].columns;
for (const key in columns) {
function buildDefineFields(define: any) {
const formWrapperRef = crudExpose.getFormWrapperRef();
const columnsRef = toRef(formWrapperRef.formOptions, "columns");
for (const key in columnsRef.value) {
if (key.indexOf(".") >= 0) {
delete columns[key];
delete columnsRef.value[key];
}
}
console.log('crudBinding.value[mode + "Form"].columns', columns);
_.forEach(define.input, (value, mapKey) => {
console.log('crudBinding.value[mode + "Form"].columns', columnsRef.value);
_.forEach(define.input, (value: any, mapKey: any) => {
const key = "access." + mapKey;
const field = {
...value,
key
};
columns[key] = _.merge({ title: key }, defaultPluginConfig, field);
console.log("form", crudBinding.value[mode + "Form"]);
columnsRef.value[key] = _.merge({ title: key }, defaultPluginConfig, field);
console.log("form", columnsRef.value);
});
}
@@ -53,14 +58,14 @@ export function getCommonColumnDefine(crudBinding, typeRef) {
}
const define = await api.GetProviderDefine(value);
console.log("define", define);
buildDefineFields(define, mode);
buildDefineFields(define);
}
}
},
addForm: {
value: typeRef
}
},
} as ColumnCompositionProps,
setting: {
column: { show: false },
form: {
@@ -80,6 +85,6 @@ export function getCommonColumnDefine(crudBinding, typeRef) {
form.setting = JSON.stringify(setting);
}
}
}
} as ColumnCompositionProps
};
}
@@ -1,27 +1,34 @@
// @ts-ignore
import * as api from "./api";
import { useI18n } from "vue-i18n";
import { ref } from "vue";
import { getCommonColumnDefine } from "/@/views/certd/access/common";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
export default function ({ expose }) {
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const { t } = useI18n();
const pageRequest = async (query) => {
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
return await api.GetList(query);
};
const editRequest = async ({ form, row }) => {
const editRequest = async (req: EditReq) => {
const { form, row } = req;
form.id = row.id;
return await api.UpdateObj(form);
const res = await api.UpdateObj(form);
return res;
};
const delRequest = async ({ row }) => {
const delRequest = async (req: DelReq) => {
const { row } = req;
return await api.DelObj(row.id);
};
const addRequest = async ({ form }) => {
return await api.AddObj(form);
const addRequest = async (req: AddReq) => {
const { form } = req;
const res = await api.AddObj(form);
return res;
};
const typeRef = ref();
const { crudBinding } = expose;
const commonColumnsDefine = getCommonColumnDefine(crudBinding, typeRef);
const commonColumnsDefine = getCommonColumnDefine(crudExpose, typeRef);
return {
crudOptions: {
request: {
@@ -8,31 +8,18 @@
</template>
<script lang="ts">
import { defineComponent, ref, onMounted } from "vue";
import { useCrud } from "@fast-crud/fast-crud";
import { defineComponent, onMounted } from "vue";
import { useFs } from "@fast-crud/fast-crud";
import createCrudOptions from "./crud";
import { useExpose } from "@fast-crud/fast-crud";
import { message } from "ant-design-vue";
export default defineComponent({
name: "CertdAccess",
setup() {
// crud组件的ref
const crudRef = ref();
// crud 配置的ref
const crudBinding = ref();
// 暴露的方法
const { expose } = useExpose({ crudRef, crudBinding });
// 你的crud配置
const { crudOptions } = createCrudOptions({ expose });
// 初始化crud配置
// eslint-disable-next-line @typescript-eslint/no-unused-vars,no-unused-vars
const { resetCrudOptions } = useCrud({ expose, crudOptions });
// 你可以调用此方法,重新初始化crud配置
// resetCrudOptions(options)
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: {} });
// 页面打开后获取列表数据
onMounted(() => {
expose.doRefresh();
crudExpose.doRefresh();
});
return {
@@ -1,6 +1,6 @@
<template>
<fs-page class="fs-pipeline-detail">
<pipeline-edit v-model:edit-mode="editMode" :pipeline-id="pipelineId" :options="pipelineOptions"></pipeline-edit>
<pipeline-edit v-model:edit-mode="editMode" :pipeline-id="pipelineId" :options="pipelineOptionsRef"></pipeline-edit>
</fs-page>
</template>
@@ -11,8 +11,7 @@ import * as pluginApi from "./api.plugin";
import * as historyApi from "./api.history";
import * as api from "./api";
import { useRoute } from "vue-router";
import { Pipeline, PipelineDetail, PipelineOptions, RunHistory } from "/@/views/certd/pipeline/pipeline/type";
import { PluginDefine } from "@certd/pipeline";
import { PipelineDetail, PipelineOptions, RunHistory, Pipeline } from "/@/views/certd/pipeline/pipeline/type";
export default defineComponent({
name: "PipelineDetail",
@@ -21,51 +20,47 @@ export default defineComponent({
const route = useRoute();
const pipelineId = ref(route.query.id);
const getPipelineDetail = async ({ pipelineId }) => {
const detail = await api.GetDetail(pipelineId);
return {
pipeline: {
id: detail.pipeline.id,
stages: [],
triggers: [],
...JSON.parse(detail.pipeline.content || "{}")
}
} as PipelineDetail;
const pipelineOptions: PipelineOptions = {
async getPipelineDetail({ pipelineId }) {
const detail = await api.GetDetail(pipelineId);
return {
pipeline: {
id: detail.pipeline.id,
stages: [],
triggers: [],
...JSON.parse(detail.pipeline.content || "{}")
}
} as PipelineDetail;
},
async getHistoryList({ pipelineId }) {
const list: RunHistory[] = await historyApi.GetList({ pipelineId });
return list;
},
async getHistoryDetail({ historyId }): Promise<RunHistory> {
const detail = await historyApi.GetDetail({ id: historyId });
return detail;
},
async getPlugins() {
const plugins = await pluginApi.GetList({});
return plugins as any[];
},
async doSave(pipelineConfig: any) {
await api.Save({
id: pipelineConfig.id,
content: JSON.stringify(pipelineConfig)
});
},
async doTrigger(options: { pipelineId: number }) {
const { pipelineId } = options;
await api.Trigger(pipelineId);
}
};
const getHistoryList = async ({ pipelineId }) => {
const list: RunHistory[] = await historyApi.GetList({ pipelineId });
return list;
};
const getHistoryDetail = async ({ historyId }): Promise<RunHistory> => {
const detail = await historyApi.GetDetail({ id: historyId });
return detail;
};
const getPlugins = async () => {
const plugins = await pluginApi.GetList({});
return plugins as PluginDefine[];
};
async function doSave(pipelineConfig: Pipeline) {
await api.Save({
id: pipelineConfig.id,
content: JSON.stringify(pipelineConfig)
});
}
async function doTrigger({ pipelineId }) {
await api.Trigger(pipelineId);
}
const pipelineOptions: Ref<PipelineOptions> = ref({
doTrigger,
doSave,
getPlugins,
getHistoryList,
getHistoryDetail,
getPipelineDetail
});
const pipelineOptionsRef: Ref<PipelineOptions> = ref(pipelineOptions);
const editMode = ref(false);
if (route.query.editMode !== "false") {
@@ -73,7 +68,7 @@ export default defineComponent({
}
return {
pipelineOptions,
pipelineOptionsRef,
pipelineId,
editMode
};
@@ -1,22 +0,0 @@
import { PluginDefine, Pipeline } from "@certd/pipeline/src";
export * from "@certd/pipeline/src";
export type PipelineDetail = {
pipeline: Pipeline;
};
export type RunHistory = {
id: any;
pipeline: Pipeline;
logs?: {
[id: string]: string[];
};
};
export type PipelineOptions = {
doTrigger(options: { pipelineId }): Promise<void>;
doSave(pipelineConfig: PipelineDefile): Promise<void>;
getPipelineDetail(query: { pipelineId }): Promise<PipelineDetail>;
getHistoryList(query: { pipelineId }): Promise<RunHistory[]>;
getHistoryDetail(query: { historyId }): Promise<RunHistory>;
getPlugins(): Promise<PluginDefine[]>;
};
@@ -0,0 +1,22 @@
import { Pipeline } from "@certd/pipeline";
export * from "@certd/pipeline";
export type PipelineDetail = {
pipeline: Pipeline;
};
export type RunHistory = {
id: any;
pipeline: Pipeline;
logs?: {
[id: string]: string[];
};
};
export type PipelineOptions = {
doTrigger(options: { pipelineId: number }): Promise<void>;
doSave(pipelineConfig: Pipeline): Promise<void>;
getPipelineDetail(query: { pipelineId: number }): Promise<PipelineDetail>;
getHistoryList(query: { pipelineId: number }): Promise<RunHistory[]>;
getHistoryDetail(query: { historyId: number }): Promise<RunHistory>;
getPlugins(): Promise<Pipeline[]>;
};
@@ -0,0 +1,7 @@
CREATE TABLE "pi_history" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "user_id" integer NOT NULL, "pipeline_id" integer NOT NULL, "pipeline" varchar(40960), "status" varchar(20), "end_time" datetime, "create_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "update_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP))
CREATE TABLE "pi_history_log" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "user_id" integer NOT NULL, "pipeline_id" integer NOT NULL, "history_id" integer NOT NULL, "node_id" varchar(100), "logs" varchar(40960), "create_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "update_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP))
CREATE TABLE "pi_pipeline" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "user_id" integer NOT NULL, "title" integer NOT NULL, "content" varchar(40960) NOT NULL, "keep_history_count" integer, "remark" varchar(100), "status" varchar(100), "disabled" boolean DEFAULT (0), "last_history_time" integer, "create_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "update_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP))
CREATE TABLE "pi_storage" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "user_id" integer NOT NULL, "scope" varchar NOT NULL, "namespace" varchar NOT NULL, "key" varchar(100), "value" varchar(40960), "create_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "update_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP))
+1
View File
@@ -24,6 +24,7 @@
"@alicloud/pop-core": "^1.7.12",
"@certd/pipeline": "workspace:^0.3.0",
"@certd/plugin-all": "workspace:^0.3.0",
"@certd/plugin-cert": "workspace:^0.3.0",
"@koa/cors": "^3.4.3",
"@midwayjs/bootstrap": "^3.9.1",
"@midwayjs/cache": "^3.9.0",
@@ -1,8 +1,8 @@
import { ALL, Body, Post, Query } from "@midwayjs/decorator";
import { BaseController } from "./base-controller";
import { ALL, Body, Post, Query } from '@midwayjs/decorator';
import { BaseController } from './base-controller';
export abstract class CrudController extends BaseController {
abstract getService();
export abstract class CrudController<T> extends BaseController {
abstract getService<T>();
@Post('/page')
async page(
@@ -62,4 +62,3 @@ export abstract class CrudController extends BaseController {
return this.ok(null);
}
}
@@ -33,11 +33,7 @@ export default {
logging: true,
// 配置实体模型 或者 entities: '/entity',
entities: [
'**/modules/*/entity/*.ts',
FlywayHistory,
UserEntity,
],
entities: ['**/modules/*/entity/*.ts', FlywayHistory, UserEntity],
},
},
},
@@ -6,20 +6,19 @@ import { Configuration, App } from '@midwayjs/decorator';
import * as koa from '@midwayjs/koa';
import * as orm from '@midwayjs/typeorm';
import * as cache from '@midwayjs/cache';
import * as cors from '@koa/cors';
import cors from '@koa/cors';
import { join } from 'path';
import * as flyway from 'midway-flyway-js';
import {ReportMiddleware} from "./middleware/report";
import {GlobalExceptionMiddleware} from "./middleware/global-exception";
import {PreviewMiddleware} from "./middleware/preview";
import {AuthorityMiddleware} from "./middleware/authority";
import { ReportMiddleware } from './middleware/report';
import { GlobalExceptionMiddleware } from './middleware/global-exception';
import { PreviewMiddleware } from './middleware/preview';
import { AuthorityMiddleware } from './middleware/authority';
import * as pipeline from './plugins/pipeline';
import * as cron from './plugins/cron';
@Configuration({
imports: [koa, orm, cache, flyway, validateComp,pipeline, cron],
imports: [koa, orm, cache, flyway, validateComp, pipeline, cron],
importConfigs: [
{
default: defaultConfig,
@@ -60,4 +60,3 @@ export class PermissionController extends CrudController<PermissionService> {
return this.ok(tree);
}
}
@@ -3,7 +3,7 @@ import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';
import { UserEntity } from '../entity/user';
import * as _ from 'lodash';
import * as md5 from 'md5';
import md5 from 'md5';
import { CommonException } from '../../../basic/exception/common-exception';
import { BaseService } from '../../../basic/base-service';
import { logger } from '../../../utils/logger';
@@ -36,7 +36,7 @@ export class UserService extends BaseService<UserEntity> {
const info = await this.repository.findOne({
where: {
id: this.ctx.user.id,
}
},
});
delete info.password;
return info;
@@ -48,9 +48,9 @@ export class UserService extends BaseService<UserEntity> {
*/
async add(param) {
const exists = await this.repository.findOne({
where:{
where: {
username: param.username,
}
},
});
if (!_.isEmpty(exists)) {
throw new CommonException('用户名已经存在');
@@ -74,7 +74,7 @@ export class UserService extends BaseService<UserEntity> {
throw new CommonException('id不能为空');
}
const userInfo = await this.repository.findOne({
where:{ id: param.id }
where: { id: param.id },
});
if (!userInfo) {
throw new CommonException('用户不存在');
@@ -92,7 +92,7 @@ export class UserService extends BaseService<UserEntity> {
async findOne(param) {
return this.repository.findOne({
where:param
where: param,
});
}
@@ -15,7 +15,7 @@ import { AccessService } from '../service/access-service';
*/
@Provide()
@Controller('/api/pi/access')
export class AccessController extends CrudController {
export class AccessController extends CrudController<AccessService> {
@Inject()
service: AccessService;
@@ -19,7 +19,7 @@ import { HistoryLogEntity } from '../entity/history-log';
*/
@Provide()
@Controller('/api/pi/history')
export class HistoryController extends CrudController {
export class HistoryController extends CrudController<HistoryService> {
@Inject()
service: HistoryService;
@Inject()
@@ -16,7 +16,7 @@ import { PipelineEntity } from '../entity/pipeline';
*/
@Provide()
@Controller('/api/pi/pipeline')
export class PipelineController extends CrudController {
export class PipelineController extends CrudController<PipelineService> {
@Inject()
service: PipelineService;
@@ -1,4 +1,4 @@
import { Provide, Scope, ScopeEnum } from "@midwayjs/decorator";
import { Provide, Scope, ScopeEnum } from '@midwayjs/decorator';
import { dnsProviderRegistry } from '@certd/plugin-cert';
@Provide()
@Scope(ScopeEnum.Singleton)
@@ -139,9 +139,9 @@ export class PipelineService extends BaseService<PipelineEntity> {
if (cron == null) {
return;
}
if(cron.startsWith("*")){
cron = "0"+ cron.substring(1,cron.length)
return
if (cron.startsWith('*')) {
cron = '0' + cron.substring(1, cron.length);
return;
}
this.cron.register({
name: this.buildCronKey(pipelineId, trigger.id),
@@ -168,7 +168,17 @@ export class PipelineService extends BaseService<PipelineEntity> {
const onChanged = async (history: RunHistory) => {
//保存执行历史
await this.saveHistory(history);
try {
await this.saveHistory(history);
} catch (e) {
const pipelineEntity = new PipelineEntity();
pipelineEntity.id = parseInt(history.pipeline.id);
pipelineEntity.status = 'error';
pipelineEntity.lastHistoryTime = history.pipeline.status.startTime;
await this.update(pipelineEntity);
logger.error('保存执行历史失败:', e);
throw e;
}
};
const userId = entity.userId;
@@ -228,6 +238,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
entity.id = parseInt(history.id);
entity.userId = history.pipeline.userId;
entity.pipeline = JSON.stringify(history.pipeline);
entity.pipelineId = parseInt(history.pipeline.id);
await this.historyService.save(entity);
const logEntity: HistoryLogEntity = new HistoryLogEntity();