chore: project permission

This commit is contained in:
xiaojunnuo
2026-02-26 00:12:59 +08:00
parent faf08f6513
commit 3a8b5de8f7
14 changed files with 119 additions and 30 deletions
@@ -1,12 +1,14 @@
import { usePermission } from "/@/plugin/permission";
import { merge as LodashMerge } from "lodash-es";
import { useProjectStore } from "/@/store/project";
export type UseCrudPermissionExtraProps = {
hasActionPermission: (action: string) => boolean;
};
export type UseCrudPermissionExtra = (props: UseCrudPermissionExtraProps) => any;
export type UseCrudPermissionCompProps = {
prefix: string;
isProjectPermission?: boolean;
prefix?: string;
extra?: UseCrudPermissionExtra;
[key: string]: any;
};
@@ -20,14 +22,31 @@ export type UseCrudPermissionProps = {
export function useCrudPermission({ permission }: UseCrudPermissionProps) {
const { hasPermissions } = usePermission();
const prefix = permission instanceof Object ? permission.prefix : permission;
//根据权限显示按钮
function hasActionPermission(action: string) {
let hasActionPermission = (action: string) => {
if (!prefix) {
return true;
}
return hasPermissions(prefix + ":" + action);
};
let per: UseCrudPermissionCompProps = permission as any;
if (per == null) {
per = { prefix: "" };
}
if (typeof per === "string") {
per = {
prefix: per || "",
};
}
let prefix = per.prefix || "";
const isProjectPermission = per.isProjectPermission || false;
if (isProjectPermission) {
const projectStore = useProjectStore();
prefix = "";
hasActionPermission = function (value: string) {
return projectStore.hasPermission(value as string);
};
}
function buildCrudPermission(): any {
@@ -36,25 +55,44 @@ export function useCrudPermission({ permission }: UseCrudPermissionProps) {
}
let extra = {};
if (permission instanceof Object) {
extra = permission.extra;
if (permission.extra && permission.extra instanceof Function) {
extra = permission.extra({ hasActionPermission });
if (per instanceof Object) {
extra = per.extra;
if (per.extra && per.extra instanceof Function) {
extra = per.extra({ hasActionPermission });
}
}
let viewPermission = "view";
if (isProjectPermission) {
viewPermission = "read";
}
let addPermission = "add";
if (isProjectPermission) {
addPermission = "write";
}
let editPermission = "edit";
if (isProjectPermission) {
editPermission = "write";
}
let removePermission = "remove";
if (isProjectPermission) {
removePermission = "write";
}
return LodashMerge(
{
actionbar: {
buttons: {
add: { show: hasActionPermission("add") },
add: { show: hasActionPermission(addPermission) },
},
},
rowHandle: {
buttons: {
edit: { show: hasActionPermission("edit") },
remove: { show: hasActionPermission("remove") },
view: { show: hasActionPermission("view") },
edit: { show: hasActionPermission(editPermission) },
remove: { show: hasActionPermission(removePermission) },
view: { show: hasActionPermission(viewPermission) },
},
},
},
@@ -98,6 +98,20 @@ export const useProjectStore = defineStore("app.project", () => {
return currentProject.value?.permission === "admin";
});
function hasPermission(value: string) {
if (!isEnterprise.value) {
return true;
}
if (value === "read") {
return isRead.value;
} else if (value === "write") {
return isWrite.value;
} else if (value === "admin") {
return isAdmin.value;
}
return false;
}
function $reset() {
myProjects.value = [];
currentProjectId.value = "";
@@ -118,5 +132,6 @@ export const useProjectStore = defineStore("app.project", () => {
reload,
init,
$reset,
hasPermission,
};
});
@@ -22,7 +22,7 @@ export default defineComponent({
setup() {
const { t } = useI18n();
const api = createAccessApi("user");
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: { api } });
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: { api, permission: { isProjectPermission: true } } });
// 页面打开后获取列表数据
onMounted(() => {
@@ -12,6 +12,7 @@ import { useI18n } from "/src/locales";
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const router = useRouter();
const { t } = useI18n();
const { hasActionPermission } = context;
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
return await api.GetList(query);
};
@@ -96,6 +97,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
icon: "ion:add-circle-outline",
},
import: {
show: hasActionPermission("write"),
title: "从域名提供商导入域名",
type: "primary",
text: "从域名提供商导入",
@@ -111,6 +113,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
},
},
syncExpirationDate: {
show: hasActionPermission("write"),
title: "同步域名过期时间",
type: "primary",
icon: "ion:refresh-outline",
@@ -10,7 +10,7 @@
</template>
<fs-crud ref="crudRef" v-bind="crudBinding">
<template #pagination-left>
<a-tooltip :title="t('certd.batch_delete')">
<a-tooltip v-if="hasActionPermission('write')" :title="t('certd.batch_delete')">
<fs-button icon="DeleteOutlined" @click="handleBatchDelete"></fs-button>
</a-tooltip>
</template>
@@ -25,13 +25,22 @@ import createCrudOptions from "./crud";
import { message, Modal } from "ant-design-vue";
import { DeleteBatch } from "./api";
import { useI18n } from "/src/locales";
import { useCrudPermission } from "/@/plugin/permission";
const { t } = useI18n();
defineOptions({
name: "DomainManager",
});
const { crudBinding, crudRef, crudExpose, context } = useFs({ createCrudOptions });
const context: any = {
permission: {
isProjectPermission: true,
},
};
const { hasActionPermission } = useCrudPermission({ permission: context.permission });
context.hasActionPermission = hasActionPermission;
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context });
const selectedRowKeys = context.selectedRowKeys;
const handleBatchDelete = () => {
@@ -15,6 +15,7 @@ import GroupSelector from "../../basic/group/group-selector.vue";
import { createGroupDictRef } from "../../basic/group/api";
import { useProjectStore } from "/@/store/project";
import { useDicts } from "../../dicts";
import { useCrudPermission } from "/@/plugin/permission";
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const { t } = useI18n();
const api = siteInfoApi;
@@ -109,6 +110,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
}
const projectStore = useProjectStore();
const { hasActionPermission } = useCrudPermission({ permission: context.permission });
return {
id: "siteMonitorCrud",
crudOptions: {
@@ -231,7 +233,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
},
//导入按钮
import: {
show: true,
show: hasActionPermission("write"),
text: t("monitor.bulkImport"),
type: "primary",
async click() {
@@ -34,7 +34,12 @@ const { t } = useI18n();
defineOptions({
name: "SiteCertMonitor",
});
const { crudBinding, crudRef, crudExpose, context } = useFs({ createCrudOptions });
const context: any = {
permission: {
isProjectPermission: true,
},
};
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context });
const handleBatchDelete = context.handleBatchDelete;
@@ -17,7 +17,7 @@ import { useI18n } from "/src/locales";
import { useDicts } from "../dicts";
import { useProjectStore } from "/@/store/project";
export default function ({ crudExpose, context: { selectedRowKeys, openCertApplyDialog } }: CreateCrudOptionsProps): CreateCrudOptionsRet {
export default function ({ crudExpose, context: { selectedRowKeys, openCertApplyDialog, hasActionPermission } }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const router = useRouter();
const lastResRef = ref();
@@ -124,9 +124,11 @@ export default function ({ crudExpose, context: { selectedRowKeys, openCertApply
click() {
openCertApplyDialog({ key: "CertApply" });
},
show: hasActionPermission("add"),
},
uploadCert: {
order: 2,
show: hasActionPermission("uploadCert"),
text: t("certd.commercialCertHosting"),
type: "primary",
tooltip: {
@@ -207,6 +209,7 @@ export default function ({ crudExpose, context: { selectedRowKeys, openCertApply
},
},
copy: {
show: hasActionPermission("write"),
click: async context => {
settingStore.checkPlus();
const { ui } = useUi();
@@ -224,6 +227,7 @@ export default function ({ crudExpose, context: { selectedRowKeys, openCertApply
class: "need-plus",
},
config: {
show: hasActionPermission("write"),
order: 1,
title: t("certd.actions.editPipeline"),
type: "link",
@@ -234,6 +238,7 @@ export default function ({ crudExpose, context: { selectedRowKeys, openCertApply
},
},
edit: {
show: hasActionPermission("write"),
order: 2,
title: t("certd.actions.editConfigGroup"),
icon: "ant-design:setting-outlined",
@@ -13,7 +13,7 @@
</a-alert> -->
<fs-crud ref="crudRef" v-bind="crudBinding">
<template #actionbar-right>
<a-dropdown class="ml-1">
<a-dropdown v-if="hasActionPermission('write')" class="ml-1">
<a-button type="primary" class="ant-dropdown-link" @click.prevent>
{{ t("certd.pipelinePage.addMore") }}
<DownOutlined />
@@ -68,6 +68,7 @@ import { useSettingStore } from "/@/store/settings";
import { groupDictRef } from "./group/dicts";
import { useCertPipelineCreator } from "./certd-form/use";
import { useRouter } from "vue-router";
import { useCrudPermission } from "/@/plugin/permission";
defineOptions({
name: "PipelineManager",
@@ -106,7 +107,10 @@ function openCertApplyDialog(req: { key: string; title: string }) {
openAddCertdPipelineDialog({ pluginName: req.key, defaultGroupId, title: req.title });
}
context.openCertApplyDialog = openCertApplyDialog;
context.permission = { isProjectPermission: true };
const { hasActionPermission } = useCrudPermission({ permission: { isProjectPermission: true } });
context.hasActionPermission = hasActionPermission;
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context });
// 页面打开后获取列表数据
@@ -46,7 +46,7 @@
</span>
</a-tag>
</div>
<div class="basis-40 flex justify-end mr-10">
<div v-if="hasActionPermission('write')" class="basis-40 flex justify-end mr-10">
<template v-if="editMode">
<fs-button type="primary" :loading="saveLoading" @click="save">保存</fs-button>
<fs-button class="ml-5" @click="cancel">取消</fs-button>
@@ -333,6 +333,7 @@ import { getCronNextTimes } from "/@/components/cron-editor/utils";
import { useCertViewer } from "/@/views/certd/pipeline/use";
import { useI18n } from "/@/locales";
import TriggerIcon from "./component/trigger-icon.vue";
import { useCrudPermission } from "/@/plugin/permission";
export default defineComponent({
name: "PipelineEdit",
@@ -1002,12 +1003,15 @@ export default defineComponent({
const hasWebhookTrigger = computed(() => {
return currentPipeline.value?.triggers?.some((item: any) => item.type === "webhook");
});
const { hasActionPermission } = useCrudPermission({ permission: { isProjectPermission: true } });
return {
isCert,
pipeline,
currentHistory,
histories,
goBack,
hasActionPermission,
userStore,
settingStore,
...useTaskRet,
@@ -78,7 +78,6 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
add: {
text: t("certd.template.createTemplate"),
type: "primary",
show: true,
},
},
},
@@ -21,7 +21,12 @@ import { useI18n } from "/src/locales";
defineOptions({
name: "PipelineTemplate",
});
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: {} });
const { crudBinding, crudRef, crudExpose } = useFs({
createCrudOptions,
context: {
permission: { isProjectPermission: true },
},
});
const { t } = useI18n();
// 页面打开后获取列表数据
onMounted(() => {
@@ -6,7 +6,7 @@ import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq,
import { useUserStore } from "/@/store/user";
import { useSettingStore } from "/@/store/settings";
import { Modal } from "ant-design-vue";
import { userDict } from "../dicts";
import { userDict } from "../../sys/enterprise/dicts";
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const router = useRouter();
@@ -1,12 +1,12 @@
import * as api from "./api";
import { useI18n } from "/src/locales";
import { computed, Ref, ref } from "vue";
import { useRouter } from "vue-router";
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes, utils } from "@fast-crud/fast-crud";
import { useUserStore } from "/@/store/user";
import { useSettingStore } from "/@/store/settings";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { Modal } from "ant-design-vue";
import { Ref, ref } from "vue";
import { useRouter } from "vue-router";
import { userDict } from "../dicts";
import * as api from "./api";
import { useSettingStore } from "/@/store/settings";
import { useUserStore } from "/@/store/user";
import { useI18n } from "/src/locales";
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const router = useRouter();