index.vue 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. <template>
  2. <div id="addRelation">
  3. <!-- 数据字典部件类型 -->
  4. <el-row>
  5. <el-col :span="12">
  6. <el-button size="small" type="default" icon="el-icon-back" @click="goback"></el-button>
  7. <div style="display:inline-block;width:317px;margin-left:10px;">
  8. <dictionary-device @change="changeDictionary" :Related="false" :typeName="typeName"></dictionary-device>
  9. </div>
  10. </el-col>
  11. <el-col :span="12" class="text-right">
  12. <el-switch @change="changeType" v-model="isSwitch"></el-switch>
  13. <span style="padding:0 5px;">AI辅助</span>
  14. <el-button size="medium" @click="showHistory" class="ani-his-plus">
  15. 本次对应记录 {{num}}
  16. <span v-if="showPlus" :class="{'plusOne':true,'startAni':showPlus}">+1</span>
  17. </el-button>
  18. </el-col>
  19. </el-row>
  20. <!-- 列表及查询条件区域 -->
  21. <div class="table-container clearfix">
  22. <div class="left-table">
  23. <h5>未对应的{{typeName}}标识</h5>
  24. <!-- 查询条件 -->
  25. <div class="query-box clearfix">
  26. <div class="query-item">
  27. <label>{{typeName}}标识关键字</label>
  28. <el-input :placeholder="`请输入${typeName}标识关键字`" v-model="form.EquipmentMark" @keyup.enter.native="queryLeftTable">
  29. <i slot="suffix" class="el-input__icon el-icon-search" @click="queryLeftTable"></i>
  30. </el-input>
  31. </div>
  32. <div class="query-item">
  33. <label>数据源</label>
  34. <dataSource :Related="false" @change="changeDataSource" :typeName="typeName"></dataSource>
  35. </div>
  36. <div class="query-item">
  37. <label>位置标签</label>
  38. <locationFlag :Related="false" @change="changeLocationFlag" :typeName="typeName"></locationFlag>
  39. </div>
  40. </div>
  41. <!-- 左侧列表 -->
  42. <div class="table-box">
  43. <div class="l-custom-table custom-table" v-loading="lTableLoading">
  44. <el-table ref="lTableBody" :data="LtableData" tooltip-effect="dark" style="width: 100%" height="100%" @row-click="clickLeftRow"
  45. @selection-change="leftSelectionChange">
  46. <el-table-column label="数据源" align="right" show-overflow-tooltip>
  47. <template slot-scope="scope">{{ scope.row.Datasource }}</template>
  48. </el-table-column>
  49. <el-table-column label="位置标签" align="right">
  50. <template slot-scope="scope">
  51. <el-tooltip :content="scope.row.LocationFlag.toString()" placement="top">
  52. <div class="tool-tip">{{scope.row.LocationFlag.toString()}}</div>
  53. </el-tooltip>
  54. </template>
  55. </el-table-column>
  56. <el-table-column prop="SubTypeName" :label="`${typeName}类型关键字`" align="right" show-overflow-tooltip></el-table-column>
  57. <el-table-column prop="EquipmentMark" :label="`${typeName}标识`" show-overflow-tooltip align="right" width="200" class-name="bgf5"></el-table-column>
  58. <el-table-column type="selection" width="35" class-name="bgf5"></el-table-column>
  59. </el-table>
  60. </div>
  61. <!-- 智能推荐 -->
  62. <transition name="el-zoom-in-top">
  63. <div class="AIRecom" v-show="leftRecoList.length&&leftAI&&rArray.length">
  64. <div class="l-title">
  65. 可能对应的{{typeName}}标识
  66. <i class="el-icon-close" @click="leftRecoList=[]"></i>
  67. </div>
  68. <div v-for="(t,i) in leftRecoList" :key="t.id" class="l-ai-recom-item ai-recom-item" @click="selectAI(i,'l')">
  69. <p>
  70. <el-checkbox v-model="t.checked"></el-checkbox>
  71. <span>{{(t.Proximity*100).toFixed(2)}}%</span>
  72. </p>
  73. <p>{{t.EquipmentMark&&t.EquipmentMark!='null'?t.EquipmentMark:''}}</p>
  74. <p>{{t.LocationFlag.toString()}}</p>
  75. <!-- <p>{{t.address}}</p> -->
  76. </div>
  77. </div>
  78. </transition>
  79. </div>
  80. </div>
  81. <div class="right-table" style="float: right;">
  82. <h5>未对应的{{typeName}}实例</h5>
  83. <!-- 查询条件 -->
  84. <div class="query-box clearfix">
  85. <div class="query-item">
  86. <label>{{typeName}}实例关键字</label>
  87. <el-input :placeholder="`请输入${typeName}实例关键字`" v-model="form.ObjectLocalName" @keyup.enter.native="queryRightTable">
  88. <i slot="suffix" class="el-input__icon el-icon-search" @click="queryRightTable"></i>
  89. </el-input>
  90. </div>
  91. <div class="query-item">
  92. <label>所在位置</label>
  93. <location-cas @change="changeLocation" :Related="false" :typeName="typeName"></location-cas>
  94. </div>
  95. </div>
  96. <!-- 右侧列表 -->
  97. <div class="table-box">
  98. <div class="r-custom-table custom-table" v-loading="rTableLoading">
  99. <el-table ref="rTableBody" :data="RtableData" tooltip-effect="dark" style="width: 100%" height="100%" @row-click="clickRightRow"
  100. @selection-change="rightSelectionChange">
  101. <el-table-column type="selection" width="35" class-name="bgf5"></el-table-column>
  102. <el-table-column :label="`${typeName}实例名称`" width="200" class-name="bgf5" show-overflow-tooltip>
  103. <template slot-scope="scope">{{ scope.row.ObjectLocalName }}</template>
  104. </el-table-column>
  105. <el-table-column prop="ObjectLocalCode" :label="`${typeName}本地编码`" show-overflow-tooltip></el-table-column>
  106. <el-table-column prop="SubTypeName" :label="`${typeName}类型`" show-overflow-tooltip></el-table-column>
  107. <!-- <el-table-column prop="CascadeEquipLocalName" label="所属设备实例" show-overflow-tooltip></el-table-column> -->
  108. <el-table-column label="所在建筑楼层">
  109. <template slot-scope="scope">
  110. <el-tooltip :content="scope.row.BuildLocalName?scope.row.BuildLocalName+'-':''+scope.row.FloorLocalName?scope.row.FloorLocalName:''"
  111. placement="top">
  112. <div class="tool-tip">
  113. {{scope.row.BuildLocalName?scope.row.BuildLocalName+'-':''+scope.row.FloorLocalName?scope.row.FloorLocalName:''}}</div>
  114. </el-tooltip>
  115. </template>
  116. </el-table-column>
  117. <!-- <el-table-column prop="RoomLocalName" label="所在业务空间" show-overflow-tooltip></el-table-column> -->
  118. </el-table>
  119. </div>
  120. <!-- 智能推荐 -->
  121. <transition name="el-zoom-in-top">
  122. <div class="AIRecom" v-show="rightRecoList.length&&!leftAI&&lArray.length">
  123. <div class="r-title">
  124. 可能对应的{{typeName}}实例
  125. <i class="el-icon-close" @click="rightRecoList=[]"></i>
  126. </div>
  127. <div v-for="(t,i) in rightRecoList" :key="t.id" class="r-ai-recom-item ai-recom-item" @click="selectAI(i,'r')">
  128. <p>
  129. <el-checkbox v-model="t.checked"></el-checkbox>
  130. <span>{{(t.Proximity*100).toFixed(2)}}%</span>
  131. </p>
  132. <p>{{t.ObjectLocalName}}</p>
  133. <p>
  134. {{t.BuildLocalName&&t.BuildLocalName!='null'&&t.FloorLocalName&&t.FloorLocalName!='null'?t.BuildLocalName+'-'+t.FloorLocalName:''}}
  135. </p>
  136. <p>{{t.RoomLocalName&&t.RoomLocalName!='null'?t.RoomLocalName:''}}</p>
  137. <p>{{t.InstallLocation&&t.InstallLocation!='null'?t.InstallLocation:''}}</p>
  138. </div>
  139. </div>
  140. </transition>
  141. </div>
  142. </div>
  143. </div>
  144. <!-- 历史记录弹窗 -->
  145. <history-dialog ref="history" @delSuc="deleteSuc" :typeName="'space'"></history-dialog>
  146. </div>
  147. </template>
  148. <script>
  149. import tools from "@/utils/tools";
  150. import historyDialog from "@/components/point/dynamicdata/historyDialog";
  151. import locationCas from "@/components/point/dynamicdata/locationCascader";
  152. import dictionaryDevice from "@/components/point/dynamicdata/dictionaryDevice";
  153. import dataSource from "@/components/point/dynamicdata/dataSource";
  154. import locationFlag from "@/components/point/dynamicdata/locationFlag";
  155. import { mapGetters, mapActions } from "vuex";
  156. import {
  157. dynamicPendingobjs,
  158. dynamicPendingPoint,
  159. dynamicCreateRelation,
  160. dynamicDeleteRelation,
  161. dynamicPointTypeList,
  162. dynamicQueryAI
  163. } from "@/api/scan/request";
  164. export default {
  165. components: {
  166. historyDialog,
  167. locationCas,
  168. dictionaryDevice,
  169. dataSource,
  170. locationFlag
  171. },
  172. data() {
  173. return {
  174. isSwitch: true, //AI辅助
  175. typeName: "", //当前类型
  176. LtableData: [], //列表数据
  177. RtableData: [], //列表数据
  178. form: {
  179. EquipmentMark: "", //部件标识关键字
  180. SubTypeName: [], //数据字典部件类型
  181. LocationFlag: [], //位置标签
  182. Datasource: [], //数据源
  183. ObjectLocalName: "", //部件实例关键字
  184. locationVal: [] //所在位置下拉
  185. }, //查询条件
  186. leftRecoList: [], //左推荐
  187. rightRecoList: [], //右推荐
  188. leftAI: true, //左右推荐公用-互斥
  189. lArray: [], //左侧选中数据
  190. rArray: [], //右侧选中数据
  191. hasRequestedFlag: false, //用于标识是否关联过数据,若是则重新请求第一页数据,
  192. showPlus: false, //+1记录动画
  193. num: 0, //记录条数
  194. timer: null, //函数节流 延时器
  195. historyList: [], //操作历史
  196. lTableLoading: false, //loading
  197. rTableLoading: false,
  198. lPage: {
  199. pageNumber: 1,
  200. pageSize: 50,
  201. total: 0
  202. },
  203. rPage: {
  204. pageNumber: 1,
  205. pageSize: 50,
  206. total: 0
  207. }
  208. };
  209. },
  210. created() {
  211. this.typeName = this.$route.query.typeName;
  212. this.init();
  213. },
  214. mounted() {
  215. this.lTableBody = this.$refs.lTableBody.bodyWrapper;
  216. this.rTableBody = this.$refs.rTableBody.bodyWrapper;
  217. this.lTableBody.addEventListener("scroll", () => {
  218. // 滚动距离
  219. let scrollTop = this.lTableBody.scrollTop;
  220. // 变量windowHeight是可视区的高度
  221. let windowHeight =
  222. this.lTableBody.clientHeight || this.lTableBody.clientHeight;
  223. // 变量scrollHeight是滚动条的总高度
  224. let scrollHeight =
  225. this.lTableBody.scrollHeight || this.lTableBody.scrollHeight;
  226. if (scrollTop + windowHeight === scrollHeight) {
  227. if (this.lPage.pageNumber * this.lPage.pageSize < this.lPage.total) {
  228. this.lPage.pageNumber++;
  229. if (this.LtableData.length < 50) {
  230. this.lPage.pageNumber = 1
  231. }
  232. this.getLeftData();
  233. }
  234. }
  235. });
  236. this.rTableBody.addEventListener("scroll", () => {
  237. // 滚动距离
  238. let scrollTop = this.rTableBody.scrollTop;
  239. // 变量windowHeight是可视区的高度
  240. let windowHeight =
  241. this.rTableBody.clientHeight || this.rTableBody.clientHeight;
  242. // 变量scrollHeight是滚动条的总高度
  243. let scrollHeight =
  244. this.rTableBody.scrollHeight || this.rTableBody.scrollHeight;
  245. if (scrollTop + windowHeight === scrollHeight) {
  246. // 获取到的不是全部数据 当滚动到底部 继续获取新的数据
  247. if (this.rPage.pageNumber * this.rPage.pageSize < this.rPage.total) {
  248. this.rPage.pageNumber++;
  249. if (this.RtableData.length < 50) {
  250. this.rPage.pageNumber = 1
  251. }
  252. this.getRightData();
  253. }
  254. }
  255. });
  256. },
  257. computed: {
  258. ...mapGetters("layout", ["projectId"]),
  259. requestFlag() {
  260. return this.lArray.length > 0 && this.rArray.length > 0;
  261. }
  262. },
  263. methods: {
  264. init() {
  265. this.queryLeftTable();
  266. this.queryRightTable();
  267. },
  268. //切换AI辅助
  269. changeType() { },
  270. //推荐中的选择事件
  271. selectAI(i, l) {
  272. //i 索引 l 左侧AI or 右侧AI
  273. if (l == "l") {
  274. this.leftRecoList[i].checked = true;
  275. this.lArray = [];
  276. this.lArray.push(this.leftRecoList[i]);
  277. } else {
  278. this.rightRecoList[i].checked = true;
  279. this.rArray = [];
  280. this.rArray.push(this.rightRecoList[i]);
  281. }
  282. },
  283. //查看本次历史记录
  284. showHistory() {
  285. this.$refs.history.showDialog(this.historyList);
  286. },
  287. //重新获取数据
  288. reGetData() {
  289. //删除选中项
  290. this.delSelectedRows(this.lArray, this.rArray);
  291. let history = { leftList: this.lArray, rightList: this.rArray };
  292. this.historyList.push(history); //保存本次操作记录
  293. this.lArray = []; //清空选中list
  294. this.rArray = [];
  295. this.num++; //右上角操作记录
  296. this.showPlus = true;
  297. setTimeout(() => {
  298. this.showPlus = false;
  299. }, 800);
  300. },
  301. //少于20条请求数据-否则删除选中项
  302. delSelectedRows(lArray, rArray) {
  303. for (let li = this.LtableData.length - 1; li >= 0; li--) {
  304. for (let lj = 0; lj < lArray.length; lj++) {
  305. if (this.LtableData[li] && (this.LtableData[li].EquipmentMark == lArray[lj].EquipmentMark && this.LtableData[li].SubTypeCode == lArray[lj].SubTypeCode)) {
  306. // this.LtableData.splice(i, 1)
  307. delete this.LtableData[li]
  308. continue; //结束当前本轮循环,开始新的一轮循环
  309. }
  310. }
  311. }
  312. this.LtableData = this.LtableData.filter(item => {
  313. return !(item == 'undefined')
  314. })
  315. for (let ri = this.RtableData.length - 1; ri >= 0; ri--) {
  316. for (let rj = 0; rj < rArray.length; rj++) {
  317. if (this.RtableData[ri] && (this.RtableData[ri].ObjectID == rArray[rj].ObjectID && this.RtableData[ri].SubTypeCode == rArray[rj].SubTypeCode)) {
  318. // this.RtableData.splice(i, 1)
  319. delete this.RtableData[ri]
  320. continue; //结束当前本轮循环,开始新的一轮循环
  321. }
  322. }
  323. }
  324. this.RtableData = this.RtableData.filter(item => {
  325. return !(item == 'undefined')
  326. })
  327. if (this.LtableData.length < 20 && this.lPage.Total > 49) {
  328. this.queryLeftTable()
  329. }
  330. if (this.RtableData.length < 20 && this.rPage.Total > 49) {
  331. this.queryRightTable()
  332. }
  333. },
  334. //表格中的选中事件
  335. leftSelectionChange(selection) {
  336. this.lArray = selection;
  337. },
  338. rightSelectionChange(selection) {
  339. this.rArray = selection;
  340. },
  341. //查询左侧列表
  342. queryLeftTable() {
  343. this.lPage.pageNumber = 1;
  344. if (this.$refs.lTableBody && this.$refs.lTableBody.bodyWrapper) {
  345. this.$refs.lTableBody.bodyWrapper.scrollTop = 0
  346. }
  347. this.getLeftData();
  348. },
  349. //查询右侧列表
  350. queryRightTable() {
  351. this.rPage.pageNumber = 1;
  352. if (this.$refs.rTableBody && this.$refs.rTableBody.bodyWrapper) {
  353. this.$refs.rTableBody.bodyWrapper.scrollTop = 0
  354. }
  355. this.getRightData();
  356. },
  357. //获取待关联点位-左侧
  358. getLeftData() {
  359. let param = {
  360. PageNumber: this.lPage.pageNumber,
  361. PageSize: this.lPage.pageSize,
  362. TypeNameList: [this.typeName]
  363. };
  364. //处理查询条件(目前只是单个查,需后台支持)
  365. if (this.form.EquipmentMark && this.form.EquipmentMark.length) {
  366. param.EquipmentMark = this.form.EquipmentMark;
  367. }
  368. if (this.form.SubTypeName.length) {
  369. param.SubTypeNameList = this.form.SubTypeName;
  370. }
  371. if (this.form.LocationFlag.length) {
  372. param.LocationFlagList = this.form.LocationFlag;
  373. }
  374. if (this.form.Datasource.length) {
  375. param.DatasourceList = this.form.Datasource;
  376. }
  377. this.lTableLoading = true;
  378. dynamicPendingPoint(param, res => {
  379. this.lPage.total = res.PageSize < 50 ? res.PageSize : res.Total;
  380. if (this.lPage.pageNumber == 1) {
  381. this.LtableData = res.Content;
  382. } else {
  383. this.LtableData = this.LtableData.concat(res.Content);
  384. }
  385. this.lTableLoading = false;
  386. });
  387. },
  388. //获取待关联实例-右侧
  389. getRightData() {
  390. let param = {
  391. PageNumber: this.rPage.pageNumber,
  392. PageSize: this.rPage.pageSize,
  393. TypeNameList: [this.typeName]
  394. };
  395. //处理查询条件
  396. if (this.form.ObjectLocalName && this.form.ObjectLocalName.length) {
  397. param.ObjectLocalName = this.form.ObjectLocalName;
  398. }
  399. if (this.form.SubTypeName.length) {
  400. param.SubTypeNameList = this.form.SubTypeName;
  401. }
  402. if (this.form.locationVal.length > 0) {
  403. param.BuildLocalName = this.form.locationVal[0];
  404. }
  405. if (this.form.locationVal.length > 1) {
  406. param.FloorLocalName = this.form.locationVal[1];
  407. }
  408. if (this.form.locationVal.length > 2) {
  409. param.SpaceType = this.form.locationVal[2];
  410. }
  411. if (this.form.locationVal.length > 3) {
  412. param.RoomLocalName = this.form.locationVal[3];
  413. }
  414. if (!this.form.locationVal.length) {
  415. delete param.BuildLocalName
  416. delete param.FloorLocalName
  417. delete param.SpaceType
  418. delete param.RoomLocalName
  419. }
  420. this.rTableLoading = true;
  421. dynamicPendingobjs(param, res => {
  422. this.rPage.total = res.PageSize < 50 ? res.PageSize : res.Total;
  423. if (this.rPage.pageNumber == 1) {
  424. this.RtableData = res.Content;
  425. } else {
  426. this.RtableData = this.RtableData.concat(res.Content);
  427. }
  428. this.rTableLoading = false;
  429. });
  430. },
  431. //清除对应关系成功
  432. deleteSuc() {
  433. this.num--;
  434. this.queryLeftTable();
  435. this.queryRightTable();
  436. },
  437. //所在位置修改
  438. changeLocation(val) {
  439. this.form.locationVal = val;
  440. this.queryRightTable();
  441. },
  442. //数据字典部件类型修改
  443. changeDictionary(val) {
  444. this.form.SubTypeName = val;
  445. this.queryLeftTable();
  446. this.queryRightTable();
  447. },
  448. //数据源修改
  449. changeDataSource(val) {
  450. this.form.Datasource = val;
  451. this.queryLeftTable();
  452. },
  453. //修改位置标签
  454. changeLocationFlag(val) {
  455. this.form.LocationFlag = val;
  456. this.queryLeftTable();
  457. },
  458. //返回
  459. goback() {
  460. this.$router.push({ path: '/point/dynamicdata', query: { typeName: this.typeName } })
  461. },
  462. //点击行
  463. clickLeftRow(row, column, event) {
  464. this.$refs.lTableBody.toggleRowSelection(row);
  465. },
  466. //点击行
  467. clickRightRow(row, column, event) {
  468. this.$refs.rTableBody.toggleRowSelection(row);
  469. },
  470. },
  471. watch: {
  472. projectId(n, o) {
  473. this.init();
  474. },
  475. //判断两边是否均有选中值-创建关联
  476. requestFlag(n, o) {
  477. if (n) {
  478. this.rightRecoList = [];
  479. this.leftRecoList = [];
  480. let object = {
  481. Objs: this.rArray,
  482. Points: this.lArray
  483. };
  484. let param = [];
  485. param.push(object);
  486. setTimeout(() => {
  487. this.reGetData();
  488. }, 200)
  489. dynamicCreateRelation(param, res => {
  490. if (res.Result == "success") {
  491. this.$message.success("关联成功");
  492. }
  493. });
  494. }
  495. },
  496. //AI辅助-左侧
  497. lArray(n, o) {
  498. //先清空,返回结果后赋值
  499. this.rightRecoList = [];
  500. clearTimeout(this.timer);
  501. if (this.isSwitch && n.length) {
  502. this.timer = setTimeout(() => {
  503. let param = []
  504. n.map(item => {
  505. param.push({
  506. Points: [item],
  507. Top: 3,
  508. Proximity: 0.5
  509. })
  510. })
  511. dynamicQueryAI(param, res => {
  512. this.rightRecoList = res.Content[0].Objs;
  513. this.leftAI = !this.rightRecoList.length
  514. })
  515. }, 800)
  516. } else {
  517. this.rightRecoList = []
  518. this.leftAI = true;
  519. }
  520. },
  521. //AI辅助-右侧
  522. rArray(n, o) {
  523. this.leftRecoList = [];
  524. clearTimeout(this.timer);
  525. if (this.isSwitch && n.length) {
  526. this.timer = setTimeout(() => {
  527. let param = []
  528. n.map(item => {
  529. param.push({
  530. Objs: [item],
  531. Top: 3,
  532. Proximity: 0.5
  533. })
  534. })
  535. dynamicQueryAI(param, res => {
  536. this.leftRecoList = res.Content[0].Points;
  537. this.leftAI = !!this.leftRecoList.length
  538. })
  539. }, 800)
  540. } else {
  541. this.leftRecoList = []
  542. this.leftAI = false
  543. }
  544. }
  545. }
  546. };
  547. </script>
  548. <style lang="scss" scoped>
  549. #addRelation {
  550. height: 100%;
  551. background-color: #fff;
  552. padding: 10px 20px 10px 10px;
  553. .text-right {
  554. text-align: right;
  555. }
  556. /deep/ .table-container {
  557. height: calc(100% - 160px);
  558. & > div {
  559. width: 49.5%;
  560. float: left;
  561. }
  562. .left-table,
  563. .right-table {
  564. height: 100%;
  565. h5 {
  566. line-height: 44px;
  567. padding-left: 5px;
  568. background-color: #e1e4e5;
  569. color: #2b2b2b
  570. }
  571. .query-box {
  572. margin-bottom: 20px;
  573. .query-item {
  574. float: left;
  575. width: 30%;
  576. margin: 5px;
  577. label {
  578. display: block;
  579. margin-bottom: 5px;
  580. }
  581. .el-select {
  582. width: 100%;
  583. }
  584. }
  585. }
  586. .table-box {
  587. height: calc(100% - 50px);
  588. position: relative;
  589. .AIRecom {
  590. position: absolute;
  591. width: 96%;
  592. height: 160px;
  593. bottom: 5px;
  594. left: 1%;
  595. background-color: rgba(255, 255, 255, 0.9);
  596. z-index: 3;
  597. font-size: 12px;
  598. .r-title {
  599. padding-left: 10px;
  600. i {
  601. float: right;
  602. }
  603. }
  604. .l-title {
  605. text-align: right;
  606. padding-right: 10px;
  607. i {
  608. float: left;
  609. }
  610. }
  611. .ai-recom-item {
  612. width: 30%;
  613. height: 126px;
  614. float: left;
  615. border: 1px solid #ebeef5;
  616. overflow: hidden;
  617. padding-top: 5px;
  618. box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  619. p {
  620. position: relative;
  621. white-space: nowrap;
  622. text-overflow: ellipsis;
  623. overflow: hidden;
  624. padding: 0 8px;
  625. z-index: -1;
  626. span {
  627. float: right;
  628. }
  629. .el-checkbox {
  630. margin-right: 0;
  631. }
  632. }
  633. }
  634. .ai-recom-item.r-ai-recom-item + .ai-recom-item {
  635. margin-left: 3%;
  636. }
  637. .l-ai-recom-item {
  638. float: right;
  639. p {
  640. text-align: right;
  641. padding-right: 10px;
  642. span {
  643. float: left;
  644. }
  645. }
  646. }
  647. .ai-recom-item.l-ai-recom-item + .ai-recom-item {
  648. margin-right: 3%;
  649. }
  650. }
  651. }
  652. ::-webkit-scrollbar {
  653. display: none;
  654. }
  655. //列表
  656. .custom-table {
  657. height: 100%;
  658. .bgf5 {
  659. background-color: #f5f7fa;
  660. }
  661. thead label.el-checkbox {
  662. display: none;
  663. }
  664. }
  665. .l-custom-table {
  666. td {
  667. text-align: right;
  668. }
  669. }
  670. .tool-tip {
  671. white-space: nowrap;
  672. overflow: hidden;
  673. text-overflow: ellipsis;
  674. }
  675. }
  676. }
  677. .fr {
  678. padding-top: 10px;
  679. float: right;
  680. }
  681. .clearfix:before,
  682. .clearfix:after {
  683. content: "";
  684. display: block;
  685. clear: both;
  686. }
  687. .clearfix {
  688. zoom: 1;
  689. }
  690. .ani-his-plus {
  691. position: relative;
  692. .plusOne {
  693. position: absolute;
  694. color: red;
  695. left: 50%;
  696. bottom: 50%;
  697. font-size: 20px;
  698. font-weight: 800;
  699. }
  700. .startAni {
  701. animation: fadeToTop 1s;
  702. }
  703. }
  704. @keyframes fadeToTop {
  705. 0% {
  706. left: 50%;
  707. bottom: 50%;
  708. opacity: 1;
  709. }
  710. 100% {
  711. bottom: 100%;
  712. opacity: 0;
  713. }
  714. }
  715. }
  716. </style>
  717. <style>
  718. body {
  719. overflow-y: hidden;
  720. }
  721. </style>