index.vue 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  1. <template>
  2. <div class="container-ln">
  3. <customHeader>潞宁新增</customHeader>
  4. <div class="video-ln">
  5. <div v-for="(item, index) in addrList" :key="index" class="video-module">
  6. <div class="player-name">{{ item.name }}</div>
  7. <div style="padding-top:3px">
  8. <template v-if="item.addr.startsWith('rtsp://')">
  9. <video :id="`video${index}`" muted autoplay></video>
  10. <div class="click-box" @dblclick="goFullScreen(`video${index}`)"></div>
  11. </template>
  12. <template v-else>
  13. <div :id="'player' + index"></div>
  14. </template>
  15. </div>
  16. </div>
  17. </div>
  18. <div class="content-ln">
  19. <a-tabs class="tabs-box" type="card" v-model:activeKey="activeKey" @change="tabChange" id="tabsBox">
  20. <a-tab-pane key="1" tab="安全监控">
  21. <template v-if="deviceType == 'fan' && activeKey == '1'">
  22. <GroupMonitorTable :dataSource="dataSource" :columnsType="`${deviceType}_monitor`" />
  23. </template>
  24. <template v-else-if="activeKey == '1' && deviceType">
  25. <template v-if="hasPermission('btn:noGb')">
  26. <MonitorTable ref="monitorTable" :columnsType="`${deviceType}_monitor`"
  27. :dataSource="dataSource" design-scope="device_monitor" :isShowPagination="false"
  28. :isShowActionColumn="isHaveAction.includes(deviceType.split('_')[0]) ? false : true"
  29. :is-show-select="false" title="设备监测" :scroll="{ y: 360 }" />
  30. </template>
  31. <template v-else>
  32. <MonitorTable ref="monitorTable" :columnsType="`${deviceType}_monitor`"
  33. :dataSource="dataSource" design-scope="device_monitor" :isShowPagination="false"
  34. :isShowActionColumn="isHaveAction.includes(deviceType.split('_')[0]) ? false : true"
  35. :is-show-select="false" title="设备监测" :form-config="undefined" :scroll="{ y: 650 }">
  36. <template #filterCell="{ column, record }">
  37. <template v-if="deviceType.startsWith('gate')">
  38. <template
  39. v-if="record.frontGateOpenCtrl == 1 || record.frontGateOpenCtrl === true">
  40. <a-tag
  41. v-if="column.dataIndex === 'frontGateOpen' && record.frontGateOpen == 0 && record.frontGateClose == 0"
  42. color="red">正在打开</a-tag>
  43. <a-tag v-else-if="column.dataIndex === 'frontGateOpen'"
  44. color="processing">打开</a-tag>
  45. </template>
  46. <template
  47. v-else-if="record.frontGateOpenCtrl == 0 || record.frontGateOpenCtrl === false">
  48. <a-tag
  49. v-if="column.dataIndex === 'frontGateOpen' && record.frontGateOpen == 0 && record.frontGateClose == 0"
  50. color="red">正在关闭</a-tag>
  51. <a-tag
  52. v-else-if="column.dataIndex === 'frontGateOpen' && record.frontGateOpen == 0 && record.frontGateClose == 1"
  53. color="default">关闭</a-tag>
  54. <a-tag
  55. v-else-if="column.dataIndex === 'frontGateOpen' && record.frontGateOpen == 1 && record.frontGateClose == 0"
  56. color="default">打开</a-tag>
  57. </template>
  58. <template
  59. v-if="record.rearGateOpenCtrl == 1 || record.rearGateOpenCtrl === true">
  60. <a-tag
  61. v-if="column.dataIndex === 'rearGateOpen' && record.rearGateOpen == 0 && record.rearGateClose == 0"
  62. color="red">正在打开</a-tag>
  63. <a-tag v-else-if="column.dataIndex === 'rearGateOpen'"
  64. color="processing">打开</a-tag>
  65. </template>
  66. <template
  67. v-else-if="record.rearGateOpenCtrl == 0 || record.rearGateOpenCtrl === false">
  68. <a-tag
  69. v-if="column.dataIndex === 'rearGateOpen' && record.rearGateOpen == 0 && record.rearGateClose == 0"
  70. color="red">正在关闭</a-tag>
  71. <a-tag
  72. v-else-if="column.dataIndex === 'rearGateOpen' && record.rearGateOpen == 0 && record.rearGateClose == 1"
  73. color="default">关闭</a-tag>
  74. <a-tag
  75. v-else-if="column.dataIndex === 'rearGateOpen' && record.rearGateOpen == 1 && record.rearGateClose == 0"
  76. color="default">打开</a-tag>
  77. </template>
  78. </template>
  79. <template v-if="deviceType.startsWith('windrect')">
  80. <a-tag v-if="column.dataIndex === 'sign'"
  81. :color="record.sign == '0' ? '#95CF65' : record.sign == 1 ? '#4590EA' : '#9876AA'">
  82. {{ record.sign == '0' ? '高位' : record.sign == 1 ? '中位' : '低位' }}</a-tag>
  83. <template
  84. v-if="record && column && column.dataIndex === 'isRun' && record.isRun">
  85. <a-tag v-if="record.isRun == -2 || record.isRun == -1"
  86. :color="record.isRun == -2 ? '#95CF65' : '#ED5700'">{{
  87. record.isRun == -2 ? '空闲' : '等待'
  88. }}</a-tag>
  89. <a-tag v-else-if="record.isRun == 100" color="#4693FF">完成</a-tag>
  90. <Progress v-else :percent="Number(record.isRun)" size="small"
  91. status="active" />
  92. </template>
  93. </template>
  94. <template v-if="deviceType.startsWith('safetymonitor')">
  95. <div v-if="!record.devicename && column.dataIndex === 'devicename'">-</div>
  96. <div v-if="!record.V && column.dataIndex === 'V'">-</div>
  97. <div v-if="!record.PointUnit && column.dataIndex === 'PointUnit'">-</div>
  98. <div v-if="!record.highRange && column.dataIndex === 'highRange'">-</div>
  99. <div v-if="!record.lowRange && column.dataIndex === 'lowRange'">-</div>
  100. <div v-if="!record.dataTypeName && column.dataIndex === 'dataTypeName'">-</div>
  101. </template>
  102. <a-tag v-if="column.dataIndex === 'warnFlag'"
  103. :color="record.warnFlag == '0' ? 'green' : record.warnFlag == 1 ? '#FF5812' : 'gray'">
  104. {{ record.warnFlag == '0' ? '正常' : record.warnFlag == 1 ? '报警' : record.warnFlag
  105. == 2 ? '断开' : '未监测'
  106. }}</a-tag>
  107. <a-tag v-if="column.dataIndex === 'netStatus'"
  108. :color="record.netStatus == '0' ? '#f00' : 'green'">{{
  109. record.netStatus == '0' ? '断开' : '连接'
  110. }}</a-tag>
  111. </template>
  112. </MonitorTable>
  113. </template>
  114. </template>
  115. </a-tab-pane>
  116. <a-tab-pane key="2" tab="瓦斯抽放">
  117. <MonitorTable ref="monitorTable" :columnsType="`${deviceType1}_monitor`" :dataSource="dataSource"
  118. design-scope="device_monitor" :isShowPagination="false"
  119. :isShowActionColumn="isHaveAction.includes(deviceType1.split('_')[0]) ? false : true"
  120. :is-show-select="false" title="设备监测" :form-config="undefined" :scroll="{ y: 360 }">
  121. <template #filterCell="{ column, record }">
  122. <template v-if="deviceType1.startsWith('gate')">
  123. <template v-if="record.frontGateOpenCtrl == 1 || record.frontGateOpenCtrl === true">
  124. <a-tag
  125. v-if="column.dataIndex === 'frontGateOpen' && record.frontGateOpen == 0 && record.frontGateClose == 0"
  126. color="red">正在打开</a-tag>
  127. <a-tag v-else-if="column.dataIndex === 'frontGateOpen'"
  128. color="processing">打开</a-tag>
  129. </template>
  130. <template
  131. v-else-if="record.frontGateOpenCtrl == 0 || record.frontGateOpenCtrl === false">
  132. <a-tag
  133. v-if="column.dataIndex === 'frontGateOpen' && record.frontGateOpen == 0 && record.frontGateClose == 0"
  134. color="red">正在关闭</a-tag>
  135. <a-tag
  136. v-else-if="column.dataIndex === 'frontGateOpen' && record.frontGateOpen == 0 && record.frontGateClose == 1"
  137. color="default">关闭</a-tag>
  138. <a-tag
  139. v-else-if="column.dataIndex === 'frontGateOpen' && record.frontGateOpen == 1 && record.frontGateClose == 0"
  140. color="default">打开</a-tag>
  141. </template>
  142. <template v-if="record.rearGateOpenCtrl == 1 || record.rearGateOpenCtrl === true">
  143. <a-tag
  144. v-if="column.dataIndex === 'rearGateOpen' && record.rearGateOpen == 0 && record.rearGateClose == 0"
  145. color="red">正在打开</a-tag>
  146. <a-tag v-else-if="column.dataIndex === 'rearGateOpen'" color="processing">打开</a-tag>
  147. </template>
  148. <template v-else-if="record.rearGateOpenCtrl == 0 || record.rearGateOpenCtrl === false">
  149. <a-tag
  150. v-if="column.dataIndex === 'rearGateOpen' && record.rearGateOpen == 0 && record.rearGateClose == 0"
  151. color="red">正在关闭</a-tag>
  152. <a-tag
  153. v-else-if="column.dataIndex === 'rearGateOpen' && record.rearGateOpen == 0 && record.rearGateClose == 1"
  154. color="default">关闭</a-tag>
  155. <a-tag
  156. v-else-if="column.dataIndex === 'rearGateOpen' && record.rearGateOpen == 1 && record.rearGateClose == 0"
  157. color="default">打开</a-tag>
  158. </template>
  159. </template>
  160. <template v-if="deviceType1.startsWith('windrect')">
  161. <a-tag v-if="column.dataIndex === 'sign'"
  162. :color="record.sign == '0' ? '#95CF65' : record.sign == 1 ? '#4590EA' : '#9876AA'">
  163. {{ record.sign == '0' ? '高位' : record.sign == 1 ? '中位' : '低位' }}</a-tag>
  164. <template v-if="record && column && column.dataIndex === 'isRun' && record.isRun">
  165. <a-tag v-if="record.isRun == -2 || record.isRun == -1"
  166. :color="record.isRun == -2 ? '#95CF65' : '#ED5700'">{{
  167. record.isRun == -2 ? '空闲' : '等待'
  168. }}</a-tag>
  169. <a-tag v-else-if="record.isRun == 100" color="#4693FF">完成</a-tag>
  170. <Progress v-else :percent="Number(record.isRun)" size="small" status="active" />
  171. </template>
  172. </template>
  173. <template v-if="deviceType1.startsWith('safetymonitor')">
  174. <div v-if="!record.devicename && column.dataIndex === 'devicename'">-</div>
  175. <div v-if="!record.V && column.dataIndex === 'V'">-</div>
  176. <div v-if="!record.PointUnit && column.dataIndex === 'PointUnit'">-</div>
  177. <div v-if="!record.highRange && column.dataIndex === 'highRange'">-</div>
  178. <div v-if="!record.lowRange && column.dataIndex === 'lowRange'">-</div>
  179. <div v-if="!record.dataTypeName && column.dataIndex === 'dataTypeName'">-</div>
  180. </template>
  181. <a-tag v-if="column.dataIndex === 'warnFlag'"
  182. :color="record.warnFlag == '0' ? 'green' : record.warnFlag == 1 ? '#FF5812' : 'gray'">
  183. {{ record.warnFlag == '0' ? '正常' : record.warnFlag == 1 ? '报警' : record.warnFlag
  184. == 2 ? '断开' : '未监测'
  185. }}</a-tag>
  186. <a-tag v-if="column.dataIndex === 'netStatus'"
  187. :color="record.netStatus == '0' ? '#f00' : 'green'">{{
  188. record.netStatus == '0' ? '断开' : '连接'
  189. }}</a-tag>
  190. </template>
  191. </MonitorTable>
  192. </a-tab-pane>
  193. </a-tabs>
  194. </div>
  195. </div>
  196. </template>
  197. <script setup lang="ts">
  198. import { ref, reactive, onMounted, onUnmounted, shallowRef } from 'vue'
  199. import customHeader from '/@/components/vent/customHeader.vue';
  200. import GroupMonitorTable from '../comment/GroupMonitorTable.vue';
  201. import MonitorTable from '../comment/MonitorTable.vue';
  202. import { cameraAddr, } from '../camera/camera.api'
  203. import { list } from '../safetyMonitor/safety.api';
  204. import { formConfig, isHaveAction } from '../safetyMonitor/safety.data';
  205. import Player, { I18N } from 'xgplayer';
  206. import ZH from 'xgplayer/es/lang/zh-cn'
  207. import HlsPlugin from 'xgplayer-hls';
  208. import FlvPlugin from 'xgplayer-flv';
  209. import 'xgplayer/dist/index.min.css';
  210. import { usePermission } from '/@/hooks/web/usePermission';
  211. const { hasPermission } = usePermission();
  212. const activeKey = ref('1'); // tab key
  213. const deviceType = ref('safetymonitor'); // 监测设备类型
  214. const deviceType1 = ref('safetymonitor'); // 监测设备类型
  215. const dataSource = shallowRef([]); // 实时监测数据
  216. const monitorTable = ref();
  217. const playerList = ref([])
  218. const webRtcServerList = <any[]>[]
  219. let addrList = ref<{ name: string, addr: string, devicekind: string }[]>([
  220. { name: '摄像头1', addr: "http://0.0.0.0:8080/live/16.flv", devicekind: 'wasichoufang' },
  221. { name: '摄像头2', addr: "http://0.0.0.0:8080/live/17.flv", devicekind: 'wasichoufang' }
  222. ])
  223. I18N.use(ZH)
  224. // https获取监测数据
  225. let timer: null | NodeJS.Timeout = null;
  226. function getMonitor(flag?) {
  227. if (deviceType.value) {
  228. if (timer) timer = null;
  229. timer = setTimeout(
  230. async () => {
  231. await getDataSource();
  232. if (timer) {
  233. getMonitor();
  234. }
  235. },
  236. flag ? 0 : 1000
  237. );
  238. }
  239. }
  240. //tabs选项切换
  241. async function tabChange(activeKeyVal) {
  242. activeKey.value = activeKeyVal;
  243. clearTimeout(timer);
  244. if (activeKey.value != '1') {
  245. deviceType.value = 'wasichoufang'
  246. } else {
  247. deviceType.value = 'safetymonitor'
  248. }
  249. getMonitor(true);
  250. }
  251. //获取安全监控-实时监测数据
  252. async function getDataSource() {
  253. const res = await list({ devicetype: deviceType.value, filterParams: {} });
  254. if (res.msgTxt.length > 0) {
  255. dataSource.value = [];
  256. let dataArr = res.msgTxt[0].datalist || [];
  257. dataArr.filter((data: any) => {
  258. const readData = data.readData;
  259. return Object.assign(data, readData);
  260. });
  261. if (deviceType.value == 'safetymonitor') {
  262. dataSource.value = dataArr;
  263. dataSource.value = dataArr.filter(v => v.strinstallpos == '31102采面钻孔下风侧一氧化碳' || v.strinstallpos == '31102采面钻孔下风侧甲烷')
  264. } else {
  265. dataSource.value = dataArr;
  266. }
  267. } else {
  268. dataSource.value = [];
  269. }
  270. }
  271. function getVideo() {
  272. const ip = VUE_APP_URL.webRtcUrl;
  273. for (let i = 0; i < addrList.value.length; i++) {
  274. const item = addrList.value[i]
  275. if (item.addr.startsWith('rtsp://')) {
  276. const dom = document.getElementById('video' + i) as HTMLVideoElement
  277. dom.muted = true;
  278. dom.volume = 0
  279. const webRtcServer = new window['WebRtcStreamer'](dom, location.protocol + ip)
  280. webRtcServerList.push(webRtcServer)
  281. webRtcServer.connect(item.addr)
  282. } else {
  283. setNoRtspVideo('player' + i, item.addr)
  284. }
  285. }
  286. }
  287. async function getVideoAddrs() {
  288. clearCamera();
  289. playerList.value = []
  290. const cameraList = <{ name: string, addr: string }[]>[]
  291. for (let i = 0; i < addrList.value.length; i++) {
  292. const item = addrList.value[i];
  293. if (item['devicekind'] === 'toHKRtsp') {
  294. // 从海康平台接口获取视频流
  295. try {
  296. const data = await cameraAddr({ cameraCode: item['addr'] });
  297. if (data) {
  298. cameraList.push({ name: item['name'], addr: data['url'] });
  299. }
  300. // cameraList.push({
  301. // name: item['name'],
  302. // // addr: 'http://219.151.31.38/liveplay-kk.rtxapp.com/live/program/live/hnwshd/4000000/mnf.m3u8'
  303. // addr: 'https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.mp4/.m3u8',
  304. // });
  305. } catch (error) {
  306. }
  307. } else {
  308. if (item['addr'].includes('0.0.0.0')) {
  309. item['addr'] = item['addr'].replace('0.0.0.0', window.location.hostname)
  310. }
  311. cameraList.push({ name: item['name'], addr: item['addr'] });
  312. }
  313. }
  314. }
  315. function goFullScreen(domId) {
  316. const videoDom = document.getElementById(domId) as HTMLVideoElement
  317. if (videoDom.requestFullscreen) {
  318. videoDom.requestFullscreen()
  319. videoDom.play()
  320. } else if (videoDom.mozRequestFullscreen) {
  321. videoDom.mozRequestFullscreen()
  322. videoDom.play()
  323. } else if (videoDom.webkitRequestFullscreen) {
  324. videoDom.webkitRequestFullscreen()
  325. videoDom.play()
  326. } else if (videoDom.msRequestFullscreen) {
  327. videoDom.msRequestFullscreen()
  328. videoDom.play()
  329. }
  330. }
  331. function clearCamera() {
  332. const num = webRtcServerList.length
  333. for (let i = 0; i < num; i++) {
  334. webRtcServerList[i].disconnect()
  335. webRtcServerList[i] = null
  336. }
  337. for (let i = 0; i < playerList.value.length; i++) {
  338. const player = playerList.value[i]
  339. if (player.destroy) player.destroy()
  340. }
  341. playerList.value = []
  342. }
  343. function setNoRtspVideo(id, videoAddr) {
  344. const fileExtension = videoAddr.split('.').pop();
  345. if (fileExtension === 'flv') {
  346. const player = new Player({
  347. lang: 'zh',
  348. id: id,
  349. url: videoAddr,
  350. width: 589,
  351. height: 330,
  352. poster: '/src/assets/images/vent/noSinge.png',
  353. plugins: [FlvPlugin],
  354. fluid: true,
  355. autoplay: true,
  356. isLive: true,
  357. playsinline: true,
  358. screenShot: true,
  359. whitelist: [''],
  360. ignores: ['time'],
  361. closeVideoClick: true,
  362. customConfig: {
  363. isClickPlayBack: false
  364. },
  365. flv: {
  366. retryCount: 3, // 重试 3 次,默认值
  367. retryDelay: 1000, // 每次重试间隔 1 秒,默认值
  368. loadTimeout: 10000, // 请求超时时间为 10 秒,默认值
  369. fetchOptions: {
  370. // 该参数会透传给 fetch,默认值为 undefined
  371. mode: 'cors'
  372. },
  373. targetLatency: 10, // 直播目标延迟,默认 10 秒
  374. maxLatency: 20, // 直播允许的最大延迟,默认 20 秒
  375. disconnectTime: 10, // 直播断流时间,默认 0 秒,(独立使用时等于 maxLatency)
  376. maxJumpDistance: 10,
  377. }
  378. });
  379. playerList.value.push(player)
  380. }
  381. if (fileExtension === 'm3u8') {
  382. let player
  383. if (document.createElement('video').canPlayType('application/vnd.apple.mpegurl')) {
  384. // 原生支持 hls 播放
  385. player = new Player({
  386. lang: 'zh',
  387. id: id,
  388. url: videoAddr,
  389. width: 589,
  390. height: 330,
  391. isLive: true,
  392. autoplay: true,
  393. autoplayMuted: true,
  394. cors: true,
  395. poster: '/src/assets/images/vent/noSinge.png',
  396. hls: {
  397. retryCount: 3, // 重试 3 次,默认值
  398. retryDelay: 1000, // 每次重试间隔 1 秒,默认值
  399. loadTimeout: 10000, // 请求超时时间为 10 秒,默认值
  400. fetchOptions: {
  401. // 该参数会透传给 fetch,默认值为 undefined
  402. mode: 'cors'
  403. },
  404. targetLatency: 10, // 直播目标延迟,默认 10 秒
  405. maxLatency: 20, // 直播允许的最大延迟,默认 20 秒
  406. disconnectTime: 10, // 直播断流时间,默认 0 秒,(独立使用时等于 maxLatency)
  407. maxJumpDistance: 10,
  408. }
  409. })
  410. } else if (HlsPlugin.isSupported()) { // 第一步
  411. player = new Player({
  412. lang: 'zh',
  413. id: id,
  414. url: videoAddr,
  415. width: 589,
  416. height: 330,
  417. isLive: true,
  418. autoplay: true,
  419. autoplayMuted: true,
  420. plugins: [HlsPlugin], // 第二步
  421. poster: '/src/assets/images/vent/noSinge.png',
  422. hls: {
  423. retryCount: 3, // 重试 3 次,默认值
  424. retryDelay: 1000, // 每次重试间隔 1 秒,默认值
  425. loadTimeout: 10000, // 请求超时时间为 10 秒,默认值
  426. fetchOptions: {
  427. // 该参数会透传给 fetch,默认值为 undefined
  428. mode: 'cors'
  429. },
  430. targetLatency: 10, // 直播目标延迟,默认 10 秒
  431. maxLatency: 20, // 直播允许的最大延迟,默认 20 秒
  432. disconnectTime: 10, // 直播断流时间,默认 0 秒,(独立使用时等于 maxLatency)
  433. maxJumpDistance: 10,
  434. }
  435. })
  436. }
  437. playerList.value.push(player)
  438. }
  439. }
  440. onMounted(() => {
  441. getVideo()
  442. getVideoAddrs()
  443. getMonitor(true);
  444. })
  445. onUnmounted(() => {
  446. clearCamera()
  447. if (timer) {
  448. clearTimeout(timer);
  449. }
  450. timer = undefined;
  451. });
  452. </script>
  453. <style lang="less" scoped>
  454. @import '/@/design/vent/color.less';
  455. @import '/@/design/vent/modal.less';
  456. .container-ln {
  457. position: relative;
  458. width: 100%;
  459. height: 100%;
  460. padding: 0px 10px;
  461. box-sizing: border-box;
  462. .video-ln {
  463. display: flex;
  464. justify-content: space-around;
  465. align-items: center;
  466. width: 100%;
  467. height: 50%;
  468. padding-top: 80px;
  469. .video-module {
  470. position: relative;
  471. width: 45%;
  472. height: 100%;
  473. background: url('/@/assets/images/vent/camera_bg.png');
  474. background-size: 100% 100%;
  475. .player-name {
  476. font-size: 14px;
  477. position: absolute;
  478. top: 15px;
  479. right: 15px;
  480. color: #fff;
  481. background-color: hsla(0, 0%, 50%, .5);
  482. border-radius: 2px;
  483. padding: 1px 5px;
  484. max-width: 120px;
  485. overflow: hidden;
  486. white-space: nowrap;
  487. text-overflow: ellipsis;
  488. z-index: 999;
  489. }
  490. .click-box {
  491. position: absolute;
  492. width: 100%;
  493. height: 100%;
  494. top: 0;
  495. left: 0;
  496. }
  497. }
  498. }
  499. .content-ln {
  500. width: 100%;
  501. height: 50%;
  502. .tabs-box {
  503. width: calc(100% - 12px) !important;
  504. height: 100% !important;
  505. bottom: 3px !important;
  506. }
  507. }
  508. }
  509. @ventSpace: zxm;
  510. :deep(.@{ventSpace}-tabs-tabpane-active) {
  511. height: 100%;
  512. border: 1px solid #44d3ff70;
  513. border-radius: 2px;
  514. -webkit-backdrop-filter: blur(8px);
  515. box-shadow: 0 0 20px #44b4ff33 inset;
  516. background-color: #ffffff11;
  517. overflow-y: auto;
  518. }
  519. :deep(.@{ventSpace}-tabs-card) {
  520. .@{ventSpace}-tabs-tab {
  521. background: linear-gradient(#2cd1ff55, #1eb0ff55);
  522. border-color: #74e9fe;
  523. border-radius: 0%;
  524. &:hover {
  525. color: #64d5ff;
  526. }
  527. }
  528. .@{ventSpace}-tabs-content {
  529. height: 100% !important;
  530. }
  531. .@{ventSpace}-tabs-tab.@{ventSpace}-tabs-tab-active .@{ventSpace}-tabs-tab-btn {
  532. color: aqua;
  533. }
  534. .@{ventSpace}-tabs-nav::before {
  535. border-color: #74e9fe;
  536. }
  537. .@{ventSpace}-table-cell-row-hover {
  538. background: #264d8833 !important;
  539. }
  540. .@{ventSpace}-table-row-selected {
  541. background: #00c0a311 !important;
  542. td {
  543. background-color: #00000000 !important;
  544. }
  545. }
  546. .@{ventSpace}-table-thead {
  547. // background: linear-gradient(#004a8655 0%, #004a86aa 10%) !important;
  548. background: #3d9dd45d !important;
  549. &>tr>th,
  550. .@{ventSpace}-table-column-title {
  551. // color: #70f9fc !important;
  552. border-color: #84f2ff !important;
  553. border-left: none !important;
  554. border-right: none !important;
  555. padding: 7px;
  556. }
  557. }
  558. .@{ventSpace}-table-tbody {
  559. tr>td {
  560. padding: 12px;
  561. }
  562. }
  563. .@{ventSpace}-table-tbody>tr:hover.@{ventSpace}-table-row>td {
  564. background-color: #26648855 !important;
  565. }
  566. .jeecg-basic-table-row__striped {
  567. // background: #97efff11 !important;
  568. td {
  569. background-color: #97efff11 !important;
  570. }
  571. }
  572. }
  573. </style>