mirror of
https://github.com/certd/certd.git
synced 2026-04-30 09:17:24 +08:00
Merge branch 'v2_admin_mode' of https://github.com/certd/certd into v2_admin_mode
This commit is contained in:
Vendored
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
],
|
],
|
||||||
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
|
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
|
||||||
"[typescript]": {
|
"[typescript]": {
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
"editor.defaultFormatter": "vscode.typescript-language-features"
|
||||||
},
|
},
|
||||||
"editor.tabSize": 2,
|
"editor.tabSize": 2,
|
||||||
"explorer.autoReveal": false,
|
"explorer.autoReveal": false,
|
||||||
|
|||||||
@@ -53,7 +53,7 @@
|
|||||||
"prepublishOnly": "npm run build-docs",
|
"prepublishOnly": "npm run build-docs",
|
||||||
"test": "mocha -t 60000 \"test/setup.js\" \"test/**/*.spec.js\"",
|
"test": "mocha -t 60000 \"test/setup.js\" \"test/**/*.spec.js\"",
|
||||||
"pub": "npm publish",
|
"pub": "npm publish",
|
||||||
"compile": "tsc --skipLibCheck --watch"
|
"compile": "echo '1'"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|||||||
@@ -1,11 +1,17 @@
|
|||||||
import { Inject } from '@midwayjs/core';
|
import { ApplicationContext, Inject } from '@midwayjs/core';
|
||||||
|
import type {IMidwayContainer} from '@midwayjs/core';
|
||||||
import * as koa from '@midwayjs/koa';
|
import * as koa from '@midwayjs/koa';
|
||||||
import { Constants } from './constants.js';
|
import { Constants } from './constants.js';
|
||||||
|
import { isEnterprise } from './mode.js';
|
||||||
|
|
||||||
|
|
||||||
export abstract class BaseController {
|
export abstract class BaseController {
|
||||||
@Inject()
|
@Inject()
|
||||||
ctx: koa.Context;
|
ctx: koa.Context;
|
||||||
|
|
||||||
|
@ApplicationContext()
|
||||||
|
applicationContext: IMidwayContainer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 成功返回
|
* 成功返回
|
||||||
* @param data 返回数据
|
* @param data 返回数据
|
||||||
@@ -55,4 +61,44 @@ export abstract class BaseController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getProjectId(permission:string) {
|
||||||
|
if (!isEnterprise()) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
const projectIdStr = this.ctx.headers["project-id"] as string;
|
||||||
|
if (!projectIdStr) {
|
||||||
|
throw new Error("projectId 不能为空")
|
||||||
|
}
|
||||||
|
const userId = this.getUserId()
|
||||||
|
const projectId = parseInt(projectIdStr)
|
||||||
|
await this.checkProjectPermission(userId, projectId,permission)
|
||||||
|
return projectId;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getProjectUserId(permission:string){
|
||||||
|
let userId = this.getUserId()
|
||||||
|
const projectId = await this.getProjectId(permission)
|
||||||
|
if(projectId){
|
||||||
|
userId = 0
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
projectId,userId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async getProjectUserIdRead(){
|
||||||
|
return await this.getProjectUserId("read")
|
||||||
|
}
|
||||||
|
async getProjectUserIdWrite(){
|
||||||
|
return await this.getProjectUserId("write")
|
||||||
|
}
|
||||||
|
async getProjectUserIdAdmin(){
|
||||||
|
return await this.getProjectUserId("admin")
|
||||||
|
}
|
||||||
|
|
||||||
|
async checkProjectPermission(userId: number, projectId: number,permission:string) {
|
||||||
|
const projectService:any = await this.applicationContext.getAsync("projectService");
|
||||||
|
await projectService.checkPermission({userId,projectId,permission})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,3 +5,4 @@ export * from './enum-item.js';
|
|||||||
export * from './exception/index.js';
|
export * from './exception/index.js';
|
||||||
export * from './result.js';
|
export * from './result.js';
|
||||||
export * from './base-service.js';
|
export * from './base-service.js';
|
||||||
|
export * from "./mode.js"
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
let adminMode = "saas"
|
||||||
|
|
||||||
|
export function setAdminMode(mode:string = "saas"){
|
||||||
|
adminMode = mode
|
||||||
|
}
|
||||||
|
export function getAdminMode(){
|
||||||
|
return adminMode
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isEnterprise(){
|
||||||
|
return adminMode === "enterprise"
|
||||||
|
}
|
||||||
@@ -7,9 +7,10 @@ import { BaseSettings, SysInstallInfo, SysPrivateSettings, SysPublicSettings, Sy
|
|||||||
import { getAllSslProviderDomains, setSslProviderReverseProxies } from '@certd/acme-client';
|
import { getAllSslProviderDomains, setSslProviderReverseProxies } from '@certd/acme-client';
|
||||||
import { cache, logger, mergeUtils, setGlobalProxy } from '@certd/basic';
|
import { cache, logger, mergeUtils, setGlobalProxy } from '@certd/basic';
|
||||||
import * as dns from 'node:dns';
|
import * as dns from 'node:dns';
|
||||||
import { BaseService } from '../../../basic/index.js';
|
import { BaseService, setAdminMode } from '../../../basic/index.js';
|
||||||
import { executorQueue } from '../../basic/service/executor-queue.js';
|
import { executorQueue } from '../../basic/service/executor-queue.js';
|
||||||
const {merge} = mergeUtils;
|
import { isComm } from '@certd/plus-core';
|
||||||
|
const { merge } = mergeUtils;
|
||||||
/**
|
/**
|
||||||
* 设置
|
* 设置
|
||||||
*/
|
*/
|
||||||
@@ -116,7 +117,15 @@ export class SysSettingsService extends BaseService<SysSettingsEntity> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async savePublicSettings(bean: SysPublicSettings) {
|
async savePublicSettings(bean: SysPublicSettings) {
|
||||||
|
if(isComm()){
|
||||||
|
if(bean.adminMode === 'enterprise'){
|
||||||
|
throw new Error("商业版不支持使用企业管理模式")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await this.saveSetting(bean);
|
await this.saveSetting(bean);
|
||||||
|
//让设置生效
|
||||||
|
await this.reloadPublicSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
async getPrivateSettings(): Promise<SysPrivateSettings> {
|
async getPrivateSettings(): Promise<SysPrivateSettings> {
|
||||||
@@ -137,23 +146,33 @@ export class SysSettingsService extends BaseService<SysSettingsEntity> {
|
|||||||
await this.reloadPrivateSettings();
|
await this.reloadPrivateSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async reloadSettings() {
|
||||||
|
await this.reloadPrivateSettings()
|
||||||
|
await this.reloadPublicSettings()
|
||||||
|
}
|
||||||
|
|
||||||
|
async reloadPublicSettings() {
|
||||||
|
const publicSetting = await this.getPublicSettings()
|
||||||
|
setAdminMode(publicSetting.adminMode)
|
||||||
|
}
|
||||||
|
|
||||||
async reloadPrivateSettings() {
|
async reloadPrivateSettings() {
|
||||||
const bean = await this.getPrivateSettings();
|
const privateSetting = await this.getPrivateSettings();
|
||||||
const opts = {
|
const opts = {
|
||||||
httpProxy: bean.httpProxy,
|
httpProxy: privateSetting.httpProxy,
|
||||||
httpsProxy: bean.httpsProxy,
|
httpsProxy: privateSetting.httpsProxy,
|
||||||
};
|
};
|
||||||
setGlobalProxy(opts);
|
setGlobalProxy(opts);
|
||||||
|
|
||||||
if (bean.dnsResultOrder) {
|
if (privateSetting.dnsResultOrder) {
|
||||||
dns.setDefaultResultOrder(bean.dnsResultOrder as any);
|
dns.setDefaultResultOrder(privateSetting.dnsResultOrder as any);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bean.pipelineMaxRunningCount){
|
if (privateSetting.pipelineMaxRunningCount) {
|
||||||
executorQueue.setMaxRunningCount(bean.pipelineMaxRunningCount);
|
executorQueue.setMaxRunningCount(privateSetting.pipelineMaxRunningCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
setSslProviderReverseProxies(bean.reverseProxies);
|
setSslProviderReverseProxies(privateSetting.reverseProxies);
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateByKey(key: string, setting: any) {
|
async updateByKey(key: string, setting: any) {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { get } from "lodash-es";
|
|||||||
import { errorLog, errorCreate } from "./tools";
|
import { errorLog, errorCreate } from "./tools";
|
||||||
import { env } from "/src/utils/util.env";
|
import { env } from "/src/utils/util.env";
|
||||||
import { useUserStore } from "/@/store/user";
|
import { useUserStore } from "/@/store/user";
|
||||||
|
import { useProjectStore } from "../store/project";
|
||||||
|
|
||||||
export class CodeError extends Error {
|
export class CodeError extends Error {
|
||||||
code: number;
|
code: number;
|
||||||
@@ -138,11 +139,17 @@ function createRequestFunction(service: any) {
|
|||||||
const configDefault = {
|
const configDefault = {
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": get(config, "headers.Content-Type", "application/json"),
|
"Content-Type": get(config, "headers.Content-Type", "application/json"),
|
||||||
},
|
} as any,
|
||||||
timeout: 30000,
|
timeout: 30000,
|
||||||
baseURL: env.API,
|
baseURL: env.API,
|
||||||
data: {},
|
data: {},
|
||||||
};
|
};
|
||||||
|
const projectStore = useProjectStore();
|
||||||
|
|
||||||
|
if (projectStore.isEnterprise && !config.url.startsWith("/sys")) {
|
||||||
|
configDefault.headers["project-id"] = projectStore.currentProjectId;
|
||||||
|
}
|
||||||
|
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const token = userStore.getToken;
|
const token = userStore.getToken;
|
||||||
if (token != null) {
|
if (token != null) {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { defineAsyncComponent } from "vue";
|
|||||||
import NotificationSelector from "../views/certd/notification/notification-selector/index.vue";
|
import NotificationSelector from "../views/certd/notification/notification-selector/index.vue";
|
||||||
import EmailSelector from "./email-selector/index.vue";
|
import EmailSelector from "./email-selector/index.vue";
|
||||||
import ValidTimeFormat from "./valid-time-format.vue";
|
import ValidTimeFormat from "./valid-time-format.vue";
|
||||||
|
import ProjectSelector from "./project-selector/index.vue";
|
||||||
export default {
|
export default {
|
||||||
install(app: any) {
|
install(app: any) {
|
||||||
app.component(
|
app.component(
|
||||||
@@ -45,5 +46,6 @@ export default {
|
|||||||
app.component("ExpiresTimeText", ExpiresTimeText);
|
app.component("ExpiresTimeText", ExpiresTimeText);
|
||||||
app.use(vip);
|
app.use(vip);
|
||||||
app.use(Plugins);
|
app.use(Plugins);
|
||||||
|
app.component("ProjectSelector", ProjectSelector);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
:options="optionsRef"
|
:options="optionsRef"
|
||||||
:value="value"
|
:value="value"
|
||||||
v-bind="attrs"
|
v-bind="attrs"
|
||||||
:open="openProp"
|
|
||||||
@click="onClick"
|
@click="onClick"
|
||||||
@update:value="emit('update:value', $event)"
|
@update:value="emit('update:value', $event)"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import { request } from "/src/api/service";
|
||||||
|
|
||||||
|
export async function MyProjectList() {
|
||||||
|
return await request({
|
||||||
|
url: "/enterprise/project/list",
|
||||||
|
method: "post",
|
||||||
|
data: {},
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<template>
|
||||||
|
<a-dropdown class="project-selector">
|
||||||
|
<template #overlay>
|
||||||
|
<a-menu @click="handleMenuClick">
|
||||||
|
<a-menu-item v-for="item in projectStore.myProjects" :key="item.id">
|
||||||
|
{{ item.name }}
|
||||||
|
</a-menu-item>
|
||||||
|
</a-menu>
|
||||||
|
</template>
|
||||||
|
<div class="rounded pl-3 pr-3 px-2 py-1 flex-center flex pointer items-center bg-accent h-10 button-text">
|
||||||
|
<fs-icon icon="ion:apps" class="mr-1"></fs-icon>
|
||||||
|
{{ projectStore.currentProject?.name || "..." }}
|
||||||
|
<fs-icon icon="ion:chevron-down-outline" class="ml-1"></fs-icon>
|
||||||
|
</div>
|
||||||
|
</a-dropdown>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { onMounted } from "vue";
|
||||||
|
import { useProjectStore } from "/@/store/project";
|
||||||
|
defineOptions({
|
||||||
|
name: "ProjectSelector",
|
||||||
|
});
|
||||||
|
|
||||||
|
const projectStore = useProjectStore();
|
||||||
|
onMounted(async () => {
|
||||||
|
await projectStore.reload();
|
||||||
|
});
|
||||||
|
|
||||||
|
function handleMenuClick({ key }: any) {
|
||||||
|
projectStore.changeCurrentProject(key);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="less">
|
||||||
|
.project-selector {
|
||||||
|
&.button-text {
|
||||||
|
min-width: 100px;
|
||||||
|
max-width: 150px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -81,6 +81,11 @@ provide("fn:ai.open", openChat);
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<BasicLayout @clear-preferences-and-logout="handleLogout">
|
<BasicLayout @clear-preferences-and-logout="handleLogout">
|
||||||
|
<template #header-left-0>
|
||||||
|
<div class="ml-1 mr-2">
|
||||||
|
<project-selector class="flex-center header-btn" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
<template #user-dropdown>
|
<template #user-dropdown>
|
||||||
<UserDropdown :avatar="avatar" :menus="menus" :text="userStore.userInfo?.nickName || userStore.userInfo?.username" description="" tag-text="" @logout="handleLogout" />
|
<UserDropdown :avatar="avatar" :menus="menus" :text="userStore.userInfo?.nickName || userStore.userInfo?.username" description="" tag-text="" @logout="handleLogout" />
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -160,6 +160,8 @@ export default {
|
|||||||
updateTime: "Update Time",
|
updateTime: "Update Time",
|
||||||
triggerType: "Trigger Type",
|
triggerType: "Trigger Type",
|
||||||
pipelineId: "Pipeline Id",
|
pipelineId: "Pipeline Id",
|
||||||
|
projectName: "Project",
|
||||||
|
adminId: "Admin",
|
||||||
},
|
},
|
||||||
|
|
||||||
pi: {
|
pi: {
|
||||||
@@ -212,6 +214,8 @@ export default {
|
|||||||
enterpriseSetting: "Enterprise Settings",
|
enterpriseSetting: "Enterprise Settings",
|
||||||
projectManager: "Project Management",
|
projectManager: "Project Management",
|
||||||
projectUserManager: "Project User Management",
|
projectUserManager: "Project User Management",
|
||||||
|
myProjectManager: "My Projects",
|
||||||
|
myProjectDetail: "Project Detail",
|
||||||
},
|
},
|
||||||
certificateRepo: {
|
certificateRepo: {
|
||||||
title: "Certificate Repository",
|
title: "Certificate Repository",
|
||||||
@@ -790,6 +794,10 @@ export default {
|
|||||||
pipelineSetting: "Pipeline Settings",
|
pipelineSetting: "Pipeline Settings",
|
||||||
oauthSetting: "OAuth2 Settings",
|
oauthSetting: "OAuth2 Settings",
|
||||||
networkSetting: "Network Settings",
|
networkSetting: "Network Settings",
|
||||||
|
adminModeSetting: "Admin Mode Settings",
|
||||||
|
adminModeHelper: "enterprise mode : allow to create and manage pipelines, roles, users, etc.\n saas mode : only allow to create and manage pipelines",
|
||||||
|
enterpriseMode: "Enterprise Mode",
|
||||||
|
saasMode: "SaaS Mode",
|
||||||
|
|
||||||
showRunStrategy: "Show RunStrategy",
|
showRunStrategy: "Show RunStrategy",
|
||||||
showRunStrategyHelper: "Allow modify the run strategy of the task",
|
showRunStrategyHelper: "Allow modify the run strategy of the task",
|
||||||
@@ -868,12 +876,20 @@ export default {
|
|||||||
fromType: "From Type",
|
fromType: "From Type",
|
||||||
expirationDate: "Expiration Date",
|
expirationDate: "Expiration Date",
|
||||||
},
|
},
|
||||||
|
ent: {
|
||||||
|
projectName: "Project Name",
|
||||||
|
projectDescription: "Project Description",
|
||||||
|
projectDetailManager: "Project Detail",
|
||||||
|
projectDetailDescription: "Manage Project Members",
|
||||||
|
projectPermission: "Permission",
|
||||||
|
permission: {
|
||||||
|
read: "Read",
|
||||||
|
write: "Write",
|
||||||
|
admin: "Admin",
|
||||||
|
},
|
||||||
|
},
|
||||||
addonSelector: {
|
addonSelector: {
|
||||||
select: "Select",
|
select: "Select",
|
||||||
placeholder: "select please",
|
placeholder: "select please",
|
||||||
},
|
},
|
||||||
adminMode: {
|
|
||||||
enterpriseMode: "Enterprise Mode",
|
|
||||||
saasMode: "SaaS Mode",
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -167,6 +167,8 @@ export default {
|
|||||||
updateTime: "更新时间",
|
updateTime: "更新时间",
|
||||||
triggerType: "触发类型",
|
triggerType: "触发类型",
|
||||||
pipelineId: "流水线Id",
|
pipelineId: "流水线Id",
|
||||||
|
projectName: "项目",
|
||||||
|
adminId: "管理员",
|
||||||
},
|
},
|
||||||
pi: {
|
pi: {
|
||||||
validTime: "流水线有效期",
|
validTime: "流水线有效期",
|
||||||
@@ -214,9 +216,12 @@ export default {
|
|||||||
orderManager: "订单管理",
|
orderManager: "订单管理",
|
||||||
userSuites: "用户套餐",
|
userSuites: "用户套餐",
|
||||||
netTest: "网络测试",
|
netTest: "网络测试",
|
||||||
enterpriseSetting: "企业管理设置",
|
enterpriseManager: "企业管理设置",
|
||||||
projectManager: "项目管理",
|
projectManager: "项目管理",
|
||||||
projectUserManager: "项目用户管理",
|
projectDetail: "项目详情",
|
||||||
|
enterpriseSetting: "企业设置",
|
||||||
|
myProjectManager: "我的项目",
|
||||||
|
myProjectDetail: "项目详情",
|
||||||
},
|
},
|
||||||
certificateRepo: {
|
certificateRepo: {
|
||||||
title: "证书仓库",
|
title: "证书仓库",
|
||||||
@@ -796,6 +801,12 @@ export default {
|
|||||||
pipelineSetting: "流水线设置",
|
pipelineSetting: "流水线设置",
|
||||||
oauthSetting: "第三方登录",
|
oauthSetting: "第三方登录",
|
||||||
networkSetting: "网络设置",
|
networkSetting: "网络设置",
|
||||||
|
adminModeSetting: "管理模式",
|
||||||
|
adminModeHelper: "企业管理模式: 企业内部使用,通过项目来隔离权限,流水线、授权数据属于项目。\nsaas模式:供外部用户注册使用,各个用户之间数据隔离,流水线、授权数据属于用户。",
|
||||||
|
|
||||||
|
adminMode: "管理模式",
|
||||||
|
enterpriseMode: "企业模式",
|
||||||
|
saasMode: "SaaS模式",
|
||||||
|
|
||||||
showRunStrategy: "显示运行策略选择",
|
showRunStrategy: "显示运行策略选择",
|
||||||
showRunStrategyHelper: "任务设置中是否允许选择运行策略",
|
showRunStrategyHelper: "任务设置中是否允许选择运行策略",
|
||||||
@@ -886,11 +897,16 @@ export default {
|
|||||||
select: "选择",
|
select: "选择",
|
||||||
placeholder: "请选择",
|
placeholder: "请选择",
|
||||||
},
|
},
|
||||||
adminMode: {
|
|
||||||
enterpriseMode: "企业模式",
|
|
||||||
saasMode: "SaaS模式",
|
|
||||||
},
|
|
||||||
ent: {
|
ent: {
|
||||||
projectName: "项目名称",
|
projectName: "项目名称",
|
||||||
|
projectDescription: "项目描述",
|
||||||
|
projectDetailManager: "项目详情",
|
||||||
|
projectDetailDescription: "管理项目成员",
|
||||||
|
projectPermission: "权限",
|
||||||
|
permission: {
|
||||||
|
read: "读取",
|
||||||
|
write: "写入",
|
||||||
|
admin: "管理员",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -14,6 +14,30 @@ export const certdResources = [
|
|||||||
order: 0,
|
order: 0,
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
|
{
|
||||||
|
title: "certd.sysResources.myProjectManager",
|
||||||
|
name: "MyProjectManager",
|
||||||
|
path: "/certd/project",
|
||||||
|
component: "/certd/project/index.vue",
|
||||||
|
meta: {
|
||||||
|
show: true,
|
||||||
|
icon: "ion:apps",
|
||||||
|
permission: "sys:settings:edit",
|
||||||
|
keepAlive: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "certd.sysResources.myProjectDetail",
|
||||||
|
name: "MyProjectDetail",
|
||||||
|
path: "/certd/project/detail",
|
||||||
|
component: "/certd/project/detail/index.vue",
|
||||||
|
meta: {
|
||||||
|
isMenu: false,
|
||||||
|
show: true,
|
||||||
|
icon: "ion:apps",
|
||||||
|
permission: "sys:settings:edit",
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: "certd.pipeline",
|
title: "certd.pipeline",
|
||||||
name: "PipelineManager",
|
name: "PipelineManager",
|
||||||
@@ -94,59 +118,6 @@ export const certdResources = [
|
|||||||
keepAlive: true,
|
keepAlive: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
title: "certd.sysResources.enterpriseManager",
|
|
||||||
name: "EnterpriseManager",
|
|
||||||
path: "/sys/enterprise",
|
|
||||||
redirect: "/sys/enterprise/project",
|
|
||||||
meta: {
|
|
||||||
icon: "ion:cart-outline",
|
|
||||||
permission: "sys:settings:edit",
|
|
||||||
show: () => {
|
|
||||||
const settingStore = useSettingStore();
|
|
||||||
return settingStore.isEnterprise;
|
|
||||||
},
|
|
||||||
keepAlive: true,
|
|
||||||
},
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
title: "certd.sysResources.projectManager",
|
|
||||||
name: "ProjectManager",
|
|
||||||
path: "/sys/enterprise/project",
|
|
||||||
component: "/sys/enterprise/project/index.vue",
|
|
||||||
meta: {
|
|
||||||
show: true,
|
|
||||||
icon: "ion:cart",
|
|
||||||
permission: "sys:settings:edit",
|
|
||||||
keepAlive: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "certd.sysResources.projectMemberManager",
|
|
||||||
name: "ProjectMemberManager",
|
|
||||||
path: "/sys/enterprise/project/member",
|
|
||||||
component: "/sys/enterprise/project/member/index.vue",
|
|
||||||
meta: {
|
|
||||||
isMenu: false,
|
|
||||||
show: true,
|
|
||||||
icon: "ion:cart",
|
|
||||||
permission: "sys:settings:edit",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "certd.sysResources.enterpriseSetting",
|
|
||||||
name: "EnterpriseSetting",
|
|
||||||
path: "/sys/enterprise/setting",
|
|
||||||
redirect: "/sys/settings?tab=mode",
|
|
||||||
meta: {
|
|
||||||
isMenu: true,
|
|
||||||
show: true,
|
|
||||||
icon: "ion:cart",
|
|
||||||
permission: "sys:settings:edit",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: "certd.settings",
|
title: "certd.settings",
|
||||||
name: "MineSetting",
|
name: "MineSetting",
|
||||||
|
|||||||
@@ -40,6 +40,30 @@ export const sysResources = [
|
|||||||
permission: "sys:settings:view",
|
permission: "sys:settings:view",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: "certd.sysResources.projectManager",
|
||||||
|
name: "ProjectManager",
|
||||||
|
path: "/sys/enterprise/project",
|
||||||
|
component: "/sys/enterprise/project/index.vue",
|
||||||
|
meta: {
|
||||||
|
show: true,
|
||||||
|
icon: "ion:apps",
|
||||||
|
permission: "sys:settings:edit",
|
||||||
|
keepAlive: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "certd.sysResources.projectDetail",
|
||||||
|
name: "ProjectDetail",
|
||||||
|
path: "/sys/enterprise/project/detail",
|
||||||
|
component: "/sys/enterprise/project/detail/index.vue",
|
||||||
|
meta: {
|
||||||
|
isMenu: false,
|
||||||
|
show: true,
|
||||||
|
icon: "ion:apps",
|
||||||
|
permission: "sys:settings:edit",
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: "certd.sysResources.cnameSetting",
|
title: "certd.sysResources.cnameSetting",
|
||||||
name: "CnameSetting",
|
name: "CnameSetting",
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import { request } from "/src/api/service";
|
||||||
|
|
||||||
|
export async function MyProjectList() {
|
||||||
|
return await request({
|
||||||
|
url: "/enterprise/project/list",
|
||||||
|
method: "post",
|
||||||
|
data: {},
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
import { defineStore } from "pinia";
|
||||||
|
import * as api from "./api";
|
||||||
|
import { message } from "ant-design-vue";
|
||||||
|
import { computed, ref } from "vue";
|
||||||
|
import { useSettingStore } from "../settings";
|
||||||
|
import { LocalStorage } from "/@/utils/util.storage";
|
||||||
|
|
||||||
|
export type ProjectItem = {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
permission?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useProjectStore = defineStore("app.project", () => {
|
||||||
|
const myProjects = ref([]);
|
||||||
|
const lastProjectId = LocalStorage.get("currentProjectId");
|
||||||
|
const currentProjectId = ref(lastProjectId); // 直接调用
|
||||||
|
|
||||||
|
const projects = computed(() => {
|
||||||
|
return myProjects.value;
|
||||||
|
});
|
||||||
|
const currentProject = computed(() => {
|
||||||
|
if (currentProjectId.value) {
|
||||||
|
const project = projects.value.find(item => item.id === currentProjectId.value);
|
||||||
|
if (project) {
|
||||||
|
return project;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (projects.value.length > 0) {
|
||||||
|
return projects.value[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
const settingStore = useSettingStore();
|
||||||
|
const isEnterprise = computed(() => {
|
||||||
|
return settingStore.isEnterprise;
|
||||||
|
});
|
||||||
|
|
||||||
|
function getSearchForm() {
|
||||||
|
if (!currentProjectId.value || !isEnterprise.value) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
projectId: currentProjectId.value,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
async function loadMyProjects(): Promise<ProjectItem[]> {
|
||||||
|
if (!isEnterprise.value) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const projects = await api.MyProjectList();
|
||||||
|
myProjects.value = projects;
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeCurrentProject(id: string) {
|
||||||
|
currentProjectId.value = id;
|
||||||
|
LocalStorage.set("currentProjectId", id);
|
||||||
|
message.success("切换项目成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
async function reload() {
|
||||||
|
const projects = await api.MyProjectList();
|
||||||
|
myProjects.value = projects;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function init() {
|
||||||
|
if (!myProjects.value) {
|
||||||
|
await reload();
|
||||||
|
}
|
||||||
|
return myProjects.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
projects,
|
||||||
|
myProjects,
|
||||||
|
currentProject,
|
||||||
|
currentProjectId,
|
||||||
|
isEnterprise,
|
||||||
|
getSearchForm,
|
||||||
|
loadMyProjects,
|
||||||
|
changeCurrentProject,
|
||||||
|
reload,
|
||||||
|
init,
|
||||||
|
};
|
||||||
|
});
|
||||||
@@ -3,6 +3,8 @@ import { ref } from "vue";
|
|||||||
import { getCommonColumnDefine } from "/@/views/certd/access/common";
|
import { getCommonColumnDefine } from "/@/views/certd/access/common";
|
||||||
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||||
import { useI18n } from "/src/locales";
|
import { useI18n } from "/src/locales";
|
||||||
|
import { useProjectStore } from "/@/store/project";
|
||||||
|
import { myProjectDict } from "../../../dicts";
|
||||||
|
|
||||||
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
@@ -44,6 +46,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
context.typeRef = typeRef;
|
context.typeRef = typeRef;
|
||||||
const commonColumnsDefine = getCommonColumnDefine(crudExpose, typeRef, api);
|
const commonColumnsDefine = getCommonColumnDefine(crudExpose, typeRef, api);
|
||||||
commonColumnsDefine.type.form.component.disabled = true;
|
commonColumnsDefine.type.form.component.disabled = true;
|
||||||
|
const projectStore = useProjectStore();
|
||||||
return {
|
return {
|
||||||
typeRef,
|
typeRef,
|
||||||
crudOptions: {
|
crudOptions: {
|
||||||
@@ -58,6 +61,9 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
},
|
},
|
||||||
search: {
|
search: {
|
||||||
show: true,
|
show: true,
|
||||||
|
initialForm: {
|
||||||
|
...projectStore.getSearchForm(),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
form: {
|
form: {
|
||||||
wrapper: {
|
wrapper: {
|
||||||
@@ -141,6 +147,11 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
...commonColumnsDefine,
|
...commonColumnsDefine,
|
||||||
|
projectId: {
|
||||||
|
title: t("certd.fields.projectName"),
|
||||||
|
type: "dict-select",
|
||||||
|
dict: myProjectDict,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { useI18n } from "/src/locales";
|
|
||||||
import { ref } from "vue";
|
|
||||||
import { getCommonColumnDefine } from "/@/views/certd/access/common";
|
|
||||||
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||||
|
import { ref } from "vue";
|
||||||
|
import { myProjectDict } from "../dicts";
|
||||||
|
import { useProjectStore } from "/@/store/project";
|
||||||
|
import { getCommonColumnDefine } from "/@/views/certd/access/common";
|
||||||
|
import { useI18n } from "/src/locales";
|
||||||
|
|
||||||
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
@@ -29,6 +31,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
|
|
||||||
const typeRef = ref();
|
const typeRef = ref();
|
||||||
const commonColumnsDefine = getCommonColumnDefine(crudExpose, typeRef, api);
|
const commonColumnsDefine = getCommonColumnDefine(crudExpose, typeRef, api);
|
||||||
|
const projectStore = useProjectStore();
|
||||||
return {
|
return {
|
||||||
crudOptions: {
|
crudOptions: {
|
||||||
request: {
|
request: {
|
||||||
@@ -42,6 +45,11 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
confirmMessage: "授权如果已经被使用,可能会导致流水线无法正常运行,请谨慎操作",
|
confirmMessage: "授权如果已经被使用,可能会导致流水线无法正常运行,请谨慎操作",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
search: {
|
||||||
|
initialForm: {
|
||||||
|
...projectStore.getSearchForm(),
|
||||||
|
},
|
||||||
|
},
|
||||||
rowHandle: {
|
rowHandle: {
|
||||||
width: 200,
|
width: 200,
|
||||||
buttons: {
|
buttons: {
|
||||||
@@ -115,6 +123,11 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
...commonColumnsDefine,
|
...commonColumnsDefine,
|
||||||
|
projectId: {
|
||||||
|
title: t("certd.fields.projectName"),
|
||||||
|
type: "dict-select",
|
||||||
|
dict: myProjectDict,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -17,6 +17,16 @@ export const projectPermissionDict = dict({
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
export const projectDict = dict({
|
export const myProjectDict = dict({
|
||||||
url: "/sys/enterprise/project/list",
|
url: "/enterprise/project/list",
|
||||||
|
});
|
||||||
|
|
||||||
|
export const userDict = dict({
|
||||||
|
url: "/sys/authority/user/getSimpleUsers",
|
||||||
|
value: "id",
|
||||||
|
onReady: ({ dict }) => {
|
||||||
|
for (const item of dict.data) {
|
||||||
|
item.label = item.nickName || item.username || item.phoneCode + item.mobile;
|
||||||
|
}
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, Edi
|
|||||||
import { useUserStore } from "/@/store/user";
|
import { useUserStore } from "/@/store/user";
|
||||||
import { useSettingStore } from "/@/store/settings";
|
import { useSettingStore } from "/@/store/settings";
|
||||||
import { statusUtil } from "/@/views/certd/pipeline/pipeline/utils/util.status";
|
import { statusUtil } from "/@/views/certd/pipeline/pipeline/utils/util.status";
|
||||||
|
import { myProjectDict } from "../dicts";
|
||||||
|
import { useProjectStore } from "/@/store/project";
|
||||||
|
|
||||||
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -32,6 +34,8 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
const selectedRowKeys: Ref<any[]> = ref([]);
|
const selectedRowKeys: Ref<any[]> = ref([]);
|
||||||
context.selectedRowKeys = selectedRowKeys;
|
context.selectedRowKeys = selectedRowKeys;
|
||||||
|
|
||||||
|
const projectStore = useProjectStore();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
crudOptions: {
|
crudOptions: {
|
||||||
settings: {
|
settings: {
|
||||||
@@ -64,6 +68,9 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
search: {
|
search: {
|
||||||
|
initialForm: {
|
||||||
|
...projectStore.getSearchForm(),
|
||||||
|
},
|
||||||
formItem: {
|
formItem: {
|
||||||
labelCol: {
|
labelCol: {
|
||||||
style: {
|
style: {
|
||||||
@@ -195,17 +202,10 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
align: "center",
|
align: "center",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
createTime: {
|
projectId: {
|
||||||
title: t("certd.fields.createTime"),
|
title: t("certd.fields.projectName"),
|
||||||
type: "datetime",
|
type: "dict-select",
|
||||||
form: {
|
dict: myProjectDict,
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
column: {
|
|
||||||
sorter: true,
|
|
||||||
width: 160,
|
|
||||||
align: "center",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
updateTime: {
|
updateTime: {
|
||||||
title: t("certd.fields.updateTime"),
|
title: t("certd.fields.updateTime"),
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import { notification } from "ant-design-vue";
|
|||||||
import CertView from "/@/views/certd/pipeline/cert-view.vue";
|
import CertView from "/@/views/certd/pipeline/cert-view.vue";
|
||||||
import { useCertUpload } from "/@/views/certd/pipeline/cert-upload/use";
|
import { useCertUpload } from "/@/views/certd/pipeline/cert-upload/use";
|
||||||
import { useSettingStore } from "/@/store/settings";
|
import { useSettingStore } from "/@/store/settings";
|
||||||
|
import { useProjectStore } from "/@/store/project";
|
||||||
|
import { myProjectDict } from "../../dicts";
|
||||||
|
|
||||||
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
@@ -36,7 +38,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const settingStore = useSettingStore();
|
const settingStore = useSettingStore();
|
||||||
|
const projectStore = useProjectStore();
|
||||||
const model = useModal();
|
const model = useModal();
|
||||||
const viewCert = async (row: any) => {
|
const viewCert = async (row: any) => {
|
||||||
const cert = await api.GetCert(row.id);
|
const cert = await api.GetCert(row.id);
|
||||||
@@ -63,6 +65,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
const expireStatus = route?.query?.expireStatus as string;
|
const expireStatus = route?.query?.expireStatus as string;
|
||||||
const searchInitForm = {
|
const searchInitForm = {
|
||||||
expiresLeft: expireStatus,
|
expiresLeft: expireStatus,
|
||||||
|
...projectStore.getSearchForm(),
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
crudOptions: {
|
crudOptions: {
|
||||||
@@ -344,6 +347,11 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
projectId: {
|
||||||
|
title: t("certd.fields.projectName"),
|
||||||
|
type: "dict-select",
|
||||||
|
dict: myProjectDict,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import { useSiteImport } from "/@/views/certd/monitor/site/use";
|
|||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import GroupSelector from "../../basic/group/group-selector.vue";
|
import GroupSelector from "../../basic/group/group-selector.vue";
|
||||||
import { createGroupDictRef } from "../../basic/group/api";
|
import { createGroupDictRef } from "../../basic/group/api";
|
||||||
|
import { useProjectStore } from "/@/store/project";
|
||||||
|
import { myProjectDict } from "../../dicts";
|
||||||
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const api = siteInfoApi;
|
const api = siteInfoApi;
|
||||||
@@ -105,6 +107,8 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
return searchFrom.groupId;
|
return searchFrom.groupId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const projectStore = useProjectStore();
|
||||||
return {
|
return {
|
||||||
id: "siteMonitorCrud",
|
id: "siteMonitorCrud",
|
||||||
crudOptions: {
|
crudOptions: {
|
||||||
@@ -289,6 +293,11 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
// name: "disabled",
|
// name: "disabled",
|
||||||
// show: true,
|
// show: true,
|
||||||
// },
|
// },
|
||||||
|
search: {
|
||||||
|
initialForm: {
|
||||||
|
...projectStore.getSearchForm(),
|
||||||
|
},
|
||||||
|
},
|
||||||
columns: {
|
columns: {
|
||||||
id: {
|
id: {
|
||||||
title: "ID",
|
title: "ID",
|
||||||
@@ -800,6 +809,11 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
projectId: {
|
||||||
|
title: t("certd.fields.projectName"),
|
||||||
|
type: "dict-select",
|
||||||
|
dict: myProjectDict,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import { forEach, get, merge, set } from "lodash-es";
|
|||||||
import { Modal } from "ant-design-vue";
|
import { Modal } from "ant-design-vue";
|
||||||
import { mitter } from "/@/utils/util.mitt";
|
import { mitter } from "/@/utils/util.mitt";
|
||||||
import { useI18n } from "/src/locales";
|
import { useI18n } from "/src/locales";
|
||||||
|
import { useProjectStore } from "/@/store/project";
|
||||||
|
import { myProjectDict } from "../dicts";
|
||||||
|
|
||||||
export function notificationProvide(api: any) {
|
export function notificationProvide(api: any) {
|
||||||
provide("notificationApi", api);
|
provide("notificationApi", api);
|
||||||
@@ -26,6 +28,8 @@ export function getCommonColumnDefine(crudExpose: any, typeRef: any, api: any) {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const projectStore = useProjectStore();
|
||||||
|
|
||||||
provide("getCurrentPluginDefine", () => {
|
provide("getCurrentPluginDefine", () => {
|
||||||
return currentDefine;
|
return currentDefine;
|
||||||
});
|
});
|
||||||
@@ -247,5 +251,10 @@ export function getCommonColumnDefine(crudExpose: any, typeRef: any, api: any) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
} as ColumnCompositionProps,
|
} as ColumnCompositionProps,
|
||||||
|
projectId: {
|
||||||
|
title: t("certd.fields.projectName"),
|
||||||
|
type: "dict-select",
|
||||||
|
dict: myProjectDict,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { ref } from "vue";
|
|||||||
import { getCommonColumnDefine } from "./common";
|
import { getCommonColumnDefine } from "./common";
|
||||||
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||||
import { createNotificationApi } from "/@/views/certd/notification/api";
|
import { createNotificationApi } from "/@/views/certd/notification/api";
|
||||||
|
import { useProjectStore } from "/@/store/project";
|
||||||
const api = createNotificationApi();
|
const api = createNotificationApi();
|
||||||
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||||
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
||||||
@@ -26,6 +27,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
|
|
||||||
const typeRef = ref();
|
const typeRef = ref();
|
||||||
const commonColumnsDefine = getCommonColumnDefine(crudExpose, typeRef, api);
|
const commonColumnsDefine = getCommonColumnDefine(crudExpose, typeRef, api);
|
||||||
|
const projectStore = useProjectStore();
|
||||||
return {
|
return {
|
||||||
crudOptions: {
|
crudOptions: {
|
||||||
request: {
|
request: {
|
||||||
@@ -34,6 +36,11 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
editRequest,
|
editRequest,
|
||||||
delRequest,
|
delRequest,
|
||||||
},
|
},
|
||||||
|
search: {
|
||||||
|
initialForm: {
|
||||||
|
...projectStore.getSearchForm(),
|
||||||
|
},
|
||||||
|
},
|
||||||
form: {
|
form: {
|
||||||
labelCol: {
|
labelCol: {
|
||||||
//固定label宽度
|
//固定label宽度
|
||||||
|
|||||||
+5
@@ -2,6 +2,7 @@
|
|||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import { getCommonColumnDefine } from "../../common";
|
import { getCommonColumnDefine } from "../../common";
|
||||||
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||||
|
import { useProjectStore } from "/@/store/project";
|
||||||
|
|
||||||
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||||
const { crudBinding } = crudExpose;
|
const { crudBinding } = crudExpose;
|
||||||
@@ -29,6 +30,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const projectStore = useProjectStore();
|
||||||
const selectedRowKey = ref([props.modelValue]);
|
const selectedRowKey = ref([props.modelValue]);
|
||||||
|
|
||||||
const onSelectChange = (changed: any) => {
|
const onSelectChange = (changed: any) => {
|
||||||
@@ -54,6 +56,9 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
},
|
},
|
||||||
search: {
|
search: {
|
||||||
show: false,
|
show: false,
|
||||||
|
initialForm: {
|
||||||
|
...projectStore.getSearchForm(),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
form: {
|
form: {
|
||||||
labelCol: {
|
labelCol: {
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import { useI18n } from "/src/locales";
|
|||||||
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||||
import { OPEN_API_DOC, openkeyApi } from "./api";
|
import { OPEN_API_DOC, openkeyApi } from "./api";
|
||||||
import { useModal } from "/@/use/use-modal";
|
import { useModal } from "/@/use/use-modal";
|
||||||
|
import { useProjectStore } from "/@/store/project";
|
||||||
|
import { myProjectDict } from "../../dicts";
|
||||||
|
|
||||||
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
@@ -26,6 +28,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
const res = await api.AddObj(form);
|
const res = await api.AddObj(form);
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
const projectStore = useProjectStore();
|
||||||
const model = useModal();
|
const model = useModal();
|
||||||
return {
|
return {
|
||||||
crudOptions: {
|
crudOptions: {
|
||||||
@@ -37,6 +40,9 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
},
|
},
|
||||||
search: {
|
search: {
|
||||||
show: false,
|
show: false,
|
||||||
|
initialForm: {
|
||||||
|
...projectStore.getSearchForm(),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
form: {
|
form: {
|
||||||
labelCol: {
|
labelCol: {
|
||||||
@@ -163,6 +169,11 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
sorter: true,
|
sorter: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
projectId: {
|
||||||
|
title: t("certd.fields.projectName"),
|
||||||
|
type: "dict-select",
|
||||||
|
dict: myProjectDict,
|
||||||
|
},
|
||||||
createTime: {
|
createTime: {
|
||||||
title: t("certd.fields.createTime"),
|
title: t("certd.fields.createTime"),
|
||||||
type: "datetime",
|
type: "datetime",
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ import GroupSelector from "/@/views/certd/pipeline/group/group-selector.vue";
|
|||||||
import { statusUtil } from "/@/views/certd/pipeline/pipeline/utils/util.status";
|
import { statusUtil } from "/@/views/certd/pipeline/pipeline/utils/util.status";
|
||||||
import { useCertViewer } from "/@/views/certd/pipeline/use";
|
import { useCertViewer } from "/@/views/certd/pipeline/use";
|
||||||
import { useI18n } from "/src/locales";
|
import { useI18n } from "/src/locales";
|
||||||
import { projectDict } from "../dicts";
|
import { myProjectDict } from "../dicts";
|
||||||
|
import { useProjectStore } from "/@/store/project";
|
||||||
|
|
||||||
export default function ({ crudExpose, context: { selectedRowKeys, openCertApplyDialog } }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
export default function ({ crudExpose, context: { selectedRowKeys, openCertApplyDialog } }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -67,6 +68,8 @@ export default function ({ crudExpose, context: { selectedRowKeys, openCertApply
|
|||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const settingStore = useSettingStore();
|
const settingStore = useSettingStore();
|
||||||
|
|
||||||
|
const projectStore = useProjectStore();
|
||||||
|
|
||||||
const DEFAULT_WILL_EXPIRE_DAYS = settingStore.sysPublic.defaultWillExpireDays || settingStore.sysPublic.defaultCertRenewDays || 15;
|
const DEFAULT_WILL_EXPIRE_DAYS = settingStore.sysPublic.defaultWillExpireDays || settingStore.sysPublic.defaultCertRenewDays || 15;
|
||||||
|
|
||||||
function onDialogOpen(opt: any) {
|
function onDialogOpen(opt: any) {
|
||||||
@@ -148,7 +151,9 @@ export default function ({ crudExpose, context: { selectedRowKeys, openCertApply
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
search: {
|
search: {
|
||||||
col: { span: 3 },
|
initialForm: {
|
||||||
|
...projectStore.getSearchForm(),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
form: {
|
form: {
|
||||||
afterSubmit({ form, res, mode }) {
|
afterSubmit({ form, res, mode }) {
|
||||||
@@ -440,6 +445,7 @@ export default function ({ crudExpose, context: { selectedRowKeys, openCertApply
|
|||||||
type: "dict-select",
|
type: "dict-select",
|
||||||
search: {
|
search: {
|
||||||
show: true,
|
show: true,
|
||||||
|
col: { span: 2 },
|
||||||
},
|
},
|
||||||
dict: dict({
|
dict: dict({
|
||||||
data: statusUtil.getOptions(),
|
data: statusUtil.getOptions(),
|
||||||
@@ -532,6 +538,7 @@ export default function ({ crudExpose, context: { selectedRowKeys, openCertApply
|
|||||||
type: "dict-select",
|
type: "dict-select",
|
||||||
search: {
|
search: {
|
||||||
show: true,
|
show: true,
|
||||||
|
col: { span: 2 },
|
||||||
},
|
},
|
||||||
dict: dict({
|
dict: dict({
|
||||||
data: [
|
data: [
|
||||||
@@ -631,8 +638,8 @@ export default function ({ crudExpose, context: { selectedRowKeys, openCertApply
|
|||||||
},
|
},
|
||||||
projectId: {
|
projectId: {
|
||||||
title: t("certd.fields.projectName"),
|
title: t("certd.fields.projectName"),
|
||||||
type: "number",
|
type: "dict-select",
|
||||||
dict: projectDict,
|
dict: myProjectDict,
|
||||||
},
|
},
|
||||||
updateTime: {
|
updateTime: {
|
||||||
title: t("certd.fields.updateTime"),
|
title: t("certd.fields.updateTime"),
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { useI18n } from "/src/locales";
|
import { useI18n } from "/src/locales";
|
||||||
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||||
import { pipelineGroupApi } from "./api";
|
import { pipelineGroupApi } from "./api";
|
||||||
|
import { useProjectStore } from "/@/store/project";
|
||||||
|
import { myProjectDict } from "../../dicts";
|
||||||
|
|
||||||
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
@@ -25,6 +27,8 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const projectStore = useProjectStore();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
crudOptions: {
|
crudOptions: {
|
||||||
settings: {
|
settings: {
|
||||||
@@ -44,6 +48,11 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
editRequest,
|
editRequest,
|
||||||
delRequest,
|
delRequest,
|
||||||
},
|
},
|
||||||
|
search: {
|
||||||
|
initialForm: {
|
||||||
|
...projectStore.getSearchForm(),
|
||||||
|
},
|
||||||
|
},
|
||||||
form: {
|
form: {
|
||||||
labelCol: {
|
labelCol: {
|
||||||
//固定label宽度
|
//固定label宽度
|
||||||
@@ -127,6 +136,11 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
width: 400,
|
width: 400,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
projectId: {
|
||||||
|
title: t("certd.fields.projectName"),
|
||||||
|
type: "dict-select",
|
||||||
|
dict: myProjectDict,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import createCrudOptionsPipeline from "../crud";
|
|||||||
import * as pipelineApi from "../api";
|
import * as pipelineApi from "../api";
|
||||||
import { useTemplate } from "/@/views/certd/pipeline/template/use";
|
import { useTemplate } from "/@/views/certd/pipeline/template/use";
|
||||||
import { useI18n } from "/@/locales";
|
import { useI18n } from "/@/locales";
|
||||||
|
import { useProjectStore } from "/@/store/project";
|
||||||
|
import { myProjectDict } from "../../dicts";
|
||||||
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||||
const api = templateApi;
|
const api = templateApi;
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
@@ -28,6 +30,8 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
const res = await api.AddObj(form);
|
const res = await api.AddObj(form);
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const projectStore = useProjectStore();
|
||||||
const { openCrudFormDialog } = useFormWrapper();
|
const { openCrudFormDialog } = useFormWrapper();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
@@ -48,6 +52,11 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
router.push({ path: "/certd/pipeline/template/edit", query: { templateId: res.id, editMode: "true" } });
|
router.push({ path: "/certd/pipeline/template/edit", query: { templateId: res.id, editMode: "true" } });
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
search: {
|
||||||
|
initialForm: {
|
||||||
|
...projectStore.getSearchForm(),
|
||||||
|
},
|
||||||
|
},
|
||||||
form: {
|
form: {
|
||||||
labelCol: {
|
labelCol: {
|
||||||
//固定label宽度
|
//固定label宽度
|
||||||
@@ -232,6 +241,11 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
projectId: {
|
||||||
|
title: t("certd.fields.projectName"),
|
||||||
|
type: "dict-select",
|
||||||
|
dict: myProjectDict,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
import { request } from "/src/api/service";
|
||||||
|
|
||||||
|
const apiPrefix = "/enterprise/project";
|
||||||
|
|
||||||
|
export async function GetList(query: any) {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/list",
|
||||||
|
method: "post",
|
||||||
|
data: query,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function GetPage(query: any) {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/page",
|
||||||
|
method: "post",
|
||||||
|
data: query,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function AddObj(obj: any) {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/add",
|
||||||
|
method: "post",
|
||||||
|
data: obj,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function UpdateObj(obj: any) {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/update",
|
||||||
|
method: "post",
|
||||||
|
data: obj,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function DelObj(id: any) {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/delete",
|
||||||
|
method: "post",
|
||||||
|
params: { id },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function GetObj(id: any) {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/info",
|
||||||
|
method: "post",
|
||||||
|
params: { id },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function GetDetail(id: any) {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/detail",
|
||||||
|
method: "post",
|
||||||
|
params: { id },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function DeleteBatch(ids: any[]) {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/deleteByIds",
|
||||||
|
method: "post",
|
||||||
|
data: { ids },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function SetDisabled(id: any, disabled: boolean) {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/setDisabled",
|
||||||
|
method: "post",
|
||||||
|
data: { id, disabled },
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,165 @@
|
|||||||
|
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 { Modal } from "ant-design-vue";
|
||||||
|
import { userDict } from "../dicts";
|
||||||
|
|
||||||
|
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||||
|
const router = useRouter();
|
||||||
|
const { t } = useI18n();
|
||||||
|
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
||||||
|
const list = await api.GetList(query);
|
||||||
|
|
||||||
|
return {
|
||||||
|
records: list,
|
||||||
|
total: list.length,
|
||||||
|
offset: 0,
|
||||||
|
limit: 999,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
const editRequest = async ({ form, row }: EditReq) => {
|
||||||
|
form.id = row.id;
|
||||||
|
const res = await api.UpdateObj(form);
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
const delRequest = async ({ row }: DelReq) => {
|
||||||
|
return await api.DelObj(row.id);
|
||||||
|
};
|
||||||
|
|
||||||
|
const addRequest = async ({ form }: AddReq) => {
|
||||||
|
const res = await api.AddObj(form);
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
|
const userStore = useUserStore();
|
||||||
|
const settingStore = useSettingStore();
|
||||||
|
const selectedRowKeys: Ref<any[]> = ref([]);
|
||||||
|
context.selectedRowKeys = selectedRowKeys;
|
||||||
|
|
||||||
|
return {
|
||||||
|
crudOptions: {
|
||||||
|
settings: {
|
||||||
|
plugins: {
|
||||||
|
//这里使用行选择插件,生成行选择crudOptions配置,最终会与crudOptions合并
|
||||||
|
rowSelection: {
|
||||||
|
enabled: true,
|
||||||
|
order: -2,
|
||||||
|
before: true,
|
||||||
|
// handle: (pluginProps,useCrudProps)=>CrudOptions,
|
||||||
|
props: {
|
||||||
|
multiple: true,
|
||||||
|
crossPage: true,
|
||||||
|
selectedRowKeys,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
request: {
|
||||||
|
pageRequest,
|
||||||
|
addRequest,
|
||||||
|
editRequest,
|
||||||
|
delRequest,
|
||||||
|
},
|
||||||
|
rowHandle: {
|
||||||
|
minWidth: 200,
|
||||||
|
fixed: "right",
|
||||||
|
},
|
||||||
|
columns: {
|
||||||
|
id: {
|
||||||
|
title: "ID",
|
||||||
|
key: "id",
|
||||||
|
type: "number",
|
||||||
|
column: {
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
title: t("certd.ent.projectName"),
|
||||||
|
type: "link",
|
||||||
|
search: {
|
||||||
|
show: true,
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
component: {},
|
||||||
|
rules: [{ required: true, message: t("certd.requiredField") }],
|
||||||
|
},
|
||||||
|
column: {
|
||||||
|
width: 200,
|
||||||
|
cellRender({ row }) {
|
||||||
|
return <router-link to={{ path: `/certd/project/detail`, query: { projectId: row.id } }}>{row.name}</router-link>;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
title: t("certd.disabled"),
|
||||||
|
type: "dict-switch",
|
||||||
|
dict: dict({
|
||||||
|
data: [
|
||||||
|
{ label: t("certd.enabled"), value: false, color: "success" },
|
||||||
|
{ label: t("certd.disabledLabel"), value: true, color: "error" },
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
form: {
|
||||||
|
value: false,
|
||||||
|
},
|
||||||
|
column: {
|
||||||
|
width: 100,
|
||||||
|
component: {
|
||||||
|
title: t("certd.clickToToggle"),
|
||||||
|
on: {
|
||||||
|
async click({ value, row }) {
|
||||||
|
Modal.confirm({
|
||||||
|
title: t("certd.prompt"),
|
||||||
|
content: t("certd.confirmToggleStatus", { action: !value ? t("certd.disable") : t("certd.enable") }),
|
||||||
|
onOk: async () => {
|
||||||
|
await api.SetDisabled(row.id, !value);
|
||||||
|
await crudExpose.doRefresh();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
adminId: {
|
||||||
|
title: t("certd.fields.adminId"),
|
||||||
|
type: "dict-select",
|
||||||
|
dict: userDict,
|
||||||
|
column: {
|
||||||
|
width: 160,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
createTime: {
|
||||||
|
title: t("certd.createTime"),
|
||||||
|
type: "datetime",
|
||||||
|
form: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
column: {
|
||||||
|
sorter: true,
|
||||||
|
width: 160,
|
||||||
|
align: "center",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
updateTime: {
|
||||||
|
title: t("certd.updateTime"),
|
||||||
|
type: "datetime",
|
||||||
|
form: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
column: {
|
||||||
|
show: true,
|
||||||
|
width: 160,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
import { request } from "/src/api/service";
|
||||||
|
|
||||||
|
const apiPrefix = "/enterprise/myProjectMember";
|
||||||
|
const userApiPrefix = "/sys/authority/user";
|
||||||
|
export async function GetList(query: any) {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/page",
|
||||||
|
method: "post",
|
||||||
|
data: query,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function AddObj(obj: any) {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/add",
|
||||||
|
method: "post",
|
||||||
|
data: obj,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function UpdateObj(obj: any) {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/update",
|
||||||
|
method: "post",
|
||||||
|
data: obj,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function DelObj(id: any) {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/delete",
|
||||||
|
method: "post",
|
||||||
|
params: { id },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function GetObj(id: any) {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/info",
|
||||||
|
method: "post",
|
||||||
|
params: { id },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function GetDetail(id: any) {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/detail",
|
||||||
|
method: "post",
|
||||||
|
params: { id },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function DeleteBatch(ids: any[]) {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/deleteByIds",
|
||||||
|
method: "post",
|
||||||
|
data: { ids },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function GetUserSimpleByIds(query: any) {
|
||||||
|
return await request({
|
||||||
|
url: userApiPrefix + "/getSimpleByIds",
|
||||||
|
method: "post",
|
||||||
|
data: query,
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,162 @@
|
|||||||
|
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 * as api from "./api";
|
||||||
|
import { useSettingStore } from "/@/store/settings";
|
||||||
|
import { useUserStore } from "/@/store/user";
|
||||||
|
import { useI18n } from "/src/locales";
|
||||||
|
import { userDict } from "../../dicts";
|
||||||
|
|
||||||
|
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||||
|
const router = useRouter();
|
||||||
|
const { t } = useI18n();
|
||||||
|
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
||||||
|
return await api.GetList(query);
|
||||||
|
};
|
||||||
|
const editRequest = async ({ form, row }: EditReq) => {
|
||||||
|
form.id = row.id;
|
||||||
|
const res = await api.UpdateObj(form);
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
const delRequest = async ({ row }: DelReq) => {
|
||||||
|
return await api.DelObj(row.id);
|
||||||
|
};
|
||||||
|
|
||||||
|
const addRequest = async ({ form }: AddReq) => {
|
||||||
|
const res = await api.AddObj(form);
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
|
const projectId = context.projectId;
|
||||||
|
|
||||||
|
const userStore = useUserStore();
|
||||||
|
const settingStore = useSettingStore();
|
||||||
|
const selectedRowKeys: Ref<any[]> = ref([]);
|
||||||
|
context.selectedRowKeys = selectedRowKeys;
|
||||||
|
|
||||||
|
return {
|
||||||
|
crudOptions: {
|
||||||
|
settings: {
|
||||||
|
plugins: {
|
||||||
|
//这里使用行选择插件,生成行选择crudOptions配置,最终会与crudOptions合并
|
||||||
|
rowSelection: {
|
||||||
|
enabled: true,
|
||||||
|
order: -2,
|
||||||
|
before: true,
|
||||||
|
// handle: (pluginProps,useCrudProps)=>CrudOptions,
|
||||||
|
props: {
|
||||||
|
multiple: true,
|
||||||
|
crossPage: true,
|
||||||
|
selectedRowKeys,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
request: {
|
||||||
|
pageRequest,
|
||||||
|
addRequest,
|
||||||
|
editRequest,
|
||||||
|
delRequest,
|
||||||
|
},
|
||||||
|
rowHandle: {
|
||||||
|
minWidth: 200,
|
||||||
|
fixed: "right",
|
||||||
|
},
|
||||||
|
search: {
|
||||||
|
initialForm: {
|
||||||
|
projectId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
columns: {
|
||||||
|
id: {
|
||||||
|
title: "ID",
|
||||||
|
key: "id",
|
||||||
|
type: "number",
|
||||||
|
column: {
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
projectId: {
|
||||||
|
title: "项目ID",
|
||||||
|
type: "text",
|
||||||
|
search: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
value: projectId,
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
editForm: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
column: {
|
||||||
|
width: 200,
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
userId: {
|
||||||
|
title: "用户",
|
||||||
|
type: "dict-select",
|
||||||
|
dict: userDict,
|
||||||
|
search: {
|
||||||
|
show: true,
|
||||||
|
},
|
||||||
|
form: {},
|
||||||
|
editForm: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
column: {
|
||||||
|
width: 200,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
permission: {
|
||||||
|
title: t("certd.ent.projectPermission"),
|
||||||
|
type: "dict-select",
|
||||||
|
dict: dict({
|
||||||
|
data: [
|
||||||
|
{ label: t("certd.ent.permission.read"), value: "read", color: "cyan" },
|
||||||
|
{ label: t("certd.ent.permission.write"), value: "write", color: "blue" },
|
||||||
|
{ label: t("certd.ent.permission.admin"), value: "admin", color: "green" },
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
search: {
|
||||||
|
show: true,
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
show: true,
|
||||||
|
},
|
||||||
|
column: {
|
||||||
|
width: 200,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
createTime: {
|
||||||
|
title: t("certd.createTime"),
|
||||||
|
type: "datetime",
|
||||||
|
form: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
column: {
|
||||||
|
sorter: true,
|
||||||
|
width: 160,
|
||||||
|
align: "center",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
updateTime: {
|
||||||
|
title: t("certd.updateTime"),
|
||||||
|
type: "datetime",
|
||||||
|
form: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
column: {
|
||||||
|
show: true,
|
||||||
|
width: 160,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
<template>
|
||||||
|
<fs-page class="page-project-detail">
|
||||||
|
<template #header>
|
||||||
|
<div class="title">
|
||||||
|
{{ t("certd.ent.projectDetailManager") }}
|
||||||
|
<span class="sub">
|
||||||
|
{{ t("certd.ent.projectDetailDescription") }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<fs-crud ref="crudRef" v-bind="crudBinding">
|
||||||
|
<template #pagination-left>
|
||||||
|
<a-tooltip :title="t('certd.batchDelete')">
|
||||||
|
<fs-button icon="DeleteOutlined" @click="handleBatchDelete"></fs-button>
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
</fs-crud>
|
||||||
|
</fs-page>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { onActivated, onMounted } from "vue";
|
||||||
|
import { useFs } from "@fast-crud/fast-crud";
|
||||||
|
import createCrudOptions from "./crud";
|
||||||
|
import { message, Modal } from "ant-design-vue";
|
||||||
|
import { DeleteBatch } from "./api";
|
||||||
|
import { useI18n } from "/src/locales";
|
||||||
|
import { useRoute } from "vue-router";
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: "ProjectDetail",
|
||||||
|
});
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
const projectIdStr = route.query.projectId as string;
|
||||||
|
const projectId = Number(projectIdStr);
|
||||||
|
|
||||||
|
const context: any = {
|
||||||
|
projectId,
|
||||||
|
};
|
||||||
|
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context });
|
||||||
|
|
||||||
|
const selectedRowKeys = context.selectedRowKeys;
|
||||||
|
const handleBatchDelete = () => {
|
||||||
|
if (selectedRowKeys.value?.length > 0) {
|
||||||
|
Modal.confirm({
|
||||||
|
title: t("certd.confirmTitle"),
|
||||||
|
content: t("certd.confirmDeleteBatch", { count: selectedRowKeys.value.length }),
|
||||||
|
async onOk() {
|
||||||
|
await DeleteBatch(selectedRowKeys.value);
|
||||||
|
message.info(t("certd.deleteSuccess"));
|
||||||
|
crudExpose.doRefresh();
|
||||||
|
selectedRowKeys.value = [];
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
message.error(t("certd.selectRecordsFirst"));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 页面打开后获取列表数据
|
||||||
|
onMounted(() => {
|
||||||
|
crudExpose.doRefresh();
|
||||||
|
});
|
||||||
|
onActivated(async () => {
|
||||||
|
await crudExpose.doRefresh();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style lang="less"></style>
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
<template>
|
||||||
|
<fs-page class="page-cert">
|
||||||
|
<template #header>
|
||||||
|
<div class="title">
|
||||||
|
{{ t("certd.sysResources.myProjectManager") }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<fs-crud ref="crudRef" v-bind="crudBinding">
|
||||||
|
<!-- <div v-if="crudBinding.data" class="project-list">
|
||||||
|
<div v-for="item of crudBinding.data" :key="item.id" class="project-item">
|
||||||
|
<a-card style="width: 300px">
|
||||||
|
<p>{{ item.name }}</p>
|
||||||
|
</a-card>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
</fs-crud>
|
||||||
|
</fs-page>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { onActivated, onMounted } from "vue";
|
||||||
|
import { useFs } from "@fast-crud/fast-crud";
|
||||||
|
import createCrudOptions from "./crud";
|
||||||
|
import { message, Modal } from "ant-design-vue";
|
||||||
|
import { DeleteBatch } from "./api";
|
||||||
|
import { useI18n } from "/src/locales";
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: "MyProjectManager",
|
||||||
|
});
|
||||||
|
const { crudBinding, crudRef, crudExpose, context } = useFs({ createCrudOptions });
|
||||||
|
|
||||||
|
const selectedRowKeys = context.selectedRowKeys;
|
||||||
|
const handleBatchDelete = () => {
|
||||||
|
if (selectedRowKeys.value?.length > 0) {
|
||||||
|
Modal.confirm({
|
||||||
|
title: t("certd.confirmTitle"),
|
||||||
|
content: t("certd.confirmDeleteBatch", { count: selectedRowKeys.value.length }),
|
||||||
|
async onOk() {
|
||||||
|
await DeleteBatch(selectedRowKeys.value);
|
||||||
|
message.info(t("certd.deleteSuccess"));
|
||||||
|
crudExpose.doRefresh();
|
||||||
|
selectedRowKeys.value = [];
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
message.error(t("certd.selectRecordsFirst"));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 页面打开后获取列表数据
|
||||||
|
onMounted(() => {
|
||||||
|
crudExpose.doRefresh();
|
||||||
|
});
|
||||||
|
onActivated(async () => {
|
||||||
|
await crudExpose.doRefresh();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style lang="less"></style>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import { dict } from "@fast-crud/fast-crud";
|
||||||
|
|
||||||
|
export const userDict = dict({
|
||||||
|
url: "/sys/authority/user/getSimpleUsers",
|
||||||
|
value: "id",
|
||||||
|
onReady: ({ dict }) => {
|
||||||
|
for (const item of dict.data) {
|
||||||
|
item.label = item.nickName || item.username || item.phoneCode + item.mobile;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -6,6 +6,7 @@ import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq,
|
|||||||
import { useUserStore } from "/@/store/user";
|
import { useUserStore } from "/@/store/user";
|
||||||
import { useSettingStore } from "/@/store/settings";
|
import { useSettingStore } from "/@/store/settings";
|
||||||
import { Modal } from "ant-design-vue";
|
import { Modal } from "ant-design-vue";
|
||||||
|
import { userDict } from "../dicts";
|
||||||
|
|
||||||
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -80,17 +81,12 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
},
|
},
|
||||||
form: {
|
form: {
|
||||||
component: {},
|
component: {},
|
||||||
helper: t("certd.ent.projectNameHelper"),
|
|
||||||
rules: [{ required: true, message: t("certd.requiredField") }],
|
rules: [{ required: true, message: t("certd.requiredField") }],
|
||||||
},
|
},
|
||||||
column: {
|
column: {
|
||||||
width: 200,
|
width: 200,
|
||||||
cellRender({ row }) {
|
cellRender({ row }) {
|
||||||
return (
|
return <router-link to={{ path: `/sys/enterprise/project/detail`, query: { projectId: row.id } }}>{row.name}</router-link>;
|
||||||
<router-link to={`/sys/enterprise/project/detail`} query={{ projectId: row.id }}>
|
|
||||||
{row.name}
|
|
||||||
</router-link>
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -125,6 +121,14 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
adminId: {
|
||||||
|
title: t("certd.fields.adminId"),
|
||||||
|
type: "dict-select",
|
||||||
|
dict: userDict,
|
||||||
|
column: {
|
||||||
|
width: 160,
|
||||||
|
},
|
||||||
|
},
|
||||||
createTime: {
|
createTime: {
|
||||||
title: t("certd.createTime"),
|
title: t("certd.createTime"),
|
||||||
type: "datetime",
|
type: "datetime",
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import * as api from "./api";
|
|||||||
import { useSettingStore } from "/@/store/settings";
|
import { useSettingStore } from "/@/store/settings";
|
||||||
import { useUserStore } from "/@/store/user";
|
import { useUserStore } from "/@/store/user";
|
||||||
import { useI18n } from "/src/locales";
|
import { useI18n } from "/src/locales";
|
||||||
|
import { userDict } from "../../dicts";
|
||||||
|
|
||||||
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -27,6 +28,8 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const projectId = context.projectId;
|
||||||
|
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const settingStore = useSettingStore();
|
const settingStore = useSettingStore();
|
||||||
const selectedRowKeys: Ref<any[]> = ref([]);
|
const selectedRowKeys: Ref<any[]> = ref([]);
|
||||||
@@ -60,6 +63,11 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
minWidth: 200,
|
minWidth: 200,
|
||||||
fixed: "right",
|
fixed: "right",
|
||||||
},
|
},
|
||||||
|
search: {
|
||||||
|
initialForm: {
|
||||||
|
projectId,
|
||||||
|
},
|
||||||
|
},
|
||||||
columns: {
|
columns: {
|
||||||
id: {
|
id: {
|
||||||
title: "ID",
|
title: "ID",
|
||||||
@@ -79,6 +87,10 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
show: false,
|
show: false,
|
||||||
},
|
},
|
||||||
form: {
|
form: {
|
||||||
|
value: projectId,
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
editForm: {
|
||||||
show: false,
|
show: false,
|
||||||
},
|
},
|
||||||
column: {
|
column: {
|
||||||
@@ -87,23 +99,18 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
userId: {
|
userId: {
|
||||||
title: "用户ID",
|
title: "用户",
|
||||||
type: "dict-select",
|
type: "dict-select",
|
||||||
dict: dict({
|
dict: userDict,
|
||||||
url: "/sys/authority/user/getSimpleUsers",
|
|
||||||
value: "id",
|
|
||||||
label: "nickName",
|
|
||||||
labelBuilder: (item: any) => item.nickName || item.username || item.phoneCode + item.mobile,
|
|
||||||
}),
|
|
||||||
search: {
|
search: {
|
||||||
show: false,
|
show: true,
|
||||||
},
|
},
|
||||||
form: {
|
form: {},
|
||||||
|
editForm: {
|
||||||
show: false,
|
show: false,
|
||||||
},
|
},
|
||||||
column: {
|
column: {
|
||||||
width: 200,
|
width: 200,
|
||||||
show: false,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
permission: {
|
permission: {
|
||||||
@@ -111,9 +118,9 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||||||
type: "dict-select",
|
type: "dict-select",
|
||||||
dict: dict({
|
dict: dict({
|
||||||
data: [
|
data: [
|
||||||
{ label: t("certd.read"), value: "read", color: "cyan" },
|
{ label: t("certd.ent.permission.read"), value: "read", color: "cyan" },
|
||||||
{ label: t("certd.write"), value: "write", color: "blue" },
|
{ label: t("certd.ent.permission.write"), value: "write", color: "blue" },
|
||||||
{ label: t("certd.admin"), value: "admin", color: "green" },
|
{ label: t("certd.ent.permission.admin"), value: "admin", color: "green" },
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
search: {
|
search: {
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<fs-page class="page-project-member">
|
<fs-page class="page-project-detail">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="title">
|
<div class="title">
|
||||||
{{ t("certd.projectMemberManager") }}
|
{{ t("certd.ent.projectDetailManager") }}
|
||||||
<span class="sub">
|
<span class="sub">
|
||||||
{{ t("certd.projectMemberDescription") }}
|
{{ t("certd.ent.projectDetailDescription") }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -30,7 +30,7 @@ import { useRoute } from "vue-router";
|
|||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "ProjectMemberManager",
|
name: "ProjectDetail",
|
||||||
});
|
});
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
<a-tab-pane key="network" :tab="t('certd.sys.setting.networkSetting')">
|
<a-tab-pane key="network" :tab="t('certd.sys.setting.networkSetting')">
|
||||||
<SettingNetwork v-if="activeKey === 'network'" />
|
<SettingNetwork v-if="activeKey === 'network'" />
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
<a-tab-pane key="mode" :tab="t('certd.adminMode')">
|
<a-tab-pane key="mode" :tab="t('certd.sys.setting.adminModeSetting')">
|
||||||
<SettingMode v-if="activeKey === 'mode'" />
|
<SettingMode v-if="activeKey === 'mode'" />
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sys-settings-form sys-settings-mode">
|
<div class="sys-settings-form sys-settings-mode">
|
||||||
<a-form :model="formState" name="basic" :label-col="{ span: 8 }" :wrapper-col="{ span: 16 }" autocomplete="off" @finish="onFinish">
|
<a-form :model="formState" name="basic" :label-col="{ span: 8 }" :wrapper-col="{ span: 16 }" autocomplete="off" @finish="onFinish">
|
||||||
<a-form-item :label="t('certd.adminMode')" :name="['public', 'adminMode']">
|
<a-form-item :label="t('certd.sys.setting.adminMode')" :name="['public', 'adminMode']">
|
||||||
<fs-dict-radio v-model:value="formState.public.adminMode" :dict="adminModeDict" />
|
<fs-dict-radio v-model:value="formState.public.adminMode" :dict="adminModeDict" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
||||||
@@ -30,11 +30,11 @@ defineOptions({
|
|||||||
const adminModeDict = dict({
|
const adminModeDict = dict({
|
||||||
data: [
|
data: [
|
||||||
{
|
{
|
||||||
label: t("certd.adminMode.enterpriseMode"),
|
label: t("certd.sys.setting.enterpriseMode"),
|
||||||
value: "enterprise",
|
value: "enterprise",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t("certd.adminMode.saasMode"),
|
label: t("certd.sys.setting.saasMode"),
|
||||||
value: "saas",
|
value: "saas",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ CREATE TABLE "cd_project"
|
|||||||
"id" integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
"id" integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||||
"user_id" integer NOT NULL,
|
"user_id" integer NOT NULL,
|
||||||
"name" varchar(512) NOT NULL,
|
"name" varchar(512) NOT NULL,
|
||||||
|
"admin_id" integer NOT NULL,
|
||||||
"disabled" boolean NOT NULL DEFAULT (false),
|
"disabled" boolean NOT NULL DEFAULT (false),
|
||||||
"create_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
"create_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||||
"update_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP)
|
"update_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP)
|
||||||
@@ -11,6 +12,7 @@ CREATE TABLE "cd_project"
|
|||||||
|
|
||||||
|
|
||||||
CREATE INDEX "index_project_user_id" ON "cd_project" ("user_id");
|
CREATE INDEX "index_project_user_id" ON "cd_project" ("user_id");
|
||||||
|
CREATE INDEX "index_project_admin_id" ON "cd_project" ("admin_id");
|
||||||
INSERT INTO cd_project (id, user_id, "name", "disabled") VALUES (1, 1, 'default', false);
|
INSERT INTO cd_project (id, user_id, "name", "disabled") VALUES (1, 1, 'default', false);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,11 @@ export class SysProjectController extends CrudController<ProjectEntity> {
|
|||||||
};
|
};
|
||||||
merge(bean, def);
|
merge(bean, def);
|
||||||
bean.userId = this.getUserId();
|
bean.userId = this.getUserId();
|
||||||
return super.add(bean);
|
return super.add({
|
||||||
|
...bean,
|
||||||
|
userId:0,
|
||||||
|
adminId: bean.userId,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post("/update", { summary: "sys:settings:edit" })
|
@Post("/update", { summary: "sys:settings:edit" })
|
||||||
|
|||||||
+51
-5
@@ -3,6 +3,7 @@ import { ALL, Body, Controller, Inject, Post, Provide, Query } from "@midwayjs/c
|
|||||||
import { ProjectMemberEntity } from "../../../modules/sys/enterprise/entity/project-member.js";
|
import { ProjectMemberEntity } from "../../../modules/sys/enterprise/entity/project-member.js";
|
||||||
import { ProjectMemberService } from "../../../modules/sys/enterprise/service/project-member-service.js";
|
import { ProjectMemberService } from "../../../modules/sys/enterprise/service/project-member-service.js";
|
||||||
import { merge } from "lodash-es";
|
import { merge } from "lodash-es";
|
||||||
|
import { ProjectService } from "../../../modules/sys/enterprise/service/project-service.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
@@ -15,6 +16,9 @@ export class SysProjectMemberController extends CrudController<ProjectMemberEnti
|
|||||||
@Inject()
|
@Inject()
|
||||||
sysSettingsService: SysSettingsService;
|
sysSettingsService: SysSettingsService;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
projectService: ProjectService;
|
||||||
|
|
||||||
getService<T>() {
|
getService<T>() {
|
||||||
return this.service;
|
return this.service;
|
||||||
}
|
}
|
||||||
@@ -37,29 +41,71 @@ export class SysProjectMemberController extends CrudController<ProjectMemberEnti
|
|||||||
disabled: false,
|
disabled: false,
|
||||||
};
|
};
|
||||||
merge(bean, def);
|
merge(bean, def);
|
||||||
bean.userId = this.getUserId();
|
|
||||||
|
await this.projectService.checkAdminPermission({
|
||||||
|
userId: this.getUserId(),
|
||||||
|
projectId: bean.projectId,
|
||||||
|
});
|
||||||
|
|
||||||
return super.add(bean);
|
return super.add(bean);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post("/update", { summary: "sys:settings:edit" })
|
@Post("/update", { summary: "sys:settings:edit" })
|
||||||
async update(@Body(ALL) bean: any) {
|
async update(@Body(ALL) bean: any) {
|
||||||
bean.userId = this.getUserId();
|
if (!bean.id) {
|
||||||
return super.update(bean);
|
throw new Error("id is required");
|
||||||
|
}
|
||||||
|
const projectId = await this.service.getProjectId(bean.id)
|
||||||
|
await this.projectService.checkAdminPermission({
|
||||||
|
userId: this.getUserId(),
|
||||||
|
projectId: projectId,
|
||||||
|
});
|
||||||
|
return super.update({
|
||||||
|
id: bean.id,
|
||||||
|
permission: bean.permission,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post("/info", { summary: "sys:settings:view" })
|
@Post("/info", { summary: "sys:settings:view" })
|
||||||
async info(@Query("id") id: number) {
|
async info(@Query("id") id: number) {
|
||||||
|
if (!id) {
|
||||||
|
throw new Error("id is required");
|
||||||
|
}
|
||||||
|
const projectId = await this.service.getProjectId(id)
|
||||||
|
await this.projectService.checkReadPermission({
|
||||||
|
userId: this.getUserId(),
|
||||||
|
projectId:projectId,
|
||||||
|
});
|
||||||
return super.info(id);
|
return super.info(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post("/delete", { summary: "sys:settings:edit" })
|
@Post("/delete", { summary: "sys:settings:edit" })
|
||||||
async delete(@Query("id") id: number) {
|
async delete(@Query("id") id: number) {
|
||||||
|
if (!id) {
|
||||||
|
throw new Error("id is required");
|
||||||
|
}
|
||||||
|
const projectId = await this.service.getProjectId(id)
|
||||||
|
await this.projectService.checkAdminPermission({
|
||||||
|
userId: this.getUserId(),
|
||||||
|
projectId:projectId,
|
||||||
|
});
|
||||||
return super.delete(id);
|
return super.delete(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post("/deleteByIds", { summary: "sys:settings:edit" })
|
@Post("/deleteByIds", { summary: "sys:settings:edit" })
|
||||||
async deleteByIds(@Body("ids") ids: number[]) {
|
async deleteByIds(@Body("ids") ids: number[]) {
|
||||||
const res = await this.service.delete(ids);
|
for (const id of ids) {
|
||||||
return this.ok(res);
|
if (!id) {
|
||||||
|
throw new Error("id is required");
|
||||||
|
}
|
||||||
|
const projectId = await this.service.getProjectId(id)
|
||||||
|
await this.projectService.checkAdminPermission({
|
||||||
|
userId: this.getUserId(),
|
||||||
|
projectId:projectId,
|
||||||
|
});
|
||||||
|
await this.service.delete(id as any);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.ok({});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export class UserProjectController extends BaseController {
|
|||||||
@Post('/list', { summary: Constants.per.authOnly })
|
@Post('/list', { summary: Constants.per.authOnly })
|
||||||
async list(@Body(ALL) body: any) {
|
async list(@Body(ALL) body: any) {
|
||||||
const userId= this.getUserId();
|
const userId= this.getUserId();
|
||||||
const res = await this.service.getByUserId(userId);
|
const res = await this.service.getUserProjects(userId);
|
||||||
return this.ok(res);
|
return this.ok(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
|
|
||||||
import { Constants, CrudController, SysSettingsService } from '@certd/lib-server';
|
import { Constants, CrudController, SysSettingsService } from '@certd/lib-server';
|
||||||
import { PipelineService } from '../../../modules/pipeline/service/pipeline-service.js';
|
import { isPlus } from '@certd/plus-core';
|
||||||
|
import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
|
||||||
|
import { SiteInfoService } from '../../../modules/monitor/index.js';
|
||||||
import { PipelineEntity } from '../../../modules/pipeline/entity/pipeline.js';
|
import { PipelineEntity } from '../../../modules/pipeline/entity/pipeline.js';
|
||||||
import { HistoryService } from '../../../modules/pipeline/service/history-service.js';
|
import { HistoryService } from '../../../modules/pipeline/service/history-service.js';
|
||||||
|
import { PipelineService } from '../../../modules/pipeline/service/pipeline-service.js';
|
||||||
import { AuthService } from '../../../modules/sys/authority/service/auth-service.js';
|
import { AuthService } from '../../../modules/sys/authority/service/auth-service.js';
|
||||||
import { SiteInfoService } from '../../../modules/monitor/index.js';
|
|
||||||
import { isPlus } from '@certd/plus-core';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 证书
|
* 证书
|
||||||
@@ -25,6 +25,7 @@ export class PipelineController extends CrudController<PipelineService> {
|
|||||||
@Inject()
|
@Inject()
|
||||||
siteInfoService: SiteInfoService;
|
siteInfoService: SiteInfoService;
|
||||||
|
|
||||||
|
|
||||||
getService() {
|
getService() {
|
||||||
return this.service;
|
return this.service;
|
||||||
}
|
}
|
||||||
@@ -34,6 +35,8 @@ export class PipelineController extends CrudController<PipelineService> {
|
|||||||
const isAdmin = await this.authService.isAdmin(this.ctx);
|
const isAdmin = await this.authService.isAdmin(this.ctx);
|
||||||
const publicSettings = await this.sysSettingsService.getPublicSettings();
|
const publicSettings = await this.sysSettingsService.getPublicSettings();
|
||||||
|
|
||||||
|
const { projectId, userId } = await this.getProjectUserIdRead()
|
||||||
|
body.query.projectId = projectId
|
||||||
let onlyOther = false
|
let onlyOther = false
|
||||||
if (isAdmin) {
|
if (isAdmin) {
|
||||||
if (publicSettings.managerOtherUserPipeline) {
|
if (publicSettings.managerOtherUserPipeline) {
|
||||||
@@ -44,10 +47,10 @@ export class PipelineController extends CrudController<PipelineService> {
|
|||||||
delete body.query.userId;
|
delete body.query.userId;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
body.query.userId = this.getUserId();
|
body.query.userId = userId;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
body.query.userId = this.getUserId();
|
body.query.userId = userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
const title = body.query.title;
|
const title = body.query.title;
|
||||||
@@ -76,30 +79,43 @@ export class PipelineController extends CrudController<PipelineService> {
|
|||||||
|
|
||||||
@Post('/getSimpleByIds', { summary: Constants.per.authOnly })
|
@Post('/getSimpleByIds', { summary: Constants.per.authOnly })
|
||||||
async getSimpleById(@Body(ALL) body) {
|
async getSimpleById(@Body(ALL) body) {
|
||||||
const ret = await this.getService().getSimplePipelines(body.ids, this.getUserId());
|
const { projectId, userId } = await this.getProjectUserIdRead()
|
||||||
|
const ret = await this.getService().getSimplePipelines(body.ids, userId, projectId);
|
||||||
return this.ok(ret);
|
return this.ok(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Post('/add', { summary: Constants.per.authOnly })
|
@Post('/add', { summary: Constants.per.authOnly })
|
||||||
async add(@Body(ALL) bean: PipelineEntity) {
|
async add(@Body(ALL) bean: PipelineEntity) {
|
||||||
bean.userId = this.getUserId();
|
const { projectId, userId } = await this.getProjectUserIdWrite()
|
||||||
|
bean.userId = userId
|
||||||
|
bean.projectId = projectId
|
||||||
return super.add(bean);
|
return super.add(bean);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('/update', { summary: Constants.per.authOnly })
|
@Post('/update', { summary: Constants.per.authOnly })
|
||||||
async update(@Body(ALL) bean) {
|
async update(@Body(ALL) bean) {
|
||||||
await this.authService.checkEntityUserId(this.ctx, this.getService(), bean.id);
|
const { projectId } = await this.getProjectUserIdWrite()
|
||||||
|
if (projectId) {
|
||||||
|
await this.authService.checkEntityProjectId(this.getService(), projectId, bean.id);
|
||||||
|
} else {
|
||||||
|
await this.authService.checkEntityUserId(this.ctx, this.getService(), bean.id);
|
||||||
|
}
|
||||||
delete bean.userId;
|
delete bean.userId;
|
||||||
return super.update(bean);
|
return super.update(bean);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('/save', { summary: Constants.per.authOnly })
|
@Post('/save', { summary: Constants.per.authOnly })
|
||||||
async save(@Body(ALL) bean: { addToMonitorEnabled: boolean, addToMonitorDomains: string } & PipelineEntity) {
|
async save(@Body(ALL) bean: { addToMonitorEnabled: boolean, addToMonitorDomains: string } & PipelineEntity) {
|
||||||
|
const { projectId, userId } = await this.getProjectUserIdWrite()
|
||||||
if (bean.id > 0) {
|
if (bean.id > 0) {
|
||||||
await this.authService.checkEntityUserId(this.ctx, this.getService(), bean.id);
|
if (projectId) {
|
||||||
|
await this.authService.checkEntityProjectId(this.getService(), projectId, bean.id);
|
||||||
|
} else {
|
||||||
|
await this.authService.checkEntityUserId(this.ctx, this.getService(), bean.id);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
bean.userId = this.getUserId();
|
bean.userId = userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.isAdmin()) {
|
if (!this.isAdmin()) {
|
||||||
@@ -115,7 +131,7 @@ export class PipelineController extends CrudController<PipelineService> {
|
|||||||
//增加证书监控
|
//增加证书监控
|
||||||
await this.siteInfoService.doImport({
|
await this.siteInfoService.doImport({
|
||||||
text: bean.addToMonitorDomains,
|
text: bean.addToMonitorDomains,
|
||||||
userId: this.getUserId(),
|
userId: userId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -124,14 +140,24 @@ export class PipelineController extends CrudController<PipelineService> {
|
|||||||
|
|
||||||
@Post('/delete', { summary: Constants.per.authOnly })
|
@Post('/delete', { summary: Constants.per.authOnly })
|
||||||
async delete(@Query('id') id: number) {
|
async delete(@Query('id') id: number) {
|
||||||
await this.authService.checkEntityUserId(this.ctx, this.getService(), id);
|
const { projectId } = await this.getProjectUserIdWrite()
|
||||||
|
if (projectId) {
|
||||||
|
await this.authService.checkEntityProjectId(this.getService(), projectId, id);
|
||||||
|
} else {
|
||||||
|
await this.authService.checkEntityUserId(this.ctx, this.getService(), id);
|
||||||
|
}
|
||||||
await this.service.delete(id);
|
await this.service.delete(id);
|
||||||
return this.ok({});
|
return this.ok({});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('/disabled', { summary: Constants.per.authOnly })
|
@Post('/disabled', { summary: Constants.per.authOnly })
|
||||||
async disabled(@Body(ALL) bean) {
|
async disabled(@Body(ALL) bean) {
|
||||||
await this.authService.checkEntityUserId(this.ctx, this.getService(), bean.id);
|
const { projectId } = await this.getProjectUserIdWrite()
|
||||||
|
if (projectId) {
|
||||||
|
await this.authService.checkEntityProjectId(this.getService(), projectId, bean.id);
|
||||||
|
} else {
|
||||||
|
await this.authService.checkEntityUserId(this.ctx, this.getService(), bean.id);
|
||||||
|
}
|
||||||
delete bean.userId;
|
delete bean.userId;
|
||||||
await this.service.disabled(bean.id, bean.disabled);
|
await this.service.disabled(bean.id, bean.disabled);
|
||||||
return this.ok({});
|
return this.ok({});
|
||||||
@@ -139,75 +165,140 @@ export class PipelineController extends CrudController<PipelineService> {
|
|||||||
|
|
||||||
@Post('/detail', { summary: Constants.per.authOnly })
|
@Post('/detail', { summary: Constants.per.authOnly })
|
||||||
async detail(@Query('id') id: number) {
|
async detail(@Query('id') id: number) {
|
||||||
await this.authService.checkEntityUserId(this.ctx, this.getService(), id);
|
const { projectId } = await this.getProjectUserIdRead()
|
||||||
|
if (projectId) {
|
||||||
|
await this.authService.checkEntityProjectId(this.getService(), projectId, id);
|
||||||
|
} else {
|
||||||
|
await this.authService.checkEntityUserId(this.ctx, this.getService(), id);
|
||||||
|
}
|
||||||
const detail = await this.service.detail(id);
|
const detail = await this.service.detail(id);
|
||||||
return this.ok(detail);
|
return this.ok(detail);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('/trigger', { summary: Constants.per.authOnly })
|
@Post('/trigger', { summary: Constants.per.authOnly })
|
||||||
async trigger(@Query('id') id: number, @Query('stepId') stepId?: string) {
|
async trigger(@Query('id') id: number, @Query('stepId') stepId?: string) {
|
||||||
await this.authService.checkEntityUserId(this.ctx, this.getService(), id);
|
const { projectId } = await this.getProjectUserIdWrite()
|
||||||
|
if (projectId) {
|
||||||
|
await this.authService.checkEntityProjectId(this.getService(), projectId, id);
|
||||||
|
} else {
|
||||||
|
await this.authService.checkEntityUserId(this.ctx, this.getService(), id);
|
||||||
|
}
|
||||||
await this.service.trigger(id, stepId, true);
|
await this.service.trigger(id, stepId, true);
|
||||||
return this.ok({});
|
return this.ok({});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('/cancel', { summary: Constants.per.authOnly })
|
@Post('/cancel', { summary: Constants.per.authOnly })
|
||||||
async cancel(@Query('historyId') historyId: number) {
|
async cancel(@Query('historyId') historyId: number) {
|
||||||
await this.authService.checkEntityUserId(this.ctx, this.historyService, historyId);
|
const { projectId } = await this.getProjectUserIdWrite()
|
||||||
|
if (projectId) {
|
||||||
|
await this.authService.checkEntityProjectId(this.historyService, projectId, historyId);
|
||||||
|
} else {
|
||||||
|
await this.authService.checkEntityUserId(this.ctx, this.historyService, historyId);
|
||||||
|
}
|
||||||
await this.service.cancel(historyId);
|
await this.service.cancel(historyId);
|
||||||
return this.ok({});
|
return this.ok({});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('/count', { summary: Constants.per.authOnly })
|
@Post('/count', { summary: Constants.per.authOnly })
|
||||||
async count() {
|
async count() {
|
||||||
const count = await this.service.count({ userId: this.getUserId() });
|
const { userId } = await this.getProjectUserIdRead()
|
||||||
|
const count = await this.service.count({ userId: userId });
|
||||||
return this.ok({ count });
|
return this.ok({ count });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private async checkPermissionCall(callback:any){
|
||||||
|
let { projectId ,userId} = await this.getProjectUserIdWrite()
|
||||||
|
if(projectId){
|
||||||
|
return await callback({userId,projectId});
|
||||||
|
}
|
||||||
|
const isAdmin = await this.authService.isAdmin(this.ctx);
|
||||||
|
userId = isAdmin ? undefined : userId;
|
||||||
|
return await callback({userId});
|
||||||
|
}
|
||||||
|
|
||||||
@Post('/batchDelete', { summary: Constants.per.authOnly })
|
@Post('/batchDelete', { summary: Constants.per.authOnly })
|
||||||
async batchDelete(@Body('ids') ids: number[]) {
|
async batchDelete(@Body('ids') ids: number[]) {
|
||||||
const isAdmin = await this.authService.isAdmin(this.ctx);
|
// let { projectId ,userId} = await this.getProjectUserIdWrite()
|
||||||
const userId = isAdmin ? undefined : this.getUserId();
|
// if(projectId){
|
||||||
await this.service.batchDelete(ids, userId);
|
// await this.service.batchDelete(ids, null,projectId);
|
||||||
return this.ok({});
|
// return this.ok({});
|
||||||
|
// }
|
||||||
|
// const isAdmin = await this.authService.isAdmin(this.ctx);
|
||||||
|
// userId = isAdmin ? undefined : userId;
|
||||||
|
// await this.service.batchDelete(ids, userId);
|
||||||
|
// return this.ok({});
|
||||||
|
await this.checkPermissionCall(async ({userId,projectId})=>{
|
||||||
|
await this.service.batchDelete(ids, userId,projectId);
|
||||||
|
})
|
||||||
|
return this.ok({})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Post('/batchUpdateGroup', { summary: Constants.per.authOnly })
|
@Post('/batchUpdateGroup', { summary: Constants.per.authOnly })
|
||||||
async batchUpdateGroup(@Body('ids') ids: number[], @Body('groupId') groupId: number) {
|
async batchUpdateGroup(@Body('ids') ids: number[], @Body('groupId') groupId: number) {
|
||||||
const isAdmin = await this.authService.isAdmin(this.ctx);
|
// let { projectId ,userId} = await this.getProjectUserIdWrite()
|
||||||
const userId = isAdmin ? undefined : this.getUserId();
|
// if(projectId){
|
||||||
await this.service.batchUpdateGroup(ids, groupId, userId);
|
// await this.service.batchUpdateGroup(ids, groupId, null,projectId);
|
||||||
|
// return this.ok({});
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const isAdmin = await this.authService.isAdmin(this.ctx);
|
||||||
|
// userId = isAdmin ? undefined : this.getUserId();
|
||||||
|
// await this.service.batchUpdateGroup(ids, groupId, userId);
|
||||||
|
await this.checkPermissionCall(async ({userId,projectId})=>{
|
||||||
|
await this.service.batchUpdateGroup(ids, groupId, userId,projectId);
|
||||||
|
})
|
||||||
return this.ok({});
|
return this.ok({});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Post('/batchUpdateTrigger', { summary: Constants.per.authOnly })
|
@Post('/batchUpdateTrigger', { summary: Constants.per.authOnly })
|
||||||
async batchUpdateTrigger(@Body('ids') ids: number[], @Body('trigger') trigger: any) {
|
async batchUpdateTrigger(@Body('ids') ids: number[], @Body('trigger') trigger: any) {
|
||||||
const isAdmin = await this.authService.isAdmin(this.ctx);
|
// let { projectId ,userId} = await this.getProjectUserIdWrite()
|
||||||
const userId = isAdmin ? undefined : this.getUserId();
|
// if(projectId){
|
||||||
await this.service.batchUpdateTrigger(ids, trigger, userId);
|
// await this.service.batchUpdateTrigger(ids, trigger, null,projectId);
|
||||||
|
// return this.ok({});
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const isAdmin = await this.authService.isAdmin(this.ctx);
|
||||||
|
// userId = isAdmin ? undefined : this.getUserId();
|
||||||
|
// await this.service.batchUpdateTrigger(ids, trigger, userId);
|
||||||
|
await this.checkPermissionCall(async ({userId,projectId})=>{
|
||||||
|
await this.service.batchUpdateTrigger(ids, trigger, userId,projectId);
|
||||||
|
})
|
||||||
return this.ok({});
|
return this.ok({});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('/batchUpdateNotification', { summary: Constants.per.authOnly })
|
@Post('/batchUpdateNotification', { summary: Constants.per.authOnly })
|
||||||
async batchUpdateNotification(@Body('ids') ids: number[], @Body('notification') notification: any) {
|
async batchUpdateNotification(@Body('ids') ids: number[], @Body('notification') notification: any) {
|
||||||
const isAdmin = await this.authService.isAdmin(this.ctx);
|
// const isAdmin = await this.authService.isAdmin(this.ctx);
|
||||||
const userId = isAdmin ? undefined : this.getUserId();
|
// const userId = isAdmin ? undefined : this.getUserId();
|
||||||
await this.service.batchUpdateNotifications(ids, notification, userId);
|
// await this.service.batchUpdateNotifications(ids, notification, userId);
|
||||||
|
await this.checkPermissionCall(async ({userId,projectId})=>{
|
||||||
|
await this.service.batchUpdateNotifications(ids, notification, userId,projectId);
|
||||||
|
})
|
||||||
return this.ok({});
|
return this.ok({});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('/batchRerun', { summary: Constants.per.authOnly })
|
@Post('/batchRerun', { summary: Constants.per.authOnly })
|
||||||
async batchRerun(@Body('ids') ids: number[], @Body('force') force: boolean) {
|
async batchRerun(@Body('ids') ids: number[], @Body('force') force: boolean) {
|
||||||
await this.service.batchRerun(ids, this.getUserId(), force);
|
await this.checkPermissionCall(async ({userId,projectId})=>{
|
||||||
|
await this.service.batchRerun(ids, force,userId,projectId);
|
||||||
|
})
|
||||||
return this.ok({});
|
return this.ok({});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('/refreshWebhookKey', { summary: Constants.per.authOnly })
|
@Post('/refreshWebhookKey', { summary: Constants.per.authOnly })
|
||||||
async refreshWebhookKey(@Body('id') id: number) {
|
async refreshWebhookKey(@Body('id') id: number) {
|
||||||
await this.authService.checkEntityUserId(this.ctx, this.getService(), id);
|
|
||||||
|
const { projectId } = await this.getProjectUserIdWrite()
|
||||||
|
if (projectId) {
|
||||||
|
await this.authService.checkEntityProjectId(this.getService(), projectId, id);
|
||||||
|
} else {
|
||||||
|
await this.authService.checkEntityUserId(this.ctx, this.getService(), id);
|
||||||
|
}
|
||||||
const res = await this.service.refreshWebhookKey(id);
|
const res = await this.service.refreshWebhookKey(id);
|
||||||
return this.ok({
|
return this.ok({
|
||||||
webhookKey: res,
|
webhookKey: res,
|
||||||
|
|||||||
@@ -51,7 +51,8 @@ export class AutoAInitSite {
|
|||||||
//加载一次密钥
|
//加载一次密钥
|
||||||
await this.sysSettingsService.getSecret();
|
await this.sysSettingsService.getSecret();
|
||||||
|
|
||||||
await this.sysSettingsService.reloadPrivateSettings();
|
//加载设置
|
||||||
|
await this.sysSettingsService.reloadSettings();
|
||||||
|
|
||||||
// 授权许可
|
// 授权许可
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { In, MoreThan, Repository } from "typeorm";
|
|||||||
import {
|
import {
|
||||||
AccessService,
|
AccessService,
|
||||||
BaseService,
|
BaseService,
|
||||||
|
isEnterprise,
|
||||||
NeedSuiteException,
|
NeedSuiteException,
|
||||||
NeedVIPException,
|
NeedVIPException,
|
||||||
PageReq,
|
PageReq,
|
||||||
@@ -38,7 +39,7 @@ import { CnameRecordService } from "../../cname/service/cname-record-service.js"
|
|||||||
import { PluginConfigGetter } from "../../plugin/service/plugin-config-getter.js";
|
import { PluginConfigGetter } from "../../plugin/service/plugin-config-getter.js";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import { DbAdapter } from "../../db/index.js";
|
import { DbAdapter } from "../../db/index.js";
|
||||||
import { isComm, isPlus } from "@certd/plus-core";
|
import { checkPlus, isComm, isPlus } from "@certd/plus-core";
|
||||||
import { logger, utils } from "@certd/basic";
|
import { logger, utils } from "@certd/basic";
|
||||||
import { UrlService } from "./url-service.js";
|
import { UrlService } from "./url-service.js";
|
||||||
import { NotificationService } from "./notification-service.js";
|
import { NotificationService } from "./notification-service.js";
|
||||||
@@ -301,6 +302,12 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
|||||||
// throw new NeedVIPException(`基础版最多只能创建${freeCount}条流水线`);
|
// throw new NeedVIPException(`基础版最多只能创建${freeCount}条流水线`);
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
if(isEnterprise()){
|
||||||
|
//企业模式不限制
|
||||||
|
checkPlus()
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (isComm()) {
|
if (isComm()) {
|
||||||
//校验pipelineCount
|
//校验pipelineCount
|
||||||
const suiteSetting = await this.userSuiteService.getSuiteSetting();
|
const suiteSetting = await this.userSuiteService.getSuiteSetting();
|
||||||
@@ -328,6 +335,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async foreachPipeline(callback: (pipeline: PipelineEntity) => void) {
|
async foreachPipeline(callback: (pipeline: PipelineEntity) => void) {
|
||||||
@@ -559,6 +567,12 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async beforeCheck(entity: PipelineEntity) {
|
async beforeCheck(entity: PipelineEntity) {
|
||||||
|
|
||||||
|
if(isEnterprise()){
|
||||||
|
checkPlus()
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
|
||||||
const validTimeEnabled = await this.isPipelineValidTimeEnabled(entity)
|
const validTimeEnabled = await this.isPipelineValidTimeEnabled(entity)
|
||||||
if (!validTimeEnabled) {
|
if (!validTimeEnabled) {
|
||||||
throw new Error(`流水线${entity.id}已过期,不予执行`);
|
throw new Error(`流水线${entity.id}已过期,不予执行`);
|
||||||
@@ -582,7 +596,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
|||||||
const res = await this.beforeCheck(entity);
|
const res = await this.beforeCheck(entity);
|
||||||
suite = res.suite
|
suite = res.suite
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.error(`流水线${entity.id}触发${triggerId}失败:${e.message}`);
|
logger.error(`流水线${entity.id}触发失败(${triggerId}):${e.message}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const id = entity.id;
|
const id = entity.id;
|
||||||
@@ -625,7 +639,10 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
|||||||
|
|
||||||
const userId = entity.userId;
|
const userId = entity.userId;
|
||||||
const historyId = await this.historyService.start(entity, triggerType);
|
const historyId = await this.historyService.start(entity, triggerType);
|
||||||
const userIsAdmin = await this.userService.isAdmin(userId);
|
let userIsAdmin = false
|
||||||
|
if(userId){
|
||||||
|
userIsAdmin = await this.userService.isAdmin(userId);
|
||||||
|
}
|
||||||
const user: UserInfo = {
|
const user: UserInfo = {
|
||||||
id: userId,
|
id: userId,
|
||||||
role: userIsAdmin ? "admin" : "user"
|
role: userIsAdmin ? "admin" : "user"
|
||||||
@@ -836,7 +853,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
async batchDelete(ids: number[], userId: number) {
|
async batchDelete(ids: number[], userId?: number,projectId?:number) {
|
||||||
if (!isPlus()) {
|
if (!isPlus()) {
|
||||||
throw new NeedVIPException("此功能需要升级专业版");
|
throw new NeedVIPException("此功能需要升级专业版");
|
||||||
}
|
}
|
||||||
@@ -844,11 +861,14 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
|||||||
if (userId) {
|
if (userId) {
|
||||||
await this.checkUserId(id, userId);
|
await this.checkUserId(id, userId);
|
||||||
}
|
}
|
||||||
|
if(projectId){
|
||||||
|
await this.checkUserId(id,projectId,"projectId")
|
||||||
|
}
|
||||||
await this.delete(id);
|
await this.delete(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async batchUpdateGroup(ids: number[], groupId: number, userId: any) {
|
async batchUpdateGroup(ids: number[], groupId: number, userId: any,projectId?:number) {
|
||||||
if (!isPlus()) {
|
if (!isPlus()) {
|
||||||
throw new NeedVIPException("此功能需要升级专业版");
|
throw new NeedVIPException("此功能需要升级专业版");
|
||||||
}
|
}
|
||||||
@@ -856,6 +876,9 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
|||||||
if (userId && userId > 0) {
|
if (userId && userId > 0) {
|
||||||
query.userId = userId;
|
query.userId = userId;
|
||||||
}
|
}
|
||||||
|
if(projectId){
|
||||||
|
query.projectId = projectId;
|
||||||
|
}
|
||||||
await this.repository.update(
|
await this.repository.update(
|
||||||
{
|
{
|
||||||
id: In(ids),
|
id: In(ids),
|
||||||
@@ -866,7 +889,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async batchUpdateTrigger(ids: number[], trigger: any, userId: any) {
|
async batchUpdateTrigger(ids: number[], trigger: any, userId: any,projectId?:number) {
|
||||||
if (!isPlus()) {
|
if (!isPlus()) {
|
||||||
throw new NeedVIPException("此功能需要升级专业版");
|
throw new NeedVIPException("此功能需要升级专业版");
|
||||||
}
|
}
|
||||||
@@ -874,6 +897,9 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
|||||||
if (userId && userId > 0) {
|
if (userId && userId > 0) {
|
||||||
query.userId = userId;
|
query.userId = userId;
|
||||||
}
|
}
|
||||||
|
if(projectId){
|
||||||
|
query.projectId = projectId;
|
||||||
|
}
|
||||||
const list = await this.find({
|
const list = await this.find({
|
||||||
where: {
|
where: {
|
||||||
id: In(ids),
|
id: In(ids),
|
||||||
@@ -915,7 +941,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async batchUpdateNotifications(ids: number[], notification: Notification, userId: any) {
|
async batchUpdateNotifications(ids: number[], notification: Notification, userId: any,projectId?:number) {
|
||||||
if (!isPlus()) {
|
if (!isPlus()) {
|
||||||
throw new NeedVIPException("此功能需要升级专业版");
|
throw new NeedVIPException("此功能需要升级专业版");
|
||||||
}
|
}
|
||||||
@@ -923,6 +949,9 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
|||||||
if (userId && userId > 0) {
|
if (userId && userId > 0) {
|
||||||
query.userId = userId;
|
query.userId = userId;
|
||||||
}
|
}
|
||||||
|
if(projectId){
|
||||||
|
query.projectId = projectId;
|
||||||
|
}
|
||||||
const list = await this.find({
|
const list = await this.find({
|
||||||
where: {
|
where: {
|
||||||
id: In(ids),
|
id: In(ids),
|
||||||
@@ -950,7 +979,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async batchRerun(ids: number[], userId: any, force: boolean) {
|
async batchRerun(ids: number[], force: boolean,userId: any, projectId?:number) {
|
||||||
if (!isPlus()) {
|
if (!isPlus()) {
|
||||||
throw new NeedVIPException("此功能需要升级专业版");
|
throw new NeedVIPException("此功能需要升级专业版");
|
||||||
}
|
}
|
||||||
@@ -958,14 +987,18 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
|||||||
if (!userId || ids.length === 0) {
|
if (!userId || ids.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const where:any = {
|
||||||
|
id: In(ids),
|
||||||
|
userId,
|
||||||
|
}
|
||||||
|
if(projectId){
|
||||||
|
where.projectId = projectId
|
||||||
|
}
|
||||||
const list = await this.repository.find({
|
const list = await this.repository.find({
|
||||||
select: {
|
select: {
|
||||||
id: true
|
id: true
|
||||||
},
|
},
|
||||||
where: {
|
where:where
|
||||||
id: In(ids),
|
|
||||||
userId
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ids = list.map(item => item.id);
|
ids = list.map(item => item.id);
|
||||||
@@ -993,7 +1026,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
|||||||
return await this.repository.count({ where: { userId } });
|
return await this.repository.count({ where: { userId } });
|
||||||
}
|
}
|
||||||
|
|
||||||
async getSimplePipelines(pipelineIds: number[], userId?: number) {
|
async getSimplePipelines(pipelineIds: number[], userId?: number,projectId?:number) {
|
||||||
return await this.repository.find({
|
return await this.repository.find({
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
@@ -1001,7 +1034,8 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
|||||||
},
|
},
|
||||||
where: {
|
where: {
|
||||||
id: In(pipelineIds),
|
id: In(pipelineIds),
|
||||||
userId
|
userId,
|
||||||
|
projectId
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,4 +35,8 @@ export class AuthService {
|
|||||||
}
|
}
|
||||||
await service.checkUserId(id, ctx.user.id, userKey);
|
await service.checkUserId(id, ctx.user.id, userKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async checkEntityProjectId(service:any,projectId = 0,id:any=0){
|
||||||
|
await service.checkUserId(id, projectId , "projectId");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ export class ProjectEntity {
|
|||||||
@Column({ name: 'user_id', comment: 'UserId' })
|
@Column({ name: 'user_id', comment: 'UserId' })
|
||||||
userId: number;
|
userId: number;
|
||||||
|
|
||||||
|
@Column({ name: 'admin_id', comment: '管理员Id' })
|
||||||
|
adminId: number;
|
||||||
|
|
||||||
@Column({ name: 'name', comment: '项目名称' })
|
@Column({ name: 'name', comment: '项目名称' })
|
||||||
name: string;
|
name: string;
|
||||||
|
|
||||||
|
|||||||
@@ -46,4 +46,26 @@ export class ProjectMemberService extends BaseService<ProjectMemberEntity> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getMember(projectId: number,userId: number) {
|
||||||
|
return await this.repository.findOne({
|
||||||
|
where: {
|
||||||
|
userId,
|
||||||
|
projectId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async getProjectId(id: number) {
|
||||||
|
const member = await this.repository.findOne({
|
||||||
|
select: ['projectId'],
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (!member) {
|
||||||
|
throw new Error('项目成员记录不存在');
|
||||||
|
}
|
||||||
|
return member.projectId;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import {Inject, Provide, Scope, ScopeEnum} from '@midwayjs/core';
|
import { BaseService, SysSettingsService } from '@certd/lib-server';
|
||||||
import {BaseService, SysSettingsService} from '@certd/lib-server';
|
import { Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core';
|
||||||
import {InjectEntityModel} from '@midwayjs/typeorm';
|
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||||
import {In, Repository} from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
import { ProjectEntity } from '../entity/project.js';
|
import { ProjectEntity } from '../entity/project.js';
|
||||||
import { ProjectMemberService } from './project-member-service.js';
|
import { ProjectMemberService } from './project-member-service.js';
|
||||||
|
|
||||||
@@ -30,45 +30,34 @@ export class ProjectService extends BaseService<ProjectEntity> {
|
|||||||
const exist = await this.repository.findOne({
|
const exist = await this.repository.findOne({
|
||||||
where: {
|
where: {
|
||||||
name,
|
name,
|
||||||
userId:0,
|
userId: 0,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (exist) {
|
if (exist) {
|
||||||
throw new Error('项目名称已存在');
|
throw new Error('项目名称已存在');
|
||||||
}
|
}
|
||||||
bean.userId = 0
|
|
||||||
bean.disabled = false
|
bean.disabled = false
|
||||||
return await super.add(bean)
|
return await super.add(bean)
|
||||||
}
|
}
|
||||||
|
|
||||||
async setDisabled(id: number, disabled: boolean) {
|
async setDisabled(id: number, disabled: boolean) {
|
||||||
const project = await this.repository.findOne({
|
|
||||||
where: {
|
|
||||||
id,
|
|
||||||
userId:0,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (!project) {
|
|
||||||
throw new Error('项目不存在');
|
|
||||||
}
|
|
||||||
await this.repository.update({
|
await this.repository.update({
|
||||||
|
id,
|
||||||
userId:0,
|
userId:0,
|
||||||
}, {
|
}, {
|
||||||
disabled,
|
disabled,
|
||||||
});
|
});
|
||||||
project.disabled = disabled;
|
|
||||||
await this.repository.save(project);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getByUserId(userId: number) {
|
async getUserProjects(userId: number) {
|
||||||
|
|
||||||
const memberList = await this.projectMemberService.getByUserId(userId);
|
const memberList = await this.projectMemberService.getByUserId(userId);
|
||||||
const projectIds = memberList.map(item => item.projectId);
|
const projectIds = memberList.map(item => item.projectId);
|
||||||
const projectList = await this.repository.find({
|
const projectList = await this.repository.createQueryBuilder('project')
|
||||||
where: {
|
.where(' project.disabled = false')
|
||||||
id: In(projectIds),
|
.where(' project.userId = :userId', { userId:0 })
|
||||||
},
|
.where(' project.id IN (:...projectIds) or project.adminId = :userId', { projectIds, userId })
|
||||||
});
|
.getMany();
|
||||||
|
|
||||||
const memberPermissionMap = memberList.reduce((prev, cur) => {
|
const memberPermissionMap = memberList.reduce((prev, cur) => {
|
||||||
prev[cur.projectId] = cur.permission;
|
prev[cur.projectId] = cur.permission;
|
||||||
@@ -76,9 +65,81 @@ export class ProjectService extends BaseService<ProjectEntity> {
|
|||||||
}, {} as Record<number, string>);
|
}, {} as Record<number, string>);
|
||||||
|
|
||||||
projectList.forEach(item => {
|
projectList.forEach(item => {
|
||||||
item.permission = memberPermissionMap[item.id] || 'read';
|
if (item.adminId === userId) {
|
||||||
|
item.permission = 'admin';
|
||||||
|
}else{
|
||||||
|
item.permission = memberPermissionMap[item.id] || 'read';
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
return projectList
|
return projectList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async checkAdminPermission({userId, projectId}: {userId: number, projectId: number}) {
|
||||||
|
return await this.checkPermission({
|
||||||
|
userId,
|
||||||
|
projectId,
|
||||||
|
permission: 'admin',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
async checkWritePermission({userId, projectId}: {userId: number, projectId: number}) {
|
||||||
|
return await this.checkPermission({
|
||||||
|
userId,
|
||||||
|
projectId,
|
||||||
|
permission: 'write',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
async checkReadPermission({userId, projectId}: {userId: number, projectId: number}) {
|
||||||
|
return await this.checkPermission({
|
||||||
|
userId,
|
||||||
|
projectId,
|
||||||
|
permission: 'read',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async checkPermission({userId, projectId, permission}: {userId: number, projectId: number, permission: string}) {
|
||||||
|
if (permission !== 'admin' && permission !== 'write' && permission !== 'read') {
|
||||||
|
throw new Error('权限类型错误');
|
||||||
|
}
|
||||||
|
if (!userId ){
|
||||||
|
throw new Error('用户ID不能为空');
|
||||||
|
}
|
||||||
|
if (!projectId ){
|
||||||
|
throw new Error('项目ID不能为空');
|
||||||
|
}
|
||||||
|
const project = await this.findOne({
|
||||||
|
select: ['id', 'userId', 'adminId', 'disabled'],
|
||||||
|
where: {
|
||||||
|
id: projectId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (!project) {
|
||||||
|
throw new Error('项目不存在');
|
||||||
|
}
|
||||||
|
if (project.adminId === userId) {
|
||||||
|
//创建者拥有管理权限
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (project.disabled) {
|
||||||
|
throw new Error('项目已禁用');
|
||||||
|
}
|
||||||
|
const member = await this.projectMemberService.getMember(projectId,userId);
|
||||||
|
if (!member) {
|
||||||
|
throw new Error('项目成员不存在');
|
||||||
|
}
|
||||||
|
if (permission === 'read') {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (permission === 'write') {
|
||||||
|
if (member.permission === 'admin' || member.permission === 'write') {
|
||||||
|
return true
|
||||||
|
}else{
|
||||||
|
throw new Error('权限不足');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (member.permission !== permission) {
|
||||||
|
throw new Error('权限不足');
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user