wenlele 2 years ago
parent
commit
d521a03f3c
  1. 89
      api/app/lib/controllers/alarm/app.js
  2. 22
      api/app/lib/controllers/organization/index.js
  3. 37
      api/app/lib/controllers/project/index.js
  4. 7
      api/app/lib/index.js
  5. 15
      api/app/lib/models/app_alarm.js
  6. 10
      api/app/lib/routes/alarm/index.js
  7. 5
      api/app/lib/routes/project/index.js
  8. 2
      api/sequelize-automate.config.js
  9. 2
      script/0.0.3/1.alert_app_alarm.sql
  10. 47
      web/client/src/sections/install/components/adminModal.jsx
  11. 34
      web/client/src/sections/install/components/memberModal.jsx
  12. 18
      web/client/src/sections/install/containers/roles.jsx

89
api/app/lib/controllers/alarm/app.js

@ -30,6 +30,73 @@ async function inspection (ctx) {
}
}
async function inspectionList (ctx) {
try {
const models = ctx.fs.dc.models;
const { clickHouse } = ctx.app.fs
const { timeStart, timeEnd, projectId, appId, noted } = ctx.query
let findOption = {
where: {
},
order: [['id', 'DESC']],
include: [{
model: models.ProjectApp,
required: Boolean(appId || projectId),
where: appId ? {
id: appId
} : undefined,
include: {
model: models.ProjectCorrelation,
required: Boolean(projectId),
where: projectId ? {
id: projectId
} : undefined,
attributes: {
exclude: ['anxinProjectId', 'createTime', 'createUser']
}
}
}]
}
if (timeStart && timeEnd) {
findOption.where.createTime = { $between: [moment(timeStart).format(), moment(timeEnd).format()] }
}
if (noted) {
if (noted == 'noted') {
findOption.where.notedTime = { $ne: null }
} else if (noted == 'unnote') {
findOption.where.notedTime = null
}
}
const inspectionRes = await models.AppInspection.findAll(findOption)
let notedUserIds = new Set()
for (let ins of inspectionRes) {
if (ins.notedPepUserId) {
notedUserIds.add(ins.notedPepUserId)
}
}
let userPepRes = notedUserIds.size ?
await clickHouse.pepEmis.query(`SELECT DISTINCT user.id AS id, "user"."name" AS name FROM user WHERE user.id IN (${[...notedUserIds].join(',')})`).toPromise() :
[]
for (let ins of inspectionRes) {
if (ins.notedPepUserId) {
const corUser = userPepRes.find(up => up.id == ins.notedPepUserId)
ins.dataValues.notedPepUser = corUser ? corUser.name : ''
}
}
ctx.status = 200;
ctx.body = inspectionRes
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: error`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : undefined
}
}
}
async function notedInspection (ctx) {
try {
const models = ctx.fs.dc.models;
@ -58,7 +125,7 @@ async function notedInspection (ctx) {
async function apiError (ctx) {
try {
const models = ctx.fs.dc.models;
const { projectAppId, alarmContent, router, statusCode } = ctx.request.body
const { projectAppId, alarmContent, router, statusCode, screenshot = '' } = ctx.request.body
const now = moment().format()
let storageData = {
@ -86,6 +153,7 @@ async function apiError (ctx) {
})
storageData.serialNumber = 'WEB' + (existCount < 9 ? '0' + (existCount + 1) : existCount)
storageData.createTime = now
storageData.screenshot = screenshot
await models.AppAlarm.create(storageData)
}
@ -99,6 +167,23 @@ async function apiError (ctx) {
}
}
async function apiErrorList (ctx) {
try {
const models = ctx.fs.dc.models;
const { clickHouse } = ctx.app.fs
const { } = ctx.query
ctx.status = 200;
ctx.body = []
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: error`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : undefined
}
}
}
async function confirmApiError (ctx) {
try {
const models = ctx.fs.dc.models;
@ -124,7 +209,9 @@ async function confirmApiError (ctx) {
module.exports = {
inspection,
inspectionList,
notedInspection,
apiError,
apiErrorList,
confirmApiError,
};

22
api/app/lib/controllers/organization/index.js

@ -48,11 +48,19 @@ async function editUser (ctx) {
// 存在且传递id 或者 不传id也存在
// 修改 update
storageData.deleted = false
storageData.role = [...new Set([...existUserRes.role, ...role])]
if (
storageData.role.includes('admin')
role.includes('admin')
) {
storageData.disabled = false
if (existUserRes.role.includes('admin')) {
// 已是管理员
throw '当前人员已是管理员'
}
// 正在修改为管理员
storageData.disabled = true
storageData.role = [...new Set([...existUserRes.role, ...role])]
} else if (existUserRes.role.includes('admin')) {
// 正在修改成员 但是此时还是管理员
storageData.role = [...role, 'admin']
}
await models.User.update(storageData, {
where: {
@ -64,7 +72,7 @@ async function editUser (ctx) {
await models.User.create(storageData)
}
ctx.status = 200
ctx.status = 204
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
@ -85,7 +93,7 @@ async function putUser (ctx) {
}
})
if (existUserRes && existUserRes.role.includes('admin') && disabled) {
if (existUserRes && existUserRes.role.includes('admin') && !disabled) {
throw '成员不能既是管理员又是普通成员'
}
@ -193,7 +201,9 @@ async function user (ctx) {
for (let u of userRes.rows.concat(adminRes)) {
userIds.add(u.pepUserId)
}
let userPepRes = await clickHouse.pepEmis.query(`SELECT user.id AS id, "user"."name" AS name, department.name AS depName, department.id AS depId FROM department_user LEFT JOIN user ON department_user.user=user.id LEFT JOIN department ON department.id=department_user.department WHERE user.id IN (${[...userIds].join(',')}) AND department.delete=false`).toPromise()
let userPepRes = userIds.size ?
await clickHouse.pepEmis.query(`SELECT DISTINCT user.id AS id, "user"."name" AS name, department.name AS depName, department.id AS depId FROM department_user LEFT JOIN user ON department_user.user=user.id LEFT JOIN department ON department.id=department_user.department WHERE user.id IN (${[...userIds].join(',')}) AND department.delete=false`).toPromise() :
[]
for (let u of userRes.rows.concat(adminRes)) {
const corUsers = userPepRes.filter(up => up.id == u.pepUserId)

37
api/app/lib/controllers/project/index.js

@ -20,7 +20,44 @@ async function appList (ctx) {
}
}
async function projectAnxincloud (ctx) {
try {
const models = ctx.fs.dc.models;
const { clickHouse } = ctx.app.fs
const projectRes = await clickHouse.anxinyun.query(`SELECT * FROM t_project WHERE project_state = 4 ORDER BY id DESC`).toPromise()
ctx.status = 200;
ctx.body = projectRes
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: error`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : undefined
}
}
}
async function projectPManage (ctx) {
try {
const models = ctx.fs.dc.models;
const { clickHouse } = ctx.app.fs
const projectRes = await clickHouse.projectManage.query(`SELECT * FROM t_project WHERE project_state = 4 ORDER BY id DESC`).toPromise()
ctx.status = 200;
ctx.body = projectRes
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: error`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : undefined
}
}
}
module.exports = {
appList,
projectAnxincloud,
projectPManage,
};

7
api/app/lib/index.js

@ -55,7 +55,12 @@ module.exports.models = function (dc) { // dc = { orm: Sequelize对象, ORM: Seq
});
const {
AppInspection, ProjectApp, ProjectCorrelation
} = dc.models;
AppInspection.belongsTo(ProjectApp, { foreignKey: 'projectAppId', targetKey: 'id' });
ProjectApp.hasMany(AppInspection, { foreignKey: 'projectAppId', sourceKey: 'id' });
ProjectApp.belongsTo(ProjectCorrelation, { foreignKey: 'projectId', targetKey: 'id' });
ProjectCorrelation.hasMany(ProjectApp, { foreignKey: 'projectId', sourceKey: 'id' });
};

15
api/app/lib/models/app_alarm.js

@ -31,7 +31,11 @@ module.exports = dc => {
comment: "对应的项目id",
primaryKey: false,
field: "project_app_id",
autoIncrement: false
autoIncrement: false,
references: {
key: "id",
model: "projectApp"
}
},
appDomain: {
type: DataTypes.STRING,
@ -95,6 +99,15 @@ module.exports = dc => {
primaryKey: false,
field: "status_code",
autoIncrement: false
},
screenshot: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "screenshot",
autoIncrement: false
}
}, {
tableName: "app_alarm",

10
api/app/lib/routes/alarm/index.js

@ -9,12 +9,18 @@ module.exports = function (app, router, opts) {
app.fs.api.logAttr['POST/alarm/application/inspection'] = { content: '保存应用巡检信息', visible: true };
router.post('/alarm/application/inspection', application.inspection);
app.fs.api.logAttr['GET/alarm/application/inspection'] = { content: '查询应用巡检信息', visible: true };
router.get('/alarm/application/inspection', application.inspectionList);
app.fs.api.logAttr['PUT/alarm/application/noted'] = { content: '保存检验状态', visible: true };
router.put('/alarm/application/noted', application.notedInspection);
app.fs.api.logAttr['POST/alarm/application/api'] = { content: '保存应用接口错误信息', visible: true };
app.fs.api.logAttr['POST/alarm/application/api'] = { content: '保存应用接口/元素错误信息', visible: true };
router.post('/alarm/application/api', application.apiError);
app.fs.api.logAttr['POST/alarm/application/api_confirm'] = { content: '确认应用接口错误信息', visible: true };
app.fs.api.logAttr['GET/alarm/application/api'] = { content: '查询应用接口/元素错误信息', visible: true };
router.get('/alarm/application/api', application.apiErrorList);
app.fs.api.logAttr['POST/alarm/application/api_confirm'] = { content: '确认应用接口/元素错误信息', visible: true };
router.post('/alarm/application/api_confirm', application.confirmApiError);
};

5
api/app/lib/routes/project/index.js

@ -10,4 +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['GET/project/anxincloud'] = { content: '获取安心云项目', visible: true };
router.get('/project/anxincloud', project.projectAnxincloud);
app.fs.api.logAttr['GET/project/pmanage'] = { content: '获取PEP项目管理项目', visible: true };
router.get('/project/pmanage', project.projectPManage);
};

2
api/sequelize-automate.config.js

@ -26,7 +26,7 @@ module.exports = {
dir: './app/lib/models', // 指定输出 models 文件的目录
typesDir: 'models', // 指定输出 TypeScript 类型定义的文件目录,只有 TypeScript / Midway 等会有类型定义
emptyDir: false, // !!! 谨慎操作 生成 models 之前是否清空 `dir` 以及 `typesDir`
tables: ['app_inspection'], // 指定生成哪些表的 models,如 ['user', 'user_post'];如果为 null,则忽略改属性
tables: ['app_alarm'], // 指定生成哪些表的 models,如 ['user', 'user_post'];如果为 null,则忽略改属性
skipTables: [], // 指定跳过哪些表的 models,如 ['user'];如果为 null,则忽略改属性
tsNoCheck: false, // 是否添加 `@ts-nocheck` 注释到 models 文件中
ignorePrefix: [], // 生成的模型名称忽略的前缀,因为 项目中有以下表名是以 t_ 开头的,在实际模型中不需要, 可以添加多个 [ 't_data_', 't_',] ,长度较长的 前缀放前面

2
script/0.0.3/1.alert_app_alarm.sql

@ -0,0 +1,2 @@
alter table app_alarm
add screenshot varchar(1024);

47
web/client/src/sections/install/components/adminModal.jsx

@ -31,7 +31,7 @@ function adminModal (props) {
}
setPeopleList(departmentList)
setDepartmentId(editObj.departments[0].id)
setPeopleId(editObj.id)
setPeopleId(editObj.pepUserId)
setDisablePeople(false)
}
}, []);
@ -42,13 +42,19 @@ function adminModal (props) {
.validate()
.then((values) => {
if (adminEdit) {
dispatch(install.postOrganizationUser({ role: ['admin'], pepUserId: values.pepUserId })).then((res) => {//(PEP)
close();
})
dispatch(install.deteleOrganizationAdmin(editObj.id)).then(
dispatch(install.postOrganizationUser({ role: ['admin'], pepUserId: values.pepUserId })).then((res) => {//(PEP)
if(res.success){
close();
}
})
)
}
else {
dispatch(install.postOrganizationUser({ role: ['admin'], pepUserId: values.pepUserId })).then((res) => {//(PEP)
close();
if(res.success){
close();
}
})
}
})
@ -79,22 +85,25 @@ function adminModal (props) {
labelAlign="right"
labelWidth="90px"
onValueChange={(values, field) => {
if (values.department >= 0) {
let departmentList = []
for (let i = 0; i < pepList.length; i++) {
if (pepList[i].id == values.department) {
departmentList = pepList[i].users
for (var key in field) {
if (key == 'department') {
if (values.department >= 0) {
let departmentList = []
for (let i = 0; i < pepList.length; i++) {
if (pepList[i].id == values.department) {
departmentList = pepList[i].users
}
}
setPeopleList(departmentList)
setDisablePeople(false)
form.current.setValue('pepUserId', undefined);
}
else {
setPeopleList([])
setDisablePeople(true)
form.current.setValue('pepUserId', undefined);
}
}
setPeopleList(departmentList)
setDisablePeople(false)
// if(disablePeople){
// form.current.setValue(pepUserId, undefined);
// }
}
else {
setPeopleList([])
setDisablePeople(true)
}
}}
getFormApi={(formApi) => (form.current = formApi)}

34
web/client/src/sections/install/components/memberModal.jsx

@ -40,7 +40,7 @@ function memberModal (props) {
]); //
//
useEffect(() => {
if(editObj.id){
if (editObj.id) {
let departmentList = []
for (let i = 0; i < pepList.length; i++) {
if (pepList[i].id == editObj.departments[0].id) {
@ -57,8 +57,14 @@ function memberModal (props) {
form.current
.validate()
.then((values) => {
dispatch(install.postOrganizationUser({ role: values.role, pepUserId: values.pepUserId })).then((res) => {//(PEP)
close();
let roleArr=JSON.parse(JSON.stringify(values.role))
if (roleArr.indexOf('admin') != -1) {
roleArr.splice(roleArr.indexOf('admin'),1)
}
dispatch(install.postOrganizationUser({ role: roleArr, pepUserId: values.pepUserId })).then((res) => {//(PEP)
if(res.success){
close();
}
})
})
}
@ -88,19 +94,27 @@ function memberModal (props) {
labelAlign="right"
labelWidth="90px"
onValueChange={(values, field) => {
for(var key in field){
if(key=='department'){
for (var key in field) {
if (key == 'department') {
if (values.department >= 0) {
let departmentList = []
for (let i = 0; i < pepList.length; i++) {
if (pepList[i].id == values.department) {
departmentList = pepList[i].users
}
}
setPeopleList(departmentList)
setDisablePeople(false)
setPeopleList(pepList[values.department].users)
form.current.setValue('pepUserId', undefined);
}
else {
setPeopleList([])
setDisablePeople(true)
form.current.setValue('pepUserId', undefined);
}
}
}
}}
getFormApi={(formApi) => (form.current = formApi)}
>
@ -118,7 +132,7 @@ function memberModal (props) {
{
pepList.map((item, index) => {
return (
<Form.Select.Option key={item.id} value={index}>
<Form.Select.Option key={item.id} value={item.id}>
{item.name}
</Form.Select.Option>
)
@ -134,7 +148,7 @@ function memberModal (props) {
style={{ width: 417 }}
rules={[{ required: true, message: "请选择人员" }]}
showClear
initValue={editObj.id || ""}
initValue={editObj.pepUserId || ""}
disabled={disablePeople}
>
{
@ -153,7 +167,7 @@ function memberModal (props) {
field="role"
label='权限配置:'
showClear
initValue={editObj.role||[]}
initValue={editObj.role || []}
>
{
jurisdiction.map((item, index) => {

18
web/client/src/sections/install/containers/roles.jsx

@ -322,19 +322,33 @@ const Roles = (props) => {
borderRadius: 2, background: "url(/assets/images/install/cardBackground0" + (index + 1) + '.png)',
backgroundSize: "100% 100%", marginRight: 20, marginBottom: 20,
}}>
{
item.id ? (
<div style={{ display: 'flex', marginLeft: 21, }}>
{
item.departments?.map((itm, idx) => {
let mydepartmentsArr=[]
for (let index = 0; index < item.departments.length; index++) {
mydepartmentsArr.push(item.departments[index].name)
}
return (
<div key={idx} style={{
background: '#52A4F6', borderRadius: 2, height: 18, padding: '2px 4px',
fontSize: 10, marginTop: 17, width: 'max-content', color: '#FFFFFF',
display: 'flex', alignItems: 'center', marginRight: 4,
}}>
{itm.name}
{
idx > 2 ? (
<Tooltip content={mydepartmentsArr.join(',')}>
<div style={{ fontSize: 14, cursor: "pointer", }}>
...
</div>
</Tooltip>
) : (
itm.name
)
}
</div>
)
})

Loading…
Cancel
Save