<template>
|
<view
|
style="width: 100%; height: 100%; display: flex; flex-direction: column"
|
>
|
<headNav :idIndex="'6'" text="学术图谱" />
|
<!-- 高级搜索 -->
|
<view
|
style="
|
padding-left: 0.6rem;
|
margin-top: 0.1rem;
|
display: flex;
|
position: relative;
|
"
|
>
|
<advancedSearch
|
@onSearch="onSearch"
|
placehold="请输入关键字"
|
:isAvancedTrue="false"
|
:keyword="searchKey"
|
/>
|
<view
|
@click="isAvancedClick"
|
style="
|
color: #244a7b;
|
cursor: pointer;
|
font-size: 0.12rem;
|
margin-left: 0.35rem;
|
line-height: 0.58rem;
|
"
|
>高级搜索 {{ isAdvancedSearch ? "∧" : "∨" }}</view
|
>
|
<!-- 热门搜索 -->
|
<view class="flex flex-center hotSearch" style="margin-left: 2rem">
|
热门搜索:
|
<ul class="flex" style="margin-right: 10rpx">
|
<li
|
@click="onSearch({ text: item }, index)"
|
:class="{ cursor: true, active: hotAciveIndex === index }"
|
v-for="(item, index) in hotKeyList"
|
:key="item.name"
|
>
|
{{ item.name }}
|
</li>
|
</ul>
|
</view>
|
<view v-if="isAdvancedSearch" class="searchDialog">
|
<h3 style="margin-bottom: 0.2rem">高级搜索</h3>
|
<el-form
|
label-width="100px"
|
:model="formData"
|
ref="searchForm"
|
size="mini"
|
>
|
<el-row>
|
<el-col :span="8">
|
<el-form-item label="姓名/别名:">
|
<el-input v-model="formData.name"></el-input>
|
</el-form-item>
|
</el-col>
|
<el-col :span="8">
|
<el-form-item label="活动地:">
|
<div class="selectActivelyBox" @click="selectActively">
|
<p v-if="formData.actively.length == 0">请选择活动地</p>
|
<el-tag
|
style="margin-right: 5px"
|
v-for="item in formData.actively"
|
:key="item.index"
|
size="small"
|
type="info"
|
>{{ item.name }}</el-tag
|
>
|
</div>
|
</el-form-item>
|
</el-col>
|
<el-col :span="8">
|
<el-form-item label="作品:">
|
<el-input v-model="formData.works"></el-input>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-row>
|
<el-col :span="8">
|
<el-form-item label="人物标签:">
|
<el-select
|
multiple
|
style="width: 100%"
|
v-model="formData.personTags"
|
placeholder="请选择人物标签"
|
>
|
<el-option
|
v-for="item in personTag"
|
:key="item.id"
|
:label="item.name"
|
:value="item.id"
|
></el-option>
|
</el-select>
|
</el-form-item>
|
</el-col>
|
<el-col :span="8">
|
<el-form-item label="社会身份:">
|
<el-select
|
multiple
|
style="width: 100%"
|
v-model="formData.socialIdentity"
|
placeholder="请选择社会身份"
|
>
|
<el-option
|
v-for="item in socialDistinction"
|
:key="item.id"
|
:label="item.name"
|
:value="item.id"
|
></el-option>
|
</el-select>
|
</el-form-item>
|
</el-col>
|
<el-col :span="8">
|
<el-form-item label="时期:">
|
<el-select
|
multiple
|
style="width: 100%"
|
v-model="formData.period"
|
placeholder="请选择时期"
|
>
|
<el-option
|
v-for="item in dynastyData"
|
:key="item.dynastyId"
|
:label="item.name"
|
:value="item.dynastyId"
|
></el-option>
|
</el-select>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<div style="text-align: right">
|
<el-button
|
size="mini"
|
style="background-color: #244a7b; color: #fff"
|
@click="
|
() => {
|
searchKey = '';
|
formData.page = 1;
|
searchFun();
|
}
|
"
|
>搜索</el-button
|
>
|
<el-button size="mini" @click="resetForm">重置</el-button>
|
</div>
|
</el-form>
|
<div style="font-size: 14px">
|
注:当前数据较多,可能会出现卡死的情况,请尽量精确查询或查看某一类数据关系
|
</div>
|
<div class="fromTable">
|
<el-table
|
:data="tableData"
|
class="lightBo"
|
style="width: 100%"
|
empty-text="暂无搜索信息"
|
size="small"
|
:border="true"
|
:height="tableData.length > 0 ? '443' : 'auto'"
|
>
|
<el-table-column
|
prop="id"
|
label="序号"
|
width="70"
|
></el-table-column>
|
<el-table-column prop="name" width="150" label="姓名">
|
<template slot-scope="scope">
|
<a
|
style="cursor: pointer; color: #027edc"
|
@click="
|
() => {
|
currentId = scope.row.id;
|
getData();
|
isAdvancedSearch = false;
|
}
|
"
|
>{{ scope.row.name }}</a
|
>
|
</template>
|
</el-table-column>
|
<el-table-column prop="alias" label="别名"></el-table-column>
|
<el-table-column prop="place" label="活动地"></el-table-column>
|
<el-table-column
|
prop="medicalBranch"
|
label="医学分科"
|
width="150"
|
></el-table-column>
|
<el-table-column prop="workName" label="作品"></el-table-column>
|
<el-table-column
|
prop="personLabel"
|
width="150"
|
label="人物标签"
|
></el-table-column>
|
<el-table-column
|
prop="socialDistinction"
|
label="社会身份"
|
width="150"
|
></el-table-column>
|
<el-table-column
|
prop="period"
|
width="150"
|
label="时期"
|
></el-table-column>
|
</el-table>
|
<div class="drawerPage">
|
<el-pagination
|
class="paging flex"
|
background
|
@size-change="handleSizeChangeForm"
|
@current-change="handleCurrentChangeForm"
|
:current-page="formData.page"
|
:page-sizes="[10, 20, 60, 100]"
|
:page-size="formData.pageSize"
|
layout="total, sizes, prev, pager, next, jumper"
|
:total="formData.total"
|
>
|
</el-pagination>
|
</div>
|
</div>
|
</view>
|
<div v-if="showPerson" class="personDialog">
|
<i
|
class="el-icon-circle-close closeBtn"
|
@click="
|
() => {
|
showPerson = false;
|
}
|
"
|
></i>
|
<el-table :data="personList" style="width: 100%" :max-height="600">
|
<el-table-column prop="name" label="姓名">
|
<template slot-scope="scope">
|
<span
|
style="color: #409eff; cursor: pointer"
|
@click="
|
() => {
|
currentId = scope.row.id;
|
getData();
|
}
|
"
|
>{{ scope.row.name }}</span
|
>
|
</template>
|
</el-table-column>
|
<el-table-column prop="age" label="时代"> </el-table-column>
|
<el-table-column prop="nativePlace" label="籍贯"> </el-table-column>
|
<el-table-column prop="alias" label="别名"> </el-table-column>
|
<el-table-column prop="division" label="医学分科"> </el-table-column>
|
</el-table>
|
</div>
|
</view>
|
|
<!-- 关系表地图 -->
|
<div
|
id="relation"
|
style="margin-top: 0.1rem; flex: 1; width: 100%; position: relative"
|
>
|
<div
|
v-if="!loading && nodeDatas.length == 0"
|
style="
|
position: absolute;
|
top: 30%;
|
left: 0;
|
right: 0;
|
text-align: center;
|
font-size: 0.2rem;
|
color: #666;
|
z-index: 99;
|
"
|
>
|
暂无相关数据
|
</div>
|
<div
|
v-if="loading"
|
v-loading="loading"
|
style="
|
position: absolute;
|
top: 30%;
|
left: 0;
|
right: 0;
|
text-align: center;
|
font-size: 0.2rem;
|
color: #666;
|
z-index: 99;
|
"
|
></div>
|
</div>
|
<div id="customDialog" class="customDialog">
|
<div class="title">
|
<span>{{ detailData.name }}</span>
|
<span @click="closeDom">关闭</span>
|
</div>
|
<div class="content">
|
<p>姓名:{{ detailData.name }}</p>
|
<p>别名:{{ detailData.alias }}</p>
|
<p>籍贯:{{ detailData.nativePlace }}</p>
|
<p>医学分科: {{ detailData.medicalBranch }}</p>
|
<p>小传:{{ detailData.biography }}</p>
|
</div>
|
<div class="btn" @click="spaceTimeArr(detailData.id, 1)">查看更多>>></div>
|
</div>
|
<div id="schoolDialog" class="customDialog">
|
<div class="title">
|
<span>{{ detailData.name }}</span>
|
<span @click="closeDom">关闭</span>
|
</div>
|
<div class="content">
|
<p>代表人物:{{ detailData.character }}</p>
|
<p>重要医家:{{ detailData.skilledDoctor }}</p>
|
<p>代表性著作:{{ detailData.works }}</p>
|
<p>学派思想: {{ detailData.thought }}</p>
|
</div>
|
<div class="btn" @click="spaceTimeArr(detailData.id, 2)">查看更多>>></div>
|
</div>
|
<el-drawer
|
title="地址列表"
|
:visible.sync="drawer"
|
direction="rtl"
|
:before-close="handleClose"
|
class="customDrawer"
|
>
|
<div class="drawerContent">
|
<div class="drawerTips">選中的地址:</div>
|
<div class="drawerTable">
|
<div class="tableTabs">
|
<div class="inputItem">
|
<el-input
|
placeholder="請輸入地名搜索"
|
v-model="tableKey"
|
class="input-with-select"
|
@keyup.enter="searchAddress"
|
>
|
<el-button
|
@click="searchAddress"
|
type="primary"
|
slot="append"
|
icon="el-icon-search"
|
></el-button>
|
</el-input>
|
</div>
|
<div class="selectItem">
|
<el-select v-model="dynastyId" placeholder="請選擇時期">
|
<el-option
|
v-for="item in dynastyData"
|
:key="item.dynastyId + '0'"
|
:label="item.name"
|
:value="item.dynastyId"
|
></el-option>
|
</el-select>
|
</div>
|
</div>
|
<el-table
|
ref="multipleTable"
|
:data="gridData"
|
style="width: 100%"
|
height="530"
|
@selection-change="handleSelectionChange"
|
row-key="index"
|
>
|
<el-table-column type="selection" width="55"> </el-table-column>
|
<el-table-column prop="currentName" label="地名"> </el-table-column>
|
<el-table-column width="250" label="年代區間">
|
<template slot-scope="scope">{{
|
scope.row.start + "-" + scope.row.end
|
}}</template>
|
</el-table-column>
|
<el-table-column
|
prop="dynastyName"
|
label="時期"
|
width="250"
|
show-overflow-tooltip
|
>
|
</el-table-column>
|
</el-table>
|
</div>
|
<div class="drawerPage">
|
<el-pagination
|
class="paging flex"
|
background
|
@size-change="handleSizeChange"
|
@current-change="handleCurrentChange"
|
:current-page="page"
|
:page-sizes="[10, 20, 60, 100]"
|
:page-size="pageSize"
|
layout="total, sizes, prev, pager, next, jumper"
|
:total="total"
|
>
|
</el-pagination>
|
</div>
|
<div class="drawerBtn">
|
<el-button @click="setCurrent">全選當前頁</el-button>
|
<el-button @click="setCurrent('cancle')">取消全選</el-button>
|
<el-button @click="drawer = false" type="primary">確定</el-button>
|
</div>
|
</div>
|
</el-drawer>
|
</view>
|
</template>
|
|
<script>
|
import {
|
getPersonData,
|
getHotSearch,
|
academicSearch,
|
getPersonTag,
|
getSocialDistinction,
|
getDynastyAll,
|
getAdvancedData,
|
getPlaceInfo
|
} from "@/api/index.js";
|
import * as echarts from "echarts";
|
export default {
|
data() {
|
return {
|
// 高級搜索表格
|
tableData: [],
|
loading: true,
|
hotAciveIndex: "",
|
currentId: 21682,
|
// echarts数据
|
nodes: [],
|
// echarts两者的关系
|
relationships: [],
|
// 热门搜索
|
hotKeyList: [],
|
searchKey: "",
|
// 分类
|
categories: [
|
{
|
name: "亲属关系",
|
},
|
{
|
name: "师承关系",
|
},
|
{
|
name: "文献作品",
|
},
|
{
|
name: "社会关系",
|
},
|
{
|
name: "活动地",
|
},
|
{
|
name: "学术流派"
|
}
|
],
|
// 当前人物信息
|
ownInfo: null,
|
detailData: {
|
name: "",
|
},
|
isAdvancedSearch: false,
|
formData: {
|
name: "",
|
actively: [],
|
works: "",
|
personTags: "",
|
socialIdentity: "",
|
period: "",
|
page: 1,
|
currentPage: 1,
|
pageSize: 10,
|
total: 0
|
},
|
showPerson: false,
|
personList: [],
|
personPageInfo: {
|
totalCount: 0,
|
page: 1,
|
limit: 10,
|
},
|
personTag: [],
|
socialDistinction: [],
|
dynastyData: [],
|
// 抽屉
|
gridData: [],
|
page: 1,
|
currentPage: 1,
|
pageSize: 10,
|
total: 0,
|
drawer: false,
|
dynastyId: "",
|
tableKey: "",
|
multipleTableSelection: [],
|
// echarts
|
infoOfPersons: [],
|
infoOfSchools: [],
|
nodeDatas: [],
|
links: [],
|
};
|
},
|
mounted() {
|
this.getData();
|
this.hotSearch();
|
// 获取人物标签、社会身份
|
this.getOptionInfo();
|
// 獲取地址列表
|
this.getAddressList();
|
// 监听窗口大小变化
|
window.addEventListener("resize", this.relation);
|
},
|
onLoad(options) {
|
this.searchKey = options.keyword;
|
},
|
methods: {
|
// 搜索地址
|
searchAddress() {
|
this.page = 1;
|
this.gridData = [];
|
this.getAddressList();
|
},
|
// 分页
|
handleSizeChange(val) {
|
this.pageSize = val;
|
this.getAddressList();
|
},
|
handleCurrentChange(val) {
|
this.page = val;
|
this.getAddressList();
|
},
|
|
handleSizeChangeForm(val) {
|
this.formData.pageSize = val;
|
this.searchFun();
|
},
|
handleCurrentChangeForm(val) {
|
this.formData.page = val;
|
this.searchFun();
|
},
|
// 表格选择
|
handleSelectionChange(val) {
|
const data = val.map((item) => {
|
return {
|
...item,
|
name: item.currentName,
|
id: item.dynastyId,
|
};
|
});
|
this.formData.actively = data;
|
this.multipleTableSelection = this.formData.actively;
|
},
|
// 全選
|
setCurrent(str) {
|
if (str == "cancle") {
|
this.$refs.multipleTable.clearSelection();
|
return false;
|
}
|
if (this.gridData.length) {
|
this.$refs.multipleTable.clearSelection();
|
this.gridData.forEach((row) => {
|
this.$refs.multipleTable.toggleRowSelection(row);
|
});
|
const data = this.gridData.map((item) => {
|
return {
|
...item,
|
name: item.currentName,
|
id: item.dynastyId,
|
};
|
});
|
this.formData.actively = data;
|
this.multipleTableSelection = this.formData.actively;
|
}
|
},
|
// 獲取地址列表
|
getAddressList() {
|
const data = {
|
page: this.page,
|
pageSize: this.pageSize,
|
};
|
if (this.dynastyId != "") {
|
data["dynastyId"] = this.dynastyId;
|
}
|
if (this.tableKey != "") {
|
data["keyword"] = this.tableKey;
|
}
|
getPlaceInfo(data).then((res) => {
|
if (res?.success && res?.npage) {
|
this.total = res.npage.totalCount;
|
}
|
if (res?.success && res?.list.length) {
|
this.gridData = res?.list?.map((item, i) => {
|
return {
|
...item,
|
index: i,
|
};
|
});
|
} else {
|
this.gridData = [];
|
}
|
});
|
},
|
|
getOptionInfo() {
|
getDynastyAll().then((res) => {
|
this.dynastyData = res.list;
|
});
|
getPersonTag().then((res) => {
|
this.personTag = res.list;
|
});
|
getSocialDistinction().then((res) => {
|
this.socialDistinction = res.list;
|
});
|
},
|
|
resetForm(formName) {
|
this.formData = {
|
name: "",
|
actively: [],
|
works: "",
|
personTags: [],
|
socialIdentity: [],
|
period: [],
|
page: 1,
|
currentPage: 1,
|
pageSize: 10,
|
total: 0
|
};
|
this.formData.page = 1;
|
this.searchFun();
|
},
|
searchFun() {
|
const palceData = this.formData.actively?.map((item) => {
|
return {
|
ancientName: item.ancientName ?? "",
|
dynastyId: item.dynastyId,
|
currentName: item.currentName
|
};
|
});
|
let Obj = {
|
keyword: this.formData.name,
|
placeList: [...palceData],
|
literatureName: this.formData.works,
|
personTagIdList: this.formData.personTags,
|
socialDistinctionIdList: this.formData.socialIdentity,
|
dynastyIdList: this.formData.period,
|
page: this.formData.page,
|
pageSize: this.formData.pageSize
|
};
|
// // 搜索
|
getAdvancedData(Obj).then((res) => {
|
if (res?.success) {
|
this.tableData = res.list.map((item) => {
|
return {
|
id: item.personId,
|
name:
|
item?.NAME?.map((e, i) => {
|
let data = [];
|
Object.entries(e).forEach((c) => {
|
if (c[0]?.indexOf("content") > -1) {
|
data.push(c[1]);
|
}
|
});
|
return data;
|
}).join() ?? "",
|
alias:
|
item?.ALIAS?.map((e, i) => {
|
let data = [];
|
Object.entries(e).forEach((c) => {
|
if (c[0]?.indexOf("content") > -1) {
|
data.push(c[1]);
|
}
|
});
|
return data;
|
}).join() ?? "",
|
place:
|
item?.NATIVE_PLACE?.map((e, i) => {
|
let data = [];
|
Object.entries(e).forEach((c) => {
|
if (c[0]?.indexOf("content") > -1) {
|
data.push(c[1]);
|
}
|
});
|
return data;
|
}).join() ?? "",
|
medicalBranch:
|
item?.MEDICAL_BRANCH?.map((e, i) => {
|
let data = [];
|
Object.entries(e).forEach((c) => {
|
if (c[0]?.indexOf("content") > -1) {
|
data.push(c[1]);
|
}
|
});
|
return data;
|
}).join() ?? "",
|
socialDistinction:
|
item?.SOCIAL_IDENTITY?.map((e, i) => {
|
let data = [];
|
Object.entries(e).forEach((c) => {
|
if (c[0]?.indexOf("content") > -1) {
|
data.push(c[1]);
|
}
|
});
|
return data;
|
}).join() ?? "",
|
period:
|
item?.PERIOD?.map((e, i) => {
|
let data = [];
|
Object.entries(e).forEach((c) => {
|
if (c[0]?.indexOf("content") > -1) {
|
data.push(c[1]);
|
}
|
});
|
return data;
|
}).join() ?? "",
|
workName:
|
item?.REPRESENTATIVE_WORKS?.map((e, i) => {
|
let data = [];
|
Object.entries(e).forEach((c) => {
|
if (c[0]?.indexOf("content") > -1) {
|
data.push(c[1]);
|
}
|
});
|
return data;
|
}).join() ?? "",
|
personLabel:
|
item?.PERSON_LABEL?.map((e, i) => {
|
let data = [];
|
Object.entries(e).forEach((c) => {
|
if (c[0]?.indexOf("content") > -1) {
|
data.push(c[1]);
|
}
|
});
|
return data;
|
}).join() ?? ""
|
};
|
});
|
if (res?.npage) {
|
// 总数量
|
this.formData.total = res.npage.totalCount;
|
}
|
}
|
});
|
},
|
|
selectActively() {
|
this.drawer = true;
|
},
|
|
handleClose(done) {
|
done();
|
},
|
|
// 获取人物关系
|
getPersonInfo(arr, str, newArr, order, type, parent) {
|
for (let i = 0; i < arr.length; i++) {
|
const ele = arr[i];
|
const personInfo = this.infoOfPersons.find(
|
(item) => item.id == ele.personId
|
);
|
if (personInfo?.id) {
|
const obj = {
|
personId: ele.personId,
|
parentId: parent.id,
|
relationTypeName: ele.relationTypeName,
|
parentName: parent?.NAME[0]?.content1 ?? parent.parentName,
|
name: personInfo?.NAME[0]?.content1,
|
category: type,
|
symbolSize: 15,
|
};
|
if (order > 80) {
|
order = 80;
|
}
|
if (str == "literatureList") {
|
obj.relationTypeName = ele.literatureName;
|
}
|
if (str == "schoolList") {
|
const nameData = this.infoOfSchools?.find(
|
(i) => i.schoolId == ele.schoolId
|
);
|
obj.relationTypeName = nameData?.name[0];
|
}
|
if (str == "placeList") {
|
obj.relationTypeName = ele.ancientName ?? ele.currentName;
|
}
|
newArr.push(obj);
|
if (ele["kinList"] && ele["kinList"]?.length) {
|
order += 15;
|
this.getPersonInfo(
|
ele["kinList"],
|
"kinList",
|
newArr,
|
order,
|
0,
|
personInfo
|
);
|
}
|
if (ele["teacherStudentList"] && ele["teacherStudentList"]?.length) {
|
order += 15;
|
this.getPersonInfo(
|
ele["teacherStudentList"],
|
"teacherStudentList",
|
newArr,
|
order,
|
1,
|
personInfo
|
);
|
}
|
if (ele["literatureList"] && ele["literatureList"]?.length) {
|
const data = this.changeLiterature(
|
ele["literatureList"],
|
"literatureList"
|
);
|
order += 15;
|
this.getPersonInfo(
|
data,
|
"literatureList",
|
newArr,
|
order,
|
2,
|
personInfo
|
);
|
}
|
|
if (ele["socialList"] && ele["socialList"]?.length) {
|
const data = this.changeLiterature(ele["socialList"], "socialList");
|
order += 15;
|
this.getPersonInfo(
|
data,
|
"socialList",
|
newArr,
|
order,
|
3,
|
personInfo
|
);
|
}
|
if (ele["placeList"] && ele["placeList"]?.length) {
|
const data = this.changeLiterature(ele["placeList"], "placeList");
|
order += 15;
|
this.getPersonInfo(data, "placeList", newArr, order, 4, personInfo);
|
}
|
if (ele["schoolList"] && ele["schoolList"]?.length) {
|
const data = this.changeLiterature(ele["schoolList"], "schoolList");
|
order += 15;
|
this.getPersonInfo(
|
data,
|
"schoolList",
|
newArr,
|
order,
|
5,
|
personInfo
|
);
|
}
|
}
|
}
|
},
|
|
// 处理数据
|
changeLiterature(arr, str) {
|
for (let i = 0; i < arr.length; i++) {
|
const ele = arr[i];
|
if (!ele.personId && ele.personList?.length) {
|
ele.literatureList = [];
|
ele.personId = this.ownInfo.id;
|
if (ele["personList"] && ele["personList"]?.length) {
|
for (let j = 0; j < ele["personList"].length; j++) {
|
const item = ele["personList"][j];
|
const data = item[str]?.map((e) => {
|
return {
|
...e,
|
personId: item.personId,
|
};
|
});
|
if (ele[str] && data?.length) {
|
ele[str].push(...data);
|
}
|
}
|
}
|
}
|
}
|
return arr;
|
},
|
|
//数组去重
|
deduplicateArray(arr, idKey) {
|
// 使用一个辅助对象来跟踪已经见过的ID
|
const seen = {};
|
// 使用filter方法过滤数组
|
const deduplicatedArray = arr.filter((item) => {
|
// 获取当前对象的ID
|
const id = item[idKey];
|
// 如果ID在辅助对象中不存在,则将其添加到对象并返回true
|
if (!seen[id]) {
|
seen[id] = true;
|
return true;
|
}
|
// 如果ID已经存在,返回false
|
return false;
|
});
|
|
return deduplicatedArray;
|
},
|
|
// 查询详情
|
getData() {
|
this.loading = true;
|
getPersonData(this.currentId).then((res) => {
|
if (res && res.object) {
|
this.infoOfPersons = res?.object?.infoOfPersons;
|
this.infoOfSchools = res?.object?.infoOfSchools;
|
this.nodeDatas = [];
|
this.links = [];
|
this.handleData([res.object.personChain], null);
|
this.loading = false;
|
this.relation();
|
} else {
|
this.loading = false;
|
this.nodeDatas = [];
|
this.links = [];
|
}
|
// this.nodes = [];
|
// this.relationships = [];
|
// let kinData = [];
|
// let teacher = [];
|
// let literature = [];
|
// let social = [];
|
// let place = [];
|
// let school = [];
|
// if (res && res.success && res.object) {
|
// this.infoOfPersons = res.object?.infoOfPersons;
|
// this.infoOfSchools = res.object?.infoOfSchools;
|
|
// if (res.object?.personChain) {
|
// this.ownInfo = this.infoOfPersons.find(
|
// (item) => item.id == res.object?.personChain.personId
|
// );
|
// const obj = res.object?.personChain;
|
// if (obj.kinList?.length) {
|
// let newArr = [];
|
// this.categories.push({ name: "亲属关系" });
|
// this.getPersonInfo(
|
// obj.kinList,
|
// "kinList",
|
// newArr,
|
// 1,
|
// 0,
|
// this.ownInfo
|
// );
|
// kinData = [...newArr];
|
// }
|
// if (obj.teacherStudentList?.length) {
|
// this.categories.push({ name: "师承关系" });
|
// let newArr = [];
|
// this.getPersonInfo(
|
// obj.teacherStudentList,
|
// "teacherStudentList",
|
// newArr,
|
// 1,
|
// 1,
|
// this.ownInfo
|
// );
|
// teacher = [...newArr];
|
// }
|
// if (obj.literatureList?.length) {
|
// this.categories.push({ name: "文献作品" });
|
// let newArr = [];
|
// const data = this.changeLiterature(
|
// obj.literatureList,
|
// "literatureList"
|
// );
|
// this.getPersonInfo(
|
// data,
|
// "literatureList",
|
// newArr,
|
// 1,
|
// 2,
|
// this.ownInfo
|
// );
|
// literature = [...newArr];
|
// // console.log(literature, "literature");
|
// }
|
// if (obj.socialList?.length) {
|
// let newArr = [];
|
// this.categories.push({ name: "社会关系" });
|
// const data = this.changeLiterature(obj.socialList, "socialList");
|
// this.getPersonInfo(
|
// data,
|
// "socialList",
|
// newArr,
|
// 1,
|
// 3,
|
// this.ownInfo
|
// );
|
// social = [...newArr];
|
// }
|
// if (obj.placeList?.length) {
|
// this.categories.push({ name: "活动地" });
|
// let newArr = [];
|
// const data = this.changeLiterature(obj.placeList, "placeList");
|
// console.log(data, "place");
|
// this.getPersonInfo(data, "placeList", newArr, 1, 4, this.ownInfo);
|
// place = [...newArr];
|
// }
|
// if (obj.schoolList?.length) {
|
// this.categories.push({ name: "学术图谱" });
|
// let newArr = [];
|
// const data = this.changeLiterature(obj.schoolList, "schoolList");
|
// this.getPersonInfo(
|
// data,
|
// "schoolList",
|
// newArr,
|
// 1,
|
// 5,
|
// this.ownInfo
|
// );
|
// school = [...newArr];
|
// }
|
// }
|
// const personData = [
|
// ...kinData,
|
// ...teacher,
|
// ...literature,
|
// ...social,
|
// ...place,
|
// ...school
|
// ];
|
|
// personData.forEach((item) => {
|
// this.nodes.push({
|
// name: item.name,
|
// id: item.personId,
|
// ...item
|
// });
|
// let obj = {
|
// source: item.parentName,
|
// target: item.name,
|
// relation: item.relationTypeName || "" // 如果存在 relationName 字段则使用,否则为空字符串
|
// };
|
// this.relationships.push(obj);
|
// });
|
// }
|
});
|
},
|
|
// 递归处理所有层级数据
|
handleData(data, parent) {
|
for (let i = 0; i < data.length; i++) {
|
const item = data[i];
|
// 处理node/link
|
if (!parent) {
|
// 当前人物
|
item.mainId = item.personId + "_p";
|
const mainPerson = this.infoOfPersons.find(
|
(pItem) => pItem.id == item.personId
|
);
|
this.nodeDatas.push({
|
id: item.mainId,
|
name: mainPerson.NAME[0].content1,
|
itemStyle: {
|
color: "#244a7b",
|
},
|
});
|
} else {
|
switch (parent.thisType) {
|
case 1:
|
item.mainId = item.personId + "_p";
|
if (
|
this.nodeDatas.findIndex((cItem) => cItem.id == item.mainId) ==
|
-1
|
) {
|
const p = this.infoOfPersons.find(
|
(pItem) => pItem.id == item.personId
|
);
|
if (p) {
|
this.nodeDatas.push({
|
category: 0,
|
id: item.mainId,
|
name: p.NAME[0].content1,
|
});
|
}
|
}
|
this.links.push({
|
source: item.mainId,
|
target: parent.mainId,
|
label: {
|
show: true,
|
formatter: item.relationTypeName,
|
color: "#2C2C2C",
|
fontSize: 14,
|
backgroundColor: "rgba(255, 255, 255, 1)",
|
padding: [3, 8],
|
borderRadius: 30,
|
position: "middle", // 设置标签文本在线的中间位置上居中显示
|
distance: -10, // 将标签放置在连接线上
|
},
|
});
|
break;
|
case 2:
|
item.mainId = item.literatureId + "_l";
|
if (
|
this.nodeDatas.findIndex((cItem) => cItem.id == item.mainId) ==
|
-1
|
) {
|
this.nodeDatas.push({
|
category: 2,
|
id: item.mainId,
|
name: item.literatureName,
|
});
|
}
|
this.links.push({
|
source: item.mainId,
|
target: parent.mainId,
|
});
|
break;
|
case 3:
|
item.mainId = item.ancientName + "_a";
|
if (
|
this.nodeDatas.findIndex((cItem) => cItem.id == item.mainId) ==
|
-1
|
) {
|
this.nodeDatas.push({
|
category: 4,
|
id: item.mainId,
|
name: item.ancientName,
|
});
|
}
|
this.links.push({
|
source: item.mainId,
|
target: parent.mainId,
|
});
|
break;
|
case 4:
|
item.mainId = item.schoolId + "_s";
|
if (
|
this.nodeDatas.findIndex((cItem) => cItem.id == item.mainId) ==
|
-1
|
) {
|
const s = this.infoOfSchools.find(
|
(sItem) => sItem.schoolId == item.schoolId
|
);
|
if (s) {
|
this.nodeDatas.push({
|
category: 5,
|
id: item.mainId,
|
name: s.name[0],
|
});
|
}
|
}
|
this.links.push({
|
source: item.mainId,
|
target: parent.mainId,
|
});
|
break;
|
case 5:
|
item.mainId = item.personId + "_p";
|
if (
|
this.nodeDatas.findIndex((cItem) => cItem.id == item.mainId) ==
|
-1
|
) {
|
const p = this.infoOfPersons.find(
|
(pItem) => pItem.id == item.personId
|
);
|
if (p) {
|
this.nodeDatas.push({
|
category: 3,
|
id: item.mainId,
|
name: p.NAME[0].content1,
|
});
|
}
|
}
|
this.links.push({
|
source: item.mainId,
|
target: parent.mainId,
|
label: {
|
show: true,
|
formatter: item.relationTypeName,
|
color: "#2C2C2C",
|
fontSize: 14,
|
backgroundColor: "rgba(255, 255, 255, 1)",
|
padding: [3, 8],
|
borderRadius: 30,
|
position: "middle", // 设置标签文本在线的中间位置上居中显示
|
distance: -10, // 将标签放置在连接线上
|
},
|
});
|
break;
|
case 6:
|
item.mainId = item.personId + "_p";
|
if (
|
this.nodeDatas.findIndex((cItem) => cItem.id == item.mainId) ==
|
-1
|
) {
|
const p = this.infoOfPersons.find(
|
(pItem) => pItem.id == item.personId
|
);
|
if (p) {
|
this.nodeDatas.push({
|
category: 1,
|
id: item.mainId,
|
name: p.NAME[0].content1,
|
});
|
}
|
}
|
this.links.push({
|
source: item.mainId,
|
target: parent.mainId,
|
label: {
|
show: true,
|
formatter: item.relationTypeName,
|
color: "#2C2C2C",
|
fontSize: 14,
|
backgroundColor: "rgba(255, 255, 255, 1)",
|
padding: [3, 8],
|
borderRadius: 30,
|
position: "middle", // 设置标签文本在线的中间位置上居中显示
|
distance: -10, // 将标签放置在连接线上
|
},
|
});
|
break;
|
}
|
}
|
|
// 亲属关系
|
if (item.kinList && item.kinList.length) {
|
this.handleData(item.kinList, { ...item, thisType: 1 });
|
}
|
// 文献作品
|
if (item.literatureList && item.literatureList.length) {
|
this.handleData(item.literatureList, { ...item, thisType: 2 });
|
}
|
// 活动地
|
if (item.placeList && item.placeList.length) {
|
this.handleData(item.placeList, { ...item, thisType: 3 });
|
}
|
// 学术图谱
|
if (item.schoolList && item.schoolList.length) {
|
this.handleData(item.schoolList, { ...item, thisType: 4 });
|
}
|
// 社会关系
|
if (item.socialList && item.socialList.length) {
|
this.handleData(item.socialList, { ...item, thisType: 5 });
|
}
|
// 师承关系
|
if (item.teacherStudentList && item.teacherStudentList.length) {
|
this.handleData(item.teacherStudentList, { ...item, thisType: 6 });
|
}
|
}
|
},
|
|
// 关系图谱
|
relation() {
|
var chartDom = document.getElementById("relation");
|
var myChart = echarts.init(chartDom);
|
// 假设您有节点名称和它们之间的关系数据
|
this.nodeDatas = this.nodeDatas.map((item) => {
|
let size = 15;
|
for (let i = 0; i < this.links.length; i++) {
|
const linkItem = this.links[i];
|
if (linkItem.source == item.id) {
|
size += 5;
|
}
|
if (linkItem.target == item.id) {
|
size += 5;
|
}
|
}
|
return {
|
...item,
|
symbolSize: size > 80 ? 80 : size,
|
};
|
});
|
|
let FontSize = 12; // 字体大小
|
let BorderWidth = 2; // 边框大小
|
let SymbolSize = 80; // 尺寸距离
|
let Distance = 10;
|
// 不同尺寸下修改echarts的字体
|
if (window.innerWidth > 2560 && window.innerWidth <= 3840) {
|
FontSize = 20;
|
BorderWidth = 5;
|
SymbolSize = 90;
|
Distance = 33;
|
} else if (window.innerWidth > 1920 && window.innerWidth <= 2560) {
|
FontSize = 18;
|
BorderWidth = 4;
|
SymbolSize = 80;
|
Distance = 22;
|
} else if (window.innerWidth >= 1366 && window.innerWidth <= 1920) {
|
FontSize = 14;
|
BorderWidth = 4;
|
SymbolSize = 70;
|
Distance = 22;
|
}
|
var option;
|
option = {
|
legend: [
|
{
|
left: 20,
|
top: 20,
|
orient: "vertical",
|
data: this.categories.map(function (a) {
|
return a.name;
|
}),
|
},
|
],
|
series: [
|
{
|
type: "graph",
|
legendHoverLink: false,
|
layout: "force",
|
symbolSize: 15,
|
data: this.nodeDatas,
|
links: this.links,
|
categories: this.categories,
|
roam: true,
|
label: {
|
show: true,
|
position: "right",
|
formatter: "{b}",
|
},
|
scaleLimit: {
|
min: 0.4,
|
max: 2,
|
},
|
lineStyle: {
|
color: "source",
|
curveness: 0.2,
|
},
|
emphasis: {
|
focus: "adjacency",
|
lineStyle: {
|
width: 5,
|
},
|
},
|
force: {
|
repulsion: 600,
|
edgeLength: 300,
|
},
|
},
|
],
|
color: [
|
"#5470c6",
|
"#3dae7b",
|
"#fac858",
|
"#ee6666",
|
"#ea7ccc",
|
"#9a60b4",
|
],
|
};
|
// 设置点击事件监听
|
myChart.off("click");
|
myChart.on("click", (params) => {
|
if (params.dataType === "node") {
|
this.creatDom(params);
|
}
|
});
|
myChart.setOption(option);
|
},
|
|
creatDom(params) {
|
const id = params.data.id.split("_")[0];
|
const type = params.data.id.split("_")[1];
|
if (type == "p") {
|
// 人
|
const e = params.event;
|
const div = document.getElementById("customDialog");
|
div.style.display = "block";
|
const div2 = document.getElementById("schoolDialog");
|
div2.style.display = "none";
|
div.style.left = e.offsetX + 50 + "px";
|
div.style.top = e.offsetY - 50 + "px";
|
const data = this.infoOfPersons?.find((i) => i.id == id);
|
const obj = {
|
id: id,
|
name:
|
data?.NAME?.map((e, i) => {
|
i += 1;
|
return e["content" + i];
|
}).join("、") ?? "",
|
alias:
|
data?.ALIAS?.map((e, i) => {
|
i += 1;
|
return e["content" + i];
|
}).join("、") ?? "",
|
nativePlace:
|
data?.NATIVE_PLACE?.map((e, i) => {
|
i += 1;
|
return e["content" + i];
|
}).join("、") ?? "",
|
medicalBranch:
|
data?.MEDICAL_BRANCH?.map((e, i) => {
|
i += 1;
|
return e["content" + i];
|
}).join("、") ?? "",
|
biography: data?.BIOGRAPHY ?? "",
|
};
|
this.detailData = obj;
|
}
|
if (type == "s") {
|
// 学派
|
const e = params.event;
|
const div = document.getElementById("schoolDialog");
|
div.style.display = "block";
|
const div2 = document.getElementById("customDialog");
|
div2.style.display = "none";
|
div.style.left = e.offsetX + 50 + "px";
|
div.style.top = e.offsetY - 50 + "px";
|
const data = this.infoOfSchools?.find((i) => i.schoolId == id);
|
const obj = {
|
id: id,
|
name: data.name[0],
|
character: data.important_people
|
? data.important_people.map((item) => item.personName).join("、")
|
: "",
|
skilledDoctor: data.important_physician
|
? data.important_physician.map((item) => item.personName).join("、")
|
: "",
|
works: data.important_work
|
? data.important_work.map((item) => item.literatureTitle).join("、")
|
: "",
|
thought: data.school_introduction
|
? data.school_introduction.join("、")
|
: ""
|
};
|
this.detailData = obj;
|
}
|
},
|
|
closeDom() {
|
const div = document.getElementById("customDialog");
|
div.style.display = "none";
|
const div2 = document.getElementById("schoolDialog");
|
div2.style.display = "none";
|
},
|
|
// 基础搜索
|
onSearch(val, index) {
|
if (index !== undefined) {
|
// 热门搜索关键字,直接查询数据
|
this.searchKey = "";
|
this.hotAciveIndex = index;
|
this.currentId = val.text.id;
|
this.getData();
|
} else {
|
this.hotAciveIndex = "";
|
// 搜索先显示人物列表
|
this.personPageInfo.page = 1;
|
this.searchPerson(val.text);
|
}
|
},
|
|
// 根据关键字检索人物
|
searchPerson(key) {
|
academicSearch({
|
keyword: key,
|
page: 1,
|
pageSize: 999
|
}).then((res) => {
|
this.personList = res.list.map((item) => {
|
return {
|
id: item.personId,
|
name: item.name,
|
age:
|
item.periodList && item.periodList.length
|
? item.periodList[0].content2
|
: "-",
|
nativePlace:
|
item.nativePlaceList && item.nativePlaceList.length
|
? item.nativePlaceList[0].content1
|
: "-",
|
alias:
|
item.aliasList && item.aliasList.length
|
? item.aliasList[0].content2
|
: "-",
|
division:
|
item.medicalBranchList && item.medicalBranchList.length
|
? item.medicalBranchList[0].content1
|
: "-",
|
};
|
});
|
this.showPerson = true;
|
});
|
},
|
|
// 关系图 点击里面的元素
|
spaceTimeArr(id, type) {
|
if (type == 1) {
|
// 人物
|
uni.navigateTo({
|
url: "/pages/character/detail?id=" + id
|
});
|
} else {
|
// 学派
|
uni.navigateTo({
|
url: "/pages/academicGenres/detail?id=" + id
|
});
|
}
|
},
|
|
// 获取朝代echarts的数据
|
echartsArr() {
|
getDataStatistics().then((res) => {
|
res.object.dynastyStatistic.details.map((item, index) => {
|
// this.dynasty.id = item.dynastyId
|
// this.dynasty.name = item.dynastyName
|
// this.dynasty.coord = item.count
|
this.dynasty[index].id = item.dynastyId;
|
this.dynasty[index].name = item.dynastyName;
|
this.dynasty[index].coord = item.count;
|
});
|
});
|
},
|
|
// 热门搜索
|
hotSearch() {
|
getHotSearch().then((res) => {
|
const indexList = Object.keys(res.object);
|
indexList.sort((a, b) => parseInt(b) - parseInt(a));
|
this.hotKeyList = indexList.map((item) => {
|
return {
|
id: item,
|
name: res.object[item],
|
};
|
});
|
});
|
},
|
|
isAvancedClick() {
|
this.isAdvancedSearch = !this.isAdvancedSearch;
|
// this.$nextTick(() => {
|
// var box1Height = document.querySelector(".fbox").offsetHeight;
|
// // let box2Height= document.querySelector('.fbox1').style.height = box1Height + 'px';
|
// let box2Height = document.querySelector(".fbox1").offsetHeight;
|
// if (box1Height <= box2Height) {
|
// document.querySelector(".fbox1").style.height = box1Height + "px";
|
// }
|
// });
|
},
|
},
|
};
|
</script>
|
|
<style>
|
.fromTable {
|
width: 100%;
|
padding: 40px 0;
|
box-sizing: border-box;
|
}
|
|
.fromTable >>> .el-table thead th.el-table__cell {
|
background-color: rgb(194 208 217) !important;
|
color: #333;
|
font-weight: normal;
|
font-size: 14px;
|
}
|
|
.fromTable
|
.drawerPage
|
>>> .el-pagination.is-background
|
.el-pager
|
li:not(.disabled).active {
|
background-color: rgb(36, 74, 123) !important;
|
}
|
|
.customDrawer >>> .el-drawer__header {
|
margin-bottom: 20px;
|
border-bottom: 1px solid #eee;
|
padding: 20px;
|
box-sizing: border-box;
|
}
|
|
.headerClassBg {
|
background-color: rgb(95, 127, 168);
|
}
|
|
.drawerTips {
|
margin-bottom: 20px;
|
color: #666;
|
}
|
|
.drawerTable {
|
width: 100%;
|
}
|
|
.drawerTable >>> .el-table thead th.el-table__cell {
|
background-color: rgb(231, 236, 239) !important;
|
color: #333;
|
font-weight: normal;
|
}
|
|
.tableTabs {
|
width: 100%;
|
display: flex;
|
margin-bottom: 20px;
|
}
|
|
.inputItem {
|
width: 80%;
|
}
|
|
.drawerPage {
|
display: flex;
|
justify-content: flex-end;
|
padding: 20px 0;
|
box-sizing: border-box;
|
}
|
|
.drawerBtn {
|
display: flex;
|
justify-content: flex-end;
|
}
|
|
.drawerContent {
|
width: 100%;
|
height: 100%;
|
padding: 0 20px;
|
box-sizing: border-box;
|
}
|
|
/* 分页 */
|
.paging ::v-deep .btn-prev,
|
.paging ::v-deep .btn-next {
|
border: 0;
|
height: 30px;
|
}
|
|
.paging ::v-deep .btn-prev span,
|
.paging ::v-deep .btn-next span {
|
font-size: 0.12rem;
|
height: 0.3rem;
|
line-height: 0.3rem;
|
background-color: #fff;
|
color: #9e9e9e;
|
text-align: center;
|
border: 1px solid #9e9e9e;
|
padding: 0 0.1rem;
|
}
|
|
.paging ::v-deep .el-pager li {
|
font-size: 0.1rem;
|
width: 0.28rem;
|
height: 0.3rem;
|
line-height: 0.3rem;
|
background-color: #fff;
|
color: #9e9e9e;
|
text-align: center;
|
border: 1px solid #9e9e9e;
|
}
|
|
#relation {
|
width: 100%;
|
height: 100%;
|
position: relative;
|
background-image: url("../../static/image/characterRelationBg.png");
|
background-size: 100% 100%;
|
background-repeat: no-repeat;
|
background-position: center;
|
}
|
|
.customDialog {
|
width: 300px;
|
min-height: 240px;
|
display: none;
|
position: fixed;
|
z-index: 9999999;
|
border-radius: 2px;
|
background: #fff;
|
}
|
|
.customDialog .title {
|
width: 100%;
|
height: 35px;
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
padding: 10px;
|
box-sizing: border-box;
|
background-color: rgb(221, 232, 246);
|
font-size: 14px;
|
}
|
.customDialog .title span:nth-child(1) {
|
font-size: 16px;
|
font-weight: 600;
|
}
|
|
.customDialog .title span:nth-child(2) {
|
color: rgb(95, 127, 168);
|
cursor: pointer;
|
}
|
|
.customDialog .content {
|
padding: 15px;
|
box-sizing: border-box;
|
}
|
|
.customDialog .content p {
|
margin-bottom: 5px;
|
display: -webkit-box; /* 显示多行文本容器 */
|
-webkit-box-orient: vertical;
|
-webkit-line-clamp: 2; /*显示行数*/
|
overflow: hidden; /*隐藏多出部分文字*/
|
text-overflow: ellipsis; /*用省略号代替多出部分文字*/
|
}
|
|
.customDialog .btn {
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
color: rgb(95, 127, 168);
|
cursor: pointer;
|
font-size: 14px;
|
height: 35px;
|
}
|
|
@media screen and (min-width: 2560px) and (max-width: 3840px) {
|
}
|
|
@media screen and (min-width: 1366px) and (max-width: 1920px) {
|
}
|
|
::v-deep .uni-input-placeholder {
|
line-height: 1;
|
font-size: 0.12rem;
|
}
|
|
::v-deep .ffff {
|
border-radius: 0.5rem;
|
}
|
|
::v-deep .widget_button {
|
border-radius: 0.5rem;
|
margin: 0.02rem;
|
}
|
|
.hotSearch {
|
font-size: 0.12rem;
|
color: #2c2c2c;
|
|
li {
|
color: #244a7b;
|
margin: 0 0.1rem;
|
color: #244a7b;
|
&.active {
|
color: #027edc;
|
font-weight: bold;
|
}
|
}
|
}
|
|
.searchDialog {
|
position: absolute;
|
top: 0.68rem;
|
left: 0;
|
right: 0;
|
z-index: 999;
|
padding: 0.1rem 0.4rem;
|
background: #fff;
|
min-height: 2rem;
|
}
|
|
.personDialog {
|
position: absolute;
|
top: 0.68rem;
|
z-index: 999;
|
padding: 0.1rem;
|
background: #fff;
|
border-radius: 6px;
|
box-shadow: 0 0 10px -3px #000;
|
.closeBtn {
|
position: absolute;
|
right: -10px;
|
top: -10px;
|
width: 24px;
|
height: 24px;
|
font-size: 24px;
|
background-color: #fff;
|
border-radius: 50%;
|
color: #f56c6c;
|
cursor: pointer;
|
}
|
}
|
|
.selectActivelyBox {
|
cursor: pointer;
|
border: 1px solid #dcdfe6;
|
border-radius: 4px;
|
padding: 0 0.12rem;
|
font-size: 12px;
|
color: #c0c4cc;
|
}
|
|
.el-drawer__wrapper {
|
top: 0.86rem;
|
}
|
|
::v-deep .el-drawer__open .el-drawer.rtl {
|
width: 50% !important;
|
}
|
</style>
|