mirror of
https://github.com/certd/certd.git
synced 2026-04-24 12:27:25 +08:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6163c3f08e | |||
| e17f381b1f |
@@ -19,30 +19,30 @@ export function parse(jsonString = "{}", defaultValue = {}) {
|
||||
/**
|
||||
* @description 接口请求返回
|
||||
* @param {Any} data 返回值
|
||||
* @param {String} msg 状态信息
|
||||
* @param {String} message 状态信息
|
||||
* @param {Number} code 状态码
|
||||
*/
|
||||
export function response(data = {}, msg = "", code = 0) {
|
||||
return [200, { code, msg, data }];
|
||||
export function response(data = {}, message = "", code = 0) {
|
||||
return [200, { code, message, data }];
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 接口请求返回 正确返回
|
||||
* @param {Any} data 返回值
|
||||
* @param {String} msg 状态信息
|
||||
* @param {String} message 状态信息
|
||||
*/
|
||||
export function responseSuccess(data = {}, msg = "成功") {
|
||||
return response(data, msg);
|
||||
export function responseSuccess(data = {}, message = "成功") {
|
||||
return response(data, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 接口请求返回 错误返回
|
||||
* @param {Any} data 返回值
|
||||
* @param {String} msg 状态信息
|
||||
* @param {String} message 状态信息
|
||||
* @param {Number} code 状态码
|
||||
*/
|
||||
export function responseError(data = {}, msg = "请求失败", code = 500) {
|
||||
return response(data, msg, code);
|
||||
export function responseError(data = {}, message = "请求失败", code = 500) {
|
||||
return response(data, message, code);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -218,6 +218,7 @@ export default {
|
||||
projectUserManager: "Project User Management",
|
||||
myProjectManager: "My Projects",
|
||||
myProjectDetail: "Project Detail",
|
||||
projectJoin: "Join Project",
|
||||
},
|
||||
certificateRepo: {
|
||||
title: "Certificate Repository",
|
||||
@@ -820,6 +821,20 @@ export default {
|
||||
admin: "Admin",
|
||||
},
|
||||
},
|
||||
project: {
|
||||
noProjectJoined: "You haven't joined any projects yet",
|
||||
applyToJoin: "Please apply to join a project to start using",
|
||||
systemProjects: "System Project List",
|
||||
createdAt: "Created At",
|
||||
applyJoin: "Apply to Join",
|
||||
noSystemProjects: "No system projects available",
|
||||
fetchFailed: "Failed to fetch project list",
|
||||
applySuccess: "Application successful, waiting for admin approval",
|
||||
applyFailed: "Application failed, please try again later",
|
||||
leave: "Leave Project",
|
||||
leaveSuccess: "Leave project successful",
|
||||
leaveFailed: "Leave project failed, please try again later",
|
||||
},
|
||||
addonSelector: {
|
||||
select: "Select",
|
||||
placeholder: "select please",
|
||||
|
||||
@@ -224,6 +224,7 @@ export default {
|
||||
enterpriseSetting: "企业设置",
|
||||
myProjectManager: "我的项目",
|
||||
myProjectDetail: "项目详情",
|
||||
projectJoin: "加入项目",
|
||||
},
|
||||
certificateRepo: {
|
||||
title: "证书仓库",
|
||||
@@ -836,4 +837,18 @@ export default {
|
||||
admin: "管理员",
|
||||
},
|
||||
},
|
||||
project: {
|
||||
noProjectJoined: "您还没有加入任何项目",
|
||||
applyToJoin: "请申请加入项目以开始使用",
|
||||
projectList: "项目列表",
|
||||
createdAt: "创建时间",
|
||||
applyJoin: "申请加入",
|
||||
noProjects: "暂无项目",
|
||||
fetchFailed: "获取项目列表失败",
|
||||
applySuccess: "申请成功,等待管理员审核",
|
||||
applyFailed: "申请失败,请稍后重试",
|
||||
leave: "退出项目",
|
||||
leaveSuccess: "退出项目成功",
|
||||
leaveFailed: "退出项目失败,请稍后重试",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -9,7 +9,8 @@ import { useSettingStore } from "/@/store/settings";
|
||||
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";
|
||||
function buildAccessedMenus(menus: any) {
|
||||
if (menus == null) {
|
||||
return;
|
||||
@@ -124,6 +125,20 @@ function setupAccessGuard(router: Router) {
|
||||
};
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
// 如果是项目模式
|
||||
const projectStore = useProjectStore();
|
||||
if (projectStore.isEnterprise) {
|
||||
//加载我的项目
|
||||
await projectStore.init();
|
||||
if (!projectStore.currentProject && to.path !== PROJECT_JOIN_PATH) {
|
||||
//没有项目
|
||||
return {
|
||||
path: PROJECT_JOIN_PATH,
|
||||
replace: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -42,6 +42,17 @@ export const certdResources = [
|
||||
permission: "sys:settings:edit",
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "certd.sysResources.projectJoin",
|
||||
name: "ProjectJoin",
|
||||
path: "/certd/project/join",
|
||||
component: "/certd/project/join.vue",
|
||||
meta: {
|
||||
isMenu: false,
|
||||
show: true,
|
||||
icon: "ion:apps",
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "certd.pipeline",
|
||||
name: "PipelineManager",
|
||||
|
||||
@@ -13,6 +13,7 @@ export type ProjectItem = {
|
||||
|
||||
export const useProjectStore = defineStore("app.project", () => {
|
||||
const myProjects = ref([]);
|
||||
const inited = ref(false);
|
||||
const lastProjectId = LocalStorage.get("currentProjectId");
|
||||
const currentProjectId = ref(lastProjectId); // 直接调用
|
||||
|
||||
@@ -66,13 +67,16 @@ export const useProjectStore = defineStore("app.project", () => {
|
||||
}
|
||||
|
||||
async function reload() {
|
||||
const projects = await api.MyProjectList();
|
||||
myProjects.value = projects;
|
||||
debugger;
|
||||
inited.value = false;
|
||||
await init();
|
||||
}
|
||||
|
||||
async function init() {
|
||||
if (!myProjects.value) {
|
||||
await reload();
|
||||
debugger;
|
||||
if (!inited.value) {
|
||||
await loadMyProjects();
|
||||
inited.value = true;
|
||||
}
|
||||
return myProjects.value;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,29 @@ const projectPermissionDict = dict({
|
||||
],
|
||||
});
|
||||
|
||||
const projectMemberStatusDict = dict({
|
||||
data: [
|
||||
{
|
||||
value: "pending",
|
||||
label: "待审核",
|
||||
color: "orange",
|
||||
icon: "material-symbols:hourglass-top",
|
||||
},
|
||||
{
|
||||
value: "approved",
|
||||
label: "已加入",
|
||||
color: "green",
|
||||
icon: "material-symbols:done-all",
|
||||
},
|
||||
{
|
||||
value: "rejected",
|
||||
label: "已拒绝",
|
||||
color: "red",
|
||||
icon: "material-symbols:close",
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const myProjectDict = dict({
|
||||
url: "/enterprise/project/list",
|
||||
getData: async () => {
|
||||
@@ -56,5 +79,6 @@ export function useDicts() {
|
||||
projectPermissionDict,
|
||||
myProjectDict,
|
||||
userDict,
|
||||
projectMemberStatusDict,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
<template>
|
||||
<fs-page class="page-project-join">
|
||||
<template #header>
|
||||
<div class="title">
|
||||
{{ t("certd.sysResources.projectJoin") }}
|
||||
<span v-if="projectStore.projects.length === 0" class="sub">{{ t("certd.project.noProjectJoined") }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="project-container">
|
||||
<h3 class="text-lg font-medium mb-4">{{ t("certd.project.projectList") }}</h3>
|
||||
<div class="flex flex-wrap gap-4">
|
||||
<div v-for="project in projects" :key="project.id" class="w-full md:w-1/4">
|
||||
<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>
|
||||
<div class="flex justify-between items-center">
|
||||
<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>
|
||||
<template #actions>
|
||||
<span v-if="!project.status || project.status === 'rejected'" class="flex-inline items-center" :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") }}
|
||||
</span>
|
||||
<span v-if="project.status === 'pending' || project.status === 'approved'" class="flex-inline items-center" :title="t('certd.project.leave')" @click="leaveProject(project.id)">
|
||||
<fs-icon class="fs-18 mr-2" icon="mdi:arrow-right-thin-circle-outline"></fs-icon>
|
||||
{{ t("certd.project.leave") }}
|
||||
</span>
|
||||
</template>
|
||||
</a-card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fs-page>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted } from "vue";
|
||||
import { useI18n } from "/src/locales";
|
||||
import { message, Modal } from "ant-design-vue";
|
||||
import { request } from "/src/api/service";
|
||||
import { useProjectStore } from "/@/store/project";
|
||||
import dayjs from "dayjs";
|
||||
import { useDicts } from "../dicts";
|
||||
import { modalProps } from "ant-design-vue/es/modal/Modal";
|
||||
|
||||
defineOptions({
|
||||
name: "ProjectJoin",
|
||||
});
|
||||
const { t } = useI18n();
|
||||
|
||||
const { projectMemberStatusDict, projectPermissionDict } = useDicts();
|
||||
|
||||
const projects = ref<any[]>([]);
|
||||
|
||||
const projectStore = useProjectStore();
|
||||
|
||||
const getSystemProjects = async () => {
|
||||
try {
|
||||
// 假设这里调用获取系统项目列表的API
|
||||
const response = await request({
|
||||
url: "/enterprise/project/all",
|
||||
method: "post",
|
||||
});
|
||||
projects.value = response || [];
|
||||
} catch (error) {
|
||||
message.error(t("certd.project.fetchFailed"));
|
||||
console.error("获取项目列表失败:", error);
|
||||
}
|
||||
};
|
||||
|
||||
const applyToJoin = async (projectId: number) => {
|
||||
// 假设这里调用申请加入项目的API
|
||||
Modal.confirm({
|
||||
title: t("certd.project.applyJoin"),
|
||||
content: t("certd.project.applyJoinConfirm"),
|
||||
onOk: async () => {
|
||||
await request({
|
||||
url: "/enterprise/project/applyJoin",
|
||||
method: "post",
|
||||
data: { projectId },
|
||||
});
|
||||
message.success(t("certd.project.applySuccess"));
|
||||
await getSystemProjects();
|
||||
// 申请成功后可以刷新页面或跳转到项目列表
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const formatDate = (dateString: string) => {
|
||||
if (!dateString) {
|
||||
return "";
|
||||
}
|
||||
return dayjs(dateString).format("YYYY-MM-DD HH:mm:ss");
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getSystemProjects();
|
||||
});
|
||||
|
||||
async function leaveProject(projectId: number) {
|
||||
// 假设这里调用退出项目的API
|
||||
Modal.confirm({
|
||||
title: t("certd.project.leave"),
|
||||
content: t("certd.project.leaveConfirm"),
|
||||
onOk: async () => {
|
||||
await request({
|
||||
url: "/enterprise/project/leave",
|
||||
method: "post",
|
||||
data: { projectId },
|
||||
});
|
||||
message.success(t("certd.project.leaveSuccess"));
|
||||
// 退出成功后可以刷新页面或跳转到项目列表
|
||||
await getSystemProjects();
|
||||
},
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.page-project-join {
|
||||
.project-container {
|
||||
padding: 24px;
|
||||
margin: 0 auto;
|
||||
.project-card {
|
||||
margin-bottom: 16px;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.project-card-content {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -82,6 +82,7 @@ CREATE TABLE "cd_project_member"
|
||||
"update_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP)
|
||||
);
|
||||
|
||||
ALTER TABLE cd_project_member ADD COLUMN status varchar(128);
|
||||
|
||||
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");
|
||||
|
||||
@@ -2,6 +2,7 @@ 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';
|
||||
import { ProjectMemberService } from '../../../modules/sys/enterprise/service/project-member-service.js';
|
||||
|
||||
/**
|
||||
*/
|
||||
@@ -10,6 +11,10 @@ import { ProjectService } from '../../../modules/sys/enterprise/service/project-
|
||||
export class UserProjectController extends BaseController {
|
||||
@Inject()
|
||||
service: ProjectService;
|
||||
|
||||
@Inject()
|
||||
projectMemberService: ProjectMemberService;
|
||||
|
||||
@Inject()
|
||||
authService: AuthService;
|
||||
|
||||
@@ -17,6 +22,11 @@ export class UserProjectController extends BaseController {
|
||||
return this.service;
|
||||
}
|
||||
|
||||
/**
|
||||
* 我的项目
|
||||
* @param body
|
||||
* @returns
|
||||
*/
|
||||
@Post('/list', { summary: Constants.per.authOnly })
|
||||
async list(@Body(ALL) body: any) {
|
||||
const userId= this.getUserId();
|
||||
@@ -24,4 +34,74 @@ export class UserProjectController extends BaseController {
|
||||
return this.ok(res);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param body 所有项目
|
||||
* @returns
|
||||
*/
|
||||
@Post('/all', { summary: Constants.per.authOnly })
|
||||
async all(@Body(ALL) body: any) {
|
||||
const userId= this.getUserId();
|
||||
const res = await this.service.getAllWithStatus(userId);
|
||||
return this.ok(res);
|
||||
}
|
||||
|
||||
@Post('/applyJoin', { summary: Constants.per.authOnly })
|
||||
async applyJoin(@Body(ALL) body: any) {
|
||||
const userId= this.getUserId();
|
||||
const res = await this.service.applyJoin({ userId, projectId: body.projectId });
|
||||
return this.ok(res);
|
||||
}
|
||||
|
||||
@Post('/updateMember', { summary: Constants.per.authOnly })
|
||||
async updateMember(@Body(ALL) body: any) {
|
||||
const {projectId} = await this.getProjectUserIdAdmin();
|
||||
const {status,permission,userId} = body;
|
||||
const member = await this.projectMemberService.findOne({
|
||||
where: {
|
||||
projectId,
|
||||
userId,
|
||||
},
|
||||
});
|
||||
if (!member) {
|
||||
throw new Error('成员不存在');
|
||||
}
|
||||
const res = await this.projectMemberService.update({
|
||||
id: member.id,
|
||||
status,
|
||||
permission,
|
||||
});
|
||||
return this.ok(res);
|
||||
}
|
||||
|
||||
@Post('/approveJoin', { summary: Constants.per.authOnly })
|
||||
async approveJoin(@Body(ALL) body: any) {
|
||||
const {projectId} = await this.getProjectUserIdAdmin();
|
||||
const {status,permission,userId} = body;
|
||||
const res = await this.service.approveJoin({ userId, projectId: projectId,status,permission });
|
||||
return this.ok(res);
|
||||
}
|
||||
|
||||
@Post('/delete', { summary: Constants.per.authOnly })
|
||||
async delete(@Body(ALL) body: any) {
|
||||
const {projectId} = await this.getProjectUserIdAdmin();
|
||||
await this.projectMemberService.deleteWhere({
|
||||
projectId,
|
||||
userId: this.getUserId(),
|
||||
});
|
||||
return this.ok();
|
||||
}
|
||||
|
||||
@Post('/leave', { summary: Constants.per.authOnly })
|
||||
async leave(@Body(ALL) body: any) {
|
||||
const {projectId} = body
|
||||
const userId = this.getUserId();
|
||||
await this.projectMemberService.deleteWhere({
|
||||
projectId,
|
||||
userId,
|
||||
});
|
||||
return this.ok();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@ export class ProjectMemberEntity {
|
||||
@Column({ name: 'permission', comment: '权限' })
|
||||
permission: string; // read / write / admin
|
||||
|
||||
@Column({ name: 'status', comment: '申请状态' })
|
||||
status: string; // pending / approved / rejected
|
||||
|
||||
@Column({
|
||||
name: 'create_time',
|
||||
comment: '创建时间',
|
||||
|
||||
@@ -34,4 +34,10 @@ export class ProjectEntity {
|
||||
|
||||
// user permission read write admin
|
||||
permission:string
|
||||
|
||||
}
|
||||
|
||||
export type ProjectMemberItem = {
|
||||
memberId: number;
|
||||
status: string;
|
||||
} & ProjectEntity
|
||||
|
||||
+3
-2
@@ -18,7 +18,7 @@ export class ProjectMemberService extends BaseService<ProjectMemberEntity> {
|
||||
return this.repository;
|
||||
}
|
||||
|
||||
async add(bean: ProjectMemberEntity) {
|
||||
async add(bean: Partial<ProjectMemberEntity>) {
|
||||
const {projectId, userId} = bean;
|
||||
if (!projectId) {
|
||||
throw new Error('项目ID不能为空');
|
||||
@@ -38,10 +38,11 @@ export class ProjectMemberService extends BaseService<ProjectMemberEntity> {
|
||||
return await super.add(bean)
|
||||
}
|
||||
|
||||
async getByUserId(userId: number) {
|
||||
async getByUserId(userId: number,status?:string) {
|
||||
return await this.repository.find({
|
||||
where: {
|
||||
userId,
|
||||
status,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core';
|
||||
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||
import { LRUCache } from 'lru-cache';
|
||||
import { Repository } from 'typeorm';
|
||||
import { ProjectEntity } from '../entity/project.js';
|
||||
import { ProjectEntity, ProjectMemberItem } from '../entity/project.js';
|
||||
import { ProjectMemberService } from './project-member-service.js';
|
||||
|
||||
const projectCache = new LRUCache<string, any>({
|
||||
@@ -65,7 +65,7 @@ export class ProjectService extends BaseService<ProjectEntity> {
|
||||
|
||||
async getUserProjects(userId: number) {
|
||||
|
||||
const memberList = await this.projectMemberService.getByUserId(userId);
|
||||
const memberList = await this.projectMemberService.getByUserId(userId,'approved');
|
||||
const projectIds = memberList.map(item => item.projectId);
|
||||
const projectList = await this.repository.createQueryBuilder('project')
|
||||
.where(' project.disabled = false')
|
||||
@@ -89,6 +89,39 @@ export class ProjectService extends BaseService<ProjectEntity> {
|
||||
return projectList
|
||||
}
|
||||
|
||||
async getAllWithStatus(userId: number) : Promise<ProjectMemberItem[]> {
|
||||
let projectList:any = await this.find({
|
||||
where: {
|
||||
disabled: false,
|
||||
userId: 0,
|
||||
},
|
||||
})
|
||||
const projectMemberItemList:ProjectMemberItem[] = projectList
|
||||
|
||||
const memberList = await this.projectMemberService.getByUserId(userId);
|
||||
|
||||
const memberMap = memberList.reduce((prev, cur) => {
|
||||
prev[cur.projectId] = cur as any;
|
||||
return prev;
|
||||
}, {} as Record<number, ProjectMemberItem>);
|
||||
|
||||
projectMemberItemList.forEach(item => {
|
||||
if (item.adminId === userId) {
|
||||
item.permission = 'admin';
|
||||
item.status = 'approved';
|
||||
item.memberId = userId
|
||||
} else {
|
||||
const memberItem :any = memberMap[item.id]
|
||||
if (memberItem) {
|
||||
item.permission = memberItem.permission;
|
||||
item.status = memberItem.status;
|
||||
item.memberId = memberItem.userId
|
||||
}
|
||||
}
|
||||
})
|
||||
return projectMemberItemList
|
||||
}
|
||||
|
||||
async checkAdminPermission({ userId, projectId }: { userId: number, projectId: number }) {
|
||||
return await this.checkPermission({
|
||||
userId,
|
||||
@@ -143,8 +176,8 @@ export class ProjectService extends BaseService<ProjectEntity> {
|
||||
throw new Error('项目已禁用');
|
||||
}
|
||||
const member = await this.projectMemberService.getMember(projectId, userId);
|
||||
if (!member) {
|
||||
throw new Error(`用户${userId}不是该项目${projectId}成员`);
|
||||
if (!member || member.status !== 'approved') {
|
||||
throw new Error(`用户${userId}还不是项目${projectId}的成员`);
|
||||
}
|
||||
savedPermission = member.permission;
|
||||
}
|
||||
@@ -169,4 +202,50 @@ export class ProjectService extends BaseService<ProjectEntity> {
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
async applyJoin({ userId, projectId }: { userId: number, projectId: number }) {
|
||||
const project = await this.info(projectId);
|
||||
if (!project) {
|
||||
throw new Error('项目不存在');
|
||||
}
|
||||
if (project.disabled) {
|
||||
throw new Error('项目已禁用');
|
||||
}
|
||||
if (project.adminId === userId) {
|
||||
throw new Error('申请用户已经是该项目的管理员');
|
||||
}
|
||||
const member = await this.projectMemberService.getMember(projectId, userId);
|
||||
if (member && member.status === 'approved') {
|
||||
throw new Error('用户已加入项目');
|
||||
}
|
||||
if (member){
|
||||
this.projectMemberService.update({
|
||||
id: member.id,
|
||||
status: 'pending',
|
||||
})
|
||||
}else{
|
||||
// 加入项目
|
||||
await this.projectMemberService.add({
|
||||
userId,
|
||||
projectId,
|
||||
permission: 'read',
|
||||
status: 'pending',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async approveJoin({ userId, projectId,status,permission }: { userId: number, projectId: number,status:string,permission:string }) {
|
||||
const member = await this.projectMemberService.getMember(projectId, userId);
|
||||
if (!member) {
|
||||
throw new Error('找不到用户的申请记录');
|
||||
}
|
||||
|
||||
await this.projectMemberService.update({
|
||||
id: member.id,
|
||||
status: status,
|
||||
permission,
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Generated
+110
-50
@@ -49,7 +49,7 @@ importers:
|
||||
packages/core/acme-client:
|
||||
dependencies:
|
||||
'@certd/basic':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.12
|
||||
version: link:../basic
|
||||
'@peculiar/x509':
|
||||
specifier: ^1.11.0
|
||||
@@ -213,11 +213,11 @@ importers:
|
||||
packages/core/pipeline:
|
||||
dependencies:
|
||||
'@certd/basic':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.12
|
||||
version: link:../basic
|
||||
'@certd/plus-core':
|
||||
specifier: ^1.38.9
|
||||
version: link:../../pro/plus-core
|
||||
specifier: ^1.38.12
|
||||
version: 1.38.12
|
||||
dayjs:
|
||||
specifier: ^1.11.7
|
||||
version: 1.11.13
|
||||
@@ -412,7 +412,7 @@ importers:
|
||||
packages/libs/lib-k8s:
|
||||
dependencies:
|
||||
'@certd/basic':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.12
|
||||
version: link:../../core/basic
|
||||
'@kubernetes/client-node':
|
||||
specifier: 0.21.0
|
||||
@@ -452,20 +452,20 @@ importers:
|
||||
packages/libs/lib-server:
|
||||
dependencies:
|
||||
'@certd/acme-client':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.12
|
||||
version: link:../../core/acme-client
|
||||
'@certd/basic':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.12
|
||||
version: link:../../core/basic
|
||||
'@certd/pipeline':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.12
|
||||
version: link:../../core/pipeline
|
||||
'@certd/plugin-lib':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.12
|
||||
version: link:../../plugins/plugin-lib
|
||||
'@certd/plus-core':
|
||||
specifier: ^1.38.9
|
||||
version: link:../../pro/plus-core
|
||||
specifier: ^1.38.12
|
||||
version: 1.38.12
|
||||
'@midwayjs/cache':
|
||||
specifier: 3.14.0
|
||||
version: 3.14.0
|
||||
@@ -610,16 +610,16 @@ importers:
|
||||
packages/plugins/plugin-cert:
|
||||
dependencies:
|
||||
'@certd/acme-client':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.12
|
||||
version: link:../../core/acme-client
|
||||
'@certd/basic':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.12
|
||||
version: link:../../core/basic
|
||||
'@certd/pipeline':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.12
|
||||
version: link:../../core/pipeline
|
||||
'@certd/plugin-lib':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.12
|
||||
version: link:../plugin-lib
|
||||
psl:
|
||||
specifier: ^1.9.0
|
||||
@@ -683,17 +683,17 @@ importers:
|
||||
specifier: ^3.964.0
|
||||
version: 3.964.0(aws-crt@1.26.2)
|
||||
'@certd/acme-client':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.12
|
||||
version: link:../../core/acme-client
|
||||
'@certd/basic':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.12
|
||||
version: link:../../core/basic
|
||||
'@certd/pipeline':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.12
|
||||
version: link:../../core/pipeline
|
||||
'@certd/plus-core':
|
||||
specifier: ^1.38.9
|
||||
version: link:../../pro/plus-core
|
||||
specifier: ^1.38.12
|
||||
version: 1.38.12
|
||||
'@kubernetes/client-node':
|
||||
specifier: 0.21.0
|
||||
version: 0.21.0
|
||||
@@ -783,16 +783,16 @@ importers:
|
||||
packages/pro/commercial-core:
|
||||
dependencies:
|
||||
'@certd/basic':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.8
|
||||
version: link:../../core/basic
|
||||
'@certd/lib-server':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.8
|
||||
version: link:../../libs/lib-server
|
||||
'@certd/pipeline':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.8
|
||||
version: link:../../core/pipeline
|
||||
'@certd/plus-core':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.8
|
||||
version: link:../plus-core
|
||||
'@midwayjs/core':
|
||||
specifier: 3.20.11
|
||||
@@ -865,16 +865,16 @@ importers:
|
||||
packages/pro/plugin-plus:
|
||||
dependencies:
|
||||
'@certd/basic':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.8
|
||||
version: link:../../core/basic
|
||||
'@certd/pipeline':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.8
|
||||
version: link:../../core/pipeline
|
||||
'@certd/plugin-lib':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.8
|
||||
version: link:../../plugins/plugin-lib
|
||||
'@certd/plus-core':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.8
|
||||
version: link:../plus-core
|
||||
crypto-js:
|
||||
specifier: ^4.2.0
|
||||
@@ -950,7 +950,7 @@ importers:
|
||||
packages/pro/plus-core:
|
||||
dependencies:
|
||||
'@certd/basic':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.8
|
||||
version: link:../../core/basic
|
||||
dayjs:
|
||||
specifier: ^1.11.7
|
||||
@@ -1246,10 +1246,10 @@ importers:
|
||||
version: 0.1.3(zod@3.24.4)
|
||||
devDependencies:
|
||||
'@certd/lib-iframe':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.12
|
||||
version: link:../../libs/lib-iframe
|
||||
'@certd/pipeline':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.12
|
||||
version: link:../../core/pipeline
|
||||
'@rollup/plugin-commonjs':
|
||||
specifier: ^25.0.7
|
||||
@@ -1444,47 +1444,47 @@ importers:
|
||||
specifier: ^3.990.0
|
||||
version: 3.990.0(aws-crt@1.26.2)
|
||||
'@certd/acme-client':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.12
|
||||
version: link:../../core/acme-client
|
||||
'@certd/basic':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.12
|
||||
version: link:../../core/basic
|
||||
'@certd/commercial-core':
|
||||
specifier: ^1.38.9
|
||||
version: link:../../pro/commercial-core
|
||||
specifier: ^1.38.12
|
||||
version: 1.38.12(better-sqlite3@11.10.0)(mysql2@3.14.1)(pg@8.16.0)(reflect-metadata@0.2.2)(ts-node@10.9.2(@types/node@18.19.100)(typescript@5.9.3))
|
||||
'@certd/cv4pve-api-javascript':
|
||||
specifier: ^8.4.2
|
||||
version: 8.4.2
|
||||
'@certd/jdcloud':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.12
|
||||
version: link:../../libs/lib-jdcloud
|
||||
'@certd/lib-huawei':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.12
|
||||
version: link:../../libs/lib-huawei
|
||||
'@certd/lib-k8s':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.12
|
||||
version: link:../../libs/lib-k8s
|
||||
'@certd/lib-server':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.12
|
||||
version: link:../../libs/lib-server
|
||||
'@certd/midway-flyway-js':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.12
|
||||
version: link:../../libs/midway-flyway-js
|
||||
'@certd/pipeline':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.12
|
||||
version: link:../../core/pipeline
|
||||
'@certd/plugin-cert':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.12
|
||||
version: link:../../plugins/plugin-cert
|
||||
'@certd/plugin-lib':
|
||||
specifier: ^1.38.9
|
||||
specifier: ^1.38.12
|
||||
version: link:../../plugins/plugin-lib
|
||||
'@certd/plugin-plus':
|
||||
specifier: ^1.38.9
|
||||
version: link:../../pro/plugin-plus
|
||||
specifier: ^1.38.12
|
||||
version: 1.38.12
|
||||
'@certd/plus-core':
|
||||
specifier: ^1.38.9
|
||||
version: link:../../pro/plus-core
|
||||
specifier: ^1.38.12
|
||||
version: 1.38.12
|
||||
'@google-cloud/publicca':
|
||||
specifier: ^1.3.0
|
||||
version: 1.3.0(encoding@0.1.13)
|
||||
@@ -2820,9 +2820,18 @@ packages:
|
||||
'@better-scroll/zoom@2.5.1':
|
||||
resolution: {integrity: sha512-aGvFY5ooeZWS4RcxQLD+pGLpQHQxpPy0sMZV3yadcd2QK53PK9gS4Dp+BYfRv8lZ4/P2LoNEhr6Wq1DN6+uPlA==}
|
||||
|
||||
'@certd/commercial-core@1.38.12':
|
||||
resolution: {integrity: sha512-kP4vM3F+D6TME9NYSM7Q1YqTx6Ig1dseWQUFVf7GnfG9E3A2odaRwmeYwy5QomChF0vbPHPkJqOtfYv9WItikQ==}
|
||||
|
||||
'@certd/cv4pve-api-javascript@8.4.2':
|
||||
resolution: {integrity: sha512-udGce7ewrVl4DmZvX+17PjsnqsdDIHEDatr8QP0AVrY2p+8JkaSPW4mXCKiLGf82C9K2+GXgT+qNIqgW7tfF9Q==}
|
||||
|
||||
'@certd/plugin-plus@1.38.12':
|
||||
resolution: {integrity: sha512-I0aQAzIRaDFSwM2vb/ycLqaNjVcb/fWUOgmX/BpHEnN446oNk5+pl8d4KFE+OMzEDQcwOwZhdXhjrOsskqY3PA==}
|
||||
|
||||
'@certd/plus-core@1.38.12':
|
||||
resolution: {integrity: sha512-2BKhInDmMrH4l/WRKcSq7E6PA4ANcE1PVMIVoWlhSnnW+sghYUioymRaSoGTxJYfSvGHlLrqZXAassQHAzm98g==}
|
||||
|
||||
'@certd/vue-js-cron-core@6.0.3':
|
||||
resolution: {integrity: sha512-kqzoAMhYz9j6FGNWEODRYtt4NpUEUwjpkU89z5WVg2tCtOcI5VhwyUGOd8AxiBCRfd6PtXvzuqw85PaOps9wrQ==}
|
||||
|
||||
@@ -15028,12 +15037,63 @@ snapshots:
|
||||
dependencies:
|
||||
'@better-scroll/core': 2.5.1
|
||||
|
||||
'@certd/commercial-core@1.38.12(better-sqlite3@11.10.0)(mysql2@3.14.1)(pg@8.16.0)(reflect-metadata@0.2.2)(ts-node@10.9.2(@types/node@18.19.100)(typescript@5.9.3))':
|
||||
dependencies:
|
||||
'@certd/basic': link:packages/core/basic
|
||||
'@certd/lib-server': link:packages/libs/lib-server
|
||||
'@certd/pipeline': link:packages/core/pipeline
|
||||
'@certd/plus-core': 1.38.12
|
||||
'@midwayjs/core': 3.20.11
|
||||
'@midwayjs/koa': 3.20.13
|
||||
'@midwayjs/logger': 3.4.2
|
||||
'@midwayjs/typeorm': 3.20.11
|
||||
dayjs: 1.11.13
|
||||
typeorm: 0.3.24(better-sqlite3@11.10.0)(mysql2@3.14.1)(pg@8.16.0)(reflect-metadata@0.2.2)(ts-node@10.9.2(@types/node@18.19.100)(typescript@5.9.3))
|
||||
transitivePeerDependencies:
|
||||
- '@google-cloud/spanner'
|
||||
- '@sap/hana-client'
|
||||
- babel-plugin-macros
|
||||
- better-sqlite3
|
||||
- hdb-pool
|
||||
- ioredis
|
||||
- mongodb
|
||||
- mssql
|
||||
- mysql2
|
||||
- oracledb
|
||||
- pg
|
||||
- pg-native
|
||||
- pg-query-stream
|
||||
- redis
|
||||
- reflect-metadata
|
||||
- sql.js
|
||||
- sqlite3
|
||||
- supports-color
|
||||
- ts-node
|
||||
- typeorm-aurora-data-api-driver
|
||||
|
||||
'@certd/cv4pve-api-javascript@8.4.2':
|
||||
dependencies:
|
||||
debug: 4.4.3(supports-color@8.1.1)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@certd/plugin-plus@1.38.12':
|
||||
dependencies:
|
||||
'@certd/basic': link:packages/core/basic
|
||||
'@certd/pipeline': link:packages/core/pipeline
|
||||
'@certd/plugin-lib': link:packages/plugins/plugin-lib
|
||||
'@certd/plus-core': 1.38.12
|
||||
crypto-js: 4.2.0
|
||||
dayjs: 1.11.13
|
||||
form-data: 4.0.2
|
||||
jsrsasign: 11.1.0
|
||||
querystring: 0.2.1
|
||||
|
||||
'@certd/plus-core@1.38.12':
|
||||
dependencies:
|
||||
'@certd/basic': link:packages/core/basic
|
||||
dayjs: 1.11.13
|
||||
|
||||
'@certd/vue-js-cron-core@6.0.3':
|
||||
dependencies:
|
||||
mustache: 4.2.0
|
||||
@@ -20599,13 +20659,13 @@ snapshots:
|
||||
resolve: 1.22.10
|
||||
semver: 6.3.1
|
||||
|
||||
eslint-plugin-prettier@3.4.1(eslint-config-prettier@8.10.0(eslint@7.32.0))(eslint@7.32.0)(prettier@2.8.8):
|
||||
eslint-plugin-prettier@3.4.1(eslint-config-prettier@8.10.0(eslint@8.57.0))(eslint@7.32.0)(prettier@2.8.8):
|
||||
dependencies:
|
||||
eslint: 7.32.0
|
||||
prettier: 2.8.8
|
||||
prettier-linter-helpers: 1.0.0
|
||||
optionalDependencies:
|
||||
eslint-config-prettier: 8.10.0(eslint@7.32.0)
|
||||
eslint-config-prettier: 8.10.0(eslint@8.57.0)
|
||||
|
||||
eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.10.0(eslint@8.57.0))(eslint@8.57.0)(prettier@2.8.8):
|
||||
dependencies:
|
||||
@@ -23009,7 +23069,7 @@ snapshots:
|
||||
eslint: 7.32.0
|
||||
eslint-config-prettier: 8.10.0(eslint@7.32.0)
|
||||
eslint-plugin-node: 11.1.0(eslint@7.32.0)
|
||||
eslint-plugin-prettier: 3.4.1(eslint-config-prettier@8.10.0(eslint@7.32.0))(eslint@7.32.0)(prettier@2.8.8)
|
||||
eslint-plugin-prettier: 3.4.1(eslint-config-prettier@8.10.0(eslint@8.57.0))(eslint@7.32.0)(prettier@2.8.8)
|
||||
execa: 5.1.1
|
||||
inquirer: 7.3.3
|
||||
json5: 2.2.3
|
||||
|
||||
Reference in New Issue
Block a user