mirror of
https://github.com/certd/certd.git
synced 2026-04-23 11:37:23 +08:00
chore: admin mode
This commit is contained in:
@@ -94,7 +94,7 @@ provide("fn:ai.open", openChat);
|
||||
<div class="hover:bg-accent ml-1 mr-2 cursor-pointer rounded-full">
|
||||
<vip-button class="flex-center header-btn" mode="nav" />
|
||||
</div>
|
||||
<div v-if="!settingStore.isComm" class="hover:bg-accent ml-1 mr-2 cursor-pointer rounded-full">
|
||||
<div v-if="!settingStore.isComm" class="hover:bg-accent ml-1 mr-2 cursor-pointer rounded-full hidden md:block">
|
||||
<fs-button shape="circle" type="text" icon="ion:logo-github" :text="null" @click="goGithub" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -230,7 +230,7 @@ export const sysResources = [
|
||||
title: "certd.sysResources.enterpriseSetting",
|
||||
name: "EnterpriseSetting",
|
||||
path: "/sys/enterprise/setting",
|
||||
redirect: "/sys/settings?tab=enterprise",
|
||||
redirect: "/sys/settings?tab=mode",
|
||||
meta: {
|
||||
isMenu: true,
|
||||
show: true,
|
||||
|
||||
@@ -111,7 +111,7 @@ function clearPreferencesAndLogout() {
|
||||
<template v-for="slot in leftSlots.filter(item => item.index < REFERENCE_VALUE)" :key="slot.name">
|
||||
<slot :name="slot.name">
|
||||
<template v-if="slot.name === 'refresh'">
|
||||
<VbenIconButton class="my-0 mr-1 rounded-md" @click="refresh">
|
||||
<VbenIconButton class="my-0 mr-1 rounded-md hidden md:block" @click="refresh">
|
||||
<RotateCw class="size-4" />
|
||||
</VbenIconButton>
|
||||
</template>
|
||||
@@ -131,7 +131,7 @@ function clearPreferencesAndLogout() {
|
||||
<template v-for="slot in rightSlots" :key="slot.name">
|
||||
<slot :name="slot.name">
|
||||
<template v-if="slot.name === 'global-search'">
|
||||
<GlobalSearch :enable-shortcut-key="globalSearchShortcutKey" :menus="accessStore.accessMenus" class="mr-1 sm:mr-4" />
|
||||
<GlobalSearch :enable-shortcut-key="globalSearchShortcutKey" :menus="accessStore.accessMenus" class="mr-1 sm:mr-4 hidden md:block" />
|
||||
</template>
|
||||
|
||||
<template v-else-if="slot.name === 'preferences'">
|
||||
@@ -144,7 +144,7 @@ function clearPreferencesAndLogout() {
|
||||
<LanguageToggle class="mr-1" />
|
||||
</template>
|
||||
<template v-else-if="slot.name === 'fullscreen'">
|
||||
<VbenFullScreen class="mr-1" />
|
||||
<VbenFullScreen class="mr-1 hidden md:block" />
|
||||
</template>
|
||||
</slot>
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import { dict } from "@fast-crud/fast-crud";
|
||||
|
||||
export const projectPermissionDict = dict({
|
||||
data: [
|
||||
{
|
||||
label: "read",
|
||||
value: "只读",
|
||||
},
|
||||
{
|
||||
label: "write",
|
||||
value: "读写",
|
||||
},
|
||||
{
|
||||
label: "admin",
|
||||
value: "管理员",
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
export const projectDict = dict({
|
||||
url: "/sys/enterprise/project/list",
|
||||
});
|
||||
@@ -14,6 +14,7 @@ import GroupSelector from "/@/views/certd/pipeline/group/group-selector.vue";
|
||||
import { statusUtil } from "/@/views/certd/pipeline/pipeline/utils/util.status";
|
||||
import { useCertViewer } from "/@/views/certd/pipeline/use";
|
||||
import { useI18n } from "/src/locales";
|
||||
import { projectDict } from "../dicts";
|
||||
|
||||
export default function ({ crudExpose, context: { selectedRowKeys, openCertApplyDialog } }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||
const router = useRouter();
|
||||
@@ -294,6 +295,11 @@ export default function ({ crudExpose, context: { selectedRowKeys, openCertApply
|
||||
width: 100,
|
||||
},
|
||||
},
|
||||
projectId: {
|
||||
title: t("certd.fields.projectName"),
|
||||
type: "number",
|
||||
dict: projectDict,
|
||||
},
|
||||
title: {
|
||||
title: t("certd.fields.pipelineName"),
|
||||
type: "link",
|
||||
|
||||
@@ -74,7 +74,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
},
|
||||
name: {
|
||||
title: t("certd.ent.projectName"),
|
||||
type: "text",
|
||||
type: "link",
|
||||
search: {
|
||||
show: true,
|
||||
},
|
||||
@@ -85,6 +85,13 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
},
|
||||
column: {
|
||||
width: 200,
|
||||
cellRender({ row }) {
|
||||
return (
|
||||
<router-link to={`/sys/enterprise/project/member`} query={{ projectId: row.id }}>
|
||||
{row.name}
|
||||
</router-link>
|
||||
);
|
||||
},
|
||||
},
|
||||
},
|
||||
disabled: {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="sys-settings-form sys-settings-mode">
|
||||
<a-form :model="formState" name="basic" :label-col="{ span: 8 }" :wrapper-col="{ span: 16 }" autocomplete="off" @finish="onFinish">
|
||||
<a-form-item :label="t('certd.adminMode')" :name="['public', 'adminMode']">
|
||||
<fs-dict-radio v-model:checked="formState.public.adminMode" :dict="adminModeDict" />
|
||||
<fs-dict-radio v-model:value="formState.public.adminMode" :dict="adminModeDict" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label=" " :colon="false" :wrapper-col="{ span: 8 }">
|
||||
@@ -20,22 +20,25 @@ import { merge } from "lodash-es";
|
||||
import { useSettingStore } from "/@/store/settings";
|
||||
import { notification } from "ant-design-vue";
|
||||
import { useI18n } from "/src/locales";
|
||||
import { dict } from "@fast-crud/fast-crud";
|
||||
const { t } = useI18n();
|
||||
|
||||
defineOptions({
|
||||
name: "SettingMode",
|
||||
});
|
||||
|
||||
const adminModeDict = [
|
||||
{
|
||||
label: t("certd.adminMode.enterpriseMode"),
|
||||
value: "enterprise",
|
||||
},
|
||||
{
|
||||
label: t("certd.adminMode.saasMode"),
|
||||
value: "saas",
|
||||
},
|
||||
];
|
||||
const adminModeDict = dict({
|
||||
data: [
|
||||
{
|
||||
label: t("certd.adminMode.enterpriseMode"),
|
||||
value: "enterprise",
|
||||
},
|
||||
{
|
||||
label: t("certd.adminMode.saasMode"),
|
||||
value: "saas",
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const formState = reactive<Partial<SysSettings>>({
|
||||
public: {},
|
||||
|
||||
@@ -11,7 +11,7 @@ CREATE TABLE "cd_project"
|
||||
|
||||
|
||||
CREATE INDEX "index_project_user_id" ON "cd_project" ("user_id");
|
||||
INSERT INTO cd_project (id, user_id, "name", "disabled") VALUES (1, 0, 'default', false);
|
||||
INSERT INTO cd_project (id, user_id, "name", "disabled") VALUES (1, 1, 'default', false);
|
||||
|
||||
|
||||
ALTER TABLE cd_cert_info ADD COLUMN project_id integer;
|
||||
@@ -33,21 +33,60 @@ ALTER TABLE cd_addon ADD COLUMN project_id integer;
|
||||
CREATE INDEX "index_addon_project_id" ON "cd_addon" ("project_id");
|
||||
|
||||
ALTER TABLE pi_pipeline ADD COLUMN project_id integer;
|
||||
CREATE INDEX "index_pipeline_project_id" ON "cd_pipeline" ("project_id");
|
||||
CREATE INDEX "index_pipeline_project_id" ON "pi_pipeline" ("project_id");
|
||||
|
||||
ALTER TABLE pi_pipeline_group ADD COLUMN project_id integer;
|
||||
CREATE INDEX "index_pipeline_group_project_id" ON "cd_pipeline_group" ("project_id");
|
||||
CREATE INDEX "index_pipeline_group_project_id" ON "pi_pipeline_group" ("project_id");
|
||||
|
||||
ALTER TABLE pi_storage ADD COLUMN project_id integer;
|
||||
CREATE INDEX "index_storage_project_id" ON "cd_storage" ("project_id");
|
||||
CREATE INDEX "index_storage_project_id" ON "pi_storage" ("project_id");
|
||||
|
||||
ALTER TABLE pi_notification ADD COLUMN project_id integer;
|
||||
CREATE INDEX "index_notification_project_id" ON "cd_notification" ("project_id");
|
||||
CREATE INDEX "index_notification_project_id" ON "pi_notification" ("project_id");
|
||||
|
||||
ALTER TABLE pi_history ADD COLUMN project_id integer;
|
||||
CREATE INDEX "index_history_project_id" ON "cd_history" ("project_id");
|
||||
CREATE INDEX "index_history_project_id" ON "pi_history" ("project_id");
|
||||
|
||||
ALTER TABLE pi_history_log ADD COLUMN project_id integer;
|
||||
CREATE INDEX "index_history_log_project_id" ON "cd_history_log" ("project_id");
|
||||
CREATE INDEX "index_history_log_project_id" ON "pi_history_log" ("project_id");
|
||||
|
||||
ALTER TABLE pi_template ADD COLUMN project_id integer;
|
||||
CREATE INDEX "index_template_project_id" ON "pi_template" ("project_id");
|
||||
|
||||
|
||||
|
||||
CREATE TABLE "cd_project_member"
|
||||
(
|
||||
"id" integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
"user_id" integer NOT NULL,
|
||||
"project_id" integer NOT NULL,
|
||||
"permission" varchar(128) NOT NULL DEFAULT ('read'),
|
||||
"create_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
"update_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP)
|
||||
);
|
||||
|
||||
|
||||
CREATE INDEX "index_project_member_user_id" ON "cd_project_member" ("user_id");
|
||||
CREATE INDEX "index_project_member_project_id" ON "cd_project_member" ("project_id");
|
||||
|
||||
|
||||
CREATE TABLE "cd_audit_log"
|
||||
(
|
||||
"id" integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
"user_id" integer NOT NULL,
|
||||
"username" varchar(128) NOT NULL,
|
||||
"project_id" integer NOT NULL,
|
||||
"project_name" varchar(512) NOT NULL,
|
||||
"type" varchar(128) NOT NULL,
|
||||
"action" varchar(128) NOT NULL DEFAULT ('read'),
|
||||
"content" text NOT NULL,
|
||||
"ip_address" varchar(128) NOT NULL,
|
||||
"create_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
"update_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP)
|
||||
);
|
||||
|
||||
|
||||
CREATE INDEX "index_audit_log_user_id" ON "cd_audit_log" ("user_id");
|
||||
CREATE INDEX "index_audit_log_project_id" ON "cd_audit_log" ("project_id");
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { BaseController, Constants } from '@certd/lib-server';
|
||||
import { ALL, Body, Controller, Inject, Post, Provide } from '@midwayjs/core';
|
||||
import { AuthService } from '../../../modules/sys/authority/service/auth-service.js';
|
||||
import { ProjectService } from '../../../modules/sys/enterprise/service/project-service.js';
|
||||
|
||||
/**
|
||||
*/
|
||||
@Provide()
|
||||
@Controller('/api/enterprise/project')
|
||||
export class UserProjectController extends BaseController {
|
||||
@Inject()
|
||||
service: ProjectService;
|
||||
@Inject()
|
||||
authService: AuthService;
|
||||
|
||||
getService(): ProjectService {
|
||||
return this.service;
|
||||
}
|
||||
|
||||
@Post('/list', { summary: Constants.per.authOnly })
|
||||
async list(@Body(ALL) body: any) {
|
||||
const userId= this.getUserId();
|
||||
const res = await this.service.getByUserId(userId);
|
||||
return this.ok(res);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,6 +19,9 @@ export class AuditLogEntity {
|
||||
@Column({ name: 'project_name', comment: '项目名称' })
|
||||
projectName: string;
|
||||
|
||||
@Column({ name: 'type', comment: '类型' })
|
||||
type: string;
|
||||
|
||||
@Column({ name: 'action', comment: '操作' })
|
||||
action: string;
|
||||
|
||||
|
||||
@@ -28,4 +28,7 @@ export class ProjectEntity {
|
||||
default: () => 'CURRENT_TIMESTAMP',
|
||||
})
|
||||
updateTime: Date;
|
||||
|
||||
// user permission read write admin
|
||||
permission:string
|
||||
}
|
||||
|
||||
@@ -38,4 +38,12 @@ export class ProjectMemberService extends BaseService<ProjectMemberEntity> {
|
||||
return await super.add(bean)
|
||||
}
|
||||
|
||||
async getByUserId(userId: number) {
|
||||
return await this.repository.find({
|
||||
where: {
|
||||
userId,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import {Inject, Provide, Scope, ScopeEnum} from '@midwayjs/core';
|
||||
import {BaseService, SysSettingsService} from '@certd/lib-server';
|
||||
import {InjectEntityModel} from '@midwayjs/typeorm';
|
||||
import {Repository} from 'typeorm';
|
||||
import {In, Repository} from 'typeorm';
|
||||
import { ProjectEntity } from '../entity/project.js';
|
||||
import { ProjectMemberService } from './project-member-service.js';
|
||||
|
||||
@Provide()
|
||||
@Scope(ScopeEnum.Request, { allowDowngrade: true })
|
||||
@@ -10,6 +11,8 @@ export class ProjectService extends BaseService<ProjectEntity> {
|
||||
@InjectEntityModel(ProjectEntity)
|
||||
repository: Repository<ProjectEntity>;
|
||||
|
||||
@Inject()
|
||||
projectMemberService: ProjectMemberService;
|
||||
|
||||
@Inject()
|
||||
sysSettingsService: SysSettingsService;
|
||||
@@ -56,4 +59,26 @@ export class ProjectService extends BaseService<ProjectEntity> {
|
||||
project.disabled = disabled;
|
||||
await this.repository.save(project);
|
||||
}
|
||||
|
||||
async getByUserId(userId: number) {
|
||||
|
||||
const memberList = await this.projectMemberService.getByUserId(userId);
|
||||
const projectIds = memberList.map(item => item.projectId);
|
||||
const projectList = await this.repository.find({
|
||||
where: {
|
||||
id: In(projectIds),
|
||||
},
|
||||
});
|
||||
|
||||
const memberPermissionMap = memberList.reduce((prev, cur) => {
|
||||
prev[cur.projectId] = cur.permission;
|
||||
return prev;
|
||||
}, {} as Record<number, string>);
|
||||
|
||||
projectList.forEach(item => {
|
||||
item.permission = memberPermissionMap[item.id] || 'read';
|
||||
})
|
||||
|
||||
return projectList
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user