diff --git a/api/app/lib/controllers/alarm/app.js b/api/app/lib/controllers/alarm/app.js
index 3faa464..edbaf63 100644
--- a/api/app/lib/controllers/alarm/app.js
+++ b/api/app/lib/controllers/alarm/app.js
@@ -108,10 +108,10 @@ async function notedInspection (ctx) {
try {
const models = ctx.fs.dc.models;
const { inspectionId } = ctx.request.body
- const { userId } = ctx.fs.api
+ const { userId, pepUserId } = ctx.fs.api
await models.AppInspection.update({
- notedPepUserId: userId,
+ notedPepUserId: pepUserId,
notedTime: moment().format()
}, {
where: {
diff --git a/api/app/lib/controllers/project/bind.js b/api/app/lib/controllers/project/bind.js
index 5bed3bd..8a0981a 100644
--- a/api/app/lib/controllers/project/bind.js
+++ b/api/app/lib/controllers/project/bind.js
@@ -1,74 +1,148 @@
'use strict';
+const moment = require('moment')
async function bindAnxin2pep (ctx) {
const transaction = await ctx.fs.dc.orm.transaction();
try {
- // const models = ctx.fs.dc.models;
- // const { clickHouse } = ctx.app.fs
- // const { bindId, name, pepProjectId, anxinProjectId = [], app = [] } = ctx.request.body
+ const models = ctx.fs.dc.models;
+ const { clickHouse } = ctx.app.fs
+ const { userId, pepUserId } = ctx.fs.api
+ const { bindId, name, pepProjectId, anxinProjectId = [], app = [] } = ctx.request.body
- // let bindId_ = bindId
- // const existRes = await models.ProjectCorrelation.findOne({
- // where: {
- // pepProjectId: pepProjectId
- // }
- // })
+ let bindId_ = bindId
+ const now = moment()
+ const existRes = await models.ProjectCorrelation.findOne({
+ where: {
+ pepProjectId: pepProjectId
+ },
+ include: {
+ model: models.ProjectApp
+ }
+ })
- // let storageData = {
- // name, pepProjectId, anxinProjectId,
- // }
- // if (bindId_) {
- // if (!existRes) {
- // throw '尚无已绑定的项企项目'
- // }
- // // 修改
- // await models.ProjectCorrelation.update(storageData, {
- // where: {
- // pepProjectId: pepProjectId
- // },
- // transaction
- // })
- // } else {
- // // 新增
- // if (existRes) {
- // // 但是有之前的数据
- // if (existRes.del) {
- // // 不过之前的删除了
+ let storageData = {
+ name, pepProjectId, anxinProjectId,
+ del: false,
+ }
+ // 已经创建过的 app
+ let existApp = []
+ // 新增的
+ let createAppData = []
+ // url 相同需要更新的 解除 lock 状态
+ let updateAppData = []
+ // 没有出现但存在的 叠加 lock 状态
+ let lockAppData = []
+
+ if (bindId_) {
+ if (!existRes) {
+ throw '尚无已绑定的项企项目'
+ }
+ // 修改
+ await models.ProjectCorrelation.update(storageData, {
+ where: {
+ pepProjectId: pepProjectId
+ },
+ transaction
+ })
+ existApp = existRes.projectApps
+ } else {
+ // 新增
+ if (existRes) {
+ // 但是有之前的数据
+ if (existRes.del) {
+ // 不过之前的删除了
+ await models.ProjectCorrelation.update(storageData, {
+ where: {
+ pepProjectId: pepProjectId
+ },
+ transaction
+ })
+ existApp = existRes.projectApps
+ } else {
+ // 没有删除 重复添加
+ throw '当前项企项目已绑定'
+ }
+ } else {
+ storageData.createUser = userId;
+ storageData.createTime = now.format()
+ const createRes = await models.ProjectCorrelation.create(storageData, {
+ transaction
+ })
+ bindId_ = createRes.id
+ }
+ }
+
+ app.forEach((a, i, arr) => {
+ if (!a.name || !a.url) {
+ throw `${a.name} ${a.url} 缺少必要参数`
+ }
+ let curUrlArr = a.url.split('://')
+ if (curUrlArr.length < 2) {
+ throw `${a.name} ${a.url} url 地址错误`
+ }
+ curUrlArr.shift()
+ let curUrl = curUrlArr.join('://')
+ // 先判断传过来的数据有没有重复
+ for (let ii = i + 1; ii < arr.length; ii++) {
+ let curForUrlArr = arr[ii].url.split('://')
+ curForUrlArr.shift()
+ if (curUrl == curForUrlArr.join('://')) {
+ throw `${a.name} ${a.url} 与 ${arr[ii].name} ${arr[ii].url} 地址重复`
+ }
+ }
- // } else {
- // // 没有删除 重复添加
- // throw '当前项企项目已绑定'
- // }
- // } else {
- // const createRes = await models.ProjectCorrelation.create(storageData, {
- // transaction
- // })
- // bindId_ = createRes.id
+ // 再判断和已有的有没有重复
+ let existSameApp = existApp.find(ea => {
+ let curForUrlArr = ea.url.split('://')
+ curForUrlArr.shift()
+ return curUrl == curForUrlArr.join('://')
+ })
+ if (existSameApp) {
+ updateAppData.push({
+ id: existSameApp.id,
+ name: a.name,
+ url: a.url,
+ projectId: bindId_,
+ lock: false,
+ })
+ existSameApp.addAgain = true
+ } else {
+ createAppData.push({
+ name: a.name,
+ url: a.url,
+ projectId: bindId_,
+ lock: false,
+ })
+ }
+ lockAppData = existApp.filter(esa => !esa.addAgain).map(esa => {
+ return {
+ id: esa.id,
+ // name: esa.name,
+ // url: esa.url,
+ // projectId: bindId_,
+ lock: true,
+ }
+ })
+ })
- // await models.ProjectApp.bulkCreate(app.map((a, i, arr) => {
- // if (!a.name || !a.url) {
- // throw `${a.name} ${a.url} 缺少必要参数`
- // }
- // let curUrlArr = a.url.split('://')
- // if(curUrlArr.length < 2){
- // throw `${a.name} ${a.url} url 地址错误`
- // }
- // for (let ii = i; ii < arr.length; ii++) {
- // let
- // }
+ createAppData.length ?
+ await models.ProjectApp.bulkCreate(createAppData, {
+ transaction
+ }) : null
- // return {
- // name: a.name,
- // url: a.url,
- // projectId: bindId_,
- // lock: false,
- // }
- // }))
- // }
- // }
+ updateAppData.length || lockAppData.length ?
+ await Promise.all(updateAppData.concat(lockAppData).map(ud => {
+ return models.ProjectApp.update(ud, {
+ where: {
+ id: ud.id
+ },
+ transaction
+ })
+ }))
+ : null
- // await transaction.commit();
- // ctx.status = 204;
+ await transaction.commit();
+ ctx.status = 204;
} catch (error) {
await transaction.rollback();
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
@@ -79,7 +153,31 @@ async function bindAnxin2pep (ctx) {
}
}
+async function del (ctx) {
+ try {
+ const models = ctx.fs.dc.models;
+ const { bindId } = ctx.query
+
+ await models.ProjectCorrelation.update({
+ del: true
+ }, {
+ where: {
+ id: bindId
+ }
+ })
+
+ ctx.status = 20;
+ } catch (error) {
+ ctx.fs.logger.error(`path: ${ctx.path}, error: error`);
+ ctx.status = 400;
+ ctx.body = {
+ message: typeof error == 'string' ? error : undefined
+ }
+ }
+}
+
module.exports = {
- bindAnxin2pep
+ bindAnxin2pep,
+ del
};
\ No newline at end of file
diff --git a/api/app/lib/controllers/project/index.js b/api/app/lib/controllers/project/index.js
index 7f55f79..73df7cd 100644
--- a/api/app/lib/controllers/project/index.js
+++ b/api/app/lib/controllers/project/index.js
@@ -24,13 +24,14 @@ async function pomsProject (ctx) {
try {
const models = ctx.fs.dc.models;
const { clickHouse } = ctx.app.fs
- const { userId } = ctx.fs.api
+ const { userId, pepUserId } = ctx.fs.api
const { limit, page } = ctx.query
let findOption = {
where: {
del: false
},
+ distinct: true,
include: {
model: models.ProjectApp,
where: {
@@ -49,14 +50,11 @@ async function pomsProject (ctx) {
findOption.offset = page * limit
}
- const proRes = await models.ProjectCorrelation.findAll(findOption)
- delete findOption.limit
- delete findOption.offset
- const proCount = await models.ProjectCorrelation.count(findOption)
+ const proRes = await models.ProjectCorrelation.findAndCountAll(findOption)
let pepProjectIds = new Set()
let anxinProjectIds = new Set()
- for (let p of proRes) {
+ for (let p of proRes.rows) {
pepProjectIds.add(p.pepProjectId)
for (let ap of p.anxinProjectId) {
anxinProjectIds.add(ap)
@@ -71,7 +69,7 @@ async function pomsProject (ctx) {
[]
- for (let p of proRes) {
+ for (let p of proRes.rows) {
const corPro = pepProjectRes.find(pp => pp.id == p.pepProjectId)
p.dataValues.pepProjectName = corPro.project_name
let nextAnxinProject = anxinProjectRes.filter(ap => p.anxinProjectId.includes(ap.id))
@@ -79,10 +77,7 @@ async function pomsProject (ctx) {
delete p.dataValues.anxinProjectId
}
ctx.status = 200;
- ctx.body = {
- count: proCount,
- rows: proRes
- }
+ ctx.body = proRes
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: error`);
ctx.status = 400;
diff --git a/api/app/lib/controllers/push/config.js b/api/app/lib/controllers/push/config.js
index 3cbcdb0..f4cba4f 100644
--- a/api/app/lib/controllers/push/config.js
+++ b/api/app/lib/controllers/push/config.js
@@ -48,7 +48,7 @@ async function list (ctx) {
async function edit (ctx) {
try {
const models = ctx.fs.dc.models;
- const { userId } = ctx.fs.api
+ const { userId, pepUserId } = ctx.fs.api
const { pushId, name, pepProjectId = [], alarmType = [], receiverPepUserId = [], timeType = [], disable } = ctx.request.body
let storageData = {
diff --git a/api/app/lib/middlewares/authenticator.js b/api/app/lib/middlewares/authenticator.js
index ac08b3c..617f596 100644
--- a/api/app/lib/middlewares/authenticator.js
+++ b/api/app/lib/middlewares/authenticator.js
@@ -76,11 +76,17 @@ let authorizeToken = async function (ctx, token) {
})
const { userInfo, expired } = authorizeRes;
if (expired && moment().valueOf() <= moment(expired).valueOf()) {
+ const pomsUser = await ctx.app.fs.dc.models.User.findOne({
+ where: {
+ pepUserId: userInfo.id
+ }
+ })
rslt = {
'authorized': userInfo.authorized,
'resources': (userInfo || {}).resources || [],
};
- ctx.fs.api.userId = userInfo.id;
+ ctx.fs.api.userId = pomsUser.id;
+ ctx.fs.api.pepUserId = userInfo.id;
ctx.fs.api.userInfo = userInfo;
ctx.fs.api.token = token;
}
diff --git a/api/app/lib/routes/project/index.js b/api/app/lib/routes/project/index.js
index ec27061..241aaf3 100644
--- a/api/app/lib/routes/project/index.js
+++ b/api/app/lib/routes/project/index.js
@@ -10,6 +10,9 @@ module.exports = function (app, router, opts) {
app.fs.api.logAttr['POST/project/bind'] = { content: '绑定安心云、项目管理项目', visible: true };
router.post('/project/bind', projectBind.bindAnxin2pep);
+ app.fs.api.logAttr['DEL/project/bind/:bindId'] = { content: '删除安心云、项目管理项目绑定关系', visible: true };
+ router.delete('/project/bind/:bindId', projectBind.del);
+
app.fs.api.logAttr['GET/project/anxincloud'] = { content: '获取安心云项目', visible: true };
router.get('/project/anxincloud', project.projectAnxincloud);
diff --git a/web/client/src/sections/install/actions/roles.js b/web/client/src/sections/install/actions/roles.js
index 6081910..ff4b638 100644
--- a/web/client/src/sections/install/actions/roles.js
+++ b/web/client/src/sections/install/actions/roles.js
@@ -30,7 +30,7 @@ export function putOrganizationUser (data) {//更新成员状态
let msg = ''
if (data) {
pomsUserId = data.pomsUserId
- msg=data.msg
+ msg = data.msg
}
return (dispatch) =>
basicAction({
@@ -47,7 +47,7 @@ export function putOrganizationUser (data) {//更新成员状态
export function postOrganizationUser (data) {//添加/编辑成员
let msg = ''
if (data) {
- msg=data.msg
+ msg = data.msg
}
return (dispatch) =>
basicAction({
@@ -60,20 +60,53 @@ export function postOrganizationUser (data) {//添加/编辑成员
reducer: { name: "" },
});
}
-export function deteleOrganizationAdmin(data) {
+export function deteleOrganizationAdmin (data) {//删除管理员
let pomsUserId = ''
let msg = ''
if (data) {
pomsUserId = data.id
- msg=data.msg
+ msg = data.msg
}
return (dispatch) =>
- basicAction({
- type: "del",
+ basicAction({
+ type: "del",
+ dispatch: dispatch,
+ actionType: "DEL_ORGANIZATION_ADMIN",
+ url: `${ApiTable.deteleOrganizationAdmin.replace("{pomsUserId}", pomsUserId)}`,
+ msg: { option: msg }, //删除管理员
+ reducer: {},
+ });
+}
+export function getProjectPoms (query) {//获取已绑定项目
+ return (dispatch) => basicAction({
+ type: "get",
+ dispatch: dispatch,
+ actionType: "GET_PROJECT_POMS",
+ query: query,
+ url: `${ApiTable.getProjectPoms}`,
+ msg: { option: "获取已绑定项目" },
+ reducer: { name: "ProjectPoms", params: { noClear: true } },
+ });
+}
+export function getProjectAnxincloud (query) {//获取安心云项目
+ return (dispatch) => basicAction({
+ type: "get",
dispatch: dispatch,
- actionType: "DEL_ORGANIZATION_ADMIN",
- url: `${ApiTable.deteleOrganizationAdmin.replace("{pomsUserId}", pomsUserId)}`,
- msg: { option: msg }, //删除管理员
- reducer: {},
- });
- }
\ No newline at end of file
+ actionType: "GET_PROJECT_ANXINCLOUD",
+ query: query,
+ url: `${ApiTable.getProjectAnxincloud}`,
+ msg: { option: "获取安心云项目" },
+ reducer: { name: "ProjectPoms", params: { noClear: true } },
+ });
+}
+export function getProjectPmanage (query) {//获取PEP项目管理项目
+ return (dispatch) => basicAction({
+ type: "get",
+ dispatch: dispatch,
+ actionType: "GET_PROJECT_PMANAGE",
+ query: query,
+ url: `${ApiTable.getProjectPmanage}`,
+ msg: { option: "获取PEP项目管理项目" },
+ reducer: { name: "ProjectPoms", params: { noClear: true } },
+ });
+}
diff --git a/web/client/src/sections/install/components/systemModal.jsx b/web/client/src/sections/install/components/systemModal.jsx
new file mode 100644
index 0000000..6a03bf5
--- /dev/null
+++ b/web/client/src/sections/install/components/systemModal.jsx
@@ -0,0 +1,170 @@
+import React, { useState, useRef, useEffect } from "react";
+import { connect } from "react-redux";
+import { Modal, Form } from "@douyinfe/semi-ui";
+import { IconAlertCircle } from '@douyinfe/semi-icons';
+
+
+function adminModal (props) {
+ const {
+ close,
+ visible,
+ dispatch,
+ pepList,
+ actions,
+ adminEdit,//是否是编辑
+ editObj,
+ } = props;
+ const { install } = actions;
+ const form = useRef();//表单
+ const [disablePeople, setDisablePeople] = useState(true); //页码信息
+ const [peopleList, setPeopleList] = useState([]); //人员List
+ const [departmentId, setDepartmentId] = useState(); //部门id
+ const [peopleId, setPeopleId] = useState(); //人员id
+ //初始化
+ useEffect(() => {
+ if (editObj.id) {
+ let departmentList = []
+ for (let i = 0; i < pepList.length; i++) {
+ if (pepList[i].id == editObj.departments[0].id) {
+ departmentList = pepList[i].users
+ }
+ }
+ setPeopleList(departmentList)
+ setDepartmentId(editObj.departments[0].id)
+ setPeopleId(editObj.pepUserId)
+ setDisablePeople(false)
+ }
+ }, []);
+
+ function handleOk () {
+ //点击弹框确定 右边按钮
+ form.current
+ .validate()
+ .then((values) => {
+ if (adminEdit) {
+ dispatch(install.deteleOrganizationAdmin({id:editObj.id,msg:''})).then(
+ dispatch(install.postOrganizationUser({ role: ['admin'], pepUserId: values.pepUserId, msg: '修改管理员' })).then((res) => {//获取项企(PEP)全部部门及其下用户
+ if (res.success) {
+ close();
+ }
+ })
+ )
+ }
+ else {
+ dispatch(install.postOrganizationUser({ role: ['admin'], pepUserId: values.pepUserId, msg: '新增管理员' })).then((res) => {//获取项企(PEP)全部部门及其下用户
+ if (res.success) {
+ close();
+ }
+ })
+ }
+ })
+ }
+ function handleCancel () {
+ close();
+ //点击弹框取消 左边按钮
+ }
+ return (
+ <>
+