mirror of
https://github.com/certd/certd.git
synced 2026-04-24 04:17:25 +08:00
chore: project blank
This commit is contained in:
@@ -820,6 +820,17 @@ 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",
|
||||
},
|
||||
addonSelector: {
|
||||
select: "Select",
|
||||
placeholder: "select please",
|
||||
|
||||
@@ -836,4 +836,15 @@ export default {
|
||||
admin: "管理员",
|
||||
},
|
||||
},
|
||||
project: {
|
||||
noProjectJoined: "您还没有加入任何项目",
|
||||
applyToJoin: "请申请加入项目以开始使用",
|
||||
systemProjects: "系统项目列表",
|
||||
createdAt: "创建时间",
|
||||
applyJoin: "申请加入",
|
||||
noSystemProjects: "暂无系统项目",
|
||||
fetchFailed: "获取项目列表失败",
|
||||
applySuccess: "申请成功,等待管理员审核",
|
||||
applyFailed: "申请失败,请稍后重试",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -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_BLANK_PATH = "/certd/project/blank";
|
||||
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_BLANK_PATH) {
|
||||
//没有项目
|
||||
return {
|
||||
path: PROJECT_BLANK_PATH,
|
||||
replace: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -42,6 +42,17 @@ export const certdResources = [
|
||||
permission: "sys:settings:edit",
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "certd.sysResources.myProjectBlank",
|
||||
name: "MyProjectBlank",
|
||||
path: "/certd/project/blank",
|
||||
component: "/certd/project/blank.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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
<template>
|
||||
<fs-page class="page-cert">
|
||||
<template #header>
|
||||
<div class="title">
|
||||
{{ t("certd.sysResources.myProjectManager") }}
|
||||
</div>
|
||||
</template>
|
||||
<div class="blank-container">
|
||||
<div class="project-list-container">
|
||||
<h3 class="text-lg font-medium mb-4">{{ t("certd.project.systemProjects") }}</h3>
|
||||
<a-card v-for="project in projects" :key="project.id" :bordered="false" class="project-card">
|
||||
<div class="project-card-content">
|
||||
<div class="project-info">
|
||||
<h4 class="text-md font-medium">{{ project.name }}</h4>
|
||||
<p class="text-gray-500 text-sm">{{ t("certd.project.createdAt") }}: {{ formatDate(project.createTime) }}</p>
|
||||
</div>
|
||||
<a-button type="primary" @click="applyToJoin(project.id)">{{ t("certd.project.applyJoin") }}</a-button>
|
||||
</div>
|
||||
</a-card>
|
||||
<div v-if="projects.length === 0" class="no-projects"></div>
|
||||
</div>
|
||||
</div>
|
||||
</fs-page>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted } from "vue";
|
||||
import { useI18n } from "/src/locales";
|
||||
import { message } from "ant-design-vue";
|
||||
import { request } from "/src/api/service";
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const projects = ref<any[]>([]);
|
||||
|
||||
const getSystemProjects = async () => {
|
||||
try {
|
||||
// 假设这里调用获取系统项目列表的API
|
||||
const response = await request({
|
||||
url: "/enterprise/project/list",
|
||||
method: "post",
|
||||
data: { type: "system" }, // 假设type=system表示系统项目
|
||||
});
|
||||
projects.value = response || [];
|
||||
} catch (error) {
|
||||
message.error(t("certd.project.fetchFailed"));
|
||||
console.error("获取项目列表失败:", error);
|
||||
}
|
||||
};
|
||||
|
||||
const applyToJoin = async (projectId: number) => {
|
||||
try {
|
||||
// 假设这里调用申请加入项目的API
|
||||
await request({
|
||||
url: "/enterprise/project/apply",
|
||||
method: "post",
|
||||
data: { projectId },
|
||||
});
|
||||
message.success(t("certd.project.applySuccess"));
|
||||
// 申请成功后可以刷新页面或跳转到项目列表
|
||||
} catch (error) {
|
||||
message.error(t("certd.project.applyFailed"));
|
||||
console.error("申请加入项目失败:", error);
|
||||
}
|
||||
};
|
||||
|
||||
const formatDate = (dateString: string) => {
|
||||
if (!dateString) return "";
|
||||
const date = new Date(dateString);
|
||||
return date.toLocaleString();
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getSystemProjects();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.blank-container {
|
||||
padding: 24px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
margin-bottom: 48px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.empty-description {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.project-list-container {
|
||||
margin-top: 32px;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.project-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.no-projects {
|
||||
margin-top: 24px;
|
||||
padding: 48px 0;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user