chore: project

This commit is contained in:
xiaojunnuo
2026-02-21 23:20:26 +08:00
parent 06c69d23be
commit faf08f6513
21 changed files with 125 additions and 36 deletions

View File

@@ -146,7 +146,7 @@ function createRequestFunction(service: any) {
};
const projectStore = useProjectStore();
if (projectStore.isEnterprise && !config.url.startsWith("/sys")) {
if (projectStore.isEnterprise && !config.url.startsWith("/sys") && !config.url.startsWith("http")) {
configDefault.headers["project-id"] = projectStore.currentProjectId;
}

View File

@@ -84,7 +84,11 @@ const projectStore = useProjectStore();
<template>
<BasicLayout @clear-preferences-and-logout="handleLogout">
<template #header-left-0> </template>
<template #header-left-0>
<div v-if="projectStore.isEnterprise" class="ml-1 mr-2">
<project-selector class="flex-center header-btn" />
</div>
</template>
<template #user-dropdown>
<UserDropdown :avatar="avatar" :menus="menus" :text="userStore.userInfo?.nickName || userStore.userInfo?.username" description="" tag-text="" @logout="handleLogout" />
</template>
@@ -92,9 +96,6 @@ const projectStore = useProjectStore();
<LockScreen :avatar @to-login="handleLogout" />
</template>
<template #header-right-0>
<div v-if="projectStore.isEnterprise" class="ml-1 mr-2">
<project-selector class="flex-center header-btn" />
</div>
<div class="hover:bg-accent ml-1 mr-2 cursor-pointer rounded-full hidden md:block">
<tutorial-button class="flex-center header-btn" mode="nav" />
</div>

View File

@@ -77,16 +77,46 @@ export const useProjectStore = defineStore("app.project", () => {
return myProjects.value;
}
const isRead = computed(() => {
if (!isEnterprise.value) {
return true;
}
return currentProject.value;
});
const isWrite = computed(() => {
if (!isEnterprise.value) {
return true;
}
return currentProject.value?.permission === "write" || currentProject.value?.permission === "admin";
});
const isAdmin = computed(() => {
if (!isEnterprise.value) {
return true;
}
return currentProject.value?.permission === "admin";
});
function $reset() {
myProjects.value = [];
currentProjectId.value = "";
}
return {
projects,
myProjects,
currentProject,
currentProjectId,
isEnterprise,
isRead,
isWrite,
isAdmin,
getSearchForm,
loadMyProjects,
changeCurrentProject,
reload,
init,
$reset,
};
});

View File

@@ -6,6 +6,7 @@
@import "./antdv4.less";
@import "./certd.less";
@import "./dark.less";
@import "./vben.less";
html,
body {

View File

@@ -1,7 +1,13 @@
.dark{
.fs-page-header{
.dark {
.fs-page-header {
.title {
color: #d5d5d5 !important;
}
color: #d5d5d5 !important;
}
}
.vben-normal-menu__item.is-active{
background-color: #3b3b3b !important;
}
}

View File

@@ -0,0 +1,3 @@
.vben-normal-menu__item.is-active{
background-color: #ebf1f6 !important;
}

View File

@@ -210,11 +210,9 @@ const headerSlots = computed(() => {
</template>
<!-- 侧边额外区域 -->
<template #side-extra>
1111
<LayoutExtraMenu :accordion="preferences.navigation.accordion" :collapse="preferences.sidebar.extraCollapse" :menus="wrapperMenus(extraMenus)" :rounded="isMenuRounded" :theme="sidebarTheme" />
</template>
<template #side-extra-title>
234234234
<VbenLogo v-if="preferences.logo.enable" :text="preferences.app.name" :theme="theme" />
</template>

View File

@@ -4,7 +4,7 @@ import { getCommonColumnDefine } from "/@/views/certd/access/common";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { useI18n } from "/src/locales";
import { useProjectStore } from "/@/store/project";
import { myProjectDict } from "../../../dicts";
import { useDicts } from "../../../dicts";
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const { t } = useI18n();
@@ -41,7 +41,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
selectedRowKey.value = changed;
ctx.emit("update:modelValue", changed[0]);
};
const { myProjectDict } = useDicts();
const typeRef = ref("aliyun");
context.typeRef = typeRef;
const commonColumnsDefine = getCommonColumnDefine(crudExpose, typeRef, api);

View File

@@ -1,7 +1,7 @@
// @ts-ignore
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { ref } from "vue";
import { myProjectDict } from "../dicts";
import { useDicts } from "../dicts";
import { useProjectStore } from "/@/store/project";
import { getCommonColumnDefine } from "/@/views/certd/access/common";
import { useI18n } from "/src/locales";
@@ -32,6 +32,8 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
const typeRef = ref();
const commonColumnsDefine = getCommonColumnDefine(crudExpose, typeRef, api);
const projectStore = useProjectStore();
const { myProjectDict } = useDicts();
return {
crudOptions: {
request: {

View File

@@ -1,6 +1,7 @@
import { dict } from "@fast-crud/fast-crud";
import { GetMyProjectList } from "./project/api";
export const projectPermissionDict = dict({
const projectPermissionDict = dict({
data: [
{
label: "read",
@@ -17,13 +18,24 @@ export const projectPermissionDict = dict({
],
});
export const myProjectDict = dict({
const myProjectDict = dict({
url: "/enterprise/project/list",
getData: async () => {
const res = await GetMyProjectList();
return res;
},
value: "id",
label: "name",
immediate: false,
onReady: ({ dict }) => {
for (const item of dict.data) {
item.label = item.name;
item.value = item.id;
}
},
});
export const userDict = dict({
const userDict = dict({
url: "/sys/authority/user/getSimpleUsers",
value: "id",
onReady: ({ dict }) => {
@@ -32,3 +44,11 @@ export const userDict = dict({
}
},
});
export function useDicts() {
return {
projectPermissionDict,
myProjectDict,
userDict,
};
}

View File

@@ -6,7 +6,7 @@ import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, Edi
import { useUserStore } from "/@/store/user";
import { useSettingStore } from "/@/store/settings";
import { statusUtil } from "/@/views/certd/pipeline/pipeline/utils/util.status";
import { myProjectDict } from "../dicts";
import { useDicts } from "../dicts";
import { useProjectStore } from "/@/store/project";
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
@@ -33,7 +33,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
const settingStore = useSettingStore();
const selectedRowKeys: Ref<any[]> = ref([]);
context.selectedRowKeys = selectedRowKeys;
const { myProjectDict } = useDicts();
const projectStore = useProjectStore();
return {

View File

@@ -11,7 +11,7 @@ import CertView from "/@/views/certd/pipeline/cert-view.vue";
import { useCertUpload } from "/@/views/certd/pipeline/cert-upload/use";
import { useSettingStore } from "/@/store/settings";
import { useProjectStore } from "/@/store/project";
import { myProjectDict } from "../../dicts";
import { useDicts } from "../../dicts";
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const { t } = useI18n();
@@ -36,7 +36,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
return res;
};
const router = useRouter();
const { myProjectDict } = useDicts();
const settingStore = useSettingStore();
const projectStore = useProjectStore();
const model = useModal();

View File

@@ -14,7 +14,7 @@ import { ref } from "vue";
import GroupSelector from "../../basic/group/group-selector.vue";
import { createGroupDictRef } from "../../basic/group/api";
import { useProjectStore } from "/@/store/project";
import { myProjectDict } from "../../dicts";
import { useDicts } from "../../dicts";
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const { t } = useI18n();
const api = siteInfoApi;
@@ -39,7 +39,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
const res = await api.AddObj(form);
return res;
};
const { myProjectDict } = useDicts();
const settingsStore = useSettingStore();
const checkStatusDict = dict({

View File

@@ -6,7 +6,7 @@ import { Modal } from "ant-design-vue";
import { mitter } from "/@/utils/util.mitt";
import { useI18n } from "/src/locales";
import { useProjectStore } from "/@/store/project";
import { myProjectDict } from "../dicts";
import { useDicts } from "../dicts";
export function notificationProvide(api: any) {
provide("notificationApi", api);
@@ -29,7 +29,7 @@ export function getCommonColumnDefine(crudExpose: any, typeRef: any, api: any) {
};
const projectStore = useProjectStore();
const { myProjectDict } = useDicts();
provide("getCurrentPluginDefine", () => {
return currentDefine;
});

View File

@@ -4,7 +4,8 @@ import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, Edi
import { OPEN_API_DOC, openkeyApi } from "./api";
import { useModal } from "/@/use/use-modal";
import { useProjectStore } from "/@/store/project";
import { myProjectDict } from "../../dicts";
import { computed } from "vue";
import { useDicts } from "../../dicts";
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const { t } = useI18n();
@@ -28,6 +29,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
const res = await api.AddObj(form);
return res;
};
const { myProjectDict } = useDicts();
const projectStore = useProjectStore();
const model = useModal();
return {
@@ -176,6 +178,14 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
form: {
show: false,
},
column: {
show: computed(() => {
return projectStore.isEnterprise;
}),
width: 120,
align: "center",
sorter: true,
},
},
createTime: {
title: t("certd.fields.createTime"),

View File

@@ -14,7 +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 { myProjectDict } from "../dicts";
import { useDicts } from "../dicts";
import { useProjectStore } from "/@/store/project";
export default function ({ crudExpose, context: { selectedRowKeys, openCertApplyDialog } }: CreateCrudOptionsProps): CreateCrudOptionsRet {
@@ -69,7 +69,7 @@ export default function ({ crudExpose, context: { selectedRowKeys, openCertApply
const settingStore = useSettingStore();
const projectStore = useProjectStore();
const { myProjectDict } = useDicts();
const DEFAULT_WILL_EXPIRE_DAYS = settingStore.sysPublic.defaultWillExpireDays || settingStore.sysPublic.defaultCertRenewDays || 15;
function onDialogOpen(opt: any) {
@@ -656,6 +656,14 @@ export default function ({ crudExpose, context: { selectedRowKeys, openCertApply
form: {
show: false,
},
column: {
show: computed(() => {
return settingStore.isEnterprise;
}),
width: 120,
align: "center",
sorter: true,
},
},
updateTime: {
title: t("certd.fields.updateTime"),

View File

@@ -2,7 +2,7 @@ import { useI18n } from "/src/locales";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { pipelineGroupApi } from "./api";
import { useProjectStore } from "/@/store/project";
import { myProjectDict } from "../../dicts";
import { useDicts } from "../../dicts";
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const { t } = useI18n();
@@ -28,7 +28,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
};
const projectStore = useProjectStore();
const { myProjectDict } = useDicts();
return {
crudOptions: {
settings: {

View File

@@ -7,7 +7,7 @@ import * as pipelineApi from "../api";
import { useTemplate } from "/@/views/certd/pipeline/template/use";
import { useI18n } from "/@/locales";
import { useProjectStore } from "/@/store/project";
import { myProjectDict } from "../../dicts";
import { useDicts } from "../../dicts";
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const api = templateApi;
const { t } = useI18n();
@@ -36,7 +36,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
const router = useRouter();
const model = useModal();
const { myProjectDict } = useDicts();
const { openCreateFromTemplateDialog } = useTemplate();
return {

View File

@@ -10,6 +10,13 @@ export async function GetList(query: any) {
});
}
export async function GetMyProjectList() {
return await request({
url: apiPrefix + "/list",
method: "post",
});
}
export async function GetPage(query: any) {
return await request({
url: apiPrefix + "/page",

View File

@@ -21,6 +21,7 @@ import { useSettingStore } from "/@/store/settings";
import { notification } from "ant-design-vue";
import { useI18n } from "/src/locales";
import { dict } from "@fast-crud/fast-crud";
import { useProjectStore } from "/@/store/project";
const { t } = useI18n();
defineOptions({
@@ -53,12 +54,14 @@ async function loadSysSettings() {
const saveLoading = ref(false);
loadSysSettings();
const settingsStore = useSettingStore();
const projectStore = useProjectStore();
const onFinish = async (form: any) => {
try {
saveLoading.value = true;
await api.SysSettingsSave(form);
await settingsStore.loadSysSettings();
await projectStore.reload();
notification.success({
message: t("certd.saveSuccess"),
});

View File

@@ -144,14 +144,14 @@ export class ProjectService extends BaseService<ProjectEntity> {
}
const member = await this.projectMemberService.getMember(projectId, userId);
if (!member) {
throw new Error('项目成员不存在');
throw new Error(`用户${userId}不是该项目${projectId}成员`);
}
savedPermission = member.permission;
}
}
projectCache.set(cacheKey, savedPermission,{ttl: 3 * 60 * 1000});
if (!savedPermission) {
throw new Error('权限不足');
throw new Error(`权限不足,需要${permission}权限`);
}
if (permission === 'read') {
@@ -161,11 +161,11 @@ export class ProjectService extends BaseService<ProjectEntity> {
if (savedPermission === 'admin' || savedPermission === 'write') {
return true
} else {
throw new Error('权限不足');
throw new Error(`权限不足,需要${permission}权限`);
}
}
if (savedPermission !== permission) {
throw new Error('权限不足');
throw new Error(`权限不足,需要${permission}权限`);
}
return true
}