123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557 |
- <template>
- <div id="addRelation">
- <!-- 数据字典设备类型 -->
- <el-row>
- <el-col :span="12">
- <el-button size="small" type="default" icon="el-icon-back" @click="goback"></el-button>
- <div style="display:inline-block;width:345px;margin-left:10px;">
- <dictionary-device @change="changeDictionary" :Related="false" :typeName="typeName"></dictionary-device>
- </div>
- </el-col>
- <el-col :span="12" class="text-right">
- <el-switch @change="changeType" v-model="isSwitch"></el-switch>
- <span style="padding:0 5px;">AI辅助</span>
- <el-button size="medium" @click="showHistory" class="ani-his-plus">
- 本次对应记录 {{num}}
- <span v-if="showPlus" :class="{'plusOne':true,'startAni':showPlus}">+1</span>
- </el-button>
- </el-col>
- </el-row>
- <!-- 列表及查询条件区域 -->
- <div class="table-container clearfix">
- <div class="left-table">
- <h5>未对应的{{typeName}}标识</h5>
- <!-- 查询条件 -->
- <div class="query-box clearfix">
- <div class="query-item">
- <label>{{typeName}}标识关键字</label>
- <el-input :placeholder="`请输入${typeName}标识关键字`" v-model="form.EquipmentMark" @keyup.enter.native="queryLeftTable">
- <i slot="suffix" class="el-input__icon el-icon-search" @click="queryLeftTable"></i>
- </el-input>
- </div>
- <div class="query-item">
- <label>数据源</label>
- <dataSource :Related="false" @change="changeDataSource" :typeName="typeName"></dataSource>
- </div>
- <div class="query-item">
- <label>位置标签</label>
- <locationFlag :Related="false" @change="changeLocationFlag" :typeName="typeName"></locationFlag>
- </div>
- </div>
- <!-- 左侧列表 -->
- <div class="table-box">
- <div class="l-custom-table custom-table" v-loading="lTableLoading">
- <el-table ref="lTableBody" :data="LtableData" tooltip-effect="dark" style="width: 100%" height="100%" @row-click="clickLeftRow"
- @selection-change="leftSelectionChange">
- <el-table-column label="数据源" align="right" show-overflow-tooltip>
- <template slot-scope="scope">{{ scope.row.Datasource }}</template>
- </el-table-column>
- <el-table-column label="位置标签" align="right">
- <template slot-scope="scope">
- <el-tooltip :content="scope.row.LocationFlag.toString()" placement="top">
- <div class="tool-tip">{{scope.row.LocationFlag.toString()}}</div>
- </el-tooltip>
- </template>
- </el-table-column>
- <el-table-column prop="SubTypeName" :label="`${typeName}类型关键字`" align="right" show-overflow-tooltip></el-table-column>
- <el-table-column prop="EquipmentMark" :label="`${typeName}标识`" show-overflow-tooltip align="right" width="200" class-name="bgf5">
- </el-table-column>
- <el-table-column type="selection" width="35" class-name="bgf5"></el-table-column>
- </el-table>
- </div>
- <!-- 智能推荐 -->
- <transition name="el-zoom-in-top">
- <div class="AIRecom" v-show="leftRecoList.length&&leftAI&&rArray.length">
- <div class="l-title">
- 可能对应的{{typeName}}标识
- <i class="el-icon-close" @click="leftRecoList=[]"></i>
- </div>
- <div v-for="(t,i) in leftRecoList" :key="t.id" class="l-ai-recom-item ai-recom-item" @click="selectAI(i,'l')">
- <p>
- <el-checkbox v-model="t.checked"></el-checkbox>
- <span>{{(t.Proximity*100).toFixed(2)}}%</span>
- </p>
- <p>{{t.EquipmentMark&&t.EquipmentMark!='null'?t.EquipmentMark:''}}</p>
- <p>{{t.LocationFlag.toString()}}</p>
- <!-- <p>{{t.address}}</p> -->
- </div>
- </div>
- </transition>
- </div>
- </div>
- <div class="right-table" style="float: right;">
- <h5>未对应的{{typeName}}实例</h5>
- <!-- 查询条件 -->
- <div class="query-box clearfix">
- <div class="query-item">
- <label>{{typeName}}实例关键字</label>
- <el-input :placeholder="`请输入${typeName}实例关键字`" v-model="form.ObjectLocalName" @keyup.enter.native="queryRightTable">
- <i slot="suffix" class="el-input__icon el-icon-search" @click="queryRightTable"></i>
- </el-input>
- </div>
- <div class="query-item">
- <label>所在位置</label>
- <location-cas @change="changeLocation" :Related="false" :typeName="typeName"></location-cas>
- </div>
- </div>
- <!-- 右侧列表 -->
- <div class="table-box">
- <div class="r-custom-table custom-table" v-loading="rTableLoading">
- <el-table ref="rTableBody" :data="RtableData" tooltip-effect="dark" style="width: 100%" height="100%" @row-click="clickRightRow"
- @selection-change="rightSelectionChange">
- <el-table-column type="selection" width="35" class-name="bgf5"></el-table-column>
- <el-table-column :label="`${typeName}实例名称`" width="200" class-name="bgf5" show-overflow-tooltip>
- <template slot-scope="scope">{{ scope.row.ObjectLocalName }}</template>
- </el-table-column>
- <el-table-column prop="ObjectLocalCode" :label="`${typeName}本地编码`" show-overflow-tooltip></el-table-column>
- <el-table-column prop="SubTypeName" :label="`${typeName}类型`" show-overflow-tooltip></el-table-column>
- <el-table-column label="所在建筑楼层">
- <template slot-scope="scope">
- <el-tooltip
- :content="(scope.row.BuildLocalName?scope.row.BuildLocalName+'-':'')+(scope.row.FloorLocalName?scope.row.FloorLocalName:'')"
- placement="top">
- <div class="tool-tip">
- {{(scope.row.BuildLocalName?scope.row.BuildLocalName+'-':'')+(scope.row.FloorLocalName?scope.row.FloorLocalName:'')}}</div>
- </el-tooltip>
- </template>
- </el-table-column>
- <el-table-column prop="RoomLocalName" label="所在业务空间" show-overflow-tooltip></el-table-column>
- </el-table>
- </div>
- <!-- 智能推荐 -->
- <transition name="el-zoom-in-top">
- <div class="AIRecom" v-show="rightRecoList.length&&!leftAI&&lArray.length">
- <div class="r-title">
- 可能对应的{{typeName}}实例
- <i class="el-icon-close" @click="rightRecoList=[]"></i>
- </div>
- <div v-for="(t,i) in rightRecoList" :key="t.id" class="r-ai-recom-item ai-recom-item" @click="selectAI(i,'r')">
- <p>
- <el-checkbox v-model="t.checked"></el-checkbox>
- <span>{{(t.Proximity*100).toFixed(2)}}%</span>
- </p>
- <p>{{t.ObjectLocalName}}</p>
- <p>
- {{t.BuildLocalName&&t.BuildLocalName!='null'&&t.FloorLocalName&&t.FloorLocalName!='null'?t.BuildLocalName+'-'+t.FloorLocalName:''}}
- </p>
- <p>{{t.RoomLocalName&&t.RoomLocalName!='null'?t.RoomLocalName:''}}</p>
- <p>{{t.InstallLocation&&t.InstallLocation!='null'?t.InstallLocation:''}}</p>
- </div>
- </div>
- </transition>
- </div>
- </div>
- </div>
- <!-- 历史记录弹窗 -->
- <history-dialog ref="history" @delSuc="deleteSuc"></history-dialog>
- </div>
- </template>
- <script>
- import tools from "@/utils/tools";
- import historyDialog from "@/components/point/dynamicdata/historyDialog";
- import locationCas from "@/components/point/dynamicdata/locationCascader";
- import dictionaryDevice from "@/components/point/dynamicdata/dictionaryDevice";
- import dataSource from "@/components/point/dynamicdata/dataSource";
- import locationFlag from "@/components/point/dynamicdata/locationFlag";
- import { mapGetters, mapActions } from "vuex";
- import {
- dynamicPendingobjs,
- dynamicPendingPoint,
- dynamicCreateRelation,
- dynamicDeleteRelation,
- dynamicPointTypeList,
- dynamicQueryAI
- } from "@/api/scan/request";
- export default {
- components: {
- historyDialog,
- locationCas,
- dictionaryDevice,
- dataSource,
- locationFlag
- },
- data() {
- return {
- isSwitch: true, //AI辅助
- typeName: "", //当前类型
- LtableData: [], //列表数据
- RtableData: [], //列表数据
- form: {
- EquipmentMark: "", //设备标识关键字
- SubTypeName: [], //数据字典设备类型
- LocationFlag: [], //位置标签
- Datasource: [], //数据源
- ObjectLocalName: "", //设备实例关键字
- locationVal: [] //所在位置下拉
- }, //查询条件
- leftRecoList: [], //左推荐
- rightRecoList: [], //右推荐
- leftAI: true, //左右推荐公用-互斥
- lArray: [], //左侧选中数据
- rArray: [], //右侧选中数据
- hasRequestedFlag: false, //用于标识是否关联过数据,若是则重新请求第一页数据,
- showPlus: false, //+1记录动画
- num: 0, //记录条数
- timer: null, //函数节流 延时器
- historyList: [], //操作历史
- lTableLoading: false, //loading
- rTableLoading: false,
- lPage: {
- pageNumber: 1,
- pageSize: 50,
- total: 0
- },
- rPage: {
- pageNumber: 1,
- pageSize: 50,
- total: 0
- }
- };
- },
- created() {
- this.typeName = this.$route.query.typeName;
- this.init();
- },
- mounted() {
- this.lTableBody = this.$refs.lTableBody.bodyWrapper;
- this.rTableBody = this.$refs.rTableBody.bodyWrapper;
- this.lTableBody.addEventListener("scroll", () => {
- // 滚动距离
- let scrollTop = this.lTableBody.scrollTop;
- // 变量windowHeight是可视区的高度
- let windowHeight =
- this.lTableBody.clientHeight || this.lTableBody.clientHeight;
- // 变量scrollHeight是滚动条的总高度
- let scrollHeight =
- this.lTableBody.scrollHeight || this.lTableBody.scrollHeight;
- if (scrollTop + windowHeight === scrollHeight) {
- if (this.lPage.pageNumber * this.lPage.pageSize < this.lPage.total) {
- this.lPage.pageNumber++;
- if (this.LtableData.length < 50) {
- this.lPage.pageNumber = 1
- }
- this.getLeftData();
- }
- }
- });
- this.rTableBody.addEventListener("scroll", () => {
- // 滚动距离
- let scrollTop = this.rTableBody.scrollTop;
- // 变量windowHeight是可视区的高度
- let windowHeight =
- this.rTableBody.clientHeight || this.rTableBody.clientHeight;
- // 变量scrollHeight是滚动条的总高度
- let scrollHeight =
- this.rTableBody.scrollHeight || this.rTableBody.scrollHeight;
- if (scrollTop + windowHeight === scrollHeight) {
- // 获取到的不是全部数据 当滚动到底部 继续获取新的数据
- if (this.rPage.pageNumber * this.rPage.pageSize < this.rPage.total) {
- this.rPage.pageNumber++;
- if (this.RtableData.length < 50) {
- this.rPage.pageNumber = 1
- }
- this.getRightData();
- }
- }
- });
- },
- computed: {
- ...mapGetters("layout", ["projectId"]),
- requestFlag() {
- return this.lArray.length > 0 && this.rArray.length > 0;
- }
- },
- methods: {
- init() {
- this.queryLeftTable();
- this.queryRightTable();
- },
- //切换AI辅助
- changeType() { },
- //推荐中的选择事件
- selectAI(i, l) {
- //i 索引 l 左侧AI or 右侧AI
- if (l == "l") {
- this.leftRecoList[i].checked = true;
- this.lArray = [];
- this.lArray.push(this.leftRecoList[i]);
- } else {
- this.rightRecoList[i].checked = true;
- this.rArray = [];
- this.rArray.push(this.rightRecoList[i]);
- }
- },
- //查看本次历史记录
- showHistory() {
- this.$refs.history.showDialog(this.historyList);
- },
- //重新获取数据
- reGetData() {
- //删除选中项
- this.delSelectedRows(this.lArray, this.rArray);
- let history = { leftList: this.lArray, rightList: this.rArray };
- this.historyList.push(history); //保存本次操作记录
- this.lArray = []; //清空选中list
- this.rArray = [];
- this.num++; //右上角操作记录
- this.showPlus = true;
- setTimeout(() => {
- this.showPlus = false;
- }, 800);
- },
- //少于20条请求数据-否则删除选中项
- delSelectedRows(lArray, rArray) {
- for (let li = this.LtableData.length - 1; li >= 0; li--) {
- for (let lj = 0; lj < lArray.length; lj++) {
- if (this.LtableData[li] && (this.LtableData[li].EquipmentMark == lArray[lj].EquipmentMark && this.LtableData[li].SubTypeCode == lArray[lj].SubTypeCode)) {
- // this.LtableData.splice(i, 1)
- delete this.LtableData[li]
- continue; //结束当前本轮循环,开始新的一轮循环
- }
- }
- }
- this.LtableData = this.LtableData.filter(item => {
- return !(item == 'undefined')
- })
- for (let ri = this.RtableData.length - 1; ri >= 0; ri--) {
- for (let rj = 0; rj < rArray.length; rj++) {
- if (this.RtableData[ri] && (this.RtableData[ri].ObjectID == rArray[rj].ObjectID && this.RtableData[ri].SubTypeCode == rArray[rj].SubTypeCode)) {
- // this.RtableData.splice(i, 1)
- delete this.RtableData[ri]
- continue; //结束当前本轮循环,开始新的一轮循环
- }
- }
- }
- this.RtableData = this.RtableData.filter(item => {
- return !(item == 'undefined')
- })
- if (this.LtableData.length < 20 && this.lPage.Total > 49) {
- this.queryLeftTable()
- }
- if (this.RtableData.length < 20 && this.rPage.Total > 49) {
- this.queryRightTable()
- }
- },
- //表格中的选中事件
- leftSelectionChange(selection) {
- this.lArray = selection;
- },
- rightSelectionChange(selection) {
- this.rArray = selection;
- },
- //查询左侧列表
- queryLeftTable() {
- this.lPage.pageNumber = 1;
- if (this.$refs.lTableBody && this.$refs.lTableBody.bodyWrapper) {
- this.$refs.lTableBody.bodyWrapper.scrollTop = 0
- }
- this.getLeftData();
- },
- //查询右侧列表
- queryRightTable() {
- this.rPage.pageNumber = 1;
- if (this.$refs.rTableBody && this.$refs.rTableBody.bodyWrapper) {
- this.$refs.rTableBody.bodyWrapper.scrollTop = 0
- }
- this.getRightData();
- },
- //获取待关联点位-左侧
- getLeftData() {
- let param = {
- PageNumber: this.lPage.pageNumber,
- PageSize: this.lPage.pageSize,
- TypeNameList: [this.typeName]
- };
- //处理查询条件(目前只是单个查,需后台支持)
- if (this.form.EquipmentMark && this.form.EquipmentMark.length) {
- param.EquipmentMark = this.form.EquipmentMark;
- }
- if (this.form.SubTypeName.length) {
- param.SubTypeNameList = this.form.SubTypeName;
- }
- if (this.form.LocationFlag.length) {
- param.LocationFlagList = this.form.LocationFlag;
- }
- if (this.form.Datasource.length) {
- param.DatasourceList = this.form.Datasource;
- }
- this.lTableLoading = true;
- dynamicPendingPoint(param, res => {
- this.lPage.total = res.PageSize < 50 ? res.PageSize : res.Total;
- if (this.lPage.pageNumber == 1) {
- this.LtableData = res.Content;
- } else {
- this.LtableData = this.LtableData.concat(res.Content);
- }
- this.lTableLoading = false;
- });
- },
- //获取待关联实例-右侧
- getRightData() {
- let param = {
- PageNumber: this.rPage.pageNumber,
- PageSize: this.rPage.pageSize,
- TypeNameList: [this.typeName]
- };
- //处理查询条件
- if (this.form.ObjectLocalName && this.form.ObjectLocalName.length) {
- param.ObjectLocalName = this.form.ObjectLocalName;
- }
- if (this.form.SubTypeName.length) {
- param.SubTypeNameList = this.form.SubTypeName;
- }
- if (this.form.locationVal.length > 0) {
- param.BuildLocalName = this.form.locationVal[0];
- }
- if (this.form.locationVal.length > 1) {
- param.FloorLocalName = this.form.locationVal[1];
- }
- if (this.form.locationVal.length > 2) {
- param.SpaceType = this.form.locationVal[2];
- }
- if (this.form.locationVal.length > 3) {
- param.RoomLocalName = this.form.locationVal[3];
- }
- if (!this.form.locationVal.length) {
- delete param.BuildLocalName
- delete param.FloorLocalName
- delete param.SpaceType
- delete param.RoomLocalName
- }
- this.rTableLoading = true;
- dynamicPendingobjs(param, res => {
- this.rPage.total = res.PageSize < 50 ? res.PageSize : res.Total;
- if (this.rPage.pageNumber == 1) {
- this.RtableData = res.Content;
- } else {
- this.RtableData = this.RtableData.concat(res.Content);
- }
- this.rTableLoading = false;
- });
- },
- //清除对应关系成功
- deleteSuc() {
- this.num--;
- this.queryLeftTable();
- this.queryRightTable();
- },
- //所在位置修改
- changeLocation(val) {
- this.form.locationVal = val;
- this.queryRightTable();
- },
- //数据字典设备类型修改
- changeDictionary(val) {
- this.form.SubTypeName = val;
- this.queryLeftTable();
- this.queryRightTable();
- },
- //数据源修改
- changeDataSource(val) {
- this.form.Datasource = val;
- this.queryLeftTable();
- },
- //修改位置标签
- changeLocationFlag(val) {
- this.form.LocationFlag = val;
- this.queryLeftTable();
- },
- //返回
- goback() {
- this.$router.push({ path: '/point/dynamicdata', query: { typeName: this.typeName } })
- },
- //点击行
- clickLeftRow(row, column, event) {
- this.$refs.lTableBody.toggleRowSelection(row);
- },
- //点击行
- clickRightRow(row, column, event) {
- this.$refs.rTableBody.toggleRowSelection(row);
- },
- },
- watch: {
- projectId(n, o) {
- this.init();
- },
- //判断两边是否均有选中值-创建关联
- requestFlag(n, o) {
- if (n) {
- this.rightRecoList = [];
- this.leftRecoList = [];
- let object = {
- Objs: this.rArray,
- Points: this.lArray
- };
- let param = [];
- param.push(object);
- setTimeout(() => {
- this.reGetData();
- }, 200)
- dynamicCreateRelation(param, res => {
- if (res.Result == "success") {
- this.$message.success("关联成功");
- }
- });
- }
- },
- //AI辅助-左侧
- lArray(n, o) {
- //先清空,返回结果后赋值
- this.rightRecoList = [];
- clearTimeout(this.timer);
- if (this.isSwitch && n.length) {
- this.timer = setTimeout(() => {
- let param = []
- n.map(item => {
- param.push({
- Points: [item],
- Top: 3,
- Proximity: 0.5
- })
- })
- dynamicQueryAI(param, res => {
- this.rightRecoList = res.Content[0].Objs;
- this.leftAI = !this.rightRecoList.length
- })
- }, 800)
- } else {
- this.rightRecoList = []
- this.leftAI = true;
- }
- },
- //AI辅助-右侧
- rArray(n, o) {
- this.leftRecoList = [];
- clearTimeout(this.timer);
- if (this.isSwitch && n.length) {
- this.timer = setTimeout(() => {
- let param = []
- n.map(item => {
- param.push({
- Objs: [item],
- Top: 3,
- Proximity: 0.5
- })
- })
- dynamicQueryAI(param, res => {
- this.leftRecoList = res.Content[0].Points;
- this.leftAI = !!this.leftRecoList.length
- })
- }, 800)
- } else {
- this.leftRecoList = []
- this.leftAI = false
- }
- }
- }
- };
- </script>
- <style lang="scss" scoped>
- @import "../addRelationCommon.scss";
- </style>
- <style>
- body {
- overflow-y: hidden;
- }
- </style>
|