Compare commits
	
		
			3 Commits 
		
	
	
		
			91fbc45086
			...
			03b2e0bc85
		
	
	| Author | SHA1 | Date | 
|---|---|---|
| 
							
							
								
								 | 
						03b2e0bc85 | 3 years ago | 
| 
							
							
								
								 | 
						8aae0a4408 | 3 years ago | 
| 
							
							
								
								 | 
						17e0ee80c6 | 3 years ago | 
				 19 changed files with 1324 additions and 12 deletions
			
			
		@ -0,0 +1,209 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					async function findSingleGraph(ctx, next) { | 
				
			||||
 | 
					    let error = { name: 'FindSingleError', message: '查询单一数据失败' }; | 
				
			||||
 | 
					    let rslt = null; | 
				
			||||
 | 
					    const { projectId } = ctx.params; | 
				
			||||
 | 
					    try { | 
				
			||||
 | 
					        rslt = await ctx.fs.dc.models.ProjectGraph.findOne({ | 
				
			||||
 | 
					            where: { projectId: projectId } | 
				
			||||
 | 
					        }); | 
				
			||||
 | 
					        error = null; | 
				
			||||
 | 
					    } catch (err) { | 
				
			||||
 | 
					        ctx.fs.logger.error(`path: ${ctx.path}, error: ${err}`); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					    if (error) { | 
				
			||||
 | 
					        ctx.status = 400; | 
				
			||||
 | 
					        ctx.body = error; | 
				
			||||
 | 
					    } else { | 
				
			||||
 | 
					        ctx.status = 200; | 
				
			||||
 | 
					        ctx.body = rslt; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					async function createGraph(ctx, next) { | 
				
			||||
 | 
					    let error = { name: 'AddError', message: '添加数据失败' }; | 
				
			||||
 | 
					    let graphId = null; | 
				
			||||
 | 
					    try { | 
				
			||||
 | 
					        const data = ctx.request.body; | 
				
			||||
 | 
					        let dataToSave = { | 
				
			||||
 | 
					            projectId: data.projectId, | 
				
			||||
 | 
					            graph: data.graph, | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        const t = await ctx.fs.dc.orm.transaction(); | 
				
			||||
 | 
					        try { | 
				
			||||
 | 
					            let planarGraph = await ctx.fs.dc.models.ProjectGraph.create(dataToSave); | 
				
			||||
 | 
					            graphId = planarGraph.id; | 
				
			||||
 | 
					            await t.commit(); | 
				
			||||
 | 
					        } catch (e) { | 
				
			||||
 | 
					            await t.rollback(); | 
				
			||||
 | 
					            throw e; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        error = null; | 
				
			||||
 | 
					        // 日志信息
 | 
				
			||||
 | 
					        ctx.fs.api = ctx.fs.api || {}; | 
				
			||||
 | 
					        ctx.fs.api.actionParameter = JSON.stringify(data); | 
				
			||||
 | 
					        ctx.fs.api.actionParameterShow = `新增graphId:${graphId}`; | 
				
			||||
 | 
					    } catch (err) { | 
				
			||||
 | 
					        ctx.fs.logger.error(`path: ${ctx.path}, error: ${err}`); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					    if (error) { | 
				
			||||
 | 
					        ctx.status = 400; | 
				
			||||
 | 
					        ctx.body = error; | 
				
			||||
 | 
					    } else { | 
				
			||||
 | 
					        ctx.status = 200; | 
				
			||||
 | 
					        ctx.body = { id: graphId }; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					async function updateGraph(ctx, next) { | 
				
			||||
 | 
					    let error = { name: 'UpdateError', message: '修改数据失败' }; | 
				
			||||
 | 
					    const { id } = ctx.params; | 
				
			||||
 | 
					    const data = ctx.request.body; | 
				
			||||
 | 
					    if (id) { | 
				
			||||
 | 
					        if (data && Object.keys(data).length) { | 
				
			||||
 | 
					            try { | 
				
			||||
 | 
					                const models = ctx.fs.dc.models; | 
				
			||||
 | 
					                let planarGraph = await models.ProjectGraph.findOne({ where: { id: id } }); | 
				
			||||
 | 
					                const dataToSave = {}; | 
				
			||||
 | 
					                if (planarGraph) { | 
				
			||||
 | 
					                    const { projectId, graph } = data; | 
				
			||||
 | 
					                    if (projectId && !(projectId == planarGraph.projectId)) | 
				
			||||
 | 
					                        dataToSave.projectId = projectId; | 
				
			||||
 | 
					                    if (graph && !(graph == planarGraph.graph)) | 
				
			||||
 | 
					                        dataToSave.graph = graph; | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                dataToSave.id = planarGraph.id; | 
				
			||||
 | 
					                if (Object.keys(dataToSave).length) { | 
				
			||||
 | 
					                    await models.ProjectGraph.update(dataToSave, { where: { id: planarGraph.id } }); | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                error = null; | 
				
			||||
 | 
					                // 日志信息
 | 
				
			||||
 | 
					                ctx.fs.api = ctx.fs.api || {}; | 
				
			||||
 | 
					                ctx.fs.api.actionParameter = JSON.stringify(data); | 
				
			||||
 | 
					                ctx.fs.api.actionParameterShow = `结构物平面图id:${data.id}`; | 
				
			||||
 | 
					            } catch (err) { | 
				
			||||
 | 
					                ctx.fs.logger.error(`path: ${ctx.path}, error: ${err}`); | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } else { | 
				
			||||
 | 
					        error = { name: 'UpdateError', message: `不存在{id=${id}}的结构物平面图` }; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					    if (error) { | 
				
			||||
 | 
					        ctx.status = 400; | 
				
			||||
 | 
					        ctx.body = error; | 
				
			||||
 | 
					    } else { | 
				
			||||
 | 
					        ctx.status = 200; | 
				
			||||
 | 
					        ctx.body = { message: "结构物平面图修改成功" }; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					async function delProjectGraph(ctx) { | 
				
			||||
 | 
					    try { | 
				
			||||
 | 
					        const { id } = ctx.params; | 
				
			||||
 | 
					        const models = ctx.fs.dc.models; | 
				
			||||
 | 
					        let info = await models.ProjectGraph.findOne({ where: { id: id } }); | 
				
			||||
 | 
					        if (info) { | 
				
			||||
 | 
					            await models.ProjectPointsDeploy.destroy({ where: { graphId: id } }); | 
				
			||||
 | 
					            await models.ProjectGraph.destroy({ where: { id } }) | 
				
			||||
 | 
					            ctx.status = 204; | 
				
			||||
 | 
					        } else { | 
				
			||||
 | 
					            ctx.status = 400; | 
				
			||||
 | 
					            ctx.body = { message: '数据不存在' } | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } catch (error) { | 
				
			||||
 | 
					        ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); | 
				
			||||
 | 
					        ctx.status = 400; | 
				
			||||
 | 
					        ctx.body = { | 
				
			||||
 | 
					            "message": "删除结构物布设图失败" | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					async function getDeployPoints(ctx) { | 
				
			||||
 | 
					    try { | 
				
			||||
 | 
					        const pictureId = ctx.params.pictureId; | 
				
			||||
 | 
					        const models = ctx.fs.dc.models; | 
				
			||||
 | 
					        const heatmap = await models.ProjectGraph.findOne({ where: { id: pictureId } }) | 
				
			||||
 | 
					        if (heatmap) { | 
				
			||||
 | 
					            let allPoints = await models.Point.findAll({ | 
				
			||||
 | 
					                attributes: ['id', 'name'], | 
				
			||||
 | 
					                where: { projectId: heatmap.dataValues.projectId } | 
				
			||||
 | 
					            }) | 
				
			||||
 | 
					            let setedPoints = await models.ProjectPointsDeploy.findAll({ | 
				
			||||
 | 
					                where: { graphId: pictureId } | 
				
			||||
 | 
					            }) | 
				
			||||
 | 
					            ctx.status = 200; | 
				
			||||
 | 
					            ctx.body = { | 
				
			||||
 | 
					                allPoints, | 
				
			||||
 | 
					                setedPoints | 
				
			||||
 | 
					            }; | 
				
			||||
 | 
					        } else { | 
				
			||||
 | 
					            throw new Error('pictureId not found'); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } catch (err) { | 
				
			||||
 | 
					        ctx.fs.logger.error(`path: ${ctx.path}, error: ${err}`); | 
				
			||||
 | 
					        ctx.status = 400; | 
				
			||||
 | 
					        ctx.body = { | 
				
			||||
 | 
					            name: 'FindError', | 
				
			||||
 | 
					            message: '获取结构物平面图测点布设失败' | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					async function setDeployPoints(ctx) { | 
				
			||||
 | 
					    const pictureId = ctx.params.pictureId; | 
				
			||||
 | 
					    const req = ctx.request.body; | 
				
			||||
 | 
					    const models = ctx.fs.dc.models; | 
				
			||||
 | 
					    const orm = ctx.fs.dc.orm; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    try { | 
				
			||||
 | 
					        ctx.fs.api = ctx.fs.api || {}; | 
				
			||||
 | 
					        ctx.fs.api.actionParameter = req; | 
				
			||||
 | 
					        ctx.fs.api.actionParameterShow = '结构物平面图测点部署: ' + JSON.stringify(req); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        const t = await orm.transaction(); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        try { | 
				
			||||
 | 
					            await models.ProjectPointsDeploy.destroy({ where: { graphId: pictureId }, transaction: t }); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            const layout = req.spots.map((hotspot, index) => { | 
				
			||||
 | 
					                let msg = { | 
				
			||||
 | 
					                    graphId: pictureId, | 
				
			||||
 | 
					                    pointId: hotspot.pointId, | 
				
			||||
 | 
					                    position: JSON.stringify(hotspot.position) | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                return msg; | 
				
			||||
 | 
					            }); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            await models.ProjectPointsDeploy.bulkCreate(layout, { transaction: t }); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            await t.commit(); | 
				
			||||
 | 
					        } catch (e) { | 
				
			||||
 | 
					            await t.rollback(); | 
				
			||||
 | 
					            throw e; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        ctx.status = 200; | 
				
			||||
 | 
					        ctx.body = { | 
				
			||||
 | 
					            name: "CreateSuccess", | 
				
			||||
 | 
					            message: "结构物平面图测点部署成功" | 
				
			||||
 | 
					        }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    } catch (err) { | 
				
			||||
 | 
					        ctx.fs.logger.error(err); | 
				
			||||
 | 
					        ctx.status = 400; | 
				
			||||
 | 
					        ctx.body = { | 
				
			||||
 | 
					            name: 'CreateError', | 
				
			||||
 | 
					            message: "结构物平面图测点部署失败" | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					module.exports = { | 
				
			||||
 | 
					    findSingleGraph, | 
				
			||||
 | 
					    createGraph, | 
				
			||||
 | 
					    updateGraph, | 
				
			||||
 | 
					    delProjectGraph, | 
				
			||||
 | 
					    getDeployPoints, | 
				
			||||
 | 
					    setDeployPoints | 
				
			||||
 | 
					}; | 
				
			||||
@ -0,0 +1,44 @@ | 
				
			|||||
 | 
					/* eslint-disable*/ | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					module.exports = dc => { | 
				
			||||
 | 
					  const DataTypes = dc.ORM; | 
				
			||||
 | 
					  const sequelize = dc.orm; | 
				
			||||
 | 
					  const ProjectGraph = sequelize.define("projectGraph", { | 
				
			||||
 | 
					    id: { | 
				
			||||
 | 
					      type: DataTypes.INTEGER, | 
				
			||||
 | 
					      allowNull: false, | 
				
			||||
 | 
					      defaultValue: null, | 
				
			||||
 | 
					      comment: null, | 
				
			||||
 | 
					      primaryKey: true, | 
				
			||||
 | 
					      field: "id", | 
				
			||||
 | 
					      autoIncrement: true, | 
				
			||||
 | 
					      unique: "project_graph_id_uindex" | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    projectId: { | 
				
			||||
 | 
					      type: DataTypes.INTEGER, | 
				
			||||
 | 
					      allowNull: false, | 
				
			||||
 | 
					      defaultValue: null, | 
				
			||||
 | 
					      comment: null, | 
				
			||||
 | 
					      primaryKey: false, | 
				
			||||
 | 
					      field: "project_id", | 
				
			||||
 | 
					      autoIncrement: false | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    graph: { | 
				
			||||
 | 
					      type: DataTypes.STRING, | 
				
			||||
 | 
					      allowNull: false, | 
				
			||||
 | 
					      defaultValue: null, | 
				
			||||
 | 
					      comment: null, | 
				
			||||
 | 
					      primaryKey: false, | 
				
			||||
 | 
					      field: "graph", | 
				
			||||
 | 
					      autoIncrement: false | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					  }, { | 
				
			||||
 | 
					    tableName: "project_graph", | 
				
			||||
 | 
					    comment: "", | 
				
			||||
 | 
					    indexes: [] | 
				
			||||
 | 
					  }); | 
				
			||||
 | 
					  dc.models.ProjectGraph = ProjectGraph; | 
				
			||||
 | 
					  return ProjectGraph; | 
				
			||||
 | 
					}; | 
				
			||||
@ -0,0 +1,53 @@ | 
				
			|||||
 | 
					/* eslint-disable*/ | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					module.exports = dc => { | 
				
			||||
 | 
					  const DataTypes = dc.ORM; | 
				
			||||
 | 
					  const sequelize = dc.orm; | 
				
			||||
 | 
					  const ProjectPointsDeploy = sequelize.define("projectPointsDeploy", { | 
				
			||||
 | 
					    id: { | 
				
			||||
 | 
					      type: DataTypes.INTEGER, | 
				
			||||
 | 
					      allowNull: false, | 
				
			||||
 | 
					      defaultValue: null, | 
				
			||||
 | 
					      comment: null, | 
				
			||||
 | 
					      primaryKey: true, | 
				
			||||
 | 
					      field: "id", | 
				
			||||
 | 
					      autoIncrement: true, | 
				
			||||
 | 
					      unique: "project_points_deploy_id_uindex" | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    pointId: { | 
				
			||||
 | 
					      type: DataTypes.INTEGER, | 
				
			||||
 | 
					      allowNull: false, | 
				
			||||
 | 
					      defaultValue: null, | 
				
			||||
 | 
					      comment: null, | 
				
			||||
 | 
					      primaryKey: false, | 
				
			||||
 | 
					      field: "point_id", | 
				
			||||
 | 
					      autoIncrement: false | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    graphId: { | 
				
			||||
 | 
					      type: DataTypes.INTEGER, | 
				
			||||
 | 
					      allowNull: false, | 
				
			||||
 | 
					      defaultValue: null, | 
				
			||||
 | 
					      comment: null, | 
				
			||||
 | 
					      primaryKey: false, | 
				
			||||
 | 
					      field: "graph_id", | 
				
			||||
 | 
					      autoIncrement: false | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    position: { | 
				
			||||
 | 
					      type: DataTypes.STRING, | 
				
			||||
 | 
					      allowNull: false, | 
				
			||||
 | 
					      defaultValue: null, | 
				
			||||
 | 
					      comment: null, | 
				
			||||
 | 
					      primaryKey: false, | 
				
			||||
 | 
					      field: "position", | 
				
			||||
 | 
					      autoIncrement: false | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					  }, { | 
				
			||||
 | 
					    tableName: "project_points_deploy", | 
				
			||||
 | 
					    comment: "", | 
				
			||||
 | 
					    indexes: [] | 
				
			||||
 | 
					  }); | 
				
			||||
 | 
					  dc.models.ProjectPointsDeploy = ProjectPointsDeploy; | 
				
			||||
 | 
					  return ProjectPointsDeploy; | 
				
			||||
 | 
					}; | 
				
			||||
@ -0,0 +1,23 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					const pointDeploy = require('../../controllers/pointDeploy'); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					module.exports = function (app, router, opts) { | 
				
			||||
 | 
					    app.fs.api.logAttr['GET/project/:projectId/planarGraph'] = { content: '获取结构物平面图数据', visible: false }; | 
				
			||||
 | 
					    router.get('/project/:projectId/planarGraph', pointDeploy.findSingleGraph); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    app.fs.api.logAttr['POST/planarGraph/add'] = { content: '新增结构物平面图', visible: true }; | 
				
			||||
 | 
					    router.post('/planarGraph/add', pointDeploy.createGraph); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    app.fs.api.logAttr['PUT/planarGraph/:id/modify'] = { content: '修改结构物平面图', visible: true }; | 
				
			||||
 | 
					    router.post('/planarGraph/:id/modify', pointDeploy.updateGraph); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    app.fs.api.logAttr['DEL/project/graph/:id'] = { content: '删除结构物布设图', visible: false }; | 
				
			||||
 | 
					    router.del('/project/graph/:id', pointDeploy.delProjectGraph); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    app.fs.api.logAttr['GET/picture/:pictureId/deploy/points'] = { content: '获取点位布设信息', visible: false }; | 
				
			||||
 | 
					    router.get('/picture/:pictureId/deploy/points', pointDeploy.getDeployPoints); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    app.fs.api.logAttr['POST/set/picture/:pictureId/deploy/points'] = { content: '点位布设', visible: true }; | 
				
			||||
 | 
					    router.post('/set/picture/:pictureId/deploy/points', pointDeploy.setDeployPoints); | 
				
			||||
 | 
					}; | 
				
			||||
@ -0,0 +1,33 @@ | 
				
			|||||
 | 
					/*结构物布设图表*/ | 
				
			||||
 | 
					create table project_graph | 
				
			||||
 | 
					( | 
				
			||||
 | 
					        id serial not null, | 
				
			||||
 | 
					        project_id int not null, | 
				
			||||
 | 
					        graph varchar(255) not null | 
				
			||||
 | 
					); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					create unique index project_graph_id_uindex | 
				
			||||
 | 
					        on project_graph (id); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					alter table project_graph | 
				
			||||
 | 
					        add constraint project_graph_pk | 
				
			||||
 | 
					                primary key (id); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					/*点位布设表*/ | 
				
			||||
 | 
					create table project_points_deploy | 
				
			||||
 | 
					( | 
				
			||||
 | 
					        id serial not null, | 
				
			||||
 | 
					        point_id int not null, | 
				
			||||
 | 
					        graph_id int not null, | 
				
			||||
 | 
					        position varchar(1000) not null | 
				
			||||
 | 
					); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					create unique index project_points_deploy_id_uindex | 
				
			||||
 | 
					        on project_points_deploy (id); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					alter table project_points_deploy | 
				
			||||
 | 
					        add constraint project_points_deploy_pk | 
				
			||||
 | 
					                primary key (id); | 
				
			||||
@ -0,0 +1,72 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import { basicAction } from '@peace/utils' | 
				
			||||
 | 
					import { ApiTable } from '$utils' | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export function getProjectGraph(projectId) { | 
				
			||||
 | 
					    return (dispatch) => basicAction({ | 
				
			||||
 | 
					        type: 'get', | 
				
			||||
 | 
					        dispatch, | 
				
			||||
 | 
					        actionType: 'GET_PROJECT_PLANAR_GRAPH', | 
				
			||||
 | 
					        url: ApiTable.getProjectGraph.replace('{projectId}', projectId), | 
				
			||||
 | 
					        msg: { option: '获取结构物平面图' }, | 
				
			||||
 | 
					        reducer: { name: 'projectGraph' } | 
				
			||||
 | 
					    }); | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export function createGraph(data) { | 
				
			||||
 | 
					    return (dispatch) => basicAction({ | 
				
			||||
 | 
					        type: 'post', | 
				
			||||
 | 
					        data, | 
				
			||||
 | 
					        dispatch, | 
				
			||||
 | 
					        actionType: 'ADD_PROJECT_PLANAR_GRAPH', | 
				
			||||
 | 
					        url: ApiTable.createGraph, | 
				
			||||
 | 
					        msg: { option: '新增结构物平面图' }, | 
				
			||||
 | 
					    }); | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export function updateGraph(id, data) { | 
				
			||||
 | 
					    return (dispatch) => basicAction({ | 
				
			||||
 | 
					        type: 'post', | 
				
			||||
 | 
					        data, | 
				
			||||
 | 
					        dispatch, | 
				
			||||
 | 
					        actionType: 'UPDATE_PROJECT_PLANAR_GRAPH', | 
				
			||||
 | 
					        url: ApiTable.updateGraph.replace('{id}', id), | 
				
			||||
 | 
					        msg: { option: '修改结构物平面图' }, | 
				
			||||
 | 
					    }); | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export function deleteGraph(id) { | 
				
			||||
 | 
					    return (dispatch) => basicAction({ | 
				
			||||
 | 
					        type: 'del', | 
				
			||||
 | 
					        dispatch, | 
				
			||||
 | 
					        actionType: 'DELETE_PROJECT_GRAPH', | 
				
			||||
 | 
					        url: ApiTable.deleteGraph.replace('{id}', id), | 
				
			||||
 | 
					        msg: { | 
				
			||||
 | 
					            option: '删除结构物布设图', | 
				
			||||
 | 
					        }, | 
				
			||||
 | 
					    }); | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export function getDeployPoints(pictureId) { | 
				
			||||
 | 
					    return (dispatch) => basicAction({ | 
				
			||||
 | 
					        type: 'get', | 
				
			||||
 | 
					        dispatch, | 
				
			||||
 | 
					        actionType: 'GET_PROJECT_DEPLOY_POINTS', | 
				
			||||
 | 
					        url: ApiTable.getDeployPoints.replace('{pictureId}', pictureId), | 
				
			||||
 | 
					        msg: { option: '获取结构物平面图测点分布' }, | 
				
			||||
 | 
					        reducer: { name: 'projectDeployPoints' } | 
				
			||||
 | 
					    }); | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export function setDeployPoints(pictureId, data) { | 
				
			||||
 | 
					    return (dispatch) => basicAction({ | 
				
			||||
 | 
					        type: 'post', | 
				
			||||
 | 
					        data, | 
				
			||||
 | 
					        dispatch, | 
				
			||||
 | 
					        actionType: 'SET_PROJECT_DEPLOY_POINTS', | 
				
			||||
 | 
					        url: ApiTable.setDeployPoints.replace('{pictureId}', pictureId), | 
				
			||||
 | 
					        msg: { option: '结构物平面图点位布设' }, | 
				
			||||
 | 
					    }); | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,57 @@ | 
				
			|||||
 | 
					'use strict' | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import React, { Component, PropTypes } from 'react'; | 
				
			||||
 | 
					import { DropTarget } from 'react-dnd'; | 
				
			||||
 | 
					import StationSpot from './station-spot'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					const heatmapTarget = { | 
				
			||||
 | 
					    drop(props, monitor) { | 
				
			||||
 | 
					        //get item from station-spot.js
 | 
				
			||||
 | 
					        //item:{deployed, rect, spotInlist, info}
 | 
				
			||||
 | 
					        const item = monitor.getItem(); | 
				
			||||
 | 
					        const move = monitor.getDifferenceFromInitialOffset(); | 
				
			||||
 | 
					        props.onDeploySpot({ ...item, move }); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					}; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					function collect(connect, monitor) { | 
				
			||||
 | 
					    return { | 
				
			||||
 | 
					        connectDropTarget: connect.dropTarget(), | 
				
			||||
 | 
					        isOver: monitor.isOver() | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class Heatmap extends React.Component { | 
				
			||||
 | 
					    componentDidMount() { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    renderSpots() { | 
				
			||||
 | 
					        const { width, height, spots, onRemoveSpot } = this.props; | 
				
			||||
 | 
					        return spots.map(s => <StationSpot key={s.sensorId} info={s} | 
				
			||||
 | 
					            size={{ "width": width, "height": height }} | 
				
			||||
 | 
					            onRemoveSpot={onRemoveSpot} />); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    render() { | 
				
			||||
 | 
					        const { connectDropTarget, height, width, image } = this.props; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        let targetStyle = { | 
				
			||||
 | 
					            position: 'relative', | 
				
			||||
 | 
					            width: width, | 
				
			||||
 | 
					            // overflow:'hidden',
 | 
				
			||||
 | 
					            height: height, | 
				
			||||
 | 
					            background: `url("/_file-server/${image}") no-repeat`, | 
				
			||||
 | 
					            backgroundSize: '100% 100%', | 
				
			||||
 | 
					        }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        return connectDropTarget( | 
				
			||||
 | 
					            <div id="dragTarget" style={targetStyle}> | 
				
			||||
 | 
					                {this.renderSpots()} | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					        ) | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default DropTarget('stationSpot', heatmapTarget, collect)(Heatmap); | 
				
			||||
 | 
					
 | 
				
			||||
@ -0,0 +1,114 @@ | 
				
			|||||
 | 
					/** | 
				
			||||
 | 
					 * Created by yuanfenghua on 2018/6/18. | 
				
			||||
 | 
					 */ | 
				
			||||
 | 
					'use strict' | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import React, { Component } from 'react'; | 
				
			||||
 | 
					import { findDOMNode } from 'react-dom'; | 
				
			||||
 | 
					import { connect } from 'react-redux'; | 
				
			||||
 | 
					import { DragSource } from 'react-dnd'; | 
				
			||||
 | 
					import { Tooltip } from 'antd'; | 
				
			||||
 | 
					import { MinusOutlined } from '@ant-design/icons'; | 
				
			||||
 | 
					import Style from './style.css'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					const stationSource = { | 
				
			||||
 | 
					    beginDrag(props, monitor, component) { | 
				
			||||
 | 
					        const dom = findDOMNode(component); | 
				
			||||
 | 
					        const rect = { | 
				
			||||
 | 
					            x: dom.offsetLeft - dom.offsetParent.scrollLeft, | 
				
			||||
 | 
					            y: dom.offsetTop - dom.offsetParent.scrollTop | 
				
			||||
 | 
					        }; | 
				
			||||
 | 
					        const spotInlist = { | 
				
			||||
 | 
					            x: dom.getBoundingClientRect().left, | 
				
			||||
 | 
					            y: dom.getBoundingClientRect().top | 
				
			||||
 | 
					        }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        return { | 
				
			||||
 | 
					            info: props.info, | 
				
			||||
 | 
					            rect: rect, | 
				
			||||
 | 
					            spotInlist: spotInlist, | 
				
			||||
 | 
					            deployed: props.info.deployed | 
				
			||||
 | 
					        }; | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    endDrag(props, monitor) { | 
				
			||||
 | 
					        if (!monitor.didDrop() && props.onRemoveSpot) { | 
				
			||||
 | 
					            props.onRemoveSpot(monitor.getItem().info); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    canDrag(props) { | 
				
			||||
 | 
					        if (props.size) { | 
				
			||||
 | 
					            //热点图上的热点可拖拽
 | 
				
			||||
 | 
					            return true; | 
				
			||||
 | 
					        } else { | 
				
			||||
 | 
					            //测点树未布设的叶结点可拖拽
 | 
				
			||||
 | 
					            return !props.children && props.info.deployed == false | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					}; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					function collect(connect, monitor) { | 
				
			||||
 | 
					    return { | 
				
			||||
 | 
					        connectDragSource: connect.dragSource(), | 
				
			||||
 | 
					        isDragging: monitor.isDragging() | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class StationSpot extends React.Component { | 
				
			||||
 | 
					    constructor(props) { | 
				
			||||
 | 
					        super(props); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    renderTreeTitle = () => { | 
				
			||||
 | 
					        const { isDragging, info } = this.props; | 
				
			||||
 | 
					        const { spotId, location, deployed } = info; | 
				
			||||
 | 
					        const opacity = isDragging ? 0.4 : 1; | 
				
			||||
 | 
					        return ( | 
				
			||||
 | 
					            <span style={{ lineHeight: '15px', opacity }} className={Style['icon']}> | 
				
			||||
 | 
					                <span key={spotId}> | 
				
			||||
 | 
					                    <Tooltip title={location}> | 
				
			||||
 | 
					                        <span className={deployed == false ? Style['station-tree-node-normal'] : null}>{location.length >= 12 ? location.substring(0, 12) + "..." : location}</span> | 
				
			||||
 | 
					                    </Tooltip> | 
				
			||||
 | 
					                    {deployed ? <MinusOutlined type="minus-circle-o" className={Style['tip']} onClick={this.onRemoveSpot} /> : null} | 
				
			||||
 | 
					                </span> | 
				
			||||
 | 
					            </span> | 
				
			||||
 | 
					        ); | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    onRemoveSpot = () => { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        const { onRemoveSpot, info } = this.props; | 
				
			||||
 | 
					        if (onRemoveSpot) { | 
				
			||||
 | 
					            onRemoveSpot(info); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    renderHotspot = () => { | 
				
			||||
 | 
					        const { info, size } = this.props; | 
				
			||||
 | 
					        const { key, location, x, y, screenWidth, screenHeight } = info; | 
				
			||||
 | 
					        const { width, height } = size; | 
				
			||||
 | 
					        let style = { | 
				
			||||
 | 
					            position: 'absolute', | 
				
			||||
 | 
					            left: width * x / screenWidth, | 
				
			||||
 | 
					            top: height * y / screenHeight, | 
				
			||||
 | 
					            cursor: 'move' | 
				
			||||
 | 
					        }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        return <span style={style}> | 
				
			||||
 | 
					            <Tooltip title={location}> | 
				
			||||
 | 
					                <div style={{ height: 24, width: 24, borderRadius: '100%', backgroundColor: 'rgba(16,142,233,0.2)', padding: '5px' }}> | 
				
			||||
 | 
					                    <div style={{ height: 14, width: 14, borderRadius: '100%', backgroundColor: '#108ee9', boxShadow: '0 0 10px #108ee9' }}></div> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					            </Tooltip> | 
				
			||||
 | 
					        </span> | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    render() { | 
				
			||||
 | 
					        const { connectDragSource, size } = this.props; | 
				
			||||
 | 
					        return connectDragSource( | 
				
			||||
 | 
					            size ? this.renderHotspot() : this.renderTreeTitle() | 
				
			||||
 | 
					        ); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default connect()(DragSource('stationSpot', stationSource, collect)(StationSpot)); | 
				
			||||
@ -0,0 +1,91 @@ | 
				
			|||||
 | 
					.station-tree-node-normal{ | 
				
			||||
 | 
					    margin-right: 6px; | 
				
			||||
 | 
					    padding: 0 4px; | 
				
			||||
 | 
					    height: 15px; | 
				
			||||
 | 
					    line-height: 15px; | 
				
			||||
 | 
					    background: #108ee9; | 
				
			||||
 | 
					    color: #fff; | 
				
			||||
 | 
					    font-size: 12px; | 
				
			||||
 | 
					    text-align: center; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon .tip{ | 
				
			||||
 | 
					    margin-left:10px; | 
				
			||||
 | 
					    -webkit-transition:opacity 0.1s 0.2s; | 
				
			||||
 | 
					    opacity:0; | 
				
			||||
 | 
					    pointer-events:none; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					.icon:hover .tip{ | 
				
			||||
 | 
					    -webkit-transition:opacity 0.2s; | 
				
			||||
 | 
					    opacity:1; | 
				
			||||
 | 
					    pointer-events:auto; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					.icon .tip:hover{ | 
				
			||||
 | 
					    -webkit-transition:none; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					:global(.no-card-border>.ant-card-head){ | 
				
			||||
 | 
					    border: none; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.cardCoverBox{ | 
				
			||||
 | 
					    position: absolute; | 
				
			||||
 | 
					    top: 50px; | 
				
			||||
 | 
					    left: 0; | 
				
			||||
 | 
					    right: 0; | 
				
			||||
 | 
					    bottom: 0; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					.cardCover{ | 
				
			||||
 | 
					    display: flex; | 
				
			||||
 | 
					    flex-direction: column; | 
				
			||||
 | 
					    justify-content: center; | 
				
			||||
 | 
					    position: absolute; | 
				
			||||
 | 
					    top: 0; | 
				
			||||
 | 
					    left: 0; | 
				
			||||
 | 
					    right: 0; | 
				
			||||
 | 
					    bottom: 0; | 
				
			||||
 | 
					    width: 100%; | 
				
			||||
 | 
					    height: 100%; | 
				
			||||
 | 
					    background-color: rgba(240 , 240, 240, 0.9); | 
				
			||||
 | 
					    z-index: 2; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					.cardCover .btnCell{ | 
				
			||||
 | 
					    text-align: center; | 
				
			||||
 | 
					    margin: 25px; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.cardFootCover{ | 
				
			||||
 | 
					    display: flex; | 
				
			||||
 | 
					    justify-content: space-around; | 
				
			||||
 | 
					    align-items: center; | 
				
			||||
 | 
					    position: absolute; | 
				
			||||
 | 
					    top: 0; | 
				
			||||
 | 
					    width: 100%; | 
				
			||||
 | 
					    height: 100%; | 
				
			||||
 | 
					    background-color: rgba(255, 255, 255, 0.9); | 
				
			||||
 | 
					    z-index: 1; | 
				
			||||
 | 
					    opacity: 0; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					.cardFootCover:hover{ | 
				
			||||
 | 
					    opacity: 1; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					.deleteBox{ | 
				
			||||
 | 
					    margin: 0 40px; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					.deleteBox h3{ | 
				
			||||
 | 
					    text-align: center; | 
				
			||||
 | 
					    margin-bottom: 5px; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					.deleteBox .btnRow{ | 
				
			||||
 | 
					    display: flex; | 
				
			||||
 | 
					    justify-content: space-around; | 
				
			||||
 | 
					    margin-top: 10px; | 
				
			||||
 | 
					    width: 100%; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					.loadingBox{ | 
				
			||||
 | 
					    width: 100%; | 
				
			||||
 | 
					    margin-bottom: 50px; | 
				
			||||
 | 
					    text-align: center; | 
				
			||||
 | 
					    padding: 50px 0; | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,384 @@ | 
				
			|||||
 | 
					'use strict' | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import React, { Component } from 'react'; | 
				
			||||
 | 
					import { connect } from 'react-redux'; | 
				
			||||
 | 
					import { findDOMNode } from 'react-dom'; | 
				
			||||
 | 
					import Heatmap from '../../components/pointDeploy/heatmap'; | 
				
			||||
 | 
					import { DragDropContext } from 'react-dnd'; | 
				
			||||
 | 
					import HTML5Backend from 'react-dnd-html5-backend'; | 
				
			||||
 | 
					import { Layout, Tree, Button, Input, Popconfirm, message, Spin } from 'antd' | 
				
			||||
 | 
					const { Content, Sider } = Layout; | 
				
			||||
 | 
					const Search = Input.Search; | 
				
			||||
 | 
					const TreeNode = Tree.TreeNode; | 
				
			||||
 | 
					import StationSpot from '../../components/pointDeploy/station-spot'; | 
				
			||||
 | 
					import './deploy-style.less'; | 
				
			||||
 | 
					import { getProjectGraph, deleteGraph, getDeployPoints, setDeployPoints } from '../../actions/graph'; | 
				
			||||
 | 
					import UploadImgModal from './upload-img-modal'; | 
				
			||||
 | 
					import PerfectScrollbar from 'perfect-scrollbar'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class ConfigPlanarGraph extends Component { | 
				
			||||
 | 
					    constructor(props) { | 
				
			||||
 | 
					        super(props); | 
				
			||||
 | 
					        this.ps = null; | 
				
			||||
 | 
					        this.state = { | 
				
			||||
 | 
					            uploadImgModal: '', | 
				
			||||
 | 
					            searchValue: '', | 
				
			||||
 | 
					            deployState: -1, //0未布,1已布,-1全部
 | 
				
			||||
 | 
					            filteredSpots: [], | 
				
			||||
 | 
					            spots: [], | 
				
			||||
 | 
					            dataHasChanged: false, | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        this.projectId = props?.match?.params?.id | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    componentDidUpdate() { | 
				
			||||
 | 
					        let ele = document.getElementById('security-spots-scroller'); | 
				
			||||
 | 
					        if (ele) { | 
				
			||||
 | 
					            this.ps = new PerfectScrollbar(ele); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    componentDidMount() { | 
				
			||||
 | 
					        this.getData(); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    getData = () => { | 
				
			||||
 | 
					        this.props.dispatch(getProjectGraph(this.projectId)).then(_ => { | 
				
			||||
 | 
					            if (_.success) { | 
				
			||||
 | 
					                let graph = _.payload.data; | 
				
			||||
 | 
					                if (graph) {//有图片
 | 
				
			||||
 | 
					                    this.props.dispatch(getDeployPoints(graph.id));//获取平面图点位分布
 | 
				
			||||
 | 
					                } else { | 
				
			||||
 | 
					                    this.setSpotsState([]); | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        }); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    componentWillReceiveProps(nextProps) { | 
				
			||||
 | 
					        const { projectDeployPoints } = nextProps; | 
				
			||||
 | 
					        if (projectDeployPoints && projectDeployPoints != this.props.projectDeployPoints) { | 
				
			||||
 | 
					            this.setSpotsState(projectDeployPoints); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    setSpotsState = (projectDeployPoints) => { | 
				
			||||
 | 
					        let deployedSpotsMap = new Map(); | 
				
			||||
 | 
					        projectDeployPoints.setedPoints?.forEach(s => { | 
				
			||||
 | 
					            deployedSpotsMap.set(s.pointId, s); | 
				
			||||
 | 
					        }); | 
				
			||||
 | 
					        let tempData = []; | 
				
			||||
 | 
					        projectDeployPoints.allPoints?.map(m => { | 
				
			||||
 | 
					            let x = null, y = null, screenH = null, screenW = null; | 
				
			||||
 | 
					            let deployed = false; | 
				
			||||
 | 
					            let station = deployedSpotsMap.get(m.id); | 
				
			||||
 | 
					            if (station) { | 
				
			||||
 | 
					                let p = JSON.parse(station.position); | 
				
			||||
 | 
					                x = p.x; | 
				
			||||
 | 
					                y = p.y; | 
				
			||||
 | 
					                screenH = p.screenHeight; | 
				
			||||
 | 
					                screenW = p.screenWidth; | 
				
			||||
 | 
					                deployed = true; | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					            tempData.push({ | 
				
			||||
 | 
					                groupId: 1, | 
				
			||||
 | 
					                groupName: '全部', | 
				
			||||
 | 
					                pointId: m.id, | 
				
			||||
 | 
					                location: m.name, | 
				
			||||
 | 
					                x: x, | 
				
			||||
 | 
					                y: y, | 
				
			||||
 | 
					                screenHeight: screenH, | 
				
			||||
 | 
					                screenWidth: screenW, | 
				
			||||
 | 
					                deployed: deployed, | 
				
			||||
 | 
					            }) | 
				
			||||
 | 
					        }); | 
				
			||||
 | 
					        this.setState({ | 
				
			||||
 | 
					            spots: tempData, | 
				
			||||
 | 
					            filteredSpots: tempData, | 
				
			||||
 | 
					        }); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    onAddImgClick = () => { | 
				
			||||
 | 
					        this.openPcrModal(null) | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    editHandler = (heatmap) => { | 
				
			||||
 | 
					        this.openPcrModal(heatmap) | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    openPcrModal = (heatmap) => { | 
				
			||||
 | 
					        const { dispatch } = this.props; | 
				
			||||
 | 
					        this.setState({ | 
				
			||||
 | 
					            uploadImgModal: <UploadImgModal | 
				
			||||
 | 
					                dispatch={dispatch} | 
				
			||||
 | 
					                projectId={this.projectId} | 
				
			||||
 | 
					                pictureInfo={heatmap} | 
				
			||||
 | 
					                onCancel={this.closeUploadPointsImgModal} | 
				
			||||
 | 
					                getData={this.getData} | 
				
			||||
 | 
					            />, | 
				
			||||
 | 
					        }) | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    closeUploadPointsImgModal = () => { | 
				
			||||
 | 
					        this.setState({ uploadImgModal: '' }) | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    onDeploySpot = (spot) => { | 
				
			||||
 | 
					        const { pictureInfo, clientHeight, clientWidth } = this.props; | 
				
			||||
 | 
					        const { spots, deployState, searchValue, partsSpots } = this.state; | 
				
			||||
 | 
					        const that = this; | 
				
			||||
 | 
					        let h = clientHeight / 1.3; | 
				
			||||
 | 
					        let w = clientWidth / 1.3; | 
				
			||||
 | 
					        function dealPosition(spot, item) { | 
				
			||||
 | 
					            if (spot.deployed) { | 
				
			||||
 | 
					                item.x = spot.rect.x + spot.move.x; | 
				
			||||
 | 
					                item.y = spot.rect.y + spot.move.y; | 
				
			||||
 | 
					                item.screenHeight = h; | 
				
			||||
 | 
					                item.screenWidth = w; | 
				
			||||
 | 
					            } else { | 
				
			||||
 | 
					                const boundingClientRect = findDOMNode(that.refs.heatmapComponent).getBoundingClientRect(); | 
				
			||||
 | 
					                item.x = spot.spotInlist.x + spot.move.x - boundingClientRect.left; | 
				
			||||
 | 
					                item.y = spot.spotInlist.y + spot.move.y - boundingClientRect.top; | 
				
			||||
 | 
					                item.screenHeight = h; | 
				
			||||
 | 
					                item.screenWidth = w; | 
				
			||||
 | 
					                item.deployed = true; | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        if (pictureInfo) { | 
				
			||||
 | 
					            let tempSpots = Object.assign([], spots); | 
				
			||||
 | 
					            if (spot.info.pointId) { | 
				
			||||
 | 
					                tempSpots.forEach(item => { | 
				
			||||
 | 
					                    if (item.pointId == spot.info.pointId) { | 
				
			||||
 | 
					                        dealPosition(spot, item) | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                }); | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            this.setState({ spots: tempSpots }); | 
				
			||||
 | 
					            this.filterSpots(deployState, searchValue); | 
				
			||||
 | 
					            this.setState({ changedTreeNodeKey: spot.info.key, dataHasChanged: true }); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    filterSpots = (deployState, searchValue) => { | 
				
			||||
 | 
					        let deploySpots = this.state.spots; | 
				
			||||
 | 
					        if (deployState != -1) { | 
				
			||||
 | 
					            deploySpots = this.state.spots.filter(s => s.deployed == (deployState == 1 ? true : false)); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        let searchSpots = deploySpots; | 
				
			||||
 | 
					        if (searchValue.trim().length > 0) { | 
				
			||||
 | 
					            searchSpots = deploySpots.filter(s => s.location.indexOf(searchValue) >= 0); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        this.setState({ | 
				
			||||
 | 
					            searchValue, | 
				
			||||
 | 
					            deployState, | 
				
			||||
 | 
					            filteredSpots: searchSpots | 
				
			||||
 | 
					        }); | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    onSearch = (searchValue) => { | 
				
			||||
 | 
					        this.filterSpots(this.state.deployState, searchValue); | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					    handleStateChange = (deployState) => { | 
				
			||||
 | 
					        this.filterSpots(deployState, this.state.searchValue); | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    onRemoveSpot = (spot) => { | 
				
			||||
 | 
					        const { pictureInfo } = this.props; | 
				
			||||
 | 
					        const { spots, deployState, searchValue, partsSpots } = this.state; | 
				
			||||
 | 
					        if (pictureInfo) { | 
				
			||||
 | 
					            let tempSpots; | 
				
			||||
 | 
					            if (spot.pointId) { | 
				
			||||
 | 
					                tempSpots = Object.assign([], spots); | 
				
			||||
 | 
					                tempSpots.forEach(item => { | 
				
			||||
 | 
					                    if (item.pointId == spot.pointId) { | 
				
			||||
 | 
					                        item.x = null; | 
				
			||||
 | 
					                        item.y = null; | 
				
			||||
 | 
					                        item.screenWidth = null; | 
				
			||||
 | 
					                        item.screenHeight = null; | 
				
			||||
 | 
					                        item.deployed = false; | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                }); | 
				
			||||
 | 
					                tempSpots = tempSpots.concat(partsSpots) | 
				
			||||
 | 
					            } else { | 
				
			||||
 | 
					                tempSpots = Object.assign([], partsSpots); | 
				
			||||
 | 
					                tempSpots.forEach(item => { | 
				
			||||
 | 
					                    if (item.partId == spot.partId) { | 
				
			||||
 | 
					                        item.x = null; | 
				
			||||
 | 
					                        item.y = null; | 
				
			||||
 | 
					                        item.screenWidth = null; | 
				
			||||
 | 
					                        item.screenHeight = null; | 
				
			||||
 | 
					                        item.deployed = false; | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                }); | 
				
			||||
 | 
					                tempSpots = tempSpots.concat(spots) | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					            this.filterSpots(deployState, searchValue); | 
				
			||||
 | 
					            this.setState({ changedTreeNodeKey: spot.key, dataHasChanged: true }); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    loop = (data) => { | 
				
			||||
 | 
					        if (!data || data.length == 0) return; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        const treeNodes = []; | 
				
			||||
 | 
					        data.forEach((item) => { | 
				
			||||
 | 
					            let title = <StationSpot info={item} children={item.children} />; | 
				
			||||
 | 
					            if (item.children) { | 
				
			||||
 | 
					                treeNodes.push( | 
				
			||||
 | 
					                    <TreeNode key={item.key} title={title}> | 
				
			||||
 | 
					                        {this.loop(item.children)} | 
				
			||||
 | 
					                    </TreeNode> | 
				
			||||
 | 
					                ); | 
				
			||||
 | 
					            } else { | 
				
			||||
 | 
					                let titleProps = { | 
				
			||||
 | 
					                    info: item, | 
				
			||||
 | 
					                    children: item.children, | 
				
			||||
 | 
					                    onRemoveSpot: this.onRemoveSpot, | 
				
			||||
 | 
					                }; | 
				
			||||
 | 
					                //性能优化,减少组件渲染
 | 
				
			||||
 | 
					                if (this.state.changedTreeNodeKey == item.key) titleProps.key = Math.random(); | 
				
			||||
 | 
					                let nodeTitle = <StationSpot {...titleProps} />; | 
				
			||||
 | 
					                treeNodes.push(<TreeNode key={item.key} title={nodeTitle} />); | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        }); | 
				
			||||
 | 
					        return treeNodes; | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    formatTreeSource = (data) => { | 
				
			||||
 | 
					        if (!data || data.length == 0) return; | 
				
			||||
 | 
					        let tempGroups = new Map(); | 
				
			||||
 | 
					        data.map(item => { | 
				
			||||
 | 
					            if (tempGroups.has(item.groupId)) { | 
				
			||||
 | 
					                let groupChildren = tempGroups.get(item.groupId).children; | 
				
			||||
 | 
					                item.key = `0-${item.groupId}-${item.pointId}`; | 
				
			||||
 | 
					                groupChildren.set(item.pointId, item); | 
				
			||||
 | 
					            } else { | 
				
			||||
 | 
					                tempGroups.set(item.groupId, { | 
				
			||||
 | 
					                    'key': `0-${item.groupId}`, | 
				
			||||
 | 
					                    'location': item.groupName, | 
				
			||||
 | 
					                    'groupId': item.groupId, | 
				
			||||
 | 
					                    'children': new Map(), | 
				
			||||
 | 
					                }); | 
				
			||||
 | 
					                let groupChildren = tempGroups.get(item.groupId).children; | 
				
			||||
 | 
					                item.key = `0-${item.groupId}-${item.pointId}`; | 
				
			||||
 | 
					                groupChildren.set(item.pointId, item); | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        }); | 
				
			||||
 | 
					        return tempGroups; | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    onSaveClick = () => { | 
				
			||||
 | 
					        this.saveHotspots(this.state.spots); | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    saveHotspots = (data) => { | 
				
			||||
 | 
					        const { pictureInfo } = this.props; | 
				
			||||
 | 
					        let postData = data.filter(s => s.x != null && s.y != null).map(item => { | 
				
			||||
 | 
					            const { x, y, screenWidth, screenHeight } = item; | 
				
			||||
 | 
					            let relativeX = parseFloat((x / screenWidth).toFixed(4)); | 
				
			||||
 | 
					            let relativeY = parseFloat((y / screenHeight).toFixed(4)); | 
				
			||||
 | 
					            if (item.pointId) { | 
				
			||||
 | 
					                return ({ | 
				
			||||
 | 
					                    pointId: item.pointId, | 
				
			||||
 | 
					                    position: { x, y, screenWidth, screenHeight, relativeX, relativeY } | 
				
			||||
 | 
					                }) | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        }); | 
				
			||||
 | 
					        this.props.dispatch(setDeployPoints(pictureInfo.id, { "spots": postData })).then(res => { | 
				
			||||
 | 
					            message.success(res.payload.message); | 
				
			||||
 | 
					            this.setState({ dataHasChanged: false, deployState: -1 }, () => { | 
				
			||||
 | 
					                this.props.dispatch(getDeployPoints(pictureInfo.id));//获取平面图点位分布
 | 
				
			||||
 | 
					            }); | 
				
			||||
 | 
					        }); | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    render() { | 
				
			||||
 | 
					        const { pictureInfo, clientHeight, clientWidth } = this.props; | 
				
			||||
 | 
					        const { deployState, spots, filteredSpots, dataHasChanged } = this.state; | 
				
			||||
 | 
					        const treeDataSource = this.formatTreeSource(filteredSpots); | 
				
			||||
 | 
					        let h = clientHeight / 1.3; | 
				
			||||
 | 
					        let w = clientWidth / 1.3; | 
				
			||||
 | 
					        return (<div className='patrolLayout'> | 
				
			||||
 | 
					            <Layout> | 
				
			||||
 | 
					                <Sider width={230} style={{ background: 'transparent', height: 400 }}> | 
				
			||||
 | 
					                    <div className='search-panel'> | 
				
			||||
 | 
					                        <Button className={deployState == -1 ? 'btn-spots-filter' : 'btn-default'} style={{ borderRadius: 0 }} onClick={() => this.handleStateChange(-1)}>全部</Button> | 
				
			||||
 | 
					                        <Button className={deployState == 1 ? 'btn-spots-filter' : 'btn-default'} style={{ borderRadius: 0 }} onClick={() => this.handleStateChange(1)}>已布</Button> | 
				
			||||
 | 
					                        <Button className={deployState == 0 ? 'btn-spots-filter' : 'btn-default'} style={{ borderRadius: 0 }} onClick={() => this.handleStateChange(0)}>未布</Button> | 
				
			||||
 | 
					                        <div style={{ marginTop: -1 }}> | 
				
			||||
 | 
					                            <Search | 
				
			||||
 | 
					                                placeholder={"请输入名称关键字搜索"} | 
				
			||||
 | 
					                                style={{ borderRadius: 0 }} | 
				
			||||
 | 
					                                onChange={e => this.onSearch(e.target.value)} | 
				
			||||
 | 
					                            /> | 
				
			||||
 | 
					                        </div> | 
				
			||||
 | 
					                    </div> | 
				
			||||
 | 
					                    { | 
				
			||||
 | 
					                        treeDataSource ? | 
				
			||||
 | 
					                            <div id='security-spots-scroller' style={{ position: 'relative', height: 600 }}> | 
				
			||||
 | 
					                                <Tree className='equip-tree' showLine defaultExpandAll={true}> | 
				
			||||
 | 
					                                    {this.loop(treeDataSource)} | 
				
			||||
 | 
					                                </Tree> </div> : <div style={{ textAlign: 'center' }}>暂无点位</div> | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                </Sider> | 
				
			||||
 | 
					                <Layout> | 
				
			||||
 | 
					                    <Content className='spots-opr-content' style={{ width: w }}> | 
				
			||||
 | 
					                        {spots && pictureInfo?.graph ? | 
				
			||||
 | 
					                            <Heatmap key={Math.random()} | 
				
			||||
 | 
					                                ref="heatmapComponent" | 
				
			||||
 | 
					                                height={h} | 
				
			||||
 | 
					                                width={w} | 
				
			||||
 | 
					                                image={pictureInfo?.graph} | 
				
			||||
 | 
					                                spots={spots.filter(s => s.deployed == true)} | 
				
			||||
 | 
					                                onRemoveSpot={this.onRemoveSpot} | 
				
			||||
 | 
					                                onDeploySpot={this.onDeploySpot} | 
				
			||||
 | 
					                            /> | 
				
			||||
 | 
					                            : <div style={{ border: '1px dashed #999', width: w, height: h, paddingTop: clientHeight * 0.4, textAlign: 'center' }}> | 
				
			||||
 | 
					                                暂无热点图 | 
				
			||||
 | 
					                            </div> | 
				
			||||
 | 
					                        } | 
				
			||||
 | 
					                        <div className='opr-tip-row'> | 
				
			||||
 | 
					                            <div>说明:拖拽点位进行布设,拖出画布移除点位。</div> | 
				
			||||
 | 
					                            { | 
				
			||||
 | 
					                                pictureInfo ? | 
				
			||||
 | 
					                                    <div className='opr-button'> | 
				
			||||
 | 
					                                        <Popconfirm | 
				
			||||
 | 
					                                            title='确认删除该结构物布设图?(已布点位将同步删除)' | 
				
			||||
 | 
					                                            position='top' | 
				
			||||
 | 
					                                            onConfirm={() => { | 
				
			||||
 | 
					                                                this.props.dispatch(deleteGraph(pictureInfo.id)).then(_ => { | 
				
			||||
 | 
					                                                    this.getData(); | 
				
			||||
 | 
					                                                }) | 
				
			||||
 | 
					                                            }}> | 
				
			||||
 | 
					                                            <Button className='graph-cfg-btn'>删除图片</Button> | 
				
			||||
 | 
					                                        </Popconfirm> | 
				
			||||
 | 
					                                        <Button className='graph-cfg-btn' onClick={() => this.editHandler(pictureInfo)} style={{ marginLeft: 15 }}>修改图片</Button> | 
				
			||||
 | 
					                                        <Button className='graph-cfg-btn' type='primary' onClick={this.onSaveClick} disabled={!dataHasChanged} style={{ marginLeft: 15 }}>完成</Button> | 
				
			||||
 | 
					                                    </div> | 
				
			||||
 | 
					                                    : | 
				
			||||
 | 
					                                    <div className='opr-button'> | 
				
			||||
 | 
					                                        <Button className='graph-cfg-btn' type='primary' onClick={this.onAddImgClick}>添加布设图</Button> | 
				
			||||
 | 
					                                    </div> | 
				
			||||
 | 
					                            } | 
				
			||||
 | 
					                        </div> | 
				
			||||
 | 
					                    </Content> | 
				
			||||
 | 
					                </Layout> | 
				
			||||
 | 
					            </Layout> | 
				
			||||
 | 
					            {this.state.uploadImgModal} | 
				
			||||
 | 
					        </div>) | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					function mapStateToProps(state) { | 
				
			||||
 | 
					    const { global, projectGraph, projectDeployPoints } = state; | 
				
			||||
 | 
					    return { | 
				
			||||
 | 
					        pictureInfo: projectGraph.data, | 
				
			||||
 | 
					        projectDeployPoints: projectDeployPoints.data, | 
				
			||||
 | 
					        clientHeight: global.clientHeight, | 
				
			||||
 | 
					        clientWidth: global.clientWidth | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default connect(mapStateToProps)(DragDropContext(HTML5Backend)(ConfigPlanarGraph)); | 
				
			||||
@ -0,0 +1,114 @@ | 
				
			|||||
 | 
					.search-panel { | 
				
			||||
 | 
					    text-align: center; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.search-panel input { | 
				
			||||
 | 
					    -webkit-border-radius: 0; | 
				
			||||
 | 
					    -moz-border-radius: 0; | 
				
			||||
 | 
					    border-radius: 0; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.spots-opr-content { | 
				
			||||
 | 
					    padding: 0; | 
				
			||||
 | 
					    margin: 0; | 
				
			||||
 | 
					    position: relative; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.opr-tip-row { | 
				
			||||
 | 
					    display: flex; | 
				
			||||
 | 
					    margin-top: 10px; | 
				
			||||
 | 
					    justify-content: space-between; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.opr-button { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    .ant-btn-disabled, | 
				
			||||
 | 
					    .ant-btn.disabled, | 
				
			||||
 | 
					    .ant-btn[disabled] { | 
				
			||||
 | 
					        //按钮 禁用  | 
				
			||||
 | 
					        background-color: #3198F7; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.graph-cfg-btn { | 
				
			||||
 | 
					    color: #fff; | 
				
			||||
 | 
					    background-color: #3198F7; | 
				
			||||
 | 
					    border-color: #3198F7; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					//蓝色按钮 鼠标悬浮 | 
				
			||||
 | 
					.graph-cfg-btn:hover, | 
				
			||||
 | 
					.graph-cfg-btn:focus { | 
				
			||||
 | 
					    //color: #fff; | 
				
			||||
 | 
					    background-color: #3198F7; | 
				
			||||
 | 
					    border-color: #3198F7; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.patrolLayout { | 
				
			||||
 | 
					    margin-top: 20px; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    .ant-layout { | 
				
			||||
 | 
					        background-color: transparent; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    .ant-input:hover, | 
				
			||||
 | 
					    .ant-input:focus { | 
				
			||||
 | 
					        border-color: #fff; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.equip-tree { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    //测点 树结构 | 
				
			||||
 | 
					    .ant-tree.ant-tree-show-line li span.ant-tree-switcher { | 
				
			||||
 | 
					        //展开, 关闭按钮 | 
				
			||||
 | 
					        color: #fff; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    .ant-tree li .ant-tree-node-content-wrapper { | 
				
			||||
 | 
					        //文字白色 | 
				
			||||
 | 
					        color: #fff; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    .ant-tree.ant-tree-show-line li:not(:last-child)::before { | 
				
			||||
 | 
					        //不显示竖线 | 
				
			||||
 | 
					        width: 0px; | 
				
			||||
 | 
					        border: 0px; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    .ant-tree li .ant-tree-node-content-wrapper.ant-tree-node-selected { | 
				
			||||
 | 
					        background-color: #98e5f381; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    .ant-tree-node-content-wrapper:hover, | 
				
			||||
 | 
					    .ant-tree-node-content-wrapper:focus { | 
				
			||||
 | 
					        //文字鼠标悬浮 背景色 蓝色 | 
				
			||||
 | 
					        background-color: #3198F7 !important; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					//查询按钮 | 
				
			||||
 | 
					.ant-input-group-addon { | 
				
			||||
 | 
					    background-color: transparent; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    .ant-btn { | 
				
			||||
 | 
					        background-color: transparent !important; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    .ant-btn-primary { | 
				
			||||
 | 
					        float: right; | 
				
			||||
 | 
					        width: 90px; | 
				
			||||
 | 
					        height: 45px; | 
				
			||||
 | 
					        margin: 5px 0px 0px 10px; | 
				
			||||
 | 
					        background-color: #3198f7; | 
				
			||||
 | 
					        border-color: #3198f7; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    .ant-btn-primary:hover { | 
				
			||||
 | 
					        border-color: #3198f7; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    .ant-btn-primary:focus { | 
				
			||||
 | 
					        border-color: #3198f7; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,94 @@ | 
				
			|||||
 | 
					import React, { useEffect, useState } from 'react'; | 
				
			||||
 | 
					import { connect } from 'react-redux'; | 
				
			||||
 | 
					import Uploads from '$components/Uploads'; | 
				
			||||
 | 
					import { Input, Modal, Form, Button, message, Select } from 'antd'; | 
				
			||||
 | 
					import { getProjectGraph, createGraph, updateGraph } from '../../actions/graph'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					const DisclosureModal = (props) => { | 
				
			||||
 | 
					    const { dispatch, onCancel, projectId, pictureInfo, getData } = props; | 
				
			||||
 | 
					    let files = pictureInfo ? [{ storageUrl: pictureInfo.graph }] : [] | 
				
			||||
 | 
					    const [form] = Form.useForm(); | 
				
			||||
 | 
					    const [editUrl, setEditUrl] = useState(files); | 
				
			||||
 | 
					    //初始化表单数据
 | 
				
			||||
 | 
					    const getinitialValues = () => { | 
				
			||||
 | 
					        if (pictureInfo) { | 
				
			||||
 | 
					            return { files: 1 }; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        return {} | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    useEffect(() => { | 
				
			||||
 | 
					    }, []); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const handleOk = () => { | 
				
			||||
 | 
					        form.validateFields().then(values => { | 
				
			||||
 | 
					            let data = { | 
				
			||||
 | 
					                projectId: projectId, | 
				
			||||
 | 
					                graph: editUrl[0]?.storageUrl, | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					            if (pictureInfo) {//更新
 | 
				
			||||
 | 
					                dispatch(updateGraph(pictureInfo.id, data)).then(_ => { | 
				
			||||
 | 
					                    getData() | 
				
			||||
 | 
					                }); | 
				
			||||
 | 
					            } else {//新增
 | 
				
			||||
 | 
					                dispatch(createGraph(data)).then(_ => { | 
				
			||||
 | 
					                    getData(); | 
				
			||||
 | 
					                }); | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					            onCancel() | 
				
			||||
 | 
					        }) | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const vsjunct = (params) => { | 
				
			||||
 | 
					        if (params.length) { | 
				
			||||
 | 
					            let appendix = [] | 
				
			||||
 | 
					            for (let p of params) { | 
				
			||||
 | 
					                appendix.push({ | 
				
			||||
 | 
					                    fName: p.name, | 
				
			||||
 | 
					                    size: p.size, | 
				
			||||
 | 
					                    fileSize: p.size, | 
				
			||||
 | 
					                    storageUrl: p.storageUrl,//必须有storageUrl
 | 
				
			||||
 | 
					                }) | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					            setEditUrl(appendix) | 
				
			||||
 | 
					        } else { | 
				
			||||
 | 
					            setEditUrl([]) | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    return ( | 
				
			||||
 | 
					        <Modal title='添加布设图' visible={true} destroyOnClose | 
				
			||||
 | 
					            onCancel={onCancel} onOk={handleOk}> | 
				
			||||
 | 
					            <Form form={form} labelCol={{ span: 6 }} wrapperCol={{ span: 17 }} initialValues={getinitialValues()}> | 
				
			||||
 | 
					                <Form.Item label="布设图" name='files' | 
				
			||||
 | 
					                    rules={[{ required: true, message: '请上传布设图' }]}> | 
				
			||||
 | 
					                    <Uploads | 
				
			||||
 | 
					                        className='upload' | 
				
			||||
 | 
					                        listType='card' | 
				
			||||
 | 
					                        uploadType='project' | 
				
			||||
 | 
					                        maxFilesNum={1} | 
				
			||||
 | 
					                        maxFileSize={10} | 
				
			||||
 | 
					                        isQiniu={true} | 
				
			||||
 | 
					                        onChange={vsjunct} | 
				
			||||
 | 
					                        fileTypes={["png", "jpeg", "jpg"]} | 
				
			||||
 | 
					                        value={editUrl} | 
				
			||||
 | 
					                        defaultValue={editUrl} | 
				
			||||
 | 
					                    /> | 
				
			||||
 | 
					                </Form.Item> | 
				
			||||
 | 
					                <Form.Item style={{ paddingLeft: '17%' }}> | 
				
			||||
 | 
					                    <div style={{ color: '#999', width: 460 }}>说明:附件格式为png、jpeg、jpg,大小不超过10MB</div> | 
				
			||||
 | 
					                </Form.Item> | 
				
			||||
 | 
					            </Form> | 
				
			||||
 | 
					        </Modal> | 
				
			||||
 | 
					    ) | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					function mapStateToProps(state) { | 
				
			||||
 | 
					    const { auth, global } = state; | 
				
			||||
 | 
					    return { | 
				
			||||
 | 
					        user: auth.user, | 
				
			||||
 | 
					        actions: global.actions, | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default connect(mapStateToProps)(DisclosureModal); | 
				
			||||
					Loading…
					
					
				
		Reference in new issue