一 、java后台
1.1
package com.admin.domain;/*** 功能描述:** @author wangwei* @date 2024-01-15 22:13*/
public class ConnectWeb {private String connectWebId;private String connectWebName;private String connectWebInfo;private String personWebIdAlpha;private String personWebIdBeta;private String personWebIdAlphaName;private String personWebIdBetaName;public String getPersonWebIdAlphaName() {return personWebIdAlphaName;}public void setPersonWebIdAlphaName(String personWebIdAlphaName) {this.personWebIdAlphaName = personWebIdAlphaName;}public String getPersonWebIdBetaName() {return personWebIdBetaName;}public void setPersonWebIdBetaName(String personWebIdBetaName) {this.personWebIdBetaName = personWebIdBetaName;}public String getConnectWebId() {return connectWebId;}public void setConnectWebId(String connectWebId) {this.connectWebId = connectWebId;}public String getConnectWebName() {return connectWebName;}public void setConnectWebName(String connectWebName) {this.connectWebName = connectWebName;}public String getConnectWebInfo() {return connectWebInfo;}public void setConnectWebInfo(String connectWebInfo) {this.connectWebInfo = connectWebInfo;}public String getPersonWebIdAlpha() {return personWebIdAlpha;}public void setPersonWebIdAlpha(String personWebIdAlpha) {this.personWebIdAlpha = personWebIdAlpha;}public String getPersonWebIdBeta() {return personWebIdBeta;}public void setPersonWebIdBeta(String personWebIdBeta) {this.personWebIdBeta = personWebIdBeta;}@Overridepublic String toString() {return "ConnectWeb{" +"connectWebId='" + connectWebId + '\'' +", connectWebName='" + connectWebName + '\'' +", connectWebInfo='" + connectWebInfo + '\'' +", personWebIdAlpha='" + personWebIdAlpha + '\'' +", personWebIdBeta='" + personWebIdBeta + '\'' +", personWebIdAlphaName='" + personWebIdAlphaName + '\'' +", personWebIdBetaName='" + personWebIdBetaName + '\'' +'}';}
}
1.2
package com.admin.domain;/*** 功能描述:*人物属性实体描述** @author wangwei* @date 2024-01-15 22:12*/
public class PersonWeb {private String personWebId;private String personWebName;private String personWebPic;private String personWebShow;private String personWebLink;private String personWebPlatform;private String personWebField;private String personWebInfo;private String personWebKey;public String getPersonWebId() {return personWebId;}public void setPersonWebId(String personWebId) {this.personWebId = personWebId;}public String getPersonWebName() {return personWebName;}public void setPersonWebName(String personWebName) {this.personWebName = personWebName;}public String getPersonWebPlatform() {return personWebPlatform;}public void setPersonWebPlatform(String personWebPlatform) {this.personWebPlatform = personWebPlatform;}public String getPersonWebField() {return personWebField;}public void setPersonWebField(String personWebField) {this.personWebField = personWebField;}public String getPersonWebInfo() {return personWebInfo;}public void setPersonWebInfo(String personWebInfo) {this.personWebInfo = personWebInfo;}public String getPersonWebKey() {return personWebKey;}public void setPersonWebKey(String personWebKey) {this.personWebKey = personWebKey;}public String getPersonWebPic() {return personWebPic;}public void setPersonWebPic(String personWebPic) {this.personWebPic = personWebPic;}public String getPersonWebShow() {return personWebShow;}public void setPersonWebShow(String personWebShow) {this.personWebShow = personWebShow;}public String getPersonWebLink() {return personWebLink;}public void setPersonWebLink(String personWebLink) {this.personWebLink = personWebLink;}@Overridepublic String toString() {return "PersonWeb{" +"personWebId='" + personWebId + '\'' +", personWebName='" + personWebName + '\'' +", personWebPic='" + personWebPic + '\'' +", personWebShow='" + personWebShow + '\'' +", personWebLink='" + personWebLink + '\'' +", personWebPlatform='" + personWebPlatform + '\'' +", personWebField='" + personWebField + '\'' +", personWebInfo='" + personWebInfo + '\'' +", personWebKey='" + personWebKey + '\'' +'}';}
}
1.3
package com.admin.controller;import com.admin.common.core.controller.BaseController;
import com.admin.common.core.domain.AjaxResult;
import com.admin.common.core.page.TableDataInfo;
import com.admin.domain.ConnectWeb;
import com.admin.domain.PersonWeb;
import com.admin.service.WebService;
import com.admin.utils.transport.Result;
import org.neo4j.driver.Record;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.List;/*** 功能描述:** @author wangwei* @date 2024-01-16 11:09*/
@RestController
@RequestMapping("/people/web")
public class WebController extends BaseController {@Autowiredprivate WebService webService;@GetMapping("/map")public TableDataInfo getPersonWebMap() {List<Record> list = webService.selectPersonWebMap();return getDataTable(list);}@GetMapping("/list")public TableDataInfo getPersonWebList() {List<PersonWeb> list = webService.selectPersonWebList();return getDataTable(list);}@GetMapping("/search/{personWebName}")public AjaxResult getPersonWebSearchList(@PathVariable("personWebName") String personWebName) {List<PersonWeb> list = webService.selectPersonWebSearchList(personWebName);return AjaxResult.success(list);}@GetMapping("/search/{personWebId}/{personWebName}")public AjaxResult getPersonWebSearchListOther(@PathVariable("personWebName") String personWebName, @PathVariable("personWebId") String personWebId) {List<PersonWeb> list = webService.selectPersonWebSearchListOther(personWebName, personWebId);return AjaxResult.success(list);}@GetMapping(value = "/person/{personWebId}")public AjaxResult getPersonWebInfo(@PathVariable("personWebId") String personWebId) {return AjaxResult.success(webService.selectPersonWebById(personWebId));}@PostMapping("/person")public AjaxResult addPersonWeb(@RequestBody PersonWeb personWeb) {return toAjax(webService.insertPersonWeb(personWeb));}@PutMapping("/person")public AjaxResult editPersonWeb(@RequestBody PersonWeb personWeb) {return toAjax(webService.updatePersonWeb(personWeb));}@DeleteMapping("/person/{personWebId}")public AjaxResult removePersonWeb(@PathVariable String personWebId) {try{int rsg = webService.deletePersonWeb(personWebId);return toAjax(rsg);} catch (Exception e){return AjaxResult.error(500, "此节点仍与其他节点有关联关系!");}}@GetMapping(value = "/connect/{connectWebId}")public AjaxResult getInfoConnectWeb(@PathVariable("connectWebId") String connectWebId) {return AjaxResult.success(webService.selectConnectWebById(connectWebId));}@PostMapping("/connect")public AjaxResult addConnectWeb(@RequestBody ConnectWeb connectWeb) {return toAjax(webService.insertConnectWeb(connectWeb));}@PutMapping("/connect")public AjaxResult editConnectWeb(@RequestBody ConnectWeb connectWeb) {return toAjax(webService.updateConnectWeb(connectWeb));}@DeleteMapping("/connect/{connectWebId}")public AjaxResult removeConnectWeb(@PathVariable String connectWebId) {return toAjax(webService.deleteConnectWeb(connectWebId));}
}
1.4
package com.admin.service;import com.admin.domain.ConnectWeb;
import com.admin.domain.PersonWeb;
import org.neo4j.driver.Record;import java.util.List;public interface WebService {List<Record> selectPersonWebMap();public List<PersonWeb> selectPersonWebList() ;public List<PersonWeb> selectPersonWebSearchList(String personWebName) ;public List<PersonWeb> selectPersonWebSearchListOther(String personWebName, String personWebId) ;public PersonWeb selectPersonWebById(String personWebId) ;public int insertPersonWeb(PersonWeb personWeb) ;public int updatePersonWeb(PersonWeb personWeb) ;public int deletePersonWeb(String personWebId) ;public ConnectWeb selectConnectWebById(String connectWebId) ;public int insertConnectWeb(ConnectWeb connectWeb) ;public int updateConnectWeb(ConnectWeb connectWeb) ;public int deleteConnectWeb(String connectWebId) ;}
1.5
package com.admin.service.impl;import com.admin.common.annotation.DataSource;
import com.admin.common.enums.DataSourceType;
import com.admin.domain.ConnectWeb;
import com.admin.domain.PersonWeb;
import com.admin.mapper.ConnectWebMapper;
import com.admin.mapper.PersonWebMapper;
import com.admin.service.WebService;
import com.admin.utils.SnowflakeIdWorker;
import org.neo4j.driver.Record;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class WebServiceImpl implements WebService {@Autowiredprivate PersonWebMapper personWebMapper;@Autowiredprivate ConnectWebMapper connectWebMapper;@Autowiredprivate SnowflakeIdWorker snowflakeIdWorker;@DataSource(value = DataSourceType.SLAVE)public List<Record> selectPersonWebMap() {return personWebMapper.selectPersonWebMap();}@DataSource(value = DataSourceType.SLAVE)public List<PersonWeb> selectPersonWebList() {List<PersonWeb> personWebs = personWebMapper.selectPersonWebList();return personWebs;}@DataSource(value = DataSourceType.SLAVE)public List<PersonWeb> selectPersonWebSearchList(String personWebName) {
// System.out.println(personWebName);return personWebMapper.selectPersonWebSearchList(personWebName);}@DataSource(value = DataSourceType.SLAVE)public List<PersonWeb> selectPersonWebSearchListOther(String personWebName, String personWebId) {
// System.out.println(personWebName);return personWebMapper.selectPersonWebSearchListOther(personWebName, personWebId);}@DataSource(value = DataSourceType.SLAVE)public PersonWeb selectPersonWebById(String personWebId) {return personWebMapper.selectPersonWebById(personWebId);}@DataSource(value = DataSourceType.SLAVE)public int insertPersonWeb(PersonWeb personWeb) {personWeb.setPersonWebId(snowflakeIdWorker.nextId());return personWebMapper.insertPersonWeb(personWeb);}@DataSource(value = DataSourceType.SLAVE)public int updatePersonWeb(PersonWeb personWeb) {return personWebMapper.updatePersonWeb(personWeb);}@DataSource(value = DataSourceType.SLAVE)public int deletePersonWeb(String personWebId) {return personWebMapper.deletePersonWeb(personWebId);}@DataSource(value = DataSourceType.SLAVE)public ConnectWeb selectConnectWebById(String connectWebId) {return connectWebMapper.selectConnectWebById(connectWebId);}@DataSource(value = DataSourceType.SLAVE)public int insertConnectWeb(ConnectWeb connectWeb) {connectWeb.setConnectWebId(snowflakeIdWorker.nextId());return connectWebMapper.insertConnectWeb(connectWeb);}@DataSource(value = DataSourceType.SLAVE)public int updateConnectWeb(ConnectWeb connectWeb) {return connectWebMapper.updateConnectWeb(connectWeb);}@DataSource(value = DataSourceType.SLAVE)public int deleteConnectWeb(String connectWebId) {return connectWebMapper.deleteConnectWeb(connectWebId);}
}
1.6
package com.admin.mapper;import com.admin.domain.ConnectWeb;
import org.springframework.stereotype.Repository;/*** @author wangwei*/
@Repository
public interface ConnectWebMapper {/*** 查询单个连接信息** @param connectWebId 连接id* @return ConnectWeb实体信息*/ConnectWeb selectConnectWebById(String connectWebId);/*** 插入单个连接信息** @param connectWeb 连接实体* @return 插入个数*/int insertConnectWeb(ConnectWeb connectWeb);/*** 修改单个连接信息** @param connectWeb 修改实体* @return 插入个数*/int updateConnectWeb(ConnectWeb connectWeb);/*** 删除单个连接** @param connectWebId 连接实体* @return 删除个数*/int deleteConnectWeb(String connectWebId);
}
1.7
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.admin.mapper.ConnectWebMapper"><select id="selectConnectWebById" parameterType="String" resultType="com.admin.domain.ConnectWeb">MATCH (m)-[c:ConnectWeb{connectWebId: #{connectWebId}}]->(n)RETURNc.connectWebId as connectWebId,c.connectWebName as connectWebName,c.connectWebInfo as connectWebInfo,m.personWebId as personWebIdAlpha,m.personWebName as personWebIdAlphaName,n.personWebId as personWebIdBeta,n.personWebName as personWebIdBetaName</select><insert id="insertConnectWeb" parameterType="com.admin.domain.ConnectWeb">match(pa:PersonWeb{personWebId: #{personWebIdAlpha}}),(pb:PersonWeb{personWebId: #{personWebIdBeta}})merge (pa)-[c:ConnectWeb{connectWebId: #{connectWebId},connectWebName: #{connectWebName},connectWebInfo: #{connectWebInfo}}]->(pb)</insert><update id="updateConnectWeb" parameterType="com.admin.domain.ConnectWeb">MATCH (m)-[c:ConnectWeb{connectWebId: #{connectWebId}}]->(n)<trim prefix="SET" suffixOverrides=","><if test="connectWebName != null">c.connectWebName = #{connectWebName},</if><if test="connectWebInfo != null">c.connectWebInfo = #{connectWebInfo},</if><if test="personWebIdAlpha != null">m.personWebId = #{personWebIdAlpha},</if><if test="personWebIdBeta != null">n.personWebId = #{personWebIdBeta},</if></trim></update><delete id="deleteConnectWeb" parameterType="String">MATCH ()-[c:ConnectWeb{connectWebId: #{connectWebId}}]-()DELETE c</delete></mapper>
1.8 maven
<!--手动添加--><!--neo4j-jdbc-driver--><dependency><groupId>org.neo4j</groupId><artifactId>neo4j-jdbc-driver</artifactId><version>4.0.1</version></dependency>
1.9 数据库配置
#TODO 从库数据源 neo4jslave:# 从数据源开关/默认关闭enabled: trueurl: jdbc:neo4j:bolt://127.0.0.1:1273username: neo4jpassword: neo4jdriverClassName: org.neo4j.jdbc.bolt.BoltDriver#TODO NEO4J 配置检测连接是否有效validationQuery: match (n) return id(n) limit 2
二、vue前台
2.1
<template><div class="app-container"><div class="echarts"><div class="bin" id="main"></div></div><el-row :gutter="10" class="mb8"><el-col :span="1.5"><el-buttontype="primary"icon="el-icon-plus"size="mini"@click="handleAdd">新增成员</el-button></el-col><el-col :span="1.5"><el-buttontype="success"icon="el-icon-edit"size="mini":disabled="single"@click="handleUpdate">修改成员</el-button></el-col><el-col :span="1.5"><el-buttontype="danger"icon="el-icon-plus"size="mini"@click="handleAddConnect">新增关系</el-button></el-col><right-toolbar :showSearch.sync="showSearch" @queryTable="refresh"></right-toolbar></el-row><el-table v-loading="loading" :data="personList" @selection-change="handleSelectionChange"><el-table-column type="selection" width="55" align="center"/><el-table-column label="成员昵称" align="center" prop="personWebName" :show-overflow-tooltip="true"><template slot-scope="scope"><a v-if="scope.row.personWebLink" target="_blank" :href="scope.row.personWebLink" class="link-type"style="margin-right: 10px;"><span>{{ scope.row.personWebName }}</span></a><span v-else>{{ scope.row.personWebName }}</span></template></el-table-column><el-table-column label="成员简介" align="center" prop="personWebInfo" :show-overflow-tooltip="true"/><el-table-column label="成员头像" align="center"><template slot-scope="scope"><img :src="person_pic_url + scope.row.personWebPic" alt="" class="pic-in-list"></template></el-table-column><el-table-column label="活跃平台" align="center" prop="personWebPlatform" :formatter="personPlatformFormat"></el-table-column><el-table-column label="常驻领域" align="center" prop="personWebField"><template slot-scope="scope"><el-tag v-for="ikey in scope.row.personWebField" :key="ikey" type="success" style="margin: 10px;">{{ikey}}</el-tag></template></el-table-column><el-table-column label="沟通要旨" align="center" prop="personWebKey" :show-overflow-tooltip="true"/><el-table-column label="是否展示" align="center" width="100" prop="personWebShow" :formatter="personShowFormat"><template slot-scope="scope"><el-tag :type="scope.row.personWebShow | statusFilter">{{ scope.row.personWebShow | statusShowFilter}}</el-tag></template></el-table-column><el-table-column label="操作" align="center" class-name="small-padding fixed-width"><template slot-scope="scope"><el-buttonsize="mini"type="text"icon="el-icon-edit"@click="handleUpdate(scope.row)">修改</el-button><el-buttonsize="mini"type="text"icon="el-icon-delete"@click="handleDelete(scope.row)">删除</el-button></template></el-table-column></el-table><el-dialog :visible.sync="openConnect" width="600px" append-to-body :title="titleConnect"><el-form ref="formConnect" :model="formConnect" :rules="rulesConnect" size="medium" label-width="100px"><el-row type="flex" justify="start" align="top"><el-col :span="12"><el-form-itemlabel="关联上级"prop="personWebIdAlpha":rules="requireFlag ? rulesConnect.personWebIdAlpha:[{required: false}]"><el-select:disabled="!requireFlag"v-model="formConnect.personWebIdAlpha"class="filter-item"filterableremotereserve-keywordclearable:placeholder="formConnect.personWebIdAlphaName":remote-method="remoteMethodStart":loading="selectLoading" value=""><el-optionv-for="item in optionsStart":key="item.personWebId":label="item.personWebName":value="item.personWebId"></el-option></el-select></el-form-item></el-col><el-col :span="12"><el-form-itemlabel="关联下属"prop="personWebIdBeta":rules="requireFlag ? rulesConnect.personWebIdBeta:[{required: false}]"><el-select:disabled="!requireFlag"v-model="formConnect.personWebIdBeta"class="filter-item"filterableremotereserve-keywordclearable:placeholder="formConnect.personWebIdBetaName":remote-method="remoteMethodEnd":loading="selectLoading" value=""><el-optionv-for="item in optionsEnd":key="item.personWebId":label="item.personWebName":value="item.personWebId"></el-option></el-select></el-form-item></el-col></el-row><el-form-item label="关联关系" prop="connectWebName"><el-input v-model="formConnect.connectWebName" placeholder="请输入关联关系" clearable :style="{width: '100%'}"></el-input></el-form-item><el-form-item label="关联信息" prop="connectWebInfo"><el-input v-model="formConnect.connectWebInfo" type="textarea" placeholder="请输入关联信息":autosize="{minRows: 4, maxRows: 4}" :style="{width: '100%'}"></el-input></el-form-item></el-form><div slot="footer"><el-button v-if="!requireFlag" type="danger" @click="deleteConnect">删除</el-button><el-button @click="cancelConnect">取消</el-button><el-button type="primary" @click="handelConfirm">确定</el-button></div></el-dialog><el-dialog :title="title" :visible.sync="open" width="600px" append-to-body><el-form ref="form" :model="form" :rules="rules" label-width="80px"><el-form-item label="成员昵称" prop="personWebName"><el-input v-model="form.personWebName" placeholder="请输入成员昵称"/></el-form-item><el-form-item label="成员简介" prop="personWebInfo"><el-input v-model="form.personWebInfo" type="textarea" placeholder="请输入成员简介"/></el-form-item><el-form-item label="跳转链接" prop="personWebLink"><el-input v-model="form.personWebLink" placeholder="请输入跳转链接"/></el-form-item><el-form-item label="成员头像" prop="personWebPic"><el-button v-show="!form.personWebPic" type="primary" size="mini" @click="imageCropperShow()">上传图片</el-button><el-button v-show="form.personWebPic" type="primary" size="mini" @click="imageCropperShow()">更新图片</el-button><el-button v-show="form.personWebPic" type="primary" size="mini" @click="picShow(form.personWebPic)">预览</el-button></el-form-item><el-form-item label="活跃平台"><el-checkbox-group v-model="form.personWebPlatform"><el-checkboxv-for="dict in personWebPlatformOptions":key="dict.dictValue":label="dict.dictValue">{{dict.dictLabel}}</el-checkbox></el-checkbox-group></el-form-item><el-form-item label="常驻领域" prop="personWebField"><el-tag:key="index"v-for="(tag, index) in form.personWebField"closable:disable-transitions="false"@close="handleClose(tag)">{{tag}}</el-tag><el-inputclass="input-new-tag"v-if="inputVisible"v-model="inputValue"ref="saveTagInput"size="small"@keyup.enter.native="handleInputConfirm"@blur="handleInputConfirm"></el-input><el-button v-else class="button-new-tag" size="small" @click="showInput">+ 新标签</el-button></el-form-item><el-form-item label="沟通要旨" prop="personWebInfo"><el-input v-model="form.personWebKey" type="textarea" placeholder="请输入沟通要旨"/></el-form-item><el-form-item label="是否展示"><el-radio-group v-model="form.personWebShow"><el-radiov-for="dict in personWebShowOptions":key="dict.dictValue":label="dict.dictValue">{{dict.dictLabel}}</el-radio></el-radio-group></el-form-item></el-form><div slot="footer" class="dialog-footer"><el-button type="primary" @click="submitForm">确 定</el-button><el-button @click="cancel">取 消</el-button></div></el-dialog><my-uploadmethod="POST"field="file"v-model="upload.cropperShow":headers="upload.headers":width=300:height=300:url="this.upload.logo_url"lang-type='zh'img-format='jpg'img-bgc='#FFF':no-circle=true@crop-upload-success="cropUploadSuccess"></my-upload><el-dialog title="图片预览" :visible.sync="picVisible" width="500px" center><div style="text-align: center"><img :src="answerPicImageUrl" alt="" class="pic-in-dialog"></div><span slot="footer" class="dialog-footer"><el-button @click="picVisible = false">确定</el-button></span></el-dialog></div></template><script>// import graph from '@/assets/binray/les-miserables';import {getPersonWebMap,getPersonWebList,getPersonWebSearch,getPersonWebInfo,addPersonWeb,editPersonWeb,removePersonWeb,getInfoConnectWeb,addConnectWeb,editConnectWeb,removeConnectWeb,getPersonWebSearchOther} from '@/api/person';import 'babel-polyfill'; // es6 shimimport myUpload from 'vue-image-crop-upload/upload-2';export default {name: 'Echarts',components: {myUpload},filters: {statusShowFilter(status) {const statusMap = {0: '正常',1: '已下线',}return statusMap[status]},statusFilter(status) {const statusMap = {0: 'success',1: 'warning',}return statusMap[status]}},data() {return {// 新增or更新,新增为true,更新为falserequireFlag: false,myChart: undefined,// 表单参数form: {},formConnect: {},// 表单校验rules: {personWebName: [{required: true,message: '成员名称为必填项',trigger: 'blur'}],/* personWebPic: [{required: true,message: '成员头图为必填项',trigger: 'change'}],*/personWebShow: [{required: true,message: '是否展示为必填项',trigger: 'change'}],},rulesConnect: {personWebIdAlpha: [{required: true,message: '',trigger: 'blur'}],personWebIdBeta: [{required: true,message: '',trigger: 'blur'}],connectWebName: [{required: true,message: '请输入关联关系',trigger: 'blur'}],connectWebInfo: [{required: true,message: '请输入关联信息',trigger: 'blur'}],},selectLoading: false,optionsStart: [],optionsEnd: [],personList: [],personMap: [],// 临时标签列表personWebPlatformTemp: undefined,personWebFieldTemp: undefined,// 路径person_pic_url: process.env.VUE_APP_BASE_API + "/File/upload/nosql/",//D:\File\upload\nosql// 图片预览框picVisible: false,// 拼接answerPicImageUrl: "",// 路径// 遮罩层loading: true,// 选中数组ids: [],// 非单个禁用single: true,// 非多个禁用multiple: true,// 显示搜索条件showSearch: true,// 总条数total: 0,upload: {// 显示上传图片的弹出框cropperShow: false,// 图标路径logo_url: process.env.VUE_APP_BASE_API + "/common/upload",},// 弹出层标题title: "",titleConnect: "",// 是否显示弹出层open: false,openConnect: false,inputVisible: false,// 具体内容inputValue: '',personWebShowOptions: [],personWebPlatformOptions: [],searchQueryParams: {// 这个一定得有personWebIdStart: null,// 这个可有可无personWebIdEnd: null,},graph: {nodes: [],links: []},mapCheckList: []}},created() {this.getList();this.personWebShowOptions = [{"searchValue": null,"createBy": "admin","createTime": "2021-02-21 19:29:04","updateBy": null,"updateTime": null,"remark": null,"params": {},"dictCode": 124,"dictSort": 0,"dictLabel": "已上架","dictValue": "0","dictType": "material_public","cssClass": null,"listClass": null,"isDefault": "N","status": "0","default": false}, {"searchValue": null,"createBy": "admin","createTime": "2021-02-21 19:29:39","updateBy": null,"updateTime": null,"remark": null,"params": {},"dictCode": 125,"dictSort": 1,"dictLabel": "未发布","dictValue": "1","dictType": "material_public","cssClass": null,"listClass": null,"isDefault": "N","status": "0","default": false}];this.personWebPlatformOptions = [{"searchValue": null,"createBy": "admin","createTime": "2021-03-26 02:20:51","updateBy": null,"updateTime": null,"remark": null,"params": {},"dictCode": 135,"dictSort": 0,"dictLabel": "哔哩哔哩","dictValue": "0","dictType": "media_platform","cssClass": null,"listClass": null,"isDefault": "N","status": "0","default": false}, {"searchValue": null,"createBy": "admin","createTime": "2021-03-26 02:21:03","updateBy": null,"updateTime": null,"remark": null,"params": {},"dictCode": 136,"dictSort": 1,"dictLabel": "今日头条","dictValue": "1","dictType": "media_platform","cssClass": null,"listClass": null,"isDefault": "N","status": "0","default": false}, {"searchValue": null,"createBy": "admin","createTime": "2021-03-26 02:21:12","updateBy": null,"updateTime": null,"remark": null,"params": {},"dictCode": 137,"dictSort": 2,"dictLabel": "抖音","dictValue": "2","dictType": "media_platform","cssClass": null,"listClass": null,"isDefault": "N","status": "0","default": false}, {"searchValue": null,"createBy": "admin","createTime": "2021-03-26 02:21:21","updateBy": null,"updateTime": null,"remark": null,"params": {},"dictCode": 138,"dictSort": 3,"dictLabel": "西瓜视频","dictValue": "3","dictType": "media_platform","cssClass": null,"listClass": null,"isDefault": "N","status": "0","default": false}, {"searchValue": null,"createBy": "admin","createTime": "2021-03-26 02:21:29","updateBy": null,"updateTime": null,"remark": null,"params": {},"dictCode": 139,"dictSort": 4,"dictLabel": "YouTube","dictValue": "4","dictType": "media_platform","cssClass": null,"listClass": null,"isDefault": "N","status": "0","default": false}, {"searchValue": null,"createBy": "admin","createTime": "2021-03-26 02:22:06","updateBy": null,"updateTime": null,"remark": null,"params": {},"dictCode": 140,"dictSort": 5,"dictLabel": "知乎","dictValue": "5","dictType": "media_platform","cssClass": null,"listClass": null,"isDefault": "N","status": "0","default": false}, {"searchValue": null,"createBy": "admin","createTime": "2021-03-26 02:22:17","updateBy": null,"updateTime": null,"remark": null,"params": {},"dictCode": 141,"dictSort": 6,"dictLabel": "小红书","dictValue": "6","dictType": "media_platform","cssClass": null,"listClass": null,"isDefault": "N","status": "0","default": false}, {"searchValue": null,"createBy": "admin","createTime": "2021-03-26 02:22:27","updateBy": null,"updateTime": null,"remark": null,"params": {},"dictCode": 142,"dictSort": 7,"dictLabel": "快手","dictValue": "7","dictType": "media_platform","cssClass": null,"listClass": null,"isDefault": "N","status": "0","default": false}, {"searchValue": null,"createBy": "admin","createTime": "2021-03-26 02:22:49","updateBy": null,"updateTime": null,"remark": null,"params": {},"dictCode": 143,"dictSort": 8,"dictLabel": "Acfun","dictValue": "8","dictType": "media_platform","cssClass": null,"listClass": null,"isDefault": "N","status": "0","default": false}, {"searchValue": null,"createBy": "admin","createTime": "2021-03-26 02:23:05","updateBy": null,"updateTime": null,"remark": null,"params": {},"dictCode": 144,"dictSort": 9,"dictLabel": "网易云音乐","dictValue": "9","dictType": "media_platform","cssClass": null,"listClass": null,"isDefault": "N","status": "0","default": false}, {"searchValue": null,"createBy": "admin","createTime": "2021-03-26 02:23:34","updateBy": null,"updateTime": null,"remark": null,"params": {},"dictCode": 145,"dictSort": 10,"dictLabel": "豆瓣","dictValue": "10","dictType": "media_platform","cssClass": null,"listClass": null,"isDefault": "N","status": "0","default": false}, {"searchValue": null,"createBy": "admin","createTime": "2021-03-26 02:23:52","updateBy": null,"updateTime": null,"remark": null,"params": {},"dictCode": 146,"dictSort": 11,"dictLabel": "微博","dictValue": "11","dictType": "media_platform","cssClass": null,"listClass": null,"isDefault": "N","status": "0","default": false}, {"searchValue": null,"createBy": "admin","createTime": "2021-03-26 02:24:34","updateBy": null,"updateTime": null,"remark": null,"params": {},"dictCode": 147,"dictSort": 12,"dictLabel": "新片场","dictValue": "12","dictType": "media_platform","cssClass": null,"listClass": null,"isDefault": "N","status": "0","default": false}, {"searchValue": null,"createBy": "admin","createTime": "2021-03-26 02:24:50","updateBy": null,"updateTime": null,"remark": null,"params": {},"dictCode": 148,"dictSort": 13,"dictLabel": "图虫","dictValue": "13","dictType": "media_platform","cssClass": null,"listClass": null,"isDefault": "N","status": "0","default": false}]},methods: {myEcharts() {const that = this;this.myChart.showLoading();this.graph.nodes.forEach(function (node) {node.label = {show: true};});const option = {title: {text: '',subtext: '',top: 'bottom',left: 'right'},tooltip: {trigger: "item",// textStyle: {// width: 10,// fontWeight: "bold",// overflow: "truncate"// },confine: 'true',formatter: function (param) {if (param.dataType === 'edge') {// 连接return ['关系:' + param.data["connectWebName"] + '<br/>','详情:' + param.data["connectWebInfo"] + '<br/>'].join('');} else if (param.dataType === 'node') {// 处理标签let graphTag = '';const arr1 = JSON.parse(param.data["personWebField"]);for (let i = 0; i < arr1.length; i++) {if (i === 0) {graphTag = `<span style="display: inline-block;border-radius: 4px;min-width: min-content;padding: 0 10px;margin: 5px;background-color: #e7faf0;border-color: #d0f5e0;color: #13ce66;border-width: 1px;border-style: solid;">${arr1[i]}</span>`} else {graphTag = graphTag + `<span style="display: inline-block;border-radius: 4px;min-width: min-content;padding: 0 10px;margin: 5px;background-color: #e7faf0;border-color: #d0f5e0;color: #13ce66;border-width: 1px;border-style: solid;">${arr1[i]}</span>`;}}// 处理字典let graphDict = '';const arrTemp = that.selectDictLabel(that.personWebPlatformOptions, JSON.parse(param.data["personWebPlatform"]));const arr2 = arrTemp.split(', ')for (let i = 0; i < arr2.length; i++) {if (i === 0) {graphDict = `<span style="display: inline-block;border-radius: 4px;min-width: min-content;padding: 0 10px;margin: 5px;background-color: #faece7;border-color: #f5dad0;color: #ff7d27;border-width: 1px;border-style: solid;">${arr2[i]}</span>`} else {graphDict = graphDict + `<span style="display: inline-block;border-radius: 4px;min-width: min-content;padding: 0 10px;margin: 5px;background-color: #faece7;border-color: #f5dad0;color: #ff7d27;border-width: 1px;border-style: solid;">${arr2[i]}</span>`;}}// 节点return ['<div style="text-align:left;max-width:1000px;">昵称:' + param.data["name"] + '<br/>','<div style="display:block;word-break: break-all;word-wrap: break-word;white-space: pre-line;">简介:' + param.data["personWebInfo"] + '</div>','常驻领域:' + graphTag + '<br/>','活跃平台:' + graphDict + '</div><br/>',].join('');}}},legend: [],animationDuration: 150,animationEasingUpdate: 'quinticInOut',series: [{name: '',type: 'graph',layout: "force",force: {repulsion: 200,edgeLength: 100,gravity: 0.2},symbolSize: 50,data: this.graph.nodes,links: this.graph.links,// data: graph.nodes,// links: graph.links,roam: true,label: {show: true,},draggable: true,labelLayout: {hideOverlap: false},lineStyle: {color: 'source',curveness: 0.3},emphasis: {focus: 'adjacency',lineStyle: {width: 10}}}]};this.myChart.clear();option && this.myChart.setOption(option, true);// console.log(option)this.myChart.hideLoading();this.myChart.on("click", function (e) {if (e.dataType === 'edge') {that.handleUpdateConnect(e.data)} else if (e.dataType === 'node') {console.log(e)e.data.personWebId = e.data.idthat.handleUpdate(e.data)}})},getList() {this.loading = true;getPersonWebList().then(response => {this.personList = response.rows;Object.keys(this.personList).forEach(key => {this.personList[key].personWebPlatform = JSON.parse(this.personList[key].personWebPlatform)this.personList[key].personWebField = JSON.parse(this.personList[key].personWebField)});this.loading = false;});},async getMap() {this.loading = true;await getPersonWebMap().then(response => {this.graph = {nodes: [],links: []};this.mapCheckList = [];this.personMap = response.rows;Object.keys(this.personMap).forEach(key => {// 导入节点,列表为空表示首次加入元素,反之亦然if (this.graph.nodes !== []) {// 如果导入过就不用重复导入了if (!this.mapCheckList.includes(this.personMap[key].PersonAlpha.personWebId)) {this.pushAlpha(key);}if (!this.mapCheckList.includes(this.personMap[key].PersonBeta.personWebId)) {this.pushBeta(key);}} else {this.pushAlpha(key);this.pushBeta(key);}// 把导入过的节点id存进checkListthis.mapCheckList.push(this.personMap[key].PersonAlpha.personWebId)this.mapCheckList.push(this.personMap[key].PersonBeta.personWebId)// 导入关系this.pushConnect(key);});});// console.log(this.graph)this.loading = false;},pushAlpha(key) {this.graph.nodes.push({id: this.personMap[key].PersonAlpha.personWebId,name: this.personMap[key].PersonAlpha.personWebName,personWebPic: this.personMap[key].PersonAlpha.personWebPic,personWebShow: this.personMap[key].PersonAlpha.personWebShow,personWebLink: this.personMap[key].PersonAlpha.personWebLink,personWebPlatform: this.personMap[key].PersonAlpha.personWebPlatform,personWebField: this.personMap[key].PersonAlpha.personWebField,personWebInfo: this.personMap[key].PersonAlpha.personWebInfo,personWebKey: this.personMap[key].PersonAlpha.personWebKey,})},pushBeta(key) {this.graph.nodes.push({id: this.personMap[key].PersonBeta.personWebId,name: this.personMap[key].PersonBeta.personWebName,personWebPic: this.personMap[key].PersonBeta.personWebPic,personWebShow: this.personMap[key].PersonBeta.personWebShow,personWebLink: this.personMap[key].PersonBeta.personWebLink,personWebPlatform: this.personMap[key].PersonBeta.personWebPlatform,personWebField: this.personMap[key].PersonBeta.personWebField,personWebInfo: this.personMap[key].PersonBeta.personWebInfo,personWebKey: this.personMap[key].PersonBeta.personWebKey,})},pushConnect(key) {this.graph.links.push({source: this.personMap[key].PersonAlpha.personWebId,target: this.personMap[key].PersonBeta.personWebId,connectWebId: this.personMap[key].Connect.connectWebId,connectWebName: this.personMap[key].Connect.connectWebName,connectWebInfo: this.personMap[key].Connect.connectWebInfo,})},// 字典翻译personShowFormat(row, column) {return this.selectDictLabel(this.personWebShowOptions, row.personWebShow);},personPlatformFormat(row, column) {return this.selectDictLabel(this.personWebPlatformOptions, row.personWebPlatform);},// 取消按钮cancel() {this.open = false;this.reset();},// 取消按钮cancelConnect() {this.openConnect = false;this.resetConnect();},// 表单重置reset() {this.form = {personWebId: null,personWebName: null,personWebPic: null,personWebShow: "0",personWebLink: "",personWebPlatform: [],personWebField: [],personWebInfo: "",personWebKey: ""};this.answerPicImageUrl = null;this.resetForm("form");},resetConnect() {this.formConnect = {personWebIdAlpha: null,personWebIdBeta: null,personWebIdAlphaName: null,personWebIdBetaName: null,connectWebId: null,connectWebName: null,connectWebInfo: null,};this.resetForm("formConnect");},handleAddConnect() {this.optionsStart = []this.optionsEnd = []this.requireFlag = true;this.resetConnect();this.openConnect = true;this.titleConnect = "添加成员关系";},/** 修改按钮操作 */handleUpdateConnect(row) {this.optionsStart = []this.optionsEnd = []this.requireFlag = false;this.reset();const connectWeb = row.connectWebId;getInfoConnectWeb(connectWeb).then(response => {this.formConnect = response.data;// console.log(this.formConnect)this.formConnect.personWebIdAlpha = null;this.formConnect.personWebIdBeta = null;this.openConnect = true;this.titleConnect = "修改成员关系";});},// 多选框选中数据handleSelectionChange(selection) {this.ids = selection.map(item => item.personWebId)this.single = selection.length !== 1this.multiple = !selection.length},remoteMethodStart(keyword) {if (keyword.trim() === '') {this.optionsStart = []return}// 当后一个对象不为空的情况if (this.formConnect.personWebIdBeta) {let others = [];this.selectLoading = true;getPersonWebSearch(keyword).then(data => {getPersonWebSearchOther(this.formConnect.personWebIdBeta, keyword).then(dataOther => {others = dataOther.rows;this.optionsStart = [];data.rows.forEach(ma => {let exist = others.some(sa => {return ma.personWebId === sa.personWebId});if (!exist) {this.optionsStart.push(ma);}});this.optionsStart = this.optionsStart.filter(item => item.personWebId !== this.formConnect.personWebIdBeta)})this.selectLoading = false;})}// 后一个对象为空时else {this.selectLoading = true;getPersonWebSearch(keyword).then(data => {this.selectLoading = false;this.optionsStart = data.rows;})}},remoteMethodEnd(keyword) {if (keyword.trim() === '') {this.optionsEnd = []return}// 当前一个对象不为空的情况if (this.formConnect.personWebIdAlpha) {let others = [];this.selectLoading = true;getPersonWebSearch(keyword).then(data => {getPersonWebSearchOther(this.formConnect.personWebIdAlpha, keyword).then(dataOther => {others = dataOther.rows;this.optionsEnd = [];data.rows.forEach(ma => {let exist = others.some(sa => {return ma.personWebId === sa.personWebId});if (!exist) {this.optionsEnd.push(ma);}});this.optionsEnd = this.optionsEnd.filter(item => item.personWebId !== this.formConnect.personWebIdAlpha)})this.selectLoading = false;})}// 前一个对象为空时else {this.selectLoading = true;getPersonWebSearch(keyword).then(data => {this.selectLoading = false;this.optionsEnd = data.rows;})}},/** 新增按钮操作 */handleAdd() {this.reset();this.open = true;this.title = "添加成员管理";},/** 修改按钮操作 */handleUpdate(row) {this.reset();const personWeb = row.personWebId || this.ids;getPersonWebInfo(personWeb).then(response => {this.form = response.data;this.personWebPlatformTemp = this.form.personWebPlatform;this.form.personWebPlatform = JSON.parse(this.personWebPlatformTemp);this.personWebFieldTemp = this.form.personWebField;this.form.personWebField = JSON.parse(this.personWebFieldTemp);this.open = true;this.title = "修改成員管理";});},submitForm() {this.$refs["form"].validate(valid => {if (valid) {this.open = false;this.personWebPlatformTemp = this.form.personWebPlatform;this.form.personWebPlatform = JSON.stringify(this.personWebPlatformTemp);this.personWebFieldTemp = this.form.personWebField;this.form.personWebField = JSON.stringify(this.personWebFieldTemp);if (this.form.personWebId != null) {editPersonWeb(this.form).then(response => {if (response.code === 200) {this.msgSuccess("修改成功");this.refresh();}});} else {addPersonWeb(this.form).then(response => {if (response.code === 200) {this.msgSuccess("新增成功");this.refresh();}});}}});},handelConfirm() {this.$refs["formConnect"].validate(valid => {if (valid) {this.openConnect = false;if (this.formConnect.connectWebId != null) {editConnectWeb(this.formConnect).then(response => {if (response.code === 200) {this.msgSuccess("修改成功");this.refresh();}});} else {addConnectWeb(this.formConnect).then(response => {if (response.code === 200) {this.msgSuccess("新增成功");this.refresh();}});}}});},deleteConnect() {const connectWebId = this.formConnect.connectWebIdthis.$confirm('是否确认删除「' + this.formConnect.personWebIdAlphaName + '」和「' + this.formConnect.personWebIdBetaName + '」的关系?', "警告", {confirmButtonText: "确定",cancelButtonText: "取消",type: "warning"}).then(function () {return removeConnectWeb(connectWebId);}).then(() => {this.openConnect = false;this.refresh();this.msgSuccess("删除成功");}).catch(function (e) {console.log(e)});},/** 删除按钮操作 */handleDelete(row) {const personWebIds = row.personWebId || this.ids;this.$confirm('是否确认删除成员编号为"' + personWebIds + '"的数据项?', "警告", {confirmButtonText: "确定",cancelButtonText: "取消",type: "warning"}).then(function () {return removePersonWeb(personWebIds);}).then(() => {this.refresh();this.msgSuccess("删除成功");}).catch(function () {});},// 显示图片上传模块imageCropperShow() {this.upload.cropperShow = !this.upload.cropperShow},// 图片上传成功后执行cropUploadSuccess(jsonData, field) {this.form.personWebPic = jsonData.fileName// console.log(jsonData)},picShow(pic) {this.picVisible = !this.picVisible;this.answerPicImageUrl = this.person_pic_url + pic},handleClose(tag) {this.form.personWebField.splice(this.form.personWebField.indexOf(tag), 1);},showInput() {this.inputVisible = true;this.$nextTick(_ => {this.$refs.saveTagInput.$refs.input.focus();});},handleInputConfirm() {let inputValue = this.inputValue;if (inputValue) {this.form.personWebField.push(inputValue);}this.inputVisible = false;this.inputValue = '';},async refresh() {await this.getMap();this.myEcharts();this.getList()},},async mounted() {await this.getMap();// 基于准备好的dom,初始化echarts实例let echarts = require('echarts')this.myChart = echarts.init(document.getElementById('main'));this.myEcharts();}}
</script><style lang="scss" scoped>.avatar-uploader .el-upload {border: 1px dashed #d9d9d9;border-radius: 6px;cursor: pointer;position: relative;overflow: hidden;width: 178px;height: 178px;}.avatar-uploader .el-upload:hover {border-color: #409EFF;}.avatar-uploader-icon {line-height: 140px;}.avatar {height: 144px;}.image-preview {width: 178px;height: 178px;position: relative;border: 1px dashed #d9d9d9;border-radius: 6px;float: left;}.image-preview .image-preview-wrapper {position: relative;width: 100%;height: 100%;}.image-preview .image-preview-wrapper img {width: 100%;height: 100%;}.image-preview .image-preview-action {position: absolute;width: 100%;height: 100%;left: 0;top: 0;text-align: center;color: #fff;opacity: 0;font-size: 20px;background-color: rgba(0, 0, 0, .5);transition: opacity .3s;cursor: pointer;line-height: 200px;}.image-preview .image-preview-action .el-icon-delete {font-size: 32px;}.image-preview:hover .image-preview-action {opacity: 1;}.el-upload--picture-card {display: block;width: 258px;height: 146px;overflow: hidden;}.input-new-tag {width: 90px;margin-left: 10px;vertical-align: bottom;}.el-tag + .el-tag {margin-left: 10px;}.button-new-tag {margin-left: 10px;height: 32px;line-height: 30px;padding-top: 0;padding-bottom: 0;}.echarts {width: 100%;text-align: center;height: 800px;}.bin {/*text-align: center;*//*padding: 50px;*/width: 100%;height: 800px}.dashboard-editor-container {padding: 32px;background-color: rgb(240, 242, 245);position: relative;.chart-wrapper {background: #fff;padding: 16px 16px 0;margin-bottom: 32px;}}.graph-tag {display: inline-block;border-radius: 4px;min-width: min-content;padding: 5px;background-color: #e7faf0;border-color: #d0f5e0;color: #13ce66;}@media (max-width: 1024px) {.chart-wrapper {padding: 8px;}}</style>
2.2
import request from '@/utils/request'export function getPersonWebMap() {return request({url: '/people/web/map',method: 'get'})
}export function getPersonWebList() {return request({url: '/people/web/list',method: 'get'})
}export function getPersonWebSearch(personName) {return request({url: '/people/web/search/' + personName,method: 'get'})
}export function getPersonWebSearchOther(personId, personName) {return request({url: '/people/web/search/' + personId + '/' + personName,method: 'get'})
}export function getPersonWebInfo(personId) {return request({url: '/people/web/person/' + personId,method: 'get'})
}export function addPersonWeb(data) {return request({url: '/people/web/person',method: 'post',data: data})
}export function editPersonWeb(data) {return request({url: '/people/web/person',method: 'put',data: data})
}export function removePersonWeb(personId) {return request({url: '/people/web/person/' + personId,method: 'delete'})
}export function getInfoConnectWeb(connectId) {return request({url: '/people/web/connect/' + connectId,method: 'get'})
}export function addConnectWeb(data) {return request({url: '/people/web/connect',method: 'post',data: data})
}export function editConnectWeb(data) {return request({url: '/people/web/connect',method: 'put',data: data})
}export function removeConnectWeb(connectId) {return request({url: '/people/web/connect/' + connectId,method: 'delete'})
}
三、展示