mirror of
https://github.com/certd/certd.git
synced 2026-04-03 14:10:54 +08:00
chore: project finished
This commit is contained in:
@@ -69,10 +69,8 @@ export abstract class BaseController {
|
||||
if (!projectIdStr){
|
||||
projectIdStr = this.ctx.request.query["projectId"] as string;
|
||||
}
|
||||
if (!projectIdStr){
|
||||
return null
|
||||
}
|
||||
if (!projectIdStr) {
|
||||
//这里必须抛异常,否则可能会有权限问题
|
||||
throw new Error("projectId 不能为空")
|
||||
}
|
||||
const userId = this.getUserId()
|
||||
|
||||
@@ -24,6 +24,9 @@ export class AccessEntity {
|
||||
@Column({ name: 'project_id', comment: '项目id' })
|
||||
projectId: number;
|
||||
|
||||
@Column({ comment: '权限等级', length: 100 })
|
||||
level: string; // user common system
|
||||
|
||||
@Column({
|
||||
name: 'create_time',
|
||||
comment: '创建时间',
|
||||
|
||||
@@ -155,7 +155,7 @@ function createRequestFunction(service: any) {
|
||||
}
|
||||
Object.assign(configDefault, config);
|
||||
|
||||
if (projectStore.isEnterprise && !config.url.startsWith("/sys") && !config.url.startsWith("http")) {
|
||||
if (!configDefault.params.projectId && projectStore.isEnterprise && !config.url.startsWith("/sys") && !config.url.startsWith("http")) {
|
||||
configDefault.params.projectId = projectStore.currentProject?.id;
|
||||
}
|
||||
return service(configDefault);
|
||||
|
||||
@@ -838,6 +838,7 @@ export default {
|
||||
leaveFailed: "Leave project failed, please try again later",
|
||||
applyJoinConfirm: "Are you sure you want to apply to join this project?",
|
||||
leaveConfirm: "Are you sure you want to leave this project?",
|
||||
viewDetail: "View Detail",
|
||||
},
|
||||
addonSelector: {
|
||||
select: "Select",
|
||||
|
||||
@@ -854,5 +854,6 @@ export default {
|
||||
leaveFailed: "退出项目失败,请稍后重试",
|
||||
applyJoinConfirm: "确认加入项目?",
|
||||
leaveConfirm: "确认退出项目?",
|
||||
viewDetail: "查看详情",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -10,7 +10,9 @@ import { usePermissionStore } from "/@/plugin/permission/store.permission";
|
||||
import util from "/@/plugin/permission/util.permission";
|
||||
import { useUserStore } from "/@/store/user";
|
||||
import { useProjectStore } from "../store/project";
|
||||
export const PROJECT_JOIN_PATH = "/certd/project/join";
|
||||
export const PROJECT_PATH_PREFIX = "/certd/project";
|
||||
export const SYS_PATH_PREFIX = "/sys";
|
||||
|
||||
function buildAccessedMenus(menus: any) {
|
||||
if (menus == null) {
|
||||
return;
|
||||
@@ -131,10 +133,10 @@ function setupAccessGuard(router: Router) {
|
||||
if (projectStore.isEnterprise) {
|
||||
//加载我的项目
|
||||
await projectStore.init();
|
||||
if (!projectStore.currentProject && to.path !== PROJECT_JOIN_PATH) {
|
||||
if (!projectStore.currentProject && !to.path.startsWith(PROJECT_PATH_PREFIX) && !to.path.startsWith(SYS_PATH_PREFIX)) {
|
||||
//没有项目
|
||||
return {
|
||||
path: PROJECT_JOIN_PATH,
|
||||
path: `${PROJECT_PATH_PREFIX}/join`,
|
||||
replace: true,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -109,7 +109,10 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
search: {
|
||||
show: true,
|
||||
},
|
||||
form: {},
|
||||
form: {
|
||||
show: true,
|
||||
rules: [{ required: true, message: "请选择用户" }],
|
||||
},
|
||||
editForm: {
|
||||
show: false,
|
||||
},
|
||||
@@ -126,6 +129,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
},
|
||||
form: {
|
||||
show: true,
|
||||
rules: [{ required: true, message: "请选择权限" }],
|
||||
},
|
||||
column: {
|
||||
width: 200,
|
||||
@@ -140,6 +144,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
},
|
||||
form: {
|
||||
show: true,
|
||||
rules: [{ required: true, message: "请选择状态" }],
|
||||
},
|
||||
column: {
|
||||
width: 200,
|
||||
@@ -156,6 +161,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
id: row.id,
|
||||
permission: row.permission,
|
||||
onSubmit: async (form: any) => {
|
||||
form.userId = row.userId;
|
||||
await api.ApproveJoin(form);
|
||||
crudExpose.doRefresh();
|
||||
},
|
||||
|
||||
@@ -97,6 +97,10 @@ const handleBatchDelete = () => {
|
||||
|
||||
// 页面打开后获取列表数据
|
||||
onMounted(async () => {
|
||||
if (!projectId) {
|
||||
message.error("您还未选择项目");
|
||||
return;
|
||||
}
|
||||
await loadProjectDetail();
|
||||
crudExpose.doRefresh();
|
||||
});
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
{{ t("certd.sysResources.projectJoin") }}
|
||||
<span v-if="projectStore.projects.length === 0" class="sub">{{ t("certd.project.noProjectJoined") }}</span>
|
||||
</div>
|
||||
|
||||
<div class="more">
|
||||
<a-button v-if="userStore.isAdmin" @click="goProjectManager">{{ t("certd.project.projectManager") }}</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<div class="project-container">
|
||||
<h3 class="text-lg font-medium mb-4">{{ t("certd.project.projectList") }}</h3>
|
||||
@@ -13,20 +17,20 @@
|
||||
<a-card :bordered="true" class="project-card">
|
||||
<div class="project-card-content">
|
||||
<div class="project-info">
|
||||
<h3 class="text-md font-bold title">{{ project.name }}</h3>
|
||||
<p class="text-gray-500 text-sm">{{ formatDate(project.createTime) }}</p>
|
||||
<div class="text-md font-bold title">{{ project.name }}</div>
|
||||
<div class="flex items-center justify-start">管理员: <fs-values-format :model-value="project.adminId" :dict="userDict" color="green"></fs-values-format></div>
|
||||
<p class="text-gray-500 text-sm">创建时间:{{ formatDate(project.createTime) }}</p>
|
||||
</div>
|
||||
<div class="flex-col items-center">
|
||||
<div>管理员: <fs-values-format :model-value="project.adminId" :dict="userDict"></fs-values-format></div>
|
||||
<div class="flex items-center mt-2">
|
||||
<div v-if="project.status">
|
||||
<fs-values-format :model-value="project.status" :dict="projectMemberStatusDict"></fs-values-format>
|
||||
</div>
|
||||
<div v-if="project.permission"><fs-values-format :model-value="project.permission" :dict="projectPermissionDict"></fs-values-format></div>
|
||||
</div>
|
||||
<div class="flex-col items-start">
|
||||
<div v-if="project.status" class="mt-1 flex items-center justify-start">状态:<fs-values-format :model-value="project.status" :dict="projectMemberStatusDict"></fs-values-format></div>
|
||||
<div v-if="project.permission" class="mt-1 flex items-center justify-start">权限:<fs-values-format :model-value="project.permission" :dict="projectPermissionDict"></fs-values-format></div>
|
||||
</div>
|
||||
</div>
|
||||
<template #actions>
|
||||
<span v-if="project.status === 'approved'" class="flex-inline items-center text-blue-500" :title="t('certd.project.viewDetail')" @click="goProjectDetail(project.id)">
|
||||
<fs-icon class="fs-18 mr-2" icon="mdi:eye-outline"></fs-icon>
|
||||
{{ t("certd.project.viewDetail") }}
|
||||
</span>
|
||||
<span v-if="!project.status || project.status === 'rejected'" class="flex-inline items-center text-blue-500" :title="t('certd.project.applyJoin')" @click="applyToJoin(project.id)">
|
||||
<fs-icon class="fs-18 mr-2" icon="mdi:checkbox-marked-circle-outline"></fs-icon>
|
||||
{{ t("certd.project.applyJoin") }}
|
||||
@@ -51,6 +55,8 @@ import { request } from "/src/api/service";
|
||||
import { useProjectStore } from "/@/store/project";
|
||||
import dayjs from "dayjs";
|
||||
import { useDicts } from "../dicts";
|
||||
import { useRouter } from "vue-router";
|
||||
import { useUserStore } from "/@/store/user";
|
||||
|
||||
defineOptions({
|
||||
name: "ProjectJoin",
|
||||
@@ -62,6 +68,17 @@ const { projectMemberStatusDict, projectPermissionDict, userDict } = useDicts();
|
||||
const projects = ref<any[]>([]);
|
||||
|
||||
const projectStore = useProjectStore();
|
||||
const userStore = useUserStore();
|
||||
function goProjectManager() {
|
||||
// 假设这里调用跳转到项目管理页的API
|
||||
router.push(`/sys/enterprise/project`);
|
||||
}
|
||||
|
||||
const router = useRouter();
|
||||
function goProjectDetail(projectId: number) {
|
||||
// 假设这里调用跳转到项目详情页的API
|
||||
router.push(`/certd/project/detail?projectId=${projectId}`);
|
||||
}
|
||||
|
||||
const getSystemProjects = async () => {
|
||||
try {
|
||||
@@ -147,7 +164,6 @@ async function leaveProject(projectId: number) {
|
||||
.title {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,7 +108,9 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
search: {
|
||||
show: true,
|
||||
},
|
||||
form: {},
|
||||
form: {
|
||||
rules: [{ required: true, message: "请选择用户" }],
|
||||
},
|
||||
editForm: {
|
||||
show: false,
|
||||
},
|
||||
@@ -131,6 +133,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
},
|
||||
form: {
|
||||
show: true,
|
||||
rules: [{ required: true, message: "请选择权限" }],
|
||||
},
|
||||
column: {
|
||||
width: 200,
|
||||
@@ -145,6 +148,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||
},
|
||||
form: {
|
||||
show: true,
|
||||
rules: [{ required: true, message: "请选择状态" }],
|
||||
},
|
||||
column: {
|
||||
width: 200,
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
<h2 class="intro-title text-xl font-bold">{{ title || "管理模式介绍" }}</h2>
|
||||
<div class="mt-8 image-block">
|
||||
<div class="flex gap-8">
|
||||
<div class="intro-desc flex-1">SaaS模式:每个用户管理自己的流水线和授权资源,独立使用。</div>
|
||||
<div class="intro-desc flex-1">企业模式:企业内部员工使用,通过项目合作管理流水线证书和授权资源。</div>
|
||||
<div class="intro-desc flex-1">SaaS模式:每个用户管理自己的流水线和授权资源,每个用户独立使用。</div>
|
||||
<div class="intro-desc flex-1">企业模式:通过项目合作管理流水线证书和授权资源,所有用户视为企业内部员工。</div>
|
||||
</div>
|
||||
<div class="image-intro">
|
||||
<img :src="src" alt="" />
|
||||
|
||||
@@ -6,8 +6,10 @@
|
||||
<fs-dict-radio v-model:value="formState.public.adminMode" :disabled="!settingsStore.isPlus" :dict="adminModeDict" />
|
||||
<vip-button class="ml-5" mode="button"></vip-button>
|
||||
</div>
|
||||
<div class="helper">建议在开始使用时选择合适的模式,之后就不要随意切换了。</div>
|
||||
<div><a @click="adminModeIntroOpen = true"> 管理模式介绍</a></div>
|
||||
<div class="helper">SaaS模式:每个用户管理自己的流水线和授权资源,独立使用。</div>
|
||||
<div class="helper">企业模式:通过项目合作管理流水线证书和授权资源,所有用户视为企业内部员工。</div>
|
||||
<div class="helper text-red-500">建议在开始使用时固定一个合适的模式,之后就不要随意切换了。</div>
|
||||
<div><a @click="adminModeIntroOpen = true"> 更多管理模式介绍</a></div>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label=" " :colon="false" :wrapper-col="{ span: 8 }">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { AccessService } from "@certd/lib-server";
|
||||
import { ALL, Body, Controller, Inject, Post, Provide, Query } from "@midwayjs/core";
|
||||
import { AccessService, Constants } from "@certd/lib-server";
|
||||
import { AccessController } from "../../user/pipeline/access-controller.js";
|
||||
|
||||
/**
|
||||
@@ -15,6 +15,12 @@ export class SysAccessController extends AccessController {
|
||||
return this.service2;
|
||||
}
|
||||
|
||||
async getProjectUserId(permission:string){
|
||||
return {
|
||||
projectId:null,userId:0
|
||||
}
|
||||
}
|
||||
|
||||
getUserId() {
|
||||
// checkComm();
|
||||
return 0;
|
||||
@@ -54,7 +60,7 @@ export class SysAccessController extends AccessController {
|
||||
return await super.define(type);
|
||||
}
|
||||
|
||||
@Post('/getSecretPlain', { summary: Constants.per.authOnly })
|
||||
@Post('/getSecretPlain', { summary: 'sys:settings:view' })
|
||||
async getSecretPlain(@Body(ALL) body: { id: number; key: string }) {
|
||||
const value = await this.service.getById(body.id, 0);
|
||||
return this.ok(value[body.key]);
|
||||
@@ -69,4 +75,9 @@ export class SysAccessController extends AccessController {
|
||||
async simpleInfo(@Query('id') id: number) {
|
||||
return await super.simpleInfo(id);
|
||||
}
|
||||
|
||||
@Post('/getDictByIds', { summary: 'sys:settings:view' })
|
||||
async getDictByIds(@Body('ids') ids: number[]) {
|
||||
return await super.getDictByIds(ids);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,11 @@ export class SysAddonController extends AddonController {
|
||||
return this.service2;
|
||||
}
|
||||
|
||||
async getProjectUserId(permission:string){
|
||||
return {
|
||||
projectId:null,userId:0
|
||||
}
|
||||
}
|
||||
getUserId() {
|
||||
// checkComm();
|
||||
return 0;
|
||||
|
||||
@@ -60,10 +60,12 @@ export class SysProjectMemberController extends CrudController<ProjectMemberEnti
|
||||
userId: this.getUserId(),
|
||||
projectId: projectId,
|
||||
});
|
||||
return super.update({
|
||||
const res =await this.service.update({
|
||||
id: bean.id,
|
||||
permission: bean.permission,
|
||||
status: bean.status,
|
||||
});
|
||||
return this.ok(res);
|
||||
}
|
||||
|
||||
@Post("/info", { summary: "sys:settings:view" })
|
||||
|
||||
@@ -64,10 +64,13 @@ export class ProjectMemberController extends CrudController<ProjectMemberEntity>
|
||||
userId: this.getUserId(),
|
||||
projectId: projectId,
|
||||
});
|
||||
return super.update({
|
||||
const res = await this.service.update({
|
||||
id: bean.id,
|
||||
permission: bean.permission,
|
||||
status: bean.status,
|
||||
});
|
||||
|
||||
return this.ok(res);
|
||||
}
|
||||
|
||||
@Post("/info", { summary: Constants.per.authOnly })
|
||||
|
||||
@@ -111,7 +111,7 @@ export class AccessController extends CrudController<AccessService> {
|
||||
@Post('/simpleInfo', { summary: Constants.per.authOnly })
|
||||
async simpleInfo(@Query('id') id: number) {
|
||||
// await this.authService.checkUserIdButAllowAdmin(this.ctx, this.service, id);
|
||||
await this.checkOwner(this.getService(), id, "read",true);
|
||||
// await this.checkOwner(this.getService(), id, "read",true);
|
||||
const res = await this.service.getSimpleInfo(id);
|
||||
return this.ok(res);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user