chore: project finished

This commit is contained in:
xiaojunnuo
2026-03-03 23:31:42 +08:00
parent a853fc2026
commit 6c546b5290
17 changed files with 87 additions and 29 deletions
+1 -1
View File
@@ -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: "查看详情",
},
};
+5 -3
View File
@@ -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 }">